Skip to content

Commit e666a0b

Browse files
committed
fix(ls): parse uri's correctly and ignore unknown protocols
1 parent 622cdfe commit e666a0b

File tree

2 files changed

+41
-34
lines changed

2 files changed

+41
-34
lines changed

server/src/documents.ts

Lines changed: 40 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import * as fs from 'fs';
22
import * as ts from 'typescript';
3+
import * as url from 'url';
34

45
import {LanguageService} from '@angular/language-service';
56

@@ -100,27 +101,22 @@ class ProjectLoggerImpl implements ProjectLogger {
100101
}
101102
}
102103

103-
function removePrefix(value: string, ...prefixes: string[]): string {
104-
for (const prefix of prefixes) {
105-
if (value && value.startsWith(prefix)) {
106-
return value.substr(prefix.length);
107-
}
104+
function uriToFileName(uri: string): string {
105+
const parsedUrl = url.parse(uri);
106+
switch (parsedUrl.protocol) {
107+
case 'file:':
108+
case 'private:':
109+
return parsedUrl.path
108110
}
109-
return value;
110111
}
111112

112-
const privateProtocol = "private:";
113113
const fileProtocol = "file://";
114-
function uriToFileName(uri: string): string {
115-
return removePrefix(decodeURI(uri), fileProtocol, privateProtocol);
116-
}
117-
118114
function fileNameToUri(fileName: string): string {
119115
return encodeURI(fileProtocol + fileName);
120116
}
121117

122118
export interface NgServiceInfo {
123-
fileName: string;
119+
fileName?: string;
124120
languageId?: string;
125121
service?: LanguageService;
126122
offset?: number;
@@ -155,17 +151,21 @@ export class TextDocuments {
155151
connection.onDidOpenTextDocument(event => {
156152
// An interersting text document was opened in the client. Inform TypeScirpt's project services about it.
157153
const file = uriToFileName(event.textDocument.uri);
158-
const { configFileName, configFileErrors } = this.projectService.openClientFile(file, event.textDocument.text);
159-
if (configFileErrors && configFileErrors.length) {
160-
// TODO: Report errors
161-
this.logger.msg(`Config errors encountered and need to be reported: ${configFileErrors.length}\n ${configFileErrors.map(error => error.messageText).join('\n ')}`);
154+
if (file) {
155+
const { configFileName, configFileErrors } = this.projectService.openClientFile(file, event.textDocument.text);
156+
if (configFileErrors && configFileErrors.length) {
157+
// TODO: Report errors
158+
this.logger.msg(`Config errors encountered and need to be reported: ${configFileErrors.length}\n ${configFileErrors.map(error => error.messageText).join('\n ')}`);
159+
}
160+
this.languageIds.set(event.textDocument.uri, event.textDocument.languageId);
162161
}
163-
this.languageIds.set(event.textDocument.uri, event.textDocument.languageId);
164162
});
165163

166164
connection.onDidCloseTextDocument(event => {
167165
const file = uriToFileName(event.textDocument.uri);
168-
this.projectService.closeClientFile(file);
166+
if (file) {
167+
this.projectService.closeClientFile(file);
168+
}
169169
});
170170

171171
connection.onDidChangeTextDocument(event => {
@@ -195,16 +195,21 @@ export class TextDocuments {
195195
// If the file is saved, force the content to be reloaded from disk as the content might have changed on save.
196196
this.changeNumber++;
197197
const file = uriToFileName(event.textDocument.uri);
198-
const savedContent = this.host.readFile(file);
199-
this.projectService.closeClientFile(file);
200-
this.projectService.openClientFile(file, savedContent);
201-
this.changeNumber++;
198+
if (file) {
199+
const savedContent = this.host.readFile(file);
200+
this.projectService.closeClientFile(file);
201+
this.projectService.openClientFile(file, savedContent);
202+
this.changeNumber++;
203+
}
202204
});
203205
}
204206

205207
public offsetsToPositions(document: TextDocumentIdentifier, offsets: number[]): Position[] {
206208
const file = uriToFileName(document.uri);
207-
return this.projectService.positionsToLineOffsets(file, offsets).map(lineOffset => Position.create(lineOffset.line - 1, lineOffset.col - 1));
209+
if (file) {
210+
return this.projectService.positionsToLineOffsets(file, offsets).map(lineOffset => Position.create(lineOffset.line - 1, lineOffset.col - 1));
211+
}
212+
return [];
208213
}
209214

210215
public getNgService(document: TextDocumentIdentifier): LanguageService | undefined {
@@ -213,18 +218,20 @@ export class TextDocuments {
213218

214219
public getServiceInfo(document: TextDocumentIdentifier, position?: Position): NgServiceInfo {
215220
const fileName = uriToFileName(document.uri);
216-
const project = this.projectService.getProjectForFile(fileName);
217-
const languageId = this.languageIds.get(document.uri);
218-
if (project) {
219-
const service = project.compilerService.ngService;
220-
if (position) {
221-
// VSCode is 0 based, editor services are 1 based.
222-
const offset = this.projectService.lineOffsetsToPositions(fileName, [{line: position.line + 1, col: position.character + 1}])[0];
223-
return {fileName, service, offset, languageId};
221+
if (fileName) {
222+
const project = this.projectService.getProjectForFile(fileName);
223+
const languageId = this.languageIds.get(document.uri);
224+
if (project) {
225+
const service = project.compilerService.ngService;
226+
if (position) {
227+
// VSCode is 0 based, editor services are 1 based.
228+
const offset = this.projectService.lineOffsetsToPositions(fileName, [{line: position.line + 1, col: position.character + 1}])[0];
229+
return {fileName, service, offset, languageId};
230+
}
231+
return {fileName, service, languageId};
224232
}
225-
return {fileName, service, languageId};
233+
return {fileName, languageId};
226234
}
227-
return {fileName, languageId};
228235
}
229236

230237
public ifUnchanged(f: () => void): () => void {

server/src/server.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ function compiletionKindToCompletionItemKind(kind: string): number {
8484
connection.onCompletion((textDocumentPosition: TextDocumentPositionParams): CompletionItem[] => {
8585
const {fileName, service, offset, languageId} = documents.getServiceInfo(textDocumentPosition.textDocument,
8686
textDocumentPosition.position)
87-
if (service && offset != null) {
87+
if (fileName && service && offset != null) {
8888
let result = service.getCompletionsAt(fileName, offset);
8989
if (result && languageId == 'html') {
9090
// The HTML elements are provided by the HTML service when the text type is 'html'.

0 commit comments

Comments
 (0)