diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 6406455d71328..2fe3f63450c53 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -876,7 +876,7 @@ namespace ts { return { options, errors }; } - export function convertTypingOptionsFromJson(jsonOptions: any, basePath: string, configFileName?: string): { options: CompilerOptions, errors: Diagnostic[] } { + export function convertTypingOptionsFromJson(jsonOptions: any, basePath: string, configFileName?: string): { options: TypingOptions, errors: Diagnostic[] } { const errors: Diagnostic[] = []; const options = convertTypingOptionsFromJsonWorker(jsonOptions, basePath, errors, configFileName); return { options, errors }; diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 394613bebe4b4..8c3d7f42e2557 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -704,12 +704,13 @@ namespace ts.server { return false; } - private createAndAddExternalProject(projectFileName: string, files: protocol.ExternalFile[], compilerOptions: CompilerOptions) { + private createAndAddExternalProject(projectFileName: string, files: protocol.ExternalFile[], compilerOptions: CompilerOptions, typingOptions: TypingOptions) { const project = new ExternalProject( projectFileName, this, this.documentRegistry, compilerOptions, + typingOptions, /*languageServiceEnabled*/ !this.exceededTotalSizeLimitForNonTsFiles(compilerOptions, files, externalFilePropertyReader)); const errors = this.addFilesToProjectAndUpdateGraph(project, files, externalFilePropertyReader, /*clientFileName*/ undefined); @@ -774,7 +775,7 @@ namespace ts.server { return { success: true, project, errors }; } - private updateNonInferredProject(project: ExternalProject | ConfiguredProject, newUncheckedFiles: T[], propertyReader: FilePropertyReader, newOptions: CompilerOptions) { + private updateNonInferredProject(project: ExternalProject | ConfiguredProject, newUncheckedFiles: T[], propertyReader: FilePropertyReader, newOptions: CompilerOptions, newTypingOptions: TypingOptions) { const oldRootScriptInfos = project.getRootScriptInfos(); const newRootScriptInfos: ScriptInfo[] = []; const newRootScriptInfoMap: NormalizedPathMap = createNormalizedPathMap(); @@ -834,6 +835,7 @@ namespace ts.server { } project.setCompilerOptions(newOptions); + (project).setTypingOptions(newTypingOptions); project.updateGraph(); } @@ -863,7 +865,7 @@ namespace ts.server { project.enableLanguageService(); } this.watchConfigDirectoryForProject(project, projectOptions); - this.updateNonInferredProject(project, projectOptions.files, fileNamePropertyReader, projectOptions.compilerOptions); + this.updateNonInferredProject(project, projectOptions.files, fileNamePropertyReader, projectOptions.compilerOptions, projectOptions.typingOptions); } } @@ -1133,7 +1135,7 @@ namespace ts.server { openExternalProject(proj: protocol.ExternalProject): void { const externalProject = this.findExternalProjectByProjectName(proj.projectFileName); if (externalProject) { - this.updateNonInferredProject(externalProject, proj.rootFiles, externalFilePropertyReader, proj.options); + this.updateNonInferredProject(externalProject, proj.rootFiles, externalFilePropertyReader, proj.options, proj.typingOptions); return; } @@ -1165,7 +1167,7 @@ namespace ts.server { } } else { - this.createAndAddExternalProject(proj.projectFileName, rootFiles, proj.options); + this.createAndAddExternalProject(proj.projectFileName, rootFiles, proj.options, proj.typingOptions); } } } diff --git a/src/server/project.ts b/src/server/project.ts index e8293decdd389..d4d502c11e78c 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -19,6 +19,12 @@ namespace ts.server { } } + const jsOrDts = [".js", ".d.ts"]; + + export function allFilesAreJsOrDts(project: Project): boolean { + return project.getFileNames().every(f => fileExtensionIsAny(f, jsOrDts)); + } + export abstract class Project { private rootFiles: ScriptInfo[] = []; private rootFilesMap: FileMap = createFileMap(); @@ -103,6 +109,7 @@ namespace ts.server { } abstract getProjectName(): string; + abstract getTypingOptions(): TypingOptions; close() { if (this.program) { @@ -414,6 +421,14 @@ namespace ts.server { this.projectService.stopWatchingDirectory(directory); } } + + getTypingOptions(): TypingOptions { + return { + enableAutoDiscovery: allFilesAreJsOrDts(this), + include: [], + exclude: [] + }; + } } export class ConfiguredProject extends Project { @@ -434,6 +449,10 @@ namespace ts.server { super(ProjectKind.Configured, projectService, documentRegistry, hasExplicitListOfFiles, languageServiceEnabled, compilerOptions); } + setTypingOptions(newTypingOptions: TypingOptions): void { + this.typingOptions = newTypingOptions; + } + getTypingOptions() { return this.typingOptions; } @@ -508,12 +527,43 @@ namespace ts.server { } export class ExternalProject extends Project { + private typingOptions: TypingOptions; constructor(readonly externalProjectName: string, projectService: ProjectService, documentRegistry: ts.DocumentRegistry, compilerOptions: CompilerOptions, + typingOptions: TypingOptions, languageServiceEnabled: boolean) { super(ProjectKind.External, projectService, documentRegistry, /*hasExplicitListOfFiles*/ true, languageServiceEnabled, compilerOptions); + this.setTypingOptions(typingOptions); + } + + getTypingOptions() { + return this.typingOptions; + } + + setTypingOptions(newTypingOptions: TypingOptions): void { + if (!newTypingOptions) { + // set default typings options + newTypingOptions = { + enableAutoDiscovery: allFilesAreJsOrDts(this), + include: [], + exclude: [] + }; + } + else { + if (newTypingOptions.enableAutoDiscovery === undefined) { + // if autoDiscovery was not specified by the caller - set it based on the content of the project + newTypingOptions.enableAutoDiscovery = allFilesAreJsOrDts(this); + } + if (!newTypingOptions.include) { + newTypingOptions.include = []; + } + if (!newTypingOptions.exclude) { + newTypingOptions.exclude = []; + } + } + this.typingOptions = newTypingOptions; } getProjectName() { diff --git a/src/server/protocol.d.ts b/src/server/protocol.d.ts index ec3d219c5b580..d9267d9e4be58 100644 --- a/src/server/protocol.d.ts +++ b/src/server/protocol.d.ts @@ -499,6 +499,7 @@ declare namespace ts.server.protocol { projectFileName: string; rootFiles: ExternalFile[]; options: CompilerOptions; + typingOptions?: TypingOptions; } export interface ProjectVersionInfo { diff --git a/src/server/typingsCache.ts b/src/server/typingsCache.ts index eb1d3283e08d0..efbeb3d8fbe09 100644 --- a/src/server/typingsCache.ts +++ b/src/server/typingsCache.ts @@ -20,20 +20,6 @@ namespace ts.server { poisoned: boolean; } - const emptyArray: any[] = []; - const jsOrDts = [".js", ".d.ts"]; - - function getTypingOptionsForProjects(proj: Project): TypingOptions { - if (proj.projectKind === ProjectKind.Configured) { - return (proj).getTypingOptions(); - } - - const enableAutoDiscovery = proj.getFileNames().every(f => fileExtensionIsAny(f, jsOrDts)); - - // TODO: add .d.ts files to excludes - return { enableAutoDiscovery, include: emptyArray, exclude: emptyArray }; - } - function setIsEqualTo(arr1: string[], arr2: string[]): boolean { if (arr1 === arr2) { return true; @@ -89,7 +75,7 @@ namespace ts.server { } getTypingsForProject(project: Project): TypingsArray { - const typingOptions = getTypingOptionsForProjects(project); + const typingOptions = project.getTypingOptions(); if (!typingOptions.enableAutoDiscovery) { return emptyArray; @@ -113,7 +99,7 @@ namespace ts.server { } invalidateCachedTypingsForProject(project: Project) { - const typingOptions = getTypingOptionsForProjects(project); + const typingOptions = project.getTypingOptions(); if (!typingOptions.enableAutoDiscovery) { return; } diff --git a/src/server/utilities.ts b/src/server/utilities.ts index 40e4f3c125334..9c2c4dfb22230 100644 --- a/src/server/utilities.ts +++ b/src/server/utilities.ts @@ -8,6 +8,8 @@ namespace ts.server { verbose } + export const emptyArray: ReadonlyArray = []; + export interface Logger { close(): void; hasLevel(level: LogLevel): boolean;