[479161]: Don’t allow fragments in assignments

This commit is contained in:
Sebastian Zarnekow 2015-10-07 20:50:01 +02:00
parent 319163fb7c
commit 1ad499f4db
3 changed files with 39 additions and 0 deletions

View file

@ -23,6 +23,7 @@ public enum TransformationErrorCode {
InvalidSupertype,
InvalidFeature,
InvalidFragmentOverride,
InvalidFragmentCall,
InvalidRuleOverride;
public String getFullyQualifiedCode() {

View file

@ -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<Boolean>() {

View file

@ -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 = '''