Browse Source

Yakindu/sctpro#495 : handle not initialized values during simulation (#1433)

* Yakindu/sctpro#495 : handle not initialized values

* Yakindu/sctpro#926 : initialize fqn of slots for named interface scopes

* Yakindu/sctpro#495 : adjust slot resolving & handle values not set

* Refactored text calculation method
Johannes Dicks 8 years ago
parent
commit
b7c1ee6ddf

+ 6 - 1
plugins/org.yakindu.sct.simulation.core.sexec/src/org/yakindu/sct/simulation/core/sexec/container/DefaultExecutionContextInitializer.xtend

@@ -104,7 +104,12 @@ class DefaultExecutionContextInitializer implements IExecutionContextInitializer
 
 	def dispatch ExecutionSlot transform(InterfaceScope scope) {
 		SRuntimeFactory.eINSTANCE.createCompositeSlot => [
-			if(scope.name != null) name = scope.name else name = "default"
+			if (scope.name !== null) {
+				name = scope.name
+				fqName = scope.name
+			} else {
+				name = "default"
+			}
 			scope.declarations.forEach[decl|slots += decl.transform]
 		]
 	}

+ 46 - 38
plugins/org.yakindu.sct.simulation.core.sexec/src/org/yakindu/sct/simulation/core/sexec/interpreter/DefaultExecutionSlotResolver.xtend

@@ -4,7 +4,7 @@
  * 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:
  *     committers of YAKINDU - initial API and implementation
  */
@@ -18,11 +18,11 @@ import org.eclipse.xtext.util.SimpleAttributeResolver
 import org.yakindu.base.base.NamedElement
 import org.yakindu.base.expressions.expressions.AssignmentExpression
 import org.yakindu.base.expressions.expressions.ElementReferenceExpression
+import org.yakindu.base.expressions.expressions.Expression
 import org.yakindu.base.expressions.expressions.FeatureCall
 import org.yakindu.base.types.Event
 import org.yakindu.base.types.Operation
 import org.yakindu.base.types.Property
-import org.yakindu.sct.model.stext.stext.InterfaceScope
 import org.yakindu.sct.simulation.core.sruntime.CompositeSlot
 import org.yakindu.sct.simulation.core.sruntime.ExecutionContext
 import org.yakindu.sct.simulation.core.sruntime.ExecutionSlot
