Преглед изворни кода

Add trigger guard to reaction check sequence in execution flow (task #108)

terfloth@itemis.de пре 14 година
родитељ
комит
59b8e9f068

+ 14 - 2
plugins/org.yakindu.sct.model.sexec/src/org/yakindu/sct/model/sexec/transformation/ModelSequencer.xtend

@@ -363,12 +363,18 @@ class ModelSequencer {
 	def dispatch Statement buildCondition (Trigger t) { null }
 	
 	def dispatch Statement buildCondition (ReactionTrigger t) {
-		if (! t.triggers.empty) t.triggers.reverseView.fold(null as Expression,
+		val triggerCheck = if (! t.triggers.empty) t.triggers.reverseView.fold(null as Expression,
 			[s,e | 
 				if (s==null) raised(e)  
 				else raised(e).or(s)
 			]
-		)
+		) else null;
+		
+		val guard = if ( t.guardExpression != null ) EcoreUtil::copy(t.guardExpression) else null;
+		
+		if ( triggerCheck != null && guard != null ) and(triggerCheck, guard)
+		else if ( triggerCheck != null )  triggerCheck
+		else guard
 	}
 	
 	
@@ -380,6 +386,12 @@ class ModelSequencer {
 		or
 	}
 	
+	def Expression and(Expression left, Expression right) {
+		val or = stextFactory.createLogicalAndExpression
+		or.leftOperand = left
+		or.rightOperand = right
+		or
+	}
 	
 	 
 

+ 78 - 24
plugins/org.yakindu.sct.model.sexec/xtend-gen/org/yakindu/sct/model/sexec/transformation/ModelSequencer.java

@@ -59,6 +59,7 @@ import org.yakindu.sct.model.stext.stext.EventDefinition;
 import org.yakindu.sct.model.stext.stext.EventSpec;
 import org.yakindu.sct.model.stext.stext.Expression;
 import org.yakindu.sct.model.stext.stext.LocalReaction;
+import org.yakindu.sct.model.stext.stext.LogicalAndExpression;
 import org.yakindu.sct.model.stext.stext.LogicalOrExpression;
 import org.yakindu.sct.model.stext.stext.MultiplicativeOperator;
 import org.yakindu.sct.model.stext.stext.NumericalMultiplyDivideExpression;
@@ -708,32 +709,72 @@ public class ModelSequencer {
   }
   
   protected Statement _buildCondition(final ReactionTrigger t) {
-    Expression _xifexpression = null;
-    EList<EventSpec> _triggers = t.getTriggers();
-    boolean _isEmpty = _triggers.isEmpty();
-    boolean _operator_not = BooleanExtensions.operator_not(_isEmpty);
-    if (_operator_not) {
-      EList<EventSpec> _triggers_1 = t.getTriggers();
-      Iterable<EventSpec> _reverseView = ListExtensions.<EventSpec>reverseView(_triggers_1);
-      final Function2<Expression,EventSpec,Expression> _function = new Function2<Expression,EventSpec,Expression>() {
-          public Expression apply(final Expression s , final EventSpec e) {
-            Expression _xifexpression_1 = null;
-            boolean _operator_equals = ObjectExtensions.operator_equals(s, null);
-            if (_operator_equals) {
-              Expression _raised = ModelSequencer.this.raised(e);
-              _xifexpression_1 = _raised;
-            } else {
-              Expression _raised_1 = ModelSequencer.this.raised(e);
-              Expression _or = ModelSequencer.this.or(_raised_1, s);
-              _xifexpression_1 = _or;
+    Expression _xblockexpression = null;
+    {
+      Expression _xifexpression = null;
+      EList<EventSpec> _triggers = t.getTriggers();
+      boolean _isEmpty = _triggers.isEmpty();
+      boolean _operator_not = BooleanExtensions.operator_not(_isEmpty);
+      if (_operator_not) {
+        EList<EventSpec> _triggers_1 = t.getTriggers();
+        Iterable<EventSpec> _reverseView = ListExtensions.<EventSpec>reverseView(_triggers_1);
+        final Function2<Expression,EventSpec,Expression> _function = new Function2<Expression,EventSpec,Expression>() {
+            public Expression apply(final Expression s , final EventSpec e) {
+              Expression _xifexpression_1 = null;
+              boolean _operator_equals = ObjectExtensions.operator_equals(s, null);
+              if (_operator_equals) {
+                Expression _raised = ModelSequencer.this.raised(e);
+                _xifexpression_1 = _raised;
+              } else {
+                Expression _raised_1 = ModelSequencer.this.raised(e);
+                Expression _or = ModelSequencer.this.or(_raised_1, s);
+                _xifexpression_1 = _or;
+              }
+              return _xifexpression_1;
             }
-            return _xifexpression_1;
-          }
-        };
-      Expression _fold = IterableExtensions.<EventSpec, Expression>fold(_reverseView, ((Expression) null), _function);
-      _xifexpression = _fold;
+          };
+        Expression _fold = IterableExtensions.<EventSpec, Expression>fold(_reverseView, ((Expression) null), _function);
+        _xifexpression = _fold;
+      } else {
+        _xifexpression = null;
+      }
+      final Expression triggerCheck = _xifexpression;
+      Expression _xifexpression_2 = null;
+      Expression _guardExpression = t.getGuardExpression();
+      boolean _operator_notEquals = ObjectExtensions.operator_notEquals(_guardExpression, null);
+      if (_operator_notEquals) {
+        Expression _guardExpression_1 = t.getGuardExpression();
+        Expression _copy = EcoreUtil.<Expression>copy(_guardExpression_1);
+        _xifexpression_2 = _copy;
+      } else {
+        _xifexpression_2 = null;
+      }
+      final Expression guard = _xifexpression_2;
+      Expression _xifexpression_3 = null;
+      boolean _operator_and = false;
+      boolean _operator_notEquals_1 = ObjectExtensions.operator_notEquals(triggerCheck, null);
+      if (!_operator_notEquals_1) {
+        _operator_and = false;
+      } else {
+        boolean _operator_notEquals_2 = ObjectExtensions.operator_notEquals(guard, null);
+        _operator_and = BooleanExtensions.operator_and(_operator_notEquals_1, _operator_notEquals_2);
+      }
+      if (_operator_and) {
+        Expression _and = this.and(triggerCheck, guard);
+        _xifexpression_3 = _and;
+      } else {
+        Expression _xifexpression_4 = null;
+        boolean _operator_notEquals_3 = ObjectExtensions.operator_notEquals(triggerCheck, null);
+        if (_operator_notEquals_3) {
+          _xifexpression_4 = triggerCheck;
+        } else {
+          _xifexpression_4 = guard;
+        }
+        _xifexpression_3 = _xifexpression_4;
+      }
+      _xblockexpression = (_xifexpression_3);
     }
-    return _xifexpression;
+    return _xblockexpression;
   }
   
   public Expression or(final Expression left, final Expression right) {
@@ -749,6 +790,19 @@ public class ModelSequencer {
     return _xblockexpression;
   }
   
+  public Expression and(final Expression left, final Expression right) {
+    LogicalAndExpression _xblockexpression = null;
+    {
+      StextFactory _stextFactory = this.stextFactory();
+      LogicalAndExpression _createLogicalAndExpression = _stextFactory.createLogicalAndExpression();
+      final LogicalAndExpression or = _createLogicalAndExpression;
+      or.setLeftOperand(left);
+      or.setRightOperand(right);
+      _xblockexpression = (or);
+    }
+    return _xblockexpression;
+  }
+  
   protected Expression _raised(final EventSpec e) {
     return null;
   }

+ 58 - 2
test-plugins/org.yakindu.sct.model.sexec.test/src/org/yakindu/sct/model/sexec/transformation/test/ModelSequencerTest.java

@@ -58,9 +58,11 @@ import org.yakindu.sct.model.stext.stext.Assignment;
 import org.yakindu.sct.model.stext.stext.AssignmentOperator;
 import org.yakindu.sct.model.stext.stext.ElementReferenceExpression;
 import org.yakindu.sct.model.stext.stext.EventDefinition;
+import org.yakindu.sct.model.stext.stext.Expression;
 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.LogicalAndExpression;
 import org.yakindu.sct.model.stext.stext.LogicalOrExpression;
 import org.yakindu.sct.model.stext.stext.MultiplicativeOperator;
 import org.yakindu.sct.model.stext.stext.NumericalMultiplyDivideExpression;
@@ -367,6 +369,7 @@ public class ModelSequencerTest {
 		assertEquals(s2, ((EnterState)seq.getSteps().get(2)).getState());
 	}
 
+		
 	
 	/**
 	 * The exit action must be part of the reaction effect sequence
@@ -526,8 +529,7 @@ public class ModelSequencerTest {
 	}
 
 	
-	@Test
-	public void testReactionEffectSequence() {
+	@Test public void testTransitionCheckSequenceWithoutGuard() {
 
 		EventDefinition e1 = _createEventDefinition("e1", null);
 		EventDefinition e2 = _createEventDefinition("e2", null);
@@ -552,6 +554,60 @@ public class ModelSequencerTest {
 	}
 
 	
+	@Test public void testTransitionCheckSequenceWithGuard() {
+
+		EventDefinition e1 = _createEventDefinition("e1", null);
+		EventDefinition e2 = _createEventDefinition("e2", null);
+
+		ReactionTrigger tr1 = _createReactionTrigger(null);
+		_createRegularEventSpec(e1, tr1);
+		_createRegularEventSpec(e2, tr1);
+
+		PrimitiveValueExpression exp = _createValue("false");
+		tr1.setGuardExpression(exp);
+
+		Transition t = SGraphFactory.eINSTANCE.createTransition();
+		t.setTrigger(tr1);
+
+		Reaction reaction = sequencer.mapTransition(t);
+
+		// now check the expression structure ...
+		
+		// the root is an and condition with the trigger check as the first (left) part and the guard as the right (second) part.
+		LogicalAndExpression and = (LogicalAndExpression) reaction.getCheck().getCondition();
+		LogicalOrExpression triggerCheck = (LogicalOrExpression) and.getLeftOperand();
+		PrimitiveValueExpression guardCheck = (PrimitiveValueExpression) and.getRightOperand();
+		
+		assertTrue(triggerCheck.getLeftOperand() instanceof ElementReferenceExpression);
+		assertTrue(triggerCheck.getRightOperand() instanceof ElementReferenceExpression);
+		assertEquals(e1.getName(),
+				((ElementReferenceExpression) triggerCheck.getLeftOperand()).getValue().getName());
+		assertEquals(e2.getName(),
+				((ElementReferenceExpression) triggerCheck.getRightOperand()).getValue().getName());
+		
+		assertEquals(exp.getValue(), guardCheck.getValue());
+	}
+
+	
+	@Test public void testTransitionCheckSequenceWithoutTrigger() {
+
+		ReactionTrigger tr1 = _createReactionTrigger(null);
+		PrimitiveValueExpression exp = _createValue("false");
+		tr1.setGuardExpression(exp);
+
+		Transition t = SGraphFactory.eINSTANCE.createTransition();
+		t.setTrigger(tr1);
+
+		Reaction reaction = sequencer.mapTransition(t);
+
+		// now check the expression structure ...
+		
+		// the root is an and condition with the trigger check as the first (left) part and the guard as the right (second) part.
+		PrimitiveValueExpression guard = (PrimitiveValueExpression) reaction.getCheck().getCondition();
+		assertEquals(exp.getValue(), guard.getValue());
+	}
+
+	
 
 	/**
 	 * The state vector descriptor of the ExecutionFlow must have an offset of 0 and a size that is 

+ 1 - 1
test-plugins/org.yakindu.sct.model.sexec.test/src/org/yakindu/sct/model/sexec/transformation/test/SCTTestUtil.java

@@ -3,7 +3,6 @@ package org.yakindu.sct.model.sexec.transformation.test;
 import org.yakindu.sct.model.sgraph.Entry;
 import org.yakindu.sct.model.sgraph.EntryKind;
 import org.yakindu.sct.model.sgraph.Reaction;
-import org.yakindu.sct.model.sgraph.ReactiveElement;
 import org.yakindu.sct.model.sgraph.Region;
 import org.yakindu.sct.model.sgraph.SGraphFactory;
 import org.yakindu.sct.model.sgraph.Scope;
@@ -127,6 +126,7 @@ public class SCTTestUtil {
 		return effect;
 	}
 	
+		
 	
 	public static TimeEventSpec _createTimeEventSpec(TimeEventType type, int value, TimeUnit unit, ReactionTrigger rt) {
 		TimeEventSpec timeTrigger = StextFactory.eINSTANCE.createTimeEventSpec();