Gitiles

git.eclipse.org / papyrus-rt / org.eclipse.papyrus-rt / 6041c3f101bab2564c7e07bfaf44d42f462673c7 / . / plugins / xtumlrt / common / org.eclipse.papyrusrt.xtumlrt.util / src / org / eclipse / papyrusrt / xtumlrt / util / XTUMLRTSMVirtualInheritanceExtensions.xtend

/******************************************************************************* | |

* Copyright (c) 2015 Zeligsoft (2009) Limited 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 | |

*******************************************************************************/ | |

package org.eclipse.papyrusrt.xtumlrt.util | |

import org.eclipse.papyrusrt.xtumlrt.statemach.CompositeState | |

import org.eclipse.papyrusrt.xtumlrt.statemach.ChoicePoint | |

import org.eclipse.papyrusrt.xtumlrt.statemach.DeepHistory | |

import org.eclipse.papyrusrt.xtumlrt.statemach.EntryPoint | |

import org.eclipse.papyrusrt.xtumlrt.statemach.ExitPoint | |

import org.eclipse.papyrusrt.xtumlrt.statemach.InitialPoint | |

import org.eclipse.papyrusrt.xtumlrt.statemach.JunctionPoint | |

import org.eclipse.papyrusrt.xtumlrt.statemach.Pseudostate | |

import org.eclipse.papyrusrt.xtumlrt.statemach.State | |

import org.eclipse.papyrusrt.xtumlrt.statemach.StateMachine | |

import org.eclipse.papyrusrt.xtumlrt.statemach.Transition | |

import org.eclipse.papyrusrt.xtumlrt.statemach.Vertex | |

import static extension org.eclipse.papyrusrt.xtumlrt.util.XTUMLRTStateMachineUtil.* | |

import java.util.Collection | |

import java.util.List | |

/** | |

* This class provides extension methods that implement "virtual state machine | |

* inheritance" as described in the UML-RT profile. This provides operations to, | |

* for example, obtain all the states and transitions inside a composite state | |

* including those inherited and those refined, as well as operations to obtain | |

* the inherited transitions to and from a state. | |

* | |

* <p> | |

*/ | |

class XTUMLRTSMVirtualInheritanceExtensions | |

