Skip to content

Commit 2dd10bd

Browse files
authored
Reuse unchanged ambient declarations in incremental parsing (microsoft#32849)
* Incrementally parse unchanged ambient declarations * Re-parse modifiers and decorators so as not to skip errors * Revert unnecessary change * Undo the test change that was changed 2 years ago
1 parent ae66fbe commit 2dd10bd

File tree

2 files changed

+24
-3
lines changed

2 files changed

+24
-3
lines changed

src/compiler/parser.ts

+22-1
Original file line numberDiff line numberDiff line change
@@ -5492,10 +5492,22 @@ namespace ts {
54925492
}
54935493

54945494
function parseDeclaration(): Statement {
5495+
const modifiers = lookAhead(() => (parseDecorators(), parseModifiers()));
5496+
// `parseListElement` attempted to get the reused node at this position,
5497+
// but the ambient context flag was not yet set, so the node appeared
5498+
// not reusable in that context.
5499+
const isAmbient = some(modifiers, isDeclareModifier);
5500+
if (isAmbient) {
5501+
const node = tryReuseAmbientDeclaration();
5502+
if (node) {
5503+
return node;
5504+
}
5505+
}
5506+
54955507
const node = <Statement>createNodeWithJSDoc(SyntaxKind.Unknown);
54965508
node.decorators = parseDecorators();
54975509
node.modifiers = parseModifiers();
5498-
if (some(node.modifiers, isDeclareModifier)) {
5510+
if (isAmbient) {
54995511
for (const m of node.modifiers!) {
55005512
m.flags |= NodeFlags.Ambient;
55015513
}
@@ -5506,6 +5518,15 @@ namespace ts {
55065518
}
55075519
}
55085520

5521+
function tryReuseAmbientDeclaration(): Statement | undefined {
5522+
return doInsideOfContext(NodeFlags.Ambient, () => {
5523+
const node = currentNode(parsingContext);
5524+
if (node) {
5525+
return consumeNode(node) as Statement;
5526+
}
5527+
});
5528+
}
5529+
55095530
function parseDeclarationWorker(node: Statement): Statement {
55105531
switch (token()) {
55115532
case SyntaxKind.VarKeyword:

src/testRunner/unittests/incrementalParser.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -671,7 +671,7 @@ module m3 { }\
671671
const oldText = ScriptSnapshot.fromString(source);
672672
const newTextAndChange = withInsert(oldText, 0, "{");
673673

674-
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 4);
674+
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 9);
675675
});
676676

677677
it("Removing block around function declarations", () => {
@@ -680,7 +680,7 @@ module m3 { }\
680680
const oldText = ScriptSnapshot.fromString(source);
681681
const newTextAndChange = withDelete(oldText, 0, "{".length);
682682

683-
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 4);
683+
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 9);
684684
});
685685

686686
it("Moving methods from class to object literal", () => {

0 commit comments

Comments
 (0)