From 8c4607d8ebea0ee11b827409da2dc352da37c4d2 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Wed, 25 Jul 2018 13:12:52 -0700 Subject: [PATCH] Dont delay external project update from openExternalProject Since external projects are needed to be uptodate when opening file, so in most likely scenarios these will be loaded anyways so there is no saving in postponing this work --- src/server/editorServices.ts | 7 +++- .../unittests/tsserverProjectSystem.ts | 35 ++----------------- src/testRunner/unittests/typingsInstaller.ts | 16 --------- 3 files changed, 8 insertions(+), 50 deletions(-) diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 9dae626d91e..9ff4f4ef9b8 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -2564,7 +2564,9 @@ namespace ts.server { externalProject.enableLanguageService(); } // external project already exists and not config files were added - update the project and return; + // The graph update here isnt postponed since any file open operation needs all updated external projects this.updateRootAndOptionsOfNonInferredProject(externalProject, proj.rootFiles, externalFilePropertyReader, compilerOptions, proj.typeAcquisition, proj.options.compileOnSave); + externalProject.updateGraph(); return; } // some config files were added to external project (that previously were not there) @@ -2622,8 +2624,11 @@ namespace ts.server { } else { // no config files - remove the item from the collection + // Create external project and update its graph, do not delay update since + // any file open operation needs all updated external projects this.externalProjectToConfiguredProjectMap.delete(proj.projectFileName); - this.createExternalProject(proj.projectFileName, rootFiles, proj.options, proj.typeAcquisition, excludedFiles); + const project = this.createExternalProject(proj.projectFileName, rootFiles, proj.options, proj.typeAcquisition, excludedFiles); + project.updateGraph(); } } diff --git a/src/testRunner/unittests/tsserverProjectSystem.ts b/src/testRunner/unittests/tsserverProjectSystem.ts index 6e7a41eee12..4f85cbf00b3 100644 --- a/src/testRunner/unittests/tsserverProjectSystem.ts +++ b/src/testRunner/unittests/tsserverProjectSystem.ts @@ -1776,11 +1776,8 @@ namespace ts.projectSystem { try { projectService.openExternalProject({ projectFileName: "project", options: {}, rootFiles: toExternalFiles([file1.path, office.path]) }); const proj = projectService.externalProjects[0]; - // Since the file is not yet open, the project wont have program yet - assert.deepEqual(proj.getFileNames(/*excludeFilesFromExternalLibraries*/ true), emptyArray); - assert.deepEqual(proj.getTypeAcquisition().include, ["duck-types"]); - projectService.openClientFile(file1.path); assert.deepEqual(proj.getFileNames(/*excludeFilesFromExternalLibraries*/ true), [file1.path]); + assert.deepEqual(proj.getTypeAcquisition().include, ["duck-types"]); } finally { projectService.resetSafeList(); } @@ -1821,11 +1818,8 @@ namespace ts.projectSystem { try { projectService.openExternalProject({ projectFileName: "project", options: {}, rootFiles: toExternalFiles(files.map(f => f.path)) }); const proj = projectService.externalProjects[0]; - // Since the file is not yet open, the project wont have program yet - assert.deepEqual(proj.getFileNames(/*excludeFilesFromExternalLibraries*/ true), emptyArray); - assert.deepEqual(proj.getTypeAcquisition().include, ["kendo-ui", "office"]); - projectService.openClientFile(file1.path); assert.deepEqual(proj.getFileNames(/*excludeFilesFromExternalLibraries*/ true), [file1.path]); + assert.deepEqual(proj.getTypeAcquisition().include, ["kendo-ui", "office"]); } finally { projectService.resetSafeList(); } @@ -1865,9 +1859,6 @@ namespace ts.projectSystem { try { projectService.openExternalProject({ projectFileName: "project", options: {}, rootFiles: toExternalFiles([file1.path, file2.path]), typeAcquisition: { enable: true } }); const proj = projectService.externalProjects[0]; - // Since the file is not yet open, the project wont have program yet - assert.deepEqual(proj.getFileNames(), emptyArray); - projectService.openClientFile(file2.path); assert.deepEqual(proj.getFileNames(), [file2.path]); } finally { projectService.resetSafeList(); @@ -2083,9 +2074,6 @@ namespace ts.projectSystem { projectService.openExternalProject({ projectFileName: "project", options: {}, rootFiles: toExternalFiles([file1.path]) }); checkNumberOfProjects(projectService, { externalProjects: 1 }); - // Since the file is not yet open, the project wont have program yet - assert.deepEqual(projectService.externalProjects[0].getFileNames(), emptyArray); - projectService.openClientFile(file1.path); checkProjectActualFiles(projectService.externalProjects[0], [file1.path]); projectService.openExternalProject({ projectFileName: "project", options: {}, rootFiles: toExternalFiles([file1.path, file2.path]) }); @@ -2113,17 +2101,11 @@ namespace ts.projectSystem { projectService.openExternalProject({ projectFileName: "project", options: { moduleResolution: ModuleResolutionKind.NodeJs }, rootFiles: toExternalFiles([file1.path, file2.path]) }); checkNumberOfProjects(projectService, { externalProjects: 1 }); checkProjectRootFiles(projectService.externalProjects[0], [file1.path, file2.path]); - // Since the file is not yet open, the project wont have program yet - checkProjectActualFiles(projectService.externalProjects[0], emptyArray); - projectService.openClientFile(file1.path); checkProjectActualFiles(projectService.externalProjects[0], [file1.path, file2.path]); projectService.openExternalProject({ projectFileName: "project", options: { moduleResolution: ModuleResolutionKind.Classic }, rootFiles: toExternalFiles([file1.path, file2.path]) }); checkNumberOfProjects(projectService, { externalProjects: 1 }); checkProjectRootFiles(projectService.externalProjects[0], [file1.path, file2.path]); - // The update doesnt happen right away until needed, so either open a file or ensure projects uptodate - checkProjectActualFiles(projectService.externalProjects[0], [file1.path, file2.path]); - projectService.ensureInferredProjectsUpToDate_TestOnly(); checkProjectActualFiles(projectService.externalProjects[0], [file1.path, file2.path, file3.path]); }); @@ -2425,10 +2407,6 @@ namespace ts.projectSystem { projectService.openExternalProject({ projectFileName, options: {}, rootFiles: [{ fileName: file1.path, scriptKind: ScriptKind.JS, hasMixedContent: true }] }); checkNumberOfProjects(projectService, { externalProjects: 1 }); - // Since the external project is not updated till needed (eg opening client file/ensuringProjectStructureUptodate) - // watched files will be empty at first - checkWatchedFiles(host, emptyArray); - projectService.ensureInferredProjectsUpToDate_TestOnly(); checkWatchedFiles(host, [libFile.path]); // watching the "missing" lib file const project = projectService.externalProjects[0]; @@ -3013,9 +2991,6 @@ namespace ts.projectSystem { projectService.openExternalProjects([externalProject]); checkNumberOfProjects(projectService, { configuredProjects: 0, externalProjects: 1, inferredProjects: 0 }); - // Since the external project is not updated till needed (eg opening client file/ensuringProjectStructureUptodate) - checkProjectActualFiles(projectService.externalProjects[0], emptyArray); - projectService.ensureInferredProjectsUpToDate_TestOnly(); checkProjectActualFiles(projectService.externalProjects[0], [site.path, libFile.path]); }); @@ -4019,8 +3994,6 @@ namespace ts.projectSystem { }); projectService.checkNumberOfProjects({ externalProjects: 1 }); - checkProjectActualFiles(projectService.externalProjects[0], emptyArray); // external project created but not updated till actually needed - projectService.ensureInferredProjectsUpToDate_TestOnly(); checkProjectActualFiles(projectService.externalProjects[0], [f1.path, f2.path]); }); @@ -4058,8 +4031,6 @@ namespace ts.projectSystem { }); projectService.checkNumberOfProjects({ externalProjects: 1 }); - checkProjectActualFiles(projectService.externalProjects[0], emptyArray); // external project created but program is not created till its needed - projectService.ensureInferredProjectsUpToDate_TestOnly(); checkProjectActualFiles(projectService.externalProjects[0], [f1.path]); // add two config file as root files @@ -4093,8 +4064,6 @@ namespace ts.projectSystem { }); projectService.checkNumberOfProjects({ externalProjects: 1 }); - checkProjectActualFiles(projectService.externalProjects[0], emptyArray); // external project created but program is not created till its needed - projectService.ensureInferredProjectsUpToDate_TestOnly(); checkProjectActualFiles(projectService.externalProjects[0], [f1.path]); // open two config files diff --git a/src/testRunner/unittests/typingsInstaller.ts b/src/testRunner/unittests/typingsInstaller.ts index 0b8a62239e2..6a7e76e15de 100644 --- a/src/testRunner/unittests/typingsInstaller.ts +++ b/src/testRunner/unittests/typingsInstaller.ts @@ -330,8 +330,6 @@ namespace ts.projectSystem { typeAcquisition: { enable: true, include: ["jquery"] } }); - assert.isFalse(enqueueIsCalled, "expected enqueueIsCalled to be false since external project isnt updated right away"); - projectService.ensureInferredProjectsUpToDate_TestOnly(); assert.isTrue(enqueueIsCalled, "expected enqueueIsCalled to be true"); installer.installAll(/*expectedCount*/ 1); @@ -388,8 +386,6 @@ namespace ts.projectSystem { const p = projectService.externalProjects[0]; projectService.checkNumberOfProjects({ externalProjects: 1 }); - checkProjectActualFiles(p, emptyArray); // external project created but not updated - projectService.ensureInferredProjectsUpToDate_TestOnly(); checkProjectActualFiles(p, [file2Jsx.path, file3dts.path]); installer.installAll(/*expectedCount*/ 1); @@ -434,8 +430,6 @@ namespace ts.projectSystem { const p = projectService.externalProjects[0]; projectService.checkNumberOfProjects({ externalProjects: 1 }); - checkProjectActualFiles(p, emptyArray); // external project created but not updated - projectService.ensureInferredProjectsUpToDate_TestOnly(); checkProjectActualFiles(p, [jqueryJs.path]); installer.checkPendingCommands(/*expectedCount*/ 0); @@ -479,8 +473,6 @@ namespace ts.projectSystem { const p = projectService.externalProjects[0]; projectService.checkNumberOfProjects({ externalProjects: 1 }); - checkProjectActualFiles(p, emptyArray); // external project created but not updated - projectService.ensureInferredProjectsUpToDate_TestOnly(); checkProjectActualFiles(p, [jqueryJs.path, file2Ts.path]); installer.checkPendingCommands(/*expectedCount*/ 0); @@ -556,8 +548,6 @@ namespace ts.projectSystem { const p = projectService.externalProjects[0]; projectService.checkNumberOfProjects({ externalProjects: 1 }); - checkProjectActualFiles(p, emptyArray); // external project created but not updated - projectService.ensureInferredProjectsUpToDate_TestOnly(); checkProjectActualFiles(p, [file3dts.path]); installer.installAll(/*expectedCount*/ 1); @@ -640,8 +630,6 @@ namespace ts.projectSystem { const p = projectService.externalProjects[0]; projectService.checkNumberOfProjects({ externalProjects: 1 }); - checkProjectActualFiles(p, emptyArray); // external project created but not updated - projectService.ensureInferredProjectsUpToDate_TestOnly(); checkProjectActualFiles(p, [file3.path]); installer.checkPendingCommands(/*expectedCount*/ 1); installer.executePendingCommands(); @@ -726,8 +714,6 @@ namespace ts.projectSystem { typeAcquisition: { include: ["jquery", "cordova"] } }); - checkProjectActualFiles(projectService.externalProjects[0], emptyArray); // external project created but not updated - projectService.ensureInferredProjectsUpToDate_TestOnly(); installer.checkPendingCommands(/*expectedCount*/ 1); assert.equal(installer.pendingRunRequests.length, 0, "expect no throttled requests"); @@ -739,8 +725,6 @@ namespace ts.projectSystem { rootFiles: [toExternalFile(file3.path)], typeAcquisition: { include: ["grunt", "gulp"] } }); - checkProjectActualFiles(projectService.externalProjects[1], emptyArray); // external project created but not updated - projectService.ensureInferredProjectsUpToDate_TestOnly(); assert.equal(installer.pendingRunRequests.length, 1, "expect one throttled request"); const p1 = projectService.externalProjects[0];