[#16, partial-parser] On fully re-parse, keep the entry parser rule

When the partial parser does a full re-parse, it should use the same
entry parser rule that has been used during the last parse.

see https://github.com/eclipse/xtext-core/issues/16

Signed-off-by: Moritz Eysholdt <moritz.eysholdt@typefox.io>
This commit is contained in:
Moritz Eysholdt 2016-07-28 10:01:21 +02:00
parent 07d38dd13b
commit 927d574d96
3 changed files with 46 additions and 1 deletions

View file

@ -12,6 +12,7 @@ import java.io.StringReader;
import java.util.Iterator;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.xtext.ParserRule;
import org.eclipse.xtext.XtextStandaloneSetup;
import org.eclipse.xtext.nodemodel.BidiTreeIterator;
import org.eclipse.xtext.nodemodel.ICompositeNode;
@ -23,7 +24,10 @@ import org.eclipse.xtext.serializer.impl.Serializer;
import org.eclipse.xtext.testlanguages.LookaheadTestLanguageStandaloneSetup;
import org.eclipse.xtext.testlanguages.PartialParserTestLanguageStandaloneSetup;
import org.eclipse.xtext.testlanguages.ReferenceGrammarTestLanguageStandaloneSetup;
import org.eclipse.xtext.testlanguages.ReferenceGrammarTestLanguageStandaloneSetupGenerated;
import org.eclipse.xtext.testlanguages.SimpleExpressionsTestLanguageStandaloneSetup;
import org.eclipse.xtext.testlanguages.services.ReferenceGrammarTestLanguageGrammarAccess;
import org.eclipse.xtext.testlanguages.services.SimpleExpressionsTestLanguageGrammarAccess;
import org.junit.Test;
import com.google.common.collect.Iterables;
@ -409,5 +413,29 @@ public class PartialParserTest extends AbstractPartialParserTest {
resource.update(1, 2, "");
assertEquals("t", resource.getParseResult().getRootNode().getText());
}
@Test
public void preserveEntryParserRuleOnFullyReparse1() throws Exception {
with(ReferenceGrammarTestLanguageStandaloneSetupGenerated.class);
ParserRule rule = get(ReferenceGrammarTestLanguageGrammarAccess.class).getKindRule();
String model = "kind (Fritz 12)";
checkFullReparse(rule, model);
}
@Test
public void preserveEntryParserRuleOnFullyReparse2() throws Exception {
with(SimpleExpressionsTestLanguageStandaloneSetup.class);
ParserRule rule = get(SimpleExpressionsTestLanguageGrammarAccess.class).getMultiplicationRule();
String model = "1 * 2";
checkFullReparse(rule, model);
}
private void checkFullReparse(ParserRule rule, String model) {
IParseResult oldParseResult = getParser().parse(rule, new StringReader(model));
IParseResult partialParseResult = reparse(oldParseResult, 0, model.length(), " " + model + " ");
String oldNodeModel = NodeModelUtils.compactDump(oldParseResult.getRootNode(), false);
String partialNodeModel = NodeModelUtils.compactDump(partialParseResult.getRootNode(), false);
assertEquals(oldNodeModel, partialNodeModel);
}
}

View file

@ -427,5 +427,20 @@ public class NodeModelUtils extends InternalNodeModelUtils {
return builder.toString();
}
}
public static ParserRule getEntryParserRule(INode node) {
ICompositeNode root = node.getRootNode();
EObject ge1 = root.getGrammarElement();
if (ge1 instanceof ParserRule) {
return (ParserRule) ge1;
} else if (ge1 instanceof Action) {
INode firstChild = root.getFirstChild();
EObject ge2 = firstChild.getGrammarElement();
if (ge2 instanceof ParserRule) {
return (ParserRule) ge2;
}
}
throw new IllegalStateException("No Root Parser Rule found; The Node Model is broken.");
}
}

View file

@ -215,8 +215,10 @@ public class PartialParsingHelper implements IPartialParsingHelper {
protected IParseResult fullyReparse(IParser parser, IParseResult previousParseResult, ReplaceRegion replaceRegion) {
unloadSemanticObject(previousParseResult.getRootASTElement());
ICompositeNode node = previousParseResult.getRootNode();
ParserRule parserRule = NodeModelUtils.getEntryParserRule(node);
String reparseRegion = insertChangeIntoReplaceRegion(previousParseResult.getRootNode(), replaceRegion);
return parser.parse(new StringReader(reparseRegion));
return parser.parse(parserRule, new StringReader(reparseRegion));
}
public void unloadNode(INode node) {