diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 023cc1ac472..ef3024f890d 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -2258,6 +2258,8 @@ namespace ts { * Adds a trailing directory separator to a path, if it does not already have one. * @param path The path. */ + export function ensureTrailingDirectorySeparator(path: Path): Path; + export function ensureTrailingDirectorySeparator(path: string): string; export function ensureTrailingDirectorySeparator(path: string) { if (path.charAt(path.length - 1) !== directorySeparator) { return path + directorySeparator; diff --git a/src/harness/unittests/typingsInstaller.ts b/src/harness/unittests/typingsInstaller.ts index 0a27f860352..9b874b2aca6 100644 --- a/src/harness/unittests/typingsInstaller.ts +++ b/src/harness/unittests/typingsInstaller.ts @@ -141,12 +141,15 @@ namespace ts.projectSystem { checkNumberOfProjects(projectService, { configuredProjects: 1 }); const p = configuredProjectAt(projectService, 0); checkProjectActualFiles(p, [file1.path, tsconfig.path]); + checkWatchedFiles(host, [tsconfig.path, libFile.path, packageJson.path, "/a/b/bower_components", "/a/b/node_modules"]); installer.installAll(/*expectedCount*/ 1); checkNumberOfProjects(projectService, { configuredProjects: 1 }); host.checkTimeoutQueueLengthAndRun(2); checkProjectActualFiles(p, [file1.path, jquery.path, tsconfig.path]); + // should not watch jquery + checkWatchedFiles(host, [tsconfig.path, libFile.path, packageJson.path, "/a/b/bower_components", "/a/b/node_modules"]); }); it("inferred project (typings installed)", () => { @@ -188,7 +191,7 @@ namespace ts.projectSystem { checkProjectActualFiles(p, [file1.path]); installer.installAll(/*expectedCount*/ 1); - + host.checkTimeoutQueueLengthAndRun(2); checkNumberOfProjects(projectService, { inferredProjects: 1 }); checkProjectActualFiles(p, [file1.path, jquery.path]); }); @@ -961,6 +964,7 @@ namespace ts.projectSystem { assert.isTrue(host.fileExists(node.path), "typings for 'node' should be created"); assert.isTrue(host.fileExists(commander.path), "typings for 'commander' should be created"); + host.checkTimeoutQueueLengthAndRun(2); checkProjectActualFiles(service.inferredProjects[0], [file.path, node.path, commander.path]); }); @@ -1106,7 +1110,7 @@ namespace ts.projectSystem { checkProjectActualFiles(p, [file1.path]); installer.installAll(/*expectedCount*/ 1); - + host.checkTimeoutQueueLengthAndRun(2); checkNumberOfProjects(projectService, { inferredProjects: 1 }); checkProjectActualFiles(p, [file1.path, jquery.path]); }); diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index c46e2fa6875..d7b6d814fe5 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -389,6 +389,7 @@ namespace ts.server { public readonly useSingleInferredProject: boolean; public readonly useInferredProjectPerProjectRoot: boolean; public readonly typingsInstaller: ITypingsInstaller; + private readonly globalCacheLocationDirectoryPath: Path; public readonly throttleWaitMilliseconds?: number; private readonly eventHandler?: ProjectServiceEventHandler; @@ -423,6 +424,8 @@ namespace ts.server { } this.currentDirectory = this.host.getCurrentDirectory(); this.toCanonicalFileName = createGetCanonicalFileName(this.host.useCaseSensitiveFileNames); + this.globalCacheLocationDirectoryPath = this.typingsInstaller.globalTypingsCacheLocation && + ensureTrailingDirectorySeparator(this.toPath(this.typingsInstaller.globalTypingsCacheLocation)); this.throttledOperations = new ThrottledOperations(this.host, this.logger); if (this.typesMapLocation) { @@ -539,10 +542,11 @@ namespace ts.server { else { if (this.pendingEnsureProjectForOpenFiles) { this.ensureProjectForOpenFiles(); + + // Send the event to notify that there were background project updates + // send current list of open files + this.sendProjectsUpdatedInBackgroundEvent(); } - // Send the event to notify that there were background project updates - // send current list of open files - this.sendProjectsUpdatedInBackgroundEvent(); } }); } @@ -633,7 +637,6 @@ namespace ts.server { return undefined; } if (isInferredProjectName(projectName)) { - this.ensureProjectStructuresUptoDate(); return findProjectByName(projectName, this.inferredProjects); } return this.findExternalProjectByProjectName(projectName) || this.findConfiguredProjectByProjectName(toNormalizedPath(projectName)); @@ -1725,7 +1728,10 @@ namespace ts.server { private watchClosedScriptInfo(info: ScriptInfo) { Debug.assert(!info.fileWatcher); // do not watch files with mixed content - server doesn't know how to interpret it - if (!info.isDynamicOrHasMixedContent()) { + // do not watch files in the global cache location + if (!info.isDynamicOrHasMixedContent() && + (!this.globalCacheLocationDirectoryPath || + !startsWith(info.path, this.globalCacheLocationDirectoryPath))) { const { fileName } = info; info.fileWatcher = this.watchFactory.watchFilePath( this.host, diff --git a/src/server/server.ts b/src/server/server.ts index c1f7b866803..8b2b4893bd6 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -234,12 +234,6 @@ namespace ts.server { } } - // E.g. "12:34:56.789" - function nowString() { - const d = new Date(); - return `${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}.${d.getMilliseconds()}`; - } - interface QueuedOperation { operationId: string; operation: () => void; diff --git a/src/server/shared.ts b/src/server/shared.ts index e8b64ce06ec..b46a385106e 100644 --- a/src/server/shared.ts +++ b/src/server/shared.ts @@ -33,4 +33,11 @@ namespace ts.server { ? sys.args[index + 1] : undefined; } -} \ No newline at end of file + + /*@internal*/ + export function nowString() { + // E.g. "12:34:56.789" + const d = new Date(); + return `${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}.${d.getMilliseconds()}`; + } +} diff --git a/src/server/typingsInstaller/nodeTypingsInstaller.ts b/src/server/typingsInstaller/nodeTypingsInstaller.ts index 018dac7ec10..37555bf310b 100644 --- a/src/server/typingsInstaller/nodeTypingsInstaller.ts +++ b/src/server/typingsInstaller/nodeTypingsInstaller.ts @@ -21,7 +21,7 @@ namespace ts.server.typingsInstaller { } writeLine = (text: string) => { try { - fs.appendFileSync(this.logFile, text + sys.newLine); + fs.appendFileSync(this.logFile, `[${nowString()}] ${text}${sys.newLine}`); } catch (e) { this.logEnabled = false; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index a2f9506dc1c..3e095dba77d 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -7847,6 +7847,7 @@ declare namespace ts.server { readonly useSingleInferredProject: boolean; readonly useInferredProjectPerProjectRoot: boolean; readonly typingsInstaller: ITypingsInstaller; + private readonly globalCacheLocationDirectoryPath; readonly throttleWaitMilliseconds?: number; private readonly eventHandler?; readonly globalPlugins: ReadonlyArray;