From dcc3e726361ef89985ca7b0240c10117c6bb546c Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 7 Jul 2017 10:37:18 -0700 Subject: [PATCH] Use decodeSpan more (#16990) --- src/server/client.ts | 229 +++++++++++++++---------------------------- 1 file changed, 81 insertions(+), 148 deletions(-) diff --git a/src/server/client.ts b/src/server/client.ts index 8ca68937a6e..f0be887814d 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -34,7 +34,7 @@ namespace ts.server { export class SessionClient implements LanguageService { private sequence = 0; - private lineMaps: ts.Map = ts.createMap(); + private lineMaps: Map = createMap(); 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(command: string, args?: any): T { @@ -154,13 +148,10 @@ namespace ts.server { const request = this.processRequest(CommandNames.Quickinfo, args); const response = this.processResponse(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(CommandNames.Navto, args); const response = this.processResponse(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(CommandNames.Format, args); const response = this.processResponse(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(CommandNames.Definition, args); const response = this.processResponse(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(CommandNames.TypeDefinition, args); const response = this.processResponse(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(CommandNames.Implementation, args); const response = this.processResponse(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(CommandNames.References, args); const response = this.processResponse(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(CommandNames.Rename, args); const response = this.processResponse(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(CommandNames.Occurrences, args); const response = this.processResponse(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(CommandNames.DocumentHighlights, args); const response = this.processResponse(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(CommandNames.Brace, args); const response = this.processResponse(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 {