Forráskód Böngészése

Issue 2045 (#2057)

* Issue 2045 (#2046)

* show error if 'in events' use internal event names

* improvements

* remove check for after / every events
* added unit test

* changed grammar to disallow event trigger keywords for event definition
Andreas Mülder 7 éve
szülő
commit
620becb841

+ 18 - 10
plugins/org.yakindu.sct.model.stext/src/org/yakindu/sct/model/stext/SText.xtext

@@ -46,7 +46,7 @@ StatechartScope:
 	InterfaceScope | InternalScope | ImportScope;
 
 InterfaceScope:
-	{InterfaceScope} 'interface' (name=XID)? ':' (members+=InterfaceScopeDeclaration)*;
+	{InterfaceScope} 'interface' (name=IDWithKeywords)? ':' (members+=InterfaceScopeDeclaration)*;
 
 InterfaceScopeDeclaration returns types::Declaration:
 	EventDefinition | VariableDefinition | TypeAliasDefinition | OperationDefinition;
@@ -61,21 +61,21 @@ ImportScope:
 	 {ImportScope} 'import' ':' imports+=STRING*;
 
 EventDefinition:
-	(direction=Direction)? 'event' name=XID (':' typeSpecifier=TypeSpecifier)?;
+	(direction=Direction)? 'event' name=(ID | Keywords) (':' typeSpecifier=TypeSpecifier)?;
 
 enum Direction returns types::Direction:
 	LOCAL='local' | IN='in' | OUT='out';
 
 VariableDefinition:
-	{VariableDefinition} (const?='const'|'var') ((readonly?='readonly')? & (external?='external')?) name=XID ':' typeSpecifier=TypeSpecifier
+	{VariableDefinition} (const?='const'|'var') ((readonly?='readonly')? & (external?='external')?) name=IDWithKeywords ':' typeSpecifier=TypeSpecifier
 	('=' initialValue=Expression)?;  
 	
 TypeAliasDefinition:
-	{TypeAliasDefinition} 'alias' name=XID ':' typeSpecifier=TypeSpecifier;
+	{TypeAliasDefinition} 'alias' name=IDWithKeywords ':' typeSpecifier=TypeSpecifier;
 
 OperationDefinition:
 	{OperationDefinition} 
-	'operation' name=XID '(' (parameters+=Parameter (',' parameters+=Parameter)*)? ')' (':'
+	'operation' name=IDWithKeywords '(' (parameters+=Parameter (',' parameters+=Parameter)*)? ')' (':'
 	typeSpecifier=TypeSpecifier)?;
 	
 ArgumentedAnnotation:
@@ -87,7 +87,7 @@ SimpleArgument returns exp::Argument:
 ;
 
 Parameter returns types::Parameter:
-	 name=XID (varArgs?='...')? ':' typeSpecifier=TypeSpecifier;
+	 name=IDWithKeywords (varArgs?='...')? ':' typeSpecifier=TypeSpecifier;
 
 LocalReaction:
 	(trigger=ReactionTrigger) => ('/' effect=ReactionEffect);
@@ -174,9 +174,17 @@ PrimaryExpression returns exp::Expression:
 enum TimeUnit:
 	second='s' | millisecond='ms' | microsecond='us' | nanosecond='ns';
 
-XID:
-	ID | 'namespace' | 'interface' | 'internal' | 'event' | 'local' | 'in' | 'out' | 'var' | 'readonly' | 'external' |
-	'operation' | 'default' | 'else' | 'entry' | 'exit' | 'always' | 'oncycle' | 'raise' | 'valueof' | 'active';
+IDWithKeywords:
+	ID | TriggerKeywords | Keywords
+;
+
+Keywords:
+	 'namespace' | 'interface' | 'internal' |'import' | 'event' | 'local' | 'in' | 'out' | 'const' | 'var' | 'readonly' | 'external' |
+	'operation' | 'default' | 'else' | 'raise' | 'valueof' | 'active';
+
+TriggerKeywords:
+	 'every' | 'always' | 'oncycle' | 'after' | 'exit' | 'entry'
+;
 
 FQN:
-	XID ('.' XID)*;
+	IDWithKeywords ('.' IDWithKeywords)*;

+ 1 - 0
plugins/org.yakindu.sct.model.stext/src/org/yakindu/sct/model/stext/validation/STextJavaValidator.java

@@ -16,6 +16,7 @@ import static org.yakindu.sct.model.stext.lib.StatechartAnnotations.CYCLE_BASED_
 import static org.yakindu.sct.model.stext.lib.StatechartAnnotations.EVENT_DRIVEN_ANNOTATION;
 import static org.yakindu.sct.model.stext.lib.StatechartAnnotations.PARENT_FIRST_ANNOTATION;
 
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.LinkedList;

+ 1 - 0
plugins/org.yakindu.sct.model.stext/src/org/yakindu/sct/model/stext/validation/STextValidationMessages.java

@@ -57,4 +57,5 @@ public interface STextValidationMessages {
 	public static final String IMPORT_NOT_RESOLVED_CODE = "ImportNotResolved";
 	public static final String DUPLICATE_IMPORT = "Duplicate import '%s'.";
 	public static final String CONTRADICTORY_ANNOTATIONS = "Some annotations (%s) have contradictory effects.";
+	public static final String BAD_EVENT_NAMES = "'%s' is already used as name of an internal event.";
 }

+ 323 - 278
test-plugins/org.yakindu.sct.model.stext.test/src/org/yakindu/sct/model/stext/test/StextParserRuleTest.java

@@ -1,278 +1,323 @@
-/**
- * Copyright (c) 2012 itemis AG and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * 
- * Contributors:
- * 	itemis AG - initial API and implementation
- * 
- */
-package org.yakindu.sct.model.stext.test;
-
-import org.eclipse.xtext.junit4.InjectWith;
-import org.eclipse.xtext.junit4.XtextRunner;
-import org.junit.Ignore;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.junit.runner.RunWith;
-import org.yakindu.base.expressions.expressions.PrimitiveValueExpression;
-import org.yakindu.sct.model.stext.stext.DefaultTrigger;
-import org.yakindu.sct.model.stext.stext.EventDefinition;
-import org.yakindu.sct.model.stext.stext.InterfaceScope;
-import org.yakindu.sct.model.stext.stext.InternalScope;
-import org.yakindu.sct.model.stext.stext.LocalReaction;
-import org.yakindu.sct.model.stext.stext.OperationDefinition;
-import org.yakindu.sct.model.stext.stext.ReactionEffect;
-import org.yakindu.sct.model.stext.stext.ReactionTrigger;
-import org.yakindu.sct.model.stext.stext.TransitionReaction;
-import org.yakindu.sct.model.stext.stext.VariableDefinition;
-import org.yakindu.sct.model.stext.test.util.AbstractSTextTest;
-import org.yakindu.sct.model.stext.test.util.STextInjectorProvider;
-
-/**
- * @author andreas muelder - Initial contribution and API
- * 
- */
-@RunWith(XtextRunner.class)
-@InjectWith(STextInjectorProvider.class)
-public class StextParserRuleTest extends AbstractSTextTest {
-
-	@Rule
-	public ExpectedException exception = ExpectedException.none();
-
-	@Test
-	public void testBoolLiteral() {
-		String rule = PrimitiveValueExpression.class.getSimpleName();
-		parseExpression("true", rule);
-		parseExpression("false", rule);
-		parseExpression("yes", rule);
-		parseExpression("no", rule);
-	}
-
-	@Test
-	public void testIntLiteral() {
-		String rule = PrimitiveValueExpression.class.getSimpleName();
-		parseExpression("0", rule);
-		parseExpression("4", rule);
-		parseExpression("42", rule);
-	}
-
-	@Test
-	public void testHexLiteral() {
-		String rule = PrimitiveValueExpression.class.getSimpleName();
-		parseExpression("0xFFB5C5", rule);
-		parseExpression("0XFFB5C5", rule);
-	}
-	
-	@Test
-	public void testBinaryLiteral() {
-		String rule = PrimitiveValueExpression.class.getSimpleName();
-		parseExpression("0b1101101", rule);
-		parseExpression("0B1110001", rule);
-	}
-
-	@Test
-	public void testRealLiteral() {
-		String rule = PrimitiveValueExpression.class.getSimpleName();
-		parseExpression("0.2f", rule);
-		parseExpression("0.2F", rule);
-		parseExpression("0.2d", rule);
-		parseExpression("0.2D", rule);
-	}
-
-	@Test
-	public void testStringLiteral() {
-		String rule = PrimitiveValueExpression.class.getSimpleName();
-		parseExpression("'Hello World'", rule);
-		parseExpression("\"Hello World\"", rule);
-		parseExpression("''", rule);
-	}
-
-	@Test
-	public void testNullLiteral() {
-		String rule = PrimitiveValueExpression.class.getSimpleName();
-		parseExpression("null", rule);
-	}
-
-	/**
-	 * VariableDefinition: {VariableDefinition} 'var' ((readonly?='readonly')? &
-	 * (external?='external')?) name=ID ':' type=[types::Type|FQN] ('='
-	 * initialValue=Expression)?;
-	 */
-	@Test
-	public void testVariableDefinition() {
-		String rule = VariableDefinition.class.getSimpleName();
-		parseExpression("var MyVar : integer", rule);
-		parseExpression("var MyVar : integer = 97", rule);
-		parseExpression("var readonly MyVar : integer", rule);
-		parseExpression("var external MyVar : integer", rule);
-		parseExpression("var readonly external MyVar : integer", rule);
-		parseExpression("var external readonly MyVar : integer", rule);
-		parseExpression("var MyVar : integer = 3 * 3", rule);
-		parseExpression("var MyVar : string = null", rule);
-	}
-
-	/**
-	 * EventDefinition: (direction=Direction)? 'event' name=ID (':'
-	 * type=[types::Type|FQN])? (derivation=EventDerivation)?;
-	 */
-	@Test
-	public void testEventDefinition() {
-		String rule = EventDefinition.class.getSimpleName();
-		parseExpression("event event1", rule);
-		parseExpression("event event1 : integer", rule);
-		parseExpression("local event event1 : boolean", rule);
-		parseExpression("in event event1 : integer", rule);
-		parseExpression("out event event1 : integer", rule);
-		parseExpression("event event1 : integer", rule);
-		parseExpression("event event1 : string", rule);
-
-	}
-
-	/**
-	 * OperationDefinition: {OperationDefinition} 'operation' name=ID '('
-	 * (parameters+=Parameter (',' parameters+=Parameter)*)? ')' (':'
-	 * type=[types::Type|FQN])?;
-	 */
-	@Test
-	public void testOperationDefinition() {
-		String rule = OperationDefinition.class.getSimpleName();
-		parseExpression("operation myOpp()", rule);
-		parseExpression("operation myOpp() : boolean", rule);
-		parseExpression("operation myOpp(param1: integer)", rule);
-		parseExpression("operation myOpp(param1 : boolean) : integer", rule);
-		parseExpression("operation myOpp(param1 : boolean, param2 : real) : integer", rule);
-		parseExpression("operation myOpp(param1 : real, param2 : real) : integer", rule);
-	}
-
-	/**
-	 * {ReactionTrigger} ((triggers+=EventSpec ("," triggers+=EventSpec)* (=>
-	 * '[' guardExpression=Expression ']')?) | ('[' guardExpression=Expression
-	 * ']'));
-	 */
-	@Test
-	public void testReactionTrigger() {
-		String rule = ReactionTrigger.class.getSimpleName();
-		// Internal Scope
-		parseExpression("intEvent", rule, internalScope());
-		parseExpression("after 10 s", rule);
-		parseExpression("after 10 ms", rule);
-		parseExpression("after 10 us", rule);
-		parseExpression("after 10 ns", rule);
-		parseExpression("every 10 ns", rule);
-		parseExpression("entry", rule);
-		parseExpression("exit", rule);
-		parseExpression("oncycle", rule);
-		parseExpression("always", rule);
-		parseExpression("intEvent, after 10s", rule, internalScope());
-		parseExpression("intEvent, after 10s, every 10 ms", rule, internalScope());
-		parseExpression("intEvent, after 10s [false == true]", rule, internalScope());
-		parseExpression("intEvent, after 10s ['' != null]", rule, internalScope());
-		parseExpression("intEvent, after 10s [5  > 10]", rule, internalScope());
-		parseExpression("ABC.intEvent", rule, interfaceScope());
-	}
-
-	/**
-	 * DefaultTrigger returns sgraph::Trigger: {DefaultTrigger} ('default' |
-	 * 'else') ;
-	 */
-	@Test
-	public void testDefaultTrigger() {
-		String rule = DefaultTrigger.class.getSimpleName();
-		// Internal Scope
-		parseExpression("default", rule);
-		parseExpression("else", rule);
-	}
-
-	/**
-	 * ReactionEffect returns sgraph::Effect: {ReactionEffect}
-	 * actions+=(Expression | EventRaisingExpression) (=> ';'
-	 * actions+=(Expression|EventRaisingExpression) )* ; // (';')?;
-	 */
-	@Test
-	public void testReactionEffect() {
-		String rule = ReactionEffect.class.getSimpleName();
-		parseExpression("raise intEvent", rule, internalScope());
-		parseExpression("intVar = 5", rule, internalScope());
-		parseExpression("voidOp()", rule, internalScope());
-		parseExpression("intVar = intOp()", rule, internalScope());
-
-		parseExpression("raise ABC.intEvent : 5", rule, interfaceScope());
-		parseExpression("ABC.paramOp()", rule, interfaceScope());
-		parseExpression("ABC.paramOp(5,false)", rule, interfaceScope());
-		parseExpression("ABC.paramOp(null)", rule, interfaceScope());
-		parseExpression("ABC.paramOp(); raise ABC.voidEvent ", rule, interfaceScope());
-
-	}
-
-	@Test
-	@Ignore("Disabled entry / exit points for release")
-	public void testReactionProperties() {
-//		 String rule = ReactionProperties.class.getSimpleName();
-//		 parseExpression("> ABC.EntryPoint", interfaceScope(), rule);
-//		 parseExpression("ABC.ExitPoint >", interfaceScope(), rule);
-	}
-
-	/**
-	 * LocalReaction: (trigger=ReactionTrigger) =>('/' effect=ReactionEffect)
-	 * ('#' properties=ReactionProperties)?;
-	 */
-	@Test
-	public void tesLocalReaction() {
-		String rule = LocalReaction.class.getSimpleName();
-		parseExpression("entry [ABC.intVar > 10] / raise ABC.intEvent", rule, interfaceScope());
-	}
-
-	/**
-	 * TransitionReaction: {TransitionReaction} (trigger=ReactionTrigger)? ('/'
-	 * effect=ReactionEffect)? ('#' properties=ReactionProperties)?;
-	 */
-	@Test
-	public void testTransitionReaction() {
-		String rule = TransitionReaction.class.getSimpleName();
-		parseExpression("after 10 s / raise ABC.intEvent", rule, interfaceScope());
-	}
-
-	/**
-	 * {InterfaceScope} 'interface' (name=ID)? ':'
-	 * (declarations+=(EventDeclarartion | VariableDeclaration |
-	 * OperationDeclaration | Entrypoint | Exitpoint))*;
-	 */
-	@Test
-	public void testInterfaceScope() {
-		String rule = InterfaceScope.class.getSimpleName();
-		parseExpression("interface :", rule);
-		parseExpression("interface ABC:", rule);
-		parseExpression("interface : in event Event1", rule);
-		parseExpression("interface ABC : var myVar : integer", rule);
-		parseExpression("interface : operation myOpp()", rule);
-	}
-
-	/**
-	 * InternalScope : {InternalScope} 'internal' ':'
-	 * (declarations+=(EventDeclarartion | VariableDeclaration |
-	 * OperationDeclaration | LocalReaction))*;
-	 */
-	@Test
-	public void testInternalScope() {
-		String rule = InternalScope.class.getSimpleName();
-		parseExpression("internal :", rule);
-		parseExpression("internal : event voidEvent", rule);
-		parseExpression("internal : var intVar : integer", rule);
-		parseExpression("internal : operation voidOp()", rule);
-		parseExpression("internal : every 10 ms / raise intEvent", rule, internalScope());
-	}
-
-	/**
-	 * StateScope returns sgraph::Scope: {SimpleScope}
-	 * (declarations+=(LocalReaction | Entrypoint | Exitpoint))*;
-	 */
-	@Test
-	public void testStateScope() {
-
-	}
-
-}
+/**
+ * Copyright (c) 2012 itemis AG and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ * 	itemis AG - initial API and implementation
+ * 
+ */
+package org.yakindu.sct.model.stext.test;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.xtext.junit4.InjectWith;
+import org.eclipse.xtext.junit4.XtextRunner;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.yakindu.base.expressions.expressions.PrimitiveValueExpression;
+import org.yakindu.sct.model.stext.expressions.STextExpressionParser.SyntaxException;
+import org.yakindu.sct.model.stext.stext.DefaultTrigger;
+import org.yakindu.sct.model.stext.stext.EventDefinition;
+import org.yakindu.sct.model.stext.stext.InterfaceScope;
+import org.yakindu.sct.model.stext.stext.InternalScope;
+import org.yakindu.sct.model.stext.stext.LocalReaction;
+import org.yakindu.sct.model.stext.stext.OperationDefinition;
+import org.yakindu.sct.model.stext.stext.ReactionEffect;
+import org.yakindu.sct.model.stext.stext.ReactionTrigger;
+import org.yakindu.sct.model.stext.stext.StatechartSpecification;
+import org.yakindu.sct.model.stext.stext.TransitionReaction;
+import org.yakindu.sct.model.stext.stext.VariableDefinition;
+import org.yakindu.sct.model.stext.test.util.AbstractSTextTest;
+import org.yakindu.sct.model.stext.test.util.STextInjectorProvider;
+
+/**
+ * @author andreas muelder - Initial contribution and API
+ * 
+ */
+@RunWith(XtextRunner.class)
+@InjectWith(STextInjectorProvider.class)
+public class StextParserRuleTest extends AbstractSTextTest {
+
+	@Rule
+	public ExpectedException exception = ExpectedException.none();
+
+	@Test
+	public void testBoolLiteral() {
+		String rule = PrimitiveValueExpression.class.getSimpleName();
+		parseExpression("true", rule);
+		parseExpression("false", rule);
+		parseExpression("yes", rule);
+		parseExpression("no", rule);
+	}
+
+	@Test
+	public void testIntLiteral() {
+		String rule = PrimitiveValueExpression.class.getSimpleName();
+		parseExpression("0", rule);
+		parseExpression("4", rule);
+		parseExpression("42", rule);
+	}
+
+	@Test
+	public void testHexLiteral() {
+		String rule = PrimitiveValueExpression.class.getSimpleName();
+		parseExpression("0xFFB5C5", rule);
+		parseExpression("0XFFB5C5", rule);
+	}
+
+	@Test
+	public void testBinaryLiteral() {
+		String rule = PrimitiveValueExpression.class.getSimpleName();
+		parseExpression("0b1101101", rule);
+		parseExpression("0B1110001", rule);
+	}
+
+	@Test
+	public void testRealLiteral() {
+		String rule = PrimitiveValueExpression.class.getSimpleName();
+		parseExpression("0.2f", rule);
+		parseExpression("0.2F", rule);
+		parseExpression("0.2d", rule);
+		parseExpression("0.2D", rule);
+	}
+
+	@Test
+	public void testStringLiteral() {
+		String rule = PrimitiveValueExpression.class.getSimpleName();
+		parseExpression("'Hello World'", rule);
+		parseExpression("\"Hello World\"", rule);
+		parseExpression("''", rule);
+	}
+
+	@Test
+	public void testNullLiteral() {
+		String rule = PrimitiveValueExpression.class.getSimpleName();
+		parseExpression("null", rule);
+	}
+
+	/**
+	 * VariableDefinition: {VariableDefinition} 'var' ((readonly?='readonly')? &
+	 * (external?='external')?) name=ID ':' type=[types::Type|FQN] ('='
+	 * initialValue=Expression)?;
+	 */
+	@Test
+	public void testVariableDefinition() {
+		String rule = VariableDefinition.class.getSimpleName();
+		parseExpression("var MyVar : integer", rule);
+		parseExpression("var MyVar : integer = 97", rule);
+		parseExpression("var readonly MyVar : integer", rule);
+		parseExpression("var external MyVar : integer", rule);
+		parseExpression("var readonly external MyVar : integer", rule);
+		parseExpression("var external readonly MyVar : integer", rule);
+		parseExpression("var MyVar : integer = 3 * 3", rule);
+		parseExpression("var MyVar : string = null", rule);
+	}
+
+	/**
+	 * EventDefinition: (direction=Direction)? 'event' name=ID (':'
+	 * type=[types::Type|FQN])? (derivation=EventDerivation)?;
+	 */
+	@Test
+	public void testEventDefinition() {
+		String rule = EventDefinition.class.getSimpleName();
+		parseExpression("event event1", rule);
+		parseExpression("event event1 : integer", rule);
+		parseExpression("local event event1 : boolean", rule);
+		parseExpression("in event event1 : integer", rule);
+		parseExpression("out event event1 : integer", rule);
+		parseExpression("event event1 : integer", rule);
+		parseExpression("event event1 : string", rule);
+
+	}
+
+	/**
+	 * OperationDefinition: {OperationDefinition} 'operation' name=ID '('
+	 * (parameters+=Parameter (',' parameters+=Parameter)*)? ')' (':'
+	 * type=[types::Type|FQN])?;
+	 */
+	@Test
+	public void testOperationDefinition() {
+		String rule = OperationDefinition.class.getSimpleName();
+		parseExpression("operation myOpp()", rule);
+		parseExpression("operation myOpp() : boolean", rule);
+		parseExpression("operation myOpp(param1: integer)", rule);
+		parseExpression("operation myOpp(param1 : boolean) : integer", rule);
+		parseExpression("operation myOpp(param1 : boolean, param2 : real) : integer", rule);
+		parseExpression("operation myOpp(param1 : real, param2 : real) : integer", rule);
+	}
+
+	/**
+	 * {ReactionTrigger} ((triggers+=EventSpec ("," triggers+=EventSpec)* (=> '['
+	 * guardExpression=Expression ']')?) | ('[' guardExpression=Expression ']'));
+	 */
+	@Test
+	public void testReactionTrigger() {
+		String rule = ReactionTrigger.class.getSimpleName();
+		// Internal Scope
+		parseExpression("intEvent", rule, internalScope());
+		parseExpression("after 10 s", rule);
+		parseExpression("after 10 ms", rule);
+		parseExpression("after 10 us", rule);
+		parseExpression("after 10 ns", rule);
+		parseExpression("every 10 ns", rule);
+		parseExpression("entry", rule);
+		parseExpression("exit", rule);
+		parseExpression("oncycle", rule);
+		parseExpression("always", rule);
+		parseExpression("intEvent, after 10s", rule, internalScope());
+		parseExpression("intEvent, after 10s, every 10 ms", rule, internalScope());
+		parseExpression("intEvent, after 10s [false == true]", rule, internalScope());
+		parseExpression("intEvent, after 10s ['' != null]", rule, internalScope());
+		parseExpression("intEvent, after 10s [5  > 10]", rule, internalScope());
+		parseExpression("ABC.intEvent", rule, interfaceScope());
+	}
+
+	/**
+	 * DefaultTrigger returns sgraph::Trigger: {DefaultTrigger} ('default' | 'else')
+	 * ;
+	 */
+	@Test
+	public void testDefaultTrigger() {
+		String rule = DefaultTrigger.class.getSimpleName();
+		// Internal Scope
+		parseExpression("default", rule);
+		parseExpression("else", rule);
+	}
+
+	/**
+	 * ReactionEffect returns sgraph::Effect: {ReactionEffect} actions+=(Expression
+	 * | EventRaisingExpression) (=> ';'
+	 * actions+=(Expression|EventRaisingExpression) )* ; // (';')?;
+	 */
+	@Test
+	public void testReactionEffect() {
+		String rule = ReactionEffect.class.getSimpleName();
+		parseExpression("raise intEvent", rule, internalScope());
+		parseExpression("intVar = 5", rule, internalScope());
+		parseExpression("voidOp()", rule, internalScope());
+		parseExpression("intVar = intOp()", rule, internalScope());
+
+		parseExpression("raise ABC.intEvent : 5", rule, interfaceScope());
+		parseExpression("ABC.paramOp()", rule, interfaceScope());
+		parseExpression("ABC.paramOp(5,false)", rule, interfaceScope());
+		parseExpression("ABC.paramOp(null)", rule, interfaceScope());
+		parseExpression("ABC.paramOp(); raise ABC.voidEvent ", rule, interfaceScope());
+
+	}
+
+	/**
+	 * TransitionReaction: {TransitionReaction} (trigger=StextTrigger)? ('/'
+	 * effect=ReactionEffect)? ('#' (properties+=TransitionProperty)*)?;
+	 * 
+	 */
+	@Test
+	public void testReactionProperties() {
+		String rule = TransitionReaction.class.getSimpleName();
+		parseExpression("# > EntryPoint", rule, interfaceScope());
+		parseExpression("# ExitPoint >", rule, interfaceScope());
+	}
+
+	/**
+	 * LocalReaction: (trigger=ReactionTrigger) =>('/' effect=ReactionEffect) ('#'
+	 * properties=ReactionProperties)?;
+	 */
+	@Test
+	public void tesLocalReaction() {
+		String rule = LocalReaction.class.getSimpleName();
+		parseExpression("entry [ABC.intVar > 10] / raise ABC.intEvent", rule, interfaceScope());
+	}
+
+	/**
+	 * TransitionReaction: {TransitionReaction} (trigger=ReactionTrigger)? ('/'
+	 * effect=ReactionEffect)? ('#' properties=ReactionProperties)?;
+	 */
+	@Test
+	public void testTransitionReaction() {
+		String rule = TransitionReaction.class.getSimpleName();
+		parseExpression("after 10 s / raise ABC.intEvent", rule, interfaceScope());
+	}
+
+	/**
+	 * {InterfaceScope} 'interface' (name=ID)? ':' (declarations+=(EventDeclarartion
+	 * | VariableDeclaration | OperationDeclaration | Entrypoint | Exitpoint))*;
+	 */
+	@Test
+	public void testInterfaceScope() {
+		String rule = InterfaceScope.class.getSimpleName();
+		parseExpression("interface :", rule);
+		parseExpression("interface ABC:", rule);
+		parseExpression("interface : in event Event1", rule);
+		parseExpression("interface ABC : var myVar : integer", rule);
+		parseExpression("interface : operation myOpp()", rule);
+	}
+
+	/**
+	 * InternalScope : {InternalScope} 'internal' ':'
+	 * (declarations+=(EventDeclarartion | VariableDeclaration |
+	 * OperationDeclaration | LocalReaction))*;
+	 */
+	@Test
+	public void testInternalScope() {
+		String rule = InternalScope.class.getSimpleName();
+		parseExpression("internal :", rule);
+		parseExpression("internal : event voidEvent", rule);
+		parseExpression("internal : var intVar : integer", rule);
+		parseExpression("internal : operation voidOp()", rule);
+		parseExpression("internal : every 10 ms / raise intEvent", rule, internalScope());
+	}
+
+	/**
+	 * StateScope returns sgraph::Scope: {SimpleScope} (declarations+=(LocalReaction
+	 * | Entrypoint | Exitpoint))*;
+	 */
+	@Test
+	public void testStateScope() {
+
+	}
+
+	/**
+	 * EventDefinition: (direction=Direction)? 'event' name=(ID | Keywords) (':'
+	 * typeSpecifier=TypeSpecifier)?;
+	 */
+	@Test
+	public void testInvalidEventNamesUsed() {
+		String scope;
+		List<String> invalidEventNames = Arrays
+				.asList(new String[] { "after", "always", "oncycle", "exit", "entry", "every" });
+		for (String name : invalidEventNames) {
+			scope = "interface: in event " + name;
+			boolean thrown = false;
+			try {
+				parseExpression(scope, StatechartSpecification.class.getSimpleName());
+			} catch (SyntaxException ex) {
+				thrown = true;
+			}
+			assertTrue(thrown);
+		}
+	}
+
+	/**
+	 * EventDefinition: (direction=Direction)? 'event' name=(ID | Keywords) (':'
+	 * typeSpecifier=TypeSpecifier)?;
+	 * 
+	 */
+	public void testValidEventNamesUsed() {
+		String scope;
+		List<String> validEventNames = Arrays.asList(
+				new String[] { "namespace", "interface", "internal", "import", "event", "local", "in", "out", "const",
+						"var", "readonly", "external", "operation", "default", "else", "raise", "valueof", "active" });
+		for (String name : validEventNames) {
+			scope = "interface: in event " + name;
+			parseExpression(scope, StatechartSpecification.class.getSimpleName());
+		}
+	}
+
+}

+ 15 - 8
test-plugins/org.yakindu.sct.model.stext.test/src/org/yakindu/sct/model/stext/test/validation/STextJavaValidatorTest.java

@@ -22,8 +22,11 @@ import static org.yakindu.base.expressions.validation.ExpressionsJavaValidator.E
 import static org.yakindu.base.expressions.validation.ExpressionsJavaValidator.ERROR_WRONG_NUMBER_OF_ARGUMENTS_CODE;
 import static org.yakindu.sct.test.models.AbstractTestModelsUtil.VALIDATION_TESTMODEL_DIR;
 
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.List;
 
 import org.eclipse.emf.common.util.Diagnostic;
 import org.eclipse.emf.ecore.EObject;
@@ -65,6 +68,7 @@ import org.yakindu.sct.model.stext.validation.STextJavaValidator;
 import org.yakindu.sct.model.stext.validation.STextValidationMessages;
 import org.yakindu.sct.test.models.AbstractTestModelsUtil;
 
+import com.google.inject.Exposed;
 import com.google.inject.Inject;
 
 /**
@@ -77,7 +81,7 @@ public class STextJavaValidatorTest extends AbstractSTextValidationTest implemen
 
 	@Inject
 	TestCompletenessAssertions checkAvailable;
-	
+
 	/**
 	 * @see STextJavaValidator#checkVariableDefinition(org.yakindu.sct.model.stext.stext.VariableDefinition)
 	 */
@@ -287,7 +291,8 @@ public class STextJavaValidatorTest extends AbstractSTextValidationTest implemen
 		String scope = "@CycleBased";
 		EObject model = super.parseExpression(scope, StatechartSpecification.class.getSimpleName());
 		AssertableDiagnostics validationResult = tester.validate(model);
-		validationResult.assertError(STextJavaValidator.ERROR_WRONG_NUMBER_OF_ARGUMENTS_CODE);;
+		validationResult.assertError(STextJavaValidator.ERROR_WRONG_NUMBER_OF_ARGUMENTS_CODE);
+		;
 
 		scope = "@EventDriven";
 		model = super.parseExpression(scope, StatechartSpecification.class.getSimpleName());
@@ -401,7 +406,7 @@ public class STextJavaValidatorTest extends AbstractSTextValidationTest implemen
 		AssertableDiagnostics validationResult = tester.validate(model);
 		validationResult.assertOK();
 	}
-	
+
 	@Test
 	public void checkPostFixOperatorOnlyOnVariables() {
 		EObject model = super.parseExpression("ABC.intVar++", Expression.class.getSimpleName(), interfaceScope());
@@ -413,7 +418,7 @@ public class STextJavaValidatorTest extends AbstractSTextValidationTest implemen
 		model = super.parseExpression("5++", Expression.class.getSimpleName(), interfaceScope());
 		validationResult = tester.validate(model);
 		validationResult.assertError(ExpressionsJavaValidator.POSTFIX_ONLY_ON_VARIABLES_CODE);
-		
+
 	}
 
 	/**
@@ -630,7 +635,8 @@ public class STextJavaValidatorTest extends AbstractSTextValidationTest implemen
 		EObject model = super.parseExpression(decl, InternalScope.class.getSimpleName());
 		AssertableDiagnostics result = tester.validate(model);
 		result.assertDiagnosticsCount(1);
-		result.assertWarningContains(String.format(STextJavaValidator.DECLARATION_DEPRECATED, "external"));	}
+		result.assertWarningContains(String.format(STextJavaValidator.DECLARATION_DEPRECATED, "external"));
+	}
 
 	@Test
 	public void checkDeprecatedLocalEventDefinition() {
@@ -640,6 +646,7 @@ public class STextJavaValidatorTest extends AbstractSTextValidationTest implemen
 		result.assertDiagnosticsCount(1);
 		result.assertWarningContains(String.format(STextJavaValidator.DECLARATION_DEPRECATED, "local"));
 	}
+
 	/**
 	 * checks that each @Check method of {@link STextJavaValidator} has a @Test
 	 * method in this class with the same name
@@ -841,12 +848,13 @@ public class STextJavaValidatorTest extends AbstractSTextValidationTest implemen
 	public void checkImportExists() {
 		Scope context = (Scope) parseExpression("import: \"does.not.exist\"", ImportScope.class.getSimpleName());
 		AssertableDiagnostics validationResult = tester.validate(context);
-		validationResult.assertErrorContains(String.format(STextValidationMessages.IMPORT_NOT_RESOLVED_MSG,"does.not.exist"));
+		validationResult
+				.assertErrorContains(String.format(STextValidationMessages.IMPORT_NOT_RESOLVED_MSG, "does.not.exist"));
 	}
 
 	@Test
 	public void checkDuplicateImport() {
-		//Can't be checked here
+		// Can't be checked here
 	}
 
 	@Test
@@ -1005,5 +1013,4 @@ public class STextJavaValidatorTest extends AbstractSTextValidationTest implemen
 		result.assertAll(warningMsg("Duplicate"), warningMsg("Duplicate"), errorMsg("Duplicate"),
 				errorMsg("Duplicate"));
 	}
-
 }