@@ -247,6 +247,7 @@ class DocumentData extends LSIFData<EmitterContext> {
247
247
public readonly external : boolean ;
248
248
public readonly next : DocumentData | undefined ;
249
249
private _isClosed : boolean ;
250
+ private readonly recorded : Set < string > ;
250
251
private ranges : Range [ ] ;
251
252
private rangesEmitted : boolean ;
252
253
private diagnostics : lsp . Diagnostic [ ] ;
@@ -262,6 +263,7 @@ class DocumentData extends LSIFData<EmitterContext> {
262
263
this . external = external ;
263
264
this . next = next ;
264
265
this . _isClosed = false ;
266
+ this . recorded = new Set ( ) ;
265
267
this . ranges = [ ] ;
266
268
this . rangesEmitted = false ;
267
269
this . diagnostics = DocumentData . EMPTY_ARRAY ;
@@ -293,10 +295,25 @@ class DocumentData extends LSIFData<EmitterContext> {
293
295
this . emit ( this . vertex . event ( EventScope . document , EventKind . begin , this . document ) ) ;
294
296
}
295
297
296
- public addRange ( range : Range ) : void {
298
+ public addRange ( range : Range ) : boolean {
299
+ const key = Range . key ( range ) ;
300
+ // export type Uri = string;
301
+ // export namespace Uri { ... }
302
+ //
303
+ // In the example above the symbol for type Uri has one declaration node
304
+ // and the symbol for namespace Uri two, where the first one is the same
305
+ // as for type Uri. To avoid recording ranges twice we ignore double
306
+ // ranges and treat the first recorded one as the primary. This is what
307
+ // the TS server does as well.
308
+ if ( this . recorded . has ( key ) ) {
309
+ return false ;
310
+ } else {
311
+ this . recorded . add ( key ) ;
312
+ }
297
313
this . checkClosed ( ) ;
298
314
this . emit ( range ) ;
299
315
this . ranges . push ( range ) ;
316
+ return true ;
300
317
}
301
318
302
319
public addDiagnostics ( diagnostics : lsp . Diagnostic [ ] ) : void {
@@ -1262,7 +1279,7 @@ abstract class SymbolWalker {
1262
1279
if ( symbolData !== undefined ) {
1263
1280
symbolData . changeVisibility ( SymbolDataVisibility . indirectExported ) ;
1264
1281
} else {
1265
- this . symbols . storeSymbolInitializationData ( symbol , SymbolDataVisibility . indirectExported ) ;
1282
+ Symbols . storeSymbolInitializationData ( this . symbols . getSymbolId ( symbol ) , SymbolDataVisibility . indirectExported ) ;
1266
1283
}
1267
1284
}
1268
1285
@@ -1556,12 +1573,34 @@ class Symbols {
1556
1573
return symbol . declarations !== undefined && symbol . declarations . length > 0 ? symbol . declarations [ 0 ] : undefined ;
1557
1574
}
1558
1575
1576
+ private static readonly symbolInitializationData : Map < SymbolId , SymbolDataVisibility > = new Map ( ) ;
1577
+
1578
+ public static storeSymbolInitializationData ( symbolId : SymbolId , visibility : SymbolDataVisibility ) : void {
1579
+ this . symbolInitializationData . set ( symbolId , visibility ) ;
1580
+ }
1581
+
1582
+ private static getVisibility ( symbolId : SymbolId , symbol : ts . Symbol , exportPath : string | undefined | null ) : SymbolDataVisibility {
1583
+ const initVisibility = this . symbolInitializationData . get ( symbolId ) ;
1584
+ if ( initVisibility !== undefined ) {
1585
+ this . symbolInitializationData . delete ( symbolId ) ;
1586
+ }
1587
+
1588
+ // The symbol is exported.
1589
+ if ( exportPath === null || exportPath !== undefined ) {
1590
+ return SymbolDataVisibility . exported ;
1591
+ }
1592
+ if ( Symbols . isTransient ( symbol ) ) {
1593
+ return SymbolDataVisibility . transient ;
1594
+ }
1595
+
1596
+ return initVisibility ?? SymbolDataVisibility . unknown ;
1597
+ }
1598
+
1559
1599
public readonly types : Types ;
1560
1600
1561
1601
private readonly baseSymbolCache : LRUCache < string , ts . Symbol [ ] > ;
1562
1602
private readonly baseMemberCache : LRUCache < string , LRUCache < string , ts . Symbol [ ] > > ;
1563
1603
private readonly symbolCache : LRUCache < ts . Symbol , CachedSymbolInformation > ;
1564
- private readonly symbolInitializationData : Map < string , SymbolDataVisibility > ;
1565
1604
1566
1605
private readonly sourceFilesContainingAmbientDeclarations : Set < string > ;
1567
1606
@@ -1570,7 +1609,6 @@ class Symbols {
1570
1609
this . baseSymbolCache = new LRUCache ( 2048 ) ;
1571
1610
this . baseMemberCache = new LRUCache ( 2048 ) ;
1572
1611
this . symbolCache = new LRUCache ( 4096 ) ;
1573
- this . symbolInitializationData = new Map ( ) ;
1574
1612
1575
1613
this . sourceFilesContainingAmbientDeclarations = new Set ( ) ;
1576
1614
@@ -1908,34 +1946,12 @@ class Symbols {
1908
1946
return true ;
1909
1947
}
1910
1948
1911
- public storeSymbolInitializationData ( symbol : ts . Symbol , visibility : SymbolDataVisibility ) : void {
1912
- const key = this . getSymbolId ( symbol ) ;
1913
- this . symbolInitializationData . set ( key , visibility ) ;
1914
- }
1915
-
1916
1949
public getSymbolInitializationData ( symbol : ts . Symbol ) : [ string | undefined , ModuleSystemKind , SymbolDataVisibility , boolean ] {
1917
1950
const [ exportPath , moduleSystem , ] = this . getCachedSymbolInformation ( symbol ) ;
1918
- const visibility = this . getVisibility ( symbol , exportPath ) ;
1951
+ const symbolId = this . getSymbolId ( symbol ) ;
1952
+ const visibility = Symbols . getVisibility ( symbolId , symbol , exportPath ) ;
1919
1953
return [ exportPath === null ? undefined : exportPath , moduleSystem , visibility , ! Symbols . isInternal ( symbol ) ] ;
1920
1954
}
1921
-
1922
- private getVisibility ( symbol : ts . Symbol , exportPath : string | undefined | null ) : SymbolDataVisibility {
1923
- const id = this . getSymbolId ( symbol ) ;
1924
- const initVisibility = this . symbolInitializationData . get ( id ) ;
1925
- if ( initVisibility !== undefined ) {
1926
- this . symbolInitializationData . delete ( id ) ;
1927
- }
1928
-
1929
- // The symbol is exported.
1930
- if ( exportPath === null || exportPath !== undefined ) {
1931
- return SymbolDataVisibility . exported ;
1932
- }
1933
- if ( Symbols . isTransient ( symbol ) ) {
1934
- return SymbolDataVisibility . transient ;
1935
- }
1936
-
1937
- return initVisibility ?? SymbolDataVisibility . unknown ;
1938
- }
1939
1955
}
1940
1956
1941
1957
@@ -2424,13 +2440,11 @@ class WorkspaceProjectDataManager extends LazyProjectDataManager {
2424
2440
2425
2441
class TSConfigProjectDataManager extends ProjectDataManager {
2426
2442
2427
- private readonly sourceRoot : string ;
2428
2443
private readonly projectFiles : Set < string > ;
2429
2444
private readonly managedDocuments : Set < Document > ;
2430
2445
2431
- public constructor ( id : ProjectId , context : ProjectDataManagerContext , project : Project , sourceRoot : string , projectFiles : ReadonlyArray < string > | undefined , reporter : Reporter ) {
2446
+ public constructor ( id : ProjectId , context : ProjectDataManagerContext , project : Project , _sourceRoot : string , projectFiles : ReadonlyArray < string > | undefined , reporter : Reporter ) {
2432
2447
super ( id , context , project , reporter ) ;
2433
- this . sourceRoot = sourceRoot ;
2434
2448
this . projectFiles = new Set ( projectFiles ) ;
2435
2449
this . managedDocuments = new Set ( ) ;
2436
2450
}
@@ -2441,7 +2455,7 @@ class TSConfigProjectDataManager extends ProjectDataManager {
2441
2455
2442
2456
public handles ( sourceFile : ts . SourceFile ) : boolean {
2443
2457
const fileName = sourceFile . fileName ;
2444
- return this . projectFiles . has ( fileName ) || paths . isParent ( this . sourceRoot , fileName ) ;
2458
+ return this . projectFiles . has ( fileName ) ;
2445
2459
}
2446
2460
2447
2461
public createDocumentData ( fileName : string , document : Document , moduleSystem : ModuleSystemKind , monikerPath : string | undefined , external : boolean , next : DocumentData | undefined ) : DocumentData {
@@ -2805,9 +2819,10 @@ class TSProject {
2805
2819
kind : Converter . asSymbolKind ( declaration ) ,
2806
2820
fullRange : Converter . rangeFromNode ( sourceFile , declaration ) ,
2807
2821
} ) ;
2808
- documentData . addRange ( definition ) ;
2809
- symbolData . addDefinition ( documentData . document , definition ) ;
2810
- symbolData . recordDefinitionInfo ( tss . createDefinitionInfo ( sourceFile , identifierNode ) ) ;
2822
+ if ( documentData . addRange ( definition ) ) {
2823
+ symbolData . addDefinition ( documentData . document , definition ) ;
2824
+ symbolData . recordDefinitionInfo ( tss . createDefinitionInfo ( sourceFile , identifierNode ) ) ;
2825
+ }
2811
2826
if ( hover === undefined && tss . Node . isNamedDeclaration ( declaration ) ) {
2812
2827
// let start = Date.now();
2813
2828
hover = this . getHover ( declaration . name , sourceFile ) ;
@@ -3038,6 +3053,11 @@ export class DataManager implements SymbolDataContext, ProjectDataManagerContext
3038
3053
if ( this . currentTSProject !== tsProject || this . currentPDM === undefined ) {
3039
3054
throw new Error ( `Current project is not the one passed to end.` ) ;
3040
3055
}
3056
+ // Make sure we close partitions opened because of type folding in global files.
3057
+ const documents = this . currentPDM . getDocuments ( ) ;
3058
+ for ( const manager of [ this . workspacePDM , this . machinePDM , this . defaultLibsPDM ] ) {
3059
+ manager . endPartitions ( documents ) ;
3060
+ }
3041
3061
this . currentPDM . end ( ) ;
3042
3062
this . currentPDM = undefined ;
3043
3063
this . currentTSProject = undefined ;
@@ -3194,8 +3214,9 @@ export class DataManager implements SymbolDataContext, ProjectDataManagerContext
3194
3214
}
3195
3215
3196
3216
const reference = this . vertex . range ( Converter . rangeFromNode ( sourceFile , location ) , { type : RangeTagTypes . reference , text : location . getText ( ) } ) ;
3197
- documentData . addRange ( reference ) ;
3198
- symbolData . addReference ( documentData . document , reference , ItemEdgeProperties . references ) ;
3217
+ if ( documentData . addRange ( reference ) ) {
3218
+ symbolData . addReference ( documentData . document , reference , ItemEdgeProperties . references ) ;
3219
+ }
3199
3220
}
3200
3221
3201
3222
public getSymbolData ( symbol : SymbolId | ts . Symbol ) : SymbolData | undefined {
0 commit comments