namespace ts . NavigateTo { interface RawNavigateToItem { readonly name : string ; readonly fileName : string ; readonly matchKind : PatternMatchKind ; readonly isCaseSensitive : boolean ; readonly declaration : Declaration ; } export function getNavigateToItems ( sourceFiles , checker , cancellationToken , searchValue , maxResultCount , excludeDtsFiles ) { const patternMatcher = createPatternMatcher ( searchValue ) ; if ( ! patternMatcher ) return emptyArray ; const rawItems = [ ] ; for ( const sourceFile of sourceFiles ) { cancellationToken . throwIfCancellationRequested ( ) ; if ( excludeDtsFiles && sourceFile . isDeclarationFile ) { continue ; } sourceFile . getNamedDeclarations ( ) . forEach ( ( declarations , name ) => { getItemsFromNamedDeclaration ( patternMatcher , name , declarations , checker , sourceFile . fileName , rawItems ) ; } ) ; } rawItems . sort ( compareNavigateToItems ) ; return ( maxResultCount === undefined ? rawItems : rawItems . slice ( 0 , maxResultCount ) ) . map ( createNavigateToItem ) ; } function getItemsFromNamedDeclaration ( patternMatcher , name , declarations , checker , fileName , rawItems ) { const match = patternMatcher . getMatchForLastSegmentOfPattern ( name ) ; if ( ! match ) { return ; } for ( const declaration of declarations ) { if ( ! shouldKeepItem ( declaration , checker ) ) continue ; if ( patternMatcher . patternContainsDots ) { const fullMatch = patternMatcher . getFullMatch ( getContainers ( declaration ) , name ) ; if ( fullMatch ) { rawItems . push ( { name , fileName , matchKind : fullMatch . kind , isCaseSensitive : fullMatch . isCaseSensitive , declaration } ) ; } } else { rawItems . push ( { name , fileName , matchKind : match . kind , isCaseSensitive : match . isCaseSensitive , declaration } ) ; } } } function shouldKeepItem ( declaration , checker ) { switch ( declaration . kind ) { case SyntaxKind . ImportClause : case SyntaxKind . ImportSpecifier : case SyntaxKind . ImportEqualsDeclaration : const importer = checker . getSymbolAtLocation ( ( declaration as ImportClause | ImportSpecifier | ImportEqualsDeclaration ) . name ! ) ! ; const imported = checker . getAliasedSymbol ( importer ) ; return importer . escapedName !== imported . escapedName ; default : return true ; } } function tryAddSingleDeclarationName ( declaration , containers ) { const name = getNameOfDeclaration ( declaration ) ; return ! ! name && ( pushLiteral ( name , containers ) || name . kind === SyntaxKind . ComputedPropertyName && tryAddComputedPropertyName ( name . expression , containers ) ) ; } function tryAddComputedPropertyName ( expression , containers ) { return pushLiteral ( expression , containers ) || isPropertyAccessExpression ( expression ) && ( containers . push ( expression . name . text ) , true ) && tryAddComputedPropertyName ( expression . expression , containers ) ; } function pushLiteral ( node , containers ) { return isPropertyNameLiteral ( node ) && ( containers . push ( getTextOfIdentifierOrLiteral ( node ) ) , true ) ; } function getContainers ( declaration ) { const containers = [ ] ; const name = getNameOfDeclaration ( declaration ) ; if ( name && name . kind === SyntaxKind . ComputedPropertyName && ! tryAddComputedPropertyName ( name . expression , containers ) ) { return emptyArray ; } containers . shift ( ) ; let container = getContainerNode ( declaration ) ; while ( container ) { if ( ! tryAddSingleDeclarationName ( container , containers ) ) { return emptyArray ; } container = getContainerNode ( container ) ; } return containers . reverse ( ) ; } function compareNavigateToItems ( i1 , i2 ) { return compareValues ( i1 . matchKind , i2 . matchKind ) || compareStringsCaseSensitiveUI ( i1 . name , i2 . name ) ; } function createNavigateToItem ( rawItem ) { const declaration = rawItem . declaration ; const container = getContainerNode ( declaration ) ; const containerName = container && getNameOfDeclaration ( container ) ; return { name : rawItem . name , kind : getNodeKind ( declaration ) , kindModifiers : getNodeModifiers ( declaration ) , matchKind : PatternMatchKind [ rawItem . matchKind ] as keyof typeof PatternMatchKind , isCaseSensitive : rawItem . isCaseSensitive , fileName : rawItem . fileName , textSpan : createTextSpanFromNode ( declaration ) , containerName : containerName ? ( containerName as Identifier ) . text : "" , containerKind : containerName ? getNodeKind ( container ! ) : ScriptElementKind . unknown , } ; } }