Skip to content

Commit 2558440

Browse files
kyliauKeen Yee Liau
authored andcommitted
feat: Backwards compat with new TS LS interface
angular/angular#32115 updates the interface for ng.getDiagnostics() to return ts.Diagnostics[] whereas angular/angular#32115 updates the interface for ng.getCompletions() to return ts.CompletionInfo. This PR makes the extension backwards compatible with the older interface.
1 parent e769a76 commit 2558440

File tree

3 files changed

+65
-14
lines changed

3 files changed

+65
-14
lines changed

server/src/editorServices.ts

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1528,11 +1528,23 @@ export class ProjectService {
15281528

15291529
// Update Angular summaries
15301530
let start = Date.now();
1531-
for (let project of this.configuredProjects) {
1532-
project.compilerService.ngHost.updateAnalyzedModules();
1533-
}
1534-
for (let project of this.inferredProjects) {
1535-
project.compilerService.ngHost.updateAnalyzedModules();
1531+
for (const project of this.configuredProjects) {
1532+
const ngHost = project.compilerService.ngHost;
1533+
if (ngHost.updateAnalyzedModules) {
1534+
// For backwards compatibility
1535+
ngHost.updateAnalyzedModules();
1536+
} else {
1537+
ngHost.getAnalyzedModules();
1538+
}
1539+
}
1540+
for (const project of this.inferredProjects) {
1541+
const ngHost = project.compilerService.ngHost;
1542+
if (ngHost.updateAnalyzedModules) {
1543+
// For backwards compatibility
1544+
ngHost.updateAnalyzedModules();
1545+
} else {
1546+
ngHost.getAnalyzedModules();
1547+
}
15361548
}
15371549
this.log(`updated: ng - ${Date.now() - start}ms`, "Info");
15381550

server/src/errors.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {DiagnosticSeverity, IConnection, Range, TextDocumentIdentifier} from 'vscode-languageserver';
22
import {TextDocuments} from './documents';
33
import {DiagnosticMessageChain} from '@angular/language-service/src/types';
4+
import * as ts from 'typescript';
45

56
export class ErrorCollector {
67
private timer: NodeJS.Timer | undefined;
@@ -31,7 +32,11 @@ export class ErrorCollector {
3132
const {fileName, service} = this.documents.getServiceInfo(document);
3233
if (service) {
3334
const diagnostics = service.getDiagnostics(fileName);
34-
if (diagnostics) {
35+
if (!diagnostics || !diagnostics.length) {
36+
return;
37+
}
38+
if (diagnostics[0].message) {
39+
// Backwards compatibility with old ng.Diagnostic[]
3540
const offsets = ([] as number[]).concat(...diagnostics.map(d => [d.span.start, d.span.end]));
3641
const positions = this.documents.offsetsToPositions(document, offsets);
3742
const ranges: Range[] = [];
@@ -48,6 +53,28 @@ export class ErrorCollector {
4853
}))
4954
});
5055
}
56+
else {
57+
const tsDiagnostics = diagnostics as unknown as ts.Diagnostic[];
58+
const offsets = ([] as number[]).concat(...tsDiagnostics.map(d => {
59+
const start = d.start || 0;
60+
const end = start + (d.length || 0);
61+
return [start, end];
62+
}));
63+
const positions = this.documents.offsetsToPositions(document, offsets);
64+
const ranges: Range[] = [];
65+
for (let i = 0; i < positions.length; i += 2) {
66+
ranges.push(Range.create(positions[i], positions[i+1]));
67+
}
68+
this.connection.sendDiagnostics({
69+
uri: document.uri,
70+
diagnostics: tsDiagnostics.map((diagnostic, i) => ({
71+
range: ranges[i],
72+
message: ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'),
73+
severity: DiagnosticSeverity.Error,
74+
source: 'Angular'
75+
}))
76+
});
77+
}
5178
}
5279
}
5380
}

server/src/server.ts

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -116,17 +116,20 @@ function insertTextOf(completion: Completion): string {
116116
}
117117

118118
// This handler provides the initial list of the completion items.
119-
connection.onCompletion((textDocumentPosition: lsp.TextDocumentPositionParams): lsp.CompletionItem[] => {
120-
const {fileName, service, offset, languageId} = documents.getServiceInfo(textDocumentPosition.textDocument,
121-
textDocumentPosition.position)
119+
connection.onCompletion((params: lsp.TextDocumentPositionParams): lsp.CompletionItem[] => {
120+
const {position, textDocument} = params;
121+
const {fileName, service, offset, languageId} = documents.getServiceInfo(textDocument, position);
122122
if (fileName && service && offset != null) {
123123
let result = service.getCompletionsAt(fileName, offset);
124-
if (result && languageId == 'html') {
125-
// The HTML elements are provided by the HTML service when the text type is 'html'.
126-
result = result.filter(completion => completion.kind != 'element');
124+
if (!result) {
125+
return;
127126
}
128-
if (result) {
129-
const replaceRange = getReplaceRange(textDocumentPosition.textDocument, offset);
127+
if (Array.isArray(result)) { // old ng.Completion[]
128+
if (languageId == 'html') {
129+
// The HTML elements are provided by the HTML service when the text type is 'html'.
130+
result = result.filter(completion => completion.kind != 'element');
131+
}
132+
const replaceRange = getReplaceRange(params.textDocument, offset);
130133
return result.map(completion => ({
131134
label: completion.name,
132135
kind: compiletionKindToCompletionItemKind(completion.kind),
@@ -136,6 +139,15 @@ connection.onCompletion((textDocumentPosition: lsp.TextDocumentPositionParams):
136139
insertText: insertTextOf(completion)
137140
}));
138141
}
142+
const entries = (result as ts.CompletionInfo).entries;
143+
return entries.map(entry => {
144+
const item = lsp.CompletionItem.create(entry.name);
145+
item.kind = compiletionKindToCompletionItemKind(entry.kind);
146+
item.detail = entry.kind;
147+
item.sortText = entry.sortText;
148+
item.textEdit = lsp.TextEdit.insert(position, entry.name);
149+
return item;
150+
});
139151
}
140152
});
141153

0 commit comments

Comments
 (0)