@@ -713,6 +713,8 @@ function isAncestorConfigFileInfo(infoOrFileNameOrConfig: OpenScriptInfoOrClosed
713713export enum ConfiguredProjectLoadKind {
714714 FindOptimized ,
715715 Find ,
716+ CreateReplayOptimized ,
717+ CreateReplay ,
716718 CreateOptimized ,
717719 Create ,
718720 ReloadOptimized ,
@@ -721,11 +723,13 @@ export enum ConfiguredProjectLoadKind {
721723
722724type ConguredProjectLoadFindCreateOrReload =
723725 | ConfiguredProjectLoadKind . Find
726+ | ConfiguredProjectLoadKind . CreateReplay
724727 | ConfiguredProjectLoadKind . Create
725728 | ConfiguredProjectLoadKind . Reload ;
726729
727730type ConguredProjectLoadFindCreateOrReloadOptimized =
728731 | ConfiguredProjectLoadKind . FindOptimized
732+ | ConfiguredProjectLoadKind . CreateReplayOptimized
729733 | ConfiguredProjectLoadKind . CreateOptimized
730734 | ConfiguredProjectLoadKind . ReloadOptimized ;
731735
@@ -753,6 +757,18 @@ export interface FindCreateOrLoadConfiguredProjectResult {
753757 reason : string | undefined ;
754758}
755759
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+
756772/**
757773 * Goes through each tsconfig from project till project root of open script info and finds, creates or reloads project per kind
758774 */
@@ -794,8 +810,7 @@ function forEachAncestorProjectLoad<T>(
794810 configFileInfo : true ,
795811 isForDefaultProject : ! searchOnlyPotentialSolution ,
796812 } ,
797- kind === ConfiguredProjectLoadKind . Find ||
798- kind === ConfiguredProjectLoadKind . FindOptimized ,
813+ kind <= ConfiguredProjectLoadKind . CreateReplay ,
799814 ) ;
800815 if ( ! configFileName ) return ;
801816
@@ -865,21 +880,28 @@ function forEachResolvedProjectReferenceProjectLoad<T>(
865880 configFileExistenceInfo ?. exists || project . resolvedChildConfigs ?. has ( childCanonicalConfigPath ) ?
866881 configFileExistenceInfo ! . config ! . parsedCommandLine : undefined :
867882 project . getParsedCommandLine ( childConfigName ) ;
868- if ( childConfig && loadKind !== kind ) {
883+ if ( childConfig && loadKind !== kind && loadKind > ConfiguredProjectLoadKind . CreateReplayOptimized ) {
869884 // If this was found using find: ensure this is uptodate if looking for creating or reloading
870885 childConfig = project . getParsedCommandLine ( childConfigName ) ;
871886 }
872887 if ( ! childConfig ) return undefined ;
873888
874889 // Find the project
875890 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 ;
876897 switch ( loadKind ) {
877898 case ConfiguredProjectLoadKind . ReloadOptimized :
878899 if ( childProject ) childProject . projectService . reloadConfiguredProjectOptimized ( childProject , reason , reloadedProjects ! ) ;
879900 // falls through
880901 case ConfiguredProjectLoadKind . CreateOptimized :
881902 ( project . resolvedChildConfigs ??= new Set ( ) ) . add ( childCanonicalConfigPath ) ;
882- // falls through
903+ // falls through
904+ case ConfiguredProjectLoadKind . CreateReplayOptimized :
883905 case ConfiguredProjectLoadKind . FindOptimized :
884906 if ( childProject || loadKind !== ConfiguredProjectLoadKind . FindOptimized ) {
885907 const result = cb (
@@ -930,6 +952,12 @@ function updateProjectFoundUsingFind(
930952 // This project was found using "Find" instead of the actually specified kind of "Create" or "Reload",
931953 // We need to update or reload this existing project before calling callback
932954 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 ;
933961 case ConfiguredProjectLoadKind . CreateOptimized :
934962 configFileExistenceInfo = configFileExistenceInfoForOptimizedLoading ( project ) ;
935963 if ( configFileExistenceInfo ) break ;
@@ -1077,9 +1105,21 @@ function configFileExistenceInfoForOptimizedLoading(project: ConfiguredProject)
10771105 project . resolvedChildConfigs = undefined ;
10781106 project . updateReferences ( parsedCommandLine . projectReferences ) ;
10791107 // Composite can determine based on files themselves, no need to load project
1080- if ( parsedCommandLine . options . composite ) return configFileExistenceInfo ;
10811108 // 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 ;
10831123}
10841124
10851125function fileOpenReason ( info : ScriptInfo ) {
@@ -2603,11 +2643,26 @@ export class ProjectService {
26032643
26042644 /** @internal */
26052645 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+ ) {
26062658 return info . isScriptOpen ( ) ?
26072659 this . tryFindDefaultConfiguredProjectForOpenScriptInfo (
26082660 info ,
2609- ConfiguredProjectLoadKind . Find ,
2610- ) ?. defaultProject :
2661+ kind ,
2662+ /*allowDeferredClosed*/ undefined ,
2663+ /*reloadedProjects*/ undefined ,
2664+ replayResult ,
2665+ ) :
26112666 undefined ;
26122667 }
26132668
@@ -4360,7 +4415,12 @@ export class ProjectService {
43604415 switch ( kind ) {
43614416 case ConfiguredProjectLoadKind . FindOptimized :
43624417 case ConfiguredProjectLoadKind . Find :
4418+ case ConfiguredProjectLoadKind . CreateReplay :
4419+ if ( ! project ) return ;
4420+ break ;
4421+ case ConfiguredProjectLoadKind . CreateReplayOptimized :
43634422 if ( ! project ) return ;
4423+ configFileExistenceInfo = configFileExistenceInfoForOptimizedReplay ( project ) ;
43644424 break ;
43654425 case ConfiguredProjectLoadKind . CreateOptimized :
43664426 case ConfiguredProjectLoadKind . Create :
@@ -4413,8 +4473,10 @@ export class ProjectService {
44134473 allowDeferredClosed ?: boolean ,
44144474 /** Used with ConfiguredProjectLoadKind.Reload to check if this project was already reloaded */
44154475 reloadedProjects ?: ConfiguredProjectToAnyReloadKind ,
4476+ /** Used with ConfiguredProjectLoadKind.CreateReplay to store replay result */
4477+ replayResult ?: DefaultConfiguredProjectInfo ,
44164478 ) : DefaultConfiguredProjectResult | undefined {
4417- const configFileName = this . getConfigFileNameForFile ( info , kind === ConfiguredProjectLoadKind . Find ) ;
4479+ const configFileName = this . getConfigFileNameForFile ( info , kind <= ConfiguredProjectLoadKind . CreateReplay ) ;
44184480 // If no config file name, no result
44194481 if ( ! configFileName ) return ;
44204482
@@ -4437,6 +4499,7 @@ export class ProjectService {
44374499 project => `Creating project referenced in solution ${ project . projectName } to find possible configured project for ${ info . fileName } to open` ,
44384500 allowDeferredClosed ,
44394501 reloadedProjects ,
4502+ replayResult ,
44404503 ) ;
44414504 }
44424505
@@ -4491,6 +4554,8 @@ export class ProjectService {
44914554 allowDeferredClosed ?: boolean ,
44924555 /** Used with ConfiguredProjectLoadKind.Reload to check if this project was already reloaded */
44934556 reloadedProjects ?: ConfiguredProjectToAnyReloadKind ,
4557+ /** Used with ConfiguredProjectLoadKind.CreateReplay to store replay result */
4558+ replayResult ?: DefaultConfiguredProjectInfo ,
44944559 ) {
44954560 const infoIsOpenScriptInfo = isOpenScriptInfo ( info ) ;
44964561 const optimizedKind = toConfiguredProjectLoadOptimized ( kind ) ;
@@ -4503,14 +4568,18 @@ export class ProjectService {
45034568 let tsconfigOfPossiblyDefault : ConfiguredProject | undefined ;
45044569 // See if this is the project or is it one of the references or find ancestor projects
45054570 tryFindDefaultConfiguredProject ( initialConfigResult ) ;
4571+ const result = defaultProject ?? possiblyDefault ;
4572+ if ( replayResult ) replayResult . defaultProject = result ;
45064573 return {
4507- defaultProject : defaultProject ?? possiblyDefault ,
4574+ defaultProject : result ,
45084575 tsconfigProject : tsconfigOfDefault ?? tsconfigOfPossiblyDefault ,
45094576 sentConfigDiag,
45104577 seenProjects,
45114578 } ;
45124579
4513- function tryFindDefaultConfiguredProject ( result : FindCreateOrLoadConfiguredProjectResult ) : ConfiguredProject | undefined {
4580+ function tryFindDefaultConfiguredProject (
4581+ result : FindCreateOrLoadConfiguredProjectResult ,
4582+ ) : ConfiguredProject | undefined {
45144583 return isDefaultProjectOptimized ( result , result . project ) ??
45154584 tryFindDefaultConfiguredProjectFromReferences ( result . project ) ??
45164585 tryFindDefaultConfiguredProjectFromAncestor ( result . project ) ;
@@ -4542,7 +4611,8 @@ export class ProjectService {
45424611 info ,
45434612 )
45444613 ) {
4545- if ( tsconfigProject . languageServiceEnabled ) {
4614+ if ( replayResult ) ( replayResult . notMatchedByConfig ??= new Set ( ) ) . add ( childConfigName ) ;
4615+ else if ( tsconfigProject . languageServiceEnabled ) {
45464616 // Ensure we are watching the parsedCommandLine
45474617 tsconfigProject . projectService . watchWildcards (
45484618 childConfigName ,
@@ -4569,7 +4639,12 @@ export class ProjectService {
45694639 allowDeferredClosed ,
45704640 info . fileName ,
45714641 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+ }
45734648 seenProjects . set ( result . project , optimizedKind ) ;
45744649 if ( result . sentConfigFileDiag ) sentConfigDiag . add ( result . project ) ;
45754650 return isDefaultProject ( result . project , tsconfigProject ) ;
@@ -4589,6 +4664,10 @@ export class ProjectService {
45894664 tsconfigOfDefault = tsconfigProject ;
45904665 return defaultProject = project ;
45914666 }
4667+ if ( replayResult ) {
4668+ if ( ! projectWithInfo ) ( replayResult . notInProject ??= new Set ( ) ) . add ( project ) ;
4669+ else ( replayResult . inProjectWithReference ??= new Set ( ) ) . add ( project ) ;
4670+ }
45924671 // If this project uses the script info, if default project is not found, use this project as possible default
45934672 if ( ! possiblyDefault && infoIsOpenScriptInfo && projectWithInfo ) {
45944673 tsconfigOfPossiblyDefault = tsconfigProject ;
@@ -4658,7 +4737,7 @@ export class ProjectService {
46584737 ) : DefaultConfiguredProjectResult | undefined ;
46594738 private tryFindDefaultConfiguredProjectAndLoadAncestorsForOpenScriptInfo (
46604739 info : ScriptInfo ,
4661- kind : ConguredProjectLoadFindCreateOrReload ,
4740+ kind : ConfiguredProjectLoadKind . Find | ConfiguredProjectLoadKind . Create | ConfiguredProjectLoadKind . Reload ,
46624741 reloadedProjects ?: ConfiguredProjectToAnyReloadKind ,
46634742 delayReloadedConfiguredProjects ?: Set < ConfiguredProject > ,
46644743 ) : DefaultConfiguredProjectResult | undefined {
0 commit comments