Pārlūkot izejas kodu

fixeD for bugs regarding entry on self transition and ignored guards for entry and exit actions (issues 705 and 706)

terfloth@itemis.de 12 gadi atpakaļ
vecāks
revīzija
f081afae55

+ 47 - 6
plugins/org.yakindu.sct.model.sexec/src/org/yakindu/sct/model/sexec/transformation/BehaviorMapping.xtend

@@ -91,12 +91,29 @@ class BehaviorMapping {
 		}	
 		
 		state.entryReactions
-			.map([lr | if (lr.effect != null) { (lr.effect as ReactionEffect).mapEffect } else null])
+//			.map([lr | if (lr.effect != null) { (lr.effect as ReactionEffect).mapEffect } else null])
+			.map([lr | lr.mapEntryAction ])
 			.forEach(e | if (e != null) { seq.steps.add(e) })
 		
 		if (seq.steps.size > 0) seq else null
 	}	
-
+
+	def Step mapEntryAction(LocalReaction it) {
+		if (effect != null) { 
+			var effectSeq = (effect as ReactionEffect).mapEffect
+			var guard =  trigger.buildGuard
+			
+			if ( guard != null ) {			
+				var ifStep = sexec.factory.createIf
+				ifStep.check = sexec.factory.createCheck
+				ifStep.check.condition = guard		
+				ifStep.thenStep = effectSeq
+				ifStep as Step	
+			} else effectSeq
+			
+		} else null
+	}
+	
 	def ExecutionFlow mapChoiceTransitions(Statechart statechart, ExecutionFlow r) {
 		statechart.allChoices.forEach( choice | choice.mapChoiceTransition);		
 		return r
@@ -166,11 +183,30 @@ class BehaviorMapping {
 		}	
 		
 		state.exitReactions
-			.map([lr | if (lr.effect != null) { (lr.effect as ReactionEffect).mapEffect } else null])
+//			.map([lr | if (lr.effect != null) { (lr.effect as ReactionEffect).mapEffect } else null])
+			.map([lr | lr.mapExitAction()])
 			.forEach(e | if (e != null) { seq.steps.add(e) })
 		
 		if (seq.steps.size > 0) seq else null
 	}
+
+
+	def Step mapExitAction(LocalReaction it) {
+		if (effect != null) { 
+			var effectSeq = (effect as ReactionEffect).mapEffect
+			var guard =  trigger.buildGuard
+			
+			if ( guard != null ) {			
+				var ifStep = sexec.factory.createIf
+				ifStep.check = sexec.factory.createCheck
+				ifStep.check.condition = guard		
+				ifStep.thenStep = effectSeq
+				ifStep as Step	
+			} else effectSeq
+			
+		} else null
+	}
+	
 
 //	def Statement divide(Expression stmnt, long divisor) {
 //		val NumericalMultiplyDivideExpression div = stext.factory.createNumericalMultiplyDivideExpression
@@ -367,7 +403,7 @@ class BehaviorMapping {
 
 		// define exit behavior of transition
 		
-		// first process the exit behavior of orthogonal states that hase to be performed before source exit
+		// first process the exit behavior of orthogonal states that has to be performed before source exit
 		val topExitState = t.exitStates.last
 		if (topExitState != null) {
 			val exitSequence = topExitState.create.exitSequence
@@ -583,13 +619,18 @@ class BehaviorMapping {
 			}]
 		) else null;
 		
-		val guard = if ( t.guardExpression != null ) EcoreUtil::copy(t.guardExpression) else null;
+		val guard = t.buildGuard
 		
 		if ( triggerCheck != null && guard != null ) stext.and(triggerCheck, guard)
 		else if ( triggerCheck != null )  triggerCheck
 		else guard
 	}
-	
+	
+	def dispatch Expression buildGuard( Trigger t) {null}
+	
+	def dispatch Expression buildGuard( ReactionTrigger t) {
+		if ( t.guardExpression != null ) EcoreUtil::copy(t.guardExpression) else null
+	}
 	
 //	def Statement buildValueExpression(TimeEventSpec tes) {
 //		val PrimitiveValueExpression pve = stext.factory.createPrimitiveValueExpression 

BIN
plugins/org.yakindu.sct.model.sexec/xtend-gen/org/yakindu/sct/model/sexec/transformation/.BehaviorMapping.java._trace


