Skip to content

Commit

Permalink
Merge branch 'master' into socket
Browse files Browse the repository at this point in the history
  • Loading branch information
sockmaster27 committed Aug 21, 2024
2 parents de239ab + 5806b4b commit 230e072
Show file tree
Hide file tree
Showing 18 changed files with 1,627 additions and 899 deletions.
2,238 changes: 1,507 additions & 731 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"description": "Flix Language Server Extension",
"author": "Flix",
"license": "Apache-2.0",
"version": "1.26.0",
"version": "1.29.0",
"repository": {
"type": "git",
"url": "https://github.com/flix/vscode-flix"
Expand Down Expand Up @@ -157,7 +157,7 @@
"@vscode/test-electron": "^2.3.9",
"esbuild": "^0.17.19",
"eslint": "^8.1.0",
"prettier": "^3.0.0",
"prettier": "^3.3.3",
"typescript": "^5.0.4"
}
}
40 changes: 10 additions & 30 deletions server/src/handlers/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import * as engine from '../engine'
import * as socket from '../engine/socket'

import { clearDiagnostics, sendDiagnostics, sendNotification } from '../server'
import { makePositionalHandler, makeEnqueuePromise, enqueueUnlessHasErrors, makeDefaultResponseHandler } from './util'
import { makePositionalHandler, makeEnqueuePromise, makeDefaultResponseHandler } from './util'
import { USER_MESSAGE } from '../util/userMessages'
import { StatusCode } from '../util/statusCodes'

Expand Down Expand Up @@ -129,11 +129,7 @@ export function handleRemJar({ uri }: UriInput) {
engine.remJar(uri)
}

export const handleShowAst = enqueueUnlessHasErrors(
makeShowAstJob,
makeShowAstResponseHandler,
hasErrorsHandlerForCommands,
)
export const handleShowAst = makeEnqueuePromise(makeShowAstJob, makeShowAstResponseHandler)

/**
* Request a response to be sent when all jobs are finished.
Expand Down Expand Up @@ -179,11 +175,7 @@ export function handleChangeContent(params: TextDocumentChangeEvent<TextDocument
/**
* @function
*/
export const handleGotoDefinition = makePositionalHandler(
jobs.Request.lspGoto,
undefined,
makeGotoDefinitionResponseHandler,
)
export const handleGotoDefinition = makePositionalHandler(jobs.Request.lspGoto, makeGotoDefinitionResponseHandler)

