From e038215496fbc0e143d5f4962d8726dedef6dbdb Mon Sep 17 00:00:00 2001 From: Paul van Brenk Date: Mon, 12 Sep 2016 17:17:52 -0700 Subject: [PATCH] Implement NavigateTo for single files, instead of the project. --- src/harness/fourslash.ts | 13 +++++++------ src/server/protocol.d.ts | 7 ++++++- src/server/session.ts | 8 ++++---- src/services/navigateTo.ts | 6 +++--- src/services/services.ts | 9 ++++++--- src/services/shims.ts | 10 +++++----- src/services/types.ts | 4 ++-- tests/cases/fourslash/fourslash.ts | 2 +- .../fourslash/navigateToSingleFileResults.ts | 19 +++++++++++++++++++ 9 files changed, 53 insertions(+), 25 deletions(-) create mode 100644 tests/cases/fourslash/navigateToSingleFileResults.ts diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index b727a2e2cb7..bea59fb4ebc 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -1,4 +1,4 @@ -// +// // Copyright (c) Microsoft Corporation. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -2025,11 +2025,12 @@ namespace FourSlash { } /* - Check number of navigationItems which match both searchValue and matchKind. + Check number of navigationItems which match both searchValue and matchKind, + if a filename is passed in, limit the results to that file. Report an error if expected value and actual value do not match. */ - public verifyNavigationItemsCount(expected: number, searchValue: string, matchKind?: string) { - const items = this.languageService.getNavigateToItems(searchValue); + public verifyNavigationItemsCount(expected: number, searchValue: string, matchKind?: string, fileName?: string) { + const items = this.languageService.getNavigateToItems(searchValue, /*maxResultCount*/ undefined, fileName); let actual = 0; let item: ts.NavigateToItem; @@ -3149,8 +3150,8 @@ namespace FourSlashInterface { this.state.verifyNavigationBar(json); } - public navigationItemsListCount(count: number, searchValue: string, matchKind?: string) { - this.state.verifyNavigationItemsCount(count, searchValue, matchKind); + public navigationItemsListCount(count: number, searchValue: string, matchKind?: string, fileName?: string) { + this.state.verifyNavigationItemsCount(count, searchValue, matchKind, fileName); } public navigationItemsListContains( diff --git a/src/server/protocol.d.ts b/src/server/protocol.d.ts index 2f71c3d5b74..193d0e3e31c 100644 --- a/src/server/protocol.d.ts +++ b/src/server/protocol.d.ts @@ -1,4 +1,4 @@ -/** +/** * Declaration module describing the TypeScript Server protocol */ declare namespace ts.server.protocol { @@ -1141,6 +1141,11 @@ declare namespace ts.server.protocol { * Optional limit on the number of items to return. */ maxResultCount?: number; + /** + * Optional flag to indicate we want results for just the current file + * or the entire project. + */ + currentFileOnly?: boolean; } /** diff --git a/src/server/session.ts b/src/server/session.ts index 9cb0fd03d8a..4ed7434eb90 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -1,4 +1,4 @@ -/// +/// /// /// /// @@ -940,7 +940,7 @@ namespace ts.server { return this.decorateNavigationBarItem(project, fileName, items, compilerService.host.getLineIndex(fileName)); } - private getNavigateToItems(searchValue: string, fileName: string, maxResultCount?: number): protocol.NavtoItem[] { + private getNavigateToItems(searchValue: string, fileName: string, maxResultCount?: number, currentFileOnly?: boolean): protocol.NavtoItem[] { const file = ts.normalizePath(fileName); const info = this.projectService.getScriptInfo(file); const projects = this.projectService.findReferencingProjects(info); @@ -953,7 +953,7 @@ namespace ts.server { projectsWithLanguageServiceEnabeld, (project: Project) => { const compilerService = project.compilerService; - const navItems = compilerService.languageService.getNavigateToItems(searchValue, maxResultCount); + const navItems = compilerService.languageService.getNavigateToItems(searchValue, maxResultCount, currentFileOnly ? fileName : undefined); if (!navItems) { return []; } @@ -1188,7 +1188,7 @@ namespace ts.server { }, [CommandNames.Navto]: (request: protocol.Request) => { const navtoArgs = request.arguments; - return { response: this.getNavigateToItems(navtoArgs.searchValue, navtoArgs.file, navtoArgs.maxResultCount), responseRequired: true }; + return { response: this.getNavigateToItems(navtoArgs.searchValue, navtoArgs.file, navtoArgs.maxResultCount, navtoArgs.currentFileOnly), responseRequired: true }; }, [CommandNames.Brace]: (request: protocol.Request) => { const braceArguments = request.arguments; diff --git a/src/services/navigateTo.ts b/src/services/navigateTo.ts index ccded188e61..1cfceab1779 100644 --- a/src/services/navigateTo.ts +++ b/src/services/navigateTo.ts @@ -1,8 +1,8 @@ -/* @internal */ +/* @internal */ namespace ts.NavigateTo { type RawNavigateToItem = { name: string; fileName: string; matchKind: PatternMatchKind; isCaseSensitive: boolean; declaration: Declaration }; - export function getNavigateToItems(program: Program, checker: TypeChecker, cancellationToken: CancellationToken, searchValue: string, maxResultCount: number): NavigateToItem[] { + export function getNavigateToItems(sourceFiles: SourceFile[], checker: TypeChecker, cancellationToken: CancellationToken, searchValue: string, maxResultCount: number): NavigateToItem[] { const patternMatcher = createPatternMatcher(searchValue); let rawItems: RawNavigateToItem[] = []; @@ -10,7 +10,7 @@ namespace ts.NavigateTo { const baseSensitivity: Intl.CollatorOptions = { sensitivity: "base" }; // Search the declarations in all files and output matched NavigateToItem into array of NavigateToItem[] - forEach(program.getSourceFiles(), sourceFile => { + forEach(sourceFiles, sourceFile => { cancellationToken.throwIfCancellationRequested(); const nameToDeclarations = sourceFile.getNamedDeclarations(); diff --git a/src/services/services.ts b/src/services/services.ts index bdc6fe62d5d..c318801043b 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1,4 +1,4 @@ -/// +/// /// /// @@ -1344,10 +1344,13 @@ namespace ts { } /// NavigateTo - function getNavigateToItems(searchValue: string, maxResultCount?: number): NavigateToItem[] { + function getNavigateToItems(searchValue: string, maxResultCount?: number, fileName?: string): NavigateToItem[] { synchronizeHostData(); + + const sourceFiles = !fileName ? program.getSourceFiles() : [program.getSourceFile(fileName)]; + const checker = getProgram().getTypeChecker(); - return ts.NavigateTo.getNavigateToItems(program, checker, cancellationToken, searchValue, maxResultCount); + return ts.NavigateTo.getNavigateToItems(sourceFiles, checker, cancellationToken, searchValue, maxResultCount); } function getEmitOutput(fileName: string): EmitOutput { diff --git a/src/services/shims.ts b/src/services/shims.ts index 41b366e0857..4a1dc7cf192 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -1,4 +1,4 @@ -// +// // Copyright (c) Microsoft Corporation. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -209,7 +209,7 @@ namespace ts { * Returns a JSON-encoded value of the type: * { name: string; kind: string; kindModifiers: string; containerName: string; containerKind: string; matchKind: string; fileName: string; textSpan: { start: number; length: number}; } [] = []; */ - getNavigateToItems(searchValue: string, maxResultCount?: number): string; + getNavigateToItems(searchValue: string, maxResultCount?: number, fileName?: string): string; /** * Returns a JSON-encoded value of the type: @@ -930,10 +930,10 @@ namespace ts { /// NAVIGATE TO /** Return a list of symbols that are interesting to navigate to */ - public getNavigateToItems(searchValue: string, maxResultCount?: number): string { + public getNavigateToItems(searchValue: string, maxResultCount?: number, fileName?: string): string { return this.forwardJSONCall( - `getNavigateToItems('${searchValue}', ${maxResultCount})`, - () => this.languageService.getNavigateToItems(searchValue, maxResultCount) + `getNavigateToItems('${searchValue}', ${maxResultCount}, ${fileName})`, + () => this.languageService.getNavigateToItems(searchValue, maxResultCount, fileName) ); } diff --git a/src/services/types.ts b/src/services/types.ts index 5b0635e706d..683dbf5f71d 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -1,4 +1,4 @@ -namespace ts { +namespace ts { export interface Node { getSourceFile(): SourceFile; getChildCount(sourceFile?: SourceFile): number; @@ -217,7 +217,7 @@ namespace ts { /** @deprecated */ getOccurrencesAtPosition(fileName: string, position: number): ReferenceEntry[]; - getNavigateToItems(searchValue: string, maxResultCount?: number): NavigateToItem[]; + getNavigateToItems(searchValue: string, maxResultCount?: number, fileName?: string): NavigateToItem[]; getNavigationBarItems(fileName: string): NavigationBarItem[]; getOutliningSpans(fileName: string): OutliningSpan[]; diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index a8216de8145..15beacd49a5 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -208,7 +208,7 @@ declare namespace FourSlashInterface { noDocCommentTemplate(): void; navigationBar(json: any): void; - navigationItemsListCount(count: number, searchValue: string, matchKind?: string): void; + navigationItemsListCount(count: number, searchValue: string, matchKind?: string, fileName?: string): void; navigationItemsListContains(name: string, kind: string, searchValue: string, matchKind: string, fileName?: string, parentName?: string): void; occurrencesAtPositionContains(range: Range, isWriteAccess?: boolean): void; occurrencesAtPositionCount(expectedCount: number): void; diff --git a/tests/cases/fourslash/navigateToSingleFileResults.ts b/tests/cases/fourslash/navigateToSingleFileResults.ts new file mode 100644 index 00000000000..db9d169840c --- /dev/null +++ b/tests/cases/fourslash/navigateToSingleFileResults.ts @@ -0,0 +1,19 @@ +/// + +// @Filename: file1.ts +/////*1*/class Greeter { +//// public hello(name: string) { } +////} +////var x = new Greeter(); +// @Filename: file2.ts +/////*2*/class MyGreeter { +//// public hello(name: string) { } +////} +////class MyOtherGreeter { +//// public hello(name: string) { } +////} + +verify.navigationItemsListCount(3, "hello"); +verify.navigationItemsListCount(1, "hello", undefined, test.marker("1").fileName); +verify.navigationItemsListContains("hello", "method", "hello", "exact", test.marker("1").fileName); +verify.navigationItemsListCount(2, "hello", undefined, test.marker("2").fileName);