summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrohit21agrawal2012-12-20 11:53:28 (EST)
committerrohit21agrawal2012-12-20 11:53:28 (EST)
commit36a897a523bb2f0549d96e4f3f1e4844b7f34599 (patch)
treef44fec3ae512bb787987d16d9c51999018a8c118
parent6653a7847d36474feabce43b222db4d756af647d (diff)
downloadorg.eclipse.etrice-36a897a523bb2f0549d96e4f3f1e4844b7f34599.zip
org.eclipse.etrice-36a897a523bb2f0549d96e4f3f1e4844b7f34599.tar.gz
org.eclipse.etrice-36a897a523bb2f0549d96e4f3f1e4844b7f34599.tar.bz2
[CQ6589]: All files, committed from scratch due to resetting ofrefs/changes/99/10199/1
environment 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: I073d19dca95528603fc2af7fe585f131e9901377
-rw-r--r--plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/AbstractExecutionValidator.java200
-rw-r--r--plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/ActionCodeAnalyzer.java24
-rw-r--r--plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/Activator.java39
-rw-r--r--plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/ActiveRules.java172
-rw-r--r--plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/HandledMessage.java42
-rw-r--r--plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/ProposalGenerator.java130
-rw-r--r--plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/ReachabilityCheck.java21
-rw-r--r--plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/ReachabilityValidator.java1
-rw-r--r--plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/SemanticsCheck.java240
9 files changed, 810 insertions, 59 deletions
diff --git a/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/AbstractExecutionValidator.java b/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/AbstractExecutionValidator.java
index a2a871f..b0a2eeb 100644
--- a/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/AbstractExecutionValidator.java
+++ b/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/AbstractExecutionValidator.java
@@ -1,99 +1,223 @@
/*******************************************************************************
- * Copyright (c) 2012 protos software gmbh (http://www.protos.de).
- * All rights reserved. This program and the accompanying materials
+ * Copyright (c) 2012 Rohit Agrawal
+ * 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:
- * Henrik Rentz-Reichert (initial contribution)
+ * Rohit Agrawal (initial contribution)
*
*******************************************************************************/
+
package org.eclipse.etrice.abstractexec.behavior;
import java.util.List;
+import org.eclipse.core.runtime.Platform;
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.ActiveTrigger;
import org.eclipse.etrice.core.genmodel.etricegen.ExpandedActorClass;
import org.eclipse.etrice.core.room.ActorClass;
+import org.eclipse.etrice.core.room.DetailCode;
import org.eclipse.etrice.core.room.GeneralProtocolClass;
import org.eclipse.etrice.core.room.InterfaceItem;
+import org.eclipse.etrice.core.room.MessageFromIf;
import org.eclipse.etrice.core.room.ProtocolClass;
+import org.eclipse.etrice.core.room.State;
import org.eclipse.etrice.core.room.StateGraphItem;
+import org.eclipse.etrice.core.room.Trigger;
+import org.eclipse.etrice.core.room.TriggeredTransition;
import org.eclipse.etrice.core.room.util.RoomHelpers;
import org.eclipse.etrice.core.validation.IRoomValidator;
import org.eclipse.xtext.validation.ValidationMessageAcceptor;
/**
* @author rentzhnr
- *
+ *
*/
public class AbstractExecutionValidator implements IRoomValidator {
- /* (non-Javadoc)
- * @see org.eclipse.etrice.core.validation.IRoomValidator#validate(org.eclipse.emf.ecore.EObject, org.eclipse.xtext.validation.ValidationMessageAcceptor)
+ private static boolean traceExec = false;
+ private static String traceName = "";
+ static {
+ if (Activator.getDefault().isDebugging()) {
+ String value = Platform
+ .getDebugOption("org.eclipse.etrice.abstractexec.behavior/trace/abstractexec");
+ if (value != null && value.equalsIgnoreCase(Boolean.toString(true))) {
+ traceExec = true;
+ }
+ traceName = Platform
+ .getDebugOption("org.eclipse.etrice.abstractexec.behavior/trace/abstractexec/name");
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.etrice.core.validation.IRoomValidator#validate(org.eclipse
+ * .emf.ecore.EObject,
+ * org.eclipse.xtext.validation.ValidationMessageAcceptor)
*/
@Override
- public void validate(EObject object, ValidationMessageAcceptor messageAcceptor) {
+ public void validate(EObject object,
+ ValidationMessageAcceptor messageAcceptor) {
if (!(object instanceof ActorClass))
return;
-
ActorClass ac = (ActorClass) object;
-
- boolean allProtocolsWithSemantics = true;
+ if (traceExec && !ac.getName().equals(traceName))
+ return;
+ if (traceExec)
+ System.out.println("AbstractExecutionValidator checking class "
+ + ac.getName());
+ boolean oneProtocolsWithSemantics = false;
List<InterfaceItem> ifItems = RoomHelpers.getAllInterfaceItems(ac);
for (InterfaceItem item : ifItems) {
GeneralProtocolClass pc = item.getGeneralProtocol();
if (!(pc instanceof ProtocolClass))
continue;
- if (((ProtocolClass) pc).getSemantics() == null) {
- allProtocolsWithSemantics = false;
+ if (traceExec)
+ System.out.println(" Checking protocolClass " + pc.getName()
+ + " for semantics");
+ if (((ProtocolClass) pc).getSemantics() != null) {
+ oneProtocolsWithSemantics = true;
+ if (traceExec)
+ System.out
+ .println(" Will execute because semantics defined for "
+ + pc.getName());
break;
}
}
-
- if (allProtocolsWithSemantics) {
+ if (oneProtocolsWithSemantics) {
// begin abstract execution on state machine of expanded actor class
-
+ System.out
+ .println(" Reached where at least one interface items has semantics");
NullDiagnostician diagnostician = new NullDiagnostician();
- GeneratorModelBuilder builder = new GeneratorModelBuilder(new NullLogger(), diagnostician);
+ GeneratorModelBuilder builder = new GeneratorModelBuilder(
+ new NullLogger(), diagnostician);
ExpandedActorClass xpac = builder.createExpandedActorClass(ac);
-
+
if (xpac != null && !diagnostician.isFailed()) {
- // ActionCodeAnalyzer analyzer = new ActionCodeAnalyzer(ac);
-// ReachabilityCheck checker = new ReachabilityCheck(xpac);
-// checker.computeReachability();
+ SemanticsCheck checker = new SemanticsCheck(xpac);
+ checker.checkSemantics();
+
+ if (traceExec)
+ System.out.println(" Rule checking for "
+ + xpac.getActorClass().getName() + " is over");
- TreeIterator<EObject> it = xpac.getStateMachine().eAllContents();
+ TreeIterator<EObject> it = xpac.getStateMachine()
+ .eAllContents();
while (it.hasNext()) {
- EObject item = it.next();
- if (item instanceof StateGraphItem)
- {
-// StateGraphItem toCheck = (StateGraphItem) item;
-// if (false/*!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",
-// container, toCheck.eContainingFeature(), idx,
-// "UNREACHABLE", toCheck.getName());
-// }
+ EObject obj = it.next();
+ if (obj instanceof State) {
+ ProposalGenerator propGen = new ProposalGenerator(xpac,
+ checker);
+ State st = (State) obj;
+ propGen.createProposals(st);
+ createMarkersForProposals(propGen, messageAcceptor, st,
+ xpac);
+ }
+ // the following part takes care of all the warnings
+ if (obj instanceof StateGraphItem) {
+ StateGraphItem item = (StateGraphItem) obj;
+ createMarkersForWarnings(checker, messageAcceptor,
+ item, xpac);
}
}
+ if (traceExec)
+ System.out
+ .println("AbstractExecutionValidator done checking class "
+ + ac.getName());
}
}
}
+ private void createMarkersForProposals(ProposalGenerator propGen,
+ ValidationMessageAcceptor messageAcceptor, State st,
+ ExpandedActorClass xpac) {
+ List<MessageFromIf> incoming = propGen.getIncomingProposals();
+ EObject orig = xpac.getOrig(st);
+ EObject container = orig.eContainer();
+ @SuppressWarnings("unchecked")
+ int idx = ((List<? extends EObject>) container.eGet(orig
+ .eContainingFeature())).indexOf(orig);
+
+ for (MessageFromIf msg : incoming) {
+ messageAcceptor.acceptWarning("State should handle the message "
+ + msg.getMessage().getName() + " from port "
+ + msg.getFrom().getName() + " ", container,
+ orig.eContainingFeature(), idx, "Receive message",
+ st.getName());
+ }
+ List<MessageFromIf> outgoing = propGen.getOutgoingProposals();
+
+ for (MessageFromIf msg : outgoing) {
+ messageAcceptor.acceptInfo("State could send the message "
+ + msg.getMessage().getName() + " to port "
+ + msg.getFrom().getName() + " ", container,
+ orig.eContainingFeature(), idx, "Send message",
+ st.getName());
+
+ }
+
+ }
+
+ private void createMarkersForWarnings(SemanticsCheck checker,
+ ValidationMessageAcceptor messageAcceptor, StateGraphItem item,
+ ExpandedActorClass xpac) {
+ List<HandledMessage> warningList = checker.getWarningMsg(item);
+ if (traceExec && warningList != null) {
+ System.out.println("Messages in the warning list for item "
+ + item.getName());
+ }
+ if (warningList != null)
+ for (HandledMessage msg : warningList) {
+ EObject origin = msg.getOrigin();
+ if (origin instanceof ActiveTrigger) {
+ ActiveTrigger trigger = (ActiveTrigger) origin;
+ for (TriggeredTransition trans : trigger.getTransitions()) {
+ // have to translate back the transition to our original
+ // model
+ TriggeredTransition orig = (TriggeredTransition) xpac
+ .getOrig(trans);
+ for (Trigger trig : orig.getTriggers()) {
+ for (MessageFromIf mif : trig.getMsgFromIfPairs()) {
+ // messages haven't been copied, so all point to
+ // the same objects and we can just compare
+ // pointers
+ if (mif.getMessage() == msg.getMsg()
+ && mif.getFrom() == msg.getIfitem()) {
+ messageAcceptor
+ .acceptWarning(
+ "The message violates the semantic rule",
+ trig,
+ mif.eContainingFeature(),
+ trig.getMsgFromIfPairs()
+ .indexOf(trig),
+ "VIOLATION", trigger
+ .getMsg().getName());
+ }
+ }
+ }
+ }
+ } else if (origin instanceof DetailCode) {
+ DetailCode dc = (DetailCode) origin;
+ EObject orig = xpac.getOrig(dc);
+ messageAcceptor.acceptWarning(
+ "The message violates the semantic rule",
+ orig.eContainer(), orig.eContainingFeature(),
+ ValidationMessageAcceptor.INSIGNIFICANT_INDEX,
+ "VIOLATION");
+
+ }
+ }
+ }
}
diff --git a/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/ActionCodeAnalyzer.java b/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/ActionCodeAnalyzer.java
index ac47532..5a00ad4 100644
--- a/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/ActionCodeAnalyzer.java
+++ b/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/ActionCodeAnalyzer.java
@@ -1,12 +1,12 @@
/*******************************************************************************
- * Copyright (c) 2012 protos software gmbh (http://www.protos.de).
- * All rights reserved. This program and the accompanying materials
+ * Copyright (c) 2012 Rohit Agrawal
+ * 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:
- * Henrik Rentz-Reichert (initial contribution)
+ * Rohit Agrawal (initial contribution)
*
*******************************************************************************/
@@ -19,8 +19,6 @@ import org.eclipse.etrice.core.room.ActorClass;
import org.eclipse.etrice.core.room.DetailCode;
import org.eclipse.etrice.core.room.InterfaceItem;
import org.eclipse.etrice.core.room.Message;
-import org.eclipse.etrice.core.room.MessageFromIf;
-import org.eclipse.etrice.core.room.RoomFactory;
import org.eclipse.etrice.generator.base.DefaultTranslationProvider;
import org.eclipse.etrice.generator.base.DetailCodeTranslator;
@@ -32,9 +30,9 @@ public class ActionCodeAnalyzer {
private class Collector extends DefaultTranslationProvider {
- private ArrayList<MessageFromIf> mifs = new ArrayList<MessageFromIf>();
+ private ArrayList<HandledMessage> mifs = new ArrayList<HandledMessage>();
- public ArrayList<MessageFromIf> getMifs() {
+ public ArrayList<HandledMessage> getMifs() {
return mifs;
}
@@ -45,10 +43,8 @@ public class ActionCodeAnalyzer {
public String getInterfaceItemMessageText(InterfaceItem item,
Message msg, ArrayList<String> args, String index, String orig) {
- MessageFromIf mif = RoomFactory.eINSTANCE.createMessageFromIf();
- mif.setFrom(item);
- mif.setMessage(msg);
- mifs.add(mif);
+ HandledMessage sm = new HandledMessage(item, msg, origin);
+ mifs.add(sm);
return orig;
}
@@ -63,19 +59,21 @@ public class ActionCodeAnalyzer {
// create a new list and leave previous unchanged
public void begin() {
- mifs = new ArrayList<MessageFromIf>();
+ mifs = new ArrayList<HandledMessage>();
}
}
private Collector collector;
private DetailCodeTranslator translator;
+ private DetailCode origin;
public ActionCodeAnalyzer(ActorClass ac) {
collector = new Collector();
translator = new DetailCodeTranslator(ac, collector);
}
- public List<MessageFromIf> analyze(DetailCode dc) {
+ public List<HandledMessage> analyze(DetailCode dc) {
+ origin = dc;
collector.begin();
translator.translateDetailCode(dc);
return collector.getMifs();
diff --git a/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/Activator.java b/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/Activator.java
new file mode 100644
index 0000000..66c49dc
--- /dev/null
+++ b/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/Activator.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Rohit Agrawal
+ * 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 org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+public class Activator extends AbstractUIPlugin implements BundleActivator {
+
+ private static Activator instance = null;
+
+ public static
+ Activator getDefault() {
+ return instance;
+ }
+
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ instance = this;
+ }
+
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ instance = null;
+ super.stop(context);
+ }
+}
diff --git a/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/ActiveRules.java b/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/ActiveRules.java
new file mode 100644
index 0000000..dabe29c
--- /dev/null
+++ b/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/ActiveRules.java
@@ -0,0 +1,172 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Rohit Agrawal
+ * 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.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.etrice.core.genmodel.etricegen.ExpandedActorClass;
+import org.eclipse.etrice.core.room.GeneralProtocolClass;
+import org.eclipse.etrice.core.room.InSemanticsRule;
+import org.eclipse.etrice.core.room.InterfaceItem;
+import org.eclipse.etrice.core.room.ProtocolClass;
+import org.eclipse.etrice.core.room.SemanticsRule;
+import org.eclipse.etrice.core.room.util.RoomHelpers;
+
+public class ActiveRules {
+ private HashMap<InterfaceItem, List<SemanticsRule>> rules;
+ private static boolean traceRules = false;
+ private static int traceLevel = 0;
+ static {
+ if (Activator.getDefault().isDebugging()) {
+ String value = Platform
+ .getDebugOption("org.eclipse.etrice.abstractexec.behavior/trace/rules");
+ if (value != null && value.equalsIgnoreCase(Boolean.toString(true))) {
+ traceRules = true;
+ }
+ value = Platform
+ .getDebugOption("org.eclipse.etrice.abstractexec.behavior/trace/rules/level");
+ if (value != null) {
+ traceLevel = Integer.parseInt(value);
+ }
+ }
+ }
+
+ // private static final int TRACE_RESULT = 1;
+ private static final int TRACE_DETAILS = 2;
+
+ public ActiveRules() {
+ rules = new HashMap<InterfaceItem, List<SemanticsRule>>();
+ }
+
+ private ActiveRules(HashMap<InterfaceItem, List<SemanticsRule>> r) {
+ rules = r;
+ }
+
+ public Set<InterfaceItem> getPortList() {
+ return rules.keySet();
+ }
+
+ public List<SemanticsRule> getRulesForPort(InterfaceItem port) {
+ return rules.get(port);
+ }
+
+ // checks for currently active rules against a message list and modifies the
+ // rules which can be merged with the destination node
+ public List<HandledMessage> consumeMessages(List<HandledMessage> msgList) {
+ List<HandledMessage> wrongMsgList = new ArrayList<HandledMessage>();
+ for (HandledMessage msg : msgList) {
+ List<SemanticsRule> localRules = rules.get(msg.getIfitem());
+ if (localRules != null) {
+ SemanticsRule match = null;
+ for (SemanticsRule rule : localRules) {
+ if (rule.getMsg() == msg.getMsg()) {
+ match = rule;
+ break;
+ }
+ }
+
+ if (match != null) {
+ if (traceRules && traceLevel >= TRACE_DETAILS)
+ System.out.println(" found match for "
+ + msg.getMsg().getName());
+
+ // discard all alternatives
+ localRules.clear();
+
+ // and add all follow ups
+ localRules.addAll(match.getFollowUps());
+ } else {
+ // TODO: issue a warning?
+ wrongMsgList.add(msg);
+ }
+ }
+ }
+ return wrongMsgList;
+ }
+
+ // merges the rules with the destination active rules
+ public boolean merge(ActiveRules ar) {
+ boolean added_at_least_one = false;
+ for (Entry<InterfaceItem, List<SemanticsRule>> entry : ar.rules
+ .entrySet()) {
+ for (SemanticsRule rule : entry.getValue()) {
+ InterfaceItem ifitem = entry.getKey();
+ if (rules.containsKey(ifitem)) {
+ if (!rules.get(ifitem).contains(rule)) {
+ rules.get(ifitem).add(rule);
+ added_at_least_one = true;
+ }
+ } else {
+ List<SemanticsRule> tempList = new ArrayList<SemanticsRule>();
+ tempList.add(rule);
+ rules.put(ifitem, tempList);
+ added_at_least_one = true;
+ }
+ }
+ }
+
+ if (traceRules && traceLevel >= TRACE_DETAILS)
+ System.out.println(" merge changed rules");
+
+ return added_at_least_one;
+ }
+
+ public ActiveRules createCopy() {
+ HashMap<InterfaceItem, List<SemanticsRule>> newRules = new HashMap<InterfaceItem, List<SemanticsRule>>();
+ for (InterfaceItem ifitem : rules.keySet()) {
+ newRules.put(ifitem,
+ new ArrayList<SemanticsRule>(rules.get(ifitem)));
+ }
+ return new ActiveRules(newRules);
+ }
+
+ public void buildInitLocalRules(ExpandedActorClass xpAct) {
+ // HashMap<InterfaceItem, EList<SemanticsRule>> locals = new
+ // HashMap<InterfaceItem, EList<SemanticsRule>>();
+ List<InterfaceItem> portList = RoomHelpers.getAllInterfaceItems(xpAct
+ .getActorClass());
+ for (InterfaceItem ifitem : portList) {
+ GeneralProtocolClass gpc = ifitem.getGeneralProtocol();
+ if (gpc instanceof ProtocolClass
+ && ((ProtocolClass) gpc).getSemantics() != null)
+ rules.put(ifitem, ((ProtocolClass) gpc).getSemantics()
+ .getRules());
+ }
+
+ }
+
+ public void print() {
+ for (InterfaceItem port : rules.keySet()) {
+ System.out.println(" Rules for Port " + port.getName() + ":");
+ for (SemanticsRule rule : rules.get(port)) {
+ printRule(rule, " ");
+ }
+ }
+ }
+
+ public void printRule(SemanticsRule rule, String indent) {
+ if (rule instanceof InSemanticsRule)
+ System.out.println(indent + "in: " + rule.getMsg().getName());
+ else
+ System.out.println(indent + "out: " + rule.getMsg().getName());
+ // recursion
+ for (SemanticsRule sr : rule.getFollowUps()) {
+ printRule(sr, indent + " ");
+ }
+ }
+}
diff --git a/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/HandledMessage.java b/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/HandledMessage.java
new file mode 100644
index 0000000..2aa91f1
--- /dev/null
+++ b/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/HandledMessage.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Rohit Agrawal
+ * 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 org.eclipse.emf.ecore.EObject;
+import org.eclipse.etrice.core.room.InterfaceItem;
+import org.eclipse.etrice.core.room.Message;
+
+public class HandledMessage {
+ private InterfaceItem ifitem;
+ private Message msg;
+ private EObject origin;
+
+ public HandledMessage(InterfaceItem ifitem, Message msg, EObject origin) {
+ this.ifitem = ifitem;
+ this.msg = msg;
+ this.origin = origin;
+ }
+
+ public InterfaceItem getIfitem() {
+ return ifitem;
+ }
+
+ public Message getMsg() {
+ return msg;
+ }
+
+ public EObject getOrigin() {
+ return origin;
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/ProposalGenerator.java b/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/ProposalGenerator.java
new file mode 100644
index 0000000..61eede3
--- /dev/null
+++ b/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/ProposalGenerator.java
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Rohit Agrawal
+ * 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.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.etrice.core.genmodel.etricegen.ActiveTrigger;
+import org.eclipse.etrice.core.genmodel.etricegen.ExpandedActorClass;
+import org.eclipse.etrice.core.room.InterfaceItem;
+import org.eclipse.etrice.core.room.MessageFromIf;
+import org.eclipse.etrice.core.room.Port;
+import org.eclipse.etrice.core.room.RoomFactory;
+import org.eclipse.etrice.core.room.SemanticsRule;
+import org.eclipse.etrice.core.room.State;
+import org.eclipse.etrice.core.room.util.RoomHelpers;
+
+public class ProposalGenerator {
+ private ExpandedActorClass xpac;
+ private SemanticsCheck checker;
+ private List<MessageFromIf> outgoingProposal = new LinkedList<MessageFromIf>();
+ private List<MessageFromIf> incomingProposal = new LinkedList<MessageFromIf>();
+ private static boolean traceProposals = false;
+ static {
+ if (Activator.getDefault().isDebugging()) {
+ String value = Platform
+ .getDebugOption("org.eclipse.etrice.abstractexec.behavior/trace/proposals");
+ if (value != null && value.equalsIgnoreCase(Boolean.toString(true))) {
+ traceProposals = true;
+ }
+ }
+ }
+
+ public ProposalGenerator(ExpandedActorClass xp, SemanticsCheck chk) {
+ xpac = xp;
+ checker = chk;
+ }
+
+ public List<MessageFromIf> getIncomingProposals() {
+ return incomingProposal;
+ }
+
+ public List<MessageFromIf> getOutgoingProposals() {
+ return outgoingProposal;
+ }
+
+
+ public void createProposals(State st) {
+ ActiveRules rules = checker.getActiveRules(st);
+
+ // in case the state is disconnected component of the graph
+ if (rules == null)
+ return;
+
+ outgoingProposal.clear();
+ incomingProposal.clear();
+
+ Set<SemanticsRule> rulesToIgnore = new HashSet<SemanticsRule>();
+
+ for (ActiveTrigger trigger : xpac.getActiveTriggers(st)) {
+ SemanticsRule match = null;
+ Port port = (Port) trigger.getIfitem();
+ if (rules.getPortList().contains(port)) {
+ List<SemanticsRule> ruleList = rules.getRulesForPort(port);
+ for (SemanticsRule curRule : ruleList) {
+ if (curRule.getMsg() == trigger.getMsg()) {
+ match = curRule;
+ break;
+ }
+ }
+ }
+ if (match != null) {
+ // mark this rule for ignoring while generating proposals
+ // as they have already been taken care of
+ rulesToIgnore.add(match);
+ }
+ }
+
+ // now start generating proposals by listing all the rules and ignoring
+ // the ones
+ // marked above
+ for (InterfaceItem item : rules.getPortList()) {
+ for (SemanticsRule ruleToCheck : rules.getRulesForPort(item)) {
+ if (!rulesToIgnore.contains(ruleToCheck)) {
+ MessageFromIf mif = RoomFactory.eINSTANCE
+ .createMessageFromIf();
+ mif.setFrom(item);
+ mif.setMessage(ruleToCheck.getMsg());
+ boolean isOutgoing = RoomHelpers.getMessageListDeep(item, true)
+ .contains(ruleToCheck.getMsg());
+ if (isOutgoing) {
+ outgoingProposal.add(mif);
+ } else {
+ incomingProposal.add(mif);
+ }
+
+ }
+ }
+ }
+
+ if (traceProposals) {
+ System.out.println(" Proposals for : " + st.getName());
+
+ for (MessageFromIf msg : outgoingProposal) {
+ System.out.println(" Outgoing msg proposal : "
+ + msg.getFrom().getName() + "."
+ + msg.getMessage().getName() + "()");
+ }
+ for (MessageFromIf msg : incomingProposal) {
+ System.out.println(" Incoming msg proposal : "
+ + msg.getMessage().getName() + " from "
+ + msg.getFrom().getName());
+ }
+ }
+ }
+
+}
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
index 4a1e452..3f1b3a9 100644
--- 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
@@ -8,24 +8,29 @@
* CONTRIBUTORS:
* Rohit Agrawal (initial contribution)
*
- *
*******************************************************************************/
package org.eclipse.etrice.abstractexec.behavior;
-import java.util.*;
-
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Queue;
+import java.util.Set;
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.EntryPoint;
+import org.eclipse.etrice.core.room.InitialTransition;
+import org.eclipse.etrice.core.room.State;
+import org.eclipse.etrice.core.room.StateGraph;
+import org.eclipse.etrice.core.room.StateGraphItem;
+import org.eclipse.etrice.core.room.StateGraphNode;
+import org.eclipse.etrice.core.room.TrPoint;
+import org.eclipse.etrice.core.room.Transition;
+import org.eclipse.etrice.core.room.TransitionPoint;
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 {
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
index 406ecf6..d568aef 100644
--- 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
@@ -11,6 +11,7 @@
*
*******************************************************************************/
+
package org.eclipse.etrice.abstractexec.behavior;
import java.util.List;
diff --git a/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/SemanticsCheck.java b/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/SemanticsCheck.java
new file mode 100644
index 0000000..81947f4
--- /dev/null
+++ b/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/SemanticsCheck.java
@@ -0,0 +1,240 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Rohit Agrawal
+ * 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.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Queue;
+import java.util.Set;
+
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.etrice.core.genmodel.etricegen.ActiveTrigger;
+import org.eclipse.etrice.core.genmodel.etricegen.ExpandedActorClass;
+import org.eclipse.etrice.core.room.InitialTransition;
+import org.eclipse.etrice.core.room.State;
+import org.eclipse.etrice.core.room.StateGraph;
+import org.eclipse.etrice.core.room.StateGraphItem;
+import org.eclipse.etrice.core.room.StateGraphNode;
+import org.eclipse.etrice.core.room.Transition;
+import org.eclipse.etrice.core.room.util.RoomHelpers;
+
+public class SemanticsCheck {
+ private Queue<StateGraphNode> queue;
+ private Set<StateGraphNode> visited;
+ private ExpandedActorClass xpAct;
+ private HashMap<StateGraphItem, ActiveRules> mapToRules = new HashMap<StateGraphItem, ActiveRules>();
+ private ActionCodeAnalyzer codeAnalyzer;
+ private HashMap<StateGraphItem, List<HandledMessage>> mapToWarnings = new HashMap<StateGraphItem, List<HandledMessage>>();
+ private static boolean traceChecks = false;
+ private static int traceLevel = 0;
+ static {
+ if (Activator.getDefault().isDebugging()) {
+ String value = Platform.getDebugOption("org.eclipse.etrice.abstractexec.behavior/trace/checks");
+ if (value != null && value.equalsIgnoreCase(Boolean.toString(true))) {
+ traceChecks = true;
+ }
+ value = Platform.getDebugOption("org.eclipse.etrice.abstractexec.behavior/trace/checks/level");
+ if (value != null) {
+ traceLevel = Integer.parseInt(value);
+ }
+ }
+ }
+
+ private static final int TRACE_RESULT = 1;
+ private static final int TRACE_DETAILS = 2;
+
+ public SemanticsCheck(ExpandedActorClass xpac) {
+ queue = new LinkedList<StateGraphNode>();
+ xpAct = xpac;
+ visited = new HashSet<StateGraphNode>();
+ codeAnalyzer = new ActionCodeAnalyzer(xpac.getActorClass());
+ }
+
+ public void checkSemantics() {
+ if (traceChecks)
+ System.out.println("checkSemantics: check of ActorClass "+xpAct.getActorClass().getName());
+
+ StateGraph graph = xpAct.getStateMachine();
+ ActiveRules localRules = new ActiveRules();
+ localRules.buildInitLocalRules(xpAct);
+ addStartingPoints(graph, localRules);
+ doTraversal();
+
+ if (traceChecks) {
+ if (traceLevel>=TRACE_RESULT)
+ printRules();
+
+ System.out.println("checkSemantics: done with check of ActorClass "+xpAct.getActorClass().getName());
+ }
+ }
+
+ private void addStartingPoints(StateGraph graph, ActiveRules localRules) {
+ EList<Transition> transitions = graph.getTransitions();
+ for (Transition trans : transitions)
+ if (trans instanceof InitialTransition) {
+ StateGraphNode cur = xpAct.getNode(trans.getTo());
+ List<HandledMessage> msgList = codeAnalyzer.analyze(trans.getAction());
+ if (cur instanceof State) {
+ msgList.addAll(codeAnalyzer.analyze(((State) cur).getEntryCode()));
+ }
+ List<HandledMessage> wrongMsgList = localRules.consumeMessages(msgList);
+ addToWarning(trans, wrongMsgList);
+ boolean rulesChanged = false;
+ if (mapToRules.containsKey(cur)) {
+ rulesChanged = mapToRules.get(cur).merge(localRules);
+ } else {
+ mapToRules.put(cur, localRules);
+ rulesChanged = true;
+ }
+ if (!visited.contains(cur) || rulesChanged)
+ queue.add(cur);
+
+ break;
+ }
+ }
+
+ private void doTraversal() {
+ while (!queue.isEmpty()) {
+ Visit(queue.poll());
+ }
+ }
+
+ private void Visit(StateGraphNode node) {
+ visited.add(node);
+ if (node instanceof State) {
+ State st = (State) node;
+ if (RoomHelpers.hasDirectSubStructure(st)) {
+ addStartingPoints(st.getSubgraph(), mapToRules.get(st));
+ }
+ else {
+ for (ActiveTrigger trigger : xpAct.getActiveTriggers(st)) {
+ if (traceChecks && traceLevel>=TRACE_DETAILS) {
+ System.out.println(" Currently visiting: " + st.getName());
+ System.out.println(" Trigger: " + trigger.getMsg().getName());
+ }
+
+ for (Transition trans : trigger.getTransitions()) {
+ StateGraphNode target = xpAct.getNode(trans.getTo());
+ List<HandledMessage> msgList = new LinkedList<HandledMessage>();
+ // create a list of codes here in the order
+ // trigger, exit, action, entry
+ msgList.add(new HandledMessage(trigger.getIfitem(), trigger.getMsg(), trigger));
+ StateGraph triggerContext = (StateGraph) trans.eContainer();
+ State exitCalled = st;
+ while (true) {
+ // this is where all the exit code is added
+ msgList.addAll(codeAnalyzer.analyze(exitCalled.getExitCode()));
+ if (exitCalled.eContainer() == triggerContext)
+ break;
+ exitCalled = (State) exitCalled.eContainer().eContainer();
+ }
+ msgList.addAll(codeAnalyzer.analyze(trans.getAction()));
+ if (target instanceof State) {
+ msgList.addAll(codeAnalyzer.analyze(((State) target).getEntryCode()));
+ }
+ ActiveRules tempRule = mapToRules.get(node).createCopy();
+
+ if (traceChecks && traceLevel>=TRACE_DETAILS) {
+ System.out.println(" Messages in msglist before consuming: ");
+ for (HandledMessage msg : msgList) {
+ System.out.println(" Msg: "+ msg.getMsg().getName());
+ }
+ }
+ if (traceChecks && traceLevel>=TRACE_DETAILS) {
+ System.out.println(" rules before consuming message list : ");
+ printRules();
+ }
+ List<HandledMessage> wrongMsgList = tempRule.consumeMessages(msgList);
+ addToWarning(node, wrongMsgList);
+
+ if (traceChecks && traceLevel>=TRACE_DETAILS)
+ System.out.println(" Messages consumed");
+
+ addAndMergeRules(target, tempRule);
+
+ if (traceChecks && traceLevel>=TRACE_DETAILS) {
+ System.out.println(" rules after consuming and merging message list : ");
+ printRules();
+ }
+
+ }
+ }
+ }
+ } else {
+ /*
+ * If the current node is an Entry/Exit/Transition/Choice pt , then
+ * only the action code in the outgoing transition needs to be
+ * considered For this, a copy of the ActiveRules of the current
+ * node is created and is checked against each outgoing transition
+ * for Rule changes If there is any rule change or if the
+ * destination state hasn't been visited then the destination rules
+ * are merged with the current rules and destination node is added
+ * to the current queue.
+ */
+ for (Transition trans : xpAct.getOutgoingTransitions(node)) {
+ ActiveRules tempRule = mapToRules.get(node).createCopy();
+ List<HandledMessage> msgList = codeAnalyzer.analyze(trans.getAction());
+ StateGraphNode target = xpAct.getNode(trans.getTo());
+ if (target instanceof State) {
+ msgList.addAll(codeAnalyzer.analyze(((State) target).getEntryCode()));
+ }
+ List<HandledMessage> wrongMsgList = tempRule.consumeMessages(msgList);
+ addToWarning(node, wrongMsgList);
+ addAndMergeRules(target, tempRule);
+ }
+ }
+ }
+
+ private void addToWarning(StateGraphItem item,
+ List<HandledMessage> wrongMsgList) {
+ if (mapToWarnings.containsKey(item)) {
+ mapToWarnings.get(item).addAll(wrongMsgList);
+ } else {
+ mapToWarnings.put(item, wrongMsgList);
+ }
+ }
+ private void addAndMergeRules(StateGraphNode target, ActiveRules tempRule) {
+ boolean rulesChanged = false;
+ if (mapToRules.containsKey(target)) {
+ rulesChanged = mapToRules.get(target).merge(tempRule);
+ } else {
+ mapToRules.put(target, tempRule);
+ rulesChanged = true;
+ }
+ if (!visited.contains(target) || rulesChanged) {
+ queue.add(target);
+ }
+
+ }
+
+ public void printRules() {
+ System.out.println(" Current Rules: ");
+ System.out.println(" MapToRules size: " + this.mapToRules.size());
+ for (StateGraphItem item : this.mapToRules.keySet()) {
+ System.out.println(" Rules for " + item.getName() + " : ");
+ mapToRules.get(item).print();
+ }
+ }
+
+ public ActiveRules getActiveRules(StateGraphItem item) {
+ return mapToRules.get(item);
+ }
+ public List<HandledMessage> getWarningMsg (StateGraphItem item)
+ {
+ return mapToWarnings.get(item);
+ }
+}