Skip to content

Commit d15f6ee

Browse files
authored
Merge pull request #244074 from nknguyenhc/goto-html
Goto definition for built-in symbols in HTML script
2 parents 2138f12 + 165c109 commit d15f6ee

File tree

3 files changed

+60
-14
lines changed

3 files changed

+60
-14
lines changed

extensions/html-language-features/server/src/htmlServer.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@ import {
77
Connection, TextDocuments, InitializeParams, InitializeResult, RequestType,
88
DocumentRangeFormattingRequest, Disposable, ServerCapabilities,
99
ConfigurationRequest, ConfigurationParams, DidChangeWorkspaceFoldersNotification,
10-
DocumentColorRequest, ColorPresentationRequest, TextDocumentSyncKind, NotificationType, RequestType0, DocumentFormattingRequest, FormattingOptions, TextEdit
10+
DocumentColorRequest, ColorPresentationRequest, TextDocumentSyncKind, NotificationType, RequestType0, DocumentFormattingRequest, FormattingOptions, TextEdit,
11+
TextDocumentContentRequest
1112
} from 'vscode-languageserver';
1213
import {
1314
getLanguageModes, LanguageModes, Settings, TextDocument, Position, Diagnostic, WorkspaceFolder, ColorInformation,
14-
Range, DocumentLink, SymbolInformation, TextDocumentIdentifier, isCompletionItemData
15+
Range, DocumentLink, SymbolInformation, TextDocumentIdentifier, isCompletionItemData, FILE_PROTOCOL
1516
} from './modes/languageModes';
1617

1718
import { format } from './modes/formatting';
@@ -213,6 +214,9 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
213214
documentSelector: null,
214215
interFileDependencies: false,
215216
workspaceDiagnostics: false
217+
},
218+
workspace: {
219+
textDocumentContent: { schemes: [FILE_PROTOCOL] }
216220
}
217221
};
218222
return { capabilities };
@@ -584,6 +588,18 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
584588
});
585589
});
586590

591+
connection.onRequest(TextDocumentContentRequest.type, (params, token) => {
592+
return runSafe(runtime, async () => {
593+
for (const languageMode of languageModes.getAllModes()) {
594+
const content = await languageMode.getTextDocumentContent?.(params.uri);
595+
if (content) {
596+
return { text: content };
597+
}
598+
}
599+
return null;
600+
}, null, `Error while computing text document content for ${params.uri}`, token);
601+
});
602+
587603
// Listen on the connection
588604
connection.listen();
589605
}

