Don't consume nodes during calls to isListElement.

This commit is contained in:
Cyrus Najmabadi 2014-12-12 03:06:05 -08:00
parent e32d030144
commit 60c62e5b6b
2 changed files with 32 additions and 24 deletions

View file

@ -534,7 +534,7 @@ module ts {
return true;
}
else {
if (child.pos > position && position < child.end) {
if (child.pos < position && position < child.end) {
// Position in somewhere within this child. Search in it and
// stop searching in this array.
forEachChild(child, visitNode, visitArray);
@ -1616,7 +1616,7 @@ module ts {
while (!isListTerminator(kind)) {
if (isListElement(kind, /* inErrorRecovery */ false)) {
var element = <T>currentNode(kind) || parseElement();
var element = parseListElement(kind, parseElement);
result.push(element);
// test elements only if we are not already in strict mode
@ -1646,6 +1646,15 @@ module ts {
return result;
}
function parseListElement<T extends Node>(kind: ParsingContext, parseElement: () => T): T {
var node = currentNode(kind);
if (node) {
return <T>consumeNode(node);
}
return parseElement();
}
function currentNode(parsingContext: ParsingContext): Node {
// If there is an outstanding parse error that we've encountered, but not attached to
// some node, then we cannot get a node from the old source tree. This is because we
@ -1663,7 +1672,7 @@ module ts {
return undefined;
}
var node = syntaxCursor.currentNode(scanner.getTextPos());
var node = syntaxCursor.currentNode(scanner.getStartPos());
// Can't reuse a missing node.
if (isMissingNode(node)) {
@ -1686,7 +1695,8 @@ module ts {
// differently depending on what mode it is in.
//
// This also applies to all our other context flags as well.
if (node.parserContextFlags !== contextFlags) {
var nodeContextFlags = node.parserContextFlags || 0;
if (nodeContextFlags !== contextFlags) {
return undefined;
}
@ -1696,13 +1706,11 @@ module ts {
return undefined;
}
// It was valid. Let teh source know we're consuming this node, and pass to the list
// parser.
return consumeNode(node);
return node;
}
function consumeNode(node: Node) {
// Move the scanner so it is after the node we just consumed
// Move the scanner so it is after the node we just consumed.
scanner.setTextPos(node.end);
nextToken();
return node;
@ -1944,7 +1952,7 @@ module ts {
var commaStart = -1; // Meaning the previous token was not a comma
while (true) {
if (isListElement(kind, /* inErrorRecovery */ false)) {
result.push(<T>currentNode(kind) || parseElement());
result.push(parseListElement(kind, parseElement));
commaStart = scanner.getTokenPos();
if (parseOptional(SyntaxKind.CommaToken)) {
continue;

View file

@ -192,7 +192,7 @@ module ts {
var semicolonIndex = source.indexOf(";");
var newTextAndChange = withInsert(oldText, semicolonIndex, " + 1");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 8);
});
it('Deleting from method',() => {
@ -208,7 +208,7 @@ module ts {
var oldText = ScriptSnapshot.fromString(source);
var newTextAndChange = withDelete(oldText, index, "+ 1".length);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 8);
});
it('Regular expression 1',() => {
@ -228,7 +228,7 @@ module ts {
var oldText = ScriptSnapshot.fromString(source);
var newTextAndChange = withInsert(oldText, semicolonIndex, "/");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 4);
});
it('Comment 1',() => {
@ -266,7 +266,7 @@ module ts {
var oldText = ScriptSnapshot.fromString(source);
var newTextAndChange = withInsert(oldText, index, "*");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 4);
});
it('Parameter 1',() => {
@ -281,7 +281,7 @@ module ts {
var oldText = ScriptSnapshot.fromString(source);
var newTextAndChange = withInsert(oldText, semicolonIndex, " + 1");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 8);
});
it('Type member 1',() => {
@ -292,7 +292,7 @@ module ts {
var oldText = ScriptSnapshot.fromString(source);
var newTextAndChange = withInsert(oldText, index, "?");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 14);
});
it('Enum element 1',() => {
@ -303,7 +303,7 @@ module ts {
var oldText = ScriptSnapshot.fromString(source);
var newTextAndChange = withChange(oldText, index, 2, "+");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 21);
});
it('Strict mode 1',() => {
@ -600,7 +600,7 @@ module ts {
var index = source.lastIndexOf(";");
var newTextAndChange = withDelete(oldText, index, 1);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 4);
});
it('Edit after empty type parameter list',() => {
@ -634,7 +634,7 @@ var o2 = { set Foo(val:number) { } };";
var index = source.indexOf("set");
var newTextAndChange = withInsert(oldText, index, "public ");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 6);
});
it('Insert parameter ahead of parameter',() => {
@ -650,7 +650,7 @@ constructor(name) { }\
var index = source.indexOf("100");
var newTextAndChange = withInsert(oldText, index, "'1', ");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 5);
});
it('Insert declare modifier before module',() => {
@ -663,7 +663,7 @@ module m3 { }\
var index = 0;
var newTextAndChange = withInsert(oldText, index, "declare ");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 3);
});
it('Insert function above arrow function with comment',() => {
@ -719,7 +719,7 @@ module m3 { }\
var oldText = ScriptSnapshot.fromString(source);
var newTextAndChange = withInsert(oldText, 0, "");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 7);
});
it('Class to interface',() => {
@ -782,7 +782,7 @@ module m3 { }\
var oldText = ScriptSnapshot.fromString(source);
var newTextAndChange = withChange(oldText, 0, "class".length, "interface");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 18);
});
it('Moving index signatures from interface to class',() => {
@ -791,7 +791,7 @@ module m3 { }\
var oldText = ScriptSnapshot.fromString(source);
var newTextAndChange = withChange(oldText, 0, "interface".length, "class");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 18);
});
it('Moving accessors from class to object literal',() => {
@ -809,7 +809,7 @@ module m3 { }\
var oldText = ScriptSnapshot.fromString(source);
var newTextAndChange = withChange(oldText, 0, "var v =".length, "class C");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 16);
});
// Simulated typing tests.