summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRohit Agrawal2012-06-22 15:11:41 (EDT)
committer Rohit Agrawal2012-06-22 15:11:41 (EDT)
commit142462e9c58ef6084b73dca4e9a54ef9055b49fa (patch)
treedf83b9306da3300d5734d7561d5fcc687fb30ddd
parenta8f47d402d4e6497ed5c10fe30a7336bee8bc92a (diff)
downloadorg.eclipse.etrice-142462e9c58ef6084b73dca4e9a54ef9055b49fa.zip
org.eclipse.etrice-142462e9c58ef6084b73dca4e9a54ef9055b49fa.tar.gz
org.eclipse.etrice-142462e9c58ef6084b73dca4e9a54ef9055b49fa.tar.bz2
[CQ 6589] : Reachability Validator to find unreachable parts of staterefs/changes/75/6475/1
graph 1. I authored 100% of the content I contributed 2. I have the rights to donate the content to Eclipse 3. I contribute the content under the EPL Change-Id: I010dd8e62b8f70e0a641a2868d3544349d6ff516
-rw-r--r--plugins/org.eclipse.etrice.abstractexec.behavior/plugin.xml5
-rw-r--r--plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/ReachabilityCheck.java142
-rw-r--r--plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/ReachabilityValidator.java74
3 files changed, 221 insertions, 0 deletions
diff --git a/plugins/org.eclipse.etrice.abstractexec.behavior/plugin.xml b/plugins/org.eclipse.etrice.abstractexec.behavior/plugin.xml
index 07d46d8..ecdee00 100644
--- a/plugins/org.eclipse.etrice.abstractexec.behavior/plugin.xml
+++ b/plugins/org.eclipse.etrice.abstractexec.behavior/plugin.xml
@@ -13,6 +13,11 @@
classToCheck="org.eclipse.etrice.core.room.ActorClass"
mode="FAST">
</validator>
+ <validator
+ class="org.eclipse.etrice.abstractexec.behavior.ReachabilityValidator"
+ classToCheck="org.eclipse.etrice.core.room.ActorClass"
+ mode="FAST">
+ </validator>
</extension>
<extension
point="org.eclipse.etrice.core.room.ui.quickfix">
diff --git a/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/ReachabilityCheck.java b/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/ReachabilityCheck.java
new file mode 100644
index 0000000..007a6b0
--- /dev/null
+++ b/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/ReachabilityCheck.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * 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
+ *
+ * CONTRIBUTORS:
+ * Rohit Agrawal (initial contribution)
+ *
+ *
+ *******************************************************************************/
+
+
+package org.eclipse.etrice.abstractexec.behavior;
+
+import java.util.*;
+
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.TreeIterator;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.etrice.core.genmodel.etricegen.ActiveTrigger;
+import org.eclipse.etrice.core.genmodel.etricegen.ExpandedActorClass;
+import org.eclipse.etrice.core.room.*;
+import org.eclipse.etrice.core.room.util.RoomHelpers;
+import org.eclipse.etrice.generator.base.DefaultTranslationProvider;
+import org.eclipse.etrice.generator.base.DetailCodeTranslator;
+
+
+public class ReachabilityCheck {
+Queue<StateGraphNode> queue;
+public Set<StateGraphItem> visited;
+private ExpandedActorClass xpAct;
+private Set<StateGraphItem> exitUsed;
+public ReachabilityCheck (ExpandedActorClass xpac) {
+ queue= new LinkedList<StateGraphNode>();
+ xpAct = xpac;
+ visited = new HashSet<StateGraphItem>();
+ exitUsed = new HashSet<StateGraphItem>();
+}
+public void computeReachability() {
+ StateGraph graph = xpAct.getStateMachine();
+ addStartingPoints(graph, true);
+ doTraversal();
+}
+
+private void addStartingPoints(StateGraph graph, boolean add_initial)
+{
+
+ EList<Transition> transitions = graph.getTransitions();
+ EList<TrPoint> trPoint = graph.getTrPoints();
+ if(add_initial)
+ for(Transition trans : transitions)
+ if(trans instanceof InitialTransition)
+ {
+ visited.add(trans);
+ StateGraphNode cur = xpAct.getNode(trans.getTo());
+ if(!visited.contains(cur)) queue.add(cur);
+ break;
+ }
+ for(TrPoint tp : trPoint)
+ {
+ if(tp instanceof TransitionPoint && !visited.contains(tp) ) {
+ queue.add(tp);
+ }
+ }
+
+ //add transition points
+}
+private void doTraversal() {
+ while(!queue.isEmpty())
+ {
+ StateGraphNode node = queue.poll();
+ Visit(node);
+ //System.out.println("Visited node : " + node.getName());
+ }
+}
+public boolean isExitUsed(StateGraphItem item)
+{
+ return exitUsed.contains(item);
+}
+public boolean isReachable(StateGraphItem item)
+{
+
+ return visited.contains(item);
+}
+private void Visit(StateGraphNode node)
+{
+ visited.add(node);
+ if(node instanceof State)
+ {
+ State st = (State) node;
+ if(RoomHelpers.hasDirectSubStructure(st))
+ {
+ addStartingPoints(st.getSubgraph(),true);
+ }
+ else
+ {
+ for(ActiveTrigger trigger : xpAct.getActiveTriggers(st))
+ {
+ for(Transition trans : trigger.getTransitions())
+ {
+ visited.add(trans);
+ StateGraphNode target = xpAct.getNode(trans.getTo());
+ if(!visited.contains(target)) {
+ queue.add(target);
+ StateGraph triggerContext = (StateGraph) trans.eContainer();
+ State exitCalled = st;
+ while(true)
+ {
+ exitUsed.add(exitCalled);
+ if(exitCalled.eContainer()==triggerContext) break;
+ exitCalled = (State) exitCalled.eContainer().eContainer();
+ }
+ }
+ }
+ }
+ }
+ }
+ else {
+ if(node instanceof EntryPoint)
+ {
+ State container = (State) node.eContainer().eContainer();
+ visited.add(container);
+ }
+ for(Transition trans : xpAct.getOutgoingTransitions(node))
+ {
+ visited.add(trans);
+ StateGraphNode target = xpAct.getNode(trans.getTo());
+ if(!visited.contains(target))
+ {
+ queue.add(target);
+
+ }
+ }
+ }
+
+}
+
+
+}
+
diff --git a/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/ReachabilityValidator.java b/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/ReachabilityValidator.java
new file mode 100644
index 0000000..35baa9e
--- /dev/null
+++ b/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/ReachabilityValidator.java
@@ -0,0 +1,74 @@
+
+/*******************************************************************************
+ * 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
+ *
+ * CONTRIBUTORS:
+ * Rohit Agrawal (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.abstractexec.behavior;
+
+import java.util.List;
+
+import org.eclipse.emf.common.util.TreeIterator;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.etrice.core.genmodel.base.NullDiagnostician;
+import org.eclipse.etrice.core.genmodel.base.NullLogger;
+import org.eclipse.etrice.core.genmodel.builder.GeneratorModelBuilder;
+import org.eclipse.etrice.core.genmodel.etricegen.ExpandedActorClass;
+import org.eclipse.etrice.core.room.ActorClass;
+import org.eclipse.etrice.core.room.StateGraphItem;
+import org.eclipse.etrice.core.validation.IRoomValidator;
+import org.eclipse.xtext.validation.ValidationMessageAcceptor;
+
+
+public class ReachabilityValidator implements IRoomValidator {
+
+
+ @Override
+ public void validate(EObject object, ValidationMessageAcceptor messageAcceptor) {
+
+ if (!(object instanceof ActorClass))
+ return;
+
+ ActorClass ac = (ActorClass) object;
+
+ NullDiagnostician diagnostician = new NullDiagnostician();
+ GeneratorModelBuilder builder = new GeneratorModelBuilder(new NullLogger(), diagnostician);
+ ExpandedActorClass xpac = builder.createExpandedActorClass(ac);
+
+ if (xpac != null && !diagnostician.isFailed()) {
+ ReachabilityCheck checker = new ReachabilityCheck(xpac);
+ checker.computeReachability();
+ TreeIterator<EObject> it = xpac.getStateMachine().eAllContents();
+ while (it.hasNext()) {
+ EObject item = it.next();
+ if (item instanceof StateGraphItem)
+ {
+
+ StateGraphItem toCheck = (StateGraphItem) item;
+ //System.out.println("Checked : " + toCheck.getName());
+ if (!checker.isReachable(toCheck)) {
+ //System.out.println("Unreachable "+ toCheck.getName());
+
+ EObject orig = xpac.getOrig(toCheck);
+ EObject container = orig.eContainer();
+ @SuppressWarnings("unchecked")
+ int idx = ((List<? extends EObject>)container.eGet(orig.eContainingFeature())).indexOf(orig);
+ messageAcceptor.acceptWarning(
+ "Unreachable state/point of graph",
+ xpac.getOrig(toCheck).eContainer(), xpac.getOrig(toCheck).eContainingFeature(), idx,
+ "UNREACHABLE", toCheck.getName());
+ }
+ }
+ }
+
+ }
+
+ }
+
+}