@@ -713,6 +713,8 @@ function isAncestorConfigFileInfo(infoOrFileNameOrConfig: OpenScriptInfoOrClosed
713
713
export enum ConfiguredProjectLoadKind {
714
714
FindOptimized ,
715
715
Find ,
716
+ CreateReplayOptimized ,
717
+ CreateReplay ,
716
718
CreateOptimized ,
717
719
Create ,
718
720
ReloadOptimized ,
@@ -721,11 +723,13 @@ export enum ConfiguredProjectLoadKind {
721
723
722
724
type ConguredProjectLoadFindCreateOrReload =
723
725
| ConfiguredProjectLoadKind . Find
726
+ | ConfiguredProjectLoadKind . CreateReplay
724
727
| ConfiguredProjectLoadKind . Create
725
728
| ConfiguredProjectLoadKind . Reload ;
726
729
727
730
type ConguredProjectLoadFindCreateOrReloadOptimized =
728
731
| ConfiguredProjectLoadKind . FindOptimized
732
+ | ConfiguredProjectLoadKind . CreateReplayOptimized
729
733
| ConfiguredProjectLoadKind . CreateOptimized
730
734
| ConfiguredProjectLoadKind . ReloadOptimized ;
731
735
@@ -753,6 +757,18 @@ export interface FindCreateOrLoadConfiguredProjectResult {
753
757
reason : string | undefined ;
754
758
}
755
759
760
+ /** @internal */
761
+ export interface DefaultConfiguredProjectInfo {
762
+ /** List of config files looked and did not match because file was not part of root file names */
763
+ notMatchedByConfig ?: Set < NormalizedPath > ;
764
+ /** List of projects which were loaded but file was not part of the project */
765
+ notInProject ?: Set < ConfiguredProject > ;
766
+ /** List of projects where file was present in project but its a file from referenced project */
767
+ inProjectWithReference ?: Set < ConfiguredProject > ;
768
+ /** Configured project used as default */
769
+ defaultProject ?: ConfiguredProject ;
770
+ }
771
+
756
772
/**
757
773
* Goes through each tsconfig from project till project root of open script info and finds, creates or reloads project per kind
758
774
*/
@@ -794,8 +810,7 @@ function forEachAncestorProjectLoad<T>(
794
810
configFileInfo : true ,
795
811
isForDefaultProject : ! searchOnlyPotentialSolution ,
796
812
} ,
797
- kind === ConfiguredProjectLoadKind . Find ||
798
- kind === ConfiguredProjectLoadKind . FindOptimized ,
813
+ kind <= ConfiguredProjectLoadKind . CreateReplay ,
799
814
) ;
800
815
if ( ! configFileName ) return ;
801
816
@@ -865,21 +880,28 @@ function forEachResolvedProjectReferenceProjectLoad<T>(
865
880
configFileExistenceInfo ?. exists || project . resolvedChildConfigs ?. has ( childCanonicalConfigPath ) ?
866
881
configFileExistenceInfo ! . config ! . parsedCommandLine : undefined :
867
882
project . getParsedCommandLine ( childConfigName ) ;
868
- if ( childConfig && loadKind !== kind ) {
883
+ if ( childConfig && loadKind !== kind && loadKind > ConfiguredProjectLoadKind . CreateReplayOptimized ) {
869
884
// If this was found using find: ensure this is uptodate if looking for creating or reloading
870
885
childConfig = project . getParsedCommandLine ( childConfigName ) ;
871
886
}
872
887
if ( ! childConfig ) return undefined ;
873
888
874
889
// Find the project
875
890
const childProject = project . projectService . findConfiguredProjectByProjectName ( childConfigName , allowDeferredClosed ) ;
891
+ // Ignore if we couldnt find child project or config file existence info
892
+ if (
893
+ loadKind === ConfiguredProjectLoadKind . CreateReplayOptimized &&
894
+ ! configFileExistenceInfo &&
895
+ ! childProject
896
+ ) return undefined ;
876
897
switch ( loadKind ) {
877
898
case ConfiguredProjectLoadKind . ReloadOptimized :
878
899
if ( childProject ) childProject . projectService . reloadConfiguredProjectOptimized ( childProject , reason , reloadedProjects ! ) ;
879
900
// falls through
880
901
case ConfiguredProjectLoadKind . CreateOptimized :
881
902
( project . resolvedChildConfigs ??= new Set ( ) ) . add ( childCanonicalConfigPath ) ;
882
- // falls through
903
+ // falls through
904
+ case ConfiguredProjectLoadKind . CreateReplayOptimized :
883
905
case ConfiguredProjectLoadKind . FindOptimized :
884
906
if ( childProject || loadKind !== ConfiguredProjectLoadKind . FindOptimized ) {
885
907
const result = cb (
@@ -930,6 +952,12 @@ function updateProjectFoundUsingFind(
930
952
// This project was found using "Find" instead of the actually specified kind of "Create" or "Reload",
931
953
// We need to update or reload this existing project before calling callback
932
954
switch ( kind ) {
955
+ case ConfiguredProjectLoadKind . CreateReplayOptimized :
956
+ case ConfiguredProjectLoadKind . CreateReplay :
957
+ if ( useConfigFileExistenceInfoForOptimizedLoading ( project ) ) {
958
+ configFileExistenceInfo = project . projectService . configFileExistenceInfoCache . get ( project . canonicalConfigFilePath ) ! ;
959
+ }
960
+ break ;
933
961
case ConfiguredProjectLoadKind . CreateOptimized :
934
962
configFileExistenceInfo = configFileExistenceInfoForOptimizedLoading ( project ) ;
935
963
if ( configFileExistenceInfo ) break ;
@@ -1077,9 +1105,21 @@ function configFileExistenceInfoForOptimizedLoading(project: ConfiguredProject)
1077
1105
project . resolvedChildConfigs = undefined ;
1078
1106
project . updateReferences ( parsedCommandLine . projectReferences ) ;
1079
1107
// Composite can determine based on files themselves, no need to load project
1080
- if ( parsedCommandLine . options . composite ) return configFileExistenceInfo ;
1081
1108
// If solution, no need to load it to determine if file belongs to it
1082
- if ( isSolutionConfig ( parsedCommandLine ) ) return configFileExistenceInfo ;
1109
+ if ( useConfigFileExistenceInfoForOptimizedLoading ( project ) ) return configFileExistenceInfo ;
1110
+ }
1111
+
1112
+ function useConfigFileExistenceInfoForOptimizedLoading ( project : ConfiguredProject ) {
1113
+ return ! ! project . parsedCommandLine &&
1114
+ ( ! ! project . parsedCommandLine . options . composite ||
1115
+ // If solution, no need to load it to determine if file belongs to it
1116
+ ! ! isSolutionConfig ( project . parsedCommandLine ) ) ;
1117
+ }
1118
+
1119
+ function configFileExistenceInfoForOptimizedReplay ( project : ConfiguredProject ) {
1120
+ return useConfigFileExistenceInfoForOptimizedLoading ( project ) ?
1121
+ project . projectService . configFileExistenceInfoCache . get ( project . canonicalConfigFilePath ) ! :
1122
+ undefined ;
1083
1123
}
1084
1124
1085
1125
function fileOpenReason ( info : ScriptInfo ) {
@@ -2603,11 +2643,26 @@ export class ProjectService {
2603
2643
2604
2644
/** @internal */
2605
2645
findDefaultConfiguredProject ( info : ScriptInfo ) {
2646
+ return this . findDefaultConfiguredProjectWorker (
2647
+ info ,
2648
+ ConfiguredProjectLoadKind . Find ,
2649
+ ) ?. defaultProject ;
2650
+ }
2651
+
2652
+ /** @internal */
2653
+ findDefaultConfiguredProjectWorker (
2654
+ info : ScriptInfo ,
2655
+ kind : ConfiguredProjectLoadKind . Find | ConfiguredProjectLoadKind . CreateReplay ,
2656
+ replayResult ?: DefaultConfiguredProjectInfo ,
2657
+ ) {
2606
2658
return info . isScriptOpen ( ) ?
2607
2659
this . tryFindDefaultConfiguredProjectForOpenScriptInfo (
2608
2660
info ,
2609
- ConfiguredProjectLoadKind . Find ,
2610
- ) ?. defaultProject :
2661
+ kind ,
2662
+ /*allowDeferredClosed*/ undefined ,
2663
+ /*reloadedProjects*/ undefined ,
2664
+ replayResult ,
2665
+ ) :
2611
2666
undefined ;
2612
2667
}
2613
2668
@@ -4360,7 +4415,12 @@ export class ProjectService {
4360
4415
switch ( kind ) {
4361
4416
case ConfiguredProjectLoadKind . FindOptimized :
4362
4417
case ConfiguredProjectLoadKind . Find :
4418
+ case ConfiguredProjectLoadKind . CreateReplay :
4419
+ if ( ! project ) return ;
4420
+ break ;
4421
+ case ConfiguredProjectLoadKind . CreateReplayOptimized :
4363
4422
if ( ! project ) return ;
4423
+ configFileExistenceInfo = configFileExistenceInfoForOptimizedReplay ( project ) ;
4364
4424
break ;
4365
4425
case ConfiguredProjectLoadKind . CreateOptimized :
4366
4426
case ConfiguredProjectLoadKind . Create :
@@ -4413,8 +4473,10 @@ export class ProjectService {
4413
4473
allowDeferredClosed ?: boolean ,
4414
4474
/** Used with ConfiguredProjectLoadKind.Reload to check if this project was already reloaded */
4415
4475
reloadedProjects ?: ConfiguredProjectToAnyReloadKind ,
4476
+ /** Used with ConfiguredProjectLoadKind.CreateReplay to store replay result */
4477
+ replayResult ?: DefaultConfiguredProjectInfo ,
4416
4478
) : DefaultConfiguredProjectResult | undefined {
4417
- const configFileName = this . getConfigFileNameForFile ( info , kind === ConfiguredProjectLoadKind . Find ) ;
4479
+ const configFileName = this . getConfigFileNameForFile ( info , kind <= ConfiguredProjectLoadKind . CreateReplay ) ;
4418
4480
// If no config file name, no result
4419
4481
if ( ! configFileName ) return ;
4420
4482
@@ -4437,6 +4499,7 @@ export class ProjectService {
4437
4499
project => `Creating project referenced in solution ${ project . projectName } to find possible configured project for ${ info . fileName } to open` ,
4438
4500
allowDeferredClosed ,
4439
4501
reloadedProjects ,
4502
+ replayResult ,
4440
4503
) ;
4441
4504
}
4442
4505
@@ -4491,6 +4554,8 @@ export class ProjectService {
4491
4554
allowDeferredClosed ?: boolean ,
4492
4555
/** Used with ConfiguredProjectLoadKind.Reload to check if this project was already reloaded */
4493
4556
reloadedProjects ?: ConfiguredProjectToAnyReloadKind ,
4557
+ /** Used with ConfiguredProjectLoadKind.CreateReplay to store replay result */
4558
+ replayResult ?: DefaultConfiguredProjectInfo ,
4494
4559
) {
4495
4560
const infoIsOpenScriptInfo = isOpenScriptInfo ( info ) ;
4496
4561
const optimizedKind = toConfiguredProjectLoadOptimized ( kind ) ;
@@ -4503,14 +4568,18 @@ export class ProjectService {
4503
4568
let tsconfigOfPossiblyDefault : ConfiguredProject | undefined ;
4504
4569
// See if this is the project or is it one of the references or find ancestor projects
4505
4570
tryFindDefaultConfiguredProject ( initialConfigResult ) ;
4571
+ const result = defaultProject ?? possiblyDefault ;
4572
+ if ( replayResult ) replayResult . defaultProject = result ;
4506
4573
return {
4507
- defaultProject : defaultProject ?? possiblyDefault ,
4574
+ defaultProject : result ,
4508
4575
tsconfigProject : tsconfigOfDefault ?? tsconfigOfPossiblyDefault ,
4509
4576
sentConfigDiag,
4510
4577
seenProjects,
4511
4578
} ;
4512
4579
4513
- function tryFindDefaultConfiguredProject ( result : FindCreateOrLoadConfiguredProjectResult ) : ConfiguredProject | undefined {
4580
+ function tryFindDefaultConfiguredProject (
4581
+ result : FindCreateOrLoadConfiguredProjectResult ,
4582
+ ) : ConfiguredProject | undefined {
4514
4583
return isDefaultProjectOptimized ( result , result . project ) ??
4515
4584
tryFindDefaultConfiguredProjectFromReferences ( result . project ) ??
4516
4585
tryFindDefaultConfiguredProjectFromAncestor ( result . project ) ;
@@ -4542,7 +4611,8 @@ export class ProjectService {
4542
4611
info ,
4543
4612
)
4544
4613
) {
4545
- if ( tsconfigProject . languageServiceEnabled ) {
4614
+ if ( replayResult ) ( replayResult . notMatchedByConfig ??= new Set ( ) ) . add ( childConfigName ) ;
4615
+ else if ( tsconfigProject . languageServiceEnabled ) {
4546
4616
// Ensure we are watching the parsedCommandLine
4547
4617
tsconfigProject . projectService . watchWildcards (
4548
4618
childConfigName ,
@@ -4569,7 +4639,12 @@ export class ProjectService {
4569
4639
allowDeferredClosed ,
4570
4640
info . fileName ,
4571
4641
reloadedProjects ,
4572
- ) ! ;
4642
+ ) ;
4643
+ if ( ! result ) {
4644
+ // Did no find existing project but thats ok, we will give information based on what we find
4645
+ Debug . assert ( replayResult ) ;
4646
+ return undefined ;
4647
+ }
4573
4648
seenProjects . set ( result . project , optimizedKind ) ;
4574
4649
if ( result . sentConfigFileDiag ) sentConfigDiag . add ( result . project ) ;
4575
4650
return isDefaultProject ( result . project , tsconfigProject ) ;
@@ -4589,6 +4664,10 @@ export class ProjectService {
4589
4664
tsconfigOfDefault = tsconfigProject ;
4590
4665
return defaultProject = project ;
4591
4666
}
4667
+ if ( replayResult ) {
4668
+ if ( ! projectWithInfo ) ( replayResult . notInProject ??= new Set ( ) ) . add ( project ) ;
4669
+ else ( replayResult . inProjectWithReference ??= new Set ( ) ) . add ( project ) ;
4670
+ }
4592
4671
// If this project uses the script info, if default project is not found, use this project as possible default
4593
4672
if ( ! possiblyDefault && infoIsOpenScriptInfo && projectWithInfo ) {
4594
4673
tsconfigOfPossiblyDefault = tsconfigProject ;
@@ -4658,7 +4737,7 @@ export class ProjectService {
4658
4737
) : DefaultConfiguredProjectResult | undefined ;
4659
4738
private tryFindDefaultConfiguredProjectAndLoadAncestorsForOpenScriptInfo (
4660
4739
info : ScriptInfo ,
4661
- kind : ConguredProjectLoadFindCreateOrReload ,
4740
+ kind : ConfiguredProjectLoadKind . Find | ConfiguredProjectLoadKind . Create | ConfiguredProjectLoadKind . Reload ,
4662
4741
reloadedProjects ?: ConfiguredProjectToAnyReloadKind ,
4663
4742
delayReloadedConfiguredProjects ?: Set < ConfiguredProject > ,
4664
4743
) : DefaultConfiguredProjectResult | undefined {
0 commit comments