Prechádzať zdrojové kódy

Moved ComplexTypeAwareContextInitializer from c.domain.runtime to base

jthoene 7 rokov pred
rodič
commit
6c2d4a3d2f

+ 128 - 0
plugins/org.yakindu.sct.simulation.core.sexec/src/org/yakindu/sct/simulation/core/sexec/container/ComplexTypeAwareContextInitializer.xtend

@@ -0,0 +1,128 @@
+package org.yakindu.sct.simulation.core.sexec.container
+
+import java.util.Stack
+import org.eclipse.emf.ecore.util.EcoreUtil
+import org.yakindu.base.types.ComplexType
+import org.yakindu.base.types.GenericElement
+import org.yakindu.base.types.Operation
+import org.yakindu.base.types.Property
+import org.yakindu.base.types.Type
+import org.yakindu.base.types.TypeParameter
+import org.yakindu.base.types.TypedElement
+import org.yakindu.base.types.inferrer.ITypeSystemInferrer.InferenceResult
+import org.yakindu.sct.model.sruntime.ExecutionSlot
+import org.yakindu.sct.model.sruntime.SRuntimeFactory
+import org.yakindu.sct.model.stext.stext.VariableDefinition
+
+import static org.yakindu.base.types.typesystem.ITypeSystem.ANY
+
+/**
+ * Execution context initializer which recursively builds composite slots for variables with complex types.
+ * 
+ * @author Thomas Kutz - Initial contribution and API
+ */
+
+class ComplexTypeAwareContextInitializer extends DefaultExecutionContextInitializer {
+
+	protected extension SRuntimeFactory factory = SRuntimeFactory.eINSTANCE
+	
+	/**
+	 * Stores names of hierarchically complex typed variables for proper computation of full qualified names.
+	 */
+	protected Stack<String> nameStack = new Stack()
+
+	override dispatch ExecutionSlot create createExecutionSlotFor(variable) transform(VariableDefinition variable) {
+		it.writable = it.writable && !variable.const
+	}
+
+	/**
+	 * Do not use <code>create</code> here because properties within complex types are the same for multiple variables 
+	 * of same complex type
+	 */
+	def dispatch ExecutionSlot transform(Property prop) {
+		val slot = createExecutionSlotFor(prop)
+		slot.writable = slot.writable && !prop.const
+		slot
+	}
+
+	def dispatch ExecutionSlot transform(Operation op) {
+		val slot = createExecutionSlotFor(op)
+		slot
+	}
+
+	def public ExecutionSlot createExecutionSlotFor(TypedElement element) {
+		val inferenceResult = element.infer
+		val varType = inferenceResult.type
+
+		transformByType(varType, element, inferenceResult)
+	}
+
+	def protected dispatch ExecutionSlot transformByType(ComplexType type, TypedElement element,
+		InferenceResult inferenceResult) {
+		createCompositeSlot => [
+			it.type = type
+			it.init(element)
+			nameStack.push(it.fqName)
+			for (feature : type.features) {
+				val featureType = feature.infer.type
+				val featureSlot = transformByType(featureType, feature, inferenceResult)
+				it.slots += featureSlot
+				nameStack.push(featureSlot.name)
+				featureSlot.fqName = nameStack.join(".")
+				nameStack.pop
+			}
+			nameStack.pop
+		]
+	}
+
+	def protected dispatch ExecutionSlot transformByType(TypeParameter type, TypedElement element,
+		InferenceResult inferenceResult) {
+		val typeParameterInferenceResult = inferTypeParameter(type, inferenceResult)
+		val inferred = typeParameterInferenceResult.type
+		if (!(inferred instanceof TypeParameter)) {
+			return transformByType(inferred, element, typeParameterInferenceResult)
+		} else {
+			return createExecutionVariable => [
+				it.name = element.fullyQualifiedName.lastSegment
+				it.fqName = element.fullyQualifiedName.toString
+				it.type = inferred
+				it.value = null
+			]
+		}
+	}
+
+	def protected dispatch ExecutionSlot transformByType(Type type, TypedElement element,
+		InferenceResult inferenceResult) {
+		createExecutionVariable => [
+			it.type = type
+			it.init(element)
+		]
+	}
+
+	// copied from ExpressionsTypeInferrer
+	def protected inferTypeParameter(TypeParameter typeParameter, InferenceResult ownerResult) {
+		if (ownerResult.bindings.isEmpty() || !(ownerResult.type instanceof GenericElement)) {
+			return InferenceResult.from(ANY.type)
+		} else {
+			val index = (ownerResult.type as GenericElement).typeParameters.indexOf(typeParameter)
+			return InferenceResult.from(ownerResult.bindings.get(index).type, ownerResult.bindings.get(index).bindings)
+		}
+	}
+
+	def protected init(ExecutionSlot it, TypedElement variable) {
+		name = variable.fullyQualifiedName.lastSegment
+		fqName = variable.fullyQualifiedName.toString
+		value = initialValue(type, variable)
+	}
+
+	def protected initialValue(Type slotType, TypedElement variable) {
+		val PropertyInitialValueAdapter adapter = EcoreUtil.getExistingAdapter(variable,
+			PropertyInitialValueAdapter) as PropertyInitialValueAdapter
+		return adapter?.initialValue?.value ?: slotType?.defaultValue
+	}
+
+	def value(Object it) {
+		it
+	}
+
+}

+ 54 - 0
plugins/org.yakindu.sct.simulation.core.sexec/src/org/yakindu/sct/simulation/core/sexec/container/PropertyInitialValueAdapter.java

@@ -0,0 +1,54 @@
+/** 
+ * Copyright (c) 2016 committers of YAKINDU 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 
+ * Contributors:
+ * committers of YAKINDU - initial API and implementation
+ *
+*/
+package org.yakindu.sct.simulation.core.sexec.container;
+
+import org.eclipse.emf.common.notify.impl.AdapterImpl;
+
+/**
+ * Used to store an initial value on a property.
+ * 
+ * @author Thomas Kutz - Initial contribution and API
+ *
+ */
+public class PropertyInitialValueAdapter extends AdapterImpl {
+
+	private final Object initialValue;
+
+	public PropertyInitialValueAdapter(Object initialValue) {
+		this.initialValue = initialValue;
+	}
+
+	@Override
+	public boolean isAdapterForType(Object type) {
+		return type == PropertyInitialValueAdapter.class;
+	}
+
+	public Object getInitialValue() {
+		return initialValue;
+	}
+
+	public static class LazyInitialValue {
+
+		private String expression;
+
+		protected LazyInitialValue(String expression) {
+			this.expression = expression;
+		}
+
+		public String getExpression() {
+			return expression;
+		}
+
+		public static LazyInitialValue of(String expression) {
+			return new LazyInitialValue(expression);
+		}
+	}
+}