fixed bug that identical paths are deleted in the original ecore objects

This commit is contained in:
overflowerror 2021-12-02 17:26:39 +01:00
parent 3f665c0d39
commit 8e1fa55e7d
2 changed files with 26 additions and 1 deletions

View file

@ -11,6 +11,7 @@ package org.eclipse.xtext.xtext.generator.hoisting;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.xml.type.XMLTypePackage;
import org.eclipse.xtext.AbstractRule;
import org.eclipse.xtext.Alternatives;
import org.eclipse.xtext.Grammar;
import org.eclipse.xtext.XtextStandaloneSetup;
import org.eclipse.xtext.resource.XtextResource;
@ -386,6 +387,30 @@ public class HoistingProcessorTest extends AbstractXtextTests {
assertEquals("((" + getSyntaxForKeywordToken("j", 10) + " || ((p0) || (p1))) && (" + getSyntaxForKeywordToken("k", 10) + " || (p2)))", guard.render());
}
@Test
public void testAlternativeIdenticalPaths_bugChangesToEcoreOjects_expectNoChange() throws Exception {
// @formatter:off
String model =
// boundary check: the 10th token should be handled correctly
MODEL_PREAMBLE +
"S: {S} $$ p0 $$?=> 'a' \n" +
" | {S} $$ p1 $$?=> 'a' \n" +
" | {S} $$ p2 $$?=> 'b' ;";
// @formatter:off
XtextResource resource = getResourceFromString(model);
Grammar grammar = ((Grammar) resource.getContents().get(0));
AbstractRule rule = getRule(grammar, "S");
HoistingGuard guard = hoistingProcessor.findHoistingGuard(rule.getAlternatives());
assertFalse(guard.isTrivial());
assertTrue(guard.hasTerminal());
assertEquals("((" + getSyntaxForKeywordToken("a", 1) + " || ((p0) || (p1))) && (" + getSyntaxForKeywordToken("b", 1) + " || (p2)))", guard.render());
// number of elements in Alternatives object has to stay the same
// even though the identical paths are collapsed during the hoisting process
assertEquals(3, ((Alternatives) rule.getAlternatives()).getElements().size());
}
@Test
public void testAlternativeUnguarded() throws Exception {
// @formatter:off

View file

@ -72,7 +72,7 @@ public class HoistingProcessor {
private HoistingGuard findGuardForAlternatives(Alternatives alternatives, AbstractRule currentRule) {
log.info("find guard for alternative");
List<AbstractElement> paths = alternatives.getElements();
List<AbstractElement> paths = new ArrayList<>(alternatives.getElements());
List<MergedPathGuard> guards = paths.stream()
.map(p -> findGuardForElement(p, currentRule))
.map(MergedPathGuard::new)