feat(language_server): request for workspace configuration when client did not send them in initialize#10789
Merged
graphite-app[bot] merged 1 commit intomainfrom May 7, 2025
Conversation
This was referenced May 4, 2025
Member
Author
How to use the Graphite Merge QueueAdd either label to this PR to merge it via the merge queue:
You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has enabled the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. This stack of pull requests is managed by Graphite. Learn more about stacking. |
This was referenced May 4, 2025
CodSpeed Instrumentation Performance ReportMerging #10789 will not alter performanceComparing Summary
|
a347d10 to
70e5315
Compare
adbc788 to
230ba92
Compare
230ba92 to
2a42bf1
Compare
70e5315 to
a5245f2
Compare
2a42bf1 to
f4f7568
Compare
a5245f2 to
27021b4
Compare
f4f7568 to
f43fd18
Compare
27021b4 to
297deaa
Compare
297deaa to
f63f386
Compare
camc314
approved these changes
May 7, 2025
Contributor
Merge activity
|
…t did not send them in `initialize` (#10789) ``` 2025-05-04 12:10:02.510 [info] [Trace - 12:10:02 PM] Sending notification 'initialized'. 2025-05-04 12:10:02.510 [info] Params: {} 2025-05-04 12:10:02.511 [info] [Trace - 12:10:02 PM] Sending notification 'textDocument/didOpen'. 2025-05-04 12:10:02.511 [info] Params: { "textDocument": { "uri": "file:///home/sysix/dev/oxc/editors/vscode/client/extension.ts", "languageId": "typescript", "version": 13, "text": "import .....\n" } } 2025-05-04 12:10:02.511 [info] [Trace - 12:10:02 PM] Received request 'workspace/configuration - (0)'. 2025-05-04 12:10:02.511 [info] Params: { "items": [ { "scopeUri": "file:///home/sysix/dev/oxc", "section": "oxc_language_server" } ] } 2025-05-04 12:10:02.511 [info] [Trace - 12:10:02 PM] Sending response 'workspace/configuration - (0)'. Processing request took 0ms 2025-05-04 12:10:02.511 [info] Result: [ { "run": "onType", "configPath": null, "flags": {} } ] ``` Someone (like me) would expect that the `textDocument/didOpen` will not result into any linting. But the Async Locks are preventing it (that what I could observe): ``` 2025-05-07 14:32:20.353 [info] [Trace - 2:32:20 PM] Sending request 'initialize - (0)'. 2025-05-07 14:32:20.901 linting file file:///home/sysix/dev/oxc/editors/vscode/client/extension.ts 2025-05-07 14:32:20.907 [info] [Trace - 2:32:20 PM] Received notification 'textDocument/publishDiagnostics'. ``` <details> <summary>Full Log</summary> ```` 2025-05-07 14:32:20.353 [info] [Trace - 2:32:20 PM] Sending request 'initialize - (0)'. 2025-05-07 14:32:20.353 [info] Params: { "processId": 65760, "clientInfo": { "name": "Visual Studio Code", "version": "1.99.3" }, "locale": "en", "rootPath": "/home/sysix/dev/oxc", "rootUri": "file:///home/sysix/dev/oxc", "capabilities": { "workspace": { "applyEdit": true, "workspaceEdit": { "documentChanges": true, "resourceOperations": [ "create", "rename", "delete" ], "failureHandling": "textOnlyTransactional", "normalizesLineEndings": true, "changeAnnotationSupport": { "groupsOnLabel": true } }, "configuration": true, "didChangeWatchedFiles": { "dynamicRegistration": true, "relativePatternSupport": true }, "symbol": { "dynamicRegistration": true, "symbolKind": { "valueSet": [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 ] }, "tagSupport": { "valueSet": [ 1 ] }, "resolveSupport": { "properties": [ "location.range" ] } }, "codeLens": { "refreshSupport": true }, "executeCommand": { "dynamicRegistration": true }, "didChangeConfiguration": { "dynamicRegistration": true }, "workspaceFolders": true, "foldingRange": { "refreshSupport": true }, "semanticTokens": { "refreshSupport": true }, "fileOperations": { "dynamicRegistration": true, "didCreate": true, "didRename": true, "didDelete": true, "willCreate": true, "willRename": true, "willDelete": true }, "inlineValue": { "refreshSupport": true }, "inlayHint": { "refreshSupport": true }, "diagnostics": { "refreshSupport": true } }, "textDocument": { "publishDiagnostics": { "relatedInformation": true, "versionSupport": false, "tagSupport": { "valueSet": [ 1, 2 ] }, "codeDescriptionSupport": true, "dataSupport": true }, "synchronization": { "dynamicRegistration": true, "willSave": true, "willSaveWaitUntil": true, "didSave": true }, "completion": { "dynamicRegistration": true, "contextSupport": true, "completionItem": { "snippetSupport": true, "commitCharactersSupport": true, "documentationFormat": [ "markdown", "plaintext" ], "deprecatedSupport": true, "preselectSupport": true, "tagSupport": { "valueSet": [ 1 ] }, "insertReplaceSupport": true, "resolveSupport": { "properties": [ "documentation", "detail", "additionalTextEdits" ] }, "insertTextModeSupport": { "valueSet": [ 1, 2 ] }, "labelDetailsSupport": true }, "insertTextMode": 2, "completionItemKind": { "valueSet": [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 ] }, "completionList": { "itemDefaults": [ "commitCharacters", "editRange", "insertTextFormat", "insertTextMode", "data" ] } }, "hover": { "dynamicRegistration": true, "contentFormat": [ "markdown", "plaintext" ] }, "signatureHelp": { "dynamicRegistration": true, "signatureInformation": { "documentationFormat": [ "markdown", "plaintext" ], "parameterInformation": { "labelOffsetSupport": true }, "activeParameterSupport": true }, "contextSupport": true }, "definition": { "dynamicRegistration": true, "linkSupport": true }, "references": { "dynamicRegistration": true }, "documentHighlight": { "dynamicRegistration": true }, "documentSymbol": { "dynamicRegistration": true, "symbolKind": { "valueSet": [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 ] }, "hierarchicalDocumentSymbolSupport": true, "tagSupport": { "valueSet": [ 1 ] }, "labelSupport": true }, "codeAction": { "dynamicRegistration": true, "isPreferredSupport": true, "disabledSupport": true, "dataSupport": true, "resolveSupport": { "properties": [ "edit" ] }, "codeActionLiteralSupport": { "codeActionKind": { "valueSet": [ "", "quickfix", "refactor", "refactor.extract", "refactor.inline", "refactor.rewrite", "source", "source.organizeImports" ] } }, "honorsChangeAnnotations": true }, "codeLens": { "dynamicRegistration": true }, "formatting": { "dynamicRegistration": true }, "rangeFormatting": { "dynamicRegistration": true, "rangesSupport": true }, "onTypeFormatting": { "dynamicRegistration": true }, "rename": { "dynamicRegistration": true, "prepareSupport": true, "prepareSupportDefaultBehavior": 1, "honorsChangeAnnotations": true }, "documentLink": { "dynamicRegistration": true, "tooltipSupport": true }, "typeDefinition": { "dynamicRegistration": true, "linkSupport": true }, "implementation": { "dynamicRegistration": true, "linkSupport": true }, "colorProvider": { "dynamicRegistration": true }, "foldingRange": { "dynamicRegistration": true, "rangeLimit": 5000, "lineFoldingOnly": true, "foldingRangeKind": { "valueSet": [ "comment", "imports", "region" ] }, "foldingRange": { "collapsedText": false } }, "declaration": { "dynamicRegistration": true, "linkSupport": true }, "selectionRange": { "dynamicRegistration": true }, "callHierarchy": { "dynamicRegistration": true }, "semanticTokens": { "dynamicRegistration": true, "tokenTypes": [ "namespace", "type", "class", "enum", "interface", "struct", "typeParameter", "parameter", "variable", "property", "enumMember", "event", "function", "method", "macro", "keyword", "modifier", "comment", "string", "number", "regexp", "operator", "decorator" ], "tokenModifiers": [ "declaration", "definition", "readonly", "static", "deprecated", "abstract", "async", "modification", "documentation", "defaultLibrary" ], "formats": [ "relative" ], "requests": { "range": true, "full": { "delta": true } }, "multilineTokenSupport": false, "overlappingTokenSupport": false, "serverCancelSupport": true, "augmentsSyntaxTokens": true }, "linkedEditingRange": { "dynamicRegistration": true }, "typeHierarchy": { "dynamicRegistration": true }, "inlineValue": { "dynamicRegistration": true }, "inlayHint": { "dynamicRegistration": true, "resolveSupport": { "properties": [ "tooltip", "textEdits", "label.tooltip", "label.location", "label.command" ] } }, "diagnostic": { "dynamicRegistration": true, "relatedDocumentSupport": false } }, "window": { "showMessage": { "messageActionItem": { "additionalPropertiesSupport": true } }, "showDocument": { "support": true }, "workDoneProgress": true }, "general": { "staleRequestSupport": { "cancel": true, "retryOnContentModified": [ "textDocument/semanticTokens/full", "textDocument/semanticTokens/range", "textDocument/semanticTokens/full/delta" ] }, "regularExpressions": { "engine": "ECMAScript", "version": "ES2020" }, "markdown": { "parser": "marked", "version": "1.1.0" }, "positionEncodings": [ "utf-16" ] }, "notebookDocument": { "synchronization": { "dynamicRegistration": true, "executionSummarySupport": true } } }, "trace": "verbose", "workspaceFolders": [ { "uri": "file:///home/sysix/dev/oxc", "name": "oxc" } ] } 2025-05-07 14:32:20.353 [info] [Trace - 2:32:20 PM] Received response 'initialize - (0)' in 49ms. 2025-05-07 14:32:20.353 [info] Result: { "capabilities": { "textDocumentSync": 1, "codeActionProvider": { "codeActionKinds": [ "quickfix", "source.fixAll.oxc" ] }, "executeCommandProvider": { "commands": [ "oxc.fixAll" ] }, "workspace": { "workspaceFolders": { "supported": true, "changeNotifications": true } } }, "serverInfo": { "name": "oxc", "version": "0.16.9" } } 2025-05-07 14:32:20.353 [info] [Trace - 2:32:20 PM] Sending notification 'initialized'. 2025-05-07 14:32:20.353 [info] Params: {} 2025-05-07 14:32:20.353 [info] [Trace - 2:32:20 PM] Sending notification 'textDocument/didOpen'. 2025-05-07 14:32:20.353 [info] Params: { "textDocument": { "uri": "file:///home/sysix/dev/oxc/editors/vscode/client/extension.ts", "languageId": "typescript", "version": 1, "text": "import { promises as fsPromises } from 'node:fs';\n\nimport {\n commands,\n ExtensionContext,\n FileSystemWatcher,\n RelativePattern,\n StatusBarAlignment,\n StatusBarItem,\n ThemeColor,\n window,\n workspace,\n} from 'vscode';\n\nimport {\n ConfigurationParams,\n ExecuteCommandRequest,\n MessageType,\n ShowMessageNotification,\n} from 'vscode-languageclient';\n\nimport { Executable, LanguageClient, LanguageClientOptions, ServerOptions } from 'vscode-languageclient/node';\n\nimport { join } from 'node:path';\nimport { ConfigService } from './ConfigService';\nimport { oxlintConfigFileName } from './VSCodeConfig';\n\nconst languageClientName = 'oxc';\nconst outputChannelName = 'Oxc';\nconst commandPrefix = 'oxc';\n\nconst enum OxcCommands {\n RestartServer = `${commandPrefix}.restartServer`,\n ApplyAllFixesFile = `${commandPrefix}.applyAllFixesFile`,\n ShowOutputChannel = `${commandPrefix}.showOutputChannel`,\n ToggleEnable = `${commandPrefix}.toggleEnable`,\n}\n\nconst enum LspCommands {\n FixAll = 'oxc.fixAll',\n}\n\nlet client: LanguageClient | undefined;\n\nlet myStatusBarItem: StatusBarItem;\n\nconst globalWatchers: FileSystemWatcher[] = [];\n\nexport async function activate(context: ExtensionContext) {\n const configService = new ConfigService();\n const restartCommand = commands.registerCommand(\n OxcCommands.RestartServer,\n async () => {\n if (client === undefined) {\n window.showErrorMessage('oxc client not found');\n return;\n }\n\n try {\n if (client.isRunning()) {\n await client.restart();\n window.showInformationMessage('oxc server restarted.');\n } else {\n await client.start();\n }\n } catch (err) {\n client.error('Restarting client failed', err, 'force');\n }\n },\n );\n\n const showOutputCommand = commands.registerCommand(\n OxcCommands.ShowOutputChannel,\n () => {\n client?.outputChannel?.show();\n },\n );\n\n const toggleEnable = commands.registerCommand(\n OxcCommands.ToggleEnable,\n async () => {\n await configService.vsCodeConfig.updateEnable(!configService.vsCodeConfig.enable);\n\n if (client === undefined) {\n return;\n }\n\n if (client.isRunning()) {\n if (!configService.vsCodeConfig.enable) {\n await client.stop();\n }\n } else {\n if (configService.vsCodeConfig.enable) {\n await client.start();\n }\n }\n },\n );\n\n const applyAllFixesFile = commands.registerCommand(\n OxcCommands.ApplyAllFixesFile,\n async () => {\n if (!client) {\n window.showErrorMessage('oxc client not found');\n return;\n }\n const textEditor = window.activeTextEditor;\n if (!textEditor) {\n window.showErrorMessage('active text editor not found');\n return;\n }\n\n const params = {\n command: LspCommands.FixAll,\n arguments: [{\n uri: textEditor.document.uri.toString(),\n }],\n };\n\n await client.sendRequest(ExecuteCommandRequest.type, params);\n },\n );\n\n const outputChannel = window.createOutputChannel(outputChannelName, { log: true });\n const fileWatchers = createFileEventWatchers(configService.rootServerConfig.configPath);\n\n context.subscriptions.push(\n applyAllFixesFile,\n restartCommand,\n showOutputCommand,\n toggleEnable,\n configService,\n outputChannel,\n {\n dispose: () => {\n globalWatchers.forEach((watcher) => watcher.dispose());\n },\n },\n );\n\n async function findBinary(): Promise<string> {\n let bin = configService.vsCodeConfig.binPath;\n if (bin) {\n try {\n await fsPromises.access(bin);\n return bin;\n } catch (e) {\n outputChannel.error(`Invalid bin path: ${bin}`, e);\n }\n }\n\n const workspaceFolders = workspace.workspaceFolders;\n const isWindows = process.platform === 'win32';\n\n if (workspaceFolders?.length && !isWindows) {\n try {\n return await Promise.any(\n workspaceFolders.map(async (folder) => {\n const binPath = join(\n folder.uri.fsPath,\n 'node_modules',\n '.bin',\n 'oxc_language_server',\n );\n\n await fsPromises.access(binPath);\n return binPath;\n }),\n );\n } catch {}\n }\n\n const ext = isWindows ? '.exe' : '';\n // NOTE: The `./target/release` path is aligned with the path defined in .github/workflows/release_vscode.yml\n return (\n process.env.SERVER_PATH_DEV ??\n join(context.extensionPath, `./target/release/oxc_language_server${ext}`)\n );\n }\n\n const command = await findBinary();\n const run: Executable = {\n command: command!,\n options: {\n env: {\n ...process.env,\n RUST_LOG: process.env.RUST_LOG || 'info',\n },\n },\n };\n const serverOptions: ServerOptions = {\n run,\n debug: run,\n };\n\n // If the extension is launched in debug mode then the debug server options are used\n // Otherwise the run options are used\n // Options to control the language client\n let clientOptions: LanguageClientOptions = {\n // Register the server for plain text documents\n documentSelector: [\n 'typescript',\n 'javascript',\n 'typescriptreact',\n 'javascriptreact',\n 'vue',\n 'svelte',\n ].map((lang) => ({\n language: lang,\n scheme: 'file',\n })),\n synchronize: {\n // Notify the server about file config changes in the workspace\n fileEvents: fileWatchers,\n },\n outputChannel,\n traceOutputChannel: outputChannel,\n middleware: {\n workspace: {\n configuration: (params: ConfigurationParams) => {\n return params.items.map(item => {\n if (item.section !== 'oxc_language_server') {\n return null;\n }\n\n return configService.rootServerConfig.toLanguageServerConfig() ?? null;\n });\n },\n },\n },\n };\n\n // Create the language client and start the client.\n client = new LanguageClient(\n languageClientName,\n serverOptions,\n clientOptions,\n );\n\n const onNotificationDispose = client.onNotification(ShowMessageNotification.type, (params) => {\n switch (params.type) {\n case MessageType.Debug:\n outputChannel.debug(params.message);\n break;\n case MessageType.Log:\n outputChannel.info(params.message);\n break;\n case MessageType.Info:\n window.showInformationMessage(params.message);\n break;\n case MessageType.Warning:\n window.showWarningMessage(params.message);\n break;\n case MessageType.Error:\n window.showErrorMessage(params.message);\n break;\n default:\n outputChannel.info(params.message);\n }\n });\n\n context.subscriptions.push(onNotificationDispose);\n\n const onDeleteFilesDispose = workspace.onDidDeleteFiles((event) => {\n for (const fileUri of event.files) {\n client?.diagnostics?.delete(fileUri);\n }\n });\n\n context.subscriptions.push(onDeleteFilesDispose);\n\n configService.onConfigChange = async function onConfigChange(event) {\n let settings = this.rootServerConfig.toLanguageServerConfig();\n updateStatsBar(this.vsCodeConfig.enable);\n\n if (client === undefined) {\n return;\n }\n\n // update the initializationOptions for a possible restart\n client.clientOptions.initializationOptions = { settings };\n\n if (event.affectsConfiguration('oxc.configPath')) {\n client.clientOptions.synchronize = client.clientOptions.synchronize ?? {};\n client.clientOptions.synchronize.fileEvents = createFileEventWatchers(settings.configPath);\n\n if (client.isRunning()) {\n await client.restart();\n }\n } else if (client.isRunning()) {\n await client.sendNotification('workspace/didChangeConfiguration', { settings });\n }\n };\n\n function updateStatsBar(enable: boolean) {\n if (!myStatusBarItem) {\n myStatusBarItem = window.createStatusBarItem(\n StatusBarAlignment.Right,\n 100,\n );\n myStatusBarItem.command = OxcCommands.ToggleEnable;\n context.subscriptions.push(myStatusBarItem);\n myStatusBarItem.show();\n }\n let bgColor = new ThemeColor(\n enable\n ? 'statusBarItem.activeBackground'\n : 'statusBarItem.warningBackground',\n );\n myStatusBarItem.text = `oxc: ${enable ? '$(check-all)' : '$(check)'}`;\n\n myStatusBarItem.backgroundColor = bgColor;\n }\n\n updateStatsBar(configService.vsCodeConfig.enable);\n if (configService.vsCodeConfig.enable) {\n await client.start();\n }\n}\n\nexport async function deactivate(): Promise<void> {\n if (!client) {\n return undefined;\n }\n await client.stop();\n client = undefined;\n}\n\n// FileSystemWatcher are not ready on the start and can take some seconds on bigger repositories\nfunction createFileEventWatchers(configRelativePath: string | null): FileSystemWatcher[] {\n // cleanup old watchers\n globalWatchers.forEach((watcher) => watcher.dispose());\n globalWatchers.length = 0;\n\n // create new watchers\n let localWatchers;\n if (configRelativePath !== null) {\n localWatchers = (workspace.workspaceFolders || []).map((workspaceFolder) =>\n workspace.createFileSystemWatcher(new RelativePattern(workspaceFolder, configRelativePath))\n );\n } else {\n localWatchers = [\n workspace.createFileSystemWatcher(`**/${oxlintConfigFileName}`),\n ];\n }\n\n // assign watchers to global variable, so we can cleanup them on next call\n globalWatchers.push(...localWatchers);\n\n return localWatchers;\n}\n" } } 2025-05-07 14:32:20.353 [info] [Trace - 2:32:20 PM] Received request 'workspace/configuration - (0)'. 2025-05-07 14:32:20.353 [info] Params: { "items": [ { "scopeUri": "file:///home/sysix/dev/oxc", "section": "oxc_language_server" } ] } 2025-05-07 14:32:20.353 [info] [Trace - 2:32:20 PM] Sending response 'workspace/configuration - (0)'. Processing request took 0ms 2025-05-07 14:32:20.353 [info] Result: [ { "run": "onType", "configPath": null, "flags": {} } ] 2025-05-07 14:32:20.353 [info] [Trace - 2:32:20 PM] Sending request 'textDocument/codeAction - (1)'. 2025-05-07 14:32:20.353 [info] Params: { "textDocument": { "uri": "file:///home/sysix/dev/oxc/editors/vscode/client/extension.ts" }, "range": { "start": { "line": 236, "character": 18 }, "end": { "line": 236, "character": 18 } }, "context": { "diagnostics": [], "triggerKind": 2 } } 2025-05-07 14:32:20.358 [info] [Trace - 2:32:20 PM] Sending notification '$/cancelRequest'. 2025-05-07 14:32:20.358 [info] Params: { "id": 1 } 2025-05-07 14:32:20.394 [info] [Trace - 2:32:20 PM] Sending request 'textDocument/codeAction - (2)'. 2025-05-07 14:32:20.394 [info] Params: { "textDocument": { "uri": "file:///home/sysix/dev/oxc/editors/vscode/client/extension.ts" }, "range": { "start": { "line": 236, "character": 18 }, "end": { "line": 236, "character": 18 } }, "context": { "diagnostics": [], "triggerKind": 2 } } 2025-05-07 14:32:20.857 [info] [Trace - 2:32:20 PM] Sending notification '$/cancelRequest'. 2025-05-07 14:32:20.857 [info] Params: { "id": 2 } 2025-05-07 14:32:20.868 [info] [Trace - 2:32:20 PM] Sending notification '$/setTrace'. 2025-05-07 14:32:20.868 [info] Params: { "value": "verbose" } 2025-05-07 14:32:20.874 [info] [Trace - 2:32:20 PM] Sending notification '$/setTrace'. 2025-05-07 14:32:20.874 [info] Params: { "value": "verbose" } 2025-05-07 14:32:20.881 [info] [Trace - 2:32:20 PM] Sending notification '$/setTrace'. 2025-05-07 14:32:20.881 [info] Params: { "value": "verbose" } 2025-05-07 14:32:20.901 [info] [2025-05-07T12:32:20Z INFO oxc_language_server] linting file file:///home/sysix/dev/oxc/editors/vscode/client/extension.ts [2025-05-07T12:32:20Z INFO oxc_language_server] linting file succedded file:///home/sysix/dev/oxc/editors/vscode/client/extension.ts 2025-05-07 14:32:20.902 [info] [Trace - 2:32:20 PM] Sending request 'textDocument/codeAction - (3)'. 2025-05-07 14:32:20.902 [info] Params: { "textDocument": { "uri": "file:///home/sysix/dev/oxc/editors/vscode/client/extension.ts" }, "range": { "start": { "line": 236, "character": 18 }, "end": { "line": 236, "character": 18 } }, "context": { "diagnostics": [], "triggerKind": 2 } } 2025-05-07 14:32:20.902 [info] [Trace - 2:32:20 PM] Sending request 'textDocument/codeAction - (4)'. 2025-05-07 14:32:20.902 [info] Params: { "textDocument": { "uri": "file:///home/sysix/dev/oxc/editors/vscode/client/extension.ts" }, "range": { "start": { "line": 236, "character": 18 }, "end": { "line": 236, "character": 18 } }, "context": { "diagnostics": [], "triggerKind": 2 } } 2025-05-07 14:32:20.903 [info] [Trace - 2:32:20 PM] Sending notification '$/cancelRequest'. 2025-05-07 14:32:20.903 [info] Params: { "id": 3 } 2025-05-07 14:32:20.907 [info] [Trace - 2:32:20 PM] Received notification 'textDocument/publishDiagnostics'. 2025-05-07 14:32:20.907 [info] Params: { "uri": "file:///home/sysix/dev/oxc/editors/vscode/client/extension.ts", "diagnostics": [], "version": 1 } ```` </details>
f63f386 to
e1bc037
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Someone (like me) would expect that the
textDocument/didOpenwill not result into any linting. But the Async Locks are preventing it (that what I could observe):Full Log
```` 2025-05-07 14:32:20.353 [info] [Trace - 2:32:20 PM] Sending request 'initialize - (0)'. 2025-05-07 14:32:20.353 [info] Params: { "processId": 65760, "clientInfo": { "name": "Visual Studio Code", "version": "1.99.3" }, "locale": "en", "rootPath": "/home/sysix/dev/oxc", "rootUri": "file:///home/sysix/dev/oxc", "capabilities": { "workspace": { "applyEdit": true, "workspaceEdit": { "documentChanges": true, "resourceOperations": [ "create", "rename", "delete" ], "failureHandling": "textOnlyTransactional", "normalizesLineEndings": true, "changeAnnotationSupport": { "groupsOnLabel": true } }, "configuration": true, "didChangeWatchedFiles": { "dynamicRegistration": true, "relativePatternSupport": true }, "symbol": { "dynamicRegistration": true, "symbolKind": { "valueSet": [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 ] }, "tagSupport": { "valueSet": [ 1 ] }, "resolveSupport": { "properties": [ "location.range" ] } }, "codeLens": { "refreshSupport": true }, "executeCommand": { "dynamicRegistration": true }, "didChangeConfiguration": { "dynamicRegistration": true }, "workspaceFolders": true, "foldingRange": { "refreshSupport": true }, "semanticTokens": { "refreshSupport": true }, "fileOperations": { "dynamicRegistration": true, "didCreate": true, "didRename": true, "didDelete": true, "willCreate": true, "willRename": true, "willDelete": true }, "inlineValue": { "refreshSupport": true }, "inlayHint": { "refreshSupport": true }, "diagnostics": { "refreshSupport": true } }, "textDocument": { "publishDiagnostics": { "relatedInformation": true, "versionSupport": false, "tagSupport": { "valueSet": [ 1, 2 ] }, "codeDescriptionSupport": true, "dataSupport": true }, "synchronization": { "dynamicRegistration": true, "willSave": true, "willSaveWaitUntil": true, "didSave": true }, "completion": { "dynamicRegistration": true, "contextSupport": true, "completionItem": { "snippetSupport": true, "commitCharactersSupport": true, "documentationFormat": [ "markdown", "plaintext" ], "deprecatedSupport": true, "preselectSupport": true, "tagSupport": { "valueSet": [ 1 ] }, "insertReplaceSupport": true, "resolveSupport": { "properties": [ "documentation", "detail", "additionalTextEdits" ] }, "insertTextModeSupport": { "valueSet": [ 1, 2 ] }, "labelDetailsSupport": true }, "insertTextMode": 2, "completionItemKind": { "valueSet": [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 ] }, "completionList": { "itemDefaults": [ "commitCharacters", "editRange", "insertTextFormat", "insertTextMode", "data" ] } }, "hover": { "dynamicRegistration": true, "contentFormat": [ "markdown", "plaintext" ] }, "signatureHelp": { "dynamicRegistration": true, "signatureInformation": { "documentationFormat": [ "markdown", "plaintext" ], "parameterInformation": { "labelOffsetSupport": true }, "activeParameterSupport": true }, "contextSupport": true }, "definition": { "dynamicRegistration": true, "linkSupport": true }, "references": { "dynamicRegistration": true }, "documentHighlight": { "dynamicRegistration": true }, "documentSymbol": { "dynamicRegistration": true, "symbolKind": { "valueSet": [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 ] }, "hierarchicalDocumentSymbolSupport": true, "tagSupport": { "valueSet": [ 1 ] }, "labelSupport": true }, "codeAction": { "dynamicRegistration": true, "isPreferredSupport": true, "disabledSupport": true, "dataSupport": true, "resolveSupport": { "properties": [ "edit" ] }, "codeActionLiteralSupport": { "codeActionKind": { "valueSet": [ "", "quickfix", "refactor", "refactor.extract", "refactor.inline", "refactor.rewrite", "source", "source.organizeImports" ] } }, "honorsChangeAnnotations": true }, "codeLens": { "dynamicRegistration": true }, "formatting": { "dynamicRegistration": true }, "rangeFormatting": { "dynamicRegistration": true, "rangesSupport": true }, "onTypeFormatting": { "dynamicRegistration": true }, "rename": { "dynamicRegistration": true, "prepareSupport": true, "prepareSupportDefaultBehavior": 1, "honorsChangeAnnotations": true }, "documentLink": { "dynamicRegistration": true, "tooltipSupport": true }, "typeDefinition": { "dynamicRegistration": true, "linkSupport": true }, "implementation": { "dynamicRegistration": true, "linkSupport": true }, "colorProvider": { "dynamicRegistration": true }, "foldingRange": { "dynamicRegistration": true, "rangeLimit": 5000, "lineFoldingOnly": true, "foldingRangeKind": { "valueSet": [ "comment", "imports", "region" ] }, "foldingRange": { "collapsedText": false } }, "declaration": { "dynamicRegistration": true, "linkSupport": true }, "selectionRange": { "dynamicRegistration": true }, "callHierarchy": { "dynamicRegistration": true }, "semanticTokens": { "dynamicRegistration": true, "tokenTypes": [ "namespace", "type", "class", "enum", "interface", "struct", "typeParameter", "parameter", "variable", "property", "enumMember", "event", "function", "method", "macro", "keyword", "modifier", "comment", "string", "number", "regexp", "operator", "decorator" ], "tokenModifiers": [ "declaration", "definition", "readonly", "static", "deprecated", "abstract", "async", "modification", "documentation", "defaultLibrary" ], "formats": [ "relative" ], "requests": { "range": true, "full": { "delta": true } }, "multilineTokenSupport": false, "overlappingTokenSupport": false, "serverCancelSupport": true, "augmentsSyntaxTokens": true }, "linkedEditingRange": { "dynamicRegistration": true }, "typeHierarchy": { "dynamicRegistration": true }, "inlineValue": { "dynamicRegistration": true }, "inlayHint": { "dynamicRegistration": true, "resolveSupport": { "properties": [ "tooltip", "textEdits", "label.tooltip", "label.location", "label.command" ] } }, "diagnostic": { "dynamicRegistration": true, "relatedDocumentSupport": false } }, "window": { "showMessage": { "messageActionItem": { "additionalPropertiesSupport": true } }, "showDocument": { "support": true }, "workDoneProgress": true }, "general": { "staleRequestSupport": { "cancel": true, "retryOnContentModified": [ "textDocument/semanticTokens/full", "textDocument/semanticTokens/range", "textDocument/semanticTokens/full/delta" ] }, "regularExpressions": { "engine": "ECMAScript", "version": "ES2020" }, "markdown": { "parser": "marked", "version": "1.1.0" }, "positionEncodings": [ "utf-16" ] }, "notebookDocument": { "synchronization": { "dynamicRegistration": true, "executionSummarySupport": true } } }, "trace": "verbose", "workspaceFolders": [ { "uri": "file:///home/sysix/dev/oxc", "name": "oxc" } ] }2025-05-07 14:32:20.353 [info] [Trace - 2:32:20 PM] Received response 'initialize - (0)' in 49ms.
2025-05-07 14:32:20.353 [info] Result: {
"capabilities": {
"textDocumentSync": 1,
"codeActionProvider": {
"codeActionKinds": [
"quickfix",
"source.fixAll.oxc"
]
},
"executeCommandProvider": {
"commands": [
"oxc.fixAll"
]
},
"workspace": {
"workspaceFolders": {
"supported": true,
"changeNotifications": true
}
}
},
"serverInfo": {
"name": "oxc",
"version": "0.16.9"
}
}
2025-05-07 14:32:20.353 [info] [Trace - 2:32:20 PM] Sending notification 'initialized'.
2025-05-07 14:32:20.353 [info] Params: {}
2025-05-07 14:32:20.353 [info] [Trace - 2:32:20 PM] Sending notification 'textDocument/didOpen'.
2025-05-07 14:32:20.353 [info] Params: {
"textDocument": {
"uri": "file:///home/sysix/dev/oxc/editors/vscode/client/extension.ts",
"languageId": "typescript",
"version": 1,
"text": "import { promises as fsPromises } from 'node:fs';\n\nimport {\n commands,\n ExtensionContext,\n FileSystemWatcher,\n RelativePattern,\n StatusBarAlignment,\n StatusBarItem,\n ThemeColor,\n window,\n workspace,\n} from 'vscode';\n\nimport {\n ConfigurationParams,\n ExecuteCommandRequest,\n MessageType,\n ShowMessageNotification,\n} from 'vscode-languageclient';\n\nimport { Executable, LanguageClient, LanguageClientOptions, ServerOptions } from 'vscode-languageclient/node';\n\nimport { join } from 'node:path';\nimport { ConfigService } from './ConfigService';\nimport { oxlintConfigFileName } from './VSCodeConfig';\n\nconst languageClientName = 'oxc';\nconst outputChannelName = 'Oxc';\nconst commandPrefix = 'oxc';\n\nconst enum OxcCommands {\n RestartServer =
${commandPrefix}.restartServer,\n ApplyAllFixesFile =${commandPrefix}.applyAllFixesFile,\n ShowOutputChannel =${commandPrefix}.showOutputChannel,\n ToggleEnable =${commandPrefix}.toggleEnable,\n}\n\nconst enum LspCommands {\n FixAll = 'oxc.fixAll',\n}\n\nlet client: LanguageClient | undefined;\n\nlet myStatusBarItem: StatusBarItem;\n\nconst globalWatchers: FileSystemWatcher[] = [];\n\nexport async function activate(context: ExtensionContext) {\n const configService = new ConfigService();\n const restartCommand = commands.registerCommand(\n OxcCommands.RestartServer,\n async () => {\n if (client === undefined) {\n window.showErrorMessage('oxc client not found');\n return;\n }\n\n try {\n if (client.isRunning()) {\n await client.restart();\n window.showInformationMessage('oxc server restarted.');\n } else {\n await client.start();\n }\n } catch (err) {\n client.error('Restarting client failed', err, 'force');\n }\n },\n );\n\n const showOutputCommand = commands.registerCommand(\n OxcCommands.ShowOutputChannel,\n () => {\n client?.outputChannel?.show();\n },\n );\n\n const toggleEnable = commands.registerCommand(\n OxcCommands.ToggleEnable,\n async () => {\n await configService.vsCodeConfig.updateEnable(!configService.vsCodeConfig.enable);\n\n if (client === undefined) {\n return;\n }\n\n if (client.isRunning()) {\n if (!configService.vsCodeConfig.enable) {\n await client.stop();\n }\n } else {\n if (configService.vsCodeConfig.enable) {\n await client.start();\n }\n }\n },\n );\n\n const applyAllFixesFile = commands.registerCommand(\n OxcCommands.ApplyAllFixesFile,\n async () => {\n if (!client) {\n window.showErrorMessage('oxc client not found');\n return;\n }\n const textEditor = window.activeTextEditor;\n if (!textEditor) {\n window.showErrorMessage('active text editor not found');\n return;\n }\n\n const params = {\n command: LspCommands.FixAll,\n arguments: [{\n uri: textEditor.document.uri.toString(),\n }],\n };\n\n await client.sendRequest(ExecuteCommandRequest.type, params);\n },\n );\n\n const outputChannel = window.createOutputChannel(outputChannelName, { log: true });\n const fileWatchers = createFileEventWatchers(configService.rootServerConfig.configPath);\n\n context.subscriptions.push(\n applyAllFixesFile,\n restartCommand,\n showOutputCommand,\n toggleEnable,\n configService,\n outputChannel,\n {\n dispose: () => {\n globalWatchers.forEach((watcher) => watcher.dispose());\n },\n },\n );\n\n async function findBinary(): Promise {\n let bin = configService.vsCodeConfig.binPath;\n if (bin) {\n try {\n await fsPromises.access(bin);\n return bin;\n } catch (e) {\n outputChannel.error(Invalid bin path: ${bin}, e);\n }\n }\n\n const workspaceFolders = workspace.workspaceFolders;\n const isWindows = process.platform === 'win32';\n\n if (workspaceFolders?.length && !isWindows) {\n try {\n return await Promise.any(\n workspaceFolders.map(async (folder) => {\n const binPath = join(\n folder.uri.fsPath,\n 'node_modules',\n '.bin',\n 'oxc_language_server',\n );\n\n await fsPromises.access(binPath);\n return binPath;\n }),\n );\n } catch {}\n }\n\n const ext = isWindows ? '.exe' : '';\n // NOTE: The./target/releasepath is aligned with the path defined in .github/workflows/release_vscode.yml\n return (\n process.env.SERVER_PATH_DEV ??\n join(context.extensionPath,./target/release/oxc_language_server${ext})\n );\n }\n\n const command = await findBinary();\n const run: Executable = {\n command: command!,\n options: {\n env: {\n ...process.env,\n RUST_LOG: process.env.RUST_LOG || 'info',\n },\n },\n };\n const serverOptions: ServerOptions = {\n run,\n debug: run,\n };\n\n // If the extension is launched in debug mode then the debug server options are used\n // Otherwise the run options are used\n // Options to control the language client\n let clientOptions: LanguageClientOptions = {\n // Register the server for plain text documents\n documentSelector: [\n 'typescript',\n 'javascript',\n 'typescriptreact',\n 'javascriptreact',\n 'vue',\n 'svelte',\n ].map((lang) => ({\n language: lang,\n scheme: 'file',\n })),\n synchronize: {\n // Notify the server about file config changes in the workspace\n fileEvents: fileWatchers,\n },\n outputChannel,\n traceOutputChannel: outputChannel,\n middleware: {\n workspace: {\n configuration: (params: ConfigurationParams) => {\n return params.items.map(item => {\n if (item.section !== 'oxc_language_server') {\n return null;\n }\n\n return configService.rootServerConfig.toLanguageServerConfig() ?? null;\n });\n },\n },\n },\n };\n\n // Create the language client and start the client.\n client = new LanguageClient(\n languageClientName,\n serverOptions,\n clientOptions,\n );\n\n const onNotificationDispose = client.onNotification(ShowMessageNotification.type, (params) => {\n switch (params.type) {\n case MessageType.Debug:\n outputChannel.debug(params.message);\n break;\n case MessageType.Log:\n outputChannel.info(params.message);\n break;\n case MessageType.Info:\n window.showInformationMessage(params.message);\n break;\n case MessageType.Warning:\n window.showWarningMessage(params.message);\n break;\n case MessageType.Error:\n window.showErrorMessage(params.message);\n break;\n default:\n outputChannel.info(params.message);\n }\n });\n\n context.subscriptions.push(onNotificationDispose);\n\n const onDeleteFilesDispose = workspace.onDidDeleteFiles((event) => {\n for (const fileUri of event.files) {\n client?.diagnostics?.delete(fileUri);\n }\n });\n\n context.subscriptions.push(onDeleteFilesDispose);\n\n configService.onConfigChange = async function onConfigChange(event) {\n let settings = this.rootServerConfig.toLanguageServerConfig();\n updateStatsBar(this.vsCodeConfig.enable);\n\n if (client === undefined) {\n return;\n }\n\n // update the initializationOptions for a possible restart\n client.clientOptions.initializationOptions = { settings };\n\n if (event.affectsConfiguration('oxc.configPath')) {\n client.clientOptions.synchronize = client.clientOptions.synchronize ?? {};\n client.clientOptions.synchronize.fileEvents = createFileEventWatchers(settings.configPath);\n\n if (client.isRunning()) {\n await client.restart();\n }\n } else if (client.isRunning()) {\n await client.sendNotification('workspace/didChangeConfiguration', { settings });\n }\n };\n\n function updateStatsBar(enable: boolean) {\n if (!myStatusBarItem) {\n myStatusBarItem = window.createStatusBarItem(\n StatusBarAlignment.Right,\n 100,\n );\n myStatusBarItem.command = OxcCommands.ToggleEnable;\n context.subscriptions.push(myStatusBarItem);\n myStatusBarItem.show();\n }\n let bgColor = new ThemeColor(\n enable\n ? 'statusBarItem.activeBackground'\n : 'statusBarItem.warningBackground',\n );\n myStatusBarItem.text =oxc: ${enable ? '$(check-all)' : '$(check)'};\n\n myStatusBarItem.backgroundColor = bgColor;\n }\n\n updateStatsBar(configService.vsCodeConfig.enable);\n if (configService.vsCodeConfig.enable) {\n await client.start();\n }\n}\n\nexport async function deactivate(): Promise {\n if (!client) {\n return undefined;\n }\n await client.stop();\n client = undefined;\n}\n\n// FileSystemWatcher are not ready on the start and can take some seconds on bigger repositories\nfunction createFileEventWatchers(configRelativePath: string | null): FileSystemWatcher[] {\n // cleanup old watchers\n globalWatchers.forEach((watcher) => watcher.dispose());\n globalWatchers.length = 0;\n\n // create new watchers\n let localWatchers;\n if (configRelativePath !== null) {\n localWatchers = (workspace.workspaceFolders || []).map((workspaceFolder) =>\n workspace.createFileSystemWatcher(new RelativePattern(workspaceFolder, configRelativePath))\n );\n } else {\n localWatchers = [\n workspace.createFileSystemWatcher(**/${oxlintConfigFileName}),\n ];\n }\n\n // assign watchers to global variable, so we can cleanup them on next call\n globalWatchers.push(...localWatchers);\n\n return localWatchers;\n}\n"}
}
2025-05-07 14:32:20.353 [info] [Trace - 2:32:20 PM] Received request 'workspace/configuration - (0)'.
2025-05-07 14:32:20.353 [info] Params: {
"items": [
{
"scopeUri": "file:///home/sysix/dev/oxc",
"section": "oxc_language_server"
}
]
}
2025-05-07 14:32:20.353 [info] [Trace - 2:32:20 PM] Sending response 'workspace/configuration - (0)'. Processing request took 0ms
2025-05-07 14:32:20.353 [info] Result: [
{
"run": "onType",
"configPath": null,
"flags": {}
}
]
2025-05-07 14:32:20.353 [info] [Trace - 2:32:20 PM] Sending request 'textDocument/codeAction - (1)'.
2025-05-07 14:32:20.353 [info] Params: {
"textDocument": {
"uri": "file:///home/sysix/dev/oxc/editors/vscode/client/extension.ts"
},
"range": {
"start": {
"line": 236,
"character": 18
},
"end": {
"line": 236,
"character": 18
}
},
"context": {
"diagnostics": [],
"triggerKind": 2
}
}
2025-05-07 14:32:20.358 [info] [Trace - 2:32:20 PM] Sending notification '$/cancelRequest'.
2025-05-07 14:32:20.358 [info] Params: {
"id": 1
}
2025-05-07 14:32:20.394 [info] [Trace - 2:32:20 PM] Sending request 'textDocument/codeAction - (2)'.
2025-05-07 14:32:20.394 [info] Params: {
"textDocument": {
"uri": "file:///home/sysix/dev/oxc/editors/vscode/client/extension.ts"
},
"range": {
"start": {
"line": 236,
"character": 18
},
"end": {
"line": 236,
"character": 18
}
},
"context": {
"diagnostics": [],
"triggerKind": 2
}
}
2025-05-07 14:32:20.857 [info] [Trace - 2:32:20 PM] Sending notification '$/cancelRequest'.
2025-05-07 14:32:20.857 [info] Params: {
"id": 2
}
2025-05-07 14:32:20.868 [info] [Trace - 2:32:20 PM] Sending notification '$/setTrace'.
2025-05-07 14:32:20.868 [info] Params: {
"value": "verbose"
}
2025-05-07 14:32:20.874 [info] [Trace - 2:32:20 PM] Sending notification '$/setTrace'.
2025-05-07 14:32:20.874 [info] Params: {
"value": "verbose"
}
2025-05-07 14:32:20.881 [info] [Trace - 2:32:20 PM] Sending notification '$/setTrace'.
2025-05-07 14:32:20.881 [info] Params: {
"value": "verbose"
}
2025-05-07 14:32:20.901 [info] [2025-05-07T12:32:20Z INFO oxc_language_server] linting file file:///home/sysix/dev/oxc/editors/vscode/client/extension.ts
[2025-05-07T12:32:20Z INFO oxc_language_server] linting file succedded file:///home/sysix/dev/oxc/editors/vscode/client/extension.ts
2025-05-07 14:32:20.902 [info] [Trace - 2:32:20 PM] Sending request 'textDocument/codeAction - (3)'.
2025-05-07 14:32:20.902 [info] Params: {
"textDocument": {
"uri": "file:///home/sysix/dev/oxc/editors/vscode/client/extension.ts"
},
"range": {
"start": {
"line": 236,
"character": 18
},
"end": {
"line": 236,
"character": 18
}
},
"context": {
"diagnostics": [],
"triggerKind": 2
}
}
2025-05-07 14:32:20.902 [info] [Trace - 2:32:20 PM] Sending request 'textDocument/codeAction - (4)'.
2025-05-07 14:32:20.902 [info] Params: {
"textDocument": {
"uri": "file:///home/sysix/dev/oxc/editors/vscode/client/extension.ts"
},
"range": {
"start": {
"line": 236,
"character": 18
},
"end": {
"line": 236,
"character": 18
}
},
"context": {
"diagnostics": [],
"triggerKind": 2
}
}
2025-05-07 14:32:20.903 [info] [Trace - 2:32:20 PM] Sending notification '$/cancelRequest'.
2025-05-07 14:32:20.903 [info] Params: {
"id": 3
}
2025-05-07 14:32:20.907 [info] [Trace - 2:32:20 PM] Received notification 'textDocument/publishDiagnostics'.
2025-05-07 14:32:20.907 [info] Params: {
"uri": "file:///home/sysix/dev/oxc/editors/vscode/client/extension.ts",
"diagnostics": [],
"version": 1
}