From 187576cfdc5b5601b95292dfcc434c9817a3d926 Mon Sep 17 00:00:00 2001 From: Jesse Trinity Date: Mon, 5 Oct 2020 13:44:06 -0700 Subject: [PATCH 01/11] add typeAcquisition:inferTypings --- src/compiler/types.ts | 2 ++ src/jsTyping/jsTyping.ts | 6 +++-- src/server/editorServices.ts | 13 +++++++-- src/server/project.ts | 13 +++++++-- src/server/protocol.ts | 2 ++ src/testRunner/unittests/tsserver/projects.ts | 2 +- .../unittests/tsserver/typingsInstaller.ts | 27 +++++++++++++++++++ .../reference/api/tsserverlibrary.d.ts | 6 +++++ tests/baselines/reference/api/typescript.d.ts | 2 ++ 9 files changed, 66 insertions(+), 7 deletions(-) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index dbc916cd56756..0c8cc90a71cc9 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5845,6 +5845,7 @@ namespace ts { include?: string[]; exclude?: string[]; [option: string]: string[] | boolean | undefined; + inferTypings?: boolean; } export enum ModuleKind { @@ -8147,6 +8148,7 @@ namespace ts { readonly providePrefixAndSuffixTextForRename?: boolean; readonly includePackageJsonAutoImports?: "auto" | "on" | "off"; readonly provideRefactorNotApplicableReason?: boolean; + readonly automaticallyAcquireTypesBasedOnFilenames?: boolean; } /** Represents a bigint literal value without requiring bigint support */ diff --git a/src/jsTyping/jsTyping.ts b/src/jsTyping/jsTyping.ts index ca765bd776fd3..26444ed4390a2 100644 --- a/src/jsTyping/jsTyping.ts +++ b/src/jsTyping/jsTyping.ts @@ -149,8 +149,10 @@ namespace ts.JsTyping { const nodeModulesPath = combinePaths(searchDir, "node_modules"); getTypingNamesFromPackagesFolder(nodeModulesPath, filesToWatch); }); - getTypingNamesFromSourceFileNames(fileNames); - + // filename-based ATA must be explicitly disabled + if(typeAcquisition.inferTypings !== false) { + getTypingNamesFromSourceFileNames(fileNames); + } // add typings for unresolved imports if (unresolvedImports) { const module = deduplicate( diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index d0b4891c96324..f15757dc0c775 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -294,6 +294,7 @@ namespace ts.server { hostInfo: string; extraFileExtensions?: FileExtensionInfo[]; watchOptions?: WatchOptions; + typeAcquisition?: TypeAcquisition; } export interface OpenConfiguredProjectResult { @@ -1377,6 +1378,9 @@ namespace ts.server { ); project.addRoot(info); + if(this.hostConfiguration.typeAcquisition){ + project.setTypeAcquisition(this.hostConfiguration.typeAcquisition); + } if (info.containingProjects[0] !== project) { // Ensure this is first project, we could be in this scenario because info could be part of orphan project info.detachFromProject(project); @@ -2305,7 +2309,7 @@ namespace ts.server { if (watchOptions === undefined) { watchOptions = this.watchOptionsForInferredProjects; } - const project = new InferredProject(this, this.documentRegistry, compilerOptions, watchOptions || undefined, projectRootPath, currentDirectory, this.currentPluginConfigOverrides); + const project = new InferredProject(this, this.documentRegistry, compilerOptions, watchOptions || undefined, projectRootPath, currentDirectory, this.currentPluginConfigOverrides, this.hostConfiguration.typeAcquisition); if (isSingleInferredProject) { this.inferredProjects.unshift(project); } @@ -2764,6 +2768,10 @@ namespace ts.server { this.hostConfiguration.watchOptions = convertWatchOptions(args.watchOptions); this.logger.info(`Host watch options changed to ${JSON.stringify(this.hostConfiguration.watchOptions)}, it will be take effect for next watches.`); } + + if(args.typeAcquisition) { + this.hostConfiguration.typeAcquisition = { ...this.hostConfiguration.typeAcquisition, ...args.typeAcquisition }; + } } } @@ -3515,7 +3523,7 @@ namespace ts.server { const typeAcquisition = proj.typeAcquisition!; Debug.assert(!!typeAcquisition, "proj.typeAcquisition should be set by now"); // If type acquisition has been explicitly disabled, do not exclude anything from the project - if (typeAcquisition.enable === false) { + if (typeAcquisition.enable === false || typeAcquisition.inferTypings === false) { return []; } @@ -3632,6 +3640,7 @@ namespace ts.server { if (proj.typeAcquisition.enable === undefined) { proj.typeAcquisition.enable = hasNoTypeScriptSource(proj.rootFiles.map(f => f.fileName)); } + proj.typeAcquisition.inferTypings = this.hostConfiguration.typeAcquisition?.inferTypings ?? true; const excludedFiles = this.applySafeList(proj); diff --git a/src/server/project.ts b/src/server/project.ts index e372038354320..20eb8ca508b0c 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -1732,6 +1732,8 @@ namespace ts.server { private _isJsInferredProject = false; + private typeAcquisition: TypeAcquisition | undefined; + toggleJsInferredProject(isJsInferredProject: boolean) { if (isJsInferredProject !== this._isJsInferredProject) { this._isJsInferredProject = isJsInferredProject; @@ -1770,7 +1772,8 @@ namespace ts.server { watchOptions: WatchOptions | undefined, projectRootPath: NormalizedPath | undefined, currentDirectory: string | undefined, - pluginConfigOverrides: ESMap | undefined) { + pluginConfigOverrides: ESMap | undefined, + typeAcquisition: TypeAcquisition | undefined) { super(InferredProject.newName(), ProjectKind.Inferred, projectService, @@ -1783,6 +1786,7 @@ namespace ts.server { watchOptions, projectService.host, currentDirectory); + this.typeAcquisition = typeAcquisition; this.projectRootPath = projectRootPath && projectService.toCanonicalFileName(projectRootPath); if (!projectRootPath && !projectService.useSingleInferredProject) { this.canonicalCurrentDirectory = projectService.toCanonicalFileName(this.currentDirectory); @@ -1827,11 +1831,16 @@ namespace ts.server { super.close(); } + setTypeAcquisition(newTypeAcquisition: TypeAcquisition): void { + this.typeAcquisition = this.removeLocalTypingsFromTypeAcquisition(newTypeAcquisition); + } + getTypeAcquisition(): TypeAcquisition { return { enable: allRootFilesAreJsOrDts(this), include: ts.emptyArray, - exclude: ts.emptyArray + exclude: ts.emptyArray, + inferTypings: this.typeAcquisition?.inferTypings }; } } diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 6a52afc81757c..745cb955dabaa 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -1482,6 +1482,8 @@ namespace ts.server.protocol { extraFileExtensions?: FileExtensionInfo[]; watchOptions?: WatchOptions; + + typeAcquisition?: TypeAcquisition; } export const enum WatchFileKind { diff --git a/src/testRunner/unittests/tsserver/projects.ts b/src/testRunner/unittests/tsserver/projects.ts index 2de2da67af3d8..fbeb0a0e6f74b 100644 --- a/src/testRunner/unittests/tsserver/projects.ts +++ b/src/testRunner/unittests/tsserver/projects.ts @@ -402,7 +402,7 @@ namespace ts.projectSystem { projectName, fileNames: [libFile.path, file1.path, constructorFile.path, bliss.path], compilerOptions: { allowNonTsExtensions: true, noEmitForJsFiles: true }, - typeAcquisition: { include: ["blissfuljs"], exclude: [], enable: true }, + typeAcquisition: { include: ["blissfuljs"], exclude: [], enable: true, inferTypings: true }, unresolvedImports: ["s"], projectRootPath: "/", cachePath, diff --git a/src/testRunner/unittests/tsserver/typingsInstaller.ts b/src/testRunner/unittests/tsserver/typingsInstaller.ts index e9c77566b70ba..0d0abd9ba90b9 100644 --- a/src/testRunner/unittests/tsserver/typingsInstaller.ts +++ b/src/testRunner/unittests/tsserver/typingsInstaller.ts @@ -1375,6 +1375,33 @@ namespace ts.projectSystem { assert.deepEqual(result.newTypingNames, ["jquery", "chroma-js"]); }); + it("should not infer typings from filenames with inferTypings:false ", () => { + const app = { + path: "/a/b/app.js", + content: "" + }; + const jquery = { + path: "/a/b/jquery.js", + content: "" + }; + const chroma = { + path: "/a/b/chroma.min.js", + content: "" + }; + + const safeList = new Map(getEntries({ jquery: "jquery", chroma: "chroma-js" })); + + const host = createServerHost([app, jquery, chroma]); + const logger = trackingLogger(); + const result = JsTyping.discoverTypings(host, logger.log, [app.path, jquery.path, chroma.path], getDirectoryPath(app.path), safeList, emptyMap, { enable: true, inferTypings: false }, emptyArray, emptyMap); + const finish = logger.finish(); + assert.deepEqual(finish, [ + "Inferred typings from unresolved imports: []", + 'Result: {"cachedTypingPaths":[],"newTypingNames":[],"filesToWatch":["/a/b/bower_components","/a/b/node_modules"]}', + ], finish.join("\r\n")); + assert.deepEqual(result.newTypingNames, []); + }); + it("should return node for core modules", () => { const f = { path: "/a/b/app.js", diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 15653ecacf258..36a30d4626e05 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2892,6 +2892,7 @@ declare namespace ts { include?: string[]; exclude?: string[]; [option: string]: string[] | boolean | undefined; + inferTypings?: boolean; } export enum ModuleKind { None = 0, @@ -3869,6 +3870,7 @@ declare namespace ts { readonly providePrefixAndSuffixTextForRename?: boolean; readonly includePackageJsonAutoImports?: "auto" | "on" | "off"; readonly provideRefactorNotApplicableReason?: boolean; + readonly automaticallyAcquireTypesBasedOnFilenames?: boolean; } /** Represents a bigint literal value without requiring bigint support */ export interface PseudoBigInt { @@ -7557,6 +7559,7 @@ declare namespace ts.server.protocol { */ extraFileExtensions?: FileExtensionInfo[]; watchOptions?: WatchOptions; + typeAcquisition?: TypeAcquisition; } enum WatchFileKind { FixedPollingInterval = "FixedPollingInterval", @@ -9353,6 +9356,7 @@ declare namespace ts.server { class InferredProject extends Project { private static readonly newName; private _isJsInferredProject; + private typeAcquisition; toggleJsInferredProject(isJsInferredProject: boolean): void; setCompilerOptions(options?: CompilerOptions): void; /** this is canonical project root path */ @@ -9361,6 +9365,7 @@ declare namespace ts.server { removeRoot(info: ScriptInfo): void; isProjectWithSingleRoot(): boolean; close(): void; + setTypeAcquisition(newTypeAcquisition: TypeAcquisition): void; getTypeAcquisition(): TypeAcquisition; } class AutoImportProviderProject extends Project { @@ -9567,6 +9572,7 @@ declare namespace ts.server { hostInfo: string; extraFileExtensions?: FileExtensionInfo[]; watchOptions?: WatchOptions; + typeAcquisition?: TypeAcquisition; } export interface OpenConfiguredProjectResult { configFileName?: NormalizedPath; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 26cdf6ba46056..dda29efffdd6c 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2892,6 +2892,7 @@ declare namespace ts { include?: string[]; exclude?: string[]; [option: string]: string[] | boolean | undefined; + inferTypings?: boolean; } export enum ModuleKind { None = 0, @@ -3869,6 +3870,7 @@ declare namespace ts { readonly providePrefixAndSuffixTextForRename?: boolean; readonly includePackageJsonAutoImports?: "auto" | "on" | "off"; readonly provideRefactorNotApplicableReason?: boolean; + readonly automaticallyAcquireTypesBasedOnFilenames?: boolean; } /** Represents a bigint literal value without requiring bigint support */ export interface PseudoBigInt { From 52bc8b075888aafb050f4b3878b72a152fdc41ce Mon Sep 17 00:00:00 2001 From: Jesse Trinity Date: Mon, 5 Oct 2020 13:49:03 -0700 Subject: [PATCH 02/11] remove unused property --- src/compiler/types.ts | 1 - tests/baselines/reference/api/tsserverlibrary.d.ts | 1 - tests/baselines/reference/api/typescript.d.ts | 1 - 3 files changed, 3 deletions(-) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 0c8cc90a71cc9..11339e95f8d4b 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -8148,7 +8148,6 @@ namespace ts { readonly providePrefixAndSuffixTextForRename?: boolean; readonly includePackageJsonAutoImports?: "auto" | "on" | "off"; readonly provideRefactorNotApplicableReason?: boolean; - readonly automaticallyAcquireTypesBasedOnFilenames?: boolean; } /** Represents a bigint literal value without requiring bigint support */ diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 36a30d4626e05..81b460fb634c8 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -3870,7 +3870,6 @@ declare namespace ts { readonly providePrefixAndSuffixTextForRename?: boolean; readonly includePackageJsonAutoImports?: "auto" | "on" | "off"; readonly provideRefactorNotApplicableReason?: boolean; - readonly automaticallyAcquireTypesBasedOnFilenames?: boolean; } /** Represents a bigint literal value without requiring bigint support */ export interface PseudoBigInt { diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index dda29efffdd6c..1f1ee823a0827 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -3870,7 +3870,6 @@ declare namespace ts { readonly providePrefixAndSuffixTextForRename?: boolean; readonly includePackageJsonAutoImports?: "auto" | "on" | "off"; readonly provideRefactorNotApplicableReason?: boolean; - readonly automaticallyAcquireTypesBasedOnFilenames?: boolean; } /** Represents a bigint literal value without requiring bigint support */ export interface PseudoBigInt { From 4113e91c04316f8f86210961e3edf518e658e9a0 Mon Sep 17 00:00:00 2001 From: Jesse Trinity Date: Tue, 6 Oct 2020 10:45:48 -0700 Subject: [PATCH 03/11] handle inferred and external projects separately --- src/compiler/types.ts | 2 +- src/server/editorServices.ts | 22 ++++++++++++------- src/server/project.ts | 4 ++-- src/testRunner/unittests/tsserver/projects.ts | 2 +- .../unittests/tsserver/typingsInstaller.ts | 4 ++-- .../reference/api/tsserverlibrary.d.ts | 2 +- tests/baselines/reference/api/typescript.d.ts | 2 +- 7 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 11339e95f8d4b..5bf92ec1e9fae 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5845,7 +5845,7 @@ namespace ts { include?: string[]; exclude?: string[]; [option: string]: string[] | boolean | undefined; - inferTypings?: boolean; + inferTypingsFromFilenames?: boolean; } export enum ModuleKind { diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index f15757dc0c775..fb64b7dcbeb43 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -643,6 +643,8 @@ namespace ts.server { private compilerOptionsForInferredProjectsPerProjectRoot = new Map(); private watchOptionsForInferredProjects: WatchOptions | undefined; private watchOptionsForInferredProjectsPerProjectRoot = new Map(); + private typeAcquisitionForInferredProjects: TypeAcquisition | undefined; + private typeAcquisitionForInferredProjectsPerProjectRoot = new Map(); /** * Project size for configured or external projects */ @@ -989,6 +991,7 @@ namespace ts.server { const compilerOptions = convertCompilerOptions(projectCompilerOptions); const watchOptions = convertWatchOptions(projectCompilerOptions); + const typeAcquisition = this.hostConfiguration.typeAcquisition; // always set 'allowNonTsExtensions' for inferred projects since user cannot configure it from the outside // previously we did not expose a way for user to change these settings and this option was enabled by default @@ -997,10 +1000,12 @@ namespace ts.server { if (canonicalProjectRootPath) { this.compilerOptionsForInferredProjectsPerProjectRoot.set(canonicalProjectRootPath, compilerOptions); this.watchOptionsForInferredProjectsPerProjectRoot.set(canonicalProjectRootPath, watchOptions || false); + this.typeAcquisitionForInferredProjectsPerProjectRoot.set(canonicalProjectRootPath, typeAcquisition); } else { this.compilerOptionsForInferredProjects = compilerOptions; this.watchOptionsForInferredProjects = watchOptions; + this.typeAcquisitionForInferredProjects = typeAcquisition; } for (const project of this.inferredProjects) { @@ -1378,9 +1383,6 @@ namespace ts.server { ); project.addRoot(info); - if(this.hostConfiguration.typeAcquisition){ - project.setTypeAcquisition(this.hostConfiguration.typeAcquisition); - } if (info.containingProjects[0] !== project) { // Ensure this is first project, we could be in this scenario because info could be part of orphan project info.detachFromProject(project); @@ -2303,13 +2305,18 @@ namespace ts.server { private createInferredProject(currentDirectory: string | undefined, isSingleInferredProject?: boolean, projectRootPath?: NormalizedPath): InferredProject { const compilerOptions = projectRootPath && this.compilerOptionsForInferredProjectsPerProjectRoot.get(projectRootPath) || this.compilerOptionsForInferredProjects!; // TODO: GH#18217 let watchOptions: WatchOptions | false | undefined; + let typeAcquisition: TypeAcquisition | undefined; if (projectRootPath) { watchOptions = this.watchOptionsForInferredProjectsPerProjectRoot.get(projectRootPath); + typeAcquisition = this.typeAcquisitionForInferredProjectsPerProjectRoot.get(projectRootPath); } if (watchOptions === undefined) { watchOptions = this.watchOptionsForInferredProjects; } - const project = new InferredProject(this, this.documentRegistry, compilerOptions, watchOptions || undefined, projectRootPath, currentDirectory, this.currentPluginConfigOverrides, this.hostConfiguration.typeAcquisition); + if (typeAcquisition === undefined) { + typeAcquisition = this.typeAcquisitionForInferredProjects; + } + const project = new InferredProject(this, this.documentRegistry, compilerOptions, watchOptions || undefined, projectRootPath, currentDirectory, this.currentPluginConfigOverrides, typeAcquisition); if (isSingleInferredProject) { this.inferredProjects.unshift(project); } @@ -2770,7 +2777,7 @@ namespace ts.server { } if(args.typeAcquisition) { - this.hostConfiguration.typeAcquisition = { ...this.hostConfiguration.typeAcquisition, ...args.typeAcquisition }; + this.hostConfiguration.typeAcquisition = args.typeAcquisition; } } } @@ -3523,7 +3530,7 @@ namespace ts.server { const typeAcquisition = proj.typeAcquisition!; Debug.assert(!!typeAcquisition, "proj.typeAcquisition should be set by now"); // If type acquisition has been explicitly disabled, do not exclude anything from the project - if (typeAcquisition.enable === false || typeAcquisition.inferTypings === false) { + if (typeAcquisition.enable === false || typeAcquisition.inferTypingsFromFilenames === false) { return []; } @@ -3634,13 +3641,12 @@ namespace ts.server { const typeAcquisition = convertEnableAutoDiscoveryToEnable(proj.typingOptions); proj.typeAcquisition = typeAcquisition; } - proj.typeAcquisition = proj.typeAcquisition || {}; + proj.typeAcquisition = proj.typeAcquisition || this.hostConfiguration.typeAcquisition || {}; proj.typeAcquisition.include = proj.typeAcquisition.include || []; proj.typeAcquisition.exclude = proj.typeAcquisition.exclude || []; if (proj.typeAcquisition.enable === undefined) { proj.typeAcquisition.enable = hasNoTypeScriptSource(proj.rootFiles.map(f => f.fileName)); } - proj.typeAcquisition.inferTypings = this.hostConfiguration.typeAcquisition?.inferTypings ?? true; const excludedFiles = this.applySafeList(proj); diff --git a/src/server/project.ts b/src/server/project.ts index 20eb8ca508b0c..15703bdd538a4 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -1836,11 +1836,11 @@ namespace ts.server { } getTypeAcquisition(): TypeAcquisition { - return { + return this.typeAcquisition || { enable: allRootFilesAreJsOrDts(this), include: ts.emptyArray, exclude: ts.emptyArray, - inferTypings: this.typeAcquisition?.inferTypings + inferTypingsFromFilenames: true }; } } diff --git a/src/testRunner/unittests/tsserver/projects.ts b/src/testRunner/unittests/tsserver/projects.ts index fbeb0a0e6f74b..0ac9c0937f11e 100644 --- a/src/testRunner/unittests/tsserver/projects.ts +++ b/src/testRunner/unittests/tsserver/projects.ts @@ -402,7 +402,7 @@ namespace ts.projectSystem { projectName, fileNames: [libFile.path, file1.path, constructorFile.path, bliss.path], compilerOptions: { allowNonTsExtensions: true, noEmitForJsFiles: true }, - typeAcquisition: { include: ["blissfuljs"], exclude: [], enable: true, inferTypings: true }, + typeAcquisition: { include: ["blissfuljs"], exclude: [], enable: true, inferTypingsFromFilenames: true }, unresolvedImports: ["s"], projectRootPath: "/", cachePath, diff --git a/src/testRunner/unittests/tsserver/typingsInstaller.ts b/src/testRunner/unittests/tsserver/typingsInstaller.ts index 0d0abd9ba90b9..0209bf11d2adc 100644 --- a/src/testRunner/unittests/tsserver/typingsInstaller.ts +++ b/src/testRunner/unittests/tsserver/typingsInstaller.ts @@ -1375,7 +1375,7 @@ namespace ts.projectSystem { assert.deepEqual(result.newTypingNames, ["jquery", "chroma-js"]); }); - it("should not infer typings from filenames with inferTypings:false ", () => { + it("should not infer typings from filenames with inferTypingsFromFilenames:false ", () => { const app = { path: "/a/b/app.js", content: "" @@ -1393,7 +1393,7 @@ namespace ts.projectSystem { const host = createServerHost([app, jquery, chroma]); const logger = trackingLogger(); - const result = JsTyping.discoverTypings(host, logger.log, [app.path, jquery.path, chroma.path], getDirectoryPath(app.path), safeList, emptyMap, { enable: true, inferTypings: false }, emptyArray, emptyMap); + const result = JsTyping.discoverTypings(host, logger.log, [app.path, jquery.path, chroma.path], getDirectoryPath(app.path), safeList, emptyMap, { enable: true, inferTypingsFromFilenames: false }, emptyArray, emptyMap); const finish = logger.finish(); assert.deepEqual(finish, [ "Inferred typings from unresolved imports: []", diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 81b460fb634c8..972cc6118fbea 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2892,7 +2892,7 @@ declare namespace ts { include?: string[]; exclude?: string[]; [option: string]: string[] | boolean | undefined; - inferTypings?: boolean; + inferTypingsFromFilenames?: boolean; } export enum ModuleKind { None = 0, diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 1f1ee823a0827..2a6d5214ec827 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2892,7 +2892,7 @@ declare namespace ts { include?: string[]; exclude?: string[]; [option: string]: string[] | boolean | undefined; - inferTypings?: boolean; + inferTypingsFromFilenames?: boolean; } export enum ModuleKind { None = 0, From 45ae636a63cbe286bbd28b85700991fb35df4cb5 Mon Sep 17 00:00:00 2001 From: Jesse Trinity Date: Tue, 6 Oct 2020 10:48:08 -0700 Subject: [PATCH 04/11] update missed rename --- src/jsTyping/jsTyping.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jsTyping/jsTyping.ts b/src/jsTyping/jsTyping.ts index 26444ed4390a2..74266caa3097a 100644 --- a/src/jsTyping/jsTyping.ts +++ b/src/jsTyping/jsTyping.ts @@ -150,7 +150,7 @@ namespace ts.JsTyping { getTypingNamesFromPackagesFolder(nodeModulesPath, filesToWatch); }); // filename-based ATA must be explicitly disabled - if(typeAcquisition.inferTypings !== false) { + if(typeAcquisition.inferTypingsFromFilenames !== false) { getTypingNamesFromSourceFileNames(fileNames); } // add typings for unresolved imports From d3a2d4196a586d4cfc99b989afae71c97bb0c06b Mon Sep 17 00:00:00 2001 From: Jesse Trinity Date: Tue, 6 Oct 2020 11:33:32 -0700 Subject: [PATCH 05/11] fix tests --- src/testRunner/unittests/tsserver/projects.ts | 2 +- tests/baselines/reference/api/tsserverlibrary.d.ts | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/testRunner/unittests/tsserver/projects.ts b/src/testRunner/unittests/tsserver/projects.ts index 0ac9c0937f11e..2de2da67af3d8 100644 --- a/src/testRunner/unittests/tsserver/projects.ts +++ b/src/testRunner/unittests/tsserver/projects.ts @@ -402,7 +402,7 @@ namespace ts.projectSystem { projectName, fileNames: [libFile.path, file1.path, constructorFile.path, bliss.path], compilerOptions: { allowNonTsExtensions: true, noEmitForJsFiles: true }, - typeAcquisition: { include: ["blissfuljs"], exclude: [], enable: true, inferTypingsFromFilenames: true }, + typeAcquisition: { include: ["blissfuljs"], exclude: [], enable: true }, unresolvedImports: ["s"], projectRootPath: "/", cachePath, diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 972cc6118fbea..5bec0f0f485ab 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -9632,6 +9632,8 @@ declare namespace ts.server { private compilerOptionsForInferredProjectsPerProjectRoot; private watchOptionsForInferredProjects; private watchOptionsForInferredProjectsPerProjectRoot; + private typeAcquisitionForInferredProjects; + private typeAcquisitionForInferredProjectsPerProjectRoot; /** * Project size for configured or external projects */ From 67fda70a54a95bf5745e85cbc2bf41307e6b2fbd Mon Sep 17 00:00:00 2001 From: Jesse Trinity Date: Wed, 7 Oct 2020 17:49:46 -0700 Subject: [PATCH 06/11] pass as external compilerOption --- src/compiler/commandLineParser.ts | 6 +++++- src/compiler/types.ts | 2 +- src/server/editorServices.ts | 16 +++++++++++----- src/server/protocol.ts | 4 +--- .../baselines/reference/api/tsserverlibrary.d.ts | 6 +++--- tests/baselines/reference/api/typescript.d.ts | 2 +- 6 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 04834a11a29d4..54ee7c4499f68 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -1133,7 +1133,11 @@ namespace ts { name: "exclude", type: "string" } - } + }, + { + name: "inferTypingsFromFilenames", + type: "boolean", + }, ]; /* @internal */ diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 5bf92ec1e9fae..e7c5dbfee39c8 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5844,8 +5844,8 @@ namespace ts { enable?: boolean; include?: string[]; exclude?: string[]; - [option: string]: string[] | boolean | undefined; inferTypingsFromFilenames?: boolean; + [option: string]: CompilerOptionsValue | undefined; } export enum ModuleKind { diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index fb64b7dcbeb43..c3dd2e4790823 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -263,6 +263,16 @@ namespace ts.server { return result; } + export function convertTypeAcquisition(protocolOptions: protocol.ExternalProjectCompilerOptions): TypeAcquisition | undefined { + let result: TypeAcquisition | undefined; + typeAcquisitionDeclarations.forEach((option) => { + const propertyValue = protocolOptions[option.name]; + if (propertyValue === undefined) return; + (result || (result = {}))[option.name] = propertyValue; + }); + return result; + } + export function tryConvertScriptKindName(scriptKindName: protocol.ScriptKindName | ScriptKind): ScriptKind { return isString(scriptKindName) ? convertScriptKindName(scriptKindName) : scriptKindName; } @@ -991,7 +1001,7 @@ namespace ts.server { const compilerOptions = convertCompilerOptions(projectCompilerOptions); const watchOptions = convertWatchOptions(projectCompilerOptions); - const typeAcquisition = this.hostConfiguration.typeAcquisition; + const typeAcquisition = convertTypeAcquisition(projectCompilerOptions); // always set 'allowNonTsExtensions' for inferred projects since user cannot configure it from the outside // previously we did not expose a way for user to change these settings and this option was enabled by default @@ -2775,10 +2785,6 @@ namespace ts.server { this.hostConfiguration.watchOptions = convertWatchOptions(args.watchOptions); this.logger.info(`Host watch options changed to ${JSON.stringify(this.hostConfiguration.watchOptions)}, it will be take effect for next watches.`); } - - if(args.typeAcquisition) { - this.hostConfiguration.typeAcquisition = args.typeAcquisition; - } } } diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 745cb955dabaa..176a1daaafbb5 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -1333,7 +1333,7 @@ namespace ts.server.protocol { * For external projects, some of the project settings are sent together with * compiler settings. */ - export type ExternalProjectCompilerOptions = CompilerOptions & CompileOnSaveMixin & WatchOptions; + export type ExternalProjectCompilerOptions = CompilerOptions & CompileOnSaveMixin & WatchOptions & TypeAcquisition; /** * Contains information about current project version @@ -1482,8 +1482,6 @@ namespace ts.server.protocol { extraFileExtensions?: FileExtensionInfo[]; watchOptions?: WatchOptions; - - typeAcquisition?: TypeAcquisition; } export const enum WatchFileKind { diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 5bec0f0f485ab..0b26de5ecc4ee 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2891,8 +2891,8 @@ declare namespace ts { enable?: boolean; include?: string[]; exclude?: string[]; - [option: string]: string[] | boolean | undefined; inferTypingsFromFilenames?: boolean; + [option: string]: CompilerOptionsValue | undefined; } export enum ModuleKind { None = 0, @@ -7502,7 +7502,7 @@ declare namespace ts.server.protocol { * For external projects, some of the project settings are sent together with * compiler settings. */ - type ExternalProjectCompilerOptions = CompilerOptions & CompileOnSaveMixin & WatchOptions; + type ExternalProjectCompilerOptions = CompilerOptions & CompileOnSaveMixin & WatchOptions & TypeAcquisition; interface FileWithProjectReferenceRedirectInfo { /** * Name of file @@ -7558,7 +7558,6 @@ declare namespace ts.server.protocol { */ extraFileExtensions?: FileExtensionInfo[]; watchOptions?: WatchOptions; - typeAcquisition?: TypeAcquisition; } enum WatchFileKind { FixedPollingInterval = "FixedPollingInterval", @@ -9563,6 +9562,7 @@ declare namespace ts.server { export function convertFormatOptions(protocolOptions: protocol.FormatCodeSettings): FormatCodeSettings; export function convertCompilerOptions(protocolOptions: protocol.ExternalProjectCompilerOptions): CompilerOptions & protocol.CompileOnSaveMixin; export function convertWatchOptions(protocolOptions: protocol.ExternalProjectCompilerOptions): WatchOptions | undefined; + export function convertTypeAcquisition(protocolOptions: protocol.ExternalProjectCompilerOptions): TypeAcquisition | undefined; export function tryConvertScriptKindName(scriptKindName: protocol.ScriptKindName | ScriptKind): ScriptKind; export function convertScriptKindName(scriptKindName: protocol.ScriptKindName): ScriptKind.Unknown | ScriptKind.JS | ScriptKind.JSX | ScriptKind.TS | ScriptKind.TSX; export interface HostConfiguration { diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 2a6d5214ec827..2dba247890753 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2891,8 +2891,8 @@ declare namespace ts { enable?: boolean; include?: string[]; exclude?: string[]; - [option: string]: string[] | boolean | undefined; inferTypingsFromFilenames?: boolean; + [option: string]: CompilerOptionsValue | undefined; } export enum ModuleKind { None = 0, From 554a98f7aaaaa5d43a2f38ce8aca56dd91f3aae6 Mon Sep 17 00:00:00 2001 From: Jesse Trinity Date: Thu, 8 Oct 2020 16:29:57 -0700 Subject: [PATCH 07/11] update test --- .../unittests/tsserver/typingsInstaller.ts | 116 ++++++++++++++---- 1 file changed, 89 insertions(+), 27 deletions(-) diff --git a/src/testRunner/unittests/tsserver/typingsInstaller.ts b/src/testRunner/unittests/tsserver/typingsInstaller.ts index 0209bf11d2adc..5263da8d2100e 100644 --- a/src/testRunner/unittests/tsserver/typingsInstaller.ts +++ b/src/testRunner/unittests/tsserver/typingsInstaller.ts @@ -207,6 +207,50 @@ namespace ts.projectSystem { checkProjectActualFiles(p, [file1.path, jquery.path]); }); + it("inferred project - type acquisition with inferTypingsFromFile:false", () => { + // Tests: + // Exclude file from filename-based type acquisition with inferTypingsFromFile:false + const jqueryJs = { + path: "/a/b/jquery.js", + content: "" + }; + + const messages: string[] = []; + const host = createServerHost([jqueryJs]); + const installer = new (class extends Installer { + constructor() { + super(host, { typesRegistry: createTypesRegistry("jquery") }, { isEnabled: () => true, writeLine: msg => messages.push(msg) }); + } + enqueueInstallTypingsRequest(project: server.Project, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray) { + super.enqueueInstallTypingsRequest(project, typeAcquisition, unresolvedImports); + } + installWorker(_requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void { + const installedTypings: string[] = []; + const typingFiles: File[] = []; + executeCommand(this, host, installedTypings, typingFiles, cb); + } + })(); + + const projectService = createProjectService(host, { typingsInstaller: installer }); + projectService.setCompilerOptionsForInferredProjects({ + allowJs: true, + enable: true, + inferTypingsFromFilenames: false + }); + projectService.openClientFile(jqueryJs.path); + + checkNumberOfProjects(projectService, { inferredProjects: 1 }); + const p = projectService.inferredProjects[0]; + checkProjectActualFiles(p, [jqueryJs.path]); + + installer.installAll(/*expectedCount*/ 0); + host.checkTimeoutQueueLengthAndRun(2); + checkNumberOfProjects(projectService, { inferredProjects: 1 }); + // files should not be removed from project if ATA is skipped + checkProjectActualFiles(p, [jqueryJs.path]); + assert.isTrue(messages.indexOf("No new typings were requested as a result of typings discovery") > 0, "Should not request filename-based typings"); + }); + it("external project - no type acquisition, no .d.ts/js files", () => { const file1 = { path: "/a/b/app.ts", @@ -434,6 +478,51 @@ namespace ts.projectSystem { installer.checkPendingCommands(/*expectedCount*/ 0); }); + + it("external project - type acquisition with inferTypingsFromFilenames: false", () => { + // Tests: + // Exclude file from filename-based type acquisition with inferTypingsFromFile:false + const jqueryJs = { + path: "/a/b/jquery.js", + content: "" + }; + + const messages: string[] = []; + const host = createServerHost([jqueryJs]); + const installer = new (class extends Installer { + constructor() { + super(host, { typesRegistry: createTypesRegistry("jquery") }, { isEnabled: () => true, writeLine: msg => messages.push(msg) }); + } + enqueueInstallTypingsRequest(project: server.Project, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray) { + super.enqueueInstallTypingsRequest(project, typeAcquisition, unresolvedImports); + } + installWorker(_requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void { + const installedTypings: string[] = []; + const typingFiles: File[] = []; + executeCommand(this, host, installedTypings, typingFiles, cb); + } + })(); + + const projectFileName = "/a/app/test.csproj"; + const projectService = createProjectService(host, { typingsInstaller: installer }); + projectService.openExternalProject({ + projectFileName, + options: { allowJS: true, moduleResolution: ModuleResolutionKind.NodeJs }, + rootFiles: [toExternalFile(jqueryJs.path)], + typeAcquisition: { enable: true, inferTypingsFromFilenames: false } + }); + + const p = projectService.externalProjects[0]; + projectService.checkNumberOfProjects({ externalProjects: 1 }); + checkProjectActualFiles(p, [jqueryJs.path]); + + installer.installAll(/*expectedCount*/ 0); + projectService.checkNumberOfProjects({ externalProjects: 1 }); + // files should not be removed from project if ATA is skipped + checkProjectActualFiles(p, [jqueryJs.path]); + assert.isTrue(messages.indexOf("No new typings were requested as a result of typings discovery") > 0, "Should not request filename-based typings"); + }); + it("external project - no type acquisition, with js & ts files", () => { // Tests: // 1. No typings are included for JS projects when the project contains ts files @@ -1375,33 +1464,6 @@ namespace ts.projectSystem { assert.deepEqual(result.newTypingNames, ["jquery", "chroma-js"]); }); - it("should not infer typings from filenames with inferTypingsFromFilenames:false ", () => { - const app = { - path: "/a/b/app.js", - content: "" - }; - const jquery = { - path: "/a/b/jquery.js", - content: "" - }; - const chroma = { - path: "/a/b/chroma.min.js", - content: "" - }; - - const safeList = new Map(getEntries({ jquery: "jquery", chroma: "chroma-js" })); - - const host = createServerHost([app, jquery, chroma]); - const logger = trackingLogger(); - const result = JsTyping.discoverTypings(host, logger.log, [app.path, jquery.path, chroma.path], getDirectoryPath(app.path), safeList, emptyMap, { enable: true, inferTypingsFromFilenames: false }, emptyArray, emptyMap); - const finish = logger.finish(); - assert.deepEqual(finish, [ - "Inferred typings from unresolved imports: []", - 'Result: {"cachedTypingPaths":[],"newTypingNames":[],"filesToWatch":["/a/b/bower_components","/a/b/node_modules"]}', - ], finish.join("\r\n")); - assert.deepEqual(result.newTypingNames, []); - }); - it("should return node for core modules", () => { const f = { path: "/a/b/app.js", From 48eccaad9a70df6d92be28bb4b68f06f5626f3b4 Mon Sep 17 00:00:00 2001 From: Jesse Trinity Date: Tue, 13 Oct 2020 11:07:13 -0700 Subject: [PATCH 08/11] remove hostConfig reference --- src/server/editorServices.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index c3dd2e4790823..dd5697310cf4f 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -3647,7 +3647,7 @@ namespace ts.server { const typeAcquisition = convertEnableAutoDiscoveryToEnable(proj.typingOptions); proj.typeAcquisition = typeAcquisition; } - proj.typeAcquisition = proj.typeAcquisition || this.hostConfiguration.typeAcquisition || {}; + proj.typeAcquisition = proj.typeAcquisition || {}; proj.typeAcquisition.include = proj.typeAcquisition.include || []; proj.typeAcquisition.exclude = proj.typeAcquisition.exclude || []; if (proj.typeAcquisition.enable === undefined) { From a1871378cec55116697262016b34425fe1e45adc Mon Sep 17 00:00:00 2001 From: Jesse Trinity Date: Thu, 15 Oct 2020 10:22:09 -0700 Subject: [PATCH 09/11] change option name --- src/compiler/commandLineParser.ts | 2 +- src/compiler/types.ts | 2 +- src/jsTyping/jsTyping.ts | 3 +-- src/server/editorServices.ts | 4 ++-- src/server/project.ts | 2 +- .../unittests/tsserver/typingsInstaller.ts | 12 ++++++------ tests/baselines/reference/api/typescript.d.ts | 2 +- 7 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 54ee7c4499f68..5f42c634329d2 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -1135,7 +1135,7 @@ namespace ts { } }, { - name: "inferTypingsFromFilenames", + name: "disableFilenameBasedTypeAcquisition", type: "boolean", }, ]; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index e7c5dbfee39c8..9109d1c4af9f3 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5844,7 +5844,7 @@ namespace ts { enable?: boolean; include?: string[]; exclude?: string[]; - inferTypingsFromFilenames?: boolean; + disableFilenameBasedTypeAcquisition?: boolean; [option: string]: CompilerOptionsValue | undefined; } diff --git a/src/jsTyping/jsTyping.ts b/src/jsTyping/jsTyping.ts index 74266caa3097a..10ef0cf957a97 100644 --- a/src/jsTyping/jsTyping.ts +++ b/src/jsTyping/jsTyping.ts @@ -149,8 +149,7 @@ namespace ts.JsTyping { const nodeModulesPath = combinePaths(searchDir, "node_modules"); getTypingNamesFromPackagesFolder(nodeModulesPath, filesToWatch); }); - // filename-based ATA must be explicitly disabled - if(typeAcquisition.inferTypingsFromFilenames !== false) { + if(!typeAcquisition.disableFilenameBasedTypeAcquisition) { getTypingNamesFromSourceFileNames(fileNames); } // add typings for unresolved imports diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index dd5697310cf4f..51939d1d3d816 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -3535,8 +3535,8 @@ namespace ts.server { const { rootFiles } = proj; const typeAcquisition = proj.typeAcquisition!; Debug.assert(!!typeAcquisition, "proj.typeAcquisition should be set by now"); - // If type acquisition has been explicitly disabled, do not exclude anything from the project - if (typeAcquisition.enable === false || typeAcquisition.inferTypingsFromFilenames === false) { + + if (typeAcquisition.enable === false || typeAcquisition.disableFilenameBasedTypeAcquisition) { return []; } diff --git a/src/server/project.ts b/src/server/project.ts index 15703bdd538a4..a6d2fcf2f5166 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -1840,7 +1840,7 @@ namespace ts.server { enable: allRootFilesAreJsOrDts(this), include: ts.emptyArray, exclude: ts.emptyArray, - inferTypingsFromFilenames: true + disableFilenameBasedTypeAcquisition: false }; } } diff --git a/src/testRunner/unittests/tsserver/typingsInstaller.ts b/src/testRunner/unittests/tsserver/typingsInstaller.ts index 5263da8d2100e..26ce8eca6dde4 100644 --- a/src/testRunner/unittests/tsserver/typingsInstaller.ts +++ b/src/testRunner/unittests/tsserver/typingsInstaller.ts @@ -207,9 +207,9 @@ namespace ts.projectSystem { checkProjectActualFiles(p, [file1.path, jquery.path]); }); - it("inferred project - type acquisition with inferTypingsFromFile:false", () => { + it("inferred project - type acquisition with disableFilenameBasedTypeAcquisition:true", () => { // Tests: - // Exclude file from filename-based type acquisition with inferTypingsFromFile:false + // Exclude file with disableFilenameBasedTypeAcquisition:true const jqueryJs = { path: "/a/b/jquery.js", content: "" @@ -235,7 +235,7 @@ namespace ts.projectSystem { projectService.setCompilerOptionsForInferredProjects({ allowJs: true, enable: true, - inferTypingsFromFilenames: false + disableFilenameBasedTypeAcquisition: true }); projectService.openClientFile(jqueryJs.path); @@ -479,9 +479,9 @@ namespace ts.projectSystem { installer.checkPendingCommands(/*expectedCount*/ 0); }); - it("external project - type acquisition with inferTypingsFromFilenames: false", () => { + it("external project - type acquisition with disableFilenameBasedTypeAcquisition:true", () => { // Tests: - // Exclude file from filename-based type acquisition with inferTypingsFromFile:false + // Exclude file with disableFilenameBasedTypeAcquisition:true const jqueryJs = { path: "/a/b/jquery.js", content: "" @@ -509,7 +509,7 @@ namespace ts.projectSystem { projectFileName, options: { allowJS: true, moduleResolution: ModuleResolutionKind.NodeJs }, rootFiles: [toExternalFile(jqueryJs.path)], - typeAcquisition: { enable: true, inferTypingsFromFilenames: false } + typeAcquisition: { enable: true, disableFilenameBasedTypeAcquisition: true } }); const p = projectService.externalProjects[0]; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 2dba247890753..5ae7f935e21bf 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2891,7 +2891,7 @@ declare namespace ts { enable?: boolean; include?: string[]; exclude?: string[]; - inferTypingsFromFilenames?: boolean; + disableFilenameBasedTypeAcquisition?: boolean; [option: string]: CompilerOptionsValue | undefined; } export enum ModuleKind { From aa46e02e75c006f58f0fb60f5d2896574801d49d Mon Sep 17 00:00:00 2001 From: Jesse Trinity Date: Thu, 15 Oct 2020 10:26:21 -0700 Subject: [PATCH 10/11] remove extraneous property --- src/server/editorServices.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 51939d1d3d816..ecc60d7be5f7d 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -304,7 +304,6 @@ namespace ts.server { hostInfo: string; extraFileExtensions?: FileExtensionInfo[]; watchOptions?: WatchOptions; - typeAcquisition?: TypeAcquisition; } export interface OpenConfiguredProjectResult { From b6ee490188c63a4e5870d4947926abf7204f2e18 Mon Sep 17 00:00:00 2001 From: Jesse Trinity Date: Thu, 15 Oct 2020 17:02:37 -0700 Subject: [PATCH 11/11] add inferredProjectCompilerOptions --- src/server/editorServices.ts | 5 +- src/server/project.ts | 46 ++++++------------- src/server/protocol.ts | 9 +++- .../reference/api/tsserverlibrary.d.ts | 28 +++++------ 4 files changed, 35 insertions(+), 53 deletions(-) diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index ecc60d7be5f7d..20e426c0561f1 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -263,7 +263,7 @@ namespace ts.server { return result; } - export function convertTypeAcquisition(protocolOptions: protocol.ExternalProjectCompilerOptions): TypeAcquisition | undefined { + export function convertTypeAcquisition(protocolOptions: protocol.InferredProjectCompilerOptions): TypeAcquisition | undefined { let result: TypeAcquisition | undefined; typeAcquisitionDeclarations.forEach((option) => { const propertyValue = protocolOptions[option.name]; @@ -995,7 +995,7 @@ namespace ts.server { } } - setCompilerOptionsForInferredProjects(projectCompilerOptions: protocol.ExternalProjectCompilerOptions, projectRootPath?: string): void { + setCompilerOptionsForInferredProjects(projectCompilerOptions: protocol.InferredProjectCompilerOptions, projectRootPath?: string): void { Debug.assert(projectRootPath === undefined || this.useInferredProjectPerProjectRoot, "Setting compiler options per project root path is only supported when useInferredProjectPerProjectRoot is enabled"); const compilerOptions = convertCompilerOptions(projectCompilerOptions); @@ -1031,6 +1031,7 @@ namespace ts.server { !project.projectRootPath || !this.compilerOptionsForInferredProjectsPerProjectRoot.has(project.projectRootPath)) { project.setCompilerOptions(compilerOptions); project.setWatchOptions(watchOptions); + project.setTypeAcquisition(typeAcquisition); project.compileOnSaveEnabled = compilerOptions.compileOnSave!; project.markAsDirty(); this.delayUpdateProjectGraph(project); diff --git a/src/server/project.ts b/src/server/project.ts index a6d2fcf2f5166..7477ef5e67c86 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -249,6 +249,8 @@ namespace ts.server { private symlinks: SymlinkCache | undefined; /*@internal*/ autoImportProviderHost: AutoImportProviderProject | false | undefined; + /*@internal*/ + protected typeAcquisition: TypeAcquisition | undefined; /*@internal*/ constructor( @@ -692,12 +694,11 @@ namespace ts.server { getProjectName() { return this.projectName; } - abstract getTypeAcquisition(): TypeAcquisition; - protected removeLocalTypingsFromTypeAcquisition(newTypeAcquisition: TypeAcquisition): TypeAcquisition { + protected removeLocalTypingsFromTypeAcquisition(newTypeAcquisition: TypeAcquisition | undefined): TypeAcquisition { if (!newTypeAcquisition || !newTypeAcquisition.include) { // Nothing to filter out, so just return as-is - return newTypeAcquisition; + return newTypeAcquisition || {}; } return { ...newTypeAcquisition, include: this.removeExistingTypings(newTypeAcquisition.include) }; } @@ -1400,6 +1401,14 @@ namespace ts.server { return this.watchOptions; } + setTypeAcquisition(newTypeAcquisition: TypeAcquisition | undefined): void { + this.typeAcquisition = this.removeLocalTypingsFromTypeAcquisition(newTypeAcquisition); + } + + getTypeAcquisition() { + return this.typeAcquisition || {}; + } + /* @internal */ getChangesSinceVersion(lastKnownVersion?: number, includeProjectReferenceRedirectInfo?: boolean): ProjectFilesWithTSDiagnostics { const includeProjectReferenceRedirectInfoIfRequested = @@ -1732,8 +1741,6 @@ namespace ts.server { private _isJsInferredProject = false; - private typeAcquisition: TypeAcquisition | undefined; - toggleJsInferredProject(isJsInferredProject: boolean) { if (isJsInferredProject !== this._isJsInferredProject) { this._isJsInferredProject = isJsInferredProject; @@ -1831,16 +1838,11 @@ namespace ts.server { super.close(); } - setTypeAcquisition(newTypeAcquisition: TypeAcquisition): void { - this.typeAcquisition = this.removeLocalTypingsFromTypeAcquisition(newTypeAcquisition); - } - getTypeAcquisition(): TypeAcquisition { return this.typeAcquisition || { enable: allRootFilesAreJsOrDts(this), include: ts.emptyArray, - exclude: ts.emptyArray, - disableFilenameBasedTypeAcquisition: false + exclude: ts.emptyArray }; } } @@ -2019,7 +2021,6 @@ namespace ts.server { * Otherwise it will create an InferredProject. */ export class ConfiguredProject extends Project { - private typeAcquisition: TypeAcquisition | undefined; /* @internal */ configFileWatcher: FileWatcher | undefined; private directoriesWatchedForWildcards: ESMap | undefined; @@ -2231,14 +2232,6 @@ namespace ts.server { this.projectErrors = projectErrors; } - setTypeAcquisition(newTypeAcquisition: TypeAcquisition): void { - this.typeAcquisition = this.removeLocalTypingsFromTypeAcquisition(newTypeAcquisition); - } - - getTypeAcquisition() { - return this.typeAcquisition || {}; - } - /*@internal*/ watchWildcards(wildcardDirectories: ESMap) { updateWatchingWildcardDirectories( @@ -2357,7 +2350,6 @@ namespace ts.server { */ export class ExternalProject extends Project { excludedFiles: readonly NormalizedPath[] = []; - private typeAcquisition: TypeAcquisition | undefined; /*@internal*/ constructor(public externalProjectName: string, projectService: ProjectService, @@ -2391,18 +2383,6 @@ namespace ts.server { getExcludedFiles() { return this.excludedFiles; } - - getTypeAcquisition() { - return this.typeAcquisition || {}; - } - - setTypeAcquisition(newTypeAcquisition: TypeAcquisition): void { - Debug.assert(!!newTypeAcquisition, "newTypeAcquisition may not be null/undefined"); - Debug.assert(!!newTypeAcquisition.include, "newTypeAcquisition.include may not be null/undefined"); - Debug.assert(!!newTypeAcquisition.exclude, "newTypeAcquisition.exclude may not be null/undefined"); - Debug.assert(typeof newTypeAcquisition.enable === "boolean", "newTypeAcquisition.enable may not be null/undefined"); - this.typeAcquisition = this.removeLocalTypingsFromTypeAcquisition(newTypeAcquisition); - } } /* @internal */ diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 176a1daaafbb5..3706f5b85ecc5 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -1333,7 +1333,7 @@ namespace ts.server.protocol { * For external projects, some of the project settings are sent together with * compiler settings. */ - export type ExternalProjectCompilerOptions = CompilerOptions & CompileOnSaveMixin & WatchOptions & TypeAcquisition; + export type ExternalProjectCompilerOptions = CompilerOptions & CompileOnSaveMixin & WatchOptions; /** * Contains information about current project version @@ -1762,6 +1762,11 @@ namespace ts.server.protocol { closedFiles?: string[]; } + /** + * External projects have a typeAcquisition option so they need to be added separately to compiler options for inferred projects. + */ + export type InferredProjectCompilerOptions = ExternalProjectCompilerOptions & TypeAcquisition; + /** * Request to set compiler options for inferred projects. * External projects are opened / closed explicitly. @@ -1783,7 +1788,7 @@ namespace ts.server.protocol { /** * Compiler options to be used with inferred projects. */ - options: ExternalProjectCompilerOptions; + options: InferredProjectCompilerOptions; /** * Specifies the project root path used to scope compiler options. diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 0b26de5ecc4ee..f9f821331ba44 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2891,7 +2891,7 @@ declare namespace ts { enable?: boolean; include?: string[]; exclude?: string[]; - inferTypingsFromFilenames?: boolean; + disableFilenameBasedTypeAcquisition?: boolean; [option: string]: CompilerOptionsValue | undefined; } export enum ModuleKind { @@ -7502,7 +7502,7 @@ declare namespace ts.server.protocol { * For external projects, some of the project settings are sent together with * compiler settings. */ - type ExternalProjectCompilerOptions = CompilerOptions & CompileOnSaveMixin & WatchOptions & TypeAcquisition; + type ExternalProjectCompilerOptions = CompilerOptions & CompileOnSaveMixin & WatchOptions; interface FileWithProjectReferenceRedirectInfo { /** * Name of file @@ -7755,6 +7755,10 @@ declare namespace ts.server.protocol { */ closedFiles?: string[]; } + /** + * External projects have a typeAcquisition option so they need to be added separately to compiler options for inferred projects. + */ + type InferredProjectCompilerOptions = ExternalProjectCompilerOptions & TypeAcquisition; /** * Request to set compiler options for inferred projects. * External projects are opened / closed explicitly. @@ -7775,7 +7779,7 @@ declare namespace ts.server.protocol { /** * Compiler options to be used with inferred projects. */ - options: ExternalProjectCompilerOptions; + options: InferredProjectCompilerOptions; /** * Specifies the project root path used to scope compiler options. * It is an error to provide this property if the server has not been started with @@ -9301,8 +9305,7 @@ declare namespace ts.server { enableLanguageService(): void; disableLanguageService(lastFileExceededProgramSize?: string): void; getProjectName(): string; - abstract getTypeAcquisition(): TypeAcquisition; - protected removeLocalTypingsFromTypeAcquisition(newTypeAcquisition: TypeAcquisition): TypeAcquisition; + protected removeLocalTypingsFromTypeAcquisition(newTypeAcquisition: TypeAcquisition | undefined): TypeAcquisition; getExternalFiles(): SortedReadonlyArray; getSourceFile(path: Path): SourceFile | undefined; close(): void; @@ -9340,6 +9343,8 @@ declare namespace ts.server { getScriptInfo(uncheckedFileName: string): ScriptInfo | undefined; filesToString(writeProjectFileNames: boolean): string; setCompilerOptions(compilerOptions: CompilerOptions): void; + setTypeAcquisition(newTypeAcquisition: TypeAcquisition | undefined): void; + getTypeAcquisition(): TypeAcquisition; protected removeRoot(info: ScriptInfo): void; protected enableGlobalPlugins(options: CompilerOptions, pluginConfigOverrides: Map | undefined): void; protected enablePlugin(pluginConfigEntry: PluginImport, searchPaths: string[], pluginConfigOverrides: Map | undefined): void; @@ -9354,7 +9359,6 @@ declare namespace ts.server { class InferredProject extends Project { private static readonly newName; private _isJsInferredProject; - private typeAcquisition; toggleJsInferredProject(isJsInferredProject: boolean): void; setCompilerOptions(options?: CompilerOptions): void; /** this is canonical project root path */ @@ -9363,7 +9367,6 @@ declare namespace ts.server { removeRoot(info: ScriptInfo): void; isProjectWithSingleRoot(): boolean; close(): void; - setTypeAcquisition(newTypeAcquisition: TypeAcquisition): void; getTypeAcquisition(): TypeAcquisition; } class AutoImportProviderProject extends Project { @@ -9387,7 +9390,6 @@ declare namespace ts.server { * Otherwise it will create an InferredProject. */ class ConfiguredProject extends Project { - private typeAcquisition; private directoriesWatchedForWildcards; readonly canonicalConfigFilePath: NormalizedPath; /** Ref count to the project when opened from external project */ @@ -9411,8 +9413,6 @@ declare namespace ts.server { */ getAllProjectErrors(): readonly Diagnostic[]; setProjectErrors(projectErrors: Diagnostic[]): void; - setTypeAcquisition(newTypeAcquisition: TypeAcquisition): void; - getTypeAcquisition(): TypeAcquisition; close(): void; getEffectiveTypeRoots(): string[]; } @@ -9424,11 +9424,8 @@ declare namespace ts.server { externalProjectName: string; compileOnSaveEnabled: boolean; excludedFiles: readonly NormalizedPath[]; - private typeAcquisition; updateGraph(): boolean; getExcludedFiles(): readonly NormalizedPath[]; - getTypeAcquisition(): TypeAcquisition; - setTypeAcquisition(newTypeAcquisition: TypeAcquisition): void; } } declare namespace ts.server { @@ -9562,7 +9559,7 @@ declare namespace ts.server { export function convertFormatOptions(protocolOptions: protocol.FormatCodeSettings): FormatCodeSettings; export function convertCompilerOptions(protocolOptions: protocol.ExternalProjectCompilerOptions): CompilerOptions & protocol.CompileOnSaveMixin; export function convertWatchOptions(protocolOptions: protocol.ExternalProjectCompilerOptions): WatchOptions | undefined; - export function convertTypeAcquisition(protocolOptions: protocol.ExternalProjectCompilerOptions): TypeAcquisition | undefined; + export function convertTypeAcquisition(protocolOptions: protocol.InferredProjectCompilerOptions): TypeAcquisition | undefined; export function tryConvertScriptKindName(scriptKindName: protocol.ScriptKindName | ScriptKind): ScriptKind; export function convertScriptKindName(scriptKindName: protocol.ScriptKindName): ScriptKind.Unknown | ScriptKind.JS | ScriptKind.JSX | ScriptKind.TS | ScriptKind.TSX; export interface HostConfiguration { @@ -9571,7 +9568,6 @@ declare namespace ts.server { hostInfo: string; extraFileExtensions?: FileExtensionInfo[]; watchOptions?: WatchOptions; - typeAcquisition?: TypeAcquisition; } export interface OpenConfiguredProjectResult { configFileName?: NormalizedPath; @@ -9679,7 +9675,7 @@ declare namespace ts.server { updateTypingsForProject(response: SetTypings | InvalidateCachedTypings | PackageInstalledResponse): void; private delayUpdateProjectGraph; private delayUpdateProjectGraphs; - setCompilerOptionsForInferredProjects(projectCompilerOptions: protocol.ExternalProjectCompilerOptions, projectRootPath?: string): void; + setCompilerOptionsForInferredProjects(projectCompilerOptions: protocol.InferredProjectCompilerOptions, projectRootPath?: string): void; findProject(projectName: string): Project | undefined; getDefaultProjectForFile(fileName: NormalizedPath, ensureProject: boolean): Project | undefined; private doEnsureDefaultProjectForFile;