@@ -386,7 +386,7 @@ namespace ts.FindAllReferences.Core {
386386 const searchMeaning = getIntersectingMeaningFromDeclarations ( getMeaningFromLocation ( node ) , symbol . declarations ) ;
387387
388388 const result : SymbolAndEntries [ ] = [ ] ;
389- const state = createState ( sourceFiles , node , checker , cancellationToken , searchMeaning , options , result ) ;
389+ const state = new State ( sourceFiles , node , checker , cancellationToken , searchMeaning , options , result ) ;
390390 const search = state . createSearch ( node , symbol , /*comingFrom*/ undefined , { allSearchSymbols : populateSearchSymbolSet ( symbol , node , checker , options . implementations ) } ) ;
391391
392392 // Try to get the smallest valid scope that we can limit our search to;
@@ -446,35 +446,18 @@ namespace ts.FindAllReferences.Core {
446446 * Holds all state needed for the finding references.
447447 * Unlike `Search`, there is only one `State`.
448448 */
449- interface State extends Options {
449+ class State {
450450 /** True if we're searching for constructor references. */
451451 readonly isForConstructor : boolean ;
452452
453- readonly sourceFiles : SourceFile [ ] ;
454- readonly checker : TypeChecker ;
455- readonly cancellationToken : CancellationToken ;
456- readonly searchMeaning : SemanticMeaning ;
457-
458453 /** Cache for `explicitlyinheritsFrom`. */
459- readonly inheritsFromCache : Map < boolean > ;
460-
461- /** Gets every place to look for references of an exported symbols. See `ImportsResult` in `importTracker.ts` for more documentation. */
462- getImportSearches ( exportSymbol : Symbol , exportInfo : ExportInfo ) : ImportsResult ;
463-
464- /** @param allSearchSymbols set of additinal symbols for use by `includes`. */
465- createSearch ( location : Node , symbol : Symbol , comingFrom : ImportExport | undefined , searchOptions ?: { text ?: string , allSearchSymbols ?: Symbol [ ] } ) : Search ;
466-
467- /**
468- * Callback to add references for a particular searched symbol.
469- * This initializes a reference group, so only call this if you will add at least one reference.
470- */
471- referenceAdder ( searchSymbol : Symbol , searchLocation : Node ) : ( node : Node ) => void ;
454+ readonly inheritsFromCache = createMap < boolean > ( ) ;
472455
473- /** Add a reference with no associated definition. */
474- addStringOrCommentReference ( fileName : string , textSpan : TextSpan ) : void ;
456+ private readonly symbolIdToReferences : Entry [ ] [ ] = [ ] ;
457+ // Source file ID → symbol ID → Whether the symbol has been searched for in the source file.
458+ private readonly sourceFileToSeenSymbols : Array < Array < true > > = [ ] ;
475459
476- /** Returns `true` the first time we search for a symbol in a file and `false` afterwards. */
477- markSearchedSymbol ( sourceFile : SourceFile , symbol : Symbol ) : boolean ;
460+ private importTracker : ImportTracker | undefined ;
478461
479462 /**
480463 * Type nodes can contain multiple references to the same type. For example:
@@ -483,7 +466,7 @@ namespace ts.FindAllReferences.Core {
483466 * duplicate entries would be returned here as each of the type references is part of
484467 * the same implementation. For that reason, check before we add a new entry.
485468 */
486- markSeenContainingTypeReference ( containingTypeReference : Node ) : boolean ;
469+ readonly markSeenContainingTypeReference : ( containingTypeReference : Node ) => boolean ;
487470
488471 /**
489472 * It's possible that we will encounter the right side of `export { foo as bar } from "x";` more than once.
@@ -496,61 +479,78 @@ namespace ts.FindAllReferences.Core {
496479 * But another reference to it may appear in the same source file.
497480 * See `tests/cases/fourslash/transitiveExportImports3.ts`.
498481 */
499- markSeenReExportRHS ( rhs : Identifier ) : boolean ;
500- }
482+ readonly markSeenReExportRHS : ( rhs : Identifier ) => boolean ;
501483
502- function createState ( sourceFiles : SourceFile [ ] , originalLocation : Node , checker : TypeChecker , cancellationToken : CancellationToken , searchMeaning : SemanticMeaning , options : Options , result : Push < SymbolAndEntries > ) : State {
503- const symbolIdToReferences : Entry [ ] [ ] = [ ] ;
504- const inheritsFromCache = createMap < boolean > ( ) ;
505- // Source file ID → symbol ID → Whether the symbol has been searched for in the source file.
506- const sourceFileToSeenSymbols : Array < Array < true > > = [ ] ;
507- const isForConstructor = originalLocation . kind === SyntaxKind . ConstructorKeyword ;
508- let importTracker : ImportTracker | undefined ;
484+ readonly findInStrings ?: boolean ;
485+ readonly findInComments ?: boolean ;
486+ readonly isForRename ?: boolean ;
487+ readonly implementations ?: boolean ;
509488
510- return {
511- ...options ,
512- sourceFiles, isForConstructor, checker, cancellationToken, searchMeaning, inheritsFromCache, getImportSearches, createSearch, referenceAdder, addStringOrCommentReference,
513- markSearchedSymbol, markSeenContainingTypeReference : nodeSeenTracker ( ) , markSeenReExportRHS : nodeSeenTracker ( ) ,
514- } ;
489+ constructor (
490+ readonly sourceFiles : SourceFile [ ] ,
491+ originalLocation : Node ,
492+ readonly checker : TypeChecker ,
493+ readonly cancellationToken : CancellationToken ,
494+ readonly searchMeaning : SemanticMeaning ,
495+ options : Options ,
496+ private readonly result : Push < SymbolAndEntries > ) {
497+
498+ this . findInStrings = options . findInStrings ;
499+ this . findInComments = options . findInComments ;
500+ this . isForRename = options . isForRename ;
501+ this . implementations = options . implementations ;
502+
503+ this . isForConstructor = originalLocation . kind === SyntaxKind . ConstructorKeyword ;
504+ this . markSeenContainingTypeReference = nodeSeenTracker ( ) ;
505+ this . markSeenReExportRHS = nodeSeenTracker ( ) ;
506+ }
515507
516- function getImportSearches ( exportSymbol : Symbol , exportInfo : ExportInfo ) : ImportsResult {
517- if ( ! importTracker ) importTracker = createImportTracker ( sourceFiles , checker , cancellationToken ) ;
518- return importTracker ( exportSymbol , exportInfo , options . isForRename ) ;
508+ /** Gets every place to look for references of an exported symbols. See `ImportsResult` in `importTracker.ts` for more documentation. */
509+ getImportSearches ( exportSymbol : Symbol , exportInfo : ExportInfo ) : ImportsResult {
510+ if ( ! this . importTracker ) this . importTracker = createImportTracker ( this . sourceFiles , this . checker , this . cancellationToken ) ;
511+ return this . importTracker ( exportSymbol , exportInfo , this . isForRename ) ;
519512 }
520513
521- function createSearch ( location : Node , symbol : Symbol , comingFrom : ImportExport , searchOptions : { text ?: string , allSearchSymbols ?: Symbol [ ] } = { } ) : Search {
514+ /** @param allSearchSymbols set of additinal symbols for use by `includes`. */
515+ createSearch ( location : Node , symbol : Symbol , comingFrom : ImportExport | undefined , searchOptions : { text ?: string , allSearchSymbols ?: Symbol [ ] } = { } ) : Search {
522516 // Note: if this is an external module symbol, the name doesn't include quotes.
523- const { text = stripQuotes ( getDeclaredName ( checker , symbol , location ) ) , allSearchSymbols = undefined } = searchOptions ;
517+ const { text = stripQuotes ( getDeclaredName ( this . checker , symbol , location ) ) , allSearchSymbols = undefined } = searchOptions ;
524518 const escapedText = escapeIdentifier ( text ) ;
525- const parents = options . implementations && getParentSymbolsOfPropertyAccess ( location , symbol , checker ) ;
519+ const parents = this . implementations && getParentSymbolsOfPropertyAccess ( location , symbol , this . checker ) ;
526520 return { location, symbol, comingFrom, text, escapedText, parents, includes } ;
527521
528522 function includes ( referenceSymbol : Symbol ) : boolean {
529523 return allSearchSymbols ? contains ( allSearchSymbols , referenceSymbol ) : referenceSymbol === symbol ;
530524 }
531525 }
532526
533- function referenceAdder ( referenceSymbol : Symbol , searchLocation : Node ) : ( node : Node ) => void {
534- const symbolId = getSymbolId ( referenceSymbol ) ;
535- let references = symbolIdToReferences [ symbolId ] ;
527+ /**
528+ * Callback to add references for a particular searched symbol.
529+ * This initializes a reference group, so only call this if you will add at least one reference.
530+ */
531+ referenceAdder ( searchSymbol : Symbol , searchLocation : Node ) : ( node : Node ) => void {
532+ const symbolId = getSymbolId ( searchSymbol ) ;
533+ let references = this . symbolIdToReferences [ symbolId ] ;
536534 if ( ! references ) {
537- references = symbolIdToReferences [ symbolId ] = [ ] ;
538- result . push ( { definition : { type : "symbol" , symbol : referenceSymbol , node : searchLocation } , references } ) ;
535+ references = this . symbolIdToReferences [ symbolId ] = [ ] ;
536+ this . result . push ( { definition : { type : "symbol" , symbol : searchSymbol , node : searchLocation } , references } ) ;
539537 }
540538 return node => references . push ( nodeEntry ( node ) ) ;
541539 }
542540
543- function addStringOrCommentReference ( fileName : string , textSpan : TextSpan ) : void {
544- result . push ( {
541+ /** Add a reference with no associated definition. */
542+ addStringOrCommentReference ( fileName : string , textSpan : TextSpan ) : void {
543+ this . result . push ( {
545544 definition : undefined ,
546545 references : [ { type : "span" , fileName, textSpan } ]
547546 } ) ;
548547 }
549548
550- function markSearchedSymbol ( sourceFile : SourceFile , symbol : Symbol ) : boolean {
549+ /** Returns `true` the first time we search for a symbol in a file and `false` afterwards. */
550+ markSearchedSymbol ( sourceFile : SourceFile , symbol : Symbol ) : boolean {
551551 const sourceId = getNodeId ( sourceFile ) ;
552552 const symbolId = getSymbolId ( symbol ) ;
553- const seenSymbols = sourceFileToSeenSymbols [ sourceId ] || ( sourceFileToSeenSymbols [ sourceId ] = [ ] ) ;
553+ const seenSymbols = this . sourceFileToSeenSymbols [ sourceId ] || ( this . sourceFileToSeenSymbols [ sourceId ] = [ ] ) ;
554554 return ! seenSymbols [ symbolId ] && ( seenSymbols [ symbolId ] = true ) ;
555555 }
556556 }
0 commit comments