From ea60e9966d0dca40458f470909d682c9b88245f4 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 15 May 2017 13:13:00 -0700 Subject: [PATCH] Get configFiles as part of file names --- src/compiler/commandLineParser.ts | 9 ++- src/compiler/types.ts | 1 + .../unittests/tsserverProjectSystem.ts | 58 +++++++++---------- src/harness/unittests/typingsInstaller.ts | 20 +++---- src/server/project.ts | 13 ++++- src/server/session.ts | 8 +-- src/server/utilities.ts | 2 +- tests/cases/fourslash/server/projectInfo02.ts | 2 +- .../server/projectWithNonExistentFiles.ts | 2 +- 9 files changed, 67 insertions(+), 48 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 39e45abe712..0da5ce3f6b9 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -1526,7 +1526,7 @@ namespace ts { if (ownConfig.extendedConfigPath) { // copy the resolution stack so it is never reused between branches in potential diamond-problem scenarios. resolutionStack = resolutionStack.concat([resolvedPath]); - const extendedConfig = getExtendedConfig(ownConfig.extendedConfigPath, host, basePath, getCanonicalFileName, + const extendedConfig = getExtendedConfig(sourceFile, ownConfig.extendedConfigPath, host, basePath, getCanonicalFileName, resolutionStack, errors); if (extendedConfig && isSuccessfulParsedTsconfig(extendedConfig)) { const baseRaw = extendedConfig.raw; @@ -1674,6 +1674,7 @@ namespace ts { } function getExtendedConfig( + sourceFile: JsonSourceFile, extendedConfigPath: Path, host: ts.ParseConfigHost, basePath: string, @@ -1682,6 +1683,9 @@ namespace ts { errors: Diagnostic[], ): ParsedTsconfig | undefined { const extendedResult = readJsonConfigFile(extendedConfigPath, path => host.readFile(path)); + if (sourceFile) { + (sourceFile.extendedSourceFiles || (sourceFile.extendedSourceFiles = [])).push(extendedResult.fileName); + } if (extendedResult.parseDiagnostics.length) { errors.push(...extendedResult.parseDiagnostics); return undefined; @@ -1690,6 +1694,9 @@ namespace ts { const extendedDirname = getDirectoryPath(extendedConfigPath); const extendedConfig = parseConfig(/*json*/ undefined, extendedResult, host, extendedDirname, getBaseFileName(extendedConfigPath), resolutionStack, errors); + if (sourceFile) { + sourceFile.extendedSourceFiles.push(...extendedResult.extendedSourceFiles); + } if (isSuccessfulParsedTsconfig(extendedConfig)) { // Update the paths to reflect base path diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 00b3abe113e..c4fe490091d 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2338,6 +2338,7 @@ namespace ts { export interface JsonSourceFile extends SourceFile { jsonObject?: ObjectLiteralExpression; + extendedSourceFiles?: string[]; } export interface ScriptReferenceHost { diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 9e10b7c4fdf..c252b9b4f59 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -731,7 +731,7 @@ namespace ts.projectSystem { checkNumberOfConfiguredProjects(projectService, 1); const project = projectService.configuredProjects[0]; - checkProjectActualFiles(project, [file1.path, libFile.path, file2.path]); + checkProjectActualFiles(project, [file1.path, libFile.path, file2.path, configFile.path]); checkProjectRootFiles(project, [file1.path, file2.path]); // watching all files except one that was open checkWatchedFiles(host, [configFile.path, file2.path, libFile.path]); @@ -988,7 +988,7 @@ namespace ts.projectSystem { checkNumberOfConfiguredProjects(projectService, 1); const project = projectService.configuredProjects[0]; - checkProjectActualFiles(project, [file1.path, nodeModuleFile.path]); + checkProjectActualFiles(project, [file1.path, nodeModuleFile.path, configFile.path]); checkNumberOfInferredProjects(projectService, 1); configFile.content = `{ @@ -999,7 +999,7 @@ namespace ts.projectSystem { }`; host.reloadFS(files); host.triggerFileWatcherCallback(configFile.path); - checkProjectActualFiles(project, [file1.path, classicModuleFile.path]); + checkProjectActualFiles(project, [file1.path, classicModuleFile.path, configFile.path]); checkNumberOfInferredProjects(projectService, 1); }); @@ -1562,7 +1562,7 @@ namespace ts.projectSystem { host.reloadFS([file1, file2, file3, configFile]); host.triggerDirectoryWatcherCallback(getDirectoryPath(configFile.path), configFile.path); checkNumberOfProjects(projectService, { configuredProjects: 1 }); - checkProjectActualFiles(projectService.configuredProjects[0], [file1.path, file2.path, file3.path]); + checkProjectActualFiles(projectService.configuredProjects[0], [file1.path, file2.path, file3.path, configFile.path]); }); it("correctly migrate files between projects", () => { @@ -1620,7 +1620,7 @@ namespace ts.projectSystem { projectService.openClientFile(file1.path); checkNumberOfProjects(projectService, { configuredProjects: 1 }); - checkProjectActualFiles(projectService.configuredProjects[0], [file1.path]); + checkProjectActualFiles(projectService.configuredProjects[0], [file1.path, configFile.path]); host.reloadFS([file1, file2, configFile]); @@ -1651,7 +1651,7 @@ namespace ts.projectSystem { projectService.openClientFile(file1.path); checkNumberOfProjects(projectService, { configuredProjects: 1 }); - checkProjectActualFiles(projectService.configuredProjects[0], [file1.path]); + checkProjectActualFiles(projectService.configuredProjects[0], [file1.path, configFile.path]); const modifiedConfigFile = { path: configFile.path, @@ -1684,7 +1684,7 @@ namespace ts.projectSystem { projectService.openClientFile(file1.path); checkNumberOfProjects(projectService, { configuredProjects: 1 }); - checkProjectActualFiles(projectService.configuredProjects[0], [file1.path, file2.path]); + checkProjectActualFiles(projectService.configuredProjects[0], [file1.path, file2.path, configFile.path]); const modifiedConfigFile = { path: configFile.path, @@ -1765,11 +1765,11 @@ namespace ts.projectSystem { projectService.openClientFile(file1.path); checkNumberOfProjects(projectService, { configuredProjects: 1 }); - checkProjectActualFiles(projectService.configuredProjects[0], [file1.path, file2.path]); + checkProjectActualFiles(projectService.configuredProjects[0], [file1.path, file2.path, config.path]); projectService.openClientFile(file2.path); checkNumberOfProjects(projectService, { configuredProjects: 1 }); - checkProjectActualFiles(projectService.configuredProjects[0], [file1.path, file2.path]); + checkProjectActualFiles(projectService.configuredProjects[0], [file1.path, file2.path, config.path]); host.reloadFS([file1, file2]); host.triggerFileWatcherCallback(config.path, /*removed*/ true); @@ -1804,13 +1804,13 @@ namespace ts.projectSystem { }); projectService.openClientFile(f1.path); projectService.checkNumberOfProjects({ configuredProjects: 1 }); - checkProjectActualFiles(projectService.configuredProjects[0], [f1.path]); + checkProjectActualFiles(projectService.configuredProjects[0], [f1.path, config.path]); projectService.closeClientFile(f1.path); projectService.openClientFile(f2.path); projectService.checkNumberOfProjects({ configuredProjects: 1, inferredProjects: 1 }); - checkProjectActualFiles(projectService.configuredProjects[0], [f1.path]); + checkProjectActualFiles(projectService.configuredProjects[0], [f1.path, config.path]); checkProjectActualFiles(projectService.inferredProjects[0], [f2.path]); }); @@ -1834,7 +1834,7 @@ namespace ts.projectSystem { // HTML file will not be included in any projects yet checkNumberOfProjects(projectService, { configuredProjects: 1 }); - checkProjectActualFiles(projectService.configuredProjects[0], [file1.path]); + checkProjectActualFiles(projectService.configuredProjects[0], [file1.path, config.path]); // Specify .html extension as mixed content const extraFileExtensions = [{ extension: ".html", scriptKind: ScriptKind.JS, isMixedContent: true }]; @@ -1843,7 +1843,7 @@ namespace ts.projectSystem { // HTML file still not included in the project as it is closed checkNumberOfProjects(projectService, { configuredProjects: 1 }); - checkProjectActualFiles(projectService.configuredProjects[0], [file1.path]); + checkProjectActualFiles(projectService.configuredProjects[0], [file1.path, config.path]); // Open HTML file projectService.applyChangesInOpenFiles( @@ -1853,7 +1853,7 @@ namespace ts.projectSystem { // Now HTML file is included in the project checkNumberOfProjects(projectService, { configuredProjects: 1 }); - checkProjectActualFiles(projectService.configuredProjects[0], [file1.path, file2.path]); + checkProjectActualFiles(projectService.configuredProjects[0], [file1.path, file2.path, config.path]); // Check identifiers defined in HTML content are available in .ts file const project = projectService.configuredProjects[0]; @@ -1868,7 +1868,7 @@ namespace ts.projectSystem { // HTML file is still included in project checkNumberOfProjects(projectService, { configuredProjects: 1 }); - checkProjectActualFiles(projectService.configuredProjects[0], [file1.path, file2.path]); + checkProjectActualFiles(projectService.configuredProjects[0], [file1.path, file2.path, config.path]); // Check identifiers defined in HTML content are not available in .ts file completions = project.getLanguageService().getCompletionsAtPosition(file1.path, 5); @@ -2483,7 +2483,7 @@ namespace ts.projectSystem { options: {} }); projectService.checkNumberOfProjects({ configuredProjects: 1 }); - checkProjectActualFiles(projectService.configuredProjects[0], [f1.path]); + checkProjectActualFiles(projectService.configuredProjects[0], [f1.path, tsconfig.path]); // rename tsconfig.json back to lib.ts host.reloadFS([f1, f2]); @@ -2541,8 +2541,8 @@ namespace ts.projectSystem { options: {} }); projectService.checkNumberOfProjects({ configuredProjects: 2 }); - checkProjectActualFiles(projectService.configuredProjects[0], [cLib.path]); - checkProjectActualFiles(projectService.configuredProjects[1], [dLib.path]); + checkProjectActualFiles(projectService.configuredProjects[0], [cLib.path, cTsconfig.path]); + checkProjectActualFiles(projectService.configuredProjects[1], [dLib.path, dTsconfig.path]); // remove one config file projectService.openExternalProject({ @@ -2552,7 +2552,7 @@ namespace ts.projectSystem { }); projectService.checkNumberOfProjects({ configuredProjects: 1 }); - checkProjectActualFiles(projectService.configuredProjects[0], [dLib.path]); + checkProjectActualFiles(projectService.configuredProjects[0], [dLib.path, dTsconfig.path]); // remove second config file projectService.openExternalProject({ @@ -2572,8 +2572,8 @@ namespace ts.projectSystem { options: {} }); projectService.checkNumberOfProjects({ configuredProjects: 2 }); - checkProjectActualFiles(projectService.configuredProjects[0], [cLib.path]); - checkProjectActualFiles(projectService.configuredProjects[1], [dLib.path]); + checkProjectActualFiles(projectService.configuredProjects[0], [cLib.path, cTsconfig.path]); + checkProjectActualFiles(projectService.configuredProjects[1], [dLib.path, dTsconfig.path]); // close all projects - no projects should be opened projectService.closeExternalProject(projectName); @@ -2629,13 +2629,13 @@ namespace ts.projectSystem { projectService.openClientFile(app.path); projectService.checkNumberOfProjects({ configuredProjects: 1 }); - checkProjectActualFiles(projectService.configuredProjects[0], [libES5.path, app.path]); + checkProjectActualFiles(projectService.configuredProjects[0], [libES5.path, app.path, config1.path]); host.reloadFS([libES5, libES2015Promise, app, config2]); host.triggerFileWatcherCallback(config1.path); projectService.checkNumberOfProjects({ configuredProjects: 1 }); - checkProjectActualFiles(projectService.configuredProjects[0], [libES5.path, libES2015Promise.path, app.path]); + checkProjectActualFiles(projectService.configuredProjects[0], [libES5.path, libES2015Promise.path, app.path, config2.path]); }); it("should handle non-existing directories in config file", () => { @@ -2690,7 +2690,7 @@ namespace ts.projectSystem { projectService.openClientFile(f1.path); projectService.checkNumberOfProjects({ configuredProjects: 1 }); - checkProjectActualFiles(projectService.configuredProjects[0], [f1.path, barTypings.path]); + checkProjectActualFiles(projectService.configuredProjects[0], [f1.path, barTypings.path, config.path]); }); }); @@ -2761,7 +2761,7 @@ namespace ts.projectSystem { projectService.openClientFile(f1.path); projectService.checkNumberOfProjects({ configuredProjects: 1 }); - checkProjectActualFiles(projectService.configuredProjects[0], [f1.path, t1.path]); + checkProjectActualFiles(projectService.configuredProjects[0], [f1.path, t1.path, tsconfig.path]); // delete t1 host.reloadFS([f1, tsconfig]); @@ -2770,7 +2770,7 @@ namespace ts.projectSystem { host.runQueuedTimeoutCallbacks(); projectService.checkNumberOfProjects({ configuredProjects: 1 }); - checkProjectActualFiles(projectService.configuredProjects[0], [f1.path]); + checkProjectActualFiles(projectService.configuredProjects[0], [f1.path, tsconfig.path]); // create t2 host.reloadFS([f1, tsconfig, t2]); @@ -2779,7 +2779,7 @@ namespace ts.projectSystem { host.runQueuedTimeoutCallbacks(); projectService.checkNumberOfProjects({ configuredProjects: 1 }); - checkProjectActualFiles(projectService.configuredProjects[0], [f1.path, t2.path]); + checkProjectActualFiles(projectService.configuredProjects[0], [f1.path, t2.path, tsconfig.path]); }); }); @@ -2964,7 +2964,7 @@ namespace ts.projectSystem { const projectService = createProjectService(host); projectService.openClientFile(f1.path); projectService.checkNumberOfProjects({ configuredProjects: 1 }); - checkProjectActualFiles(projectService.configuredProjects[0], [f1.path, node.path]); + checkProjectActualFiles(projectService.configuredProjects[0], [f1.path, node.path, config.path]); }); }); @@ -4040,4 +4040,4 @@ namespace ts.projectSystem { } }); }); -} \ No newline at end of file +} diff --git a/src/harness/unittests/typingsInstaller.ts b/src/harness/unittests/typingsInstaller.ts index af95874a32c..84618c5e524 100644 --- a/src/harness/unittests/typingsInstaller.ts +++ b/src/harness/unittests/typingsInstaller.ts @@ -80,7 +80,7 @@ namespace ts.projectSystem { const service = createProjectService(host, { typingsInstaller: installer }); service.openClientFile(f1.path); service.checkNumberOfProjects({ configuredProjects: 1 }); - checkProjectActualFiles(service.configuredProjects[0], [f1.path, f2.path]); + checkProjectActualFiles(service.configuredProjects[0], [f1.path, f2.path, config.path]); installer.installAll(0); }); }); @@ -133,12 +133,12 @@ namespace ts.projectSystem { checkNumberOfProjects(projectService, { configuredProjects: 1 }); const p = projectService.configuredProjects[0]; - checkProjectActualFiles(p, [file1.path]); + checkProjectActualFiles(p, [file1.path, tsconfig.path]); installer.installAll(/*expectedCount*/ 1); checkNumberOfProjects(projectService, { configuredProjects: 1 }); - checkProjectActualFiles(p, [file1.path, jquery.path]); + checkProjectActualFiles(p, [file1.path, jquery.path, tsconfig.path]); }); it("inferred project (typings installed)", () => { @@ -684,12 +684,12 @@ namespace ts.projectSystem { checkNumberOfProjects(projectService, { configuredProjects: 1 }); const p = projectService.configuredProjects[0]; - checkProjectActualFiles(p, [app.path]); + checkProjectActualFiles(p, [app.path, jsconfig.path]); installer.installAll(/*expectedCount*/ 1); checkNumberOfProjects(projectService, { configuredProjects: 1 }); - checkProjectActualFiles(p, [app.path, jqueryDTS.path]); + checkProjectActualFiles(p, [app.path, jqueryDTS.path, jsconfig.path]); }); it("configured projects discover from bower_components", () => { @@ -730,13 +730,13 @@ namespace ts.projectSystem { checkNumberOfProjects(projectService, { configuredProjects: 1 }); const p = projectService.configuredProjects[0]; - checkProjectActualFiles(p, [app.path]); + checkProjectActualFiles(p, [app.path, jsconfig.path]); checkWatchedFiles(host, [jsconfig.path, "/bower_components", "/node_modules"]); installer.installAll(/*expectedCount*/ 1); checkNumberOfProjects(projectService, { configuredProjects: 1 }); - checkProjectActualFiles(p, [app.path, jqueryDTS.path]); + checkProjectActualFiles(p, [app.path, jqueryDTS.path, jsconfig.path]); }); it("configured projects discover from bower.json", () => { @@ -777,12 +777,12 @@ namespace ts.projectSystem { checkNumberOfProjects(projectService, { configuredProjects: 1 }); const p = projectService.configuredProjects[0]; - checkProjectActualFiles(p, [app.path]); + checkProjectActualFiles(p, [app.path, jsconfig.path]); installer.installAll(/*expectedCount*/ 1); checkNumberOfProjects(projectService, { configuredProjects: 1 }); - checkProjectActualFiles(p, [app.path, jqueryDTS.path]); + checkProjectActualFiles(p, [app.path, jqueryDTS.path, jsconfig.path]); }); it("Malformed package.json should be watched", () => { @@ -1185,4 +1185,4 @@ namespace ts.projectSystem { checkProjectActualFiles(projectService.inferredProjects[0], [f1.path]); }); }); -} \ No newline at end of file +} diff --git a/src/server/project.ts b/src/server/project.ts index 56c394379a0..3095b02c415 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -362,7 +362,7 @@ namespace ts.server { return this.getLanguageService().getEmitOutput(info.fileName, emitOnlyDtsFiles); } - getFileNames(excludeFilesFromExternalLibraries?: boolean) { + getFileNames(excludeFilesFromExternalLibraries?: boolean, excludeConfigFiles?: boolean) { if (!this.program) { return []; } @@ -385,6 +385,17 @@ namespace ts.server { } result.push(asNormalizedPath(f.fileName)); } + if (!excludeConfigFiles) { + const configFile = this.program.getCompilerOptions().configFile; + if (configFile) { + result.push(asNormalizedPath(configFile.fileName)); + if (configFile.extendedSourceFiles) { + for (const f of configFile.extendedSourceFiles) { + result.push(asNormalizedPath(f)); + } + } + } + } return result; } diff --git a/src/server/session.ts b/src/server/session.ts index 50adfcb945b..1de3c3a208b 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -812,15 +812,15 @@ namespace ts.server { } private getProjectInfo(args: protocol.ProjectInfoRequestArgs): protocol.ProjectInfo { - return this.getProjectInfoWorker(args.file, args.projectFileName, args.needFileNameList); + return this.getProjectInfoWorker(args.file, args.projectFileName, args.needFileNameList, /*excludeConfigFiles*/ false); } - private getProjectInfoWorker(uncheckedFileName: string, projectFileName: string, needFileNameList: boolean) { + private getProjectInfoWorker(uncheckedFileName: string, projectFileName: string, needFileNameList: boolean, excludeConfigFiles: boolean) { const { project } = this.getFileAndProjectWorker(uncheckedFileName, projectFileName, /*refreshInferredProjects*/ true, /*errorOnMissingProject*/ true); const projectInfo = { configFileName: project.getProjectName(), languageServiceDisabled: !project.languageServiceEnabled, - fileNames: needFileNameList ? project.getFileNames() : undefined + fileNames: needFileNameList ? project.getFileNames(/*excludeFilesFromExternalLibraries*/ false, excludeConfigFiles) : undefined }; return projectInfo; } @@ -1587,7 +1587,7 @@ namespace ts.server { } private getDiagnosticsForProject(next: NextStep, delay: number, fileName: string): void { - const { fileNames, languageServiceDisabled } = this.getProjectInfoWorker(fileName, /*projectFileName*/ undefined, /*needFileNameList*/ true); + const { fileNames, languageServiceDisabled } = this.getProjectInfoWorker(fileName, /*projectFileName*/ undefined, /*needFileNameList*/ true, /*excludeConfigFiles*/ true); if (languageServiceDisabled) { return; } diff --git a/src/server/utilities.ts b/src/server/utilities.ts index ffc09f29ccd..da84369e8ed 100644 --- a/src/server/utilities.ts +++ b/src/server/utilities.ts @@ -49,7 +49,7 @@ namespace ts.server { export function createInstallTypingsRequest(project: Project, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray, cachePath?: string): DiscoverTypings { return { projectName: project.getProjectName(), - fileNames: project.getFileNames(/*excludeFilesFromExternalLibraries*/ true), + fileNames: project.getFileNames(/*excludeFilesFromExternalLibraries*/ true, /*excludeConfigFiles*/ true), compilerOptions: project.getCompilerOptions(), typeAcquisition, unresolvedImports, diff --git a/tests/cases/fourslash/server/projectInfo02.ts b/tests/cases/fourslash/server/projectInfo02.ts index eb86c721ac7..3077deb453c 100644 --- a/tests/cases/fourslash/server/projectInfo02.ts +++ b/tests/cases/fourslash/server/projectInfo02.ts @@ -10,4 +10,4 @@ ////{ "files": ["a.ts", "b.ts"] } goTo.file("a.ts") -verify.ProjectInfo(["lib.d.ts", "a.ts", "b.ts"]) +verify.ProjectInfo(["lib.d.ts", "a.ts", "b.ts", "tsconfig.json"]) diff --git a/tests/cases/fourslash/server/projectWithNonExistentFiles.ts b/tests/cases/fourslash/server/projectWithNonExistentFiles.ts index ceba136bf96..0e263d9aca6 100644 --- a/tests/cases/fourslash/server/projectWithNonExistentFiles.ts +++ b/tests/cases/fourslash/server/projectWithNonExistentFiles.ts @@ -10,4 +10,4 @@ ////{ "files": ["a.ts", "c.ts", "b.ts"] } goTo.file("a.ts"); -verify.ProjectInfo(["lib.d.ts", "a.ts", "b.ts"]) +verify.ProjectInfo(["lib.d.ts", "a.ts", "b.ts", "tsconfig.json"])