@@ -1432,7 +1432,11 @@ module ts {
14321432
14331433 interface DocumentRegistryEntry {
14341434 sourceFile : SourceFile ;
1435- refCount : number ;
1435+
1436+ // The number of language services that this source file is referenced in. When no more
1437+ // language services are referencing the file, then the file can be removed from the
1438+ // registry.
1439+ languageServiceRefCount : number ;
14361440 owners : string [ ] ;
14371441 }
14381442
@@ -1661,6 +1665,8 @@ module ts {
16611665 }
16621666
16631667 export function createDocumentRegistry ( ) : DocumentRegistry {
1668+ // Maps from compiler setting target (ES3, ES5, etc.) to all the cached documents we have
1669+ // for those settings.
16641670 var buckets : Map < Map < DocumentRegistryEntry > > = { } ;
16651671
16661672 function getKeyFromCompilationSettings ( settings : CompilerOptions ) : string {
@@ -1684,7 +1690,7 @@ module ts {
16841690 var entry = entries [ i ] ;
16851691 sourceFiles . push ( {
16861692 name : i ,
1687- refCount : entry . refCount ,
1693+ refCount : entry . languageServiceRefCount ,
16881694 references : entry . owners . slice ( 0 )
16891695 } ) ;
16901696 }
@@ -1697,45 +1703,52 @@ module ts {
16971703 return JSON . stringify ( bucketInfoArray , null , 2 ) ;
16981704 }
16991705
1700- function acquireDocument (
1706+ function acquireDocument ( fileName : string , compilationSettings : CompilerOptions , scriptSnapshot : IScriptSnapshot , version : string ) : SourceFile {
1707+ return acquireOrUpdateDocument ( fileName , compilationSettings , scriptSnapshot , version , /*acquiring:*/ true ) ;
1708+ }
1709+
1710+ function updateDocument ( fileName : string , compilationSettings : CompilerOptions , scriptSnapshot : IScriptSnapshot , version : string ) : SourceFile {
1711+ return acquireOrUpdateDocument ( fileName , compilationSettings , scriptSnapshot , version , /*acquiring:*/ false ) ;
1712+ }
1713+
1714+ function acquireOrUpdateDocument (
17011715 fileName : string ,
17021716 compilationSettings : CompilerOptions ,
17031717 scriptSnapshot : IScriptSnapshot ,
1704- version : string ) : SourceFile {
1718+ version : string ,
1719+ acquiring : boolean ) : SourceFile {
17051720
17061721 var bucket = getBucketForCompilationSettings ( compilationSettings , /*createIfMissing*/ true ) ;
17071722 var entry = lookUp ( bucket , fileName ) ;
17081723 if ( ! entry ) {
1724+ Debug . assert ( acquiring , "How could we be trying to update a document that the registry doesn't have?" ) ;
1725+
1726+ // Have never seen this file with these settings. Create a new source file for it.
17091727 var sourceFile = createLanguageServiceSourceFile ( fileName , scriptSnapshot , compilationSettings . target , version , /*setNodeParents:*/ false ) ;
17101728
17111729 bucket [ fileName ] = entry = {
17121730 sourceFile : sourceFile ,
1713- refCount : 0 ,
1731+ languageServiceRefCount : 0 ,
17141732 owners : [ ]
17151733 } ;
17161734 }
1717- entry . refCount ++ ;
1718-
1719- return entry . sourceFile ;
1720- }
1721-
1722- function updateDocument (
1723- fileName : string ,
1724- compilationSettings : CompilerOptions ,
1725- scriptSnapshot : IScriptSnapshot ,
1726- version : string ) : SourceFile {
1727-
1728- var bucket = getBucketForCompilationSettings ( compilationSettings , /*createIfMissing*/ false ) ;
1729- Debug . assert ( bucket !== undefined ) ;
1730- var entry = lookUp ( bucket , fileName ) ;
1731- Debug . assert ( entry !== undefined ) ;
1735+ else {
1736+ // We have an entry for this file. However, it may be for a different version of
1737+ // the script snapshot. If so, update it appropriately. Otherwise, we can just
1738+ // return it as is.
1739+ if ( entry . sourceFile . version !== version ) {
1740+ entry . sourceFile = updateLanguageServiceSourceFile ( entry . sourceFile , scriptSnapshot , version ,
1741+ scriptSnapshot . getChangeRange ( entry . sourceFile . scriptSnapshot ) ) ;
1742+ }
1743+ }
17321744
1733- // Check with the host if anything actually changed.
1734- if ( entry . sourceFile . version !== version ) {
1735- // If so, ask the host for what changed between these two versions and then do the
1736- // actual incremental parsing.
1737- var textChangeRange = scriptSnapshot . getChangeRange ( entry . sourceFile . scriptSnapshot ) ;
1738- entry . sourceFile = updateLanguageServiceSourceFile ( entry . sourceFile , scriptSnapshot , version , textChangeRange ) ;
1745+ // If we're acquiring, then this is the first time this LS is asking for this document.
1746+ // Increase our ref count so we know there's another LS using the document. If we're
1747+ // not acquiring, then that means the LS is 'updating' the file instead, and that means
1748+ // it has already acquired the document previously. As such, we do not need to increase
1749+ // the ref count.
1750+ if ( acquiring ) {
1751+ entry . languageServiceRefCount ++ ;
17391752 }
17401753
17411754 return entry . sourceFile ;
@@ -1746,10 +1759,10 @@ module ts {
17461759 Debug . assert ( bucket !== undefined ) ;
17471760
17481761 var entry = lookUp ( bucket , fileName ) ;
1749- entry . refCount -- ;
1762+ entry . languageServiceRefCount -- ;
17501763
1751- Debug . assert ( entry . refCount >= 0 ) ;
1752- if ( entry . refCount === 0 ) {
1764+ Debug . assert ( entry . languageServiceRefCount >= 0 ) ;
1765+ if ( entry . languageServiceRefCount === 0 ) {
17531766 delete bucket [ fileName ] ;
17541767 }
17551768 }
0 commit comments