Skip to content

Commit baf872c

Browse files
committed
Ensure that Project.program is same as LS program
1 parent ff40714 commit baf872c

18 files changed

+281
-39
lines changed

src/harness/incrementalUtils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ function verifyDocumentRegistry(service: ts.server.ProjectService) {
7373
const collectStats = (project: ts.server.Project) => {
7474
if (project.autoImportProviderHost) collectStats(project.autoImportProviderHost);
7575
if (project.noDtsResolutionProject) collectStats(project.noDtsResolutionProject);
76-
const program = project.getCurrentLSProgram();
76+
const program = project.getCurrentProgram();
7777
if (!program) return;
7878
const key = service.documentRegistry.getKeyForCompilationSettings(program.getCompilerOptions());
7979
program.getSourceFiles().forEach(f => {

src/server/editorServices.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2643,6 +2643,7 @@ export class ProjectService {
26432643
private clearSemanticCache(project: Project) {
26442644
project.resolutionCache.clear();
26452645
project.getLanguageService(/*ensureSynchronized*/ false).cleanupSemanticCache();
2646+
project.cleanupProgram();
26462647
project.markAsDirty();
26472648
}
26482649

src/server/project.ts

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -969,13 +969,27 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
969969
this.projectService.onUpdateLanguageServiceStateForProject(this, /*languageServiceEnabled*/ true);
970970
}
971971

972+
/** @internal */
973+
cleanupProgram() {
974+
if (this.program) {
975+
// Root files are always attached to the project irrespective of program
976+
for (const f of this.program.getSourceFiles()) {
977+
this.detachScriptInfoIfNotRoot(f.fileName);
978+
}
979+
this.program.forEachResolvedProjectReference(ref =>
980+
this.detachScriptInfoFromProject(ref.sourceFile.fileName));
981+
this.program = undefined;
982+
}
983+
}
984+
972985
disableLanguageService(lastFileExceededProgramSize?: string) {
973986
if (!this.languageServiceEnabled) {
974987
return;
975988
}
976989
Debug.assert(this.projectService.serverMode !== LanguageServiceMode.Syntactic);
977990
this.languageService.cleanupSemanticCache();
978991
this.languageServiceEnabled = false;
992+
this.cleanupProgram();
979993
this.lastFileExceededProgramSize = lastFileExceededProgramSize;
980994
this.builderState = undefined;
981995
if (this.autoImportProviderHost) {
@@ -1031,17 +1045,10 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
10311045
close() {
10321046
this.projectService.typingsCache.onProjectClosed(this);
10331047
this.closeWatchingTypingLocations();
1034-
if (this.program) {
1035-
// if we have a program - release all files that are enlisted in program but arent root
1036-
// The releasing of the roots happens later
1037-
// The project could have pending update remaining and hence the info could be in the files but not in program graph
1038-
for (const f of this.program.getSourceFiles()) {
1039-
this.detachScriptInfoIfNotRoot(f.fileName);
1040-
}
1041-
this.program.forEachResolvedProjectReference(ref =>
1042-
this.detachScriptInfoFromProject(ref.sourceFile.fileName));
1043-
}
1044-
1048+
// if we have a program - release all files that are enlisted in program but arent root
1049+
// The releasing of the roots happens later
1050+
// The project could have pending update remaining and hence the info could be in the files but not in program graph
1051+
this.cleanupProgram();
10451052
// Release external files
10461053
forEach(this.externalFiles, externalFile => this.detachScriptInfoIfNotRoot(externalFile));
10471054
// Always remove root files from the project
@@ -1486,20 +1493,14 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
14861493
return this.program;
14871494
}
14881495

1489-
/** @internal */
1490-
getCurrentLSProgram(): Program | undefined {
1491-
// TODO:: we dont have same program as LS in some scenarios, can that cause issues?
1492-
// Eg when we clear semantic cache of the LS during disabling LS or reloading projects
1493-
return this.languageService.getCurrentProgram();
1494-
}
1495-
14961496
protected removeExistingTypings(include: string[]): string[] {
14971497
const existing = getAutomaticTypeDirectiveNames(this.getCompilerOptions(), this.directoryStructureHost);
14981498
return include.filter(i => existing.indexOf(i) < 0);
14991499
}
15001500

15011501
private updateGraphWorker() {
15021502
const oldProgram = this.languageService.getCurrentProgram();
1503+
Debug.assert(oldProgram === this.program);
15031504
Debug.assert(!this.isClosed(), "Called update graph worker of closed project");
15041505
this.writeLog(`Starting updateGraphWorker: Project: ${this.getProjectName()}`);
15051506
const start = timestamp();

src/server/session.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1341,6 +1341,7 @@ export class Session<TMessage = string> implements EventSender {
13411341
this.logger.info(`cleaning ${caption}`);
13421342
for (const p of projects) {
13431343
p.getLanguageService(/*ensureSynchronized*/ false).cleanupSemanticCache();
1344+
p.cleanupProgram();
13441345
}
13451346
}
13461347

tests/baselines/reference/tsserver/projectReferences/disables-looking-into-the-child-project-if-disableReferencedProjectLoad-is-set-in-first-indirect-project-but-not-in-another-one.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,15 @@ Info seq [hh:mm:ss:mss] Files (3)
687687
/a/lib/lib.d.ts Text-1 "/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }"
688688
/user/username/projects/myproject/src/helpers/functions.ts Text-2 "export const foo = 1;"
689689
/user/username/projects/myproject/src/main.ts SVC-2-0 "import { foo } from 'helpers/functions';\nexport { foo };"
690+
691+
692+
../../../../a/lib/lib.d.ts
693+
Default library for target 'es5'
694+
src/helpers/functions.ts
695+
Imported via 'helpers/functions' from file 'src/main.ts'
696+
Matched by include pattern './src/**/*' in 'tsconfig-src.json'
697+
src/main.ts
698+
Matched by include pattern './src/**/*' in 'tsconfig-src.json'
690699

691700
Info seq [hh:mm:ss:mss] -----------------------------------------------
692701
Info seq [hh:mm:ss:mss] event:
@@ -719,7 +728,7 @@ Info seq [hh:mm:ss:mss] Files (3)
719728

720729
Info seq [hh:mm:ss:mss] -----------------------------------------------
721730
Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject1*' (Inferred)
722-
Info seq [hh:mm:ss:mss] Files (2)
731+
Info seq [hh:mm:ss:mss] Files (0) NoProgram
723732

724733
Info seq [hh:mm:ss:mss] -----------------------------------------------
725734
Info seq [hh:mm:ss:mss] Open files:
@@ -733,6 +742,12 @@ Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject1*' (Inferred)
733742
Info seq [hh:mm:ss:mss] Files (2)
734743
/a/lib/lib.d.ts Text-1 "/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }"
735744
/dummy/dummy.ts SVC-1-0 "let a = 10;"
745+
746+
747+
../a/lib/lib.d.ts
748+
Default library for target 'es5'
749+
dummy.ts
750+
Root file specified for compilation
736751

737752
Info seq [hh:mm:ss:mss] -----------------------------------------------
738753
Info seq [hh:mm:ss:mss] After ensureProjectForOpenFiles:

tests/baselines/reference/tsserver/projectReferences/disables-looking-into-the-child-project-if-disableReferencedProjectLoad-is-set-in-indirect-project.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,16 @@ Info seq [hh:mm:ss:mss] Files (4)
634634
/user/username/projects/myproject/src/helpers/functions.ts Text-2 "export const foo = 1;"
635635
/user/username/projects/myproject/src/main.ts SVC-2-0 "import { foo } from 'helpers/functions';\nexport { foo };"
636636
/user/username/projects/myproject/indirect1/main.ts Text-2 "import { foo } from 'main';\nfoo;\nexport function bar() {}"
637+
638+
639+
../../../../a/lib/lib.d.ts
640+
Default library for target 'es5'
641+
src/helpers/functions.ts
642+
Imported via 'helpers/functions' from file 'src/main.ts'
643+
src/main.ts
644+
Imported via 'main' from file 'indirect1/main.ts'
645+
indirect1/main.ts
646+
Part of 'files' list in tsconfig.json
637647

638648
Info seq [hh:mm:ss:mss] -----------------------------------------------
639649
Info seq [hh:mm:ss:mss] event:
@@ -666,7 +676,7 @@ Info seq [hh:mm:ss:mss] Files (4)
666676

667677
Info seq [hh:mm:ss:mss] -----------------------------------------------
668678
Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject1*' (Inferred)
669-
Info seq [hh:mm:ss:mss] Files (2)
679+
Info seq [hh:mm:ss:mss] Files (0) NoProgram
670680

671681
Info seq [hh:mm:ss:mss] -----------------------------------------------
672682
Info seq [hh:mm:ss:mss] Open files:
@@ -680,6 +690,12 @@ Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject1*' (Inferred)
680690
Info seq [hh:mm:ss:mss] Files (2)
681691
/a/lib/lib.d.ts Text-1 "/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }"
682692
/dummy/dummy.ts SVC-1-0 "let a = 10;"
693+
694+
695+
../a/lib/lib.d.ts
696+
Default library for target 'es5'
697+
dummy.ts
698+
Root file specified for compilation
683699

684700
Info seq [hh:mm:ss:mss] -----------------------------------------------
685701
Info seq [hh:mm:ss:mss] After ensureProjectForOpenFiles:

tests/baselines/reference/tsserver/projectReferences/disables-looking-into-the-child-project-if-disableReferencedProjectLoad-is-set.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -480,11 +480,11 @@ Info seq [hh:mm:ss:mss] Files (0)
480480

481481
Info seq [hh:mm:ss:mss] -----------------------------------------------
482482
Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject2*' (Inferred)
483-
Info seq [hh:mm:ss:mss] Files (2)
483+
Info seq [hh:mm:ss:mss] Files (0) NoProgram
484484

485485
Info seq [hh:mm:ss:mss] -----------------------------------------------
486486
Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject3*' (Inferred)
487-
Info seq [hh:mm:ss:mss] Files (2)
487+
Info seq [hh:mm:ss:mss] Files (0) NoProgram
488488

489489
Info seq [hh:mm:ss:mss] -----------------------------------------------
490490
Info seq [hh:mm:ss:mss] Open files:
@@ -498,6 +498,12 @@ Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject2*' (Inferred)
498498
Info seq [hh:mm:ss:mss] Files (2)
499499
/a/lib/lib.d.ts Text-1 "/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }"
500500
/dummy/dummy.ts SVC-1-0 "let a = 10;"
501+
502+
503+
../a/lib/lib.d.ts
504+
Default library for target 'es5'
505+
dummy.ts
506+
Root file specified for compilation
501507

502508
Info seq [hh:mm:ss:mss] -----------------------------------------------
503509
Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /dev/null/inferredProject3*
@@ -518,6 +524,12 @@ Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject3*' (Inferred)
518524
Info seq [hh:mm:ss:mss] Files (2)
519525
/a/lib/lib.d.ts Text-1 "/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }"
520526
/user/username/projects/myproject/src/main.ts SVC-2-0 "import { foo } from 'helpers/functions';\nexport { foo };"
527+
528+
529+
../../../../../a/lib/lib.d.ts
530+
Default library for target 'es5'
531+
main.ts
532+
Root file specified for compilation
521533

522534
Info seq [hh:mm:ss:mss] -----------------------------------------------
523535
Info seq [hh:mm:ss:mss] After ensureProjectForOpenFiles:

tests/baselines/reference/tsserver/projectReferences/project-is-directly-referenced-by-solution.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,15 @@ Info seq [hh:mm:ss:mss] Files (3)
748748
/a/lib/lib.d.ts Text-1 "/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }"
749749
/user/username/projects/myproject/src/helpers/functions.ts Text-2 "export const foo = 1;"
750750
/user/username/projects/myproject/src/main.ts SVC-2-0 "import { foo } from 'helpers/functions';\nexport { foo };"
751+
752+
753+
../../../../a/lib/lib.d.ts
754+
Default library for target 'es5'
755+
src/helpers/functions.ts
756+
Imported via 'helpers/functions' from file 'src/main.ts'
757+
Matched by include pattern './src/**/*' in 'tsconfig-src.json'
758+
src/main.ts
759+
Matched by include pattern './src/**/*' in 'tsconfig-src.json'
751760

752761
Info seq [hh:mm:ss:mss] -----------------------------------------------
753762
Info seq [hh:mm:ss:mss] event:
@@ -782,7 +791,7 @@ Info seq [hh:mm:ss:mss] Files (3)
782791

783792
Info seq [hh:mm:ss:mss] -----------------------------------------------
784793
Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject1*' (Inferred)
785-
Info seq [hh:mm:ss:mss] Files (2)
794+
Info seq [hh:mm:ss:mss] Files (0) NoProgram
786795

787796
Info seq [hh:mm:ss:mss] -----------------------------------------------
788797
Info seq [hh:mm:ss:mss] Open files:
@@ -796,6 +805,12 @@ Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject1*' (Inferred)
796805
Info seq [hh:mm:ss:mss] Files (2)
797806
/a/lib/lib.d.ts Text-1 "/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }"
798807
/dummy/dummy.ts SVC-1-0 "let a = 10;"
808+
809+
810+
../a/lib/lib.d.ts
811+
Default library for target 'es5'
812+
dummy.ts
813+
Root file specified for compilation
799814

800815
Info seq [hh:mm:ss:mss] -----------------------------------------------
801816
Info seq [hh:mm:ss:mss] After ensureProjectForOpenFiles:

tests/baselines/reference/tsserver/projectReferences/project-is-indirectly-referenced-by-solution.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -888,6 +888,15 @@ Info seq [hh:mm:ss:mss] Files (3)
888888
/a/lib/lib.d.ts Text-1 "/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }"
889889
/user/username/projects/myproject/src/helpers/functions.ts Text-2 "export const foo = 1;"
890890
/user/username/projects/myproject/src/main.ts SVC-2-0 "import { foo } from 'helpers/functions';\nexport { foo };"
891+
892+
893+
../../../../a/lib/lib.d.ts
894+
Default library for target 'es5'
895+
src/helpers/functions.ts
896+
Imported via 'helpers/functions' from file 'src/main.ts'
897+
Matched by include pattern './src/**/*' in 'tsconfig-src.json'
898+
src/main.ts
899+
Matched by include pattern './src/**/*' in 'tsconfig-src.json'
891900

892901
Info seq [hh:mm:ss:mss] -----------------------------------------------
893902
Info seq [hh:mm:ss:mss] event:
@@ -922,7 +931,7 @@ Info seq [hh:mm:ss:mss] Files (3)
922931

923932
Info seq [hh:mm:ss:mss] -----------------------------------------------
924933
Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject1*' (Inferred)
925-
Info seq [hh:mm:ss:mss] Files (2)
934+
Info seq [hh:mm:ss:mss] Files (0) NoProgram
926935

927936
Info seq [hh:mm:ss:mss] -----------------------------------------------
928937
Info seq [hh:mm:ss:mss] Open files:
@@ -936,6 +945,12 @@ Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject1*' (Inferred)
936945
Info seq [hh:mm:ss:mss] Files (2)
937946
/a/lib/lib.d.ts Text-1 "/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }"
938947
/dummy/dummy.ts SVC-1-0 "let a = 10;"
948+
949+
950+
../a/lib/lib.d.ts
951+
Default library for target 'es5'
952+
dummy.ts
953+
Root file specified for compilation
939954

940955
Info seq [hh:mm:ss:mss] -----------------------------------------------
941956
Info seq [hh:mm:ss:mss] After ensureProjectForOpenFiles:

0 commit comments

Comments
 (0)