+ 137 - 57
plugins/org.yakindu.sct.model.sexec/xtend-gen/org/yakindu/sct/model/sexec/transformation/BehaviorMapping.java

@@ -32,6 +32,7 @@ import org.yakindu.sct.model.sexec.ExecutionRegion;
 import org.yakindu.sct.model.sexec.ExecutionScope;
 import org.yakindu.sct.model.sexec.ExecutionState;
 import org.yakindu.sct.model.sexec.ExecutionSynchronization;
+import org.yakindu.sct.model.sexec.If;
 import org.yakindu.sct.model.sexec.Reaction;
 import org.yakindu.sct.model.sexec.ReactionFired;
 import org.yakindu.sct.model.sexec.ScheduleTimeEvent;
@@ -179,24 +180,15 @@ public class BehaviorMapping {
         }
       }
       List<LocalReaction> _entryReactions = this.sc.entryReactions(state);
-      final Function1<LocalReaction,Sequence> _function = new Function1<LocalReaction,Sequence>() {
-          public Sequence apply(final LocalReaction lr) {
-            Sequence _xifexpression = null;
-            Effect _effect = lr.getEffect();
-            boolean _notEquals = (!Objects.equal(_effect, null));
-            if (_notEquals) {
-              Effect _effect_1 = lr.getEffect();
-              Sequence _mapEffect = BehaviorMapping.this.mapEffect(((ReactionEffect) _effect_1));
-              _xifexpression = _mapEffect;
-            } else {
-              _xifexpression = null;
-            }
-            return _xifexpression;
+      final Function1<LocalReaction,Step> _function = new Function1<LocalReaction,Step>() {
+          public Step apply(final LocalReaction lr) {
+            Step _mapEntryAction = BehaviorMapping.this.mapEntryAction(lr);
+            return _mapEntryAction;
           }
         };
-      List<Sequence> _map = ListExtensions.<LocalReaction, Sequence>map(_entryReactions, _function);
-      final Procedure1<Sequence> _function_1 = new Procedure1<Sequence>() {
-          public void apply(final Sequence e) {
+      List<Step> _map = ListExtensions.<LocalReaction, Step>map(_entryReactions, _function);
+      final Procedure1<Step> _function_1 = new Procedure1<Step>() {
+          public void apply(final Step e) {
             boolean _notEquals = (!Objects.equal(e, null));
             if (_notEquals) {
               EList<Step> _steps = seq.getSteps();
@@ -204,7 +196,7 @@ public class BehaviorMapping {
             }
           }
         };
-      IterableExtensions.<Sequence>forEach(_map, _function_1);
+      IterableExtensions.<Step>forEach(_map, _function_1);
       Sequence _xifexpression = null;
       EList<Step> _steps = seq.getSteps();
       int _size = _steps.size();
@@ -219,6 +211,45 @@ public class BehaviorMapping {
     return _xblockexpression;
   }
   
+  public Step mapEntryAction(final LocalReaction it) {
+    Step _xifexpression = null;
+    Effect _effect = it.getEffect();
+    boolean _notEquals = (!Objects.equal(_effect, null));
+    if (_notEquals) {
+      Step _xblockexpression = null;
+      {
+        Effect _effect_1 = it.getEffect();
+        Sequence effectSeq = this.mapEffect(((ReactionEffect) _effect_1));
+        Trigger _trigger = it.getTrigger();
+        Expression guard = this.buildGuard(_trigger);
+        Step _xifexpression_1 = null;
+        boolean _notEquals_1 = (!Objects.equal(guard, null));
+        if (_notEquals_1) {
+          Step _xblockexpression_1 = null;
+          {
+            SexecFactory _factory = this.sexec.factory();
+            If ifStep = _factory.createIf();
+            SexecFactory _factory_1 = this.sexec.factory();
+            Check _createCheck = _factory_1.createCheck();
+            ifStep.setCheck(_createCheck);
+            Check _check = ifStep.getCheck();
+            _check.setCondition(guard);
+            ifStep.setThenStep(effectSeq);
+            _xblockexpression_1 = (((Step) ifStep));
+          }
+          _xifexpression_1 = _xblockexpression_1;
+        } else {
+          _xifexpression_1 = effectSeq;
+        }
+        _xblockexpression = (_xifexpression_1);
+      }
+      _xifexpression = _xblockexpression;
+    } else {
+      _xifexpression = null;
+    }
+    return _xifexpression;
+  }
+  
   public ExecutionFlow mapChoiceTransitions(final Statechart statechart, final ExecutionFlow r) {
     Iterable<Choice> _allChoices = this.sc.allChoices(statechart);
     final Procedure1<Choice> _function = new Procedure1<Choice>() {
@@ -350,24 +381,15 @@ public class BehaviorMapping {
         }
       }
       List<LocalReaction> _exitReactions = this.sc.exitReactions(state);
-      final Function1<LocalReaction,Sequence> _function = new Function1<LocalReaction,Sequence>() {
-          public Sequence apply(final LocalReaction lr) {
-            Sequence _xifexpression = null;
-            Effect _effect = lr.getEffect();
-            boolean _notEquals = (!Objects.equal(_effect, null));
-            if (_notEquals) {
-              Effect _effect_1 = lr.getEffect();
-              Sequence _mapEffect = BehaviorMapping.this.mapEffect(((ReactionEffect) _effect_1));
-              _xifexpression = _mapEffect;
-            } else {
-              _xifexpression = null;
-            }
-            return _xifexpression;
+      final Function1<LocalReaction,Step> _function = new Function1<LocalReaction,Step>() {
+          public Step apply(final LocalReaction lr) {
+            Step _mapExitAction = BehaviorMapping.this.mapExitAction(lr);
+            return _mapExitAction;
           }
         };
-      List<Sequence> _map = ListExtensions.<LocalReaction, Sequence>map(_exitReactions, _function);
-      final Procedure1<Sequence> _function_1 = new Procedure1<Sequence>() {
-          public void apply(final Sequence e) {
+      List<Step> _map = ListExtensions.<LocalReaction, Step>map(_exitReactions, _function);
+      final Procedure1<Step> _function_1 = new Procedure1<Step>() {
+          public void apply(final Step e) {
             boolean _notEquals = (!Objects.equal(e, null));
             if (_notEquals) {
               EList<Step> _steps = seq.getSteps();
@@ -375,7 +397,7 @@ public class BehaviorMapping {
             }
           }
         };
-      IterableExtensions.<Sequence>forEach(_map, _function_1);
+      IterableExtensions.<Step>forEach(_map, _function_1);
       Sequence _xifexpression = null;
       EList<Step> _steps = seq.getSteps();
       int _size = _steps.size();
@@ -390,6 +412,45 @@ public class BehaviorMapping {
     return _xblockexpression;
   }
   
+  public Step mapExitAction(final LocalReaction it) {
+    Step _xifexpression = null;
+    Effect _effect = it.getEffect();
+    boolean _notEquals = (!Objects.equal(_effect, null));
+    if (_notEquals) {
+      Step _xblockexpression = null;
+      {
+        Effect _effect_1 = it.getEffect();
+        Sequence effectSeq = this.mapEffect(((ReactionEffect) _effect_1));
+        Trigger _trigger = it.getTrigger();
+        Expression guard = this.buildGuard(_trigger);
+        Step _xifexpression_1 = null;
+        boolean _notEquals_1 = (!Objects.equal(guard, null));
+        if (_notEquals_1) {
+          Step _xblockexpression_1 = null;
+          {
+            SexecFactory _factory = this.sexec.factory();
+            If ifStep = _factory.createIf();
+            SexecFactory _factory_1 = this.sexec.factory();
+            Check _createCheck = _factory_1.createCheck();
+            ifStep.setCheck(_createCheck);
+            Check _check = ifStep.getCheck();
+            _check.setCondition(guard);
+            ifStep.setThenStep(effectSeq);
+            _xblockexpression_1 = (((Step) ifStep));
+          }
+          _xifexpression_1 = _xblockexpression_1;
+        } else {
+          _xifexpression_1 = effectSeq;
+        }
+        _xblockexpression = (_xifexpression_1);
+      }
+      _xifexpression = _xblockexpression;
+    } else {
+      _xifexpression = null;
+    }
+    return _xifexpression;
+  }
+  
   protected Sequence _mapEffect(final Effect effect) {
     return null;
   }
@@ -1175,44 +1236,52 @@ public class BehaviorMapping {
         _xifexpression = null;
       }
       final Expression triggerCheck = _xifexpression;
+      final Expression guard = this.buildGuard(t);
       Expression _xifexpression_1 = null;
-      Expression _guardExpression = t.getGuardExpression();
-      boolean _notEquals = (!Objects.equal(_guardExpression, null));
-      if (_notEquals) {
-        Expression _guardExpression_1 = t.getGuardExpression();
-        Expression _copy = EcoreUtil.<Expression>copy(_guardExpression_1);
-        _xifexpression_1 = _copy;
-      } else {
-        _xifexpression_1 = null;
-      }
-      final Expression guard = _xifexpression_1;
-      Expression _xifexpression_2 = null;
       boolean _and = false;
-      boolean _notEquals_1 = (!Objects.equal(triggerCheck, null));
-      if (!_notEquals_1) {
+      boolean _notEquals = (!Objects.equal(triggerCheck, null));
+      if (!_notEquals) {
         _and = false;
       } else {
-        boolean _notEquals_2 = (!Objects.equal(guard, null));
-        _and = (_notEquals_1 && _notEquals_2);
+        boolean _notEquals_1 = (!Objects.equal(guard, null));
+        _and = (_notEquals && _notEquals_1);
       }
       if (_and) {
         Expression _and_1 = this.stext.and(triggerCheck, guard);
-        _xifexpression_2 = _and_1;
+        _xifexpression_1 = _and_1;
       } else {
-        Expression _xifexpression_3 = null;
-        boolean _notEquals_3 = (!Objects.equal(triggerCheck, null));
-        if (_notEquals_3) {
-          _xifexpression_3 = triggerCheck;
+        Expression _xifexpression_2 = null;
+        boolean _notEquals_2 = (!Objects.equal(triggerCheck, null));
+        if (_notEquals_2) {
+          _xifexpression_2 = triggerCheck;
         } else {
-          _xifexpression_3 = guard;
+          _xifexpression_2 = guard;
         }
-        _xifexpression_2 = _xifexpression_3;
+        _xifexpression_1 = _xifexpression_2;
       }
-      _xblockexpression = (_xifexpression_2);
+      _xblockexpression = (_xifexpression_1);
     }
     return _xblockexpression;
   }
   
+  protected Expression _buildGuard(final Trigger t) {
+    return null;
+  }
+  
+  protected Expression _buildGuard(final ReactionTrigger t) {
+    Expression _xifexpression = null;
+    Expression _guardExpression = t.getGuardExpression();
+    boolean _notEquals = (!Objects.equal(_guardExpression, null));
+    if (_notEquals) {
+      Expression _guardExpression_1 = t.getGuardExpression();
+      Expression _copy = EcoreUtil.<Expression>copy(_guardExpression_1);
+      _xifexpression = _copy;
+    } else {
+      _xifexpression = null;
+    }
+    return _xifexpression;
+  }
+  
   public Sequence mapEffect(final Effect effect) {
     if (effect instanceof ReactionEffect) {
       return _mapEffect((ReactionEffect)effect);
@@ -1294,4 +1363,15 @@ public class BehaviorMapping {
         Arrays.<Object>asList(t).toString());
     }
   }
+  
+  public Expression buildGuard(final Trigger t) {
+    if (t instanceof ReactionTrigger) {
+      return _buildGuard((ReactionTrigger)t);
+    } else if (t != null) {
+      return _buildGuard(t);
+    } else {
+      throw new IllegalArgumentException("Unhandled parameter types: " +
+        Arrays.<Object>asList(t).toString());
+    }
+  }
 }

+ 2 - 2
plugins/org.yakindu.sct.simulation.ui/src/org/yakindu/sct/simulation/ui/view/SimulationView.java

@@ -115,8 +115,8 @@ public class SimulationView extends ViewPart implements IDebugContextListener,
 	protected Point mouseLocation;
 
 	protected Viewer createViewer(Composite parent) {
-		viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL
-				| SWT.FULL_SELECTION);
+		viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
+//				| SWT.FULL_SELECTION);
 		viewer.getTree().setHeaderVisible(true);
 		viewer.getTree().setLinesVisible(true);
 		TreeViewerColumn column = new TreeViewerColumn(viewer, SWT.DEFAULT);

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

@@ -56,7 +56,7 @@ public class Assert {
 
 	public static void assertAssignment(Step step, String variableName,
 			AssignmentOperator operator, String value) {
-		assertTrue(step instanceof Execution);
+		assertClass(Execution.class, step);
 		Execution exec = (Execution) step;
 		assertTrue(exec.getStatement() instanceof AssignmentExpression);
 		AssignmentExpression assignment = (AssignmentExpression) exec

+ 43 - 4
test-plugins/org.yakindu.sct.model.sexec.test/src/org/yakindu/sct/model/sexec/transformation/test/ModelSequencerHierarchyTest.java

@@ -1,9 +1,6 @@
 package org.yakindu.sct.model.sexec.transformation.test;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.*;
 import static org.yakindu.sct.model.sexec.transformation.test.SCTTestUtil.TYPE_INTEGER;
 import static org.yakindu.sct.model.sexec.transformation.test.SCTTestUtil.findState;
 import static org.yakindu.sct.model.sgraph.test.util.SgraphTestFactory._createRegion;
@@ -491,4 +488,46 @@ public class ModelSequencerHierarchyTest extends ModelSequencerTest {
 
 	}
 
+	
+	/**
+	 * The transition sequence of a self transition must include the exit and entry sequences of the state.
+	 * 
+	 */
+	@Test
+	public void testExitEntryOnSelfTransition() {
+
+		Statechart sc = _createStatechart("sc");
+		{
+
+			InterfaceScope s_scope = _createInterfaceScope("Interface", sc);
+			VariableDefinition v1 = _createVariableDefinition("v1",
+					TYPE_INTEGER, s_scope);
+
+			Region r = _createRegion("r", sc);
+			{
+				State s1 = _createState("s1", r);
+				{
+					_createExitAssignment(v1, s1, 1);
+				}
+			}
+		}
+
+		_createTransition(findState(sc, "s1"), findState(sc, "s1"));
+
+		ExecutionFlow flow = sequencer.transform(sc);
+
+		ExecutionState _s1 = flow.getStates().get(0);
+		assertEquals("sc.r.s1", _s1.getName());
+		assertNotNull(_s1.getExitAction());
+
+		Reaction _t = _s1.getReactions().get(0);
+		assertTrue(_t.isTransition());
+
+		Sequence _effect = (Sequence) _t.getEffect();
+		assertEquals(2, _effect.getSteps().size());
+
+		assertCall(_effect, 0, _s1.getExitSequence());
+		assertCall(_effect, 1, _s1.getEnterSequence());
+	}
+
 }

+ 151 - 11
test-plugins/org.yakindu.sct.model.sexec.test/src/org/yakindu/sct/model/sexec/transformation/test/ModelSequencerStateReactionTest.java

@@ -2,24 +2,16 @@ package org.yakindu.sct.model.sexec.transformation.test;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 import static org.yakindu.sct.model.sexec.transformation.test.SCTTestUtil.TYPE_INTEGER;
+import static org.yakindu.sct.model.sgraph.test.util.SgraphTestFactory._createEntry;
 import static org.yakindu.sct.model.sgraph.test.util.SgraphTestFactory._createRegion;
 import static org.yakindu.sct.model.sgraph.test.util.SgraphTestFactory._createState;
 import static org.yakindu.sct.model.sgraph.test.util.SgraphTestFactory._createStatechart;
 import static org.yakindu.sct.model.sgraph.test.util.SgraphTestFactory._createTransition;
-import static org.yakindu.sct.model.stext.test.util.StextTestFactory._createEventDefinition;
-import static org.yakindu.sct.model.stext.test.util.StextTestFactory._createInterfaceScope;
-import static org.yakindu.sct.model.stext.test.util.StextTestFactory._createLocalReaction;
-import static org.yakindu.sct.model.stext.test.util.StextTestFactory._createOncycleEventSpec;
-import static org.yakindu.sct.model.stext.test.util.StextTestFactory._createReactionTrigger;
-import static org.yakindu.sct.model.stext.test.util.StextTestFactory._createRegularEventSpec;
-import static org.yakindu.sct.model.stext.test.util.StextTestFactory._createTimeEventSpec;
-import static org.yakindu.sct.model.stext.test.util.StextTestFactory._createTimeTriggeredReaction;
-import static org.yakindu.sct.model.stext.test.util.StextTestFactory._createValue;
-import static org.yakindu.sct.model.stext.test.util.StextTestFactory._createVariableAssignment;
-import static org.yakindu.sct.model.stext.test.util.StextTestFactory._createVariableDefinition;
+import static org.yakindu.sct.model.stext.test.util.StextTestFactory.*;
 
 import org.junit.Test;
 import org.yakindu.base.base.NamedElement;
@@ -31,6 +23,8 @@ import org.yakindu.sct.model.sexec.ScheduleTimeEvent;
 import org.yakindu.sct.model.sexec.Sequence;
 import org.yakindu.sct.model.sexec.TimeEvent;
 import org.yakindu.sct.model.sexec.UnscheduleTimeEvent;
+import org.yakindu.sct.model.sgraph.Entry;
+import org.yakindu.sct.model.sgraph.EntryKind;
 import org.yakindu.sct.model.sgraph.Region;
 import org.yakindu.sct.model.sgraph.SGraphFactory;
 import org.yakindu.sct.model.sgraph.Scope;
@@ -262,6 +256,152 @@ public class ModelSequencerStateReactionTest extends ModelSequencerTest {
 		assertBoolLiteral(false, guard.getValue());
 	}
 
+	/**
+	 * If a entry trigger is combined with a guard condition then the entry action is executed conditionally with this trigger.
+	 */
+	@Test
+	public void testEntryActionWithGuard() {
+	
+		Statechart sc = _createStatechart("test");
+		Scope scope = _createInterfaceScope("interface", sc);
+		VariableDefinition v1 = _createVariableDefinition("v1", TYPE_INTEGER,
+				scope);
+		Region r = _createRegion("main", sc);
+		Entry e = _createEntry(EntryKind.INITIAL, null, r);
+		State s1 = _createState("s1", r);
+		State s2 = _createState("s2", r);
+		_createTransition(e, s1);
+		_createTransition(s1, s2);
+		LocalReaction entryAction = _createEntryAction(s2);
+		_createVariableAssignment(v1, AssignmentOperator.ASSIGN,
+				_createValue(42), (ReactionEffect) entryAction.getEffect());
+		((ReactionTrigger)entryAction.getTrigger()).setGuardExpression(_createValue(true));
+		
+		ExecutionFlow flow = sequencer.transform(sc);
+		
+		ExecutionState _s1 = flow.getStates().get(0);
+		ExecutionState _s2 = flow.getStates().get(1);
+		assertEquals(s1.getName(), _s1.getSimpleName());
+		assertEquals(s2.getName(), _s2.getSimpleName());
+
+		Sequence _entrySeq = (Sequence) _s2.getEntryAction();
+		
+		assertClass(If.class, _entrySeq.getSteps().get(0));
+		assertClass(PrimitiveValueExpression.class, ((If)_entrySeq.getSteps().get(0)).getCheck().getCondition());
+		assertAssignment( ((Sequence)((If)_entrySeq.getSteps().get(0)).getThenStep()).getSteps().get(0), "v1", AssignmentOperator.ASSIGN, "42");
+		
+	}
+
+
+	/**
+	 * If a entry trigger is combined with a guard condition then the entry action is executed conditionally with this trigger.
+	 */
+	@Test
+	public void testEntryActionWithoutGuard() {
+	
+		Statechart sc = _createStatechart("test");
+		Scope scope = _createInterfaceScope("interface", sc);
+		VariableDefinition v1 = _createVariableDefinition("v1", TYPE_INTEGER,
+				scope);
+		Region r = _createRegion("main", sc);
+		Entry e = _createEntry(EntryKind.INITIAL, null, r);
+		State s1 = _createState("s1", r);
+		State s2 = _createState("s2", r);
+		_createTransition(e, s1);
+		_createTransition(s1, s2);
+		LocalReaction entryAction = _createEntryAction(s2);
+		_createVariableAssignment(v1, AssignmentOperator.ASSIGN,
+				_createValue(42), (ReactionEffect) entryAction.getEffect());
+//		((ReactionTrigger)entryAction.getTrigger()).setGuardExpression(_createValue(true));
+		
+		ExecutionFlow flow = sequencer.transform(sc);
+		
+		ExecutionState _s1 = flow.getStates().get(0);
+		ExecutionState _s2 = flow.getStates().get(1);
+		assertEquals(s1.getName(), _s1.getSimpleName());
+		assertEquals(s2.getName(), _s2.getSimpleName());
+
+		Sequence _entrySeq = (Sequence) _s2.getEntryAction();
+		
+		assertClass(Sequence.class, _entrySeq.getSteps().get(0));
+		assertAssignment( ((Sequence)_entrySeq.getSteps().get(0)).getSteps().get(0), "v1", AssignmentOperator.ASSIGN, "42");
+		
+	}
+
+
+	/**
+	 * If a entry trigger is combined with a guard condition then the entry action is executed conditionally with this trigger.
+	 */
+	@Test
+	public void testExitActionWithGuard() {
+	
+		Statechart sc = _createStatechart("test");
+		Scope scope = _createInterfaceScope("interface", sc);
+		VariableDefinition v1 = _createVariableDefinition("v1", TYPE_INTEGER,
+				scope);
+		Region r = _createRegion("main", sc);
+		Entry e = _createEntry(EntryKind.INITIAL, null, r);
+		State s1 = _createState("s1", r);
+		State s2 = _createState("s2", r);
+		_createTransition(e, s1);
+		_createTransition(s1, s2);
+		LocalReaction exitAction = _createExitAction(s2);
+		_createVariableAssignment(v1, AssignmentOperator.ASSIGN,
+				_createValue(42), (ReactionEffect) exitAction.getEffect());
+		((ReactionTrigger)exitAction.getTrigger()).setGuardExpression(_createValue(true));
+		
+		ExecutionFlow flow = sequencer.transform(sc);
+		
+		ExecutionState _s1 = flow.getStates().get(0);
+		ExecutionState _s2 = flow.getStates().get(1);
+		assertEquals(s1.getName(), _s1.getSimpleName());
+		assertEquals(s2.getName(), _s2.getSimpleName());
+
+		Sequence _exitSeq = (Sequence) _s2.getExitAction();
+		
+		assertClass(If.class, _exitSeq.getSteps().get(0));
+		assertClass(PrimitiveValueExpression.class, ((If)_exitSeq.getSteps().get(0)).getCheck().getCondition());
+		assertAssignment( ((Sequence)((If)_exitSeq.getSteps().get(0)).getThenStep()).getSteps().get(0), "v1", AssignmentOperator.ASSIGN, "42");
+		
+	}
+
+
+	/**
+	 * If a entry trigger is combined with a guard condition then the entry action is executed conditionally with this trigger.
+	 */
+	@Test
+	public void testExitActionWithoutGuard() {
+	
+		Statechart sc = _createStatechart("test");
+		Scope scope = _createInterfaceScope("interface", sc);
+		VariableDefinition v1 = _createVariableDefinition("v1", TYPE_INTEGER,
+				scope);
+		Region r = _createRegion("main", sc);
+		Entry e = _createEntry(EntryKind.INITIAL, null, r);
+		State s1 = _createState("s1", r);
+		State s2 = _createState("s2", r);
+		_createTransition(e, s1);
+		_createTransition(s1, s2);
+		LocalReaction exitAction = _createExitAction(s2);
+		_createVariableAssignment(v1, AssignmentOperator.ASSIGN,
+				_createValue(42), (ReactionEffect) exitAction.getEffect());
+//		((ReactionTrigger)entryAction.getTrigger()).setGuardExpression(_createValue(true));
+		
+		ExecutionFlow flow = sequencer.transform(sc);
+		
+		ExecutionState _s1 = flow.getStates().get(0);
+		ExecutionState _s2 = flow.getStates().get(1);
+		assertEquals(s1.getName(), _s1.getSimpleName());
+		assertEquals(s2.getName(), _s2.getSimpleName());
+
+		Sequence _exitSeq = (Sequence) _s2.getExitAction();
+		
+		assertClass(Sequence.class, _exitSeq.getSteps().get(0));
+		assertAssignment( ((Sequence)_exitSeq.getSteps().get(0)).getSteps().get(0), "v1", AssignmentOperator.ASSIGN, "42");
+		
+	}
+
+
 	/**
 	 * If a time trigger is defined for a transition then an event must be
 	 * introduced into the execution flow.

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

@@ -65,6 +65,7 @@ public class SelfTransitionTest extends ModelSequencerTest {
 		EList<Reaction> _t = _s2.getReactions();
 
 		Reaction tr0 = _t.get(0);
-		assertCall(assertedSequence(tr0.getEffect()), 0, _s2.getEnterSequence());
+		assertCall(assertedSequence(tr0.getEffect()), 0, _s2.getExitSequence());
+		assertCall(assertedSequence(tr0.getEffect()), 1, _s2.getEnterSequence());
 	}
 }