Procházet zdrojové kódy

Added support for final states ( YAKHMI-311 )

terfloth@itemis.de před 14 roky
rodič
revize
bafbae7c0c

+ 4 - 2
plugins/org.yakindu.sct.model.sexec/src/org/yakindu/sct/model/sexec/transformation/FactoryExtension.xtend

@@ -35,6 +35,8 @@ import org.yakindu.sct.model.sexec.ScheduleTimeEvent
 import org.yakindu.sct.model.sgraph.Statement
 import org.yakindu.sct.model.sexec.UnscheduleTimeEvent
 import org.yakindu.sct.model.stext.stext.LocalReaction
+import org.yakindu.sct.model.sgraph.RegularState
+import org.yakindu.sct.model.sgraph.FinalState
 
 class FactoryExtension {
 	
@@ -59,9 +61,9 @@ class FactoryExtension {
 	def VariableDefinition create r : EcoreUtil::copy(v) create(VariableDefinition v) {}
 	
 	
-	def ExecutionState create r : sexecFactory.createExecutionState create(State state){
+	def ExecutionState create r : sexecFactory.createExecutionState create(RegularState state){
 		if (state != null) {
-			r.simpleName = state.name
+			r.simpleName = if (state instanceof FinalState) "_final_" else state.name
 			r.name = state.fullyQualifiedName.toString.replaceAll(" ", "")		
 		}
 	}

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

@@ -66,6 +66,8 @@ import org.yakindu.sct.model.stext.stext.AlwaysEvent
 import org.yakindu.sct.model.stext.stext.IntLiteral
 import org.yakindu.sct.model.stext.stext.BoolLiteral
 import javax.sound.sampled.BooleanControl$Type
+import org.yakindu.sct.model.sgraph.RegularState
+import org.yakindu.sct.model.sgraph.FinalState
 
 class ModelSequencer {
 	
@@ -149,22 +151,31 @@ class ModelSequencer {
 		
 	def ExecutionFlow mapStates(Statechart statechart, ExecutionFlow r){
 		var content = EcoreUtil2::eAllContentsAsList(statechart)
-		val allStates = statechart.allStates
+		val allStates = statechart.allRegularStates
 		r.states.addAll(allStates.map( s | s.mapState));
 		return r
 	}
 
 
 	// TODO : move to other extension
-	def List<State> allStates(Statechart sc) {
+	def List<RegularState> allRegularStates(Statechart sc) {
 		var content = EcoreUtil2::eAllContentsAsList(sc)
-		val allStates = content.filter( typeof(State) )
+		val allStates = content.filter( typeof(RegularState) )
 		
 		return allStates.toList
 	}
 	
 	
-	def ExecutionState mapState(State state) {
+	
+	def dispatch ExecutionState mapState(FinalState state) {
+		val _state = state.create
+		_state.leaf = true
+		_state.entryAction = null
+		_state.exitAction = null
+		return _state		
+	}
+	
+	def dispatch ExecutionState mapState(State state) {
 		val _state = state.create
 		_state.leaf = state.simple
 		_state.entryAction = state.mapEntryAction
@@ -172,6 +183,8 @@ class ModelSequencer {
 		return _state
 	}
 	 
+	def dispatch ExecutionState mapState(RegularState state) {}
+	
 
 	/** Time trigger will be mapped to execution model time events for each real state. */
 	def ExecutionFlow mapTimeEvents(Statechart statechart, ExecutionFlow r) {
@@ -311,8 +324,8 @@ class ModelSequencer {
 		l.filter( typeof(State) ).toList
 	}
 	
-	def List<State> parentStates(State s) {
-		s.containers.filter( typeof(State) ).toList		
+	def List<RegularState> parentStates(RegularState s) {
+		s.containers.filter( typeof(RegularState) ).toList		
 	}
 	
 	
@@ -446,15 +459,16 @@ class ModelSequencer {
 	
 	def defineStateCycles(ExecutionFlow flow, Statechart sc) {
 		
-		val states = sc.allStates
-		states.filter(s | s.isSimple()).forEach(s | defineCycle(s as State))
+		val states = sc.allRegularStates
+		
+		states.filter(typeof(State)).filter(s | s.simple).forEach(s | defineCycle(s))
+		states.filter(typeof(FinalState)).forEach(s | defineCycle(s))
 		
-//		flow.states.filter(s | s.leaf).forEach(s | defineCycle(s))	
 		return flow
 	}
 	
 
-	def Cycle defineCycle(State state) {
+	def Cycle defineCycle(RegularState state) {
 	
 		val execState = state.create
 		val stateReaction = execState.createReactionSequence(null)
@@ -466,10 +480,24 @@ class ModelSequencer {
 		return execState.cycle
 	}	
 
-	def Cycle defineCycle(ExecutionState state) {	
-		state.cycle = state.createReactionSequence(null)
-		return state.cycle
-	}
+
+//	def Cycle defineCycle(FinalState state) {
+//	
+//		val execState = state.create
+//		val stateReaction = execState.createReactionSequence(null)
+//		val parents = state.parentStates		
+//		execState.cycle = parents.fold(null, [r, s | {
+//			s.create.createReactionSequence(r)
+//		}])
+//		
+//		return execState.cycle
+//	}	
+
+
+//	def Cycle defineCycle(ExecutionState state) {	
+//		state.cycle = state.createReactionSequence(null)
+//		return state.cycle
+//	}
 	
 
 	def Cycle createReactionSequence(ExecutionState state, Step localStep) {	
@@ -692,6 +720,13 @@ class ModelSequencer {
 				
 				val StateSwitch sSwitch = sexecFactory.createStateSwitch
 				
+				// collect leaf states
+				val List<State> leafStates = new ArrayList<State>()
+				
+				// create a case for each leaf state
+				// include exitAction calls up to the direct child level.
+				
+				
 				for ( s : r.states ) {
 					if (s.create.exitSequence != null) sSwitch.cases.add(s.create.newCase(s.create.exitSequence.newCall))
 				}
@@ -704,6 +739,18 @@ class ModelSequencer {
 	}
 	
 	
+	
+//	def List<State> collectLeafStates(State state, List<State> leafStates) {
+//		if ( state.simple ) 
+//			leafStates += state
+//		else
+//			
+//			
+//		return leafStates	
+//	}
+	
+	
+	
 	def newCase(ExecutionState it, Step step) {
 		val sCase = sexecFactory.createStateCase
 		sCase.state = it

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

@@ -2,6 +2,7 @@ package org.yakindu.sct.model.sexec.transformation;
 
 import org.eclipse.xtext.naming.DefaultDeclarativeQualifiedNameProvider;
 import org.eclipse.xtext.naming.IQualifiedNameProvider;
+import org.yakindu.sct.model.sgraph.naming.SGraphNameProvider;
 
 import com.google.inject.Binder;
 import com.google.inject.Module;
@@ -16,7 +17,7 @@ public class SequencerModule implements Module {
 	public void configure(Binder binder) {
 
 		binder.bind(IQualifiedNameProvider.class).to(
-				DefaultDeclarativeQualifiedNameProvider.class);
+				SGraphNameProvider.class);
 
 	}
 

+ 10 - 4
plugins/org.yakindu.sct.model.sexec/xtend-gen/org/yakindu/sct/model/sexec/transformation/FactoryExtension.java

@@ -20,8 +20,8 @@ import org.yakindu.sct.model.sexec.TimeEvent;
 import org.yakindu.sct.model.sexec.UnscheduleTimeEvent;
 import org.yakindu.sct.model.sexec.transformation.StatechartExtensions;
 import org.yakindu.sct.model.sgraph.Reaction;
+import org.yakindu.sct.model.sgraph.RegularState;
 import org.yakindu.sct.model.sgraph.Scope;
-import org.yakindu.sct.model.sgraph.State;
 import org.yakindu.sct.model.sgraph.Statechart;
 import org.yakindu.sct.model.sgraph.Statement;
 import org.yakindu.sct.model.sgraph.Transition;
@@ -131,7 +131,7 @@ public class FactoryExtension {
   
   private final HashMap<ArrayList<?>,ExecutionState> _createCache_create_5 = new HashMap<ArrayList<?>,ExecutionState>();
   
-  public ExecutionState create(final State state) {
+  public ExecutionState create(final RegularState state) {
     final ArrayList<?>_cacheKey = CollectionLiterals.newArrayList(state);
     ExecutionState r;
     synchronized (_createCache_create_5) {
@@ -146,8 +146,14 @@ public class FactoryExtension {
     boolean _operator_notEquals = ObjectExtensions.operator_notEquals(state, null);
     if (_operator_notEquals) {
       {
-        String _name = state.getName();
-        r.setSimpleName(_name);
+        String _xifexpression = null;
+        if ((state instanceof org.yakindu.sct.model.sgraph.FinalState)) {
+          _xifexpression = "_final_";
+        } else {
+          String _name = state.getName();
+          _xifexpression = _name;
+        }
+        r.setSimpleName(_xifexpression);
         QualifiedName _fullyQualifiedName = this.qfnProvider.getFullyQualifiedName(state);
         String _string = _fullyQualifiedName.toString();
         String _replaceAll = _string.replaceAll(" ", "");

+ 65 - 33
plugins/org.yakindu.sct.model.sexec/xtend-gen/org/yakindu/sct/model/sexec/transformation/ModelSequencer.java

@@ -45,7 +45,9 @@ import org.yakindu.sct.model.sgraph.Declaration;
 import org.yakindu.sct.model.sgraph.Effect;
 import org.yakindu.sct.model.sgraph.Entry;
 import org.yakindu.sct.model.sgraph.Event;
+import org.yakindu.sct.model.sgraph.FinalState;
 import org.yakindu.sct.model.sgraph.Region;
+import org.yakindu.sct.model.sgraph.RegularState;
 import org.yakindu.sct.model.sgraph.SGraphFactory;
 import org.yakindu.sct.model.sgraph.Scope;
 import org.yakindu.sct.model.sgraph.State;
@@ -177,33 +179,44 @@ public class ModelSequencer {
     {
       List<EObject> _eAllContentsAsList = EcoreUtil2.eAllContentsAsList(statechart);
       List<EObject> content = _eAllContentsAsList;
-      List<State> _allStates = this.allStates(statechart);
-      final List<State> allStates = _allStates;
+      List<RegularState> _allRegularStates = this.allRegularStates(statechart);
+      final List<RegularState> allStates = _allRegularStates;
       EList<ExecutionState> _states = r.getStates();
-      final Function1<State,ExecutionState> _function = new Function1<State,ExecutionState>() {
-          public ExecutionState apply(final State s) {
+      final Function1<RegularState,ExecutionState> _function = new Function1<RegularState,ExecutionState>() {
+          public ExecutionState apply(final RegularState s) {
             ExecutionState _mapState = ModelSequencer.this.mapState(s);
             return _mapState;
           }
         };
-      List<ExecutionState> _map = ListExtensions.<State, ExecutionState>map(allStates, _function);
+      List<ExecutionState> _map = ListExtensions.<RegularState, ExecutionState>map(allStates, _function);
       _states.addAll(_map);
       return r;
     }
   }
   
-  public List<State> allStates(final Statechart sc) {
+  public List<RegularState> allRegularStates(final Statechart sc) {
     {
       List<EObject> _eAllContentsAsList = EcoreUtil2.eAllContentsAsList(sc);
       List<EObject> content = _eAllContentsAsList;
-      Iterable<State> _filter = IterableExtensions.<State>filter(content, org.yakindu.sct.model.sgraph.State.class);
-      final Iterable<State> allStates = _filter;
-      List<State> _list = IterableExtensions.<State>toList(allStates);
+      Iterable<RegularState> _filter = IterableExtensions.<RegularState>filter(content, org.yakindu.sct.model.sgraph.RegularState.class);
+      final Iterable<RegularState> allStates = _filter;
+      List<RegularState> _list = IterableExtensions.<RegularState>toList(allStates);
       return _list;
     }
   }
   
-  public ExecutionState mapState(final State state) {
+  protected ExecutionState _mapState(final FinalState state) {
+    {
+      ExecutionState _create = this.factory.create(state);
+      final ExecutionState _state = _create;
+      _state.setLeaf(true);
+      _state.setEntryAction(null);
+      _state.setExitAction(null);
+      return _state;
+    }
+  }
+  
+  protected ExecutionState _mapState(final State state) {
     {
       ExecutionState _create = this.factory.create(state);
       final ExecutionState _state = _create;
@@ -217,6 +230,10 @@ public class ModelSequencer {
     }
   }
   
+  protected ExecutionState _mapState(final RegularState state) {
+    return null;
+  }
+  
   public ExecutionFlow mapTimeEvents(final Statechart statechart, final ExecutionFlow r) {
     {
       List<EObject> _eAllContentsAsList = EcoreUtil2.eAllContentsAsList(statechart);
@@ -564,10 +581,10 @@ public class ModelSequencer {
     return _xblockexpression;
   }
   
-  public List<State> parentStates(final State s) {
+  public List<RegularState> parentStates(final RegularState s) {
     List<EObject> _containers = this.containers(s);
-    Iterable<State> _filter = IterableExtensions.<State>filter(_containers, org.yakindu.sct.model.sgraph.State.class);
-    List<State> _list = IterableExtensions.<State>toList(_filter);
+    Iterable<RegularState> _filter = IterableExtensions.<RegularState>filter(_containers, org.yakindu.sct.model.sgraph.RegularState.class);
+    List<RegularState> _list = IterableExtensions.<RegularState>toList(_filter);
     return _list;
   }
   
@@ -869,57 +886,57 @@ public class ModelSequencer {
   
   public ExecutionFlow defineStateCycles(final ExecutionFlow flow, final Statechart sc) {
     {
-      List<State> _allStates = this.allStates(sc);
-      final List<State> states = _allStates;
+      List<RegularState> _allRegularStates = this.allRegularStates(sc);
+      final List<RegularState> states = _allRegularStates;
+      Iterable<State> _filter = IterableExtensions.<State>filter(states, org.yakindu.sct.model.sgraph.State.class);
       final Function1<State,Boolean> _function = new Function1<State,Boolean>() {
           public Boolean apply(final State s) {
             boolean _isSimple = s.isSimple();
             return ((Boolean)_isSimple);
           }
         };
-      Iterable<State> _filter = IterableExtensions.<State>filter(states, _function);
+      Iterable<State> _filter_1 = IterableExtensions.<State>filter(_filter, _function);
       final Function1<State,Cycle> _function_1 = new Function1<State,Cycle>() {
           public Cycle apply(final State s_1) {
-            Cycle _defineCycle = ModelSequencer.this.defineCycle(((State) s_1));
+            Cycle _defineCycle = ModelSequencer.this.defineCycle(s_1);
             return _defineCycle;
           }
         };
-      IterableExtensions.<State>forEach(_filter, _function_1);
+      IterableExtensions.<State>forEach(_filter_1, _function_1);
+      Iterable<FinalState> _filter_2 = IterableExtensions.<FinalState>filter(states, org.yakindu.sct.model.sgraph.FinalState.class);
+      final Function1<FinalState,Cycle> _function_2 = new Function1<FinalState,Cycle>() {
+          public Cycle apply(final FinalState s_2) {
+            Cycle _defineCycle_1 = ModelSequencer.this.defineCycle(s_2);
+            return _defineCycle_1;
+          }
+        };
+      IterableExtensions.<FinalState>forEach(_filter_2, _function_2);
       return flow;
     }
   }
   
-  public Cycle defineCycle(final State state) {
+  public Cycle defineCycle(final RegularState state) {
     {
       ExecutionState _create = this.factory.create(state);
       final ExecutionState execState = _create;
       Cycle _createReactionSequence = this.createReactionSequence(execState, null);
       final Cycle stateReaction = _createReactionSequence;
-      List<State> _parentStates = this.parentStates(state);
-      final List<State> parents = _parentStates;
-      final Function2<Cycle,State,Cycle> _function = new Function2<Cycle,State,Cycle>() {
-          public Cycle apply(final Cycle r , final State s) {
+      List<RegularState> _parentStates = this.parentStates(state);
+      final List<RegularState> parents = _parentStates;
+      final Function2<Cycle,RegularState,Cycle> _function = new Function2<Cycle,RegularState,Cycle>() {
+          public Cycle apply(final Cycle r , final RegularState s) {
             ExecutionState _create_1 = ModelSequencer.this.factory.create(s);
             Cycle _createReactionSequence_1 = ModelSequencer.this.createReactionSequence(_create_1, r);
             return _createReactionSequence_1;
           }
         };
-      Cycle _fold = IterableExtensions.<State, Cycle>fold(parents, null, _function);
+      Cycle _fold = IterableExtensions.<RegularState, Cycle>fold(parents, null, _function);
       execState.setCycle(_fold);
       Cycle _cycle = execState.getCycle();
       return _cycle;
     }
   }
   
-  public Cycle defineCycle(final ExecutionState state) {
-    {
-      Cycle _createReactionSequence = this.createReactionSequence(state, null);
-      state.setCycle(_createReactionSequence);
-      Cycle _cycle = state.getCycle();
-      return _cycle;
-    }
-  }
-  
   public Cycle createReactionSequence(final ExecutionState state, final Step localStep) {
     {
       SexecFactory _sexecFactory = this.sexecFactory();
@@ -1357,6 +1374,8 @@ public class ModelSequencer {
             SexecFactory _sexecFactory_1 = this.sexecFactory();
             StateSwitch _createStateSwitch = _sexecFactory_1.createStateSwitch();
             final StateSwitch sSwitch = _createStateSwitch;
+            ArrayList<State> _arrayList = new ArrayList<State>();
+            final List<State> leafStates = _arrayList;
             Iterable<State> _states = this.states(r);
             for (State s : _states) {
               ExecutionState _create_1 = this.factory.create(s);
@@ -1715,6 +1734,19 @@ public class ModelSequencer {
     }
   }
   
+  public ExecutionState mapState(final RegularState state) {
+    if ((state instanceof FinalState)) {
+      return _mapState((FinalState)state);
+    } else if ((state instanceof State)) {
+      return _mapState((State)state);
+    } else if ((state instanceof RegularState)) {
+      return _mapState((RegularState)state);
+    } else {
+      throw new IllegalArgumentException("Unhandled parameter types: " +
+        java.util.Arrays.<Object>asList(state).toString());
+    }
+  }
+  
   public Sequence mapEffect(final Effect effect) {
     if ((effect instanceof ReactionEffect)) {
       return _mapEffect((ReactionEffect)effect);

+ 25 - 9
test-plugins/org.yakindu.sct.model.sexec.test/src/org/yakindu/sct/model/sexec/transformation/test/ModelSequencerStateReactionTest.java

@@ -24,8 +24,11 @@ import org.yakindu.sct.model.sgraph.Statement;
 import org.yakindu.sct.model.sgraph.Transition;
 import org.yakindu.sct.model.stext.stext.Assignment;
 import org.yakindu.sct.model.stext.stext.AssignmentOperator;
+import org.yakindu.sct.model.stext.stext.BoolLiteral;
 import org.yakindu.sct.model.stext.stext.ElementReferenceExpression;
 import org.yakindu.sct.model.stext.stext.EventDefinition;
+import org.yakindu.sct.model.stext.stext.IntLiteral;
+import org.yakindu.sct.model.stext.stext.Literal;
 import org.yakindu.sct.model.stext.stext.LocalReaction;
 import org.yakindu.sct.model.stext.stext.LogicalAndExpression;
 import org.yakindu.sct.model.stext.stext.LogicalOrExpression;
@@ -95,9 +98,21 @@ public class ModelSequencerStateReactionTest extends ModelSequencerTest {
 
 		assertNotNull(s);
 		assertTrue(s instanceof PrimitiveValueExpression);
-		assertEquals("true", ((PrimitiveValueExpression) s).getValue());
+		assertBoolLiteral(true, ((PrimitiveValueExpression) s).getValue());
 	}
 
+	
+	public static void assertBoolLiteral(boolean value, Literal lit) {
+		assertTrue("Literal is no BoolLiteral", lit instanceof BoolLiteral);
+		assertEquals(value, ((BoolLiteral)lit).isValue() );
+	}
+	
+	public static void assertIntLiteral(int value, Literal lit) {
+		assertTrue("Literal is no IntLiteral", lit instanceof IntLiteral);
+		assertEquals(value, ((IntLiteral)lit).getValue() );
+	}
+	
+	
 	/**
 	 * The 'always' trigger event will be converted to a simple 'true' condition.
 	 */
@@ -110,7 +125,7 @@ public class ModelSequencerStateReactionTest extends ModelSequencerTest {
 
 		assertNotNull(s);
 		assertTrue(s instanceof PrimitiveValueExpression);
-		assertEquals("true", ((PrimitiveValueExpression) s).getValue());
+		assertBoolLiteral(true, ((PrimitiveValueExpression) s).getValue());
 	}
 
 
@@ -172,7 +187,7 @@ public class ModelSequencerStateReactionTest extends ModelSequencerTest {
 		assertEquals(e2.getName(),
 				((ElementReferenceExpression) triggerCheck.getRightOperand()).getValue().getName());
 		
-		assertEquals(exp.getValue(), guardCheck.getValue());
+		assertBoolLiteral(false, guardCheck.getValue());
 	}
 
 	
@@ -191,7 +206,7 @@ public class ModelSequencerStateReactionTest extends ModelSequencerTest {
 		
 		// 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());
+		assertBoolLiteral(false, guard.getValue());
 	}
 
 	
@@ -237,8 +252,8 @@ public class ModelSequencerStateReactionTest extends ModelSequencerTest {
 		ScheduleTimeEvent ste = (ScheduleTimeEvent) entryAction.getSteps().get(0);
 		assertSame(te, ste.getTimeEvent());
 		NumericalMultiplyDivideExpression multiply = (NumericalMultiplyDivideExpression) ste.getTimeValue();
-		assertEquals("1", ((PrimitiveValueExpression)multiply.getLeftOperand()).getValue());
-		assertEquals("1000", ((PrimitiveValueExpression)multiply.getRightOperand()).getValue());
+		assertIntLiteral(1, ((PrimitiveValueExpression)multiply.getLeftOperand()).getValue());
+		assertIntLiteral(1000, ((PrimitiveValueExpression)multiply.getRightOperand()).getValue());
 		assertEquals(MultiplicativeOperator.MUL, multiply.getOperator());
 						
 		// assert the unscheduling of the time events during state exit
@@ -278,7 +293,7 @@ public class ModelSequencerStateReactionTest extends ModelSequencerTest {
 		ScheduleTimeEvent ste = (ScheduleTimeEvent) entryAction.getSteps().get(0);
 		assertSame(te, ste.getTimeEvent());
 		PrimitiveValueExpression value = (PrimitiveValueExpression) ste.getTimeValue();
-		assertEquals("2", value.getValue());
+		assertIntLiteral(2, value.getValue());
 		assertNotNull(_s.getExitAction());
 		Sequence exitAction = (Sequence) _s.getExitAction();
 		UnscheduleTimeEvent ute = (UnscheduleTimeEvent) exitAction.getSteps().get(0);
@@ -309,7 +324,8 @@ public class ModelSequencerStateReactionTest extends ModelSequencerTest {
 		// assert that a local reaction is created
 		Reaction reaction = _s.getReactions().get(0);
 		PrimitiveValueExpression pve = (PrimitiveValueExpression) reaction.getCheck().getCondition();
-		assertSame("true", pve.getValue());
+		assertBoolLiteral(true, pve.getValue());
+		
 		
 	}
 	
@@ -336,7 +352,7 @@ public class ModelSequencerStateReactionTest extends ModelSequencerTest {
 		// assert that a local reaction is created
 		Reaction reaction = _s.getReactions().get(0);
 		PrimitiveValueExpression pve = (PrimitiveValueExpression) reaction.getCheck().getCondition();
-		assertSame("true", pve.getValue());
+		assertBoolLiteral(true, pve.getValue());
 		
 	}
 	

+ 2 - 0
test-plugins/org.yakindu.sct.model.sexec.test/src/org/yakindu/sct/model/sexec/transformation/test/ModelSequencerStateTest.java

@@ -897,6 +897,8 @@ public class ModelSequencerStateTest extends ModelSequencerTest {
 		ExecutionState _s6 = flow.getStates().get(5);
 		assertEquals("sc.r.s2.r.s6", _s6.getName());
 		
+		assertNull(_fs.getEntryAction());
+		assertNull(_fs.getExitAction());
 			
 		Cycle cycle = _fs.getCycle();