diff --git a/src/document.ts b/src/document.ts index f941f258..c1b96046 100644 --- a/src/document.ts +++ b/src/document.ts @@ -5,10 +5,12 @@ * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 */ +import { extname } from 'node:path'; import { URI } from 'vscode-uri'; import * as lsp from 'vscode-languageserver'; import { TextDocument } from 'vscode-languageserver-textdocument'; import * as languageModeIds from './configuration/languageIds.js'; +import { LspClient } from './lsp-client.js'; import { CommandTypes, type ts } from './ts-protocol.js'; import { ClientCapability, type ITypeScriptServiceClient } from './typescriptService.js'; import API from './utils/api.js'; @@ -26,6 +28,24 @@ function mode2ScriptKind(mode: string): ts.server.protocol.ScriptKindName | unde return undefined; } +/** + * @deprecated Remove in next major. + */ +function getModeFromFileUri(uri: string): string | undefined { + const extension = extname(uri).toUpperCase(); + switch (extension) { + case '.TS': + return languageModeIds.typescript; + case '.TSX': + return languageModeIds.typescriptreact; + case '.JS': + return languageModeIds.javascript; + case '.JSX': + return languageModeIds.javascriptreact; + } + return undefined; +} + class PendingDiagnostics extends ResourceMap { public getOrderedFileSet(): ResourceMap { const orderedResources = Array.from(this.entries()) @@ -203,6 +223,7 @@ export class LspDocument { export class LspDocuments { private readonly client: ITypeScriptServiceClient; + private readonly lspClient: LspClient; private _validateJavaScript = true; private _validateTypeScript = true; @@ -216,9 +237,11 @@ export class LspDocuments { constructor( client: ITypeScriptServiceClient, + lspClient: LspClient, onCaseInsensitiveFileSystem: boolean, ) { this.client = client; + this.lspClient = lspClient; this.modeIds = new Set(languageModeIds.jsTsLanguageModes); const pathNormalizer = (path: URI) => this.client.toTsFilePath(path.toString()); @@ -251,7 +274,16 @@ export class LspDocuments { public openTextDocument(textDocument: lsp.TextDocumentItem): boolean { if (!this.modeIds.has(textDocument.languageId)) { - return false; + const detectedLanguageId = getModeFromFileUri(textDocument.uri); + if (detectedLanguageId) { + this.lspClient.logMessage({ + type: lsp.MessageType.Warning, + message: `Invalid langaugeId "${textDocument.languageId}" provided for uri "${textDocument.uri}". Correcting to "${detectedLanguageId}"`, + }); + textDocument.languageId = detectedLanguageId; + } else { + return false; + } } const resource = textDocument.uri; const filepath = this.client.toTsFilePath(resource); diff --git a/src/lsp-server.spec.ts b/src/lsp-server.spec.ts index d72948c1..f4627fd8 100644 --- a/src/lsp-server.spec.ts +++ b/src/lsp-server.spec.ts @@ -2423,3 +2423,24 @@ describe('linked editing', () => { ]); }); }); + +describe('handles invalid languageId', () => { + it('simple test', async () => { + const textDocument = { + uri: uri('foo.tsx'), + languageId: 'tsx', + version: 1, + text: 'let bar =
', + }; + await openDocumentAndWaitForDiagnostics(server, textDocument); + const position = positionAfter(textDocument, ' pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy