diff --git a/packages/typescript/lib/plugins/semantic.ts b/packages/typescript/lib/plugins/semantic.ts index ce540e09..6b520695 100644 --- a/packages/typescript/lib/plugins/semantic.ts +++ b/packages/typescript/lib/plugins/semantic.ts @@ -208,7 +208,6 @@ export function create( return context.documents.get(uri, sourceFile.languageId, sourceFile.snapshot); } } - throw new Error(`getTextDocument: uri not found: ${uri}`); }, }; const getCodeActions = codeActions.register(ctx); @@ -278,7 +277,7 @@ export function create( return item; } const { fileName, offset } = data; - const document = ctx.getTextDocument(data.uri); + const document = ctx.getTextDocument(data.uri)!; const [formatOptions, preferences] = await Promise.all([ getFormatCodeSettings(ctx, document), getUserPreferences(ctx, document), @@ -506,7 +505,7 @@ export function create( async provideCallHierarchyIncomingCalls(item, token) { return await worker(token, () => { - const document = ctx.getTextDocument(item.uri); + const document = ctx.getTextDocument(item.uri)!; const fileName = ctx.uriToFileName(item.uri); const offset = document.offsetAt(item.selectionRange.start); const calls = safeCall(() => ctx.languageService.provideCallHierarchyIncomingCalls(fileName, offset)); @@ -520,7 +519,7 @@ export function create( async provideCallHierarchyOutgoingCalls(item, token) { return await worker(token, () => { - const document = ctx.getTextDocument(item.uri); + const document = ctx.getTextDocument(item.uri)!; const fileName = ctx.uriToFileName(item.uri); const offset = document.offsetAt(item.selectionRange.start); const calls = safeCall(() => ctx.languageService.provideCallHierarchyOutgoingCalls(fileName, offset)); @@ -698,14 +697,14 @@ export function create( } return items .filter(item => item.containerName || item.kind !== 'alias') - .map(item => convertNavigateToItem(item, ctx.getTextDocument(ctx.fileNameToUri(item.fileName)))) + .map(item => convertNavigateToItem(item, ctx.getTextDocument(ctx.fileNameToUri(item.fileName))!)) .filter(notEmpty); }); }, provideFileRenameEdits(oldUri, newUri, token) { return worker(token, async () => { - const document = ctx.getTextDocument(oldUri); + const document = ctx.getTextDocument(oldUri)!; const [formatOptions, preferences] = await Promise.all([ getFormatCodeSettings(ctx, document), getUserPreferences(ctx, document), diff --git a/packages/typescript/lib/semanticFeatures/codeActionResolve.ts b/packages/typescript/lib/semanticFeatures/codeActionResolve.ts index 5102ee0b..8b50d2e6 100644 --- a/packages/typescript/lib/semanticFeatures/codeActionResolve.ts +++ b/packages/typescript/lib/semanticFeatures/codeActionResolve.ts @@ -12,7 +12,7 @@ export function register(ctx: SharedContext) { return async (codeAction: vscode.CodeAction) => { const data: Data = codeAction.data; - const document = ctx.getTextDocument(data.uri); + const document = ctx.getTextDocument(data.uri)!; const [formatOptions, preferences] = await Promise.all([ getFormatCodeSettings(ctx, document), getUserPreferences(ctx, document), diff --git a/packages/typescript/lib/semanticFeatures/types.ts b/packages/typescript/lib/semanticFeatures/types.ts index aa4ba6d5..950f3e72 100644 --- a/packages/typescript/lib/semanticFeatures/types.ts +++ b/packages/typescript/lib/semanticFeatures/types.ts @@ -5,7 +5,7 @@ import type { TextDocument } from 'vscode-languageserver-textdocument'; export type SharedContext = ServiceContext & { languageServiceHost: ts.LanguageServiceHost; languageService: ts.LanguageService; - getTextDocument: (uri: string) => TextDocument; + getTextDocument: (uri: string) => TextDocument | undefined; uriToFileName: (uri: string) => string; fileNameToUri: (fileName: string) => string; }; diff --git a/packages/typescript/lib/utils/lspConverters.ts b/packages/typescript/lib/utils/lspConverters.ts index c1650634..a052fba8 100644 --- a/packages/typescript/lib/utils/lspConverters.ts +++ b/packages/typescript/lib/utils/lspConverters.ts @@ -16,7 +16,7 @@ export function convertDiagnostic( diag: ts.Diagnostic, document: TextDocument, fileNameToUri: (fileName: string) => string, - getTextDocument: (uri: string) => TextDocument, + getTextDocument: (uri: string) => TextDocument | undefined, ): vscode.Diagnostic | undefined { if (diag.start === undefined) { @@ -61,7 +61,7 @@ export function convertDiagnostic( function convertDiagnosticRelatedInformation( diag: ts.Diagnostic, fileNameToUri: (fileName: string) => string, - getTextDocument: (uri: string) => TextDocument, + getTextDocument: (uri: string) => TextDocument | undefined, ): vscode.DiagnosticRelatedInformation | undefined { if (diag.start === undefined) { @@ -129,7 +129,7 @@ export function applyCompletionEntryDetails( data: ts.CompletionEntryDetails, document: TextDocument, fileNameToUri: (fileName: string) => string, - getTextDocument: (uri: string) => TextDocument, + getTextDocument: (uri: string) => TextDocument | undefined, ) { const { sourceDisplay } = data; if (sourceDisplay) { @@ -613,7 +613,7 @@ export function convertSelectionRange(range: ts.SelectionRange, document: TextDo export function convertFileTextChanges( changes: readonly ts.FileTextChanges[], fileNameToUri: (fileName: string) => string, - getTextDocument: (uri: string) => TextDocument, + getTextDocument: (uri: string) => TextDocument | undefined, ) { const workspaceEdit: vscode.WorkspaceEdit = {}; for (const change of changes) { @@ -642,7 +642,7 @@ export function convertRenameLocations( newText: string, locations: readonly ts.RenameLocation[], fileNameToUri: (fileName: string) => string, - getTextDocument: (uri: string) => TextDocument, + getTextDocument: (uri: string) => TextDocument | undefined, ) { const workspaceEdit: vscode.WorkspaceEdit = {}; for (const location of locations) { @@ -676,7 +676,7 @@ export function convertQuickInfo( info: ts.QuickInfo, document: TextDocument, fileNameToUri: (fileName: string) => string, - getTextDocument: (uri: string) => TextDocument, + getTextDocument: (uri: string) => TextDocument | undefined, ): vscode.Hover { const parts: string[] = []; const displayString = ts.displayPartsToString(info.displayParts); @@ -820,7 +820,7 @@ function adjustFoldingEnd(start: vscode.Position, end: vscode.Position, document // formatting -export function convertTextChange(edit: ts.TextChange, document: TextDocument): vscode.TextEdit { +export function convertTextChange(edit: ts.TextChange, document: TextDocument | undefined): vscode.TextEdit { return { range: convertTextSpan(edit.span, document), newText: edit.newText, @@ -922,7 +922,13 @@ export function convertDocumentSpantoLocationLink(documentSpan: ts.DocumentSpan, }; } -export function convertTextSpan(textSpan: ts.TextSpan, document: TextDocument): vscode.Range { +export function convertTextSpan(textSpan: ts.TextSpan, document: TextDocument | undefined): vscode.Range { + if (!document) { + return { + start: { line: 0, character: 0 }, + end: { line: 0, character: 0 }, + }; + } return { start: document.positionAt(textSpan.start), end: document.positionAt(textSpan.start + textSpan.length), diff --git a/packages/typescript/lib/utils/previewer.ts b/packages/typescript/lib/utils/previewer.ts index 043ef131..94648f27 100644 --- a/packages/typescript/lib/utils/previewer.ts +++ b/packages/typescript/lib/utils/previewer.ts @@ -27,7 +27,7 @@ function processInlineTags(text: string): string { function getTagBodyText( tag: ts.server.protocol.JSDocTagInfo, fileNameToUri: (fileName: string) => string, - getTextDocument: (uri: string) => TextDocument, + getTextDocument: (uri: string) => TextDocument | undefined, ): string | undefined { if (!tag.text) { return undefined; @@ -70,7 +70,7 @@ function getTagBodyText( function getTagDocumentation( tag: ts.server.protocol.JSDocTagInfo, fileNameToUri: (fileName: string) => string, - getTextDocument: (uri: string) => TextDocument, + getTextDocument: (uri: string) => TextDocument | undefined, ): string | undefined { switch (tag.name) { case 'augments': @@ -101,7 +101,7 @@ function getTagDocumentation( export function plainWithLinks( parts: readonly ts.server.protocol.SymbolDisplayPart[] | string, fileNameToUri: (fileName: string) => string, - getTextDocument: (uri: string) => TextDocument, + getTextDocument: (uri: string) => TextDocument | undefined, ): string { return processInlineTags(convertLinkTags(parts, fileNameToUri, getTextDocument)); } @@ -112,7 +112,7 @@ export function plainWithLinks( function convertLinkTags( parts: readonly ts.server.protocol.SymbolDisplayPart[] | string | undefined, fileNameToUri: (fileName: string) => string, - getTextDocument: (uri: string) => TextDocument, + getTextDocument: (uri: string) => TextDocument | undefined, ): string { if (!parts) { return ''; @@ -138,19 +138,34 @@ function convertLinkTags( textSpan: { start: number, length: number; }, }; const fileDoc = getTextDocument(fileNameToUri(_target.fileName)); - const start = fileDoc.positionAt(_target.textSpan.start); - const end = fileDoc.positionAt(_target.textSpan.start + _target.textSpan.length); - target = { - file: _target.fileName, - start: { - line: start.line + 1, - offset: start.character + 1, - }, - end: { - line: end.line + 1, - offset: end.character + 1, - }, - }; + if (fileDoc) { + const start = fileDoc.positionAt(_target.textSpan.start); + const end = fileDoc.positionAt(_target.textSpan.start + _target.textSpan.length); + target = { + file: _target.fileName, + start: { + line: start.line + 1, + offset: start.character + 1, + }, + end: { + line: end.line + 1, + offset: end.character + 1, + }, + }; + } + else { + target = { + file: _target.fileName, + start: { + line: 1, + offset: 1, + }, + end: { + line: 1, + offset: 1, + }, + }; + } } if (target) { @@ -192,7 +207,7 @@ function convertLinkTags( export function tagsMarkdownPreview( tags: readonly ts.JSDocTagInfo[], fileNameToUri: (fileName: string) => string, - getTextDocument: (uri: string) => TextDocument, + getTextDocument: (uri: string) => TextDocument | undefined, ): string { return tags.map(tag => getTagDocumentation(tag, fileNameToUri, getTextDocument)).join(' \n\n'); } @@ -201,7 +216,7 @@ export function markdownDocumentation( documentation: ts.server.protocol.SymbolDisplayPart[] | string | undefined, tags: ts.JSDocTagInfo[] | undefined, fileNameToUri: (fileName: string) => string, - getTextDocument: (uri: string) => TextDocument, + getTextDocument: (uri: string) => TextDocument | undefined, ): string { return addMarkdownDocumentation('', documentation, tags, fileNameToUri, getTextDocument); } @@ -211,7 +226,7 @@ export function addMarkdownDocumentation( documentation: ts.server.protocol.SymbolDisplayPart[] | string | undefined, tags: ts.JSDocTagInfo[] | undefined, fileNameToUri: (fileName: string) => string, - getTextDocument: (uri: string) => TextDocument, + getTextDocument: (uri: string) => TextDocument | undefined, ): string { if (documentation) { out += plainWithLinks(documentation, fileNameToUri, getTextDocument);