@@ -38,36 +38,35 @@ class DefaultExecutionSlotResolver implements IExecutionSlotResolver {
 	@Inject
 	protected extension IQualifiedNameProvider nameProvider
 
-	def dispatch ExecutionSlot resolve(ExecutionContext context, FeatureCall e) {		
-		return resolveByFeature(context, e, e.feature)		
+	def dispatch ExecutionSlot resolve(ExecutionContext context, FeatureCall e) {
+		return resolveByFeature(context, e, e.feature)
 	}
-	
+
 	def dispatch ExecutionSlot resolve(ExecutionContext context, ElementReferenceExpression e) {
 		packageNamespaceAwareResolve(context, e.reference)
 	}
-	
+
 	def dispatch ExecutionSlot resolve(ExecutionContext context, AssignmentExpression e) {
 		return context.resolve(e.varRef)
 	}
-	
-	def dispatch ExecutionSlot resolveByFeature(ExecutionContext context, FeatureCall e, EObject feature){
+
+	def dispatch ExecutionSlot resolveByFeature(ExecutionContext context, FeatureCall e, EObject feature) {
 		return context.getVariable(e.feature.fullyQualifiedName.toString)
 	}
-	
-	def dispatch ExecutionSlot resolveByFeature(ExecutionContext context, FeatureCall e, Operation feature){
+
+	def dispatch ExecutionSlot resolveByFeature(ExecutionContext context, FeatureCall e, Operation feature) {
 		return resolveCompositeSlot(context, e)
 	}
-	
-	def dispatch ExecutionSlot resolveByFeature(ExecutionContext context, FeatureCall e, Event feature){
+
+	def dispatch ExecutionSlot resolveByFeature(ExecutionContext context, FeatureCall e, Event feature) {
 		return resolveCompositeSlot(context, e)
 	}
-	
-	def dispatch ExecutionSlot resolveByFeature(ExecutionContext context, FeatureCall e, Property feature){
+
+	def dispatch ExecutionSlot resolveByFeature(ExecutionContext context, FeatureCall e, Property feature) {
 		return resolveCompositeSlot(context, e)
 	}
-	
-	
-	def ExecutionSlot resolveCompositeSlot(ExecutionContext context, FeatureCall e){
+
+	def ExecutionSlot resolveCompositeSlot(ExecutionContext context, FeatureCall e) {
 		var current = e
 		val Stack<FeatureCall> callStack = new Stack
 		callStack.add(0, e)
@@ -76,61 +75,70 @@ class DefaultExecutionSlotResolver implements IExecutionSlotResolver {
 			callStack.add(0, current)
 		}
 		// first: get the root slot where to start the search
-		val root = (current.owner as ElementReferenceExpression).reference
-		var ExecutionSlot featureSlot = null
+		var ExecutionSlot featureSlot = resolve(context, current.owner)
+
 		
-		if (root instanceof InterfaceScope) {
-			featureSlot = context.getSlot(callStack.pop.feature.fullyQualifiedName.toString)
-		} else {
-			featureSlot = resolve(context, current.owner)
-			if (featureSlot == null) {
-				return null // could not find starting slot for feature call
-			}
-		}
-		// go through all calls and traverse execution context hierarchy accordingly
+		// second: go through all calls and traverse execution context hierarchy accordingly
 		for (FeatureCall call : callStack) {
+			if (featureSlot === null) {
+				throw new IllegalStateException(
+					"Value of '" + current.feature.name  + "' in expression '" + getExpressionText(e) +
+						"' has not been set.") // could not find starting slot for feature call
+			}
 			featureSlot = resolveFromSlot(featureSlot, call)
 		}
 		return featureSlot
 	}
 	
+	def dispatch String getExpressionText(FeatureCall call) {
+		getExpressionText(call.owner) + "." + call.feature.name
+	}
+	
+	def dispatch String getExpressionText(ElementReferenceExpression exp) {
+		exp.reference.fullyQualifiedName.toString
+	}
+	
+	def dispatch String getExpressionText(Expression exp) {
+		// fallback
+	}
+
 	def protected dispatch ExecutionSlot resolveFromSlot(ExecutionSlot slot, FeatureCall call) {
 		slot // fallback
 	}
-	
+
 	def protected dispatch ExecutionSlot resolveFromSlot(CompositeSlot slot, Operation call) {
 		resolveByFeature(slot, call)
 	}
-	
+
 	def protected dispatch ExecutionSlot resolveFromSlot(CompositeSlot slot, FeatureCall call) {
 		resolveByFeature(slot, call.feature)
 	}
-	
+
 	def protected dispatch ExecutionSlot resolveByFeature(CompositeSlot slot, EObject feature) {
 		slot // fallback
 	}
-	
+
 	def protected dispatch ExecutionSlot resolveByFeature(CompositeSlot slot, Property feature) {
 		resolveByName(slot, feature)
 	}
-	
+
 	def protected dispatch ExecutionSlot resolveByFeature(CompositeSlot slot, Operation feature) {
 		resolveByName(slot, feature)
 	}
-	
+
 	def protected dispatch ExecutionSlot resolveByFeature(CompositeSlot slot, Event feature) {
 		resolveByName(slot, feature)
 	}
-	
+
 	def protected ExecutionSlot resolveByName(CompositeSlot slot, NamedElement element) {
 		slot.slots.findFirst[name == element.name]
 	}
-	
+
 	def protected ExecutionSlot packageNamespaceAwareResolve(ExecutionContext context, EObject element) {
-			context.getSlot(element.fullyQualifiedName.toString)
+		context.getSlot(element.fullyQualifiedName.toString)
 	}
 
 	def protected name(EObject e) {
 		return SimpleAttributeResolver::NAME_RESOLVER.apply(e)
 	}
-}
+}