function makeGotoDefinitionResponseHandler(promiseResolver: (result?: socket.FlixResult) => void) {
return function responseHandler({ status, result }: socket.FlixResponse) {
Expand Down Expand Up @@ -232,11 +224,9 @@ export const handleCodelens = makePositionalHandler(jobs.Request.lspCodelens)
/**
* @function
*/
export const handleRename = enqueueUnlessHasErrors(
makeRenameJob,
makeDefaultResponseHandler,
hasErrorsHandlerForCommands,
)
export const handleRename = makeEnqueuePromise(makeRenameJob, makeDefaultResponseHandler) as (
params: any,
) => Promise<any>

function makeRenameJob(params: any) {
return {
Expand Down Expand Up @@ -266,11 +256,9 @@ export function handleCodeAction(params: any): Promise<any> {
/**
* @function
*/
export const handleWorkspaceSymbols = enqueueUnlessHasErrors(
makeWorkspaceSymbolsJob,
makeDefaultResponseHandler,
hasErrorsHandlerForCommands,
)
export const handleWorkspaceSymbols = makeEnqueuePromise(makeWorkspaceSymbolsJob, makeDefaultResponseHandler) as (
params: any,
) => Promise<any>

function makeWorkspaceSymbolsJob(params: any) {
return {
Expand All @@ -294,18 +282,10 @@ export const handleInlayHints = (params: InlayHintParams): Thenable<any> =>
socket.eventEmitter.once(job.id, makeDefaultResponseHandler(resolve))
})

function hasErrorsHandlerForCommands() {
sendNotification(jobs.Request.internalError, {
message: 'Cannot run commands when errors are present.',
actions: [],
})
sendNotification(jobs.Request.internalFinishedJob)
}

/**
* @function
*/
export const handleVersion = makeEnqueuePromise(jobs.Request.apiVersion, makeVersionResponseHandler)
export const handleVersion = makeEnqueuePromise({ request: jobs.Request.apiVersion }, makeVersionResponseHandler)

function makeVersionResponseHandler(promiseResolver: () => void) {
return function responseHandler({ status, result }: any) {
Expand Down
51 changes: 10 additions & 41 deletions server/src/handlers/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import * as jobs from '../engine/jobs'
import * as engine from '../engine'
import * as socket from '../engine/socket'
import { hasErrors } from '../server'
import { StatusCode } from '../util/statusCodes'

type ResponseHandler = ({ status, result }: socket.FlixResponse) => void
Expand All @@ -32,45 +31,20 @@ export function makeDefaultResponseHandler(promiseResolver: (result?: socket.Fli
}
}

export function makeEnqueuePromise(
type: jobs.Request,
makeResponseHandler?: (promiseResolver: (result?: socket.FlixResult) => void) => ResponseHandler,
uri?: string,
position?: any,
) {
return function enqueuePromise() {
return new Promise(function (resolve) {
const job = engine.enqueueJobWithFlattenedParams(type, { uri, position })
const handler = makeResponseHandler || makeDefaultResponseHandler
socket.eventEmitter.once(job.id, handler(resolve))
})
}
}

/**
* Function to enqueue a job unless errors are present.
* If errors are present the hasErrorsHandler is called.
* Otherwise a promise is returned that is finally resolved with the result of running the command.
* Function to enqueue a job.
* A promise is returned that is finally resolved with the result of running the command.
*
* @param jobOrGetJob - Either a Job with request and optional params or a function that returns a Job
* @param makeResponseHandler
* @param hasErrorsHandler
*/
export function enqueueUnlessHasErrors(
jobOrGetJob: jobs.Job | ((params: any) => jobs.Job),
makeResponseHandler?: (promiseResolver: (result?: socket.FlixResult | undefined) => void) => ResponseHandler,
hasErrorsHandler?: () => void,
): (params: any) => any {
if (typeof hasErrorsHandler !== 'function') {
// development check (remove later)
throw '`enqueueUnlessHasErrors` must have `hasErrorsHandler` when called with errors'
}
return function enqueuePromise(params: any) {
if (hasErrors() && hasErrorsHandler) {
return hasErrorsHandler()
}
export function makeEnqueuePromise<JobParams extends unknown[]>(
jobOrGetJob: jobs.Job | ((...params: JobParams) => jobs.Job),
makeResponseHandler?: (promiseResolver: (result?: socket.FlixResult) => void) => ResponseHandler,
) {
return function enqueuePromise(...params: JobParams) {
return new Promise(function (resolve) {
const { request, ...jobData } = typeof jobOrGetJob === 'function' ? jobOrGetJob(params) : jobOrGetJob
const { request, ...jobData } = typeof jobOrGetJob === 'function' ? jobOrGetJob(...params) : jobOrGetJob
const job = engine.enqueueJobWithFlattenedParams(request, jobData)
const handler = makeResponseHandler || makeDefaultResponseHandler
socket.eventEmitter.once(job.id, handler(resolve))
Expand All @@ -80,16 +54,11 @@ export function enqueueUnlessHasErrors(

export function makePositionalHandler(
type: jobs.Request,
handlerWhenErrorsExist?: () => Thenable<any>,
makeResponseHandler?: (promiseResolver: (result?: socket.FlixResult) => void) => ResponseHandler,
) {
return function positionalHandler(params: any): Thenable<any> {
if (hasErrors() && handlerWhenErrorsExist) {
// NOTE: At present this isn't used by anyone (neither is makeResponseHandler)
return handlerWhenErrorsExist()
}
const uri = params.textDocument ? params.textDocument.uri : undefined
const uri = params.textDocument?.uri
const position = params.position
return makeEnqueuePromise(type, makeResponseHandler, uri, position)()
return makeEnqueuePromise({ request: type, uri, position }, makeResponseHandler)()
}
}
13 changes: 1 addition & 12 deletions server/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,30 +119,19 @@ export function sendNotification(notificationType: string, payload?: any) {
// VS Code remembers files with errors and won't clear them itself.
const fileUrisWithErrors: Set<string> = new Set()

// A Boolean of whether the program contains errors.
let programHasError: boolean = false

export function hasErrors() {
return programHasError
}

/**
* Clear `fileUrisWithErrors` after removing error flags for all `uri`s.
*/
export function clearDiagnostics() {
fileUrisWithErrors.forEach((uri: string) => sendDiagnostics({ uri, diagnostics: [] }))
fileUrisWithErrors.clear()
programHasError = false
}

/**
* Proxy for `connection.sendDiagnostics` that also adds the `uri` to `fileUrisWithErrors`.
*/
export function sendDiagnostics(params: PublishDiagnosticsParams) {
params.diagnostics.forEach(diagnostic => {
if (diagnostic.severity && diagnostic.severity < 3) {
programHasError = true
}
params.diagnostics.forEach(() => {
fileUrisWithErrors.add(params.uri)
})
connection.sendDiagnostics(params)
Expand Down
12 changes: 0 additions & 12 deletions syntaxes/flix.tmLanguage.json
Original file line number Diff line number Diff line change
Expand Up @@ -155,18 +155,6 @@
"name": "keyword.expression.import.flix",
"match": "\\b(import)\\b"
},
{
"name": "keyword.expression.javanew.flix",
"match": "\\b(java_new)\\b"
},
{
"name": "keyword.expression.javagetfield.flix",
"match": "\\b(java_get_field)\\b"
},
{
"name": "keyword.expression.javasetfield.flix",
"match": "\\b(java_set_field)\\b"
},
{
"name": "keyword.expression.let.flix",
"match": "\\b(let\\*|let)\\b"
Expand Down
38 changes: 20 additions & 18 deletions test/src/findReferences.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ suite('Find references', () => {
})

test('Should find references to Dividable trait', async () => {
await testFindReferences(dividableDocUri, new vscode.Position(5, 6), [
new vscode.Location(dividableDocUri, new vscode.Range(5, 6, 5, 15)),
new vscode.Location(dividableDocUri, new vscode.Range(10, 9, 10, 18)),
await testFindReferences(dividableDocUri, new vscode.Position(1, 6), [
new vscode.Location(dividableDocUri, new vscode.Range(1, 6, 1, 15)),
new vscode.Location(dividableDocUri, new vscode.Range(5, 9, 5, 18)),
])
})

Expand All @@ -79,21 +79,21 @@ suite('Find references', () => {
test('Should find references to Equatable.equals signature', async () => {
await testFindReferences(equatableDocUri, new vscode.Position(2, 12), [
new vscode.Location(equatableDocUri, new vscode.Range(2, 12, 2, 18)),
new vscode.Location(equatableDocUri, new vscode.Range(9, 51, 9, 57)),
new vscode.Location(equatableDocUri, new vscode.Range(22, 14, 22, 20)),
new vscode.Location(equatableDocUri, new vscode.Range(29, 14, 29, 20)),
new vscode.Location(equatableDocUri, new vscode.Range(36, 18, 36, 24)),
new vscode.Location(equatableDocUri, new vscode.Range(43, 18, 43, 24)),
new vscode.Location(equatableDocUri, new vscode.Range(9, 41, 9, 57)),
new vscode.Location(equatableDocUri, new vscode.Range(22, 4, 22, 20)),
new vscode.Location(equatableDocUri, new vscode.Range(29, 4, 29, 20)),
new vscode.Location(equatableDocUri, new vscode.Range(36, 8, 36, 24)),
new vscode.Location(equatableDocUri, new vscode.Range(43, 8, 43, 24)),
])
})
test('Should find references to Equatable.equals signature-use', async () => {
await testFindReferences(equatableDocUri, new vscode.Position(29, 14), [
new vscode.Location(equatableDocUri, new vscode.Range(2, 12, 2, 18)),
new vscode.Location(equatableDocUri, new vscode.Range(9, 51, 9, 57)),
new vscode.Location(equatableDocUri, new vscode.Range(22, 14, 22, 20)),
new vscode.Location(equatableDocUri, new vscode.Range(29, 14, 29, 20)),
new vscode.Location(equatableDocUri, new vscode.Range(36, 18, 36, 24)),
new vscode.Location(equatableDocUri, new vscode.Range(43, 18, 43, 24)),
new vscode.Location(equatableDocUri, new vscode.Range(9, 41, 9, 57)),
new vscode.Location(equatableDocUri, new vscode.Range(22, 4, 22, 20)),
new vscode.Location(equatableDocUri, new vscode.Range(29, 4, 29, 20)),
new vscode.Location(equatableDocUri, new vscode.Range(36, 8, 36, 24)),
new vscode.Location(equatableDocUri, new vscode.Range(43, 8, 43, 24)),
])
})

Expand All @@ -111,28 +111,30 @@ suite('Find references', () => {
])
})

test('Should find references to Dividable.Aef associated effect', async () => {
/////// See https://github.com/flix/flix/issues/8326 ///////
test.skip('Should find references to Dividable.Aef associated effect', async () => {
await testFindReferences(dividableDocUri, new vscode.Position(6, 9), [
new vscode.Location(dividableDocUri, new vscode.Range(6, 9, 6, 12)),
new vscode.Location(dividableDocUri, new vscode.Range(7, 33, 7, 46)),
new vscode.Location(dividableDocUri, new vscode.Range(11, 9, 11, 12)),
])
})

test('Should find references to DivByZero effect', async () => {
test.skip('Should find references to DivByZero effect', async () => {
await testFindReferences(dividableDocUri, new vscode.Position(1, 4), [
new vscode.Location(dividableDocUri, new vscode.Range(1, 4, 1, 13)),
new vscode.Location(dividableDocUri, new vscode.Range(11, 15, 11, 24)),
new vscode.Location(dividableDocUri, new vscode.Range(12, 45, 12, 54)),
])
})

test('Should find references to DivByZero.throw operation', async () => {
test.skip('Should find references to DivByZero.throw operation', async () => {
await testFindReferences(dividableDocUri, new vscode.Position(2, 12), [
new vscode.Location(dividableDocUri, new vscode.Range(2, 12, 2, 17)),
new vscode.Location(dividableDocUri, new vscode.Range(13, 23, 13, 38)),
])
})
////////////////////////////////////////////////////////////

test('Should find references to function parameter', async () => {
await testFindReferences(equatableDocUri, new vscode.Position(6, 19), [
Expand Down Expand Up @@ -179,8 +181,8 @@ suite('Find references', () => {
new vscode.Location(recordsDocUri, new vscode.Range(2, 48, 2, 49)),
new vscode.Location(recordsDocUri, new vscode.Range(3, 6, 3, 7)),
new vscode.Location(recordsDocUri, new vscode.Range(13, 14, 13, 15)),
new vscode.Location(recordsDocUri, new vscode.Range(15, 7, 15, 8)),
new vscode.Location(recordsDocUri, new vscode.Range(15, 14, 15, 15)),
new vscode.Location(recordsDocUri, new vscode.Range(15, 8, 15, 9)),
new vscode.Location(recordsDocUri, new vscode.Range(15, 15, 15, 16)),
])
})
})
Loading

0 comments on commit 230e072

Please sign in to comment.