Use decodeSpan more (#16990)

This commit is contained in:
Andy 2017-07-07 10:37:18 -07:00 committed by GitHub
parent ee48c1b4cc
commit dcc3e72636

View File

@ -34,7 +34,7 @@ namespace ts.server {
export class SessionClient implements LanguageService {
private sequence = 0;
private lineMaps: ts.Map<number[]> = ts.createMap<number[]>();
private lineMaps: Map<number[]> = createMap<number[]>();
private messages: string[] = [];
private lastRenameEntry: RenameEntry;
@ -53,7 +53,7 @@ namespace ts.server {
let lineMap = this.lineMaps.get(fileName);
if (!lineMap) {
const scriptSnapshot = this.host.getScriptSnapshot(fileName);
lineMap = ts.computeLineStarts(scriptSnapshot.getText(0, scriptSnapshot.getLength()));
lineMap = computeLineStarts(scriptSnapshot.getText(0, scriptSnapshot.getLength()));
this.lineMaps.set(fileName, lineMap);
}
return lineMap;
@ -61,11 +61,11 @@ namespace ts.server {
private lineOffsetToPosition(fileName: string, lineOffset: protocol.Location, lineMap?: number[]): number {
lineMap = lineMap || this.getLineMap(fileName);
return ts.computePositionOfLineAndCharacter(lineMap, lineOffset.line - 1, lineOffset.offset - 1);
return computePositionOfLineAndCharacter(lineMap, lineOffset.line - 1, lineOffset.offset - 1);
}
private positionToOneBasedLineOffset(fileName: string, position: number): protocol.Location {
const lineOffset = ts.computeLineAndCharacterOfPosition(this.getLineMap(fileName), position);
const lineOffset = computeLineAndCharacterOfPosition(this.getLineMap(fileName), position);
return {
line: lineOffset.line + 1,
offset: lineOffset.character + 1
@ -73,13 +73,7 @@ namespace ts.server {
}
private convertCodeEditsToTextChange(fileName: string, codeEdit: protocol.CodeEdit): ts.TextChange {
const start = this.lineOffsetToPosition(fileName, codeEdit.start);
const end = this.lineOffsetToPosition(fileName, codeEdit.end);
return {
span: ts.createTextSpanFromBounds(start, end),
newText: codeEdit.newText
};
return { span: this.decodeSpan(codeEdit, fileName), newText: codeEdit.newText };
}
private processRequest<T extends protocol.Request>(command: string, args?: any): T {
@ -154,13 +148,10 @@ namespace ts.server {
const request = this.processRequest<protocol.QuickInfoRequest>(CommandNames.Quickinfo, args);
const response = this.processResponse<protocol.QuickInfoResponse>(request);
const start = this.lineOffsetToPosition(fileName, response.body.start);
const end = this.lineOffsetToPosition(fileName, response.body.end);
return {
kind: response.body.kind,
kindModifiers: response.body.kindModifiers,
textSpan: ts.createTextSpanFromBounds(start, end),
textSpan: this.decodeSpan(response.body, fileName),
displayParts: [{ kind: "text", text: response.body.displayString }],
documentation: [{ kind: "text", text: response.body.documentation }],
tags: response.body.tags
@ -192,11 +183,8 @@ namespace ts.server {
entries: response.body.map(entry => {
if (entry.replacementSpan !== undefined) {
const { name, kind, kindModifiers, sortText, replacementSpan} = entry;
const convertedSpan = createTextSpanFromBounds(this.lineOffsetToPosition(fileName, replacementSpan.start),
this.lineOffsetToPosition(fileName, replacementSpan.end));
return { name, kind, kindModifiers, sortText, replacementSpan: convertedSpan };
const { name, kind, kindModifiers, sortText, replacementSpan } = entry;
return { name, kind, kindModifiers, sortText, replacementSpan: this.decodeSpan(replacementSpan, fileName) };
}
return entry as { name: string, kind: ScriptElementKind, kindModifiers: string, sortText: string };
@ -226,28 +214,23 @@ namespace ts.server {
const request = this.processRequest<protocol.NavtoRequest>(CommandNames.Navto, args);
const response = this.processResponse<protocol.NavtoResponse>(request);
return response.body.map(entry => {
const fileName = entry.file;
const start = this.lineOffsetToPosition(fileName, entry.start);
const end = this.lineOffsetToPosition(fileName, entry.end);
return {
name: entry.name,
containerName: entry.containerName || "",
containerKind: entry.containerKind || ScriptElementKind.unknown,
kind: entry.kind,
kindModifiers: entry.kindModifiers,
matchKind: entry.matchKind,
isCaseSensitive: entry.isCaseSensitive,
fileName,
textSpan: ts.createTextSpanFromBounds(start, end)
};
});
return response.body.map(entry => ({
name: entry.name,
containerName: entry.containerName || "",
containerKind: entry.containerKind || ScriptElementKind.unknown,
kind: entry.kind,
kindModifiers: entry.kindModifiers,
matchKind: entry.matchKind,
isCaseSensitive: entry.isCaseSensitive,
fileName: entry.file,
textSpan: this.decodeSpan(entry),
}));
}
getFormattingEditsForRange(file: string, start: number, end: number, _options: ts.FormatCodeOptions): ts.TextChange[] {
const args: protocol.FormatRequestArgs = this.createFileLocationRequestArgsWithEndLineAndOffset(file, start, end);
// TODO: handle FormatCodeOptions
const request = this.processRequest<protocol.FormatRequest>(CommandNames.Format, args);
const response = this.processResponse<protocol.FormatResponse>(request);
@ -255,7 +238,7 @@ namespace ts.server {
return response.body.map(entry => this.convertCodeEditsToTextChange(file, entry));
}
getFormattingEditsForDocument(fileName: string, options: ts.FormatCodeOptions): ts.TextChange[] {
getFormattingEditsForDocument(fileName: string, options: FormatCodeOptions): ts.TextChange[] {
return this.getFormattingEditsForRange(fileName, 0, this.host.getScriptSnapshot(fileName).getLength(), options);
}
@ -275,19 +258,14 @@ namespace ts.server {
const request = this.processRequest<protocol.DefinitionRequest>(CommandNames.Definition, args);
const response = this.processResponse<protocol.DefinitionResponse>(request);
return response.body.map(entry => {
const fileName = entry.file;
const start = this.lineOffsetToPosition(fileName, entry.start);
const end = this.lineOffsetToPosition(fileName, entry.end);
return {
containerKind: ScriptElementKind.unknown,
containerName: "",
fileName,
textSpan: ts.createTextSpanFromBounds(start, end),
kind: ScriptElementKind.unknown,
name: ""
};
});
return response.body.map(entry => ({
containerKind: ScriptElementKind.unknown,
containerName: "",
fileName: entry.file,
textSpan: this.decodeSpan(entry),
kind: ScriptElementKind.unknown,
name: ""
}));
}
getTypeDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[] {
@ -296,19 +274,14 @@ namespace ts.server {
const request = this.processRequest<protocol.TypeDefinitionRequest>(CommandNames.TypeDefinition, args);
const response = this.processResponse<protocol.TypeDefinitionResponse>(request);
return response.body.map(entry => {
const fileName = entry.file;
const start = this.lineOffsetToPosition(fileName, entry.start);
const end = this.lineOffsetToPosition(fileName, entry.end);
return {
containerKind: ScriptElementKind.unknown,
containerName: "",
fileName,
textSpan: ts.createTextSpanFromBounds(start, end),
kind: ScriptElementKind.unknown,
name: ""
};
});
return response.body.map(entry => ({
containerKind: ScriptElementKind.unknown,
containerName: "",
fileName: entry.file,
textSpan: this.decodeSpan(entry),
kind: ScriptElementKind.unknown,
name: ""
}));
}
getImplementationAtPosition(fileName: string, position: number): ImplementationLocation[] {
@ -317,17 +290,12 @@ namespace ts.server {
const request = this.processRequest<protocol.ImplementationRequest>(CommandNames.Implementation, args);
const response = this.processResponse<protocol.ImplementationResponse>(request);
return response.body.map(entry => {
const fileName = entry.file;
const start = this.lineOffsetToPosition(fileName, entry.start);
const end = this.lineOffsetToPosition(fileName, entry.end);
return {
fileName,
textSpan: ts.createTextSpanFromBounds(start, end),
kind: ScriptElementKind.unknown,
displayParts: []
};
});
return response.body.map(entry => ({
fileName: entry.file,
textSpan: this.decodeSpan(entry),
kind: ScriptElementKind.unknown,
displayParts: []
}));
}
findReferences(_fileName: string, _position: number): ReferencedSymbol[] {
@ -341,17 +309,12 @@ namespace ts.server {
const request = this.processRequest<protocol.ReferencesRequest>(CommandNames.References, args);
const response = this.processResponse<protocol.ReferencesResponse>(request);
return response.body.refs.map(entry => {
const fileName = entry.file;
const start = this.lineOffsetToPosition(fileName, entry.start);
const end = this.lineOffsetToPosition(fileName, entry.end);
return {
fileName,
textSpan: ts.createTextSpanFromBounds(start, end),
isWriteAccess: entry.isWriteAccess,
isDefinition: entry.isDefinition,
};
});
return response.body.refs.map(entry => ({
fileName: entry.file,
textSpan: this.decodeSpan(entry),
isWriteAccess: entry.isWriteAccess,
isDefinition: entry.isDefinition,
}));
}
getEmitOutput(_fileName: string): EmitOutput {
@ -406,14 +369,13 @@ namespace ts.server {
const request = this.processRequest<protocol.RenameRequest>(CommandNames.Rename, args);
const response = this.processResponse<protocol.RenameResponse>(request);
const locations: RenameLocation[] = [];
response.body.locs.map((entry: protocol.SpanGroup) => {
for (const entry of response.body.locs) {
const fileName = entry.file;
entry.locs.map((loc: protocol.TextSpan) => {
const start = this.lineOffsetToPosition(fileName, loc.start);
const end = this.lineOffsetToPosition(fileName, loc.end);
locations.push({ textSpan: ts.createTextSpanFromBounds(start, end), fileName, });
});
});
for (const loc of entry.locs) {
locations.push({ textSpan: this.decodeSpan(loc, fileName), fileName });
}
}
return this.lastRenameEntry = {
canRename: response.body.info.canRename,
displayName: response.body.info.displayName,
@ -421,7 +383,7 @@ namespace ts.server {
kind: response.body.info.kind,
kindModifiers: response.body.info.kindModifiers,
localizedErrorMessage: response.body.info.localizedErrorMessage,
triggerSpan: ts.createTextSpanFromBounds(position, position),
triggerSpan: createTextSpanFromBounds(position, position),
fileName,
position,
findInStrings,
@ -485,7 +447,11 @@ namespace ts.server {
return this.decodeNavigationTree(response.body, file, lineMap);
}
private decodeSpan(span: protocol.TextSpan, fileName: string, lineMap: number[]) {
private decodeSpan(span: protocol.TextSpan & { file: string }): TextSpan;
private decodeSpan(span: protocol.TextSpan, fileName: string, lineMap?: number[]): TextSpan;
private decodeSpan(span: protocol.TextSpan & { file: string }, fileName?: string, lineMap?: number[]): TextSpan {
fileName = fileName || span.file;
lineMap = lineMap || this.getLineMap(fileName);
return createTextSpanFromBounds(
this.lineOffsetToPosition(fileName, span.start, lineMap),
this.lineOffsetToPosition(fileName, span.end, lineMap));
@ -509,19 +475,11 @@ namespace ts.server {
return undefined;
}
const helpItems: protocol.SignatureHelpItems = response.body;
const span = helpItems.applicableSpan;
const start = this.lineOffsetToPosition(fileName, span.start);
const end = this.lineOffsetToPosition(fileName, span.end);
const { items, applicableSpan: encodedApplicableSpan, selectedItemIndex, argumentIndex, argumentCount } = response.body;
const result: SignatureHelpItems = {
items: helpItems.items,
applicableSpan: { start, length: end - start },
selectedItemIndex: helpItems.selectedItemIndex,
argumentIndex: helpItems.argumentIndex,
argumentCount: helpItems.argumentCount,
};
return result;
const applicableSpan = this.decodeSpan(encodedApplicableSpan, fileName);
return { items, applicableSpan, selectedItemIndex, argumentIndex, argumentCount };
}
getOccurrencesAtPosition(fileName: string, position: number): ReferenceEntry[] {
@ -530,17 +488,12 @@ namespace ts.server {
const request = this.processRequest<protocol.OccurrencesRequest>(CommandNames.Occurrences, args);
const response = this.processResponse<protocol.OccurrencesResponse>(request);
return response.body.map(entry => {
const fileName = entry.file;
const start = this.lineOffsetToPosition(fileName, entry.start);
const end = this.lineOffsetToPosition(fileName, entry.end);
return {
fileName,
textSpan: ts.createTextSpanFromBounds(start, end),
isWriteAccess: entry.isWriteAccess,
isDefinition: false
};
});
return response.body.map(entry => ({
fileName: entry.file,
textSpan: this.decodeSpan(entry),
isWriteAccess: entry.isWriteAccess,
isDefinition: false
}));
}
getDocumentHighlights(fileName: string, position: number, filesToSearch: string[]): DocumentHighlights[] {
@ -549,26 +502,13 @@ namespace ts.server {
const request = this.processRequest<protocol.DocumentHighlightsRequest>(CommandNames.DocumentHighlights, args);
const response = this.processResponse<protocol.DocumentHighlightsResponse>(request);
const self = this;
return response.body.map(convertToDocumentHighlights);
function convertToDocumentHighlights(item: ts.server.protocol.DocumentHighlightsItem): ts.DocumentHighlights {
const { file, highlightSpans } = item;
return {
fileName: file,
highlightSpans: highlightSpans.map(convertHighlightSpan)
};
function convertHighlightSpan(span: ts.server.protocol.HighlightSpan): ts.HighlightSpan {
const start = self.lineOffsetToPosition(file, span.start);
const end = self.lineOffsetToPosition(file, span.end);
return {
textSpan: ts.createTextSpanFromBounds(start, end),
kind: span.kind
};
}
}
return response.body.map(item => ({
fileName: item.file,
highlightSpans: item.highlightSpans.map(span => ({
textSpan: this.decodeSpan(span, item.file),
kind: span.kind
})),
}));
}
getOutliningSpans(_fileName: string): OutliningSpan[] {
@ -662,7 +602,7 @@ namespace ts.server {
};
}
private convertCodeEditsToTextChanges(edits: ts.server.protocol.FileCodeEdits[]): FileTextChanges[] {
private convertCodeEditsToTextChanges(edits: protocol.FileCodeEdits[]): FileTextChanges[] {
return edits.map(edit => {
const fileName = edit.fileName;
return {
@ -683,11 +623,8 @@ namespace ts.server {
}
convertTextChangeToCodeEdit(change: protocol.CodeEdit, fileName: string): ts.TextChange {
const start = this.lineOffsetToPosition(fileName, change.start);
const end = this.lineOffsetToPosition(fileName, change.end);
return {
span: { start, length: end - start },
span: this.decodeSpan(change, fileName),
newText: change.newText ? change.newText : ""
};
}
@ -698,11 +635,7 @@ namespace ts.server {
const request = this.processRequest<protocol.BraceRequest>(CommandNames.Brace, args);
const response = this.processResponse<protocol.BraceResponse>(request);
return response.body.map(entry => {
const start = this.lineOffsetToPosition(fileName, entry.start);
const end = this.lineOffsetToPosition(fileName, entry.end);
return { start, length: end - start };
});
return response.body.map(entry => this.decodeSpan(entry, fileName));
}
getIndentationAtPosition(_fileName: string, _position: number, _options: EditorOptions): number {