Skip to content

Commit 958a423

Browse files
Make classification cancellable.
1 parent 6db4faf commit 958a423

File tree

1 file changed

+26
-1
lines changed

1 file changed

+26
-1
lines changed

src/services/services.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5986,6 +5986,26 @@ namespace ts {
59865986
return convertClassifications(getEncodedSemanticClassifications(fileName, span));
59875987
}
59885988

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+
59896009
function getEncodedSemanticClassifications(fileName: string, span: TextSpan): Classifications {
59906010
synchronizeHostData();
59916011

@@ -6053,7 +6073,10 @@ namespace ts {
60536073
function processNode(node: Node) {
60546074
// Only walk into nodes that intersect the requested span.
60556075
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)) {
60576080
let identifier = <Identifier>node;
60586081

60596082
// Only bother calling into the typechecker if this is an identifier that
@@ -6405,6 +6428,8 @@ namespace ts {
64056428

64066429
// Ignore nodes that don't intersect the original span to classify.
64076430
if (textSpanIntersectsWith(span, element.getFullStart(), element.getFullWidth())) {
6431+
checkForClassificationCancellation(element.kind);
6432+
64086433
let children = element.getChildren(sourceFile);
64096434
for (let child of children) {
64106435
if (isToken(child)) {

0 commit comments

Comments
 (0)