Allow multiple annotations on Terminal but restrict it to a well defined set.

This commit is contained in:
Holger Schill 2018-03-26 16:15:53 +02:00
parent d6f4ecc4c1
commit 47effb3ff1
11 changed files with 259 additions and 272 deletions
org.eclipse.xtext.tests/src/org/eclipse/xtext/xtext
org.eclipse.xtext.xtext.ide/src-gen/org/eclipse/xtext/xtext/ide/contentassist/antlr/internal
org.eclipse.xtext

View file

@ -256,6 +256,31 @@ public class XtextValidationTest extends AbstractValidationMessageAcceptingTestC
assertEquals("diag.isWarning", diag.getSeverity(), Diagnostic.WARNING);
}
@Test public void testTerminalAnnotation() throws Exception {
Resource resource = getResourceFromString("grammar org.xtext.Supergrammar with org.eclipse.xtext.common.Terminals\n" +
"generate supergrammar \"http://org.xtext.supergrammar\"\n" +
"Rule: name=ID;\n"+
"@Deprecated\n"+
"terminal TERMINAL: ID;");
Diagnostic diag = Diagnostician.INSTANCE.validate(resource.getContents().get(0));
List<Diagnostic> issues = diag.getChildren();
assertEquals(issues.toString(), 1, issues.size());
assertEquals("TerminalRule cannot be deprecated!", issues.get(0).getMessage());
assertEquals("diag.isError", diag.getSeverity(), Diagnostic.ERROR);
}
@Test public void testTerminalAnnotation_1() throws Exception {
Resource resource = getResourceFromString("grammar org.xtext.Supergrammar with org.eclipse.xtext.common.Terminals\n" +
"generate supergrammar \"http://org.xtext.supergrammar\"\n" +
"Rule: name=ID;\n"+
"@Exported\n"+
"terminal TERMINAL: ID;");
Diagnostic diag = Diagnostician.INSTANCE.validate(resource.getContents().get(0));
List<Diagnostic> issues = diag.getChildren();
assertEquals(issues.toString(), 1, issues.size());
assertEquals("TerminalRule cannot be exported!", issues.get(0).getMessage());
assertEquals("diag.isError", diag.getSeverity(), Diagnostic.ERROR);
}
@Test public void testMissingArgument() throws Exception {
XtextResource resource = getResourceFromString(

View file

@ -6846,7 +6846,7 @@ rule__TerminalRule__Group__0__Impl
:
(
{ before(grammarAccess.getTerminalRuleAccess().getAnnotationsAssignment_0()); }
(rule__TerminalRule__AnnotationsAssignment_0)?
(rule__TerminalRule__AnnotationsAssignment_0)*
{ after(grammarAccess.getTerminalRuleAccess().getAnnotationsAssignment_0()); }
)
;

View file

@ -4476,73 +4476,7 @@ public class InternalXtextParser extends AbstractInternalContentAssistParser {
try {
// InternalXtext.g:1473:1: ( ( ruleParserRule ) | ( ruleTerminalRule ) | ( ruleEnumRule ) )
int alt1=3;
switch ( input.LA(1) ) {
case 28:
{
int LA1_1 = input.LA(2);
if ( (LA1_1==RULE_ID) ) {
switch ( input.LA(3) ) {
case 43:
{
alt1=2;
}
break;
case 47:
{
alt1=3;
}
break;
case RULE_ID:
case 16:
case 17:
case 28:
case 49:
{
alt1=1;
}
break;
default:
NoViableAltException nvae =
new NoViableAltException("", 1, 5, input);
throw nvae;
}
}
else {
NoViableAltException nvae =
new NoViableAltException("", 1, 1, input);
throw nvae;
}
}
break;
case RULE_ID:
case 16:
case 17:
case 49:
{
alt1=1;
}
break;
case 43:
{
alt1=2;
}
break;
case 47:
{
alt1=3;
}
break;
default:
NoViableAltException nvae =
new NoViableAltException("", 1, 0, input);
throw nvae;
}
alt1 = dfa1.predict(input);
switch (alt1) {
case 1 :
// InternalXtext.g:1474:2: ( ruleParserRule )
@ -5316,13 +5250,6 @@ public class InternalXtextParser extends AbstractInternalContentAssistParser {
case 50:
{
switch ( input.LA(2) ) {
case RULE_ID:
case 16:
case 17:
{
alt11=5;
}
break;
case RULE_STRING:
{
alt11=4;
@ -5333,6 +5260,13 @@ public class InternalXtextParser extends AbstractInternalContentAssistParser {
alt11=6;
}
break;
case RULE_ID:
case 16:
case 17:
{
alt11=5;
}
break;
default:
NoViableAltException nvae =
new NoViableAltException("", 11, 4, input);
@ -21510,40 +21444,47 @@ public class InternalXtextParser extends AbstractInternalContentAssistParser {
// $ANTLR start "rule__TerminalRule__Group__0__Impl"
// InternalXtext.g:6842:1: rule__TerminalRule__Group__0__Impl : ( ( rule__TerminalRule__AnnotationsAssignment_0 )? ) ;
// InternalXtext.g:6842:1: rule__TerminalRule__Group__0__Impl : ( ( rule__TerminalRule__AnnotationsAssignment_0 )* ) ;
public final void rule__TerminalRule__Group__0__Impl() throws RecognitionException {
int stackSize = keepStackSize();
try {
// InternalXtext.g:6846:1: ( ( ( rule__TerminalRule__AnnotationsAssignment_0 )? ) )
// InternalXtext.g:6847:1: ( ( rule__TerminalRule__AnnotationsAssignment_0 )? )
// InternalXtext.g:6846:1: ( ( ( rule__TerminalRule__AnnotationsAssignment_0 )* ) )
// InternalXtext.g:6847:1: ( ( rule__TerminalRule__AnnotationsAssignment_0 )* )
{
// InternalXtext.g:6847:1: ( ( rule__TerminalRule__AnnotationsAssignment_0 )? )
// InternalXtext.g:6848:2: ( rule__TerminalRule__AnnotationsAssignment_0 )?
// InternalXtext.g:6847:1: ( ( rule__TerminalRule__AnnotationsAssignment_0 )* )
// InternalXtext.g:6848:2: ( rule__TerminalRule__AnnotationsAssignment_0 )*
{
before(grammarAccess.getTerminalRuleAccess().getAnnotationsAssignment_0());
// InternalXtext.g:6849:2: ( rule__TerminalRule__AnnotationsAssignment_0 )?
int alt67=2;
int LA67_0 = input.LA(1);
// InternalXtext.g:6849:2: ( rule__TerminalRule__AnnotationsAssignment_0 )*
loop67:
do {
int alt67=2;
int LA67_0 = input.LA(1);
if ( (LA67_0==28) ) {
alt67=1;
}
switch (alt67) {
case 1 :
// InternalXtext.g:6849:3: rule__TerminalRule__AnnotationsAssignment_0
{
pushFollow(FollowSets000.FOLLOW_2);
rule__TerminalRule__AnnotationsAssignment_0();
state._fsp--;
if ( (LA67_0==28) ) {
alt67=1;
}
}
break;
switch (alt67) {
case 1 :
// InternalXtext.g:6849:3: rule__TerminalRule__AnnotationsAssignment_0
{
pushFollow(FollowSets000.FOLLOW_17);
rule__TerminalRule__AnnotationsAssignment_0();
}
state._fsp--;
}
break;
default :
break loop67;
}
} while (true);
after(grammarAccess.getTerminalRuleAccess().getAnnotationsAssignment_0());
@ -30148,14 +30089,55 @@ public class InternalXtextParser extends AbstractInternalContentAssistParser {
// Delegated rules
protected DFA1 dfa1 = new DFA1(this);
protected DFA8 dfa8 = new DFA8(this);
static final String dfa_1s = "\13\uffff";
static final String dfa_2s = "\3\uffff\3\6\1\uffff\3\6\1\uffff";
static final String dfa_3s = "\6\4\1\uffff\3\4\1\uffff";
static final String dfa_4s = "\1\62\2\26\3\62\1\uffff\3\62\1\uffff";
static final String dfa_5s = "\6\uffff\1\2\3\uffff\1\1";
static final String dfa_6s = "\13\uffff}>";
static final String[] dfa_7s = {
static final String dfa_1s = "\10\uffff";
static final String dfa_2s = "\2\4\3\uffff\3\4";
static final String dfa_3s = "\1\61\1\4\3\uffff\1\61\1\4\1\61";
static final String dfa_4s = "\2\uffff\1\1\1\2\1\3\3\uffff";
static final String dfa_5s = "\10\uffff}>";
static final String[] dfa_6s = {
"\1\2\13\uffff\2\2\12\uffff\1\1\16\uffff\1\3\3\uffff\1\4\1\uffff\1\2",
"\1\5",
"",
"",
"",
"\1\2\13\uffff\2\2\12\uffff\1\6\16\uffff\1\3\3\uffff\1\4\1\uffff\1\2",
"\1\7",
"\1\2\13\uffff\2\2\12\uffff\1\6\16\uffff\1\3\5\uffff\1\2"
};
static final short[] dfa_1 = DFA.unpackEncodedString(dfa_1s);
static final char[] dfa_2 = DFA.unpackEncodedStringToUnsignedChars(dfa_2s);
static final char[] dfa_3 = DFA.unpackEncodedStringToUnsignedChars(dfa_3s);
static final short[] dfa_4 = DFA.unpackEncodedString(dfa_4s);
static final short[] dfa_5 = DFA.unpackEncodedString(dfa_5s);
static final short[][] dfa_6 = unpackEncodedStringArray(dfa_6s);
class DFA1 extends DFA {
public DFA1(BaseRecognizer recognizer) {
this.recognizer = recognizer;
this.decisionNumber = 1;
this.eot = dfa_1;
this.eof = dfa_1;
this.min = dfa_2;
this.max = dfa_3;
this.accept = dfa_4;
this.special = dfa_5;
this.transition = dfa_6;
}
public String getDescription() {
return "1469:1: rule__AbstractRule__Alternatives : ( ( ruleParserRule ) | ( ruleTerminalRule ) | ( ruleEnumRule ) );";
}
}
static final String dfa_7s = "\13\uffff";
static final String dfa_8s = "\3\uffff\3\6\1\uffff\3\6\1\uffff";
static final String dfa_9s = "\6\4\1\uffff\3\4\1\uffff";
static final String dfa_10s = "\1\62\2\26\3\62\1\uffff\3\62\1\uffff";
static final String dfa_11s = "\6\uffff\1\2\3\uffff\1\1";
static final String dfa_12s = "\13\uffff}>";
static final String[] dfa_13s = {
"\1\3\1\6\12\uffff\1\5\1\4\4\uffff\1\6\25\uffff\1\2\5\uffff\1\1",
"\1\7\1\6\12\uffff\1\11\1\10\4\uffff\1\6",
"\1\7\1\6\12\uffff\1\11\1\10\4\uffff\1\6",
@ -30169,26 +30151,26 @@ public class InternalXtextParser extends AbstractInternalContentAssistParser {
""
};
static final short[] dfa_1 = DFA.unpackEncodedString(dfa_1s);
static final short[] dfa_2 = DFA.unpackEncodedString(dfa_2s);
static final char[] dfa_3 = DFA.unpackEncodedStringToUnsignedChars(dfa_3s);
static final char[] dfa_4 = DFA.unpackEncodedStringToUnsignedChars(dfa_4s);
static final short[] dfa_5 = DFA.unpackEncodedString(dfa_5s);
static final short[] dfa_6 = DFA.unpackEncodedString(dfa_6s);
static final short[][] dfa_7 = unpackEncodedStringArray(dfa_7s);
static final short[] dfa_7 = DFA.unpackEncodedString(dfa_7s);
static final short[] dfa_8 = DFA.unpackEncodedString(dfa_8s);
static final char[] dfa_9 = DFA.unpackEncodedStringToUnsignedChars(dfa_9s);
static final char[] dfa_10 = DFA.unpackEncodedStringToUnsignedChars(dfa_10s);
static final short[] dfa_11 = DFA.unpackEncodedString(dfa_11s);
static final short[] dfa_12 = DFA.unpackEncodedString(dfa_12s);
static final short[][] dfa_13 = unpackEncodedStringArray(dfa_13s);
class DFA8 extends DFA {
public DFA8(BaseRecognizer recognizer) {
this.recognizer = recognizer;
this.decisionNumber = 8;
this.eot = dfa_1;
this.eof = dfa_2;
this.min = dfa_3;
this.max = dfa_4;
this.accept = dfa_5;
this.special = dfa_6;
this.transition = dfa_7;
this.eot = dfa_7;
this.eof = dfa_8;
this.min = dfa_9;
this.max = dfa_10;
this.accept = dfa_11;
this.special = dfa_12;
this.transition = dfa_13;
}
public String getDescription() {
return "1601:1: rule__AbstractTokenWithCardinality__Alternatives_0 : ( ( ruleAssignment ) | ( ruleAbstractTerminal ) );";

View file

@ -2876,7 +2876,7 @@ ruleTerminalRule returns [EObject current=null]
afterParserOrEnumRuleCall();
}
)
)?
)*
otherlv_1='terminal'
{
newLeafNode(otherlv_1, grammarAccess.getTerminalRuleAccess().getTerminalKeyword_1());

View file

@ -782,73 +782,7 @@ public class InternalXtextParser extends AbstractInternalAntlrParser {
{
// InternalXtext.g:312:2: (this_ParserRule_0= ruleParserRule | this_TerminalRule_1= ruleTerminalRule | this_EnumRule_2= ruleEnumRule )
int alt9=3;
switch ( input.LA(1) ) {
case 21:
{
int LA9_1 = input.LA(2);
if ( (LA9_1==RULE_ID) ) {
switch ( input.LA(3) ) {
case RULE_ID:
case 21:
case 22:
case 39:
case 40:
{
alt9=1;
}
break;
case 47:
{
alt9=2;
}
break;
case 50:
{
alt9=3;
}
break;
default:
NoViableAltException nvae =
new NoViableAltException("", 9, 5, input);
throw nvae;
}
}
else {
NoViableAltException nvae =
new NoViableAltException("", 9, 1, input);
throw nvae;
}
}
break;
case RULE_ID:
case 22:
case 39:
case 40:
{
alt9=1;
}
break;
case 47:
{
alt9=2;
}
break;
case 50:
{
alt9=3;
}
break;
default:
NoViableAltException nvae =
new NoViableAltException("", 9, 0, input);
throw nvae;
}
alt9 = dfa9.predict(input);
switch (alt9) {
case 1 :
// InternalXtext.g:313:3: this_ParserRule_0= ruleParserRule
@ -7899,7 +7833,7 @@ public class InternalXtextParser extends AbstractInternalAntlrParser {
// $ANTLR start "ruleTerminalRule"
// InternalXtext.g:2853:1: ruleTerminalRule returns [EObject current=null] : ( ( (lv_annotations_0_0= ruleAnnotation ) )? otherlv_1= 'terminal' ( ( ( (lv_fragment_2_0= 'fragment' ) ) ( (lv_name_3_0= ruleValidID ) ) ) | ( ( (lv_name_4_0= ruleValidID ) ) (otherlv_5= 'returns' ( (lv_type_6_0= ruleTypeRef ) ) )? ) ) otherlv_7= ':' ( (lv_alternatives_8_0= ruleTerminalAlternatives ) ) otherlv_9= ';' ) ;
// InternalXtext.g:2853:1: ruleTerminalRule returns [EObject current=null] : ( ( (lv_annotations_0_0= ruleAnnotation ) )* otherlv_1= 'terminal' ( ( ( (lv_fragment_2_0= 'fragment' ) ) ( (lv_name_3_0= ruleValidID ) ) ) | ( ( (lv_name_4_0= ruleValidID ) ) (otherlv_5= 'returns' ( (lv_type_6_0= ruleTypeRef ) ) )? ) ) otherlv_7= ':' ( (lv_alternatives_8_0= ruleTerminalAlternatives ) ) otherlv_9= ';' ) ;
public final EObject ruleTerminalRule() throws RecognitionException {
EObject current = null;
@ -7923,53 +7857,60 @@ public class InternalXtextParser extends AbstractInternalAntlrParser {
enterRule();
try {
// InternalXtext.g:2859:2: ( ( ( (lv_annotations_0_0= ruleAnnotation ) )? otherlv_1= 'terminal' ( ( ( (lv_fragment_2_0= 'fragment' ) ) ( (lv_name_3_0= ruleValidID ) ) ) | ( ( (lv_name_4_0= ruleValidID ) ) (otherlv_5= 'returns' ( (lv_type_6_0= ruleTypeRef ) ) )? ) ) otherlv_7= ':' ( (lv_alternatives_8_0= ruleTerminalAlternatives ) ) otherlv_9= ';' ) )
// InternalXtext.g:2860:2: ( ( (lv_annotations_0_0= ruleAnnotation ) )? otherlv_1= 'terminal' ( ( ( (lv_fragment_2_0= 'fragment' ) ) ( (lv_name_3_0= ruleValidID ) ) ) | ( ( (lv_name_4_0= ruleValidID ) ) (otherlv_5= 'returns' ( (lv_type_6_0= ruleTypeRef ) ) )? ) ) otherlv_7= ':' ( (lv_alternatives_8_0= ruleTerminalAlternatives ) ) otherlv_9= ';' )
// InternalXtext.g:2859:2: ( ( ( (lv_annotations_0_0= ruleAnnotation ) )* otherlv_1= 'terminal' ( ( ( (lv_fragment_2_0= 'fragment' ) ) ( (lv_name_3_0= ruleValidID ) ) ) | ( ( (lv_name_4_0= ruleValidID ) ) (otherlv_5= 'returns' ( (lv_type_6_0= ruleTypeRef ) ) )? ) ) otherlv_7= ':' ( (lv_alternatives_8_0= ruleTerminalAlternatives ) ) otherlv_9= ';' ) )
// InternalXtext.g:2860:2: ( ( (lv_annotations_0_0= ruleAnnotation ) )* otherlv_1= 'terminal' ( ( ( (lv_fragment_2_0= 'fragment' ) ) ( (lv_name_3_0= ruleValidID ) ) ) | ( ( (lv_name_4_0= ruleValidID ) ) (otherlv_5= 'returns' ( (lv_type_6_0= ruleTypeRef ) ) )? ) ) otherlv_7= ':' ( (lv_alternatives_8_0= ruleTerminalAlternatives ) ) otherlv_9= ';' )
{
// InternalXtext.g:2860:2: ( ( (lv_annotations_0_0= ruleAnnotation ) )? otherlv_1= 'terminal' ( ( ( (lv_fragment_2_0= 'fragment' ) ) ( (lv_name_3_0= ruleValidID ) ) ) | ( ( (lv_name_4_0= ruleValidID ) ) (otherlv_5= 'returns' ( (lv_type_6_0= ruleTypeRef ) ) )? ) ) otherlv_7= ':' ( (lv_alternatives_8_0= ruleTerminalAlternatives ) ) otherlv_9= ';' )
// InternalXtext.g:2861:3: ( (lv_annotations_0_0= ruleAnnotation ) )? otherlv_1= 'terminal' ( ( ( (lv_fragment_2_0= 'fragment' ) ) ( (lv_name_3_0= ruleValidID ) ) ) | ( ( (lv_name_4_0= ruleValidID ) ) (otherlv_5= 'returns' ( (lv_type_6_0= ruleTypeRef ) ) )? ) ) otherlv_7= ':' ( (lv_alternatives_8_0= ruleTerminalAlternatives ) ) otherlv_9= ';'
// InternalXtext.g:2860:2: ( ( (lv_annotations_0_0= ruleAnnotation ) )* otherlv_1= 'terminal' ( ( ( (lv_fragment_2_0= 'fragment' ) ) ( (lv_name_3_0= ruleValidID ) ) ) | ( ( (lv_name_4_0= ruleValidID ) ) (otherlv_5= 'returns' ( (lv_type_6_0= ruleTypeRef ) ) )? ) ) otherlv_7= ':' ( (lv_alternatives_8_0= ruleTerminalAlternatives ) ) otherlv_9= ';' )
// InternalXtext.g:2861:3: ( (lv_annotations_0_0= ruleAnnotation ) )* otherlv_1= 'terminal' ( ( ( (lv_fragment_2_0= 'fragment' ) ) ( (lv_name_3_0= ruleValidID ) ) ) | ( ( (lv_name_4_0= ruleValidID ) ) (otherlv_5= 'returns' ( (lv_type_6_0= ruleTypeRef ) ) )? ) ) otherlv_7= ':' ( (lv_alternatives_8_0= ruleTerminalAlternatives ) ) otherlv_9= ';'
{
// InternalXtext.g:2861:3: ( (lv_annotations_0_0= ruleAnnotation ) )?
int alt62=2;
int LA62_0 = input.LA(1);
// InternalXtext.g:2861:3: ( (lv_annotations_0_0= ruleAnnotation ) )*
loop62:
do {
int alt62=2;
int LA62_0 = input.LA(1);
if ( (LA62_0==21) ) {
alt62=1;
}
switch (alt62) {
case 1 :
// InternalXtext.g:2862:4: (lv_annotations_0_0= ruleAnnotation )
{
// InternalXtext.g:2862:4: (lv_annotations_0_0= ruleAnnotation )
// InternalXtext.g:2863:5: lv_annotations_0_0= ruleAnnotation
{
newCompositeNode(grammarAccess.getTerminalRuleAccess().getAnnotationsAnnotationParserRuleCall_0_0());
pushFollow(FollowSets000.FOLLOW_44);
lv_annotations_0_0=ruleAnnotation();
state._fsp--;
if ( (LA62_0==21) ) {
alt62=1;
}
if (current==null) {
current = createModelElementForParent(grammarAccess.getTerminalRuleRule());
}
add(
current,
"annotations",
lv_annotations_0_0,
"org.eclipse.xtext.Xtext.Annotation");
afterParserOrEnumRuleCall();
switch (alt62) {
case 1 :
// InternalXtext.g:2862:4: (lv_annotations_0_0= ruleAnnotation )
{
// InternalXtext.g:2862:4: (lv_annotations_0_0= ruleAnnotation )
// InternalXtext.g:2863:5: lv_annotations_0_0= ruleAnnotation
{
}
newCompositeNode(grammarAccess.getTerminalRuleAccess().getAnnotationsAnnotationParserRuleCall_0_0());
pushFollow(FollowSets000.FOLLOW_44);
lv_annotations_0_0=ruleAnnotation();
state._fsp--;
}
break;
if (current==null) {
current = createModelElementForParent(grammarAccess.getTerminalRuleRule());
}
add(
current,
"annotations",
lv_annotations_0_0,
"org.eclipse.xtext.Xtext.Annotation");
afterParserOrEnumRuleCall();
}
}
}
break;
default :
break loop62;
}
} while (true);
otherlv_1=(Token)match(input,47,FollowSets000.FOLLOW_45);
@ -10371,14 +10312,55 @@ public class InternalXtextParser extends AbstractInternalAntlrParser {
// Delegated rules
protected DFA9 dfa9 = new DFA9(this);
protected DFA34 dfa34 = new DFA34(this);
static final String dfa_1s = "\13\uffff";
static final String dfa_2s = "\3\uffff\3\6\1\uffff\3\6\1\uffff";
static final String dfa_3s = "\6\4\1\uffff\3\4\1\uffff";
static final String dfa_4s = "\1\53\2\50\3\54\1\uffff\3\54\1\uffff";
static final String dfa_5s = "\6\uffff\1\2\3\uffff\1\1";
static final String dfa_6s = "\13\uffff}>";
static final String[] dfa_7s = {
static final String dfa_1s = "\10\uffff";
static final String dfa_2s = "\2\5\3\uffff\3\5";
static final String dfa_3s = "\1\62\1\5\3\uffff\1\62\1\5\1\57";
static final String dfa_4s = "\2\uffff\1\1\1\2\1\3\3\uffff";
static final String dfa_5s = "\10\uffff}>";
static final String[] dfa_6s = {
"\1\2\17\uffff\1\1\1\2\20\uffff\2\2\6\uffff\1\3\2\uffff\1\4",
"\1\5",
"",
"",
"",
"\1\2\17\uffff\1\6\1\2\20\uffff\2\2\6\uffff\1\3\2\uffff\1\4",
"\1\7",
"\1\2\17\uffff\1\6\1\2\20\uffff\2\2\6\uffff\1\3"
};
static final short[] dfa_1 = DFA.unpackEncodedString(dfa_1s);
static final char[] dfa_2 = DFA.unpackEncodedStringToUnsignedChars(dfa_2s);
static final char[] dfa_3 = DFA.unpackEncodedStringToUnsignedChars(dfa_3s);
static final short[] dfa_4 = DFA.unpackEncodedString(dfa_4s);
static final short[] dfa_5 = DFA.unpackEncodedString(dfa_5s);
static final short[][] dfa_6 = unpackEncodedStringArray(dfa_6s);
class DFA9 extends DFA {
public DFA9(BaseRecognizer recognizer) {
this.recognizer = recognizer;
this.decisionNumber = 9;
this.eot = dfa_1;
this.eof = dfa_1;
this.min = dfa_2;
this.max = dfa_3;
this.accept = dfa_4;
this.special = dfa_5;
this.transition = dfa_6;
}
public String getDescription() {
return "312:2: (this_ParserRule_0= ruleParserRule | this_TerminalRule_1= ruleTerminalRule | this_EnumRule_2= ruleEnumRule )";
}
}
static final String dfa_7s = "\13\uffff";
static final String dfa_8s = "\3\uffff\3\6\1\uffff\3\6\1\uffff";
static final String dfa_9s = "\6\4\1\uffff\3\4\1\uffff";
static final String dfa_10s = "\1\53\2\50\3\54\1\uffff\3\54\1\uffff";
static final String dfa_11s = "\6\uffff\1\2\3\uffff\1\1";
static final String dfa_12s = "\13\uffff}>";
static final String[] dfa_13s = {
"\1\6\1\3\11\uffff\1\6\27\uffff\1\4\1\5\1\uffff\1\1\1\2",
"\1\6\1\7\11\uffff\1\6\27\uffff\1\10\1\11",
"\1\6\1\7\11\uffff\1\6\27\uffff\1\10\1\11",
@ -10392,26 +10374,26 @@ public class InternalXtextParser extends AbstractInternalAntlrParser {
""
};
static final short[] dfa_1 = DFA.unpackEncodedString(dfa_1s);
static final short[] dfa_2 = DFA.unpackEncodedString(dfa_2s);
static final char[] dfa_3 = DFA.unpackEncodedStringToUnsignedChars(dfa_3s);
static final char[] dfa_4 = DFA.unpackEncodedStringToUnsignedChars(dfa_4s);
static final short[] dfa_5 = DFA.unpackEncodedString(dfa_5s);
static final short[] dfa_6 = DFA.unpackEncodedString(dfa_6s);
static final short[][] dfa_7 = unpackEncodedStringArray(dfa_7s);
static final short[] dfa_7 = DFA.unpackEncodedString(dfa_7s);
static final short[] dfa_8 = DFA.unpackEncodedString(dfa_8s);
static final char[] dfa_9 = DFA.unpackEncodedStringToUnsignedChars(dfa_9s);
static final char[] dfa_10 = DFA.unpackEncodedStringToUnsignedChars(dfa_10s);
static final short[] dfa_11 = DFA.unpackEncodedString(dfa_11s);
static final short[] dfa_12 = DFA.unpackEncodedString(dfa_12s);
static final short[][] dfa_13 = unpackEncodedStringArray(dfa_13s);
class DFA34 extends DFA {
public DFA34(BaseRecognizer recognizer) {
this.recognizer = recognizer;
this.decisionNumber = 34;
this.eot = dfa_1;
this.eof = dfa_2;
this.min = dfa_3;
this.max = dfa_4;
this.accept = dfa_5;
this.special = dfa_6;
this.transition = dfa_7;
this.eot = dfa_7;
this.eof = dfa_8;
this.min = dfa_9;
this.max = dfa_10;
this.accept = dfa_11;
this.special = dfa_12;
this.transition = dfa_13;
}
public String getDescription() {
return "1285:3: (this_Assignment_0= ruleAssignment | this_AbstractTerminal_1= ruleAbstractTerminal )";
@ -10464,7 +10446,7 @@ public class InternalXtextParser extends AbstractInternalAntlrParser {
public static final BitSet FOLLOW_41 = new BitSet(new long[]{0x0000400040000000L});
public static final BitSet FOLLOW_42 = new BitSet(new long[]{0x0000018000000030L});
public static final BitSet FOLLOW_43 = new BitSet(new long[]{0x0000400000000000L});
public static final BitSet FOLLOW_44 = new BitSet(new long[]{0x0000800000000000L});
public static final BitSet FOLLOW_44 = new BitSet(new long[]{0x0000800000200000L});
public static final BitSet FOLLOW_45 = new BitSet(new long[]{0x0000018000400020L});
public static final BitSet FOLLOW_46 = new BitSet(new long[]{0x0000000003000000L});
public static final BitSet FOLLOW_47 = new BitSet(new long[]{0x00010B8000028030L});

View file

@ -1170,7 +1170,7 @@ public class XtextSemanticSequencer extends AbstractDelegatingSemanticSequencer
* TerminalRule returns TerminalRule
*
* Constraint:
* (annotations+=Annotation? ((fragment?='fragment' name=ValidID) | (name=ValidID type=TypeRef?)) alternatives=TerminalAlternatives)
* (annotations+=Annotation* ((fragment?='fragment' name=ValidID) | (name=ValidID type=TypeRef?)) alternatives=TerminalAlternatives)
*/
protected void sequence_TerminalRule(ISerializationContext context, TerminalRule semanticObject) {
genericSequencer.createSequence(context, semanticObject);

View file

@ -1792,17 +1792,17 @@ public class XtextGrammarAccess extends AbstractGrammarElementFinder {
private final Keyword cSemicolonKeyword_5 = (Keyword)cGroup.eContents().get(5);
//TerminalRule:
// annotations+=Annotation?
// annotations+=Annotation*
// 'terminal' (^fragment?='fragment' name=ValidID | name=ValidID ('returns' type=TypeRef)?) ':'
// alternatives=TerminalAlternatives
// ';';
@Override public ParserRule getRule() { return rule; }
//annotations+=Annotation? 'terminal' (^fragment?='fragment' name=ValidID | name=ValidID ('returns' type=TypeRef)?) ':'
//annotations+=Annotation* 'terminal' (^fragment?='fragment' name=ValidID | name=ValidID ('returns' type=TypeRef)?) ':'
//alternatives=TerminalAlternatives ';'
public Group getGroup() { return cGroup; }
//annotations+=Annotation?
//annotations+=Annotation*
public Assignment getAnnotationsAssignment_0() { return cAnnotationsAssignment_0; }
//Annotation
@ -2903,7 +2903,7 @@ public class XtextGrammarAccess extends AbstractGrammarElementFinder {
}
//TerminalRule:
// annotations+=Annotation?
// annotations+=Annotation*
// 'terminal' (^fragment?='fragment' name=ValidID | name=ValidID ('returns' type=TypeRef)?) ':'
// alternatives=TerminalAlternatives
// ';';

View file

@ -205,7 +205,7 @@ PredicatedGroup returns Group:
;
TerminalRule :
(annotations += Annotation)?
(annotations += Annotation)*
'terminal' (^fragment?='fragment' name=ValidID | name=ValidID ('returns' type=TypeRef)?) ':'
alternatives=TerminalAlternatives
';'

View file

@ -19,6 +19,7 @@ import com.google.inject.Singleton;
* Use {@link #getConfigurableIssueCodes()} to get all registered codes.
*
* @author Miro Spoenemann - Initial contribution and API
* @author Holger Schill
*/
@Singleton
public class XtextConfigurableIssueCodes extends ConfigurableIssueCodesProvider {
@ -43,6 +44,7 @@ public class XtextConfigurableIssueCodes extends ConfigurableIssueCodesProvider
public static final String EXPLICIT_OVERRIDE_MISSING = ISSUE_CODE_PREFIX + "ExplicitOverrideMissing";
public static final String EXPLICIT_OVERRIDE_INVALID = ISSUE_CODE_PREFIX + "ExplicitOverrideInvalid";
public static final String INVALID_ANNOTAION = ISSUE_CODE_PREFIX + "InvalidAnnotation";
@Override
protected void initialize(IAcceptor<PreferenceKey> acceptor) {

View file

@ -1217,6 +1217,16 @@ public class XtextValidator extends AbstractDeclarativeValidator {
INVALID_TERMINALRULE_NAME, terminalRule.getName());
}
@Check
public void checkTerminalRuleAnnotations(TerminalRule terminalRule){
if(hasAnnotation(terminalRule, AnnotationNames.EXPORTED)) {
error("TerminalRule cannot be exported!",terminalRule, XtextPackage.eINSTANCE.getAbstractRule_Name(), INVALID_ANNOTAION);
}
if(hasAnnotation(terminalRule, AnnotationNames.DEPRECATED)) {
error("TerminalRule cannot be deprecated!",terminalRule, XtextPackage.eINSTANCE.getAbstractRule_Name(), INVALID_ANNOTAION);
}
}
@Check
public void checkOppositeReferenceUsed(Assignment assignment) {
Severity severity = getIssueSeverities(getContext(), getCurrentObject()).getSeverity(BIDIRECTIONAL_REFERENCE);
@ -1253,7 +1263,7 @@ public class XtextValidator extends AbstractDeclarativeValidator {
public void checkOverridingRule(AbstractRule rule) {
final String name = rule.getName();
final List<Grammar> superGrammars = GrammarUtil.getGrammar(rule).getUsedGrammars();
boolean isOverride = isOverride(rule);
boolean isOverride = hasAnnotation(rule, AnnotationNames.OVERRIDE);
if (isOverride && superGrammars.isEmpty()) {
error("This grammar has no super grammar and therefore cannot override any rules.", rule,
XtextPackage.Literals.ABSTRACT_RULE__NAME, XtextConfigurableIssueCodes.EXPLICIT_OVERRIDE_INVALID);
@ -1262,11 +1272,11 @@ public class XtextValidator extends AbstractDeclarativeValidator {
for (Grammar g : superGrammars) {
final AbstractRule r = GrammarUtil.findRuleForName(g, rule.getName());
if (r != null) {
if(isDeprecated(r)) {
if(hasAnnotation(r, AnnotationNames.DEPRECATED)) {
warning("This rule overrides " + name + " in " + GrammarUtil.getGrammar(r).getName() + " which is deprecated.", rule,
XtextPackage.Literals.ABSTRACT_RULE__NAME, XtextConfigurableIssueCodes.EXPLICIT_OVERRIDE_INVALID);
}
if(isFinal(r)) {
if(hasAnnotation(r, AnnotationNames.FINAL)) {
error("This rule illegally overrides " + name + " in " + GrammarUtil.getGrammar(r).getName() + " which is final.", rule,
XtextPackage.Literals.ABSTRACT_RULE__NAME, XtextConfigurableIssueCodes.EXPLICIT_OVERRIDE_INVALID);
break;
@ -1300,22 +1310,8 @@ public class XtextValidator extends AbstractDeclarativeValidator {
/**
* @since 2.14
*/
protected boolean isOverride(AbstractRule rule) {
return rule.getAnnotations().stream().anyMatch(e -> AnnotationNames.OVERRIDE.equals(e.getName()));
}
/**
* @since 2.14
*/
protected boolean isFinal(AbstractRule rule) {
return rule.getAnnotations().stream().anyMatch(e -> AnnotationNames.FINAL.equals(e.getName()));
}
/**
* @since 2.14
*/
protected boolean isDeprecated(AbstractRule rule) {
return rule.getAnnotations().stream().anyMatch(e -> AnnotationNames.DEPRECATED.equals(e.getName()));
protected boolean hasAnnotation(AbstractRule rule, String annotationName) {
return rule.getAnnotations().stream().anyMatch(e -> annotationName.equals(e.getName()));
}