Reuse unchanged ambient declarations in incremental parsing (#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
This commit is contained in:
Andrew Branch 2019-08-15 10:05:21 -07:00 committed by GitHub
parent ae66fbeab9
commit 2dd10bdfa1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 24 additions and 3 deletions

View file

@ -5492,10 +5492,22 @@ namespace ts {
}
function parseDeclaration(): Statement {
const modifiers = lookAhead(() => (parseDecorators(), parseModifiers()));
// `parseListElement` attempted to get the reused node at this position,
// but the ambient context flag was not yet set, so the node appeared
// not reusable in that context.
const isAmbient = some(modifiers, isDeclareModifier);
if (isAmbient) {
const node = tryReuseAmbientDeclaration();
if (node) {
return node;
}
}
const node = <Statement>createNodeWithJSDoc(SyntaxKind.Unknown);
node.decorators = parseDecorators();
node.modifiers = parseModifiers();
if (some(node.modifiers, isDeclareModifier)) {
if (isAmbient) {
for (const m of node.modifiers!) {
m.flags |= NodeFlags.Ambient;
}
@ -5506,6 +5518,15 @@ namespace ts {
}
}
function tryReuseAmbientDeclaration(): Statement | undefined {
return doInsideOfContext(NodeFlags.Ambient, () => {
const node = currentNode(parsingContext);
if (node) {
return consumeNode(node) as Statement;
}
});
}
function parseDeclarationWorker(node: Statement): Statement {
switch (token()) {
case SyntaxKind.VarKeyword:

View file

@ -671,7 +671,7 @@ module m3 { }\
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withInsert(oldText, 0, "{");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 4);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 9);
});
it("Removing block around function declarations", () => {
@ -680,7 +680,7 @@ module m3 { }\
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withDelete(oldText, 0, "{".length);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 4);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 9);
});
it("Moving methods from class to object literal", () => {