From a3cd7d8c974986b55e721558636d630393e14c2c Mon Sep 17 00:00:00 2001 From: Zhengbo Li Date: Thu, 1 Sep 2016 15:17:38 -0700 Subject: [PATCH] Avoid returning type symbols for js configured projects (#10654) * Exclude all things from .d.ts files for projects containing only .js and .d.ts files --- src/harness/unittests/compileOnSave.ts | 5 --- .../unittests/tsserverProjectSystem.ts | 38 ++++++++++++++++++- src/server/project.ts | 18 +++++++-- src/server/session.ts | 4 +- src/services/navigateTo.ts | 5 ++- src/services/services.ts | 6 +-- 6 files changed, 61 insertions(+), 15 deletions(-) diff --git a/src/harness/unittests/compileOnSave.ts b/src/harness/unittests/compileOnSave.ts index f1895912230..fde83170f36 100644 --- a/src/harness/unittests/compileOnSave.ts +++ b/src/harness/unittests/compileOnSave.ts @@ -37,11 +37,6 @@ namespace ts.projectSystem { // A compile on save affected file request using file1 let moduleFile1FileListRequest: server.protocol.Request; - function createSession(host: server.ServerHost) { - const typingsInstaller = new TestTypingsInstaller("/a/data/", host); - return new server.Session(host, nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ false); - } - beforeEach(() => { moduleFile1 = { path: "/a/b/moduleFile1.ts", diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 941215fc3ae..8cbc3848cf6 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -113,6 +113,13 @@ namespace ts.projectSystem { fileOrFolderList); } + export function createSession(host: server.ServerHost, typingsInstaller?: server.ITypingsInstaller) { + if (typingsInstaller === undefined) { + typingsInstaller = new TestTypingsInstaller("/a/data/", host); + } + return new server.Session(host, nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ false); + } + export interface CreateProjectServiceParameters { cancellationToken?: HostCancellationToken; logger?: server.Logger; @@ -1699,7 +1706,36 @@ namespace ts.projectSystem { "File '/a/cache/node_modules/@types/lib/index.tsx' does not exist.", "File '/a/cache/node_modules/@types/lib/index.d.ts' exist - use it as a name resolution result.", ]); - checkProjectActualFiles(proj, [ file1.path, lib.path ]); + checkProjectActualFiles(proj, [file1.path, lib.path]); + }); + }); + + describe("navigate-to for javascript project", () => { + function containsNavToItem(items: server.protocol.NavtoItem[], itemName: string, itemKind: string) { + return find(items, item => item.name === itemName && item.kind === itemKind) !== undefined; + } + + it("should not include type symbols", () => { + const file1: FileOrFolder = { + path: "/a/b/file1.js", + content: "function foo() {}" + }; + const configFile: FileOrFolder = { + path: "/a/b/jsconfig.json", + content: "{}" + }; + const host = createServerHost([file1, configFile, libFile]); + const session = createSession(host); + openFilesForSession([file1], session); + + // Try to find some interface type defined in lib.d.ts + const libTypeNavToRequest = makeSessionRequest(server.CommandNames.Navto, { searchValue: "Document", file: file1.path, projectFileName: configFile.path }); + const items: server.protocol.NavtoItem[] = session.executeCommand(libTypeNavToRequest).response; + assert.isFalse(containsNavToItem(items, "Document", "interface"), `Found lib.d.ts symbol in JavaScript project nav to request result.`); + + const localFunctionNavToRequst = makeSessionRequest(server.CommandNames.Navto, { searchValue: "foo", file: file1.path, projectFileName: configFile.path }); + const items2: server.protocol.NavtoItem[] = session.executeCommand(localFunctionNavToRequst).response; + assert.isTrue(containsNavToItem(items2, "foo", "function"), `Cannot find function symbol "foo".`); }); }); } \ No newline at end of file diff --git a/src/server/project.ts b/src/server/project.ts index a627373f2f6..bb4808a767f 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -20,10 +20,16 @@ namespace ts.server { } } + function isJsOrDtsFile(info: ScriptInfo) { + return info.scriptKind === ScriptKind.JS || info.scriptKind == ScriptKind.JSX || fileExtensionIs(info.fileName, ".d.ts"); + } + export function allRootFilesAreJsOrDts(project: Project): boolean { - return project.getRootScriptInfos().every(f => { - return f.scriptKind === ScriptKind.JS || f.scriptKind == ScriptKind.JSX || fileExtensionIs(f.fileName, ".d.ts"); - }); + return project.getRootScriptInfos().every(isJsOrDtsFile); + } + + export function allFilesAreJsOrDts(project: Project): boolean { + return project.getScriptInfos().every(isJsOrDtsFile); } export interface ProjectFilesWithTSDiagnostics extends protocol.ProjectFiles { @@ -63,6 +69,11 @@ namespace ts.server { protected projectErrors: Diagnostic[]; + public isJsOnlyProject() { + this.updateGraph(); + return allFilesAreJsOrDts(this); + } + constructor( readonly projectKind: ProjectKind, readonly projectService: ProjectService, @@ -550,6 +561,7 @@ namespace ts.server { private projectFileWatcher: FileWatcher; private directoryWatcher: FileWatcher; private directoriesWatchedForWildcards: Map; + /** Used for configured projects which may have multiple open roots */ openRefCount = 0; diff --git a/src/server/session.ts b/src/server/session.ts index 4d9c7892b10..1f55673aefe 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -1099,7 +1099,7 @@ namespace ts.server { return combineProjectOutput( projects, project => { - const navItems = project.getLanguageService().getNavigateToItems(args.searchValue, args.maxResultCount); + const navItems = project.getLanguageService().getNavigateToItems(args.searchValue, args.maxResultCount, /*excludeDts*/ project.isJsOnlyProject()); if (!navItems) { return []; } @@ -1137,7 +1137,7 @@ namespace ts.server { else { return combineProjectOutput( projects, - project => project.getLanguageService().getNavigateToItems(args.searchValue, args.maxResultCount), + project => project.getLanguageService().getNavigateToItems(args.searchValue, args.maxResultCount, /*excludeDts*/ project.isJsOnlyProject()), /*comparer*/ undefined, navigateToItemIsEqualTo); } diff --git a/src/services/navigateTo.ts b/src/services/navigateTo.ts index ccded188e61..119727d50f8 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(program: Program, checker: TypeChecker, cancellationToken: CancellationToken, searchValue: string, maxResultCount: number, excludeDts: boolean): NavigateToItem[] { const patternMatcher = createPatternMatcher(searchValue); let rawItems: RawNavigateToItem[] = []; @@ -43,6 +43,9 @@ namespace ts.NavigateTo { const fileName = sourceFile.fileName; const matchKind = bestMatchKind(matches); + if (excludeDts && fileExtensionIs(declaration.getSourceFile().fileName, ".d.ts")) { + continue; + } rawItems.push({ name, fileName, matchKind, isCaseSensitive: allMatchesAreCaseSensitive(matches), declaration }); } } diff --git a/src/services/services.ts b/src/services/services.ts index 39a447a3b74..fa7fd760c5a 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1240,7 +1240,7 @@ namespace ts { /** @deprecated */ getOccurrencesAtPosition(fileName: string, position: number): ReferenceEntry[]; - getNavigateToItems(searchValue: string, maxResultCount?: number): NavigateToItem[]; + getNavigateToItems(searchValue: string, maxResultCount?: number, excludeDts?: boolean): NavigateToItem[]; getNavigationBarItems(fileName: string): NavigationBarItem[]; getOutliningSpans(fileName: string): OutliningSpan[]; @@ -7066,10 +7066,10 @@ namespace ts { } /// NavigateTo - function getNavigateToItems(searchValue: string, maxResultCount?: number): NavigateToItem[] { + function getNavigateToItems(searchValue: string, maxResultCount?: number, excludeDts?: boolean): NavigateToItem[] { synchronizeHostData(); const checker = getProgram().getTypeChecker(); - return ts.NavigateTo.getNavigateToItems(program, checker, cancellationToken, searchValue, maxResultCount); + return ts.NavigateTo.getNavigateToItems(program, checker, cancellationToken, searchValue, maxResultCount, excludeDts); } function getEmitOutput(fileName: string, emitDeclarationsOnly?: boolean): EmitOutput {