@@ -482,7 +482,7 @@ module ts {
482482 getNavigateToItems ( searchValue : string ) : NavigateToItem [ ] ;
483483 getScriptLexicalStructure ( fileName : string ) : NavigateToItem [ ] ;
484484
485- getOutliningRegions ( fileName : string ) : TypeScript . TextSpan [ ] ;
485+ getOutliningRegions ( fileName : string ) : OutliningSpan [ ] ;
486486 getBraceMatchingAtPosition ( fileName : string , position : number ) : TypeScript . TextSpan [ ] ;
487487 getIndentationAtPosition ( fileName : string , position : number , options : EditorOptions ) : number ;
488488
@@ -962,39 +962,79 @@ module ts {
962962 // currently edited file.
963963 private currentfilename : string = "" ;
964964 private currentFileVersion : number = - 1 ;
965+ private currentSourceFile : SourceFile = null ;
965966 private currentFileSyntaxTree : TypeScript . SyntaxTree = null ;
966967 private currentFileScriptSnapshot : TypeScript . IScriptSnapshot = null ;
967968
968969 constructor ( private host : LanguageServiceHost ) {
969970 this . hostCache = new HostCache ( host ) ;
970971 }
971972
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 ) ;
973976 this . hostCache = new HostCache ( this . host ) ;
974977
975978 var version = this . hostCache . getVersion ( filename ) ;
976979 var syntaxTree : TypeScript . SyntaxTree = null ;
980+ var sourceFile : SourceFile ;
977981
978982 if ( this . currentFileSyntaxTree === null || this . currentfilename !== filename ) {
979983 var scriptSnapshot = this . hostCache . getScriptSnapshot ( filename ) ;
980984 syntaxTree = this . createSyntaxTree ( filename , scriptSnapshot ) ;
985+ sourceFile = createSourceFileFromScriptSnapshot ( filename , scriptSnapshot , getDefaultCompilerOptions ( ) , version , /*isOpen*/ true ) ;
986+
987+ fixupParentReferences ( sourceFile ) ;
981988 }
982989 else if ( this . currentFileVersion !== version ) {
983990 var scriptSnapshot = this . hostCache . getScriptSnapshot ( filename ) ;
984991 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 ) ;
985999 }
9861000
9871001 if ( syntaxTree !== null ) {
1002+ Debug . assert ( sourceFile ) ;
9881003 // All done, ensure state is up to date
9891004 this . currentFileScriptSnapshot = scriptSnapshot ;
9901005 this . currentFileVersion = version ;
9911006 this . currentfilename = filename ;
9921007 this . currentFileSyntaxTree = syntaxTree ;
1008+ this . currentSourceFile = sourceFile ;
9931009 }
9941010
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 ) ;
9951030 return this . currentFileSyntaxTree ;
9961031 }
9971032
1033+ public getCurrentSourceFile ( filename : string ) : SourceFile {
1034+ this . initialize ( filename ) ;
1035+ return this . currentSourceFile ;
1036+ }
1037+
9981038 public getCurrentScriptSnapshot ( filename : string ) : TypeScript . IScriptSnapshot {
9991039 // update currentFileScriptSnapshot as a part of 'getCurrentFileSyntaxTree' call
10001040 this . getCurrentFileSyntaxTree ( filename ) ;
@@ -1093,6 +1133,10 @@ module ts {
10931133 }
10941134 }
10951135
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+
10961140 export function createDocumentRegistry ( ) : DocumentRegistry {
10971141 var buckets : Map < Map < DocumentRegistryEntry > > = { } ;
10981142
@@ -1140,7 +1184,7 @@ module ts {
11401184 var bucket = getBucketForCompilationSettings ( compilationSettings , /*createIfMissing*/ true ) ;
11411185 var entry = lookUp ( bucket , filename ) ;
11421186 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 ) ;
11441188
11451189 bucket [ filename ] = entry = {
11461190 sourceFile : sourceFile ,
@@ -2024,6 +2068,12 @@ module ts {
20242068 return syntaxTreeCache . getCurrentFileSyntaxTree ( filename ) ;
20252069 }
20262070
2071+ function getCurrentSourceFile ( filename : string ) : SourceFile {
2072+ filename = TypeScript . switchToForwardSlashes ( filename ) ;
2073+ var currentSourceFile = syntaxTreeCache . getCurrentSourceFile ( filename ) ;
2074+ return currentSourceFile ;
2075+ }
2076+
20272077 function getNameOrDottedNameSpan ( filename : string , startPos : number , endPos : number ) : SpanInfo {
20282078 function getTypeInfoEligiblePath ( filename : string , position : number , isConstructorValidPosition : boolean ) {
20292079 var sourceUnit = syntaxTreeCache . getCurrentFileSyntaxTree ( filename ) . sourceUnit ( ) ;
@@ -2097,11 +2147,11 @@ module ts {
20972147 return items ;
20982148 }
20992149
2100- function getOutliningRegions ( filename : string ) {
2150+ function getOutliningRegions ( filename : string ) : OutliningSpan [ ] {
21012151 // doesn't use compiler - no need to synchronize with host
21022152 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 ) ;
21052155 }
21062156
21072157 function getBraceMatchingAtPosition ( filename : string , position : number ) {
0 commit comments