From 1ad499f4db8aab2820773ac8aecdd30726eef895 Mon Sep 17 00:00:00 2001 From: Sebastian Zarnekow Date: Wed, 7 Oct 2015 20:50:01 +0200 Subject: [PATCH] =?UTF-8?q?[479161]:=20Don=E2=80=99t=20allow=20fragments?= =?UTF-8?q?=20in=20assignments?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TransformationErrorCode.java | 1 + .../Xtext2EcoreInterpretationContext.java | 12 +++++++++ .../Xtext2EcoreTransformerTest.xtend | 26 +++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/plugins/org.eclipse.xtext/src/org/eclipse/xtext/xtext/ecoreInference/TransformationErrorCode.java b/plugins/org.eclipse.xtext/src/org/eclipse/xtext/xtext/ecoreInference/TransformationErrorCode.java index 6b2d71af8..8a0970674 100644 --- a/plugins/org.eclipse.xtext/src/org/eclipse/xtext/xtext/ecoreInference/TransformationErrorCode.java +++ b/plugins/org.eclipse.xtext/src/org/eclipse/xtext/xtext/ecoreInference/TransformationErrorCode.java @@ -23,6 +23,7 @@ public enum TransformationErrorCode { InvalidSupertype, InvalidFeature, InvalidFragmentOverride, + InvalidFragmentCall, InvalidRuleOverride; public String getFullyQualifiedCode() { diff --git a/plugins/org.eclipse.xtext/src/org/eclipse/xtext/xtext/ecoreInference/Xtext2EcoreInterpretationContext.java b/plugins/org.eclipse.xtext/src/org/eclipse/xtext/xtext/ecoreInference/Xtext2EcoreInterpretationContext.java index ecabb93e8..a437c5d15 100644 --- a/plugins/org.eclipse.xtext/src/org/eclipse/xtext/xtext/ecoreInference/Xtext2EcoreInterpretationContext.java +++ b/plugins/org.eclipse.xtext/src/org/eclipse/xtext/xtext/ecoreInference/Xtext2EcoreInterpretationContext.java @@ -87,6 +87,7 @@ public class Xtext2EcoreInterpretationContext { if (terminal == null) { throw new TransformationException(TransformationErrorCode.NoSuchTypeAvailable, "Cannot derive type from incomplete assignment.", assignment); } + checkNoFragmentRuleCall(terminal); EClassifier type = getTerminalType(terminal); isContainment = isContainmentAssignment(assignment); featureTypeInfo = getEClassifierInfoOrThrowException(type, assignment); @@ -94,6 +95,17 @@ public class Xtext2EcoreInterpretationContext { addFeature(featureName, featureTypeInfo, isMultivalue, isContainment, assignment); } + private void checkNoFragmentRuleCall(AbstractElement terminal) throws TransformationException { + if (GrammarUtil.isEObjectFragmentRuleCall(terminal)) { + throw new TransformationException(TransformationErrorCode.InvalidFragmentCall, "Cannot call a fragment from an assignment", terminal); + } + if (terminal instanceof Alternatives) { + for(AbstractElement child: ((Alternatives) terminal).getElements()) { + checkNoFragmentRuleCall(child); + } + } + } + public boolean isContainmentAssignment(Assignment assignment) { // TODO throw TransformationException in case of unexpected terminal return new XtextSwitch() { diff --git a/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/xtext/ecoreInference/Xtext2EcoreTransformerTest.xtend b/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/xtext/ecoreInference/Xtext2EcoreTransformerTest.xtend index fd92a9b67..d1206eac0 100644 --- a/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/xtext/ecoreInference/Xtext2EcoreTransformerTest.xtend +++ b/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/xtext/ecoreInference/Xtext2EcoreTransformerTest.xtend @@ -351,6 +351,32 @@ class Xtext2EcoreTransformerTest extends AbstractXtextTests { assertTrue(bottomType.superTypes.contains(middleType1)) assertTrue(bottomType.superTypes.contains(middleType2)) } + + @Test def void testParserRuleFragment_08() throws Exception { + val grammar = ''' + grammar test with org.eclipse.xtext.common.Terminals + generate test 'http://test' + RuleA: feature=Fragment; + fragment Fragment * Fragment: name=ID; + ''' + errorAcceptorMock.acceptError(TransformationErrorCode.InvalidFragmentCall, + TestErrorAcceptor.ANY_STRING, TestErrorAcceptor.ANY_EOBJECT) + var EPackage result = getEPackageFromGrammar(grammar, 2) + assertEquals(1, result.EClassifiers.size) + } + + @Test def void testParserRuleFragment_09() throws Exception { + val grammar = ''' + grammar test with org.eclipse.xtext.common.Terminals + generate test 'http://test' + RuleA: feature=(Fragment|Fragment); + fragment Fragment returns Fragment: name=ID; + ''' + errorAcceptorMock.acceptError(TransformationErrorCode.InvalidFragmentCall, + TestErrorAcceptor.ANY_STRING, TestErrorAcceptor.ANY_EOBJECT) + var EPackage result = getEPackageFromGrammar(grammar, 1) + assertEquals(2, result.EClassifiers.size) + } @Test def void testTypesOfImplicitSuperGrammar() throws Exception { val xtextGrammar = '''