Parcourir la source

entry and exit actions are now handled correctly (#208)

terfloth@itemis.de il y a 13 ans
Parent
commit
483deda529

+ 9 - 6
plugins/org.yakindu.sct.model.sexec/src/org/yakindu/sct/model/sexec/transformation/ModelSequencer.xtend

@@ -217,7 +217,7 @@ class ModelSequencer {
 
 		if (t.source != null) sequence.steps.add(newExitStateStep(t.source as State))
 		if (t.effect != null) sequence.steps.add(t.effect.mapEffect)		
-		if (t.target != null) sequence.steps.add(newEnterStateStep(t.target as State))
+		if (t.target != null && t.target instanceof State) sequence.steps.add(newEnterStateStep(t.target as State))
 	
 		if (t.target instanceof State && (t.target as State).create.entryAction != null) 
 			sequence.steps.add( (t.target as State).create.entryAction.newCall)
@@ -519,20 +519,23 @@ class ModelSequencer {
 	/**
 	 * Returns a list of all local reactions defined for a state. This includes also entry and exit actions but excludes 
 	 * local reactions of child states.
+	 * 
+	 * TODO: remove this function as soon the localReactions property in the sgraph model is correctly derived.
 	 */
-	def List<LocalReaction> localReactions(State state)	{
-		state.scopes.get(0).declarations.filter(typeof(LocalReaction)).toList
+	def List<LocalReaction> localReactions_(State state)	{
+		if (state.scopes != null && state.scopes.size > 0 ) state.scopes.get(0).declarations.filter(typeof(LocalReaction)).toList
+		else new ArrayList<LocalReaction>()
 	}
-	
+	 
 	def List<LocalReaction> entryReactions(State state) {
-		state.localReactions()
+		state.localReactions
 			.filter(r | ((r as LocalReaction).trigger as ReactionTrigger).triggers.exists( t | t instanceof EntryEvent))
 			.map(lr | lr as LocalReaction)
 			.toList	
 	} 
 	
 	def List<LocalReaction> exitReactions(State state) {
-		state.localReactions()
+		state.localReactions
 			.filter(r | ((r as LocalReaction).trigger as ReactionTrigger).triggers.exists( t | t instanceof ExitEvent))
 			.map(lr | lr as LocalReaction)
 			.toList	

+ 13 - 1
plugins/org.yakindu.sct.model.sexec/src/org/yakindu/sct/model/sexec/transformation/StatechartExtensions.xtend

@@ -38,6 +38,7 @@ class StatechartExtensions {
 	}
 
 
+
 	//=================================================================
 	// navigation and query util extensions
 	//
@@ -59,12 +60,23 @@ class StatechartExtensions {
 	 */
 	def List<TimeEventSpec> timeEventSpecs(State state) { 
 		// TODO: also query local reactions
-		state.outgoingTransitions.fold(new ArrayList<TimeEventSpec>(), 
+		var tesList = new ArrayList<TimeEventSpec>()
+		
+		state.outgoingTransitions.fold(tesList, 
+			[s, r | {
+				EcoreUtil2::eAllContentsAsList(r).filter(typeof (TimeEventSpec)).forEach(tes | s.add(tes))
+				s
+			}]
+		)
+
+		state.localReactions.fold(tesList, 
 			[s, r | {
 				EcoreUtil2::eAllContentsAsList(r).filter(typeof (TimeEventSpec)).forEach(tes | s.add(tes))
 				s
 			}]
 		)
+				
+		return tesList
 	}
 
 	//=================================================================

+ 58 - 32
plugins/org.yakindu.sct.model.sexec/xtend-gen/org/yakindu/sct/model/sexec/transformation/ModelSequencer.java

@@ -169,7 +169,7 @@ public class ModelSequencer {
       List<EObject> content = _eAllContentsAsList;
       final Function1<EObject,Boolean> _function = new Function1<EObject,Boolean>() {
           public Boolean apply(final EObject e) {
-            return ((Boolean)(e instanceof org.yakindu.sct.model.sgraph.State));
+            return (e instanceof org.yakindu.sct.model.sgraph.State);
           }
         };
       Iterable<EObject> _filter = IterableExtensions.<EObject>filter(content, _function);
@@ -225,7 +225,7 @@ public class ModelSequencer {
       final List<TimeEventSpec> timeEventSpecs = _timeEventSpecs;
       ArrayList<TimeEvent> _arrayList = new ArrayList<TimeEvent>();
       final ArrayList<TimeEvent> result = _arrayList;
-      for (final TimeEventSpec tes : timeEventSpecs) {
+      for (TimeEventSpec tes : timeEventSpecs) {
         {
           TimeEvent _createDerivedEvent = this.createDerivedEvent(tes);
           final TimeEvent timeEvent = _createDerivedEvent;
@@ -253,7 +253,7 @@ public class ModelSequencer {
       List<EObject> content = _eAllContentsAsList;
       final Function1<EObject,Boolean> _function = new Function1<EObject,Boolean>() {
           public Boolean apply(final EObject e) {
-            return ((Boolean)(e instanceof org.yakindu.sct.model.sgraph.State));
+            return (e instanceof org.yakindu.sct.model.sgraph.State);
           }
         };
       Iterable<EObject> _filter = IterableExtensions.<EObject>filter(content, _function);
@@ -344,29 +344,36 @@ public class ModelSequencer {
         Sequence _mapEffect = this.mapEffect(_effect_1);
         _steps_2.add(_mapEffect);
       }
+      boolean _operator_and_1 = false;
       Vertex _target = t.getTarget();
       boolean _operator_notEquals_3 = ObjectExtensions.operator_notEquals(_target, null);
-      if (_operator_notEquals_3) {
-        EList<Step> _steps_3 = sequence.getSteps();
+      if (!_operator_notEquals_3) {
+        _operator_and_1 = false;
+      } else {
         Vertex _target_1 = t.getTarget();
-        EnterState _newEnterStateStep = this.newEnterStateStep(((State) _target_1));
+        _operator_and_1 = BooleanExtensions.operator_and(_operator_notEquals_3, (_target_1 instanceof org.yakindu.sct.model.sgraph.State));
+      }
+      if (_operator_and_1) {
+        EList<Step> _steps_3 = sequence.getSteps();
+        Vertex _target_2 = t.getTarget();
+        EnterState _newEnterStateStep = this.newEnterStateStep(((State) _target_2));
         _steps_3.add(_newEnterStateStep);
       }
-      boolean _operator_and_1 = false;
-      Vertex _target_2 = t.getTarget();
-      if (!(_target_2 instanceof org.yakindu.sct.model.sgraph.State)) {
-        _operator_and_1 = false;
+      boolean _operator_and_2 = false;
+      Vertex _target_3 = t.getTarget();
+      if (!(_target_3 instanceof org.yakindu.sct.model.sgraph.State)) {
+        _operator_and_2 = false;
       } else {
-        Vertex _target_3 = t.getTarget();
-        ExecutionState _create_2 = this.factory.create(((State) _target_3));
+        Vertex _target_4 = t.getTarget();
+        ExecutionState _create_2 = this.factory.create(((State) _target_4));
         Step _entryAction = _create_2.getEntryAction();
         boolean _operator_notEquals_4 = ObjectExtensions.operator_notEquals(_entryAction, null);
-        _operator_and_1 = BooleanExtensions.operator_and((_target_2 instanceof org.yakindu.sct.model.sgraph.State), _operator_notEquals_4);
+        _operator_and_2 = BooleanExtensions.operator_and((_target_3 instanceof org.yakindu.sct.model.sgraph.State), _operator_notEquals_4);
       }
-      if (_operator_and_1) {
+      if (_operator_and_2) {
         EList<Step> _steps_4 = sequence.getSteps();
-        Vertex _target_4 = t.getTarget();
-        ExecutionState _create_3 = this.factory.create(((State) _target_4));
+        Vertex _target_5 = t.getTarget();
+        ExecutionState _create_3 = this.factory.create(((State) _target_5));
         Step _entryAction_1 = _create_3.getEntryAction();
         Call _newCall_1 = this.factory.newCall(_entryAction_1);
         _steps_4.add(_newCall_1);
@@ -427,7 +434,7 @@ public class ModelSequencer {
       final Sequence seq = _createSequence;
       seq.setName("entryAction");
       List<TimeEventSpec> _timeEventSpecs = this.sct.timeEventSpecs(state);
-      for (final TimeEventSpec tes : _timeEventSpecs) {
+      for (TimeEventSpec tes : _timeEventSpecs) {
         {
           TimeEvent _createDerivedEvent = this.createDerivedEvent(tes);
           final TimeEvent timeEvent = _createDerivedEvent;
@@ -569,7 +576,7 @@ public class ModelSequencer {
       final Sequence seq = _createSequence;
       seq.setName("exitAction");
       List<TimeEventSpec> _timeEventSpecs = this.sct.timeEventSpecs(state);
-      for (final TimeEventSpec tes : _timeEventSpecs) {
+      for (TimeEventSpec tes : _timeEventSpecs) {
         {
           TimeEvent _createDerivedEvent = this.createDerivedEvent(tes);
           final TimeEvent timeEvent = _createDerivedEvent;
@@ -773,7 +780,7 @@ public class ModelSequencer {
   
   public TimeEvent createDerivedEvent(final TimeEventSpec tes) {
     final ArrayList<?>_cacheKey = CollectionLiterals.newArrayList(tes);
-    final TimeEvent r;
+    TimeEvent r;
     synchronized (_createCache_createDerivedEvent) {
       if (_createCache_createDerivedEvent.containsKey(_cacheKey)) {
         return _createCache_createDerivedEvent.get(_cacheKey);
@@ -793,7 +800,7 @@ public class ModelSequencer {
   
   public Scope timeEventScope(final ExecutionFlow flow) {
     final ArrayList<?>_cacheKey = CollectionLiterals.newArrayList(flow);
-    final Scope r;
+    Scope r;
     synchronized (_createCache_timeEventScope) {
       if (_createCache_timeEventScope.containsKey(_cacheKey)) {
         return _createCache_timeEventScope.get(_cacheKey);
@@ -826,7 +833,7 @@ public class ModelSequencer {
       ArrayList<Step> _arrayList = new ArrayList<Step>();
       final ArrayList<Step> enterSteps = _arrayList;
       EList<Region> _regions = sc.getRegions();
-      for (final Region r : _regions) {
+      for (Region r : _regions) {
         {
           Entry _entry = this.entry(r);
           State _target = this==null?(State)null:this.target(_entry);
@@ -834,7 +841,8 @@ public class ModelSequencer {
           final EnterState step = _newEnterStateStep;
           boolean _operator_notEquals = ObjectExtensions.operator_notEquals(step, null);
           if (_operator_notEquals) {
-            enterSteps.add(step);
+            final ArrayList<Step> typeConverted_enterSteps = (ArrayList<Step>)enterSteps;
+            typeConverted_enterSteps.add(step);
           }
         }
       }
@@ -909,7 +917,7 @@ public class ModelSequencer {
       final List<EObject> declared = _list;
       final Function1<EObject,Boolean> _function_1 = new Function1<EObject,Boolean>() {
           public Boolean apply(final EObject e_1) {
-            return ((Boolean)(e_1 instanceof org.yakindu.sct.model.stext.stext.ElementReferenceExpression));
+            return (e_1 instanceof org.yakindu.sct.model.stext.stext.ElementReferenceExpression);
           }
         };
       Iterable<EObject> _filter_1 = IterableExtensions.<EObject>filter(allContent, _function_1);
@@ -928,7 +936,7 @@ public class ModelSequencer {
       IterableExtensions.<ElementReferenceExpression>forEach(_map, _function_3);
       final Function1<EObject,Boolean> _function_4 = new Function1<EObject,Boolean>() {
           public Boolean apply(final EObject e_2) {
-            return ((Boolean)(e_2 instanceof org.yakindu.sct.model.stext.stext.Assignment));
+            return (e_2 instanceof org.yakindu.sct.model.stext.stext.Assignment);
           }
         };
       Iterable<EObject> _filter_2 = IterableExtensions.<EObject>filter(allContent, _function_4);
@@ -1055,13 +1063,31 @@ public class ModelSequencer {
     return _xifexpression;
   }
   
-  public List<LocalReaction> localReactions(final State state) {
+  public List<LocalReaction> localReactions_(final State state) {
+    List<LocalReaction> _xifexpression = null;
+    boolean _operator_and = false;
     EList<Scope> _scopes = state.getScopes();
-    Scope _get = _scopes.get(0);
-    EList<Declaration> _declarations = _get.getDeclarations();
-    Iterable<LocalReaction> _filter = IterableExtensions.<LocalReaction>filter(_declarations, org.yakindu.sct.model.stext.stext.LocalReaction.class);
-    List<LocalReaction> _list = IterableExtensions.<LocalReaction>toList(_filter);
-    return _list;
+    boolean _operator_notEquals = ObjectExtensions.operator_notEquals(_scopes, null);
+    if (!_operator_notEquals) {
+      _operator_and = false;
+    } else {
+      EList<Scope> _scopes_1 = state.getScopes();
+      int _size = _scopes_1.size();
+      boolean _operator_greaterThan = ComparableExtensions.<Integer>operator_greaterThan(((Integer)_size), ((Integer)0));
+      _operator_and = BooleanExtensions.operator_and(_operator_notEquals, _operator_greaterThan);
+    }
+    if (_operator_and) {
+      EList<Scope> _scopes_2 = state.getScopes();
+      Scope _get = _scopes_2.get(0);
+      EList<Declaration> _declarations = _get.getDeclarations();
+      Iterable<LocalReaction> _filter = IterableExtensions.<LocalReaction>filter(_declarations, org.yakindu.sct.model.stext.stext.LocalReaction.class);
+      List<LocalReaction> _list = IterableExtensions.<LocalReaction>toList(_filter);
+      _xifexpression = _list;
+    } else {
+      ArrayList<LocalReaction> _arrayList = new ArrayList<LocalReaction>();
+      _xifexpression = _arrayList;
+    }
+    return _xifexpression;
   }
   
   public List<LocalReaction> entryReactions(final State state) {
@@ -1072,7 +1098,7 @@ public class ModelSequencer {
           EList<EventSpec> _triggers = ((ReactionTrigger) _trigger).getTriggers();
           final Function1<EventSpec,Boolean> _function_1 = new Function1<EventSpec,Boolean>() {
               public Boolean apply(final EventSpec t) {
-                return ((Boolean)(t instanceof org.yakindu.sct.model.stext.stext.EntryEvent));
+                return (t instanceof org.yakindu.sct.model.stext.stext.EntryEvent);
               }
             };
           boolean _exists = IterableExtensions.<EventSpec>exists(_triggers, _function_1);
@@ -1098,7 +1124,7 @@ public class ModelSequencer {
           EList<EventSpec> _triggers = ((ReactionTrigger) _trigger).getTriggers();
           final Function1<EventSpec,Boolean> _function_1 = new Function1<EventSpec,Boolean>() {
               public Boolean apply(final EventSpec t) {
-                return ((Boolean)(t instanceof org.yakindu.sct.model.stext.stext.ExitEvent));
+                return (t instanceof org.yakindu.sct.model.stext.stext.ExitEvent);
               }
             };
           boolean _exists = IterableExtensions.<EventSpec>exists(_triggers, _function_1);

+ 44 - 21
plugins/org.yakindu.sct.model.sexec/xtend-gen/org/yakindu/sct/model/sexec/transformation/StatechartExtensions.java

@@ -113,28 +113,51 @@ public class StatechartExtensions {
   }
   
   public List<TimeEventSpec> timeEventSpecs(final State state) {
-    EList<Transition> _outgoingTransitions = state.getOutgoingTransitions();
-    ArrayList<TimeEventSpec> _arrayList = new ArrayList<TimeEventSpec>();
-    final Function2<ArrayList<TimeEventSpec>,Transition,ArrayList<TimeEventSpec>> _function = new Function2<ArrayList<TimeEventSpec>,Transition,ArrayList<TimeEventSpec>>() {
-        public ArrayList<TimeEventSpec> apply(final ArrayList<TimeEventSpec> s , final Transition r) {
-          ArrayList<TimeEventSpec> _xblockexpression = null;
-          {
-            List<EObject> _eAllContentsAsList = EcoreUtil2.eAllContentsAsList(r);
-            Iterable<TimeEventSpec> _filter = IterableExtensions.<TimeEventSpec>filter(_eAllContentsAsList, org.yakindu.sct.model.stext.stext.TimeEventSpec.class);
-            final Function1<TimeEventSpec,Boolean> _function_1 = new Function1<TimeEventSpec,Boolean>() {
-                public Boolean apply(final TimeEventSpec tes) {
-                  boolean _add = s.add(tes);
-                  return ((Boolean)_add);
-                }
-              };
-            IterableExtensions.<TimeEventSpec>forEach(_filter, _function_1);
-            _xblockexpression = (s);
+    {
+      ArrayList<TimeEventSpec> _arrayList = new ArrayList<TimeEventSpec>();
+      ArrayList<TimeEventSpec> tesList = _arrayList;
+      EList<Transition> _outgoingTransitions = state.getOutgoingTransitions();
+      final Function2<ArrayList<TimeEventSpec>,Transition,ArrayList<TimeEventSpec>> _function = new Function2<ArrayList<TimeEventSpec>,Transition,ArrayList<TimeEventSpec>>() {
+          public ArrayList<TimeEventSpec> apply(final ArrayList<TimeEventSpec> s , final Transition r) {
+            ArrayList<TimeEventSpec> _xblockexpression = null;
+            {
+              List<EObject> _eAllContentsAsList = EcoreUtil2.eAllContentsAsList(r);
+              Iterable<TimeEventSpec> _filter = IterableExtensions.<TimeEventSpec>filter(_eAllContentsAsList, org.yakindu.sct.model.stext.stext.TimeEventSpec.class);
+              final Function1<TimeEventSpec,Boolean> _function_1 = new Function1<TimeEventSpec,Boolean>() {
+                  public Boolean apply(final TimeEventSpec tes) {
+                    boolean _add = s.add(tes);
+                    return ((Boolean)_add);
+                  }
+                };
+              IterableExtensions.<TimeEventSpec>forEach(_filter, _function_1);
+              _xblockexpression = (s);
+            }
+            return _xblockexpression;
           }
-          return _xblockexpression;
-        }
-      };
-    ArrayList<TimeEventSpec> _fold = IterableExtensions.<Transition, ArrayList<TimeEventSpec>>fold(_outgoingTransitions, _arrayList, _function);
-    return _fold;
+        };
+      IterableExtensions.<Transition, ArrayList<TimeEventSpec>>fold(_outgoingTransitions, tesList, _function);
+      EList<Reaction> _localReactions = state.getLocalReactions();
+      final Function2<ArrayList<TimeEventSpec>,Reaction,ArrayList<TimeEventSpec>> _function_2 = new Function2<ArrayList<TimeEventSpec>,Reaction,ArrayList<TimeEventSpec>>() {
+          public ArrayList<TimeEventSpec> apply(final ArrayList<TimeEventSpec> s_1 , final Reaction r_1) {
+            ArrayList<TimeEventSpec> _xblockexpression_1 = null;
+            {
+              List<EObject> _eAllContentsAsList_1 = EcoreUtil2.eAllContentsAsList(r_1);
+              Iterable<TimeEventSpec> _filter_1 = IterableExtensions.<TimeEventSpec>filter(_eAllContentsAsList_1, org.yakindu.sct.model.stext.stext.TimeEventSpec.class);
+              final Function1<TimeEventSpec,Boolean> _function_3 = new Function1<TimeEventSpec,Boolean>() {
+                  public Boolean apply(final TimeEventSpec tes_1) {
+                    boolean _add_1 = s_1.add(tes_1);
+                    return ((Boolean)_add_1);
+                  }
+                };
+              IterableExtensions.<TimeEventSpec>forEach(_filter_1, _function_3);
+              _xblockexpression_1 = (s_1);
+            }
+            return _xblockexpression_1;
+          }
+        };
+      IterableExtensions.<Reaction, ArrayList<TimeEventSpec>>fold(_localReactions, tesList, _function_2);
+      return tesList;
+    }
   }
   
   protected String _id(final Object obj) {

+ 16 - 7
test-plugins/org.yakindu.sct.model.sexec.test/src/org/yakindu/sct/model/sexec/transformation/test/ModelSequencerTest.java

@@ -731,8 +731,7 @@ public class ModelSequencerTest {
 		assertEquals("1", ((PrimitiveValueExpression)multiply.getLeftOperand()).getValue());
 		assertEquals("1000", ((PrimitiveValueExpression)multiply.getRightOperand()).getValue());
 		assertEquals(MultiplicativeOperator.MUL, multiply.getOperator());
-				
-		
+						
 		// assert the unscheduling of the time events during state exit
 		assertNotNull(_s.getExitAction());
 		Sequence exitAction = (Sequence) _s.getExitAction();
@@ -757,14 +756,24 @@ public class ModelSequencerTest {
 		ExecutionFlow flow = sequencer.transform(sc);
 		
 		Scope timerScope = flow.getScopes().get(1);
-		assertTrue(timerScope.getDeclarations().get(0) instanceof EventDefinition);
+		assertTrue(timerScope.getDeclarations().get(0) instanceof TimeEvent);
 		
+		TimeEvent te = (TimeEvent) timerScope.getDeclarations().get(0);
 		
-		fail("incomplete test: time event check");
+		// assert that the reaction check checks the time event
+		ExecutionState _s = flow.getStates().get(0);
 
-		fail("incomplete test: scheduling time events");
-		
-		fail("incomplete test: unscheduling time events");
+		// assert the scheduling of the time event during state entry
+		assertNotNull(_s.getEntryAction());
+		Sequence entryAction = (Sequence) _s.getEntryAction();
+		ScheduleTimeEvent ste = (ScheduleTimeEvent) entryAction.getSteps().get(0);
+		assertSame(te, ste.getTimeEvent());
+		PrimitiveValueExpression value = (PrimitiveValueExpression) ste.getTimeValue();
+		assertEquals("2", value.getValue());
+		assertNotNull(_s.getExitAction());
+		Sequence exitAction = (Sequence) _s.getExitAction();
+		UnscheduleTimeEvent ute = (UnscheduleTimeEvent) exitAction.getSteps().get(0);
+		assertSame(te, ute.getTimeEvent());
 
 	}
 

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

@@ -139,16 +139,16 @@ public class SCTTestUtil {
 	}
 
 	
-	public static LocalReaction _createEntryAction(ReactiveElement parent) {
+	public static LocalReaction _createEntryAction(State parent) {
 		return _createLocalRection(parent, StextFactory.eINSTANCE.createEntryEvent() );
 	}
 	
 	
-	public static LocalReaction _createExitAction(ReactiveElement parent) {
+	public static LocalReaction _createExitAction(State parent) {
 		return _createLocalRection(parent, StextFactory.eINSTANCE.createExitEvent() );
 	}
 	
-	public static LocalReaction _createTimeTriggeredReaction(ReactiveElement parent, TimeEventType type, int value, TimeUnit unit) {
+	public static LocalReaction _createTimeTriggeredReaction(State parent, TimeEventType type, int value, TimeUnit unit) {
 //		TimeEventSpec timeTrigger = StextFactory.eINSTANCE.createTimeEventSpec();
 //		timeTrigger.setType(type);
 //		timeTrigger.setValue(value);
@@ -157,14 +157,25 @@ public class SCTTestUtil {
 	}
 	
 
-	public static LocalReaction _createLocalRection(ReactiveElement parent, EventSpec triggerEvent) {
+	public static LocalReaction _createLocalRection(State parent, EventSpec triggerEvent) {
 		LocalReaction reaction = StextFactory.eINSTANCE.createLocalReaction();
 		ReactionTrigger trigger = StextFactory.eINSTANCE.createReactionTrigger();
 		_createReactionEffect(reaction);
 		
 		trigger.getTriggers().add(triggerEvent);
 		reaction.setTrigger(trigger);
-		if (parent != null) parent.getLocalReactions().add(reaction);
+
+		Scope scope = null;
+		if (parent != null) {
+			if (parent.getScopes().size() > 0 ) {
+				scope = parent.getScopes().get(0);
+			} else {
+				scope = StextFactory.eINSTANCE.createSimpleScope();
+				parent.getScopes().add(scope);
+			}
+		}
+		
+		scope.getDeclarations().add(reaction);
 		
 		return reaction;
 	}