@@ -962,39 +962,80 @@ 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
+ if ( parent ) {
1018
+ n . parent = parent ;
1019
+ }
1020
+ var saveParent = parent ;
1021
+ parent = n ;
1022
+ forEachChild ( n , walk ) ;
1023
+ parent = saveParent ;
1024
+ }
1025
+ forEachChild ( sourceFile , walk ) ;
1026
+ }
1027
+ }
1028
+
1029
+ public getCurrentFileSyntaxTree ( filename : string ) : TypeScript . SyntaxTree {
1030
+ this . initialize ( filename ) ;
995
1031
return this . currentFileSyntaxTree ;
996
1032
}
997
1033
1034
+ public getCurrentSourceFile ( filename : string ) : SourceFile {
1035
+ this . initialize ( filename ) ;
1036
+ return this . currentSourceFile ;
1037
+ }
1038
+
998
1039
public getCurrentScriptSnapshot ( filename : string ) : TypeScript . IScriptSnapshot {
999
1040
// update currentFileScriptSnapshot as a part of 'getCurrentFileSyntaxTree' call
1000
1041
this . getCurrentFileSyntaxTree ( filename ) ;
@@ -1093,6 +1134,10 @@ module ts {
1093
1134
}
1094
1135
}
1095
1136
1137
+ function createSourceFileFromScriptSnapshot ( filename : string , scriptSnapshot : TypeScript . IScriptSnapshot , settings : CompilerOptions , version : number , isOpen : boolean ) {
1138
+ return createSourceFile ( filename , scriptSnapshot . getText ( 0 , scriptSnapshot . getLength ( ) ) , settings . target , version , isOpen ) ;
1139
+ }
1140
+
1096
1141
export function createDocumentRegistry ( ) : DocumentRegistry {
1097
1142
var buckets : Map < Map < DocumentRegistryEntry > > = { } ;
1098
1143
@@ -1140,7 +1185,7 @@ module ts {
1140
1185
var bucket = getBucketForCompilationSettings ( compilationSettings , /*createIfMissing*/ true ) ;
1141
1186
var entry = lookUp ( bucket , filename ) ;
1142
1187
if ( ! entry ) {
1143
- var sourceFile = createSourceFile ( filename , scriptSnapshot . getText ( 0 , scriptSnapshot . getLength ( ) ) , compilationSettings . target , version , isOpen ) ;
1188
+ var sourceFile = createSourceFileFromScriptSnapshot ( filename , scriptSnapshot , compilationSettings , version , isOpen ) ;
1144
1189
1145
1190
bucket [ filename ] = entry = {
1146
1191
sourceFile : sourceFile ,
@@ -2024,6 +2069,12 @@ module ts {
2024
2069
return syntaxTreeCache . getCurrentFileSyntaxTree ( filename ) ;
2025
2070
}
2026
2071
2072
+ function getCurrentSourceFile ( filename : string ) : SourceFile {
2073
+ filename = TypeScript . switchToForwardSlashes ( filename ) ;
2074
+ var currentSourceFile = syntaxTreeCache . getCurrentSourceFile ( filename ) ;
2075
+ return currentSourceFile ;
2076
+ }
2077
+
2027
2078
function getNameOrDottedNameSpan ( filename : string , startPos : number , endPos : number ) : SpanInfo {
2028
2079
function getTypeInfoEligiblePath ( filename : string , position : number , isConstructorValidPosition : boolean ) {
2029
2080
var sourceUnit = syntaxTreeCache . getCurrentFileSyntaxTree ( filename ) . sourceUnit ( ) ;
@@ -2100,8 +2151,8 @@ module ts {
2100
2151
function getOutliningRegions ( filename : string ) {
2101
2152
// doesn't use compiler - no need to synchronize with host
2102
2153
filename = TypeScript . switchToForwardSlashes ( filename ) ;
2103
- var syntaxTree = getSyntaxTree ( filename ) ;
2104
- return TypeScript . Services . OutliningElementsCollector . collectElements ( syntaxTree . sourceUnit ( ) ) ;
2154
+ var sourceFile = getCurrentSourceFile ( filename ) ;
2155
+ return OutliningElementsCollector . collectElements ( sourceFile ) ;
2105
2156
}
2106
2157
2107
2158
function getBraceMatchingAtPosition ( filename : string , position : number ) {
0 commit comments