extensions/html-language-features/server/src/modes/javascriptMode.ts

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
SymbolInformation, SymbolKind, CompletionItem, Location, SignatureHelp, SignatureInformation, ParameterInformation,
99
Definition, TextEdit, TextDocument, Diagnostic, DiagnosticSeverity, Range, CompletionItemKind, Hover,
1010
DocumentHighlight, DocumentHighlightKind, CompletionList, Position, FormattingOptions, FoldingRange, FoldingRangeKind, SelectionRange,
11-
LanguageMode, Settings, SemanticTokenData, Workspace, DocumentContext, CompletionItemData, isCompletionItemData
11+
LanguageMode, Settings, SemanticTokenData, Workspace, DocumentContext, CompletionItemData, isCompletionItemData, FILE_PROTOCOL, DocumentUri
1212
} from './languageModes';
1313
import { getWordAtText, isWhitespaceOnly, repeat } from '../utils/strings';
1414
import { HTMLDocumentRegions } from './embeddedSupport';
@@ -77,18 +77,24 @@ function getLanguageServiceHost(scriptKind: ts.ScriptKind) {
7777

7878
}
7979
};
80-
return ts.createLanguageService(host);
80+
return {
81+
service: ts.createLanguageService(host),
82+
loadLibrary: libs.loadLibrary,
83+
};
8184
});
8285
return {
8386
async getLanguageService(jsDocument: TextDocument): Promise<ts.LanguageService> {
8487
currentTextDocument = jsDocument;
85-
return jsLanguageService;
88+
return (await jsLanguageService).service;
8689
},
8790
getCompilationSettings() {
8891
return compilerOptions;
8992
},
93+
async loadLibrary(fileName: string) {
94+
return (await jsLanguageService).loadLibrary(fileName);
95+
},
9096
dispose() {
91-
jsLanguageService.then(s => s.dispose());
97+
jsLanguageService.then(s => s.service.dispose());
9298
}
9399
};
94100
}
@@ -104,6 +110,8 @@ export function getJavaScriptMode(documentRegions: LanguageModelCache
104110
const host = getLanguageServiceHost(languageId === 'javascript' ? ts.ScriptKind.JS : ts.ScriptKind.TS);
105111
const globalSettings: Settings = {};
106112

113+
const libParentUri = `${FILE_PROTOCOL}://${languageId}/libs/`;
114+
107115
function updateHostSettings(settings: Settings) {
108116
const hostSettings = host.getCompilationSettings();
109117
hostSettings.experimentalDecorators = settings?.['js/ts']?.implicitProjectConfig?.experimentalDecorators;
@@ -302,12 +310,25 @@ export function getJavaScriptMode(documentRegions: LanguageModelCache
302310
const jsLanguageService = await host.getLanguageService(jsDocument);
303311
const definition = jsLanguageService.getDefinitionAtPosition(jsDocument.uri, jsDocument.offsetAt(position));
304312
if (definition) {
305-
return definition.filter(d => d.fileName === jsDocument.uri).map(d => {
306-
return {
307-
uri: document.uri,
308-
range: convertRange(jsDocument, d.textSpan)
309-
};
310-
});
313+
return (await Promise.all(definition.map(async d => {
314+
if (d.fileName === jsDocument.uri) {
315+
return {
316+
uri: document.uri,
317+
range: convertRange(jsDocument, d.textSpan)
318+
};
319+
} else {
320+
const libUri = libParentUri + d.fileName;
321+
const content = await host.loadLibrary(d.fileName);
322+
if (!content) {
323+
return undefined;
324+
}
325+
const libDocument = TextDocument.create(libUri, languageId, 1, content);
326+
return {
327+
uri: libUri,
328+
range: convertRange(libDocument, d.textSpan)
329+
};
330+
}
331+
}))).filter(d => !!d);
311332
}
312333
return null;
313334
},
@@ -402,6 +423,12 @@ export function getJavaScriptMode(documentRegions: LanguageModelCache
402423
getSemanticTokenLegend(): { types: string[]; modifiers: string[] } {
403424
return getSemanticTokenLegend();
404425
},
426+
async getTextDocumentContent(documentUri: DocumentUri): Promise<string | undefined> {
427+
if (documentUri.startsWith(libParentUri)) {
428+
return host.loadLibrary(documentUri.substring(libParentUri.length));
429+
}
430+
return undefined;
431+
},
405432
dispose() {
406433
host.dispose();
407434
jsDocuments.dispose();

extensions/html-language-features/server/src/modes/languageModes.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414
Color, ColorInformation, ColorPresentation, WorkspaceEdit,
1515
WorkspaceFolder
1616
} from 'vscode-languageserver';
17-
import { TextDocument } from 'vscode-languageserver-textdocument';
17+
import { DocumentUri, TextDocument } from 'vscode-languageserver-textdocument';
1818

1919
import { getLanguageModelCache, LanguageModelCache } from '../languageModelCache';
2020
import { getCSSMode } from './cssMode';
@@ -34,7 +34,7 @@ export {
3434

3535
export { ClientCapabilities, DocumentContext, LanguageService, HTMLDocument, HTMLFormatConfiguration, TokenType } from 'vscode-html-languageservice';
3636

37-
export { TextDocument } from 'vscode-languageserver-textdocument';
37+
export { TextDocument, DocumentUri } from 'vscode-languageserver-textdocument';
3838

3939
export interface Settings {
4040
readonly css?: any;
@@ -89,6 +89,7 @@ export interface LanguageMode {
8989
onDocumentRemoved(document: TextDocument): void;
9090
getSemanticTokens?(document: TextDocument): Promise<SemanticTokenData[]>;
9191
getSemanticTokenLegend?(): { types: string[]; modifiers: string[] };
92+
getTextDocumentContent?(uri: DocumentUri): Promise<string | undefined>;
9293
dispose(): void;
9394
}
9495

@@ -108,6 +109,8 @@ export interface LanguageModeRange extends Range {
108109
attributeValue?: boolean;
109110
}
110111

112+
export const FILE_PROTOCOL = 'html-server';
113+
111114
export function getLanguageModes(supportedLanguages: { [languageId: string]: boolean }, workspace: Workspace, clientCapabilities: ClientCapabilities, requestService: FileSystemProvider): LanguageModes {
112115
const htmlLanguageService = getHTMLLanguageService({ clientCapabilities, fileSystemProvider: requestService });
113116
const cssLanguageService = getCSSLanguageService({ clientCapabilities, fileSystemProvider: requestService });

0 commit comments

Comments
 (0)