@@ -326,6 +326,13 @@ namespace ts.server {
326
326
syntaxOnly ?: boolean ;
327
327
}
328
328
329
+ interface OriginalFileInfo { fileName : NormalizedPath ; path : Path ; }
330
+ type OpenScriptInfoOrClosedFileInfo = ScriptInfo | OriginalFileInfo ;
331
+
332
+ function isOpenScriptInfo ( infoOrFileName : OpenScriptInfoOrClosedFileInfo ) : infoOrFileName is ScriptInfo {
333
+ return ! ! ( infoOrFileName as ScriptInfo ) . containingProjects ;
334
+ }
335
+
329
336
function getDetailWatchInfo ( watchType : WatchType , project : Project | undefined ) {
330
337
return `Project: ${ project ? project . getProjectName ( ) : "" } WatchType: ${ watchType } ` ;
331
338
}
@@ -1044,12 +1051,12 @@ namespace ts.server {
1044
1051
}
1045
1052
}
1046
1053
1047
- private configFileExists ( configFileName : NormalizedPath , canonicalConfigFilePath : string , info : ScriptInfo ) {
1054
+ private configFileExists ( configFileName : NormalizedPath , canonicalConfigFilePath : string , info : OpenScriptInfoOrClosedFileInfo ) {
1048
1055
let configFileExistenceInfo = this . configFileExistenceInfoCache . get ( canonicalConfigFilePath ) ;
1049
1056
if ( configFileExistenceInfo ) {
1050
1057
// By default the info would get impacted by presence of config file since its in the detection path
1051
1058
// Only adding the info as a root to inferred project will need the existence to be watched by file watcher
1052
- if ( ! configFileExistenceInfo . openFilesImpactedByConfigFile . has ( info . path ) ) {
1059
+ if ( isOpenScriptInfo ( info ) && ! configFileExistenceInfo . openFilesImpactedByConfigFile . has ( info . path ) ) {
1053
1060
configFileExistenceInfo . openFilesImpactedByConfigFile . set ( info . path , false ) ;
1054
1061
this . logConfigFileWatchUpdate ( configFileName , canonicalConfigFilePath , configFileExistenceInfo , ConfigFileWatcherStatus . OpenFilesImpactedByConfigFileAdd ) ;
1055
1062
}
@@ -1066,9 +1073,11 @@ namespace ts.server {
1066
1073
// Or the whole chain of config files for the roots of the inferred projects
1067
1074
1068
1075
// Cache the host value of file exists and add the info to map of open files impacted by this config file
1069
- const openFilesImpactedByConfigFile = createMap < boolean > ( ) ;
1070
- openFilesImpactedByConfigFile . set ( info . path , false ) ;
1071
1076
const exists = this . host . fileExists ( configFileName ) ;
1077
+ const openFilesImpactedByConfigFile = createMap < boolean > ( ) ;
1078
+ if ( isOpenScriptInfo ( info ) ) {
1079
+ openFilesImpactedByConfigFile . set ( info . path , false ) ;
1080
+ }
1072
1081
configFileExistenceInfo = { exists, openFilesImpactedByConfigFile } ;
1073
1082
this . configFileExistenceInfoCache . set ( canonicalConfigFilePath , configFileExistenceInfo ) ;
1074
1083
this . logConfigFileWatchUpdate ( configFileName , canonicalConfigFilePath , configFileExistenceInfo , ConfigFileWatcherStatus . OpenFilesImpactedByConfigFileAdd ) ;
@@ -1180,7 +1189,7 @@ namespace ts.server {
1180
1189
*/
1181
1190
private stopWatchingConfigFilesForClosedScriptInfo ( info : ScriptInfo ) {
1182
1191
Debug . assert ( ! info . isScriptOpen ( ) ) ;
1183
- this . forEachConfigFileLocation ( info , /*infoShouldBeOpen*/ true , ( configFileName , canonicalConfigFilePath ) => {
1192
+ this . forEachConfigFileLocation ( info , ( configFileName , canonicalConfigFilePath ) => {
1184
1193
const configFileExistenceInfo = this . configFileExistenceInfoCache . get ( canonicalConfigFilePath ) ;
1185
1194
if ( configFileExistenceInfo ) {
1186
1195
const infoIsRootOfInferredProject = configFileExistenceInfo . openFilesImpactedByConfigFile . get ( info . path ) ;
@@ -1214,7 +1223,7 @@ namespace ts.server {
1214
1223
/* @internal */
1215
1224
startWatchingConfigFilesForInferredProjectRoot ( info : ScriptInfo ) {
1216
1225
Debug . assert ( info . isScriptOpen ( ) ) ;
1217
- this . forEachConfigFileLocation ( info , /*infoShouldBeOpen*/ true , ( configFileName , canonicalConfigFilePath ) => {
1226
+ this . forEachConfigFileLocation ( info , ( configFileName , canonicalConfigFilePath ) => {
1218
1227
let configFileExistenceInfo = this . configFileExistenceInfoCache . get ( canonicalConfigFilePath ) ;
1219
1228
if ( ! configFileExistenceInfo ) {
1220
1229
// Create the cache
@@ -1242,7 +1251,7 @@ namespace ts.server {
1242
1251
*/
1243
1252
/* @internal */
1244
1253
stopWatchingConfigFilesForInferredProjectRoot ( info : ScriptInfo ) {
1245
- this . forEachConfigFileLocation ( info , /*infoShouldBeOpen*/ true , ( configFileName , canonicalConfigFilePath ) => {
1254
+ this . forEachConfigFileLocation ( info , ( configFileName , canonicalConfigFilePath ) => {
1246
1255
const configFileExistenceInfo = this . configFileExistenceInfoCache . get ( canonicalConfigFilePath ) ;
1247
1256
if ( configFileExistenceInfo && configFileExistenceInfo . openFilesImpactedByConfigFile . has ( info . path ) ) {
1248
1257
Debug . assert ( info . isScriptOpen ( ) ) ;
@@ -1265,12 +1274,12 @@ namespace ts.server {
1265
1274
* The server must start searching from the directory containing
1266
1275
* the newly opened file.
1267
1276
*/
1268
- private forEachConfigFileLocation ( info : ScriptInfo , infoShouldBeOpen : boolean , action : ( configFileName : NormalizedPath , canonicalConfigFilePath : string ) => boolean | void ) {
1277
+ private forEachConfigFileLocation ( info : OpenScriptInfoOrClosedFileInfo , action : ( configFileName : NormalizedPath , canonicalConfigFilePath : string ) => boolean | void ) {
1269
1278
if ( this . syntaxOnly ) {
1270
1279
return undefined ;
1271
1280
}
1272
1281
1273
- Debug . assert ( ! infoShouldBeOpen || this . openFiles . has ( info . path ) ) ;
1282
+ Debug . assert ( ! isOpenScriptInfo ( info ) || this . openFiles . has ( info . path ) ) ;
1274
1283
const projectRootPath = this . openFiles . get ( info . path ) ;
1275
1284
1276
1285
let searchPath = asNormalizedPath ( getDirectoryPath ( info . fileName ) ) ;
@@ -1309,11 +1318,13 @@ namespace ts.server {
1309
1318
* current directory (the directory in which tsc was invoked).
1310
1319
* The server must start searching from the directory containing
1311
1320
* the newly opened file.
1321
+ * If script info is passed in, it is asserted to be open script info
1322
+ * otherwise just file name
1312
1323
*/
1313
- private getConfigFileNameForFile ( info : ScriptInfo , infoShouldBeOpen : boolean ) {
1314
- if ( infoShouldBeOpen ) Debug . assert ( info . isScriptOpen ( ) ) ;
1324
+ private getConfigFileNameForFile ( info : OpenScriptInfoOrClosedFileInfo ) {
1325
+ if ( isOpenScriptInfo ( info ) ) Debug . assert ( info . isScriptOpen ( ) ) ;
1315
1326
this . logger . info ( `Search path: ${ getDirectoryPath ( info . fileName ) } ` ) ;
1316
- const configFileName = this . forEachConfigFileLocation ( info , infoShouldBeOpen , ( configFileName , canonicalConfigFilePath ) =>
1327
+ const configFileName = this . forEachConfigFileLocation ( info , ( configFileName , canonicalConfigFilePath ) =>
1317
1328
this . configFileExists ( configFileName , canonicalConfigFilePath , info ) ) ;
1318
1329
if ( configFileName ) {
1319
1330
this . logger . info ( `For info: ${ info . fileName } :: Config file name: ${ configFileName } ` ) ;
@@ -2005,7 +2016,7 @@ namespace ts.server {
2005
2016
// we first detect if there is already a configured project created for it: if so,
2006
2017
// we re- read the tsconfig file content and update the project only if we havent already done so
2007
2018
// otherwise we create a new one.
2008
- const configFileName = this . getConfigFileNameForFile ( info , /*infoShouldBeOpen*/ true ) ;
2019
+ const configFileName = this . getConfigFileNameForFile ( info ) ;
2009
2020
if ( configFileName ) {
2010
2021
const project = this . findConfiguredProjectByProjectName ( configFileName ) ;
2011
2022
if ( ! project ) {
@@ -2093,17 +2104,25 @@ namespace ts.server {
2093
2104
return this . openClientFileWithNormalizedPath ( toNormalizedPath ( fileName ) , fileContent , scriptKind , /*hasMixedContent*/ false , projectRootPath ? toNormalizedPath ( projectRootPath ) : undefined ) ;
2094
2105
}
2095
2106
2096
- /** @internal */
2097
- getProjectForFileWithoutOpening ( fileName : NormalizedPath ) : { readonly scriptInfo : ScriptInfo , readonly projects : ReadonlyArray < Project > } | undefined {
2098
- const scriptInfo = this . filenameToScriptInfo . get ( fileName ) ||
2099
- this . getOrCreateScriptInfoNotOpenedByClientForNormalizedPath ( fileName , this . currentDirectory , /*fileContent*/ undefined , /*scriptKind*/ undefined , /*hasMixedContent*/ undefined ) ;
2100
- if ( ! scriptInfo ) return undefined ;
2101
- if ( scriptInfo . containingProjects . length ) {
2102
- return { scriptInfo, projects : scriptInfo . containingProjects } ;
2107
+ /*@internal */
2108
+ getOriginalLocationEnsuringConfiguredProject ( project : Project , location : sourcemaps . SourceMappableLocation ) : sourcemaps . SourceMappableLocation | undefined {
2109
+ const originalLocation = project . getSourceMapper ( ) . tryGetOriginalLocation ( location ) ;
2110
+ if ( ! originalLocation ) return undefined ;
2111
+
2112
+ const { fileName } = originalLocation ;
2113
+ const originalScriptInfo = this . getScriptInfo ( fileName ) ;
2114
+ if ( originalScriptInfo && originalScriptInfo . containingProjects . length ) {
2115
+ return originalLocation ;
2103
2116
}
2104
- const configFileName = this . getConfigFileNameForFile ( scriptInfo , /*infoShouldBeOpen*/ false ) ;
2105
- const project = configFileName === undefined ? undefined : this . findConfiguredProjectByProjectName ( configFileName ) || this . createConfiguredProject ( configFileName ) ;
2106
- return project && project . containsScriptInfo ( scriptInfo ) ? { scriptInfo, projects : [ project ] } : undefined ;
2117
+
2118
+ const info : OriginalFileInfo = { fileName : toNormalizedPath ( fileName ) , path : this . toPath ( fileName ) } ;
2119
+ const configFileName = this . getConfigFileNameForFile ( info ) ;
2120
+ if ( ! configFileName ) return undefined ;
2121
+
2122
+ const configuredProject = this . findConfiguredProjectByProjectName ( configFileName ) || this . createConfiguredProject ( configFileName ) ;
2123
+ updateProjectIfDirty ( configuredProject ) ;
2124
+
2125
+ return configuredProject . containsFile ( info . fileName ) ? originalLocation : undefined ;
2107
2126
}
2108
2127
2109
2128
/** @internal */
@@ -2128,7 +2147,7 @@ namespace ts.server {
2128
2147
this . openFiles . set ( info . path , projectRootPath ) ;
2129
2148
let project : ConfiguredProject | ExternalProject | undefined = this . findExternalProjectContainingOpenScriptInfo ( info ) ;
2130
2149
if ( ! project && ! this . syntaxOnly ) { // Checking syntaxOnly is an optimization
2131
- configFileName = this . getConfigFileNameForFile ( info , /*infoShouldBeOpen*/ true ) ;
2150
+ configFileName = this . getConfigFileNameForFile ( info ) ;
2132
2151
if ( configFileName ) {
2133
2152
project = this . findConfiguredProjectByProjectName ( configFileName ) ;
2134
2153
if ( ! project ) {
0 commit comments