@@ -488,89 +488,71 @@ namespace ts {
488
488
489
489
/* @internal */
490
490
export function getEncodedSemanticClassifications ( typeChecker : TypeChecker , cancellationToken : CancellationToken , sourceFile : SourceFile , classifiableNames : UnderscoreEscapedMap < true > , span : TextSpan ) : Classifications {
491
- const result : number [ ] = [ ] ;
492
- processNode ( sourceFile ) ;
493
-
494
- return { spans : result , endOfLineState : EndOfLineState . None } ;
495
-
496
- function pushClassification ( start : number , length : number , type : ClassificationType ) {
497
- result . push ( start ) ;
498
- result . push ( length ) ;
499
- result . push ( type ) ;
500
- }
501
-
502
- function classifySymbol ( symbol : Symbol , meaningAtPosition : SemanticMeaning ) : ClassificationType {
503
- const flags = symbol . getFlags ( ) ;
504
- if ( ( flags & SymbolFlags . Classifiable ) === SymbolFlags . None ) {
491
+ const spans : number [ ] = [ ] ;
492
+ sourceFile . forEachChild ( function cb ( node : Node ) : void {
493
+ // Only walk into nodes that intersect the requested span.
494
+ if ( ! node || ! textSpanIntersectsWith ( span , node . pos , node . getFullWidth ( ) ) ) {
505
495
return ;
506
496
}
507
497
508
- if ( flags & SymbolFlags . Class ) {
509
- return ClassificationType . className ;
510
- }
511
- else if ( flags & SymbolFlags . Enum ) {
512
- return ClassificationType . enumName ;
513
- }
514
- else if ( flags & SymbolFlags . TypeAlias ) {
515
- return ClassificationType . typeAliasName ;
516
- }
517
- else if ( meaningAtPosition & SemanticMeaning . Type ) {
518
- if ( flags & SymbolFlags . Interface ) {
519
- return ClassificationType . interfaceName ;
520
- }
521
- else if ( flags & SymbolFlags . TypeParameter ) {
522
- return ClassificationType . typeParameterName ;
523
- }
524
- }
525
- else if ( flags & SymbolFlags . Module ) {
526
- // Only classify a module as such if
527
- // - It appears in a namespace context.
528
- // - There exists a module declaration which actually impacts the value side.
529
- if ( meaningAtPosition & SemanticMeaning . Namespace ||
530
- ( meaningAtPosition & SemanticMeaning . Value && hasValueSideModule ( symbol ) ) ) {
531
- return ClassificationType . moduleName ;
498
+ checkForClassificationCancellation ( cancellationToken , node . kind ) ;
499
+ // Only bother calling into the typechecker if this is an identifier that
500
+ // could possibly resolve to a type name. This makes classification run
501
+ // in a third of the time it would normally take.
502
+ if ( isIdentifier ( node ) && ! nodeIsMissing ( node ) && classifiableNames . has ( node . escapedText ) ) {
503
+ const symbol = typeChecker . getSymbolAtLocation ( node ) ;
504
+ const type = symbol && classifySymbol ( symbol , getMeaningFromLocation ( node ) , typeChecker ) ;
505
+ if ( type ) {
506
+ pushClassification ( node . getStart ( sourceFile ) , node . getEnd ( ) , type ) ;
532
507
}
533
508
}
534
509
535
- return undefined ;
510
+ node . forEachChild ( cb ) ;
511
+ } ) ;
512
+ return { spans, endOfLineState : EndOfLineState . None } ;
536
513
537
- /**
538
- * Returns true if there exists a module that introduces entities on the value side.
539
- */
540
- function hasValueSideModule ( symbol : Symbol ) : boolean {
541
- return forEach ( symbol . declarations , declaration => {
542
- return declaration . kind === SyntaxKind . ModuleDeclaration &&
543
- getModuleInstanceState ( declaration ) === ModuleInstanceState . Instantiated ;
544
- } ) ;
545
- }
514
+ function pushClassification ( start : number , end : number , type : ClassificationType ) : void {
515
+ spans . push ( start ) ;
516
+ spans . push ( end - start ) ;
517
+ spans . push ( type ) ;
546
518
}
519
+ }
547
520
548
- function processNode ( node : Node ) {
549
- // Only walk into nodes that intersect the requested span.
550
- if ( node && textSpanIntersectsWith ( span , node . getFullStart ( ) , node . getFullWidth ( ) ) ) {
551
- const kind = node . kind ;
552
- checkForClassificationCancellation ( cancellationToken , kind ) ;
553
-
554
- if ( kind === SyntaxKind . Identifier && ! nodeIsMissing ( node ) ) {
555
- const identifier = < Identifier > node ;
556
-
557
- // Only bother calling into the typechecker if this is an identifier that
558
- // could possibly resolve to a type name. This makes classification run
559
- // in a third of the time it would normally take.
560
- if ( classifiableNames . has ( identifier . escapedText ) ) {
561
- const symbol = typeChecker . getSymbolAtLocation ( node ) ;
562
- if ( symbol ) {
563
- const type = classifySymbol ( symbol , getMeaningFromLocation ( node ) ) ;
564
- if ( type ) {
565
- pushClassification ( node . getStart ( ) , node . getWidth ( ) , type ) ;
566
- }
567
- }
568
- }
569
- }
570
-
571
- forEachChild ( node , processNode ) ;
572
- }
521
+ function classifySymbol ( symbol : Symbol , meaningAtPosition : SemanticMeaning , checker : TypeChecker ) : ClassificationType | undefined {
522
+ const flags = symbol . getFlags ( ) ;
523
+ if ( ( flags & SymbolFlags . Classifiable ) === SymbolFlags . None ) {
524
+ return undefined ;
525
+ }
526
+ else if ( flags & SymbolFlags . Class ) {
527
+ return ClassificationType . className ;
573
528
}
529
+ else if ( flags & SymbolFlags . Enum ) {
530
+ return ClassificationType . enumName ;
531
+ }
532
+ else if ( flags & SymbolFlags . TypeAlias ) {
533
+ return ClassificationType . typeAliasName ;
534
+ }
535
+ else if ( flags & SymbolFlags . Module ) {
536
+ // Only classify a module as such if
537
+ // - It appears in a namespace context.
538
+ // - There exists a module declaration which actually impacts the value side.
539
+ return meaningAtPosition & SemanticMeaning . Namespace || meaningAtPosition & SemanticMeaning . Value && hasValueSideModule ( symbol ) ? ClassificationType . moduleName : undefined ;
540
+ }
541
+ else if ( flags & SymbolFlags . Alias ) {
542
+ return classifySymbol ( checker . getAliasedSymbol ( symbol ) , meaningAtPosition , checker ) ;
543
+ }
544
+ else if ( meaningAtPosition & SemanticMeaning . Type ) {
545
+ return flags & SymbolFlags . Interface ? ClassificationType . interfaceName : flags & SymbolFlags . TypeParameter ? ClassificationType . typeParameterName : undefined ;
546
+ }
547
+ else {
548
+ return undefined ;
549
+ }
550
+ }
551
+
552
+ /** Returns true if there exists a module that introduces entities on the value side. */
553
+ function hasValueSideModule ( symbol : Symbol ) : boolean {
554
+ return some ( symbol . declarations , declaration =>
555
+ isModuleDeclaration ( declaration ) && getModuleInstanceState ( declaration ) === ModuleInstanceState . Instantiated ) ;
574
556
}
575
557
576
558
function getClassificationTypeName ( type : ClassificationType ) : ClassificationTypeNames {
0 commit comments