diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 78dc8cdb37b67..5fd8194071a38 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -2038,11 +2038,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; @@ -3170,8 +3171,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 2f71c3d5b743e..f053906428087 100644 --- a/src/server/protocol.d.ts +++ b/src/server/protocol.d.ts @@ -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 9cb0fd03d8a4c..ff4e9e2d29f99 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -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 ccded188e618e..a73a82db4b7ab 100644 --- a/src/services/navigateTo.ts +++ b/src/services/navigateTo.ts @@ -2,7 +2,7 @@ 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 146baf96d3221..f3e95e9486853 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1347,10 +1347,11 @@ namespace ts { } /// NavigateTo - function getNavigateToItems(searchValue: string, maxResultCount?: number): NavigateToItem[] { + function getNavigateToItems(searchValue: string, maxResultCount?: number, fileName?: string): NavigateToItem[] { synchronizeHostData(); - const checker = getProgram().getTypeChecker(); - return ts.NavigateTo.getNavigateToItems(program, checker, cancellationToken, searchValue, maxResultCount); + + const sourceFiles = fileName ? [getValidSourceFile(fileName)] : program.getSourceFiles(); + return ts.NavigateTo.getNavigateToItems(sourceFiles, program.getTypeChecker(), cancellationToken, searchValue, maxResultCount); } function getEmitOutput(fileName: string): EmitOutput { diff --git a/src/services/shims.ts b/src/services/shims.ts index 41b366e0857ec..b7de34f53d6e8 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -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 ee3482a8c3ab9..08501dc872549 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -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 c4d1df0a559d3..b8c8402705376 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 0000000000000..db9d169840c14 --- /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);