From 73fd155426fb091c73465db3bba8254a2dc56c95 Mon Sep 17 00:00:00 2001 From: Christian Dietrich Date: Wed, 31 Aug 2016 13:50:18 +0200 Subject: [PATCH] [445175] Missing error message on invalid alternative assignments with cross references Signed-off-by: Christian Dietrich --- .../xtext/xtext/XtextValidationTest.java | 17 +++++++++++++++++ .../xtext/XtextConfigurableIssueCodes.java | 2 ++ .../org/eclipse/xtext/xtext/XtextValidator.java | 11 +++++++++++ 3 files changed, 30 insertions(+) diff --git a/org.eclipse.xtext.tests/src/org/eclipse/xtext/xtext/XtextValidationTest.java b/org.eclipse.xtext.tests/src/org/eclipse/xtext/xtext/XtextValidationTest.java index 8502b4f38..e5d9d6043 100644 --- a/org.eclipse.xtext.tests/src/org/eclipse/xtext/xtext/XtextValidationTest.java +++ b/org.eclipse.xtext.tests/src/org/eclipse/xtext/xtext/XtextValidationTest.java @@ -29,6 +29,7 @@ import org.eclipse.emf.ecore.util.EcoreValidator; import org.eclipse.xtext.AbstractMetamodelDeclaration; import org.eclipse.xtext.AbstractRule; import org.eclipse.xtext.Action; +import org.eclipse.xtext.Alternatives; import org.eclipse.xtext.Assignment; import org.eclipse.xtext.CompoundElement; import org.eclipse.xtext.CrossReference; @@ -1876,6 +1877,22 @@ public class XtextValidationTest extends AbstractValidationMessageAcceptingTestC messageAcceptor.validate(); } + + @Test public void testCrossReferenceNotInAlternatives() throws Exception { + String grammarAsText = + "grammar test with org.eclipse.xtext.common.Terminals\n" + + "generate test 'http://test'\n" + + "A: foo=([A|ID]|[A|STRING]);"; + Grammar grammar = (Grammar) getModel(grammarAsText); + XtextValidator validator = get(XtextValidator.class); + ValidatingMessageAcceptor messageAcceptor = new ValidatingMessageAcceptor(null, true, false); + Assignment assignment = (Assignment) grammar.getRules().get(0).getAlternatives(); + Alternatives alternatives = (Alternatives) assignment.getTerminal(); + messageAcceptor.expectedContext(alternatives); + configureValidator(validator, messageAcceptor, alternatives); + validator.checkCrossReferenceNotInAlternatives(alternatives); + messageAcceptor.validate(); + } public class ValidatingMessageAcceptor extends AbstractValidationMessageAcceptor { diff --git a/org.eclipse.xtext/src/org/eclipse/xtext/xtext/XtextConfigurableIssueCodes.java b/org.eclipse.xtext/src/org/eclipse/xtext/xtext/XtextConfigurableIssueCodes.java index db66bda02..c18348092 100644 --- a/org.eclipse.xtext/src/org/eclipse/xtext/xtext/XtextConfigurableIssueCodes.java +++ b/org.eclipse.xtext/src/org/eclipse/xtext/xtext/XtextConfigurableIssueCodes.java @@ -43,6 +43,7 @@ public class XtextConfigurableIssueCodes extends ConfigurableIssueCodesProvider public static final String DISCOURAGED_RULE_NAME = ISSUE_CODE_PREFIX + "DiscouragedName"; public static final String DUPLICATE_ENUM_LITERAL = ISSUE_CODE_PREFIX + "DuplicateEnumLiteral"; public static final String BIDIRECTIONAL_REFERENCE = ISSUE_CODE_PREFIX + "BidirectionalReference"; + public static final String CROSS_REFERENCE_IN_ALTERNATIVES = ISSUE_CODE_PREFIX + "CrossReferenceInAlternatives"; private Map issueCodes; @@ -65,6 +66,7 @@ public class XtextConfigurableIssueCodes extends ConfigurableIssueCodesProvider acceptor.accept(create(INVALID_HIDDEN_TOKEN, SeverityConverter.SEVERITY_ERROR)); acceptor.accept(create(INVALID_HIDDEN_TOKEN_FRAGMENT, SeverityConverter.SEVERITY_ERROR)); acceptor.accept(create(INVALID_PACKAGE_REFERENCE_INHERITED, SeverityConverter.SEVERITY_ERROR)); + acceptor.accept(create(CROSS_REFERENCE_IN_ALTERNATIVES, SeverityConverter.SEVERITY_ERROR)); acceptor.accept(create(INVALID_METAMODEL_NAME, SeverityConverter.SEVERITY_WARNING)); acceptor.accept(create(INVALID_PACKAGE_REFERENCE_EXTERNAL, SeverityConverter.SEVERITY_WARNING)); diff --git a/org.eclipse.xtext/src/org/eclipse/xtext/xtext/XtextValidator.java b/org.eclipse.xtext/src/org/eclipse/xtext/xtext/XtextValidator.java index 5ba0ae1b3..745da4934 100644 --- a/org.eclipse.xtext/src/org/eclipse/xtext/xtext/XtextValidator.java +++ b/org.eclipse.xtext/src/org/eclipse/xtext/xtext/XtextValidator.java @@ -81,6 +81,7 @@ import org.eclipse.xtext.validation.AbstractDeclarativeValidator; import org.eclipse.xtext.validation.AbstractValidationMessageAcceptor; import org.eclipse.xtext.validation.Check; import org.eclipse.xtext.validation.ValidationMessageAcceptor; +import org.eclipse.xtext.xbase.lib.IterableExtensions; import org.eclipse.xtext.xtext.ecoreInference.SourceAdapter; import com.google.common.base.Function; @@ -1133,6 +1134,16 @@ public class XtextValidator extends AbstractDeclarativeValidator { checkTypeIsEClass(reference.getType()); } + @Check + public void checkCrossReferenceNotInAlternatives(Alternatives alternatives) { + int numOfCrossRefs = IterableExtensions.size(IterableExtensions.filter(alternatives.getElements(), CrossReference.class)); + if (numOfCrossRefs > 1) { + String errorMessage = "Cross references using the pattern 'feature=([SomeClass|ID] | [SomeClass|STRING])' are not allowed." + + " Use the pattern '(feature=[SomeClass|ID] | feature=[SomeClass|STRING])' instead."; + error(errorMessage, alternatives, null, ValidationMessageAcceptor.INSIGNIFICANT_INDEX, CROSS_REFERENCE_IN_ALTERNATIVES); + } + } + private void checkTypeIsEClass(TypeRef type) { if (type != null) { EClassifier classifier = type.getClassifier();