From 1cb2d24c5d218a8119655d584bd61d749b18dec2 Mon Sep 17 00:00:00 2001 From: Armando Aguirre Date: Thu, 12 Oct 2017 17:18:38 -0700 Subject: [PATCH 01/12] Added DefinitionAndBoundSpan command --- src/harness/harnessLanguageService.ts | 3 +++ src/harness/unittests/session.ts | 5 +++-- src/server/client.ts | 6 +++++- src/server/protocol.ts | 2 ++ src/server/session.ts | 20 +++++++++++++++++-- src/services/services.ts | 14 +++++++++++-- src/services/types.ts | 1 + .../reference/api/tsserverlibrary.d.ts | 18 +++++++++-------- tests/baselines/reference/api/typescript.d.ts | 7 ++++--- 9 files changed, 58 insertions(+), 18 deletions(-) diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index ad79c96d833f8..34043195429dd 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -490,6 +490,9 @@ namespace Harness.LanguageService { getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): ts.TextSpan { return unwrapJSONCallResult(this.shim.getSpanOfEnclosingComment(fileName, position, onlyMultiLine)); } + getSpanForPosition(): ts.TextSpan { + throw new Error("Not supportred on the shim."); + } getCodeFixesAtPosition(): ts.CodeAction[] { throw new Error("Not supported on the shim."); } diff --git a/src/harness/unittests/session.ts b/src/harness/unittests/session.ts index 3b5efc2d6defb..2ce5ef530e466 100644 --- a/src/harness/unittests/session.ts +++ b/src/harness/unittests/session.ts @@ -117,7 +117,7 @@ namespace ts.server { body: undefined }); }); - it ("should handle literal types in request", () => { + it("should handle literal types in request", () => { const configureRequest: protocol.ConfigureRequest = { command: CommandNames.Configure, seq: 0, @@ -175,6 +175,7 @@ namespace ts.server { CommandNames.Configure, CommandNames.Definition, CommandNames.DefinitionFull, + CommandNames.DefinitionAndBoundSpan, CommandNames.Implementation, CommandNames.ImplementationFull, CommandNames.Exit, @@ -341,7 +342,7 @@ namespace ts.server { session.addProtocolHandler(command, () => resp); expect(() => session.addProtocolHandler(command, () => resp)) - .to.throw(`Protocol handler already exists for command "${command}"`); + .to.throw(`Protocol handler already exists for command "${command}"`); }); }); diff --git a/src/server/client.ts b/src/server/client.ts index d08d1e13d2e66..f467f7f9224ba 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -322,7 +322,7 @@ namespace ts.server { } getSyntacticDiagnostics(file: string): Diagnostic[] { - const args: protocol.SyntacticDiagnosticsSyncRequestArgs = { file, includeLinePosition: true }; + const args: protocol.SyntacticDiagnosticsSyncRequestArgs = { file, includeLinePosition: true }; const request = this.processRequest(CommandNames.SyntacticDiagnosticsSync, args); const response = this.processResponse(request); @@ -531,6 +531,10 @@ namespace ts.server { return notImplemented(); } + getSpanForPosition(_fileName: string, _position: number): TextSpan { + return notImplemented(); + } + getCodeFixesAtPosition(file: string, start: number, end: number, errorCodes: number[]): CodeAction[] { const args: protocol.CodeFixRequestArgs = { ...this.createFileRangeRequestArgs(file, start, end), errorCodes }; diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 3d07392bbe69f..0685728c3b0df 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -21,6 +21,8 @@ namespace ts.server.protocol { Definition = "definition", /* @internal */ DefinitionFull = "definition-full", + /* @internal */ + DefinitionAndBoundSpan = "definitionAndBoundSpan", Implementation = "implementation", /* @internal */ ImplementationFull = "implementation-full", diff --git a/src/server/session.ts b/src/server/session.ts index 800d09ff6c283..5a8426f23b34e 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -167,7 +167,7 @@ namespace ts.server { private timerHandle: any; private immediateId: number | undefined; - constructor(private readonly operationHost: MultistepOperationHost) {} + constructor(private readonly operationHost: MultistepOperationHost) { } public startNew(action: (next: NextStep) => void) { this.complete(); @@ -579,7 +579,7 @@ namespace ts.server { private getDiagnosticsWorker( args: protocol.FileRequestArgs, isSemantic: boolean, selector: (project: Project, file: string) => ReadonlyArray, includeLinePosition: boolean - ): ReadonlyArray | ReadonlyArray { + ): ReadonlyArray | ReadonlyArray { const { project, file } = this.getFileAndProject(args); if (isSemantic && isDeclarationFileInJSOnlyNonConfiguredProject(project, file)) { return emptyArray; @@ -1081,6 +1081,13 @@ namespace ts.server { } } + private getSpanForLocation(args: protocol.FileLocationRequestArgs): TextSpan { + const { file, project } = this.getFileAndProject(args); + const scriptInfo = project.getScriptInfoForNormalizedPath(file); + + return project.getLanguageService().getSpanForPosition(file, this.getPosition(args, scriptInfo)); + } + private getFormattingEditsForRange(args: protocol.FormatRequestArgs): protocol.CodeEdit[] { const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args); const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file); @@ -1707,6 +1714,15 @@ namespace ts.server { [CommandNames.DefinitionFull]: (request: protocol.DefinitionRequest) => { return this.requiredResponse(this.getDefinition(request.arguments, /*simplifiedResult*/ false)); }, + [CommandNames.DefinitionAndBoundSpan]: (request: protocol.DefinitionRequest) => { + const definitions = this.getDefinition(request.arguments, /*simplifiedResult*/ false); + const textSpan = definitions.length !== 0 ? this.getSpanForLocation(request.arguments) : {}; + + return this.requiredResponse({ + definitions, + textSpan + }); + }, [CommandNames.TypeDefinition]: (request: protocol.FileLocationRequest) => { return this.requiredResponse(this.getTypeDefinition(request.arguments)); }, diff --git a/src/services/services.ts b/src/services/services.ts index 6bdc96d8b4d65..5b24fa1947e5a 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -724,9 +724,9 @@ namespace ts { case SyntaxKind.BinaryExpression: if (getSpecialPropertyAssignmentKind(node as BinaryExpression) !== SpecialPropertyAssignmentKind.None) { - addDeclaration(node as BinaryExpression); + addDeclaration(node as BinaryExpression); } - // falls through + // falls through default: forEachChild(node, visit); @@ -1807,6 +1807,15 @@ namespace ts { return range && createTextSpanFromRange(range); } + function getSpanForPosition(fileName: string, position: number): TextSpan { + synchronizeHostData(); + + const sourceFile = getValidSourceFile(fileName); + const node = getTouchingPropertyName(sourceFile, position, /*includeJsDocCcomment*/ false); + + return createTextSpan(node.getStart(), node.getWidth()); + } + function getTodoComments(fileName: string, descriptors: TodoCommentDescriptor[]): TodoComment[] { // Note: while getting todo comments seems like a syntactic operation, we actually // treat it as a semantic operation here. This is because we expect our host to call @@ -2032,6 +2041,7 @@ namespace ts { getDocCommentTemplateAtPosition, isValidBraceCompletionAtPosition, getSpanOfEnclosingComment, + getSpanForPosition, getCodeFixesAtPosition, getEmitOutput, getNonBoundSourceFile, diff --git a/src/services/types.ts b/src/services/types.ts index e853eb7b96cad..034b45100e00c 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -273,6 +273,7 @@ namespace ts { isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean; getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan; + getSpanForPosition(fileName: string, position: number): TextSpan; getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[]; getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[]; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 151c948602de4..1cf429546dec4 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -44,9 +44,9 @@ declare namespace ts { value: T; done: false; } | { - value: never; - done: true; - }; + value: never; + done: true; + }; } /** Array that is only intended to be pushed to, never read. */ interface Push { @@ -3942,6 +3942,7 @@ declare namespace ts { getDocCommentTemplateAtPosition(fileName: string, position: number): TextInsertion; isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean; getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan; + getSpanForPosition(fileName: string, position: number): TextSpan; getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[]; getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[]; getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string): RefactorEditInfo | undefined; @@ -4609,12 +4610,12 @@ declare namespace ts.server { module: {}; error: undefined; } | { - module: undefined; - error: { - stack?: string; - message?: string; + module: undefined; + error: { + stack?: string; + message?: string; + }; }; - }; interface ServerHost extends System { setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): any; clearTimeout(timeoutId: any): void; @@ -6887,6 +6888,7 @@ declare namespace ts.server { private getNameOrDottedNameSpan(args); private isValidBraceCompletion(args); private getQuickInfoWorker(args, simplifiedResult); + private getSpanForLocation(args); private getFormattingEditsForRange(args); private getFormattingEditsForRangeFull(args); private getFormattingEditsForDocumentFull(args); diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 14fae7d0d77a0..8350b2d7a9dbf 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -44,9 +44,9 @@ declare namespace ts { value: T; done: false; } | { - value: never; - done: true; - }; + value: never; + done: true; + }; } /** Array that is only intended to be pushed to, never read. */ interface Push { @@ -3942,6 +3942,7 @@ declare namespace ts { getDocCommentTemplateAtPosition(fileName: string, position: number): TextInsertion; isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean; getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan; + getSpanForPosition(fileName: string, position: number): TextSpan; getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[]; getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[]; getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string): RefactorEditInfo | undefined; From c6a8a32b710a3c8c3581c1792e7858c97e22318a Mon Sep 17 00:00:00 2001 From: Armando Aguirre Date: Fri, 13 Oct 2017 16:36:25 -0700 Subject: [PATCH 02/12] Fixed api reference tests --- .../baselines/reference/api/tsserverlibrary.d.ts | 16 ++++++++-------- tests/baselines/reference/api/typescript.d.ts | 6 +++--- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 1cf429546dec4..8beb5ff60e449 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -44,9 +44,9 @@ declare namespace ts { value: T; done: false; } | { - value: never; - done: true; - }; + value: never; + done: true; + }; } /** Array that is only intended to be pushed to, never read. */ interface Push { @@ -4610,12 +4610,12 @@ declare namespace ts.server { module: {}; error: undefined; } | { - module: undefined; - error: { - stack?: string; - message?: string; - }; + module: undefined; + error: { + stack?: string; + message?: string; }; + }; interface ServerHost extends System { setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): any; clearTimeout(timeoutId: any): void; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 8350b2d7a9dbf..2733bb20e56c4 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -44,9 +44,9 @@ declare namespace ts { value: T; done: false; } | { - value: never; - done: true; - }; + value: never; + done: true; + }; } /** Array that is only intended to be pushed to, never read. */ interface Push { From b86153da8806a0b9ee7aaa76cc549ee37b2dc3bc Mon Sep 17 00:00:00 2001 From: Armando Aguirre Date: Mon, 16 Oct 2017 17:50:35 -0700 Subject: [PATCH 03/12] Changed command designed based on review input --- src/harness/harnessLanguageService.ts | 6 +- src/harness/unittests/session.ts | 1 + src/server/client.ts | 8 +-- src/server/protocol.ts | 8 ++- src/server/session.ts | 71 +++++++++++++------ src/services/services.ts | 25 ++++--- src/services/types.ts | 7 +- .../reference/api/tsserverlibrary.d.ts | 15 +++- tests/baselines/reference/api/typescript.d.ts | 6 +- 9 files changed, 103 insertions(+), 44 deletions(-) diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 34043195429dd..2ec40a8981d6d 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -432,6 +432,9 @@ namespace Harness.LanguageService { getDefinitionAtPosition(fileName: string, position: number): ts.DefinitionInfo[] { return unwrapJSONCallResult(this.shim.getDefinitionAtPosition(fileName, position)); } + getDefinitionAndBoundSpan(): ts.DefinitionInfoAndBoundSpan { + throw new Error("Not supported on the shim."); + } getTypeDefinitionAtPosition(fileName: string, position: number): ts.DefinitionInfo[] { return unwrapJSONCallResult(this.shim.getTypeDefinitionAtPosition(fileName, position)); } @@ -490,9 +493,6 @@ namespace Harness.LanguageService { getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): ts.TextSpan { return unwrapJSONCallResult(this.shim.getSpanOfEnclosingComment(fileName, position, onlyMultiLine)); } - getSpanForPosition(): ts.TextSpan { - throw new Error("Not supportred on the shim."); - } getCodeFixesAtPosition(): ts.CodeAction[] { throw new Error("Not supported on the shim."); } diff --git a/src/harness/unittests/session.ts b/src/harness/unittests/session.ts index 2ce5ef530e466..fd278dc3c3a94 100644 --- a/src/harness/unittests/session.ts +++ b/src/harness/unittests/session.ts @@ -176,6 +176,7 @@ namespace ts.server { CommandNames.Definition, CommandNames.DefinitionFull, CommandNames.DefinitionAndBoundSpan, + CommandNames.DefinitionAndBoundSpanFull, CommandNames.Implementation, CommandNames.ImplementationFull, CommandNames.Exit, diff --git a/src/server/client.ts b/src/server/client.ts index f467f7f9224ba..0fe5f48ed31a5 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -268,6 +268,10 @@ namespace ts.server { })); } + getDefinitionAndBoundSpan(_fileName: string, _position: number): DefinitionInfoAndBoundSpan { + return notImplemented(); + } + getTypeDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[] { const args: protocol.FileLocationRequestArgs = this.createFileLocationRequestArgs(fileName, position); @@ -531,10 +535,6 @@ namespace ts.server { return notImplemented(); } - getSpanForPosition(_fileName: string, _position: number): TextSpan { - return notImplemented(); - } - getCodeFixesAtPosition(file: string, start: number, end: number, errorCodes: number[]): CodeAction[] { const args: protocol.CodeFixRequestArgs = { ...this.createFileRangeRequestArgs(file, start, end), errorCodes }; diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 0685728c3b0df..327c351ba6f22 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -21,8 +21,9 @@ namespace ts.server.protocol { Definition = "definition", /* @internal */ DefinitionFull = "definition-full", - /* @internal */ DefinitionAndBoundSpan = "definitionAndBoundSpan", + /* @internal */ + DefinitionAndBoundSpanFull = "definitionAndBoundSpan-full", Implementation = "implementation", /* @internal */ ImplementationFull = "implementation-full", @@ -690,6 +691,11 @@ namespace ts.server.protocol { file: string; } + export interface DefinitionInfoAndBoundSpan { + definitions: ReadonlyArray; + textSpan: TextSpan; + } + /** * Definition response message. Gives text range for definition. */ diff --git a/src/server/session.ts b/src/server/session.ts index 5a8426f23b34e..54ac3082c18fd 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -601,20 +601,57 @@ namespace ts.server { } if (simplifiedResult) { - return definitions.map(def => { - const defScriptInfo = project.getScriptInfo(def.fileName); - return { - file: def.fileName, - start: defScriptInfo.positionToLineOffset(def.textSpan.start), - end: defScriptInfo.positionToLineOffset(textSpanEnd(def.textSpan)) - }; - }); + return this.getSimplifiedDefinition(definitions, project); } else { return definitions; } } + private getDefinitionAndBoundSpan(args: protocol.FileLocationRequestArgs, simplifiedResult: boolean): protocol.DefinitionInfoAndBoundSpan | DefinitionInfoAndBoundSpan { + const { file, project } = this.getFileAndProject(args); + const position = this.getPositionInFile(args, file); + const scriptInfo = project.getScriptInfo(file); + + const definitionAndBoundSpan = project.getLanguageService().getDefinitionAndBoundSpan(file, position); + + if (!definitionAndBoundSpan || !definitionAndBoundSpan.definitions) { + return { + definitions: emptyArray, + textSpan: undefined + }; + } + + if (simplifiedResult) { + return { + definitions: this.getSimplifiedDefinition(definitionAndBoundSpan.definitions, project), + textSpan: this.getSimplifiedTextSpan(definitionAndBoundSpan.textSpan, scriptInfo) + }; + } + + return definitionAndBoundSpan; + } + + private getSimplifiedDefinition(definitions: ReadonlyArray, project: Project): ReadonlyArray { + return definitions.map(def => { + const defScriptInfo = project.getScriptInfo(def.fileName); + const simplifiedTextSpan = this.getSimplifiedTextSpan(def.textSpan, defScriptInfo); + + return { + file: def.fileName, + start: simplifiedTextSpan.start, + end: simplifiedTextSpan.end + }; + }); + } + + private getSimplifiedTextSpan(textSpan: TextSpan, scriptInfo: ScriptInfo): protocol.TextSpan { + return { + start: scriptInfo.positionToLineOffset(textSpan.start), + end: scriptInfo.positionToLineOffset(textSpanEnd(textSpan)) + }; + } + private getTypeDefinition(args: protocol.FileLocationRequestArgs): ReadonlyArray { const { file, project } = this.getFileAndProject(args); const position = this.getPositionInFile(args, file); @@ -1081,13 +1118,6 @@ namespace ts.server { } } - private getSpanForLocation(args: protocol.FileLocationRequestArgs): TextSpan { - const { file, project } = this.getFileAndProject(args); - const scriptInfo = project.getScriptInfoForNormalizedPath(file); - - return project.getLanguageService().getSpanForPosition(file, this.getPosition(args, scriptInfo)); - } - private getFormattingEditsForRange(args: protocol.FormatRequestArgs): protocol.CodeEdit[] { const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args); const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file); @@ -1715,13 +1745,10 @@ namespace ts.server { return this.requiredResponse(this.getDefinition(request.arguments, /*simplifiedResult*/ false)); }, [CommandNames.DefinitionAndBoundSpan]: (request: protocol.DefinitionRequest) => { - const definitions = this.getDefinition(request.arguments, /*simplifiedResult*/ false); - const textSpan = definitions.length !== 0 ? this.getSpanForLocation(request.arguments) : {}; - - return this.requiredResponse({ - definitions, - textSpan - }); + return this.requiredResponse(this.getDefinitionAndBoundSpan(request.arguments, /*simplifiedResult*/ true)); + }, + [CommandNames.DefinitionAndBoundSpanFull]: (request: protocol.DefinitionRequest) => { + return this.requiredResponse(this.getDefinitionAndBoundSpan(request.arguments, /*simplifiedResult*/ false)); }, [CommandNames.TypeDefinition]: (request: protocol.FileLocationRequest) => { return this.requiredResponse(this.getTypeDefinition(request.arguments)); diff --git a/src/services/services.ts b/src/services/services.ts index 5b24fa1947e5a..f2702082470f2 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1411,6 +1411,20 @@ namespace ts { return GoToDefinition.getDefinitionAtPosition(program, getValidSourceFile(fileName), position); } + function getDefinitionAndBoundSpan(fileName: string, position: number): DefinitionInfoAndBoundSpan { + const definitions = getDefinitionAtPosition(fileName, position); + + if (!definitions) { + return undefined; + } + + const sourceFile = getValidSourceFile(fileName); + const node = getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true); + const textSpan = createTextSpan(node.getStart(), node.getWidth()); + + return { definitions, textSpan }; + } + function getTypeDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[] { synchronizeHostData(); return GoToDefinition.getTypeDefinitionAtPosition(program.getTypeChecker(), getValidSourceFile(fileName), position); @@ -1807,15 +1821,6 @@ namespace ts { return range && createTextSpanFromRange(range); } - function getSpanForPosition(fileName: string, position: number): TextSpan { - synchronizeHostData(); - - const sourceFile = getValidSourceFile(fileName); - const node = getTouchingPropertyName(sourceFile, position, /*includeJsDocCcomment*/ false); - - return createTextSpan(node.getStart(), node.getWidth()); - } - function getTodoComments(fileName: string, descriptors: TodoCommentDescriptor[]): TodoComment[] { // Note: while getting todo comments seems like a syntactic operation, we actually // treat it as a semantic operation here. This is because we expect our host to call @@ -2018,6 +2023,7 @@ namespace ts { getSignatureHelpItems, getQuickInfoAtPosition, getDefinitionAtPosition, + getDefinitionAndBoundSpan, getImplementationAtPosition, getTypeDefinitionAtPosition, getReferencesAtPosition, @@ -2041,7 +2047,6 @@ namespace ts { getDocCommentTemplateAtPosition, isValidBraceCompletionAtPosition, getSpanOfEnclosingComment, - getSpanForPosition, getCodeFixesAtPosition, getEmitOutput, getNonBoundSourceFile, diff --git a/src/services/types.ts b/src/services/types.ts index 034b45100e00c..c6ab8c876f04d 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -245,6 +245,7 @@ namespace ts { findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): RenameLocation[]; getDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[]; + getDefinitionAndBoundSpan(fileName: string, position: number): DefinitionInfoAndBoundSpan; getTypeDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[]; getImplementationAtPosition(fileName: string, position: number): ImplementationLocation[]; @@ -273,7 +274,6 @@ namespace ts { isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean; getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan; - getSpanForPosition(fileName: string, position: number): TextSpan; getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[]; getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[]; @@ -549,6 +549,11 @@ namespace ts { containerName: string; } + export interface DefinitionInfoAndBoundSpan { + definitions: ReadonlyArray; + textSpan: TextSpan; + } + export interface ReferencedSymbolDefinitionInfo extends DefinitionInfo { displayParts: SymbolDisplayPart[]; } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 8beb5ff60e449..b69b44e98a029 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -3922,6 +3922,7 @@ declare namespace ts { getRenameInfo(fileName: string, position: number): RenameInfo; findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): RenameLocation[]; getDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[]; + getDefinitionAndBoundSpan(fileName: string, position: number): DefinitionInfoAndBoundSpan; getTypeDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[]; getImplementationAtPosition(fileName: string, position: number): ImplementationLocation[]; getReferencesAtPosition(fileName: string, position: number): ReferenceEntry[]; @@ -3942,7 +3943,6 @@ declare namespace ts { getDocCommentTemplateAtPosition(fileName: string, position: number): TextInsertion; isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean; getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan; - getSpanForPosition(fileName: string, position: number): TextSpan; getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[]; getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[]; getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string): RefactorEditInfo | undefined; @@ -4174,6 +4174,10 @@ declare namespace ts { containerKind: ScriptElementKind; containerName: string; } + interface DefinitionInfoAndBoundSpan { + definitions: ReadonlyArray; + textSpan: TextSpan; + } interface ReferencedSymbolDefinitionInfo extends DefinitionInfo { displayParts: SymbolDisplayPart[]; } @@ -4793,6 +4797,7 @@ declare namespace ts.server.protocol { CompileOnSaveEmitFile = "compileOnSaveEmitFile", Configure = "configure", Definition = "definition", + DefinitionAndBoundSpan = "definitionAndBoundSpan", Implementation = "implementation", Exit = "exit", Format = "format", @@ -5298,6 +5303,10 @@ declare namespace ts.server.protocol { */ file: string; } + interface DefinitionInfoAndBoundSpan { + definitions: ReadonlyArray; + textSpan: TextSpan; + } /** * Definition response message. Gives text range for definition. */ @@ -6855,6 +6864,9 @@ declare namespace ts.server { private convertToDiagnosticsWithLinePosition(diagnostics, scriptInfo); private getDiagnosticsWorker(args, isSemantic, selector, includeLinePosition); private getDefinition(args, simplifiedResult); + private getDefinitionAndBoundSpan(args, simplifiedResult); + private getSimplifiedDefinition(definitions, project); + private getSimplifiedTextSpan(textSpan, scriptInfo); private getTypeDefinition(args); private getImplementation(args, simplifiedResult); private getOccurrences(args); @@ -6888,7 +6900,6 @@ declare namespace ts.server { private getNameOrDottedNameSpan(args); private isValidBraceCompletion(args); private getQuickInfoWorker(args, simplifiedResult); - private getSpanForLocation(args); private getFormattingEditsForRange(args); private getFormattingEditsForRangeFull(args); private getFormattingEditsForDocumentFull(args); diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 2733bb20e56c4..9f9319fd7faa7 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -3922,6 +3922,7 @@ declare namespace ts { getRenameInfo(fileName: string, position: number): RenameInfo; findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): RenameLocation[]; getDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[]; + getDefinitionAndBoundSpan(fileName: string, position: number): DefinitionInfoAndBoundSpan; getTypeDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[]; getImplementationAtPosition(fileName: string, position: number): ImplementationLocation[]; getReferencesAtPosition(fileName: string, position: number): ReferenceEntry[]; @@ -3942,7 +3943,6 @@ declare namespace ts { getDocCommentTemplateAtPosition(fileName: string, position: number): TextInsertion; isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean; getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan; - getSpanForPosition(fileName: string, position: number): TextSpan; getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[]; getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[]; getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string): RefactorEditInfo | undefined; @@ -4174,6 +4174,10 @@ declare namespace ts { containerKind: ScriptElementKind; containerName: string; } + interface DefinitionInfoAndBoundSpan { + definitions: ReadonlyArray; + textSpan: TextSpan; + } interface ReferencedSymbolDefinitionInfo extends DefinitionInfo { displayParts: SymbolDisplayPart[]; } From 8004fec2ceebc69c2dad06c61990bb47c8cd8daf Mon Sep 17 00:00:00 2001 From: Armando Aguirre Date: Wed, 18 Oct 2017 14:48:06 -0700 Subject: [PATCH 04/12] Addressed PR comments: added simplified/full version, changed design --- src/harness/harnessLanguageService.ts | 4 +-- src/server/client.ts | 19 ++++++++++-- src/server/protocol.ts | 4 +++ src/server/session.ts | 29 ++++++++++--------- src/services/goToDefinition.ts | 17 ++++++++++- src/services/services.ts | 13 ++------- src/services/shims.ts | 13 +++++++++ .../reference/api/tsserverlibrary.d.ts | 8 +++-- 8 files changed, 75 insertions(+), 32 deletions(-) diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 2ec40a8981d6d..9740d493662ed 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -432,8 +432,8 @@ namespace Harness.LanguageService { getDefinitionAtPosition(fileName: string, position: number): ts.DefinitionInfo[] { return unwrapJSONCallResult(this.shim.getDefinitionAtPosition(fileName, position)); } - getDefinitionAndBoundSpan(): ts.DefinitionInfoAndBoundSpan { - throw new Error("Not supported on the shim."); + getDefinitionAndBoundSpan(fileName: string, position: number): ts.DefinitionInfoAndBoundSpan { + return unwrapJSONCallResult(this.shim.getDefinitionAndBoundSpan(fileName, position)); } getTypeDefinitionAtPosition(fileName: string, position: number): ts.DefinitionInfo[] { return unwrapJSONCallResult(this.shim.getTypeDefinitionAtPosition(fileName, position)); diff --git a/src/server/client.ts b/src/server/client.ts index 0fe5f48ed31a5..c0208d7490362 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -268,8 +268,23 @@ namespace ts.server { })); } - getDefinitionAndBoundSpan(_fileName: string, _position: number): DefinitionInfoAndBoundSpan { - return notImplemented(); + getDefinitionAndBoundSpan(fileName: string, position: number): DefinitionInfoAndBoundSpan { + const args: protocol.FileLocationRequestArgs = this.createFileLocationRequestArgs(fileName, position); + + const request = this.processRequest(CommandNames.DefinitionAndBoundSpan, args); + const response = this.processResponse(request); + + return { + definitions: response.body.definitions.map(entry => ({ + containerKind: ScriptElementKind.unknown, + containerName: "", + fileName: entry.file, + textSpan: this.decodeSpan(entry), + kind: ScriptElementKind.unknown, + name: "" + })), + textSpan: this.decodeSpan(response.body.textSpan, request.arguments.file) + }; } getTypeDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[] { diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 327c351ba6f22..21b090548ff18 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -703,6 +703,10 @@ namespace ts.server.protocol { body?: FileSpan[]; } + export interface DefinitionInfoAndBoundSpanReponse extends Response { + body?: DefinitionInfoAndBoundSpan; + } + /** * Definition response message. Gives text range for definition. */ diff --git a/src/server/session.ts b/src/server/session.ts index 54ac3082c18fd..fb37bf5540850 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -601,7 +601,7 @@ namespace ts.server { } if (simplifiedResult) { - return this.getSimplifiedDefinition(definitions, project); + return this.getSimplifiedDefinitions(definitions, project); } else { return definitions; @@ -624,28 +624,29 @@ namespace ts.server { if (simplifiedResult) { return { - definitions: this.getSimplifiedDefinition(definitionAndBoundSpan.definitions, project), - textSpan: this.getSimplifiedTextSpan(definitionAndBoundSpan.textSpan, scriptInfo) + definitions: this.getSimplifiedDefinitions(definitionAndBoundSpan.definitions, project), + textSpan: this.getSimplifiedTextSpan(scriptInfo, definitionAndBoundSpan.textSpan) }; } return definitionAndBoundSpan; } - private getSimplifiedDefinition(definitions: ReadonlyArray, project: Project): ReadonlyArray { - return definitions.map(def => { - const defScriptInfo = project.getScriptInfo(def.fileName); - const simplifiedTextSpan = this.getSimplifiedTextSpan(def.textSpan, defScriptInfo); + private getSimplifiedDefinitions(definitions: ReadonlyArray, project: Project): ReadonlyArray { + return definitions.map(def => this.getSimplifiedFileSpan(def.fileName, def.textSpan, project)); + } - return { - file: def.fileName, - start: simplifiedTextSpan.start, - end: simplifiedTextSpan.end - }; - }); + private getSimplifiedFileSpan(fileName: string, textSpan: TextSpan, project: Project): protocol.FileSpan { + const scriptInfo = project.getScriptInfo(fileName); + const simplifiedTextSpan = this.getSimplifiedTextSpan(scriptInfo, textSpan); + + return { + file: fileName, + ...simplifiedTextSpan + }; } - private getSimplifiedTextSpan(textSpan: TextSpan, scriptInfo: ScriptInfo): protocol.TextSpan { + private getSimplifiedTextSpan(scriptInfo: ScriptInfo, textSpan: TextSpan): protocol.TextSpan { return { start: scriptInfo.positionToLineOffset(textSpan.start), end: scriptInfo.positionToLineOffset(textSpanEnd(textSpan)) diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index cb2be7d484caf..158d6d6ac6fb6 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -88,7 +88,7 @@ namespace ts.GoToDefinition { // } // bar(({pr/*goto*/op1})=>{}); if (isPropertyName(node) && isBindingElement(node.parent) && isObjectBindingPattern(node.parent.parent) && - (node === (node.parent.propertyName || node.parent.name))) { + (node === (node.parent.propertyName || node.parent.name))) { const type = typeChecker.getTypeAtLocation(node.parent.parent); if (type) { const propSymbols = getPropertySymbolsFromType(type, node); @@ -149,6 +149,21 @@ namespace ts.GoToDefinition { return getDefinitionFromSymbol(typeChecker, type.symbol, node); } + export function getDefinitionAndBoundSpan(program: Program, sourceFile: SourceFile, position: number): DefinitionInfoAndBoundSpan { + const definitions = getDefinitionAtPosition(program, sourceFile, position); + + if (!definitions || definitions.length === 0) { + return undefined; + } + + // TODO: Add textSpan for triple slash references (file and type). + + const node = getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true); + const textSpan = createTextSpan(node.getStart(), node.getWidth()); + + return { definitions, textSpan }; + } + // Go to the original declaration for cases: // // (1) when the aliased symbol was declared in the location(parent). diff --git a/src/services/services.ts b/src/services/services.ts index f2702082470f2..90ff50e45d0d4 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1412,17 +1412,8 @@ namespace ts { } function getDefinitionAndBoundSpan(fileName: string, position: number): DefinitionInfoAndBoundSpan { - const definitions = getDefinitionAtPosition(fileName, position); - - if (!definitions) { - return undefined; - } - - const sourceFile = getValidSourceFile(fileName); - const node = getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true); - const textSpan = createTextSpan(node.getStart(), node.getWidth()); - - return { definitions, textSpan }; + synchronizeHostData(); + return GoToDefinition.getDefinitionAndBoundSpan(program, getValidSourceFile(fileName), position); } function getTypeDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[] { diff --git a/src/services/shims.ts b/src/services/shims.ts index 9d4baccc3c4e0..f97628d638803 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -170,6 +170,8 @@ namespace ts { */ getDefinitionAtPosition(fileName: string, position: number): string; + getDefinitionAndBoundSpan(fileName: string, position: number): string; + /** * Returns a JSON-encoded value of the type: * { fileName: string; textSpan: { start: number; length: number}; kind: string; name: string; containerKind: string; containerName: string } @@ -772,6 +774,17 @@ namespace ts { ); } + /** + * Computes the definition location and file for the symbol + * at the requested position. + */ + public getDefinitionAndBoundSpan(fileName: string, position: number): string { + return this.forwardJSONCall( + `getDefinitionAndBoundSpan('${fileName}', ${position})`, + () => this.languageService.getDefinitionAndBoundSpan(fileName, position) + ); + } + /// GOTO Type /** diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index b69b44e98a029..306f15e952152 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -5313,6 +5313,9 @@ declare namespace ts.server.protocol { interface DefinitionResponse extends Response { body?: FileSpan[]; } + interface DefinitionInfoAndBoundSpanReponse extends Response { + body?: DefinitionInfoAndBoundSpan; + } /** * Definition response message. Gives text range for definition. */ @@ -6865,8 +6868,9 @@ declare namespace ts.server { private getDiagnosticsWorker(args, isSemantic, selector, includeLinePosition); private getDefinition(args, simplifiedResult); private getDefinitionAndBoundSpan(args, simplifiedResult); - private getSimplifiedDefinition(definitions, project); - private getSimplifiedTextSpan(textSpan, scriptInfo); + private getSimplifiedDefinitions(definitions, project); + private getSimplifiedFileSpan(fileName, textSpan, project); + private getSimplifiedTextSpan(scriptInfo, textSpan); private getTypeDefinition(args); private getImplementation(args, simplifiedResult); private getOccurrences(args); From 16c32559886a31cf62b87be1fccb521ab9d5d2b4 Mon Sep 17 00:00:00 2001 From: Armando Aguirre Date: Wed, 18 Oct 2017 15:49:46 -0700 Subject: [PATCH 05/12] Updated an incredible amount of tests. --- src/harness/fourslash.ts | 56 ++++++++++++++++--- src/services/goToDefinition.ts | 4 ++ .../ambientShorthandGotoDefinition.ts | 8 +-- tests/cases/fourslash/definition.ts | 2 +- .../fourslash/definitionNameOnEnumMember.ts | 2 +- .../fourslash/duplicatePackageServices.ts | 4 +- .../fourslash/findAllRefsForDefaultExport.ts | 2 +- tests/cases/fourslash/fourslash.ts | 1 + .../goToDefinitionAcrossMultipleProjects.ts | 2 +- tests/cases/fourslash/goToDefinitionAlias.ts | 8 +-- .../goToDefinitionApparentTypeProperties.ts | 4 +- ...efinitionConstructorOfClassExpression01.ts | 2 +- ...OfClassWhenClassIsPrecededByNamespace01.ts | 2 +- .../goToDefinitionConstructorOverloads.ts | 6 +- .../fourslash/goToDefinitionDecorator.ts | 4 +- .../goToDefinitionDecoratorOverloads.ts | 4 +- .../fourslash/goToDefinitionDynamicImport1.ts | 4 +- .../fourslash/goToDefinitionDynamicImport2.ts | 2 +- .../fourslash/goToDefinitionDynamicImport3.ts | 2 +- .../fourslash/goToDefinitionDynamicImport4.ts | 2 +- .../goToDefinitionExternalModuleName.ts | 2 +- .../goToDefinitionExternalModuleName2.ts | 2 +- .../goToDefinitionExternalModuleName3.ts | 2 +- .../goToDefinitionExternalModuleName5.ts | 2 +- .../goToDefinitionExternalModuleName6.ts | 2 +- .../goToDefinitionExternalModuleName7.ts | 2 +- .../goToDefinitionExternalModuleName8.ts | 2 +- .../goToDefinitionExternalModuleName9.ts | 2 +- .../goToDefinitionFunctionOverloads.ts | 8 +-- .../goToDefinitionFunctionOverloadsInClass.ts | 4 +- .../fourslash/goToDefinitionImportedNames.ts | 2 +- .../fourslash/goToDefinitionImportedNames2.ts | 2 +- .../fourslash/goToDefinitionImportedNames3.ts | 4 +- .../fourslash/goToDefinitionImportedNames4.ts | 2 +- .../fourslash/goToDefinitionImportedNames5.ts | 2 +- .../fourslash/goToDefinitionImportedNames6.ts | 2 +- .../fourslash/goToDefinitionImportedNames7.ts | 2 +- .../cases/fourslash/goToDefinitionImports.ts | 8 +-- .../goToDefinitionInMemberDeclaration.ts | 12 ++-- .../fourslash/goToDefinitionJsModuleName.ts | 2 +- tests/cases/fourslash/goToDefinitionLabels.ts | 6 +- .../goToDefinitionMethodOverloads.ts | 12 ++-- .../goToDefinitionMultipleDefinitions.ts | 4 +- ...itionObjectBindingElementPropertyName01.ts | 2 +- .../goToDefinitionObjectLiteralProperties1.ts | 4 +- .../fourslash/goToDefinitionObjectSpread.ts | 2 +- ...tionOverloadsInMultiplePropertyAccesses.ts | 2 +- .../goToDefinitionPartialImplementation.ts | 2 +- tests/cases/fourslash/goToDefinitionRest.ts | 2 +- .../goToDefinitionShorthandProperty01.ts | 6 +- .../goToDefinitionShorthandProperty02.ts | 2 +- .../goToDefinitionShorthandProperty03.ts | 4 +- tests/cases/fourslash/goToDefinitionSimple.ts | 4 +- .../goToDefinitionTaggedTemplateOverloads.ts | 4 +- tests/cases/fourslash/goToDefinitionThis.ts | 6 +- .../fourslash/goToDefinitionTypePredicate.ts | 2 +- .../goToDefinitionUnionTypeProperty1.ts | 2 +- .../goToDefinitionUnionTypeProperty2.ts | 2 +- .../goToDefinitionUnionTypeProperty3.ts | 2 +- .../goToDefinitionUnionTypeProperty4.ts | 2 +- tests/cases/fourslash/goToDefinition_super.ts | 4 +- .../fourslash/goToDefinition_untypedModule.ts | 2 +- .../fourslash/goToModuleAliasDefinition.ts | 2 +- .../gotoDefinitionInObjectBindingPattern1.ts | 2 +- .../gotoDefinitionInObjectBindingPattern2.ts | 2 +- ...nPropertyAccessExpressionHeritageClause.ts | 4 +- tests/cases/fourslash/javaScriptClass3.ts | 4 +- .../fourslash/jsdocTypedefTagServices.ts | 2 +- tests/cases/fourslash/server/definition01.ts | 2 +- .../server/jsdocTypedefTagGoToDefinition.ts | 4 +- .../fourslash/tsxGoToDefinitionClasses.ts | 6 +- .../fourslash/tsxGoToDefinitionIntrinsics.ts | 6 +- .../tsxGoToDefinitionStatelessFunction1.ts | 8 +-- .../tsxGoToDefinitionStatelessFunction2.ts | 12 ++-- .../tsxGoToDefinitionUnionElementType1.ts | 2 +- .../tsxGoToDefinitionUnionElementType2.ts | 2 +- 76 files changed, 184 insertions(+), 139 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index de6d92eda05ed..a95221e3b26ed 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -584,18 +584,23 @@ namespace FourSlash { public verifyGoToDefinition(arg0: any, endMarkerNames?: string | string[]) { this.verifyGoToX(arg0, endMarkerNames, () => this.getGoToDefinition()); + this.verifyGoToX(arg0, endMarkerNames, () => this.getGoToDefinitionAndBoundSpan()); } private getGoToDefinition(): ts.DefinitionInfo[] { return this.languageService.getDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition); } + private getGoToDefinitionAndBoundSpan(): ts.DefinitionInfoAndBoundSpan { + return this.languageService.getDefinitionAndBoundSpan(this.activeFile.fileName, this.currentCaretPosition); + } + public verifyGoToType(arg0: any, endMarkerNames?: string | string[]) { this.verifyGoToX(arg0, endMarkerNames, () => this.languageService.getTypeDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition)); } - private verifyGoToX(arg0: any, endMarkerNames: string | string[] | undefined, getDefs: () => ts.DefinitionInfo[] | undefined) { + private verifyGoToX(arg0: any, endMarkerNames: string | string[] | undefined, getDefs: () => ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined) { if (endMarkerNames) { this.verifyGoToXPlain(arg0, endMarkerNames, getDefs); } @@ -615,7 +620,7 @@ namespace FourSlash { } } - private verifyGoToXPlain(startMarkerNames: string | string[], endMarkerNames: string | string[], getDefs: () => ts.DefinitionInfo[] | undefined) { + private verifyGoToXPlain(startMarkerNames: string | string[], endMarkerNames: string | string[], getDefs: () => ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined) { for (const start of toArray(startMarkerNames)) { this.verifyGoToXSingle(start, endMarkerNames, getDefs); } @@ -627,26 +632,60 @@ namespace FourSlash { } } - private verifyGoToXSingle(startMarkerName: string, endMarkerNames: string | string[], getDefs: () => ts.DefinitionInfo[] | undefined) { + private verifyGoToXSingle(startMarkerName: string, endMarkerNames: string | string[], getDefs: () => ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined) { this.goToMarker(startMarkerName); - this.verifyGoToXWorker(toArray(endMarkerNames), getDefs); + this.verifyGoToXWorker(toArray(endMarkerNames), getDefs, startMarkerName); } - private verifyGoToXWorker(endMarkers: string[], getDefs: () => ts.DefinitionInfo[] | undefined) { - const definitions = getDefs() || []; + private verifyGoToXWorker(endMarkers: string[], getDefs: () => ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined, startMarkerName?: string) { + const defs = getDefs(); + let definitions: ts.DefinitionInfo[] | ReadonlyArray; + let testName: string; + if (this.isDefinitionInfoAndBoundSpan(defs)) { + this.verifyDefinitionTextSpan(defs, startMarkerName); + + definitions = defs.definitions; + testName = "goToDefinitionsAndBoundSpan"; + } + else { + definitions = defs || []; + testName = "goToDefinitions"; + } if (endMarkers.length !== definitions.length) { - this.raiseError(`goToDefinitions failed - expected to find ${endMarkers.length} definitions but got ${definitions.length}`); + this.raiseError(`${testName} failed - expected to find ${endMarkers.length} definitions but got ${definitions.length}`); } ts.zipWith(endMarkers, definitions, (endMarker, definition, i) => { const marker = this.getMarkerByName(endMarker); if (marker.fileName !== definition.fileName || marker.position !== definition.textSpan.start) { - this.raiseError(`goToDefinition failed for definition ${endMarker} (${i}): expected ${marker.fileName} at ${marker.position}, got ${definition.fileName} at ${definition.textSpan.start}`); + this.raiseError(`${testName} failed for definition ${endMarker} (${i}): expected ${marker.fileName} at ${marker.position}, got ${definition.fileName} at ${definition.textSpan.start}`); } }); } + private verifyDefinitionTextSpan(defs: ts.DefinitionInfoAndBoundSpan, startMarkerName: string) { + const range = this.testData.ranges.find(range => this.markerName(range.marker) === startMarkerName); + + if (!range && !defs.textSpan) { + return; + } + + if (!range) { + this.raiseError(`goToDefinitionsAndBoundSpan failed - found a TextSpan ${JSON.stringify(defs.textSpan)} when it wasn't expected.`); + } + else if (defs.textSpan.start !== range.start || defs.textSpan.length !== range.end - range.start) { + const expected: ts.TextSpan = { + start: range.start, length: range.end - range.start + }; + this.raiseError(`goToDefinitionsAndBoundSpan failed - expected to find TextSpan ${JSON.stringify(expected)} but got ${JSON.stringify(defs.textSpan)}`); + } + } + + private isDefinitionInfoAndBoundSpan(definition: ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined): definition is ts.DefinitionInfoAndBoundSpan { + return definition && (definition).definitions !== undefined; + } + public verifyGetEmitOutputForCurrentFile(expected: string): void { const emit = this.languageService.getEmitOutput(this.activeFile.fileName); if (emit.outputFiles.length !== 1) { @@ -3828,6 +3867,7 @@ namespace FourSlashInterface { } public goToDefinition(startMarkerName: string | string[], endMarkerName: string | string[]): void; + public goToDefinition(startMarkerName: string | string[], endMarkerName: string | string[], range: FourSlash.Range): void; public goToDefinition(startsAndEnds: [string | string[], string | string[]][]): void; public goToDefinition(startsAndEnds: { [startMarkerName: string]: string | string[] }): void; public goToDefinition(arg0: any, endMarkerName?: string | string[]) { diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index 158d6d6ac6fb6..eaee0afdd1ec9 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -157,6 +157,10 @@ namespace ts.GoToDefinition { } // TODO: Add textSpan for triple slash references (file and type). + const comment = findReferenceInPosition(sourceFile.referencedFiles, position); + if (comment && tryResolveScriptReference(program, sourceFile, comment) || findReferenceInPosition(sourceFile.typeReferenceDirectives, position)) { + return { definitions, textSpan: undefined }; + } const node = getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true); const textSpan = createTextSpan(node.getStart(), node.getWidth()); diff --git a/tests/cases/fourslash/ambientShorthandGotoDefinition.ts b/tests/cases/fourslash/ambientShorthandGotoDefinition.ts index 74e348beb7437..f0e717999cf6e 100644 --- a/tests/cases/fourslash/ambientShorthandGotoDefinition.ts +++ b/tests/cases/fourslash/ambientShorthandGotoDefinition.ts @@ -5,10 +5,10 @@ // @Filename: user.ts /////// -////import /*importFoo*/foo, {bar} from "jquery"; -////import * as /*importBaz*/baz from "jquery"; -////import /*importBang*/bang = require("jquery"); -////foo/*useFoo*/(bar/*useBar*/, baz/*useBaz*/, bang/*useBang*/); +////import [|/*importFoo*/foo|], {bar} from "jquery"; +////import * as [|/*importBaz*/baz|] from "jquery"; +////import [|/*importBang*/bang|] = require("jquery"); +////[|foo/*useFoo*/|]([|bar/*useBar*/|], [|baz/*useBaz*/|], [|bang/*useBang*/|]); verify.quickInfoAt("useFoo", "import foo"); verify.goToDefinition({ diff --git a/tests/cases/fourslash/definition.ts b/tests/cases/fourslash/definition.ts index 705cdd655832b..f91d8a9e34610 100644 --- a/tests/cases/fourslash/definition.ts +++ b/tests/cases/fourslash/definition.ts @@ -1,7 +1,7 @@ /// // @Filename: b.ts -////import n = require('./a/*1*/'); +////import n = require([|'./a/*1*/'|]); ////var x = new n.Foo(); // @Filename: a.ts diff --git a/tests/cases/fourslash/definitionNameOnEnumMember.ts b/tests/cases/fourslash/definitionNameOnEnumMember.ts index b82b0dc0465a7..5529dc2bb5515 100644 --- a/tests/cases/fourslash/definitionNameOnEnumMember.ts +++ b/tests/cases/fourslash/definitionNameOnEnumMember.ts @@ -5,7 +5,7 @@ //// secondMember, //// thirdMember ////} -////var enumMember = e./*1*/thirdMember; +////var enumMember = e.[|/*1*/thirdMember|]; goTo.marker("1"); verify.goToDefinitionName("thirdMember", "e"); diff --git a/tests/cases/fourslash/duplicatePackageServices.ts b/tests/cases/fourslash/duplicatePackageServices.ts index 360611ad1403b..c84c43cdd9e8c 100644 --- a/tests/cases/fourslash/duplicatePackageServices.ts +++ b/tests/cases/fourslash/duplicatePackageServices.ts @@ -2,7 +2,7 @@ // @noImplicitReferences: true // @Filename: /node_modules/a/index.d.ts -////import /*useAX*/[|{| "isWriteAccess": true, "isDefinition": true |}X|] from "x"; +////import [|{| "name": "useAX", "isWriteAccess": true, "isDefinition": true |}X|] from "x"; ////export function a(x: [|X|]): void; // @Filename: /node_modules/a/node_modules/x/index.d.ts @@ -14,7 +14,7 @@ ////{ "name": "x", "version": "1.2.3" } // @Filename: /node_modules/b/index.d.ts -////import /*useBX*/[|{| "isWriteAccess": true, "isDefinition": true |}X|] from "x"; +////import [|{| "name": "useBX", "isWriteAccess": true, "isDefinition": true |}X|] from "x"; ////export const b: [|X|]; // @Filename: /node_modules/b/node_modules/x/index.d.ts diff --git a/tests/cases/fourslash/findAllRefsForDefaultExport.ts b/tests/cases/fourslash/findAllRefsForDefaultExport.ts index 7cd6fe8d57c62..414b2503391a1 100644 --- a/tests/cases/fourslash/findAllRefsForDefaultExport.ts +++ b/tests/cases/fourslash/findAllRefsForDefaultExport.ts @@ -5,7 +5,7 @@ // @Filename: b.ts ////import [|{| "isWriteAccess": true, "isDefinition": true |}g|] from "./a"; -/////*ref*/[|g|](); +////[|/*ref*/g|](); // @Filename: c.ts ////import { f } from "./a"; diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index f4d47abc9c9c4..5a0bd4bd2e764 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -193,6 +193,7 @@ declare namespace FourSlashInterface { * `verify.goToDefinition("a", ["b", "bb"]);` verifies that "a" has multiple definitions available. */ goToDefinition(startMarkerNames: string | string[], endMarkerNames: string | string[]): void; + goToDefinition(startMarkerNames: string | string[], endMarkerNames: string | string[], range: Range): void; /** Performs `goToDefinition` for each pair. */ goToDefinition(startsAndEnds: [string | string[], string | string[]][]): void; /** Performs `goToDefinition` on each key and value. */ diff --git a/tests/cases/fourslash/goToDefinitionAcrossMultipleProjects.ts b/tests/cases/fourslash/goToDefinitionAcrossMultipleProjects.ts index 7c0565c626a8f..5447609c02785 100644 --- a/tests/cases/fourslash/goToDefinitionAcrossMultipleProjects.ts +++ b/tests/cases/fourslash/goToDefinitionAcrossMultipleProjects.ts @@ -9,6 +9,6 @@ //@Filename: c.ts /////// /////// -/////*use*/x++; +////[|/*use*/x|]++; verify.goToDefinition("use", ["def1", "def2"]); diff --git a/tests/cases/fourslash/goToDefinitionAlias.ts b/tests/cases/fourslash/goToDefinitionAlias.ts index 22aa049fde3a8..66afe07b6334f 100644 --- a/tests/cases/fourslash/goToDefinitionAlias.ts +++ b/tests/cases/fourslash/goToDefinitionAlias.ts @@ -7,12 +7,12 @@ ////} //// ////// Type position -////var t1: /*alias1Type*/alias1.IFoo; -////var t2: Module./*alias2Type*/alias2.IFoo; +////var t1: [|/*alias1Type*/alias1|].IFoo; +////var t2: Module.[|/*alias2Type*/alias2|].IFoo; //// ////// Value posistion -////var v1 = new /*alias1Value*/alias1.Foo(); -////var v2 = new Module./*alias2Value*/alias2.Foo(); +////var v1 = new [|/*alias1Value*/alias1|].Foo(); +////var v2 = new Module.[|/*alias2Value*/alias2|].Foo(); // @Filename: a.ts diff --git a/tests/cases/fourslash/goToDefinitionApparentTypeProperties.ts b/tests/cases/fourslash/goToDefinitionApparentTypeProperties.ts index dd0d91810c498..5d4ec89638064 100644 --- a/tests/cases/fourslash/goToDefinitionApparentTypeProperties.ts +++ b/tests/cases/fourslash/goToDefinitionApparentTypeProperties.ts @@ -5,7 +5,7 @@ ////} //// ////var o = 0; -////o./*reference1*/myObjectMethod(); -////o["/*reference2*/myObjectMethod"](); +////o.[|/*reference1*/myObjectMethod|](); +////o[[|"/*reference2*/myObjectMethod"|]](); verify.goToDefinition(["reference1", "reference2"], "definition"); diff --git a/tests/cases/fourslash/goToDefinitionConstructorOfClassExpression01.ts b/tests/cases/fourslash/goToDefinitionConstructorOfClassExpression01.ts index 4b774b8b0ee2d..b9f17611b18a5 100644 --- a/tests/cases/fourslash/goToDefinitionConstructorOfClassExpression01.ts +++ b/tests/cases/fourslash/goToDefinitionConstructorOfClassExpression01.ts @@ -2,7 +2,7 @@ ////var x = class C { //// /*definition*/constructor() { -//// var other = new /*usage*/C; +//// var other = new [|/*usage*/C|]; //// } ////} diff --git a/tests/cases/fourslash/goToDefinitionConstructorOfClassWhenClassIsPrecededByNamespace01.ts b/tests/cases/fourslash/goToDefinitionConstructorOfClassWhenClassIsPrecededByNamespace01.ts index bf698c0752da0..8f1bc2496dc0b 100644 --- a/tests/cases/fourslash/goToDefinitionConstructorOfClassWhenClassIsPrecededByNamespace01.ts +++ b/tests/cases/fourslash/goToDefinitionConstructorOfClassWhenClassIsPrecededByNamespace01.ts @@ -9,6 +9,6 @@ //// } ////} //// -////var x = new /*usage*/Foo(); +////var x = new [|/*usage*/Foo|](); verify.goToDefinition("usage", "definition"); diff --git a/tests/cases/fourslash/goToDefinitionConstructorOverloads.ts b/tests/cases/fourslash/goToDefinitionConstructorOverloads.ts index a3a5e3286b28f..edc9e85d44426 100644 --- a/tests/cases/fourslash/goToDefinitionConstructorOverloads.ts +++ b/tests/cases/fourslash/goToDefinitionConstructorOverloads.ts @@ -1,13 +1,13 @@ /// ////class ConstructorOverload { -//// /*constructorOverload1*/constructor(); +//// [|/*constructorOverload1*/constructor|](); //// /*constructorOverload2*/constructor(foo: string); //// /*constructorDefinition*/constructor(foo: any) { } ////} //// -////var constructorOverload = new /*constructorOverloadReference1*/ConstructorOverload(); -////var constructorOverload = new /*constructorOverloadReference2*/ConstructorOverload("foo"); +////var constructorOverload = new [|/*constructorOverloadReference1*/ConstructorOverload|](); +////var constructorOverload = new [|/*constructorOverloadReference2*/ConstructorOverload|]("foo"); verify.goToDefinition({ constructorOverloadReference1: "constructorOverload1", diff --git a/tests/cases/fourslash/goToDefinitionDecorator.ts b/tests/cases/fourslash/goToDefinitionDecorator.ts index bef9c8fa5f11a..535726aef0889 100644 --- a/tests/cases/fourslash/goToDefinitionDecorator.ts +++ b/tests/cases/fourslash/goToDefinitionDecorator.ts @@ -1,9 +1,9 @@ /// // @Filename: b.ts -////@/*decoratorUse*/decorator +////@[|/*decoratorUse*/decorator|] ////class C { -//// @decora/*decoratorFactoryUse*/torFactory(a, "22", true) +//// @[|decora/*decoratorFactoryUse*/torFactory|](a, "22", true) //// method() {} ////} diff --git a/tests/cases/fourslash/goToDefinitionDecoratorOverloads.ts b/tests/cases/fourslash/goToDefinitionDecoratorOverloads.ts index 965c8bbbc6d48..4943c23e392e6 100644 --- a/tests/cases/fourslash/goToDefinitionDecoratorOverloads.ts +++ b/tests/cases/fourslash/goToDefinitionDecoratorOverloads.ts @@ -9,8 +9,8 @@ //// ////declare const s: symbol; ////class C { -//// @/*useDecString*/dec f() {} -//// @/*useDecSymbol*/dec [s]() {} +//// @[|/*useDecString*/dec|] f() {} +//// @[|/*useDecSymbol*/dec|] [s]() {} ////} verify.goToDefinition({ diff --git a/tests/cases/fourslash/goToDefinitionDynamicImport1.ts b/tests/cases/fourslash/goToDefinitionDynamicImport1.ts index 2e93534496a87..d85ba12d72529 100644 --- a/tests/cases/fourslash/goToDefinitionDynamicImport1.ts +++ b/tests/cases/fourslash/goToDefinitionDynamicImport1.ts @@ -3,8 +3,8 @@ // @Filename: foo.ts //// /*Destination*/export function foo() { return "foo"; } -//// import("./f/*1*/oo") -//// var x = import("./fo/*2*/o") +//// import([|"./f/*1*/oo"|]) +//// var x = import([|"./fo/*2*/o"|]) verify.goToDefinition("1", "Destination"); verify.goToDefinition("2", "Destination"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToDefinitionDynamicImport2.ts b/tests/cases/fourslash/goToDefinitionDynamicImport2.ts index c3c213a6cdb25..678628d641fdd 100644 --- a/tests/cases/fourslash/goToDefinitionDynamicImport2.ts +++ b/tests/cases/fourslash/goToDefinitionDynamicImport2.ts @@ -5,7 +5,7 @@ //// var x = import("./foo"); //// x.then(foo => { -//// foo.b/*1*/ar(); +//// foo.[|b/*1*/ar|](); //// }) verify.goToDefinition("1", "Destination"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToDefinitionDynamicImport3.ts b/tests/cases/fourslash/goToDefinitionDynamicImport3.ts index f8c5962f9847e..dc63696d62a52 100644 --- a/tests/cases/fourslash/goToDefinitionDynamicImport3.ts +++ b/tests/cases/fourslash/goToDefinitionDynamicImport3.ts @@ -3,6 +3,6 @@ // @Filename: foo.ts //// export function /*Destination*/bar() { return "bar"; } -//// import('./foo').then(({ ba/*1*/r }) => undefined); +//// import('./foo').then(({ [|ba/*1*/r|] }) => undefined); verify.goToDefinition("1", "Destination"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToDefinitionDynamicImport4.ts b/tests/cases/fourslash/goToDefinitionDynamicImport4.ts index f8c5962f9847e..dc63696d62a52 100644 --- a/tests/cases/fourslash/goToDefinitionDynamicImport4.ts +++ b/tests/cases/fourslash/goToDefinitionDynamicImport4.ts @@ -3,6 +3,6 @@ // @Filename: foo.ts //// export function /*Destination*/bar() { return "bar"; } -//// import('./foo').then(({ ba/*1*/r }) => undefined); +//// import('./foo').then(({ [|ba/*1*/r|] }) => undefined); verify.goToDefinition("1", "Destination"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToDefinitionExternalModuleName.ts b/tests/cases/fourslash/goToDefinitionExternalModuleName.ts index 705cdd655832b..f91d8a9e34610 100644 --- a/tests/cases/fourslash/goToDefinitionExternalModuleName.ts +++ b/tests/cases/fourslash/goToDefinitionExternalModuleName.ts @@ -1,7 +1,7 @@ /// // @Filename: b.ts -////import n = require('./a/*1*/'); +////import n = require([|'./a/*1*/'|]); ////var x = new n.Foo(); // @Filename: a.ts diff --git a/tests/cases/fourslash/goToDefinitionExternalModuleName2.ts b/tests/cases/fourslash/goToDefinitionExternalModuleName2.ts index 866d21b363292..913b297feb898 100644 --- a/tests/cases/fourslash/goToDefinitionExternalModuleName2.ts +++ b/tests/cases/fourslash/goToDefinitionExternalModuleName2.ts @@ -1,7 +1,7 @@ /// // @Filename: b.ts -////import n = require('./a/*1*/'); +////import n = require([|'./a/*1*/'|]); ////var x = new n.Foo(); // @Filename: a.ts diff --git a/tests/cases/fourslash/goToDefinitionExternalModuleName3.ts b/tests/cases/fourslash/goToDefinitionExternalModuleName3.ts index 7ac0376474d46..d6e28263239d8 100644 --- a/tests/cases/fourslash/goToDefinitionExternalModuleName3.ts +++ b/tests/cases/fourslash/goToDefinitionExternalModuleName3.ts @@ -1,7 +1,7 @@ /// // @Filename: b.ts -////import n = require('e/*1*/'); +////import n = require([|'e/*1*/'|]); ////var x = new n.Foo(); // @Filename: a.ts diff --git a/tests/cases/fourslash/goToDefinitionExternalModuleName5.ts b/tests/cases/fourslash/goToDefinitionExternalModuleName5.ts index 36ae9dd716f53..9dede44a7bcd5 100644 --- a/tests/cases/fourslash/goToDefinitionExternalModuleName5.ts +++ b/tests/cases/fourslash/goToDefinitionExternalModuleName5.ts @@ -1,7 +1,7 @@ /// // @Filename: a.ts -////declare module /*2*/"external/*1*/" { +////declare module /*2*/[|"external/*1*/"|] { //// class Foo { } ////} diff --git a/tests/cases/fourslash/goToDefinitionExternalModuleName6.ts b/tests/cases/fourslash/goToDefinitionExternalModuleName6.ts index a71030628e68f..51b96cfe3baeb 100644 --- a/tests/cases/fourslash/goToDefinitionExternalModuleName6.ts +++ b/tests/cases/fourslash/goToDefinitionExternalModuleName6.ts @@ -1,7 +1,7 @@ /// // @Filename: b.ts -////import * from 'e/*1*/'; +////import * from [|'e/*1*/'|]; // @Filename: a.ts ////declare module /*2*/"e" { diff --git a/tests/cases/fourslash/goToDefinitionExternalModuleName7.ts b/tests/cases/fourslash/goToDefinitionExternalModuleName7.ts index b025944d012d0..591577bf47020 100644 --- a/tests/cases/fourslash/goToDefinitionExternalModuleName7.ts +++ b/tests/cases/fourslash/goToDefinitionExternalModuleName7.ts @@ -1,7 +1,7 @@ /// // @Filename: b.ts -////import {Foo, Bar} from 'e/*1*/'; +////import {Foo, Bar} from [|'e/*1*/'|]; // @Filename: a.ts ////declare module /*2*/"e" { diff --git a/tests/cases/fourslash/goToDefinitionExternalModuleName8.ts b/tests/cases/fourslash/goToDefinitionExternalModuleName8.ts index ca9d7c83e66da..636c234c79e47 100644 --- a/tests/cases/fourslash/goToDefinitionExternalModuleName8.ts +++ b/tests/cases/fourslash/goToDefinitionExternalModuleName8.ts @@ -1,7 +1,7 @@ /// // @Filename: b.ts -////export {Foo, Bar} from 'e/*1*/'; +////export {Foo, Bar} from [|'e/*1*/'|]; // @Filename: a.ts ////declare module /*2*/"e" { diff --git a/tests/cases/fourslash/goToDefinitionExternalModuleName9.ts b/tests/cases/fourslash/goToDefinitionExternalModuleName9.ts index 80971be100faa..60decba626cd5 100644 --- a/tests/cases/fourslash/goToDefinitionExternalModuleName9.ts +++ b/tests/cases/fourslash/goToDefinitionExternalModuleName9.ts @@ -1,7 +1,7 @@ /// // @Filename: b.ts -////export * from 'e/*1*/'; +////export * from [|'e/*1*/'|]; // @Filename: a.ts ////declare module /*2*/"e" { diff --git a/tests/cases/fourslash/goToDefinitionFunctionOverloads.ts b/tests/cases/fourslash/goToDefinitionFunctionOverloads.ts index 60c7a8111ee14..ca3883be86c9f 100644 --- a/tests/cases/fourslash/goToDefinitionFunctionOverloads.ts +++ b/tests/cases/fourslash/goToDefinitionFunctionOverloads.ts @@ -1,12 +1,12 @@ /// -////function /*functionOverload1*/functionOverload(value: number); +////function [|/*functionOverload1*/functionOverload|](value: number); ////function /*functionOverload2*/functionOverload(value: string); ////function /*functionOverloadDefinition*/functionOverload() {} //// -/////*functionOverloadReference1*/functionOverload(123); -/////*functionOverloadReference2*/functionOverload("123"); -/////*brokenOverload*/functionOverload({}); +////[|/*functionOverloadReference1*/functionOverload|](123); +////[|/*functionOverloadReference2*/functionOverload|]("123"); +////[|/*brokenOverload*/functionOverload|]({}); verify.goToDefinition({ functionOverloadReference1: "functionOverload1", diff --git a/tests/cases/fourslash/goToDefinitionFunctionOverloadsInClass.ts b/tests/cases/fourslash/goToDefinitionFunctionOverloadsInClass.ts index 04017123fd872..08ec93b5eeac5 100644 --- a/tests/cases/fourslash/goToDefinitionFunctionOverloadsInClass.ts +++ b/tests/cases/fourslash/goToDefinitionFunctionOverloadsInClass.ts @@ -2,9 +2,9 @@ ////class clsInOverload { //// static fnOverload(); -//// static /*staticFunctionOverload*/fnOverload(foo: string); +//// static [|/*staticFunctionOverload*/fnOverload|](foo: string); //// static /*staticFunctionOverloadDefinition*/fnOverload(foo: any) { } -//// public /*functionOverload*/fnOverload(): any; +//// public [|/*functionOverload*/fnOverload|](): any; //// public fnOverload(foo: string); //// public /*functionOverloadDefinition*/fnOverload(foo: any) { return "foo" } //// diff --git a/tests/cases/fourslash/goToDefinitionImportedNames.ts b/tests/cases/fourslash/goToDefinitionImportedNames.ts index 41a1c443b281b..c525783b9c2b7 100644 --- a/tests/cases/fourslash/goToDefinitionImportedNames.ts +++ b/tests/cases/fourslash/goToDefinitionImportedNames.ts @@ -1,7 +1,7 @@ /// // @Filename: b.ts -////export {/*classAliasDefinition*/Class} from "./a"; +////export {[|/*classAliasDefinition*/Class|]} from "./a"; // @Filename: a.ts diff --git a/tests/cases/fourslash/goToDefinitionImportedNames2.ts b/tests/cases/fourslash/goToDefinitionImportedNames2.ts index fa3c5c862b7d8..58a5d018eefa8 100644 --- a/tests/cases/fourslash/goToDefinitionImportedNames2.ts +++ b/tests/cases/fourslash/goToDefinitionImportedNames2.ts @@ -1,7 +1,7 @@ /// // @Filename: b.ts -////import {/*classAliasDefinition*/Class} from "./a"; +////import {[|/*classAliasDefinition*/Class|]} from "./a"; // @Filename: a.ts diff --git a/tests/cases/fourslash/goToDefinitionImportedNames3.ts b/tests/cases/fourslash/goToDefinitionImportedNames3.ts index b9f598f30cde7..ea52f660c11f2 100644 --- a/tests/cases/fourslash/goToDefinitionImportedNames3.ts +++ b/tests/cases/fourslash/goToDefinitionImportedNames3.ts @@ -1,8 +1,8 @@ /// // @Filename: e.ts -//// import {M, /*classAliasDefinition*/C, I} from "./d"; -//// var c = new /*classReference*/C(); +//// import {M, [|/*classAliasDefinition*/C|], I} from "./d"; +//// var c = new [|/*classReference*/C|](); // @Filename: d.ts diff --git a/tests/cases/fourslash/goToDefinitionImportedNames4.ts b/tests/cases/fourslash/goToDefinitionImportedNames4.ts index 81f2e67126665..435ab41a2ad48 100644 --- a/tests/cases/fourslash/goToDefinitionImportedNames4.ts +++ b/tests/cases/fourslash/goToDefinitionImportedNames4.ts @@ -1,7 +1,7 @@ /// // @Filename: b.ts -////import {Class as /*classAliasDefinition*/ClassAlias} from "./a"; +////import {Class as [|/*classAliasDefinition*/ClassAlias|]} from "./a"; // @Filename: a.ts diff --git a/tests/cases/fourslash/goToDefinitionImportedNames5.ts b/tests/cases/fourslash/goToDefinitionImportedNames5.ts index b78110c95d950..7965b341d9efc 100644 --- a/tests/cases/fourslash/goToDefinitionImportedNames5.ts +++ b/tests/cases/fourslash/goToDefinitionImportedNames5.ts @@ -1,7 +1,7 @@ /// // @Filename: b.ts -////export {Class as /*classAliasDefinition*/ClassAlias} from "./a"; +////export {Class as [|/*classAliasDefinition*/ClassAlias|]} from "./a"; // @Filename: a.ts diff --git a/tests/cases/fourslash/goToDefinitionImportedNames6.ts b/tests/cases/fourslash/goToDefinitionImportedNames6.ts index 21603cded426b..a8acf33e42af0 100644 --- a/tests/cases/fourslash/goToDefinitionImportedNames6.ts +++ b/tests/cases/fourslash/goToDefinitionImportedNames6.ts @@ -1,7 +1,7 @@ /// // @Filename: b.ts -////import /*moduleAliasDefinition*/alias = require("./a"); +////import [|/*moduleAliasDefinition*/alias|] = require("./a"); // @Filename: a.ts diff --git a/tests/cases/fourslash/goToDefinitionImportedNames7.ts b/tests/cases/fourslash/goToDefinitionImportedNames7.ts index bdf1eff86eb77..d798dcfff0c05 100644 --- a/tests/cases/fourslash/goToDefinitionImportedNames7.ts +++ b/tests/cases/fourslash/goToDefinitionImportedNames7.ts @@ -1,7 +1,7 @@ /// // @Filename: b.ts -////import /*classAliasDefinition*/defaultExport from "./a"; +////import [|/*classAliasDefinition*/defaultExport|] from "./a"; // @Filename: a.ts diff --git a/tests/cases/fourslash/goToDefinitionImports.ts b/tests/cases/fourslash/goToDefinitionImports.ts index 4fdaedb5c3db7..1debd3c6b6f9c 100644 --- a/tests/cases/fourslash/goToDefinitionImports.ts +++ b/tests/cases/fourslash/goToDefinitionImports.ts @@ -12,10 +12,10 @@ ////import f, { x } from "./a"; ////import * as /*aDef*/a from "./a"; ////import b = require("./b"); -/////*fUse*/f; -/////*xUse*/x; -/////*aUse*/a; -/////*bUse*/b; +////[|/*fUse*/f|]; +////[|/*xUse*/x|]; +////[|/*aUse*/a|]; +////[|/*bUse*/b|]; verify.goToDefinition({ aUse: "aDef", // Namespace import isn't "skipped" diff --git a/tests/cases/fourslash/goToDefinitionInMemberDeclaration.ts b/tests/cases/fourslash/goToDefinitionInMemberDeclaration.ts index 93be208644083..4a09a931bf6e9 100644 --- a/tests/cases/fourslash/goToDefinitionInMemberDeclaration.ts +++ b/tests/cases/fourslash/goToDefinitionInMemberDeclaration.ts @@ -9,13 +9,13 @@ ////enum /*enumDefinition*/Enum { value1, value2 }; //// ////class /*selfDefinition*/Bar { -//// public _interface: IFo/*interfaceReference*/o = new Fo/*classReferenceInInitializer*/o(); -//// public _class: Fo/*classReference*/o = new Foo(); -//// public _list: IF/*interfaceReferenceInList*/oo[]=[]; -//// public _enum: E/*enumReference*/num = En/*enumReferenceInInitializer*/um.value1; -//// public _self: Ba/*selfReference*/r; +//// public _interface: [|IFo/*interfaceReference*/o|] = new [|Fo/*classReferenceInInitializer*/o|](); +//// public _class: [|Fo/*classReference*/o|] = new Foo(); +//// public _list: [|IF/*interfaceReferenceInList*/oo|][]=[]; +//// public _enum: [|E/*enumReference*/num|] = [|En/*enumReferenceInInitializer*/um|].value1; +//// public _self: [|Ba/*selfReference*/r|]; //// -//// constructor(public _inConstructor: IFo/*interfaceReferenceInConstructor*/o) { +//// constructor(public _inConstructor: [|IFo/*interfaceReferenceInConstructor*/o|]) { //// } ////} diff --git a/tests/cases/fourslash/goToDefinitionJsModuleName.ts b/tests/cases/fourslash/goToDefinitionJsModuleName.ts index cdd322158f7a7..8514e7070e465 100644 --- a/tests/cases/fourslash/goToDefinitionJsModuleName.ts +++ b/tests/cases/fourslash/goToDefinitionJsModuleName.ts @@ -5,6 +5,6 @@ /////*2*/module.exports = {}; // @Filename: bar.js -////var x = require(/*1*/"./foo"); +////var x = require([|/*1*/"./foo"|]); verify.goToDefinition("1", "2"); diff --git a/tests/cases/fourslash/goToDefinitionLabels.ts b/tests/cases/fourslash/goToDefinitionLabels.ts index 5cbf3ac8f2f05..3736d9207eeb0 100644 --- a/tests/cases/fourslash/goToDefinitionLabels.ts +++ b/tests/cases/fourslash/goToDefinitionLabels.ts @@ -2,9 +2,9 @@ /////*label1Definition*/label1: while (true) { //// /*label2Definition*/label2: while (true) { -//// break /*1*/label1; -//// continue /*2*/label2; -//// () => { break /*3*/label1; } +//// break [|/*1*/label1|]; +//// continue [|/*2*/label2|]; +//// () => { break [|/*3*/label1|]; } //// continue /*4*/unknownLabel; //// } ////} diff --git a/tests/cases/fourslash/goToDefinitionMethodOverloads.ts b/tests/cases/fourslash/goToDefinitionMethodOverloads.ts index 4dfe4753ce721..fa67b5dbef5ba 100644 --- a/tests/cases/fourslash/goToDefinitionMethodOverloads.ts +++ b/tests/cases/fourslash/goToDefinitionMethodOverloads.ts @@ -1,22 +1,22 @@ /// ////class MethodOverload { -//// static /*staticMethodOverload1*/method(); +//// static [|/*staticMethodOverload1*/method|](); //// static /*staticMethodOverload2*/method(foo: string); //// static /*staticMethodDefinition*/method(foo?: any) { } -//// public /*instanceMethodOverload1*/method(): any; +//// public [|/*instanceMethodOverload1*/method|](): any; //// public /*instanceMethodOverload2*/method(foo: string); //// public /*instanceMethodDefinition*/method(foo?: any) { return "foo" } ////} ////// static method -////MethodOverload./*staticMethodReference1*/method(); -////MethodOverload./*staticMethodReference2*/method("123"); +////MethodOverload.[|/*staticMethodReference1*/method|](); +////MethodOverload.[|/*staticMethodReference2*/method|]("123"); ////// instance method ////var methodOverload = new MethodOverload(); -////methodOverload./*instanceMethodReference1*/method(); -////methodOverload./*instanceMethodReference2*/method("456"); +////methodOverload.[|/*instanceMethodReference1*/method|](); +////methodOverload.[|/*instanceMethodReference2*/method|]("456"); verify.goToDefinition({ staticMethodReference1: "staticMethodOverload1", diff --git a/tests/cases/fourslash/goToDefinitionMultipleDefinitions.ts b/tests/cases/fourslash/goToDefinitionMultipleDefinitions.ts index fb022f7711fde..99b6d32e7f39b 100644 --- a/tests/cases/fourslash/goToDefinitionMultipleDefinitions.ts +++ b/tests/cases/fourslash/goToDefinitionMultipleDefinitions.ts @@ -14,7 +14,7 @@ //// instance3: number; ////} //// -////var ifoo: IFo/*interfaceReference*/o; +////var ifoo: [|IFo/*interfaceReference*/o|]; verify.goToDefinition("interfaceReference", ["interfaceDefinition1", "interfaceDefinition2", "interfaceDefinition3"]); @@ -29,6 +29,6 @@ verify.goToDefinition("interfaceReference", ["interfaceDefinition1", "interfaceD ////} // @Filename: e.ts -////Modul/*moduleReference*/e; +////[|Modul/*moduleReference*/e|]; verify.goToDefinition("moduleReference", ["moduleDefinition1", "moduleDefinition2"]); diff --git a/tests/cases/fourslash/goToDefinitionObjectBindingElementPropertyName01.ts b/tests/cases/fourslash/goToDefinitionObjectBindingElementPropertyName01.ts index 32b08ab710d57..1bcae72797166 100644 --- a/tests/cases/fourslash/goToDefinitionObjectBindingElementPropertyName01.ts +++ b/tests/cases/fourslash/goToDefinitionObjectBindingElementPropertyName01.ts @@ -6,6 +6,6 @@ ////} //// ////var foo: I; -////var { /*use*/property1: prop1 } = foo; +////var { [|/*use*/property1|]: prop1 } = foo; verify.goToDefinition("use", "def"); diff --git a/tests/cases/fourslash/goToDefinitionObjectLiteralProperties1.ts b/tests/cases/fourslash/goToDefinitionObjectLiteralProperties1.ts index a1c22ca4ca395..0024682dc71d3 100644 --- a/tests/cases/fourslash/goToDefinitionObjectLiteralProperties1.ts +++ b/tests/cases/fourslash/goToDefinitionObjectLiteralProperties1.ts @@ -5,11 +5,11 @@ //// } //// function foo(arg: PropsBag) {} //// foo({ -//// pr/*p1*/opx: 10 +//// [|pr/*p1*/opx|]: 10 //// }) //// function bar(firstarg: boolean, secondarg: PropsBag) {} //// bar(true, { -//// pr/*p2*/opx: 10 +//// [|pr/*p2*/opx|]: 10 //// }) diff --git a/tests/cases/fourslash/goToDefinitionObjectSpread.ts b/tests/cases/fourslash/goToDefinitionObjectSpread.ts index b23d0a8044832..918fa555f8649 100644 --- a/tests/cases/fourslash/goToDefinitionObjectSpread.ts +++ b/tests/cases/fourslash/goToDefinitionObjectSpread.ts @@ -5,5 +5,5 @@ ////let a1: A1; ////let a2: A2; ////let a12 = { ...a1, ...a2 }; -////a12.a/*3*/; +////a12.[|a/*3*/|]; verify.goToDefinition('3', [ '1', '2' ]); diff --git a/tests/cases/fourslash/goToDefinitionOverloadsInMultiplePropertyAccesses.ts b/tests/cases/fourslash/goToDefinitionOverloadsInMultiplePropertyAccesses.ts index 04a07f41a7f29..9898b6dad1ec6 100644 --- a/tests/cases/fourslash/goToDefinitionOverloadsInMultiplePropertyAccesses.ts +++ b/tests/cases/fourslash/goToDefinitionOverloadsInMultiplePropertyAccesses.ts @@ -9,6 +9,6 @@ //// export function f(value: number | string) {} //// } ////} -////A.B./*2*/f(""); +////A.B.[|/*2*/f|](""); verify.goToDefinition("2", "1"); diff --git a/tests/cases/fourslash/goToDefinitionPartialImplementation.ts b/tests/cases/fourslash/goToDefinitionPartialImplementation.ts index 81f19b578ed05..00cf6fd181966 100644 --- a/tests/cases/fourslash/goToDefinitionPartialImplementation.ts +++ b/tests/cases/fourslash/goToDefinitionPartialImplementation.ts @@ -13,7 +13,7 @@ //// x: number; //// } //// -//// var x: /*Part2Use*/IA; +//// var x: [|/*Part2Use*/IA|]; ////} verify.goToDefinition("Part2Use", ["Part1Definition", "Part2Definition"]); diff --git a/tests/cases/fourslash/goToDefinitionRest.ts b/tests/cases/fourslash/goToDefinitionRest.ts index 1459b9ffa8845..2577aafb62584 100644 --- a/tests/cases/fourslash/goToDefinitionRest.ts +++ b/tests/cases/fourslash/goToDefinitionRest.ts @@ -7,6 +7,6 @@ ////} ////let t: Gen; ////var { x, ...rest } = t; -////rest./*2*/parent; +////rest.[|/*2*/parent|]; const ranges = test.ranges(); verify.goToDefinition('2', [ '1' ]); diff --git a/tests/cases/fourslash/goToDefinitionShorthandProperty01.ts b/tests/cases/fourslash/goToDefinitionShorthandProperty01.ts index 4107049286c08..7e46894d244cd 100644 --- a/tests/cases/fourslash/goToDefinitionShorthandProperty01.ts +++ b/tests/cases/fourslash/goToDefinitionShorthandProperty01.ts @@ -3,9 +3,9 @@ //// var /*valueDeclaration1*/name = "hello"; //// var /*valueDeclaration2*/id = 100000; //// declare var /*valueDeclaration3*/id; -//// var obj = {/*valueDefinition1*/name, /*valueDefinition2*/id}; -//// obj./*valueReference1*/name; -//// obj./*valueReference2*/id; +//// var obj = {[|/*valueDefinition1*/name|], [|/*valueDefinition2*/id|]}; +//// obj.[|/*valueReference1*/name|]; +//// obj.[|/*valueReference2*/id|]; verify.goToDefinition({ valueDefinition1: "valueDeclaration1", diff --git a/tests/cases/fourslash/goToDefinitionShorthandProperty02.ts b/tests/cases/fourslash/goToDefinitionShorthandProperty02.ts index 0ecdcacdcd6ea..1d78ade426771 100644 --- a/tests/cases/fourslash/goToDefinitionShorthandProperty02.ts +++ b/tests/cases/fourslash/goToDefinitionShorthandProperty02.ts @@ -1,7 +1,7 @@ /// ////let x = { -//// f/*1*/oo +//// [|f/*1*/oo|] ////} verify.goToDefinition("1", []); diff --git a/tests/cases/fourslash/goToDefinitionShorthandProperty03.ts b/tests/cases/fourslash/goToDefinitionShorthandProperty03.ts index 42a9ee0a4d692..3a04d3efa0630 100644 --- a/tests/cases/fourslash/goToDefinitionShorthandProperty03.ts +++ b/tests/cases/fourslash/goToDefinitionShorthandProperty03.ts @@ -1,10 +1,10 @@ /// ////var /*varDef*/x = { -//// /*varProp*/x +//// [|/*varProp*/x|] ////} ////let /*letDef*/y = { -//// /*letProp*/y +//// [|/*letProp*/y|] ////} verify.goToDefinition({ diff --git a/tests/cases/fourslash/goToDefinitionSimple.ts b/tests/cases/fourslash/goToDefinitionSimple.ts index 9ae02f26bf2c9..3d1cdd632ba28 100644 --- a/tests/cases/fourslash/goToDefinitionSimple.ts +++ b/tests/cases/fourslash/goToDefinitionSimple.ts @@ -4,7 +4,7 @@ ////class /*2*/c { } // @Filename: Consumption.ts -//// var n = new /*1*/c(); -//// var n = new c/*3*/(); +//// var n = new [|/*1*/c|](); +//// var n = new [|c/*3*/|](); verify.goToDefinition(["1", "3"], "2"); diff --git a/tests/cases/fourslash/goToDefinitionTaggedTemplateOverloads.ts b/tests/cases/fourslash/goToDefinitionTaggedTemplateOverloads.ts index b01bace4febb1..fcb28f86d0572 100644 --- a/tests/cases/fourslash/goToDefinitionTaggedTemplateOverloads.ts +++ b/tests/cases/fourslash/goToDefinitionTaggedTemplateOverloads.ts @@ -4,8 +4,8 @@ ////function /*defFBool*/f(strs: TemplateStringsArray, x: boolean): void; ////function f(strs: TemplateStringsArray, x: number | boolean) {} //// -/////*useFNumber*/f`${0}`; -/////*useFBool*/f`${false}`; +////[|/*useFNumber*/f|]`${0}`; +////[|/*useFBool*/f|]`${false}`; verify.goToDefinition({ useFNumber: "defFNumber", diff --git a/tests/cases/fourslash/goToDefinitionThis.ts b/tests/cases/fourslash/goToDefinitionThis.ts index 923fb6c8febde..88cbcb8ca9631 100644 --- a/tests/cases/fourslash/goToDefinitionThis.ts +++ b/tests/cases/fourslash/goToDefinitionThis.ts @@ -1,11 +1,11 @@ /// ////function f(/*fnDecl*/this: number) { -//// return /*fnUse*/this; +//// return [|/*fnUse*/this|]; ////} ////class /*cls*/C { -//// constructor() { return /*clsUse*/this; } -//// get self(/*getterDecl*/this: number) { return /*getterUse*/this; } +//// constructor() { return [|/*clsUse*/this|]; } +//// get self(/*getterDecl*/this: number) { return [|/*getterUse*/this|]; } ////} verify.goToDefinition({ diff --git a/tests/cases/fourslash/goToDefinitionTypePredicate.ts b/tests/cases/fourslash/goToDefinitionTypePredicate.ts index 17e6fc1be6b25..9988611885c67 100644 --- a/tests/cases/fourslash/goToDefinitionTypePredicate.ts +++ b/tests/cases/fourslash/goToDefinitionTypePredicate.ts @@ -1,7 +1,7 @@ /// //// class /*classDeclaration*/A {} -//// function f(/*parameterDeclaration*/parameter: any): /*parameterName*/parameter is /*typeReference*/A { +//// function f(/*parameterDeclaration*/parameter: any): [|/*parameterName*/parameter|] is [|/*typeReference*/A|] { //// return typeof parameter === "string"; //// } diff --git a/tests/cases/fourslash/goToDefinitionUnionTypeProperty1.ts b/tests/cases/fourslash/goToDefinitionUnionTypeProperty1.ts index 82bd07e32f04f..6baca39e01181 100644 --- a/tests/cases/fourslash/goToDefinitionUnionTypeProperty1.ts +++ b/tests/cases/fourslash/goToDefinitionUnionTypeProperty1.ts @@ -12,7 +12,7 @@ //// ////var x : One | Two; //// -////x./*propertyReference*/commonProperty; +////x.[|/*propertyReference*/commonProperty|]; ////x./*3*/commonFunction; verify.goToDefinition("propertyReference", ["propertyDefinition1", "propertyDefinition2"]); diff --git a/tests/cases/fourslash/goToDefinitionUnionTypeProperty2.ts b/tests/cases/fourslash/goToDefinitionUnionTypeProperty2.ts index 22ffb906e8e5a..3ade25ca62267 100644 --- a/tests/cases/fourslash/goToDefinitionUnionTypeProperty2.ts +++ b/tests/cases/fourslash/goToDefinitionUnionTypeProperty2.ts @@ -14,6 +14,6 @@ //// ////var x : One | Two; //// -////x.common./*propertyReference*/a; +////x.common.[|/*propertyReference*/a|]; verify.goToDefinition("propertyReference", ["propertyDefinition2", "propertyDefinition1"]); diff --git a/tests/cases/fourslash/goToDefinitionUnionTypeProperty3.ts b/tests/cases/fourslash/goToDefinitionUnionTypeProperty3.ts index fde4d2319fec6..3f5666f19b884 100644 --- a/tests/cases/fourslash/goToDefinitionUnionTypeProperty3.ts +++ b/tests/cases/fourslash/goToDefinitionUnionTypeProperty3.ts @@ -7,6 +7,6 @@ ////var strings: string[]; ////var numbers: number[]; //// -////var x = (strings || numbers)./*usage*/specialPop() +////var x = (strings || numbers).[|/*usage*/specialPop|]() verify.goToDefinition("usage", "definition"); diff --git a/tests/cases/fourslash/goToDefinitionUnionTypeProperty4.ts b/tests/cases/fourslash/goToDefinitionUnionTypeProperty4.ts index f69554098c52a..a4c5996159265 100644 --- a/tests/cases/fourslash/goToDefinitionUnionTypeProperty4.ts +++ b/tests/cases/fourslash/goToDefinitionUnionTypeProperty4.ts @@ -16,6 +16,6 @@ ////var magnitude: Magnitude; ////var snapcrackle: SnapCrackle; //// -////var x = (snapcrackle || magnitude || art)./*usage*/pop; +////var x = (snapcrackle || magnitude || art).[|/*usage*/pop|]; verify.goToDefinition("usage", ["def1", "def2", "def3"]); diff --git a/tests/cases/fourslash/goToDefinition_super.ts b/tests/cases/fourslash/goToDefinition_super.ts index 115e4a4a6edc5..22f00aff7dc34 100644 --- a/tests/cases/fourslash/goToDefinition_super.ts +++ b/tests/cases/fourslash/goToDefinition_super.ts @@ -7,10 +7,10 @@ ////class /*B*/B extends A {} ////class C extends B { //// constructor() { -//// /*super*/super(); +//// [|/*super*/super|](); //// } //// method() { -//// /*superExpression*/super.x(); +//// [|/*superExpression*/super|].x(); //// } ////} ////class D { diff --git a/tests/cases/fourslash/goToDefinition_untypedModule.ts b/tests/cases/fourslash/goToDefinition_untypedModule.ts index fe29f7104cfa7..8c9e83711a931 100644 --- a/tests/cases/fourslash/goToDefinition_untypedModule.ts +++ b/tests/cases/fourslash/goToDefinition_untypedModule.ts @@ -5,6 +5,6 @@ // @Filename: /a.ts ////import { /*def*/f } from "foo"; -/////*use*/f(); +////[|/*use*/f|](); verify.goToDefinition("use", "def"); diff --git a/tests/cases/fourslash/goToModuleAliasDefinition.ts b/tests/cases/fourslash/goToModuleAliasDefinition.ts index dfccc3393c59b..98724228a6e4c 100644 --- a/tests/cases/fourslash/goToModuleAliasDefinition.ts +++ b/tests/cases/fourslash/goToModuleAliasDefinition.ts @@ -5,7 +5,7 @@ // @Filename: b.ts //// import /*3*/n = require('a'); -//// var x = new /*1*/n.Foo(); +//// var x = new [|/*1*/n|].Foo(); // Won't-fixed: Should go to '2' instead verify.goToDefinition("1", "3"); diff --git a/tests/cases/fourslash/gotoDefinitionInObjectBindingPattern1.ts b/tests/cases/fourslash/gotoDefinitionInObjectBindingPattern1.ts index 98c06c06d7be4..dcc5a977be581 100644 --- a/tests/cases/fourslash/gotoDefinitionInObjectBindingPattern1.ts +++ b/tests/cases/fourslash/gotoDefinitionInObjectBindingPattern1.ts @@ -7,6 +7,6 @@ //// interface Test { //// /*destination*/prop2: number //// } -//// bar(({pr/*goto*/op2})=>{}); +//// bar(({[|pr/*goto*/op2|]})=>{}); verify.goToDefinition("goto", "destination"); \ No newline at end of file diff --git a/tests/cases/fourslash/gotoDefinitionInObjectBindingPattern2.ts b/tests/cases/fourslash/gotoDefinitionInObjectBindingPattern2.ts index 9e41f646c4635..6d513d6abee3a 100644 --- a/tests/cases/fourslash/gotoDefinitionInObjectBindingPattern2.ts +++ b/tests/cases/fourslash/gotoDefinitionInObjectBindingPattern2.ts @@ -1,7 +1,7 @@ /// //// var p0 = ({a/*1*/a}) => {console.log(aa)}; -//// function f2({ a/*a1*/1, b/*b1*/1 }: { /*a1_dest*/a1: number, /*b1_dest*/b1: number } = { a1: 0, b1: 0 }) {} +//// function f2({ [|a/*a1*/1|], [|b/*b1*/1|] }: { /*a1_dest*/a1: number, /*b1_dest*/b1: number } = { a1: 0, b1: 0 }) {} verify.goToDefinition("1", []); verify.goToDefinition("a1", "a1_dest"); diff --git a/tests/cases/fourslash/gotoDefinitionPropertyAccessExpressionHeritageClause.ts b/tests/cases/fourslash/gotoDefinitionPropertyAccessExpressionHeritageClause.ts index d46ea7c842220..3d58d869c49e2 100644 --- a/tests/cases/fourslash/gotoDefinitionPropertyAccessExpressionHeritageClause.ts +++ b/tests/cases/fourslash/gotoDefinitionPropertyAccessExpressionHeritageClause.ts @@ -4,7 +4,7 @@ //// function foo() { //// return {/*refB*/B: B}; //// } -//// class C extends (foo())./*B*/B {} -//// class C1 extends foo()./*B1*/B {} +//// class C extends (foo()).[|/*B*/B|] {} +//// class C1 extends foo().[|/*B1*/B|] {} verify.goToDefinition([["B", "refB"], ["B1", "refB"]]); \ No newline at end of file diff --git a/tests/cases/fourslash/javaScriptClass3.ts b/tests/cases/fourslash/javaScriptClass3.ts index fd67f6f53a536..60f51b4ac791c 100644 --- a/tests/cases/fourslash/javaScriptClass3.ts +++ b/tests/cases/fourslash/javaScriptClass3.ts @@ -12,8 +12,8 @@ //// method() { return this.alpha; } //// } //// var x = new Foo(); -//// x.alpha/*src1*/; -//// x.beta/*src2*/; +//// x.[|alpha/*src1*/|]; +//// x.[|beta/*src2*/|]; verify.goToDefinition({ src1: "dst1", diff --git a/tests/cases/fourslash/jsdocTypedefTagServices.ts b/tests/cases/fourslash/jsdocTypedefTagServices.ts index c97707e4d255b..e4b262c3ee43e 100644 --- a/tests/cases/fourslash/jsdocTypedefTagServices.ts +++ b/tests/cases/fourslash/jsdocTypedefTagServices.ts @@ -10,7 +10,7 @@ //// */ /////** -//// * @type {/*use*/[|Product|]} +//// * @type {[|/*use*/Product|]} //// */ ////const product = null; diff --git a/tests/cases/fourslash/server/definition01.ts b/tests/cases/fourslash/server/definition01.ts index 7889d185fcd72..70921b72ed409 100644 --- a/tests/cases/fourslash/server/definition01.ts +++ b/tests/cases/fourslash/server/definition01.ts @@ -1,7 +1,7 @@ /// // @Filename: b.ts -////import n = require('./a/*1*/'); +////import n = require([|'./a/*1*/'|]); ////var x = new n.Foo(); // @Filename: a.ts diff --git a/tests/cases/fourslash/server/jsdocTypedefTagGoToDefinition.ts b/tests/cases/fourslash/server/jsdocTypedefTagGoToDefinition.ts index 000adef90815f..dd72fdd42addb 100644 --- a/tests/cases/fourslash/server/jsdocTypedefTagGoToDefinition.ts +++ b/tests/cases/fourslash/server/jsdocTypedefTagGoToDefinition.ts @@ -14,10 +14,10 @@ //// */ //// //// /** @type {Person} */ -//// var person; person.personName/*3*/ +//// var person; person.[|personName/*3*/|] //// //// /** @type {Animal} */ -//// var animal; animal.animalName/*4*/ +//// var animal; animal.[|animalName/*4*/|] verify.goToDefinition({ 3: "1", diff --git a/tests/cases/fourslash/tsxGoToDefinitionClasses.ts b/tests/cases/fourslash/tsxGoToDefinitionClasses.ts index 688ce879adfae..f0b58155bf5a8 100644 --- a/tests/cases/fourslash/tsxGoToDefinitionClasses.ts +++ b/tests/cases/fourslash/tsxGoToDefinitionClasses.ts @@ -11,9 +11,9 @@ //// /*pt*/foo: string; //// } //// } -//// var x = ; -//// var y = ; -//// var z = ; +//// var x = <[|My/*c*/Class|] />; +//// var y = ; +//// var z = <[|MyCl/*w*/ass|] wrong= 'hello' />; verify.goToDefinition({ c: "ct", diff --git a/tests/cases/fourslash/tsxGoToDefinitionIntrinsics.ts b/tests/cases/fourslash/tsxGoToDefinitionIntrinsics.ts index a82e813baa73d..9b202a64c213e 100644 --- a/tests/cases/fourslash/tsxGoToDefinitionIntrinsics.ts +++ b/tests/cases/fourslash/tsxGoToDefinitionIntrinsics.ts @@ -11,9 +11,9 @@ //// /*st*/span: { n: string; }; //// } //// } -//// var x = ; -//// var y = ; -//// var z =
; +//// var x = <[|di/*ds*/v|] />; +//// var y = <[|s/*ss*/pan|] />; +//// var z =
; verify.goToDefinition({ ds: "dt", diff --git a/tests/cases/fourslash/tsxGoToDefinitionStatelessFunction1.ts b/tests/cases/fourslash/tsxGoToDefinitionStatelessFunction1.ts index d620b3585af8e..6ef0e93445fb3 100644 --- a/tests/cases/fourslash/tsxGoToDefinitionStatelessFunction1.ts +++ b/tests/cases/fourslash/tsxGoToDefinitionStatelessFunction1.ts @@ -16,10 +16,10 @@ //// /*pt2*/optional?: boolean //// } //// declare function /*opt*/Opt(attributes: OptionPropBag): JSX.Element; -//// let opt = ; -//// let opt1 = ; -//// let opt2 = ; -//// let opt3 = ; +//// let opt = <[|O/*one*/pt|] />; +//// let opt1 = <[|Op/*two*/t|] [|pr/*p1*/opx|]={100} />; +//// let opt2 = <[|Op/*three*/t|] propx={100} [|opt/*p2*/ional|] />; +//// let opt3 = <[|Op/*four*/t|] wr/*p3*/ong />; verify.goToDefinition({ one: "opt", diff --git a/tests/cases/fourslash/tsxGoToDefinitionStatelessFunction2.ts b/tests/cases/fourslash/tsxGoToDefinitionStatelessFunction2.ts index 177379832307c..9d5efe2442be5 100644 --- a/tests/cases/fourslash/tsxGoToDefinitionStatelessFunction2.ts +++ b/tests/cases/fourslash/tsxGoToDefinitionStatelessFunction2.ts @@ -23,12 +23,12 @@ //// declare function /*firstSource*/MainButton(buttonProps: ButtonProps): JSX.Element; //// declare function /*secondSource*/MainButton(linkProps: LinkProps): JSX.Element; //// declare function /*thirdSource*/MainButton(props: ButtonProps | LinkProps): JSX.Element; -//// let opt =
; -//// let opt =
; -//// let opt =
{}} />; -//// let opt =
{}} ignore-prop />; -//// let opt =
; -//// let opt =
; +//// let opt = <[|Main/*firstTarget*/Button|] />; +//// let opt = <[|Main/*secondTarget*/Button|] children="chidlren" />; +//// let opt = <[|Main/*thirdTarget*/Button|] onClick={()=>{}} />; +//// let opt = <[|Main/*fourthTarget*/Button|] onClick={()=>{}} ignore-prop />; +//// let opt = <[|Main/*fivethTarget*/Button|] goTo="goTo" />; +//// let opt = <[|Main/*sixthTarget*/Button|] wrong />; verify.goToDefinition({ firstTarget: "thirdSource", diff --git a/tests/cases/fourslash/tsxGoToDefinitionUnionElementType1.ts b/tests/cases/fourslash/tsxGoToDefinitionUnionElementType1.ts index db78f46f3adf1..d6b5dfab70999 100644 --- a/tests/cases/fourslash/tsxGoToDefinitionUnionElementType1.ts +++ b/tests/cases/fourslash/tsxGoToDefinitionUnionElementType1.ts @@ -19,7 +19,7 @@ //// } //// var SFCComp = SFC1 || SFC2; -//// +//// <[|SFC/*one*/Comp|] x /> verify.goToDefinition({ "one": "pt1" diff --git a/tests/cases/fourslash/tsxGoToDefinitionUnionElementType2.ts b/tests/cases/fourslash/tsxGoToDefinitionUnionElementType2.ts index 75ca81998a07f..548ce94db5a29 100644 --- a/tests/cases/fourslash/tsxGoToDefinitionUnionElementType2.ts +++ b/tests/cases/fourslash/tsxGoToDefinitionUnionElementType2.ts @@ -19,7 +19,7 @@ //// var /*pt1*/RCComp = RC1 || RC2; -//// +//// <[|RC/*one*/Comp|] /> verify.goToDefinition({ "one": "pt1" From 051da1111366f74ec9714ca8edfc35570d76ce73 Mon Sep 17 00:00:00 2001 From: Armando Aguirre Date: Mon, 23 Oct 2017 16:03:47 -0700 Subject: [PATCH 06/12] Removed custom guard and added isArray --- src/harness/fourslash.ts | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index a95221e3b26ed..1addfba6396a8 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -641,16 +641,17 @@ namespace FourSlash { const defs = getDefs(); let definitions: ts.DefinitionInfo[] | ReadonlyArray; let testName: string; - if (this.isDefinitionInfoAndBoundSpan(defs)) { + + if (!defs || Array.isArray(defs)) { + definitions = defs as ts.DefinitionInfo[] || []; + testName = "goToDefinitions"; + } + else { this.verifyDefinitionTextSpan(defs, startMarkerName); definitions = defs.definitions; testName = "goToDefinitionsAndBoundSpan"; } - else { - definitions = defs || []; - testName = "goToDefinitions"; - } if (endMarkers.length !== definitions.length) { this.raiseError(`${testName} failed - expected to find ${endMarkers.length} definitions but got ${definitions.length}`); @@ -682,10 +683,6 @@ namespace FourSlash { } } - private isDefinitionInfoAndBoundSpan(definition: ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined): definition is ts.DefinitionInfoAndBoundSpan { - return definition && (definition).definitions !== undefined; - } - public verifyGetEmitOutputForCurrentFile(expected: string): void { const emit = this.languageService.getEmitOutput(this.activeFile.fileName); if (emit.outputFiles.length !== 1) { From f8ccde5218e72d23753d596744797e0318c64f9e Mon Sep 17 00:00:00 2001 From: Armando Aguirre Date: Tue, 24 Oct 2017 11:05:21 -0700 Subject: [PATCH 07/12] Renamed a couple of methods, refactored code for reusability --- src/server/session.ts | 105 ++++++------------ .../reference/api/tsserverlibrary.d.ts | 11 +- 2 files changed, 41 insertions(+), 75 deletions(-) diff --git a/src/server/session.ts b/src/server/session.ts index fb37bf5540850..b5c0c1b4d29f6 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -601,7 +601,7 @@ namespace ts.server { } if (simplifiedResult) { - return this.getSimplifiedDefinitions(definitions, project); + return this.mapFileSpan(definitions, project); } else { return definitions; @@ -624,32 +624,24 @@ namespace ts.server { if (simplifiedResult) { return { - definitions: this.getSimplifiedDefinitions(definitionAndBoundSpan.definitions, project), - textSpan: this.getSimplifiedTextSpan(scriptInfo, definitionAndBoundSpan.textSpan) + definitions: this.mapFileSpan(definitionAndBoundSpan.definitions, project), + textSpan: this.toLocationTextSpan(definitionAndBoundSpan.textSpan, scriptInfo) }; } return definitionAndBoundSpan; } - private getSimplifiedDefinitions(definitions: ReadonlyArray, project: Project): ReadonlyArray { - return definitions.map(def => this.getSimplifiedFileSpan(def.fileName, def.textSpan, project)); + private mapFileSpan(definitions: ReadonlyArray, project: Project): ReadonlyArray { + return definitions.map(def => this.getFileSpan(def.fileName, def.textSpan, project)); } - private getSimplifiedFileSpan(fileName: string, textSpan: TextSpan, project: Project): protocol.FileSpan { + private getFileSpan(fileName: string, textSpan: TextSpan, project: Project): protocol.FileSpan { const scriptInfo = project.getScriptInfo(fileName); - const simplifiedTextSpan = this.getSimplifiedTextSpan(scriptInfo, textSpan); return { file: fileName, - ...simplifiedTextSpan - }; - } - - private getSimplifiedTextSpan(scriptInfo: ScriptInfo, textSpan: TextSpan): protocol.TextSpan { - return { - start: scriptInfo.positionToLineOffset(textSpan.start), - end: scriptInfo.positionToLineOffset(textSpanEnd(textSpan)) + ...this.toLocationTextSpan(textSpan, scriptInfo) }; } @@ -662,14 +654,7 @@ namespace ts.server { return emptyArray; } - return definitions.map(def => { - const defScriptInfo = project.getScriptInfo(def.fileName); - return { - file: def.fileName, - start: defScriptInfo.positionToLineOffset(def.textSpan.start), - end: defScriptInfo.positionToLineOffset(textSpanEnd(def.textSpan)) - }; - }); + return this.mapFileSpan(definitions, project); } private getImplementation(args: protocol.FileLocationRequestArgs, simplifiedResult: boolean): ReadonlyArray | ReadonlyArray { @@ -680,14 +665,7 @@ namespace ts.server { return emptyArray; } if (simplifiedResult) { - return implementations.map(({ fileName, textSpan }) => { - const scriptInfo = project.getScriptInfo(fileName); - return { - file: fileName, - start: scriptInfo.positionToLineOffset(textSpan.start), - end: scriptInfo.positionToLineOffset(textSpanEnd(textSpan)) - }; - }); + return implementations.map(({ fileName, textSpan }) => this.getFileSpan(fileName, textSpan, project)); } else { return implementations; @@ -707,13 +685,10 @@ namespace ts.server { return occurrences.map(occurrence => { const { fileName, isWriteAccess, textSpan, isInString } = occurrence; const scriptInfo = project.getScriptInfo(fileName); - const start = scriptInfo.positionToLineOffset(textSpan.start); - const end = scriptInfo.positionToLineOffset(textSpanEnd(textSpan)); const result: protocol.OccurrencesResponseItem = { - start, - end, file: fileName, isWriteAccess, + ...this.toLocationTextSpan(textSpan, scriptInfo) }; // no need to serialize the property if it is not true if (isInString) { @@ -751,13 +726,13 @@ namespace ts.server { } if (simplifiedResult) { - return documentHighlights.map(convertToDocumentHighlightsItem); + return documentHighlights.map(x => convertToDocumentHighlightsItem(x, this.toLocationTextSpan)); } else { return documentHighlights; } - function convertToDocumentHighlightsItem(documentHighlights: DocumentHighlights): protocol.DocumentHighlightsItem { + function convertToDocumentHighlightsItem(documentHighlights: DocumentHighlights, toLocationSpan: (textSpan: TextSpan, scriptInfo: ScriptInfo) => protocol.TextSpan): protocol.DocumentHighlightsItem { const { fileName, highlightSpans } = documentHighlights; const scriptInfo = project.getScriptInfo(fileName); @@ -766,11 +741,10 @@ namespace ts.server { highlightSpans: highlightSpans.map(convertHighlightSpan) }; - function convertHighlightSpan(highlightSpan: HighlightSpan): protocol.HighlightSpan { + function convertHighlightSpan(this: Session, highlightSpan: HighlightSpan): protocol.HighlightSpan { const { textSpan, kind } = highlightSpan; - const start = scriptInfo.positionToLineOffset(textSpan.start); - const end = scriptInfo.positionToLineOffset(textSpanEnd(textSpan)); - return { start, end, kind }; + + return { kind, ...toLocationSpan(textSpan, scriptInfo) }; } } } @@ -863,8 +837,7 @@ namespace ts.server { const locationScriptInfo = project.getScriptInfo(location.fileName); return { file: location.fileName, - start: locationScriptInfo.positionToLineOffset(location.textSpan.start), - end: locationScriptInfo.positionToLineOffset(textSpanEnd(location.textSpan)), + ...this.toLocationTextSpan(location.textSpan, locationScriptInfo) }; }); }, @@ -959,16 +932,15 @@ namespace ts.server { return references.map(ref => { const refScriptInfo = project.getScriptInfo(ref.fileName); - const start = refScriptInfo.positionToLineOffset(ref.textSpan.start); - const refLineSpan = refScriptInfo.lineToTextSpan(start.line - 1); + const textSpan = this.toLocationTextSpan(ref.textSpan, refScriptInfo); + const refLineSpan = refScriptInfo.lineToTextSpan(textSpan.start.line - 1); const lineText = refScriptInfo.getSnapshot().getText(refLineSpan.start, textSpanEnd(refLineSpan)).replace(/\r|\n/g, ""); return { file: ref.fileName, - start, lineText, - end: refScriptInfo.positionToLineOffset(textSpanEnd(ref.textSpan)), isWriteAccess: ref.isWriteAccess, - isDefinition: ref.isDefinition + isDefinition: ref.isDefinition, + ...textSpan }; }); }, @@ -1107,11 +1079,10 @@ namespace ts.server { return { kind: quickInfo.kind, kindModifiers: quickInfo.kindModifiers, - start: scriptInfo.positionToLineOffset(quickInfo.textSpan.start), - end: scriptInfo.positionToLineOffset(textSpanEnd(quickInfo.textSpan)), displayString, documentation: docString, - tags: quickInfo.tags || [] + tags: quickInfo.tags || [], + ...this.toLocationTextSpan(quickInfo.textSpan, scriptInfo) }; } else { @@ -1201,9 +1172,8 @@ namespace ts.server { return edits.map((edit) => { return { - start: scriptInfo.positionToLineOffset(edit.span.start), - end: scriptInfo.positionToLineOffset(textSpanEnd(edit.span)), - newText: edit.newText ? edit.newText : "" + newText: edit.newText ? edit.newText : "", + ...this.toLocationTextSpan(edit.span, scriptInfo) }; }); } @@ -1219,7 +1189,7 @@ namespace ts.server { return mapDefined(completions && completions.entries, entry => { if (completions.isMemberCompletion || (entry.name.toLowerCase().indexOf(prefix.toLowerCase()) === 0)) { const { name, kind, kindModifiers, sortText, replacementSpan } = entry; - const convertedSpan = replacementSpan ? this.decorateSpan(replacementSpan, scriptInfo) : undefined; + const convertedSpan = replacementSpan ? this.toLocationTextSpan(replacementSpan, scriptInfo) : undefined; return { name, kind, kindModifiers, sortText, replacementSpan: convertedSpan }; } }).sort((a, b) => compareStrings(a.name, b.name)); @@ -1353,13 +1323,13 @@ namespace ts.server { this.projectService.closeClientFile(file); } - private decorateNavigationBarItems(items: NavigationBarItem[], scriptInfo: ScriptInfo): protocol.NavigationBarItem[] { + private mapLocationNavigationBarItems(items: NavigationBarItem[], scriptInfo: ScriptInfo): protocol.NavigationBarItem[] { return map(items, item => ({ text: item.text, kind: item.kind, kindModifiers: item.kindModifiers, - spans: item.spans.map(span => this.decorateSpan(span, scriptInfo)), - childItems: this.decorateNavigationBarItems(item.childItems, scriptInfo), + spans: item.spans.map(span => this.toLocationTextSpan(span, scriptInfo)), + childItems: this.mapLocationNavigationBarItems(item.childItems, scriptInfo), indent: item.indent })); } @@ -1370,21 +1340,21 @@ namespace ts.server { return !items ? undefined : simplifiedResult - ? this.decorateNavigationBarItems(items, this.projectService.getScriptInfoForNormalizedPath(file)) + ? this.mapLocationNavigationBarItems(items, this.projectService.getScriptInfoForNormalizedPath(file)) : items; } - private decorateNavigationTree(tree: NavigationTree, scriptInfo: ScriptInfo): protocol.NavigationTree { + private toLocationNavigationTree(tree: NavigationTree, scriptInfo: ScriptInfo): protocol.NavigationTree { return { text: tree.text, kind: tree.kind, kindModifiers: tree.kindModifiers, - spans: tree.spans.map(span => this.decorateSpan(span, scriptInfo)), - childItems: map(tree.childItems, item => this.decorateNavigationTree(item, scriptInfo)) + spans: tree.spans.map(span => this.toLocationTextSpan(span, scriptInfo)), + childItems: map(tree.childItems, item => this.toLocationNavigationTree(item, scriptInfo)) }; } - private decorateSpan(span: TextSpan, scriptInfo: ScriptInfo): protocol.TextSpan { + private toLocationTextSpan(span: TextSpan, scriptInfo: ScriptInfo): protocol.TextSpan { return { start: scriptInfo.positionToLineOffset(span.start), end: scriptInfo.positionToLineOffset(textSpanEnd(span)) @@ -1397,7 +1367,7 @@ namespace ts.server { return !tree ? undefined : simplifiedResult - ? this.decorateNavigationTree(tree, this.projectService.getScriptInfoForNormalizedPath(file)) + ? this.toLocationNavigationTree(tree, this.projectService.getScriptInfoForNormalizedPath(file)) : tree; } @@ -1416,14 +1386,11 @@ namespace ts.server { return navItems.map((navItem) => { const scriptInfo = project.getScriptInfo(navItem.fileName); - const start = scriptInfo.positionToLineOffset(navItem.textSpan.start); - const end = scriptInfo.positionToLineOffset(textSpanEnd(navItem.textSpan)); const bakedItem: protocol.NavtoItem = { name: navItem.name, kind: navItem.kind, file: navItem.fileName, - start, - end, + ...this.toLocationTextSpan(navItem.textSpan, scriptInfo) }; if (navItem.kindModifiers && (navItem.kindModifiers !== "")) { bakedItem.kindModifiers = navItem.kindModifiers; @@ -1629,7 +1596,7 @@ namespace ts.server { return !spans ? undefined : simplifiedResult - ? spans.map(span => this.decorateSpan(span, scriptInfo)) + ? spans.map(span => this.toLocationTextSpan(span, scriptInfo)) : spans; } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 306f15e952152..9c7d98517e3e2 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -6868,9 +6868,8 @@ declare namespace ts.server { private getDiagnosticsWorker(args, isSemantic, selector, includeLinePosition); private getDefinition(args, simplifiedResult); private getDefinitionAndBoundSpan(args, simplifiedResult); - private getSimplifiedDefinitions(definitions, project); - private getSimplifiedFileSpan(fileName, textSpan, project); - private getSimplifiedTextSpan(scriptInfo, textSpan); + private mapFileSpan(definitions, project); + private getFileSpan(fileName, textSpan, project); private getTypeDefinition(args); private getImplementation(args, simplifiedResult); private getOccurrences(args); @@ -6920,10 +6919,10 @@ declare namespace ts.server { private reload(args, reqSeq); private saveToTmp(fileName, tempFileName); private closeClientFile(fileName); - private decorateNavigationBarItems(items, scriptInfo); + private mapLocationNavigationBarItems(items, scriptInfo); private getNavigationBarItems(args, simplifiedResult); - private decorateNavigationTree(tree, scriptInfo); - private decorateSpan(span, scriptInfo); + private toLocationNavigationTree(tree, scriptInfo); + private toLocationTextSpan(span, scriptInfo); private getNavigationTree(args, simplifiedResult); private getNavigateToItems(args, simplifiedResult); private getSupportedCodeFixes(); From 7f577dcef3bc414a5ea9a87aebeedbc7c035100a Mon Sep 17 00:00:00 2001 From: Armando Aguirre Date: Tue, 24 Oct 2017 14:02:02 -0700 Subject: [PATCH 08/12] Added triple slash support --- src/services/goToDefinition.ts | 14 ++++++++++---- tests/cases/fourslash/goToDefinitionSourceUnit.ts | 2 +- .../goToDefinitionTypeReferenceDirective.ts | 2 +- .../goToDefinitionTypeReferenceDirective.ts | 2 +- .../shims/goToDefinitionTypeReferenceDirective.ts | 2 +- 5 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index eaee0afdd1ec9..0641c814caca2 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -156,10 +156,16 @@ namespace ts.GoToDefinition { return undefined; } - // TODO: Add textSpan for triple slash references (file and type). - const comment = findReferenceInPosition(sourceFile.referencedFiles, position); - if (comment && tryResolveScriptReference(program, sourceFile, comment) || findReferenceInPosition(sourceFile.typeReferenceDirectives, position)) { - return { definitions, textSpan: undefined }; + let comment = findReferenceInPosition(sourceFile.referencedFiles, position); + if (!comment || !tryResolveScriptReference(program, sourceFile, comment)) { + comment = findReferenceInPosition(sourceFile.typeReferenceDirectives, position); + } + + if (comment) { + return { + definitions, + textSpan: createTextSpanFromBounds(comment.pos, comment.end) + }; } const node = getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true); diff --git a/tests/cases/fourslash/goToDefinitionSourceUnit.ts b/tests/cases/fourslash/goToDefinitionSourceUnit.ts index e66b5ef79606f..d823b366eee6b 100644 --- a/tests/cases/fourslash/goToDefinitionSourceUnit.ts +++ b/tests/cases/fourslash/goToDefinitionSourceUnit.ts @@ -4,7 +4,7 @@ //// //MyFile Comments //// //more comments //// /// -//// /// +//// /// //// //// class clsInOverload { //// static fnOverload(); diff --git a/tests/cases/fourslash/goToDefinitionTypeReferenceDirective.ts b/tests/cases/fourslash/goToDefinitionTypeReferenceDirective.ts index ad02bb9d85124..532390fb35e7d 100644 --- a/tests/cases/fourslash/goToDefinitionTypeReferenceDirective.ts +++ b/tests/cases/fourslash/goToDefinitionTypeReferenceDirective.ts @@ -5,7 +5,7 @@ /////*0*/declare let $: {x: number}; // @Filename: src/app.ts -//// /// +//// /// //// $.x; verify.goToDefinition("1", "0"); diff --git a/tests/cases/fourslash/shims-pp/goToDefinitionTypeReferenceDirective.ts b/tests/cases/fourslash/shims-pp/goToDefinitionTypeReferenceDirective.ts index ad02bb9d85124..532390fb35e7d 100644 --- a/tests/cases/fourslash/shims-pp/goToDefinitionTypeReferenceDirective.ts +++ b/tests/cases/fourslash/shims-pp/goToDefinitionTypeReferenceDirective.ts @@ -5,7 +5,7 @@ /////*0*/declare let $: {x: number}; // @Filename: src/app.ts -//// /// +//// /// //// $.x; verify.goToDefinition("1", "0"); diff --git a/tests/cases/fourslash/shims/goToDefinitionTypeReferenceDirective.ts b/tests/cases/fourslash/shims/goToDefinitionTypeReferenceDirective.ts index 4669b7f62e902..f318de7c25e0e 100644 --- a/tests/cases/fourslash/shims/goToDefinitionTypeReferenceDirective.ts +++ b/tests/cases/fourslash/shims/goToDefinitionTypeReferenceDirective.ts @@ -5,7 +5,7 @@ /////*0*/declare let $: {x: number}; // @Filename: src/app.ts -//// /// +//// /// //// $.x; verify.goToDefinition("1", "0"); From 7fd9fe686b6d40c0f2b8db7b6b384d5c9e2d96b3 Mon Sep 17 00:00:00 2001 From: Armando Aguirre Date: Tue, 24 Oct 2017 15:58:43 -0700 Subject: [PATCH 09/12] Rollback spread operator changes --- src/server/session.ts | 59 +++++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/src/server/session.ts b/src/server/session.ts index f6d21fe87725c..a63620252bcb4 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -609,7 +609,7 @@ namespace ts.server { } if (simplifiedResult) { - return this.mapFileSpan(definitions, project); + return this.mapDefinitionInfo(definitions, project); } else { return definitions; @@ -632,7 +632,7 @@ namespace ts.server { if (simplifiedResult) { return { - definitions: this.mapFileSpan(definitionAndBoundSpan.definitions, project), + definitions: this.mapDefinitionInfo(definitionAndBoundSpan.definitions, project), textSpan: this.toLocationTextSpan(definitionAndBoundSpan.textSpan, scriptInfo) }; } @@ -640,16 +640,17 @@ namespace ts.server { return definitionAndBoundSpan; } - private mapFileSpan(definitions: ReadonlyArray, project: Project): ReadonlyArray { - return definitions.map(def => this.getFileSpan(def.fileName, def.textSpan, project)); + private mapDefinitionInfo(definitions: ReadonlyArray, project: Project): ReadonlyArray { + return definitions.map(def => this.toFileSpan(def.fileName, def.textSpan, project)); } - private getFileSpan(fileName: string, textSpan: TextSpan, project: Project): protocol.FileSpan { + private toFileSpan(fileName: string, textSpan: TextSpan, project: Project): protocol.FileSpan { const scriptInfo = project.getScriptInfo(fileName); return { file: fileName, - ...this.toLocationTextSpan(textSpan, scriptInfo) + start: scriptInfo.positionToLineOffset(textSpan.start), + end: scriptInfo.positionToLineOffset(textSpanEnd(textSpan)) }; } @@ -662,7 +663,7 @@ namespace ts.server { return emptyArray; } - return this.mapFileSpan(definitions, project); + return this.mapDefinitionInfo(definitions, project); } private getImplementation(args: protocol.FileLocationRequestArgs, simplifiedResult: boolean): ReadonlyArray | ReadonlyArray { @@ -673,7 +674,7 @@ namespace ts.server { return emptyArray; } if (simplifiedResult) { - return implementations.map(({ fileName, textSpan }) => this.getFileSpan(fileName, textSpan, project)); + return implementations.map(({ fileName, textSpan }) => this.toFileSpan(fileName, textSpan, project)); } else { return implementations; @@ -682,6 +683,7 @@ namespace ts.server { private getOccurrences(args: protocol.FileLocationRequestArgs): ReadonlyArray { const { file, project } = this.getFileAndProject(args); + const position = this.getPositionInFile(args, file); const occurrences = project.getLanguageService().getOccurrencesAtPosition(file, position); @@ -694,9 +696,10 @@ namespace ts.server { const { fileName, isWriteAccess, textSpan, isInString } = occurrence; const scriptInfo = project.getScriptInfo(fileName); const result: protocol.OccurrencesResponseItem = { + start: scriptInfo.positionToLineOffset(textSpan.start), + end: scriptInfo.positionToLineOffset(textSpanEnd(textSpan)), file: fileName, isWriteAccess, - ...this.toLocationTextSpan(textSpan, scriptInfo) }; // no need to serialize the property if it is not true if (isInString) { @@ -734,13 +737,13 @@ namespace ts.server { } if (simplifiedResult) { - return documentHighlights.map(x => convertToDocumentHighlightsItem(x, this.toLocationTextSpan)); + return documentHighlights.map(convertToDocumentHighlightsItem); } else { return documentHighlights; } - function convertToDocumentHighlightsItem(documentHighlights: DocumentHighlights, toLocationSpan: (textSpan: TextSpan, scriptInfo: ScriptInfo) => protocol.TextSpan): protocol.DocumentHighlightsItem { + function convertToDocumentHighlightsItem(documentHighlights: DocumentHighlights): protocol.DocumentHighlightsItem { const { fileName, highlightSpans } = documentHighlights; const scriptInfo = project.getScriptInfo(fileName); @@ -749,10 +752,11 @@ namespace ts.server { highlightSpans: highlightSpans.map(convertHighlightSpan) }; - function convertHighlightSpan(this: Session, highlightSpan: HighlightSpan): protocol.HighlightSpan { + function convertHighlightSpan(highlightSpan: HighlightSpan): protocol.HighlightSpan { const { textSpan, kind } = highlightSpan; - - return { kind, ...toLocationSpan(textSpan, scriptInfo) }; + const start = scriptInfo.positionToLineOffset(textSpan.start); + const end = scriptInfo.positionToLineOffset(textSpanEnd(textSpan)); + return { start, end, kind }; } } } @@ -845,7 +849,8 @@ namespace ts.server { const locationScriptInfo = project.getScriptInfo(location.fileName); return { file: location.fileName, - ...this.toLocationTextSpan(location.textSpan, locationScriptInfo) + start: locationScriptInfo.positionToLineOffset(location.textSpan.start), + end: locationScriptInfo.positionToLineOffset(textSpanEnd(location.textSpan)), }; }); }, @@ -940,15 +945,16 @@ namespace ts.server { return references.map(ref => { const refScriptInfo = project.getScriptInfo(ref.fileName); - const textSpan = this.toLocationTextSpan(ref.textSpan, refScriptInfo); - const refLineSpan = refScriptInfo.lineToTextSpan(textSpan.start.line - 1); + const start = refScriptInfo.positionToLineOffset(ref.textSpan.start); + const refLineSpan = refScriptInfo.lineToTextSpan(start.line - 1); const lineText = refScriptInfo.getSnapshot().getText(refLineSpan.start, textSpanEnd(refLineSpan)).replace(/\r|\n/g, ""); return { file: ref.fileName, + start, lineText, + end: refScriptInfo.positionToLineOffset(textSpanEnd(ref.textSpan)), isWriteAccess: ref.isWriteAccess, - isDefinition: ref.isDefinition, - ...textSpan + isDefinition: ref.isDefinition }; }); }, @@ -1087,10 +1093,11 @@ namespace ts.server { return { kind: quickInfo.kind, kindModifiers: quickInfo.kindModifiers, + start: scriptInfo.positionToLineOffset(quickInfo.textSpan.start), + end: scriptInfo.positionToLineOffset(textSpanEnd(quickInfo.textSpan)), displayString, documentation: docString, - tags: quickInfo.tags || [], - ...this.toLocationTextSpan(quickInfo.textSpan, scriptInfo) + tags: quickInfo.tags || [] }; } else { @@ -1180,8 +1187,9 @@ namespace ts.server { return edits.map((edit) => { return { - newText: edit.newText ? edit.newText : "", - ...this.toLocationTextSpan(edit.span, scriptInfo) + start: scriptInfo.positionToLineOffset(edit.span.start), + end: scriptInfo.positionToLineOffset(textSpanEnd(edit.span)), + newText: edit.newText ? edit.newText : "" }; }); } @@ -1409,7 +1417,8 @@ namespace ts.server { name: navItem.name, kind: navItem.kind, file: navItem.fileName, - ...this.toLocationTextSpan(navItem.textSpan, scriptInfo) + start: scriptInfo.positionToLineOffset(navItem.textSpan.start), + end: scriptInfo.positionToLineOffset(textSpanEnd(navItem.textSpan)) }; if (navItem.kindModifiers && (navItem.kindModifiers !== "")) { bakedItem.kindModifiers = navItem.kindModifiers; @@ -1596,7 +1605,7 @@ namespace ts.server { fileName: change.fileName, textChanges: change.textChanges.map(textChange => this.convertTextChangeToCodeEdit(textChange, scriptInfo)) })); - return { description, changes, commands }; + return { description, changes, commands }; } private mapTextChangesToCodeEdits(project: Project, textChanges: FileTextChanges): protocol.FileCodeEdits { From 5b7abf2425e96489a4d8197d4bbccf0641789b57 Mon Sep 17 00:00:00 2001 From: Armando Aguirre Date: Tue, 24 Oct 2017 15:59:33 -0700 Subject: [PATCH 10/12] Fixed tsserverlibrary.d.ts tests --- tests/baselines/reference/api/tsserverlibrary.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 289137cbcf7be..87d88ba43557a 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -6922,8 +6922,8 @@ declare namespace ts.server { private getDiagnosticsWorker(args, isSemantic, selector, includeLinePosition); private getDefinition(args, simplifiedResult); private getDefinitionAndBoundSpan(args, simplifiedResult); - private mapFileSpan(definitions, project); - private getFileSpan(fileName, textSpan, project); + private mapDefinitionInfo(definitions, project); + private toFileSpan(fileName, textSpan, project); private getTypeDefinition(args); private getImplementation(args, simplifiedResult); private getOccurrences(args); From f3059ce698364872d0bb945672c4278803a81f96 Mon Sep 17 00:00:00 2001 From: Armando Aguirre Date: Tue, 24 Oct 2017 16:08:23 -0700 Subject: [PATCH 11/12] Addressed PR comments. --- src/services/goToDefinition.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index 0641c814caca2..35f4d079e292c 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -156,11 +156,8 @@ namespace ts.GoToDefinition { return undefined; } - let comment = findReferenceInPosition(sourceFile.referencedFiles, position); - if (!comment || !tryResolveScriptReference(program, sourceFile, comment)) { - comment = findReferenceInPosition(sourceFile.typeReferenceDirectives, position); - } - + // Check if position is on triple slash reference. + const comment = findReferenceInPosition(sourceFile.referencedFiles, position) || findReferenceInPosition(sourceFile.typeReferenceDirectives, position); if (comment) { return { definitions, From c4a675ef99d67ac2835ca1756fd4af2c6af86616 Mon Sep 17 00:00:00 2001 From: Armando Aguirre Date: Tue, 24 Oct 2017 16:55:41 -0700 Subject: [PATCH 12/12] Removed double tests of gotoDefinition --- src/harness/fourslash.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index c1f3f36e386da..1885fd4598929 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -583,7 +583,6 @@ namespace FourSlash { } public verifyGoToDefinition(arg0: any, endMarkerNames?: string | string[]) { - this.verifyGoToX(arg0, endMarkerNames, () => this.getGoToDefinition()); this.verifyGoToX(arg0, endMarkerNames, () => this.getGoToDefinitionAndBoundSpan()); }