@@ -482,7 +482,7 @@ module ts {
482
482
getNavigateToItems ( searchValue : string ) : NavigateToItem [ ] ;
483
483
getScriptLexicalStructure ( fileName : string ) : NavigateToItem [ ] ;
484
484
485
- getOutliningRegions ( fileName : string ) : TypeScript . TextSpan [ ] ;
485
+ getOutliningRegions ( fileName : string ) : OutliningSpan [ ] ;
486
486
getBraceMatchingAtPosition ( fileName : string , position : number ) : TypeScript . TextSpan [ ] ;
487
487
getIndentationAtPosition ( fileName : string , position : number , options : EditorOptions ) : number ;
488
488
@@ -962,39 +962,79 @@ module ts {
962
962
// currently edited file.
963
963
private currentfilename : string = "" ;
964
964
private currentFileVersion : number = - 1 ;
965
+ private currentSourceFile : SourceFile = null ;
965
966
private currentFileSyntaxTree : TypeScript . SyntaxTree = null ;
966
967
private currentFileScriptSnapshot : TypeScript . IScriptSnapshot = null ;
967
968
968
969
constructor ( private host : LanguageServiceHost ) {
969
970
this . hostCache = new HostCache ( host ) ;
970
971
}
971
972
972
- public getCurrentFileSyntaxTree ( filename : string ) : TypeScript . SyntaxTree {
973
+ private initialize ( filename : string ) {
974
+ // ensure that both source file and syntax tree are either initialized or not initialized
975
+ Debug . assert ( ! ! this . currentFileSyntaxTree === ! ! this . currentSourceFile ) ;
973
976
this . hostCache = new HostCache ( this . host ) ;
974
977
975
978
var version = this . hostCache . getVersion ( filename ) ;
976
979
var syntaxTree : TypeScript . SyntaxTree = null ;
980
+ var sourceFile : SourceFile ;
977
981
978
982
if ( this . currentFileSyntaxTree === null || this . currentfilename !== filename ) {
979
983
var scriptSnapshot = this . hostCache . getScriptSnapshot ( filename ) ;
980
984
syntaxTree = this . createSyntaxTree ( filename , scriptSnapshot ) ;
985
+ sourceFile = createSourceFileFromScriptSnapshot ( filename , scriptSnapshot , getDefaultCompilerOptions ( ) , version , /*isOpen*/ true ) ;
986
+
987
+ fixupParentReferences ( sourceFile ) ;
981
988
}
982
989
else if ( this . currentFileVersion !== version ) {
983
990
var scriptSnapshot = this . hostCache . getScriptSnapshot ( filename ) ;
984
991
syntaxTree = this . updateSyntaxTree ( filename , scriptSnapshot , this . currentFileSyntaxTree , this . currentFileVersion ) ;
992
+
993
+ var editRange = this . hostCache . getScriptTextChangeRangeSinceVersion ( filename , this . currentFileVersion ) ;
994
+ sourceFile = ! editRange
995
+ ? createSourceFileFromScriptSnapshot ( filename , scriptSnapshot , getDefaultCompilerOptions ( ) , version , /*isOpen*/ true )
996
+ : this . currentSourceFile . update ( scriptSnapshot , version , /*isOpen*/ true , editRange ) ;
997
+
998
+ fixupParentReferences ( sourceFile ) ;
985
999
}
986
1000
987
1001
if ( syntaxTree !== null ) {
1002
+ Debug . assert ( sourceFile ) ;
988
1003
// All done, ensure state is up to date
989
1004
this . currentFileScriptSnapshot = scriptSnapshot ;
990
1005
this . currentFileVersion = version ;
991
1006
this . currentfilename = filename ;
992
1007
this . currentFileSyntaxTree = syntaxTree ;
1008
+ this . currentSourceFile = sourceFile ;
993
1009
}
994
1010
1011
+ function fixupParentReferences ( sourceFile : SourceFile ) {
1012
+ // normally parent references are set during binding.
1013
+ // however here SourceFile data is used only for syntactic features so running the whole binding process is an overhead.
1014
+ // walk over the nodes and set parent references
1015
+ var parent : Node = sourceFile ;
1016
+ function walk ( n : Node ) : void {
1017
+ n . parent = parent ;
1018
+
1019
+ var saveParent = parent ;
1020
+ parent = n ;
1021
+ forEachChild ( n , walk ) ;
1022
+ parent = saveParent ;
1023
+ }
1024
+ forEachChild ( sourceFile , walk ) ;
1025
+ }
1026
+ }
1027
+
1028
+ public getCurrentFileSyntaxTree ( filename : string ) : TypeScript . SyntaxTree {
1029
+ this . initialize ( filename ) ;
995
1030
return this . currentFileSyntaxTree ;
996
1031
}
997
1032
1033
+ public getCurrentSourceFile ( filename : string ) : SourceFile {
1034
+ this . initialize ( filename ) ;
1035
+ return this . currentSourceFile ;
1036
+ }
1037
+
998
1038
public getCurrentScriptSnapshot ( filename : string ) : TypeScript . IScriptSnapshot {
999
1039
// update currentFileScriptSnapshot as a part of 'getCurrentFileSyntaxTree' call
1000
1040
this . getCurrentFileSyntaxTree ( filename ) ;
@@ -1093,6 +1133,10 @@ module ts {
1093
1133
}
1094
1134
}
1095
1135
1136
+ function createSourceFileFromScriptSnapshot ( filename : string , scriptSnapshot : TypeScript . IScriptSnapshot , settings : CompilerOptions , version : number , isOpen : boolean ) {
1137
+ return createSourceFile ( filename , scriptSnapshot . getText ( 0 , scriptSnapshot . getLength ( ) ) , settings . target , version , isOpen ) ;
1138
+ }
1139
+
1096
1140
export function createDocumentRegistry ( ) : DocumentRegistry {
1097
1141
var buckets : Map < Map < DocumentRegistryEntry > > = { } ;
1098
1142
@@ -1140,7 +1184,7 @@ module ts {
1140
1184
var bucket = getBucketForCompilationSettings ( compilationSettings , /*createIfMissing*/ true ) ;
1141
1185
var entry = lookUp ( bucket , filename ) ;
1142
1186
if ( ! entry ) {
1143
- var sourceFile = createSourceFile ( filename , scriptSnapshot . getText ( 0 , scriptSnapshot . getLength ( ) ) , compilationSettings . target , version , isOpen ) ;
1187
+ var sourceFile = createSourceFileFromScriptSnapshot ( filename , scriptSnapshot , compilationSettings , version , isOpen ) ;
1144
1188
1145
1189
bucket [ filename ] = entry = {
1146
1190
sourceFile : sourceFile ,
@@ -2024,6 +2068,12 @@ module ts {
2024
2068
return syntaxTreeCache . getCurrentFileSyntaxTree ( filename ) ;
2025
2069
}
2026
2070
2071
+ function getCurrentSourceFile ( filename : string ) : SourceFile {
2072
+ filename = TypeScript . switchToForwardSlashes ( filename ) ;
2073
+ var currentSourceFile = syntaxTreeCache . getCurrentSourceFile ( filename ) ;
2074
+ return currentSourceFile ;
2075
+ }
2076
+
2027
2077
function getNameOrDottedNameSpan ( filename : string , startPos : number , endPos : number ) : SpanInfo {
2028
2078
function getTypeInfoEligiblePath ( filename : string , position : number , isConstructorValidPosition : boolean ) {
2029
2079
var sourceUnit = syntaxTreeCache . getCurrentFileSyntaxTree ( filename ) . sourceUnit ( ) ;
@@ -2097,11 +2147,11 @@ module ts {
2097
2147
return items ;
2098
2148
}
2099
2149
2100
- function getOutliningRegions ( filename : string ) {
2150
+ function getOutliningRegions ( filename : string ) : OutliningSpan [ ] {
2101
2151
// doesn't use compiler - no need to synchronize with host
2102
2152
filename = TypeScript . switchToForwardSlashes ( filename ) ;
2103
- var syntaxTree = getSyntaxTree ( filename ) ;
2104
- return TypeScript . Services . OutliningElementsCollector . collectElements ( syntaxTree . sourceUnit ( ) ) ;
2153
+ var sourceFile = getCurrentSourceFile ( filename ) ;
2154
+ return OutliningElementsCollector . collectElements ( sourceFile ) ;
2105
2155
}
2106
2156
2107
2157
function getBraceMatchingAtPosition ( filename : string , position : number ) {
0 commit comments