{ | |

/** | |

* Returns the initial point of the state machine if it has one, or the | |

* inherited initial point, if there is one along the inheritance hierarchy. | |

*/ | |

static dispatch def InitialPoint getActualInitialPoint( StateMachine stateMachine ) | |

{ | |

if (stateMachine.top === null) return null | |

stateMachine.top.actualInitialPoint | |

} | |

static dispatch def InitialPoint getActualInitialPoint( CompositeState state ) | |

{ | |

if (state.hasInitial) state.initial | |

else | |

{ | |

val refinedState = state.redefinedState | |

if (refinedState !== null && refinedState instanceof CompositeState) | |

refinedState.actualInitialPoint | |

} | |

} | |

/** | |

* Returns the initial point of the state machine if it has one, or the | |

* inherited initial point, if there is one along the inheritance hierarchy. | |

*/ | |

static dispatch def DeepHistory getActualDeepHistory( StateMachine stateMachine ) | |

{ | |

if (stateMachine.top === null) return null | |

stateMachine.top.actualDeepHistory | |

} | |

static dispatch def DeepHistory getActualDeepHistory( CompositeState state ) | |

{ | |

if (state.hasDeepHistory) state.deepHistory | |

else | |

{ | |

val refinedState = state.redefinedState | |

if (refinedState !== null && refinedState instanceof CompositeState) | |

refinedState.actualDeepHistory | |

} | |

} | |

/** | |

* Returns the union of: | |

* | |

* <ol> | |

* <li> the set inherited choice points, | |

* <li> the set of new choice points which are neither inherited, not redefinitions | |

* </ol> | |

*/ | |

static def dispatch Iterable<ChoicePoint> getAllChoicePoints( StateMachine stateMachine ) | |

{ | |

if (stateMachine.top === null) return #[]; | |

stateMachine.top.allChoicePoints | |

} | |

static def dispatch Iterable<ChoicePoint> getAllChoicePoints( State state ) | |

{ | |

#[] | |

} | |

static def dispatch Iterable<ChoicePoint> getAllChoicePoints( CompositeState state ) | |

{ | |

val List<ChoicePoint> allChoicePoints = newArrayList | |

if (state !== null) | |

{ | |

allChoicePoints.addAll( state.choicePoints ) | |

val redefinedState = state.redefinedState | |

if (redefinedState !== null) | |

{ | |

allChoicePoints.addAll( redefinedState.allChoicePoints ) | |

} | |

} | |

allChoicePoints | |

} | |

/** | |

* Returns the union of: | |

* | |

* <ol> | |

* <li> the set inherited connection points, and | |

* <li> the set of new connection points which are not inherited | |

* </ol> | |

*/ | |

static def Iterable<Pseudostate> getAllConnectionPoints( State state ) | |

{ | |

val List<Pseudostate> allConnectionPoints = newArrayList | |

if (state !== null) | |

{ | |

if (state.connectionPoints !== null) | |

allConnectionPoints.addAll( state.connectionPoints ) | |

val redefinedState = state.redefinedState | |

if (redefinedState !== null) | |

{ | |

val inheritedPseudostates = redefinedState.allConnectionPoints | |

allConnectionPoints.addAll( inheritedPseudostates ) | |

} | |

} | |

allConnectionPoints | |

} | |

/** | |

* Returns the union of: | |

* | |

* <ol> | |

* <li> the set inherited incoming transitions that have not been | |

* redefined, | |

* <li> the set of incoming transitions that are redefinitions of states | |

* in the extended composite state, and | |

* <li> the set of new incoming transitions which are neither inherited, | |

* not redefinitions | |

* </ol> | |

* | |

* <p> The last two sets are already present in the vertex container, | |

* so this method takes those transitions in that container and adds all | |

* inherited transitions for which there is no transition in the container | |

* redefining them. | |

*/ | |

static def Iterable<Transition> getAllDirectIncomingTransitions( Vertex v ) | |

{ | |

val List<Transition> allTransitions = newArrayList | |

if (v !== null) | |

{ | |

allTransitions.addAll( v.directIncomingTransitions ) | |

if (v instanceof State) | |

{ | |

val redefinedState = v.redefines as State | |

if (redefinedState !== null) | |

{ | |

val inheritedTransitions = redefinedState.allDirectIncomingTransitions | |

for (t : inheritedTransitions) | |

{ | |

val container = v.ownerState as CompositeState | |

if ( container !== null && !container.redefines(t) ) | |

allTransitions.add(t) | |

} | |

} | |

} | |

} | |

allTransitions | |

} | |

/** | |

* Returns the union of: | |

* | |

* <ol> | |

* <li> the set inherited outgoing transitions that have not been | |

* redefined, | |

* <li> the set of outgoing transitions that are redefinitions of states | |

* in the extended composite state, and | |

* <li> the set of new outgoing transitions which are neither inherited, | |

* not redefinitions | |

* </ol> | |

* | |

* <p> The last two sets are already present in the vertex container, | |

* so this method takes those transitions in that container and adds all | |

* inherited transitions for which there is no transition in the container | |

* redefining them. | |

*/ | |

static def Iterable<Transition> getAllDirectOutgoingTransitions( Vertex v ) | |

{ | |

val List<Transition> allTransitions = newArrayList | |

if (v !== null) | |

{ | |

allTransitions.addAll( v.directOutgoingTransitions ) | |

if (v instanceof State) | |

{ | |

val redefinedState = v.redefines as State | |

if (redefinedState !== null) | |

{ | |

val inheritedTransitions = redefinedState.allDirectOutgoingTransitions | |

for (t : inheritedTransitions) | |

{ | |

val container = v.ownerState as CompositeState | |

if ( container !== null && !container.redefines(t) ) | |

allTransitions.add(t) | |

} | |

} | |

} | |

} | |

allTransitions | |

} | |

/** | |

* Returns the union of: | |

* | |

* <ol> | |

* <li> the set inherited entry points, and | |

* <li> the set of new entry points which are not inherited | |

* </ol> | |

*/ | |

static def Iterable<EntryPoint> getAllEntryPoints( State state ) | |

{ | |

val List<EntryPoint> allEntryPoints = newArrayList | |

if (state !== null) | |

{ | |

if (state.entryPoints !== null) | |

allEntryPoints.addAll( state.entryPoints ) | |

val redefinedState = state.redefinedState | |

if (redefinedState !== null) | |

{ | |

val inheritedPseudostates = redefinedState.allEntryPoints | |

allEntryPoints.addAll( inheritedPseudostates ) | |

} | |

} | |

allEntryPoints | |

} | |

/** | |

* Returns the union of: | |

* | |

* <ol> | |

* <li> the set inherited entry points, and | |

* <li> the set of new entry points which are not inherited | |

* </ol> | |

*/ | |

static def Iterable<ExitPoint> getAllExitPoints( State state ) | |

{ | |

val List<ExitPoint> allExitPoints = newArrayList | |

if (state !== null) | |

{ | |

if (state.entryPoints !== null) | |

allExitPoints.addAll( state.exitPoints ) | |

val redefinedState = state.redefinedState | |

if (redefinedState !== null) | |

{ | |

val inheritedPseudostates = redefinedState.allExitPoints | |

allExitPoints.addAll( inheritedPseudostates ) | |

} | |

} | |

allExitPoints | |

} | |

/** | |

* Returns the union of: | |

* | |

* <ol> | |

* <li> the set inherited incoming transitions that have not been | |

* redefined, | |

* <li> the set of incoming transitions that are redefinitions of states | |

* in the extended composite state, and | |

* <li> the set of new incoming transitions which are neither inherited, | |

* not redefinitions | |

* </ol> | |

* | |

* <p> The last two sets are already present in the vertex container, | |

* so this method takes those transitions in that container and adds all | |

* inherited transitions for which there is no transition in the container | |

* redefining them. | |

*/ | |

static def Iterable<Transition> getAllIncomingTransitions( State s ) | |

{ | |

val List<Transition> transitions = newArrayList | |

transitions.addAll( s.allDirectIncomingTransitions ) | |

transitions.addAll( s.allIndirectIncomingTransitions ) | |

transitions | |

} | |

/** | |

* Returns the union of: | |

* | |

* <ol> | |

* <li> the set inherited incoming transitions that have not been | |

* redefined, | |

* <li> the set of incoming transitions that are redefinitions of states | |

* in the extended composite state, and | |

* <li> the set of new incoming transitions which are neither inherited, | |

* not redefinitions | |

* </ol> | |

* | |

* <p> The last two sets are already present in the vertex container, | |

* so this method takes those transitions in that container and adds all | |

* inherited transitions for which there is no transition in the container | |

* redefining them. | |

*/ | |

static def Iterable<Transition> getAllIndirectIncomingTransitions( State s ) | |

{ | |

val List<Transition> allTransitions = newArrayList | |

if (s !== null) | |

{ | |

allTransitions.addAll( s.indirectIncomingTransitions ) | |

val redefinedState = s.redefinedState | |

if (redefinedState !== null) | |

{ | |

val inheritedTransitions = redefinedState.allIndirectIncomingTransitions | |

for (t : inheritedTransitions) | |

{ | |

val container = s.ownerState as CompositeState | |

if ( container !== null && !container.redefines(t) ) | |

allTransitions.add(t) | |

} | |

} | |

} | |

allTransitions | |

} | |

/** | |

* Returns the union of: | |

* | |

* <ol> | |

* <li> the set inherited outgoing transitions that have not been | |

* redefined, | |

* <li> the set of outgoing transitions that are redefinitions of states | |

* in the extended composite state, and | |

* <li> the set of new outgoing transitions which are neither inherited, | |

* not redefinitions | |

* </ol> | |

* | |

* <p> The last two sets are already present in the vertex container, | |

* so this method takes those transitions in that container and adds all | |

* inherited transitions for which there is no transition in the container | |

* redefining them. | |

*/ | |

static def Iterable<Transition> getAllIndirectOutgoingTransitions( State s ) | |

{ | |

val List<Transition> allTransitions = newArrayList | |

if (s !== null) | |

{ | |

allTransitions.addAll( s.indirectOutgoingTransitions ) | |

val redefinedState = s.redefinedState | |

if (redefinedState !== null) | |

{ | |

val inheritedTransitions = redefinedState.allIndirectOutgoingTransitions | |

for (t : inheritedTransitions) | |

{ | |

val container = s.ownerState as CompositeState | |

if ( container !== null && !container.redefines(t) ) | |

allTransitions.add(t) | |

} | |

} | |

} | |

allTransitions | |

} | |

/** | |

* Returns the union of: | |

* | |

* <ol> | |

* <li> the set inherited junction points, | |

* <li> the set of new junction points which are neither inherited, not redefinitions | |

* </ol> | |

*/ | |

static def dispatch Iterable<JunctionPoint> getAllJunctionPoints( StateMachine stateMachine ) | |

{ | |

if (stateMachine.top === null) return #[]; | |

stateMachine.top.allJunctionPoints | |

} | |

static def dispatch Iterable<JunctionPoint> getAllJunctionPoints( State state ) | |

{ | |

#[] | |

} | |

static def dispatch Iterable<JunctionPoint> getAllJunctionPoints( CompositeState state ) | |

{ | |

val List<JunctionPoint> allJunctionPoints = newArrayList | |

if (state !== null) | |

{ | |

allJunctionPoints.addAll( state.junctionPoints ) | |

val redefinedState = state.redefinedState | |

if (redefinedState !== null) | |

{ | |

allJunctionPoints.addAll( redefinedState.allJunctionPoints ) | |

} | |

} | |

allJunctionPoints | |

} | |

/** | |

* Returns the union of: | |

* | |

* <ol> | |

* <li> the set inherited outgoing transitions that have not been | |

* redefined, | |

* <li> the set of outgoing transitions that are redefinitions of states | |

* in the extended composite state, and | |

* <li> the set of new outgoing transitions which are neither inherited, | |

* not redefinitions | |

* </ol> | |

* | |

* <p> The last two sets are already present in the vertex container, | |

* so this method takes those transitions in that container and adds all | |

* inherited transitions for which there is no transition in the container | |

* redefining them. | |

*/ | |

static def Iterable<Transition> getAllOutgoingTransitions( State s ) | |

{ | |

val List<Transition> transitions = newArrayList | |

transitions.addAll( s.allDirectOutgoingTransitions ) | |

transitions.addAll( s.allIndirectOutgoingTransitions ) | |

transitions | |

} | |

/** | |

* Returns the union of: | |

* | |

* <ol> | |

* <li> the set inherited (internal) pseudostates, and | |

* <li> the set of new (internal) pseudostates which are not inherited | |

* </ol> | |

* | |

* <p> The last two sets are already present in the given region, so this method takes | |

* those states in the current region and adds all inherited states for which there is | |

* no state in the given region redefining them. | |

*/ | |

static dispatch def Iterable<Pseudostate> getAllPseudostates( StateMachine stateMachine ) | |

{ | |

if (stateMachine.top === null) return #[]; | |

stateMachine.top.allPseudostates | |

} | |

static dispatch def Iterable<Pseudostate> getAllPseudostates( State state ) | |

{ | |

#[] | |

} | |

static dispatch def Iterable<Pseudostate> getAllPseudostates( CompositeState state ) | |

{ | |

val List<Pseudostate> allPseudostates = newArrayList | |

if (state !== null) | |

{ | |

allPseudostates.addAll( state.pseudostates ) | |

val redefinedState = state.redefinedState | |

if (redefinedState !== null) | |

{ | |

val inheritedPseudostates = redefinedState.allPseudostates | |

allPseudostates.addAll( inheritedPseudostates ) | |

} | |

} | |

allPseudostates | |

} | |

/** | |

* Returns the union of: | |

* | |

* <ol> | |

* <li> the set inherited states that have not been redefined, | |

* <li> the set of states that are redefinitions of states in the extended region, and | |

* <li> the set of new states which are neither inherited, not redefinitions | |

* </ol> | |

* | |

* <p> The last two sets are already present in the given region, so this method takes | |

* those states in the current region and adds all inherited states for which there is | |

* no state in the given region redefining them. | |

*/ | |

static def dispatch Iterable<State> getAllSubstates( StateMachine stateMachine ) | |

{ | |

if (stateMachine.top === null) return #[]; | |

stateMachine.top.allSubstates | |

} | |

static def dispatch Iterable<State> getAllSubstates( State state ) | |

{ | |

#[] | |

} | |

static def dispatch Iterable<State> getAllSubstates( CompositeState state ) | |

{ | |

val List<State> allStates = newArrayList | |

if (state !== null) | |

{ | |

allStates.addAll( state.substates ) | |

val redefinedState = state.redefinedState | |

if (redefinedState !== null) | |

{ | |

val inheritedStates = redefinedState.allSubstates | |

for (s : inheritedStates) | |

{ | |

if (!state.redefines(s)) | |

allStates.add(s) | |

} | |

} | |

} | |

allStates | |

} | |

/** | |

* Returns the union of: | |

* | |

* <ol> | |

* <li> the set inherited transitions that have not been redefined, | |

* <li> the set of transitions that are redefinitions of states in the extended region, and | |

* <li> the set of new transitions which are neither inherited, not redefinitions | |

* </ol> | |

* | |

* <p> The last two sets are already present in the given region, so this method takes | |

* those states in the current region and adds all inherited states for which there is | |

* no state in the given region redefining them. | |

*/ | |

static def dispatch Iterable<Transition> getAllTransitions( StateMachine stateMachine ) | |

{ | |

if (stateMachine.top === null) return #[]; | |

stateMachine.top.allTransitions | |

} | |

static def dispatch Iterable<Transition> getAllTransitions( State state ) | |

{ | |

#[] | |

} | |

static def dispatch Iterable<Transition> getAllTransitions( CompositeState state ) | |

{ | |

val List<Transition> allTransitions = newArrayList | |

if (state !== null) | |

{ | |

allTransitions.addAll( state.transitions ) | |

val redefinedState = state.redefinedState | |

if (redefinedState !== null) | |

{ | |

val inheritedStates = redefinedState.allTransitions | |

for (s : inheritedStates) | |

{ | |

if (!state.redefines(s)) | |

allTransitions.add(s) | |

} | |

} | |

} | |

allTransitions | |

} | |

/** | |

* Returns the state redefined by the given state or null if it doesn't | |

* redefine any. | |

*/ | |

static def State getRedefinedState( State s ) | |

{ | |

if (s === null || s.redefines === null || !(s.redefines instanceof State)) | |

null | |

else | |

s.redefines as State | |

} | |

/** | |

* Returns a collection of states from the extended composite state that | |

* have been redefined in the given composite state. | |

*/ | |

static def Iterable<State> getRedefinedStates( CompositeState state ) | |

{ | |

state.stateRedefinitions.map [ it.redefinedState ] | |

} | |

/** | |

* Returns the state redefined by the given state or null if it doesn't | |

* redefine any. | |

*/ | |

static def Transition getRedefinedTransition( Transition t ) | |

{ | |

if (t === null || t.redefines === null || !(t.redefines instanceof Transition)) | |

null | |

else | |

t.redefines as Transition | |

} | |

/** | |

* Returns a collection of transitions from the extended composite state | |

* that have been redefined in the given composite state. | |

*/ | |

static def Iterable<Transition> getRedefinedTransitions( CompositeState state ) | |

{ | |

state.transitionRedefinitions.map [ it.redefinedTransition ] | |

} | |

/** | |

* Returns the collection of states which are redefinitions of a state in | |

* the extended composite state. In other words, it returns the collection | |

* of substates of the given composite state which redefine some state. | |

*/ | |

static def Collection<State> getStateRedefinitions( CompositeState state ) | |

{ | |

val List<State> states = newArrayList | |

if (state !== null) | |

{ | |

for (s : state.substates) | |

{ | |

if (s.redefinedState !== null) | |

states.add(s) | |

} | |

} | |

states | |

} | |

/** | |

* Returns the collection of transitions which are redefinitions of a | |

* transition in the extended composite state. In other words, it returns | |

* the collection of transitions of the given composite state that redefine | |

* some transition. | |

*/ | |

static def Collection<Transition> getTransitionRedefinitions( CompositeState state ) | |

{ | |

val List<Transition> transitions = newArrayList | |

if (state !== null) | |

{ | |

for (t : state.transitions) | |

{ | |

if (t.redefinedTransition !== null) | |

transitions.add(t) | |

} | |

} | |

transitions | |

} | |

/** | |

* Returns the source vertex of a given transition inside a given composite | |

* state which may be an extended state of the state containing the "real" | |

* source of the transition. This is, if transition t is inside (composite) | |

* state r because it was inherited, this is, t is defined in and actually | |

* belongs to a (composite) state r' redefined by r, then the real source s' | |

* of t is in r', but there may be a vertex s in r which redefines s', and | |

* therefore it should be considered the source of t in r. | |

* | |

* <p> The following diagram describes the situation: t in r is inherited | |

* from r', and its real source is s' and target is d'. This method returns | |

* s, the source of t in r. | |

* <p> | |

* <pre> | |

* <code> | |

* parent state r': s' --t--> d' | |

* ^ ^ ^ | |

* | | | | |

* extended state r: s --t--> d | |

* </code> | |

* </pre> | |

* | |

*/ | |

static def Vertex getTransitionSourceInState( Transition t, CompositeState r ) | |

{ | |

// Check if the source is one of the pseudostates, owned or inherited by r | |

for (s : r.allPseudostates) | |

{ | |

if (t.sourceVertex === s) | |

return s | |

} | |

// Check if the source is one of the states, owned or inherited by r or a connection | |

// point for any such state | |

val statesToConsider = newArrayList | |

statesToConsider.add( r ) | |

statesToConsider.addAll( r.allSubstates ) | |

for (s : statesToConsider ) | |

{ | |

var v = s | |

// Go up the chain of state redefinitions looking for the actual source. | |

while (v !== null) | |

{ | |

// Check if the source is the given state... | |

if (t.sourceVertex === v) | |

return s | |

// Check if it is the deep history pseudostate if the state is composite | |

if (v instanceof CompositeState) | |

{ | |

val h = v.deepHistory | |

if (t.sourceVertex === h) | |

return h | |

} | |

// ... or if it is one of its connection (exit) points | |

if (v.connectionPoints !== null) | |

{ | |

for (p : v.connectionPoints) | |

{ | |

if (t.sourceVertex === p) | |

// p is not owned by r but we still need to report it, and since | |

// p is a pseudostate and non-redefinable, it must be inherited | |

// by s (TODO: unless it has been explicitly excluded, in which | |

// case we should report s) | |

return p | |

} | |

} | |

// If not, go up to the state that v redefines. | |

v = v.redefinedState | |

} | |

} | |

} | |

/** | |

* Returns the target vertex of a given transition inside a given composite | |

* state which may be an extended state of the state containing the "real" | |

* target of the transition. This is, if transition t is inside (composite) | |

* state r because it was inherited, this is, t is defined in and actually | |

* belongs to a (composite) state r' redefined by r, then the real target s' | |

* of t is in r', but there may be a vertex s in r which redefines s', and | |

* therefore it should be considered the target of t in r. | |

* | |

* <p> The following diagram describes the situation: t in r is inherited | |

* from r', and its real target is s' and target is d'. This method returns | |

* s, the target of t in r. | |

* <p> | |

* <pre> | |

* <code> | |

* parent state r': s' --t--> d' | |

* ^ ^ ^ | |

* | | | | |

* extended state r: s --t--> d | |

* </code> | |

* </pre> | |

* | |

*/ | |

static def Vertex getTransitionTargetInState( Transition t, CompositeState r ) | |

{ | |

// Check if the source is one of the pseudostates, owned or inherited by r | |

for (s : r.allPseudostates) | |

{ | |

if (t.targetVertex === s) | |

return s | |

} | |

// Check if the target is one of the states, owned or inherited by r or a connection | |

// point for any such state | |

val statesToConsider = newArrayList | |

statesToConsider.add( r ) | |

statesToConsider.addAll( r.allSubstates ) | |

for (s : statesToConsider ) | |

{ | |

var v = s | |

// Go up the chain of state redefinitions looking for the actual target. | |

while (v !== null) | |

{ | |

// Check if the source is the given state... | |

if (t.targetVertex === v) | |

return s | |

// Check if it is the deep history pseudostate if the state is composite | |

if (v instanceof CompositeState) | |

{ | |

val h = v.deepHistory | |

if (t.targetVertex === h) | |

return h | |

} | |

// ... or if it is one of its connection (exit) points | |

if (v.connectionPoints !== null) | |

{ | |

for (p : v.connectionPoints) | |

{ | |

if (t.targetVertex === p) | |

// p is not owned by r but we still need to report it, and since | |

// p is a pseudostate and non-redefinable, it must be inherited | |

// by s (TODO: unless it has been explicitly excluded, in which | |

// case we should report s) | |

return p | |

} | |

} | |

// If not, go up to the state that v redefines. | |

v = v.redefinedState | |

} | |

} | |

} | |

/** | |

* Returns true is the given state from the region extended by the given region is | |

* redefined in the given region. | |

* | |

* @param compositeState - A {@link CompositeState} | |

* @param state - A {@link State} | |

* @return {@code true} iff: | |

* <ol> | |

* <li> {@code state} is a substate of the composite state that | |

* is extended by the given {@code compositeState} and | |

* <li> {@code state} is redefined by some state in the given | |

* {@code compositeState} | |

* </ol> | |

*/ | |

static def dispatch redefines( CompositeState compositeState, State state ) | |

{ | |

compositeState.redefinedStates.exists [it == state] | |

} | |

/** | |

* Returns true is the given transition from the region extended by the given region is | |

* redefined in the given region. | |

* | |

* @param compositeState - A {@link CompositeState} | |

* @param transition - A {@link Transition} | |

* @return {@code true} iff: | |

* <ol> | |

* <li> {@code transition} is a transition in the composite state | |

* extended by the given {@code compositeState} and | |

* <li> {@code transition} is redefined by some transition in the | |

* given {@code compositeState} | |

* </ol> | |

*/ | |

static def dispatch redefines(CompositeState compositeState, Transition transition) | |

{ | |

compositeState.redefinedTransitions.exists [it == transition] | |

} | |

} |