@@ -5986,6 +5986,26 @@ namespace ts {
5986
5986
return convertClassifications ( getEncodedSemanticClassifications ( fileName , span ) ) ;
5987
5987
}
5988
5988
5989
+ function checkForClassificationCancellation ( kind : SyntaxKind ) {
5990
+ // We don't want to actually call back into our host on every node to find out if we've
5991
+ // been canceled. That would be an enormous amount of chattyness, along with the all
5992
+ // the overhead of marshalling the data to/from the host. So instead we pick a few
5993
+ // reasonable node kinds to bother checking on. These node kinds represent high level
5994
+ // constructs that we would expect to see commonly, but just at a far less frequent
5995
+ // interval.
5996
+ //
5997
+ // For example, in checker.ts (around 750k) we only have around 600 of these constructs.
5998
+ // That means we're calling back into the host around every 1.2k of the file we process.
5999
+ // Lib.d.ts has similar numbers.
6000
+ switch ( kind ) {
6001
+ case SyntaxKind . ModuleDeclaration :
6002
+ case SyntaxKind . ClassDeclaration :
6003
+ case SyntaxKind . InterfaceDeclaration :
6004
+ case SyntaxKind . FunctionDeclaration :
6005
+ cancellationToken . throwIfCancellationRequested ( ) ;
6006
+ }
6007
+ }
6008
+
5989
6009
function getEncodedSemanticClassifications ( fileName : string , span : TextSpan ) : Classifications {
5990
6010
synchronizeHostData ( ) ;
5991
6011
@@ -6053,7 +6073,10 @@ namespace ts {
6053
6073
function processNode ( node : Node ) {
6054
6074
// Only walk into nodes that intersect the requested span.
6055
6075
if ( node && textSpanIntersectsWith ( span , node . getFullStart ( ) , node . getFullWidth ( ) ) ) {
6056
- if ( node . kind === SyntaxKind . Identifier && ! nodeIsMissing ( node ) ) {
6076
+ let kind = node . kind ;
6077
+ checkForClassificationCancellation ( kind ) ;
6078
+
6079
+ if ( kind === SyntaxKind . Identifier && ! nodeIsMissing ( node ) ) {
6057
6080
let identifier = < Identifier > node ;
6058
6081
6059
6082
// Only bother calling into the typechecker if this is an identifier that
@@ -6405,6 +6428,8 @@ namespace ts {
6405
6428
6406
6429
// Ignore nodes that don't intersect the original span to classify.
6407
6430
if ( textSpanIntersectsWith ( span , element . getFullStart ( ) , element . getFullWidth ( ) ) ) {
6431
+ checkForClassificationCancellation ( element . kind ) ;
6432
+
6408
6433
let children = element . getChildren ( sourceFile ) ;
6409
6434
for ( let child of children ) {
6410
6435
if ( isToken ( child ) ) {
0 commit comments