@@ -5,6 +5,8 @@ namespace ts.server {
5
5
6
6
// tslint:disable variable-name
7
7
export const ProjectsUpdatedInBackgroundEvent = "projectsUpdatedInBackground" ;
8
+ export const ProjectLoadingStartEvent = "projectLoadingStart" ;
9
+ export const ProjectLoadingFinishEvent = "projectLoadingFinish" ;
8
10
export const SurveyReady = "surveyReady" ;
9
11
export const LargeFileReferencedEvent = "largeFileReferenced" ;
10
12
export const ConfigFileDiagEvent = "configFileDiag" ;
@@ -18,6 +20,16 @@ namespace ts.server {
18
20
data : { openFiles : string [ ] ; } ;
19
21
}
20
22
23
+ export interface ProjectLoadingStartEvent {
24
+ eventName : typeof ProjectLoadingStartEvent ;
25
+ data : { project : Project ; reason : string ; } ;
26
+ }
27
+
28
+ export interface ProjectLoadingFinishEvent {
29
+ eventName : typeof ProjectLoadingFinishEvent ;
30
+ data : { project : Project ; } ;
31
+ }
32
+
21
33
export interface SurveyReady {
22
34
eventName : typeof SurveyReady ;
23
35
data : { surveyId : string ; } ;
@@ -122,7 +134,15 @@ namespace ts.server {
122
134
readonly checkJs : boolean ;
123
135
}
124
136
125
- export type ProjectServiceEvent = LargeFileReferencedEvent | SurveyReady | ProjectsUpdatedInBackgroundEvent | ConfigFileDiagEvent | ProjectLanguageServiceStateEvent | ProjectInfoTelemetryEvent | OpenFileInfoTelemetryEvent ;
137
+ export type ProjectServiceEvent = LargeFileReferencedEvent |
138
+ SurveyReady |
139
+ ProjectsUpdatedInBackgroundEvent |
140
+ ProjectLoadingStartEvent |
141
+ ProjectLoadingFinishEvent |
142
+ ConfigFileDiagEvent |
143
+ ProjectLanguageServiceStateEvent |
144
+ ProjectInfoTelemetryEvent |
145
+ OpenFileInfoTelemetryEvent ;
126
146
127
147
export type ProjectServiceEventHandler = ( event : ProjectServiceEvent ) => void ;
128
148
@@ -721,6 +741,33 @@ namespace ts.server {
721
741
this . eventHandler ( event ) ;
722
742
}
723
743
744
+ /* @internal */
745
+ sendProjectLoadingStartEvent ( project : ConfiguredProject , reason : string ) {
746
+ if ( ! this . eventHandler ) {
747
+ return ;
748
+ }
749
+ project . sendLoadingProjectFinish = true ;
750
+ const event : ProjectLoadingStartEvent = {
751
+ eventName : ProjectLoadingStartEvent ,
752
+ data : { project, reason }
753
+ } ;
754
+ this . eventHandler ( event ) ;
755
+ }
756
+
757
+ /* @internal */
758
+ sendProjectLoadingFinishEvent ( project : ConfiguredProject ) {
759
+ if ( ! this . eventHandler || ! project . sendLoadingProjectFinish ) {
760
+ return ;
761
+ }
762
+
763
+ project . sendLoadingProjectFinish = false ;
764
+ const event : ProjectLoadingFinishEvent = {
765
+ eventName : ProjectLoadingFinishEvent ,
766
+ data : { project }
767
+ } ;
768
+ this . eventHandler ( event ) ;
769
+ }
770
+
724
771
/* @internal */
725
772
delayUpdateProjectGraphAndEnsureProjectStructureForOpenFiles ( project : Project ) {
726
773
this . delayUpdateProjectGraph ( project ) ;
@@ -955,6 +1002,7 @@ namespace ts.server {
955
1002
else {
956
1003
this . logConfigFileWatchUpdate ( project . getConfigFilePath ( ) , project . canonicalConfigFilePath , configFileExistenceInfo , ConfigFileWatcherStatus . ReloadingInferredRootFiles ) ;
957
1004
project . pendingReload = ConfigFileProgramReloadLevel . Full ;
1005
+ project . pendingReloadReason = "Change in config file detected" ;
958
1006
this . delayUpdateProjectGraph ( project ) ;
959
1007
// As we scheduled the update on configured project graph,
960
1008
// we would need to schedule the project reload for only the root of inferred projects
@@ -1613,22 +1661,23 @@ namespace ts.server {
1613
1661
}
1614
1662
1615
1663
/* @internal */
1616
- private createConfiguredProjectWithDelayLoad ( configFileName : NormalizedPath ) {
1664
+ private createConfiguredProjectWithDelayLoad ( configFileName : NormalizedPath , reason : string ) {
1617
1665
const project = this . createConfiguredProject ( configFileName ) ;
1618
1666
project . pendingReload = ConfigFileProgramReloadLevel . Full ;
1667
+ project . pendingReloadReason = reason ;
1619
1668
return project ;
1620
1669
}
1621
1670
1622
1671
/* @internal */
1623
- private createAndLoadConfiguredProject ( configFileName : NormalizedPath ) {
1672
+ private createAndLoadConfiguredProject ( configFileName : NormalizedPath , reason : string ) {
1624
1673
const project = this . createConfiguredProject ( configFileName ) ;
1625
- this . loadConfiguredProject ( project ) ;
1674
+ this . loadConfiguredProject ( project , reason ) ;
1626
1675
return project ;
1627
1676
}
1628
1677
1629
1678
/* @internal */
1630
- private createLoadAndUpdateConfiguredProject ( configFileName : NormalizedPath ) {
1631
- const project = this . createAndLoadConfiguredProject ( configFileName ) ;
1679
+ private createLoadAndUpdateConfiguredProject ( configFileName : NormalizedPath , reason : string ) {
1680
+ const project = this . createAndLoadConfiguredProject ( configFileName , reason ) ;
1632
1681
project . updateGraph ( ) ;
1633
1682
return project ;
1634
1683
}
@@ -1637,7 +1686,9 @@ namespace ts.server {
1637
1686
* Read the config file of the project, and update the project root file names.
1638
1687
*/
1639
1688
/* @internal */
1640
- private loadConfiguredProject ( project : ConfiguredProject ) {
1689
+ private loadConfiguredProject ( project : ConfiguredProject , reason : string ) {
1690
+ this . sendProjectLoadingStartEvent ( project , reason ) ;
1691
+
1641
1692
// Read updated contents from disk
1642
1693
const configFilename = normalizePath ( project . getConfigFilePath ( ) ) ;
1643
1694
@@ -1776,7 +1827,7 @@ namespace ts.server {
1776
1827
* Read the config file of the project again by clearing the cache and update the project graph
1777
1828
*/
1778
1829
/* @internal */
1779
- reloadConfiguredProject ( project : ConfiguredProject ) {
1830
+ reloadConfiguredProject ( project : ConfiguredProject , reason : string ) {
1780
1831
// At this point, there is no reason to not have configFile in the host
1781
1832
const host = project . getCachedDirectoryStructureHost ( ) ;
1782
1833
@@ -1786,7 +1837,7 @@ namespace ts.server {
1786
1837
this . logger . info ( `Reloading configured project ${ configFileName } ` ) ;
1787
1838
1788
1839
// Load project from the disk
1789
- this . loadConfiguredProject ( project ) ;
1840
+ this . loadConfiguredProject ( project , reason ) ;
1790
1841
project . updateGraph ( ) ;
1791
1842
1792
1843
this . sendConfigFileDiagEvent ( project , configFileName ) ;
@@ -2139,7 +2190,6 @@ namespace ts.server {
2139
2190
if ( project . hasExternalProjectRef ( ) &&
2140
2191
project . pendingReload === ConfigFileProgramReloadLevel . Full &&
2141
2192
! this . pendingProjectUpdates . has ( project . getProjectName ( ) ) ) {
2142
- this . loadConfiguredProject ( project ) ;
2143
2193
project . updateGraph ( ) ;
2144
2194
}
2145
2195
} ) ;
@@ -2171,7 +2221,7 @@ namespace ts.server {
2171
2221
// as there is no need to load contents of the files from the disk
2172
2222
2173
2223
// Reload Projects
2174
- this . reloadConfiguredProjectForFiles ( this . openFiles , /*delayReload*/ false , returnTrue ) ;
2224
+ this . reloadConfiguredProjectForFiles ( this . openFiles , /*delayReload*/ false , returnTrue , "User requested reload projects" ) ;
2175
2225
this . ensureProjectForOpenFiles ( ) ;
2176
2226
}
2177
2227
@@ -2182,7 +2232,8 @@ namespace ts.server {
2182
2232
/*delayReload*/ true ,
2183
2233
ignoreIfNotRootOfInferredProject ?
2184
2234
isRootOfInferredProject => isRootOfInferredProject : // Reload open files if they are root of inferred project
2185
- returnTrue // Reload all the open files impacted by config file
2235
+ returnTrue , // Reload all the open files impacted by config file
2236
+ "Change in config file detected"
2186
2237
) ;
2187
2238
this . delayEnsureProjectForOpenFiles ( ) ;
2188
2239
}
@@ -2194,7 +2245,7 @@ namespace ts.server {
2194
2245
* If the there is no existing project it just opens the configured project for the config file
2195
2246
* reloadForInfo provides a way to filter out files to reload configured project for
2196
2247
*/
2197
- private reloadConfiguredProjectForFiles < T > ( openFiles : Map < T > , delayReload : boolean , shouldReloadProjectFor : ( openFileValue : T ) => boolean ) {
2248
+ private reloadConfiguredProjectForFiles < T > ( openFiles : Map < T > , delayReload : boolean , shouldReloadProjectFor : ( openFileValue : T ) => boolean , reason : string ) {
2198
2249
const updatedProjects = createMap < true > ( ) ;
2199
2250
// try to reload config file for all open files
2200
2251
openFiles . forEach ( ( openFileValue , path ) => {
@@ -2215,11 +2266,12 @@ namespace ts.server {
2215
2266
if ( ! updatedProjects . has ( configFileName ) ) {
2216
2267
if ( delayReload ) {
2217
2268
project . pendingReload = ConfigFileProgramReloadLevel . Full ;
2269
+ project . pendingReloadReason = reason ;
2218
2270
this . delayUpdateProjectGraph ( project ) ;
2219
2271
}
2220
2272
else {
2221
2273
// reload from the disk
2222
- this . reloadConfiguredProject ( project ) ;
2274
+ this . reloadConfiguredProject ( project , reason ) ;
2223
2275
}
2224
2276
updatedProjects . set ( configFileName , true ) ;
2225
2277
}
@@ -2306,7 +2358,8 @@ namespace ts.server {
2306
2358
const configFileName = this . getConfigFileNameForFile ( originalFileInfo ) ;
2307
2359
if ( ! configFileName ) return undefined ;
2308
2360
2309
- const configuredProject = this . findConfiguredProjectByProjectName ( configFileName ) || this . createAndLoadConfiguredProject ( configFileName ) ;
2361
+ const configuredProject = this . findConfiguredProjectByProjectName ( configFileName ) ||
2362
+ this . createAndLoadConfiguredProject ( configFileName , `Creating project for original file: ${ originalFileInfo . fileName } for location: ${ location . fileName } ` ) ;
2310
2363
updateProjectIfDirty ( configuredProject ) ;
2311
2364
// Keep this configured project as referenced from project
2312
2365
addOriginalConfiguredProject ( configuredProject ) ;
@@ -2356,7 +2409,7 @@ namespace ts.server {
2356
2409
if ( configFileName ) {
2357
2410
project = this . findConfiguredProjectByProjectName ( configFileName ) ;
2358
2411
if ( ! project ) {
2359
- project = this . createLoadAndUpdateConfiguredProject ( configFileName ) ;
2412
+ project = this . createLoadAndUpdateConfiguredProject ( configFileName , `Creating possible configured project for ${ fileName } to open` ) ;
2360
2413
// Send the event only if the project got created as part of this open request and info is part of the project
2361
2414
if ( info . isOrphan ( ) ) {
2362
2415
// Since the file isnt part of configured project, do not send config file info
@@ -2797,8 +2850,8 @@ namespace ts.server {
2797
2850
if ( ! project ) {
2798
2851
// errors are stored in the project, do not need to update the graph
2799
2852
project = this . getHostPreferences ( ) . lazyConfiguredProjectsFromExternalProject ?
2800
- this . createConfiguredProjectWithDelayLoad ( tsconfigFile ) :
2801
- this . createLoadAndUpdateConfiguredProject ( tsconfigFile ) ;
2853
+ this . createConfiguredProjectWithDelayLoad ( tsconfigFile , `Creating configured project in external project: ${ proj . projectFileName } ` ) :
2854
+ this . createLoadAndUpdateConfiguredProject ( tsconfigFile , `Creating configured project in external project: ${ proj . projectFileName } ` ) ;
2802
2855
}
2803
2856
if ( project && ! contains ( exisingConfigFiles , tsconfigFile ) ) {
2804
2857
// keep project alive even if no documents are opened - its lifetime is bound to the lifetime of containing external project
0 commit comments