|
@@ -35,10 +35,15 @@ import org.yakindu.sct.simulation.core.sruntime.EventDirection
|
|
|
import org.yakindu.sct.simulation.core.sruntime.ExecutionContext
|
|
|
import org.yakindu.sct.simulation.core.sruntime.ExecutionSlot
|
|
|
import org.yakindu.sct.simulation.core.sruntime.SRuntimeFactory
|
|
|
+import org.yakindu.base.expressions.expressions.ElementReferenceExpression
|
|
|
+import org.yakindu.sct.model.sexec.extensions.SExecExtensions
|
|
|
+import java.util.Set
|
|
|
+import java.util.HashSet
|
|
|
|
|
|
/**
|
|
|
*
|
|
|
* @author andreas muelder - Initial contribution and API
|
|
|
+ * @author axel terfloth - added functionality to filter unused declaration roots
|
|
|
*
|
|
|
*/
|
|
|
class DefaultExecutionContextInitializer implements IExecutionContextInitializer {
|
|
@@ -47,19 +52,45 @@ class DefaultExecutionContextInitializer implements IExecutionContextInitializer
|
|
|
@Inject protected extension ITypeSystem
|
|
|
@Inject protected extension ITypeSystemInferrer
|
|
|
@Inject protected extension ITypeValueProvider
|
|
|
+ @Inject protected extension SExecExtensions
|
|
|
|
|
|
+ protected boolean mapUnusedDaclarationRoots = false
|
|
|
+
|
|
|
override initialize(ExecutionContext context, ExecutionFlow flow) {
|
|
|
flow.scopes.forEach[context.slots += transform]
|
|
|
}
|
|
|
|
|
|
- def dispatch ExecutionSlot transform(ImportScope scope) {
|
|
|
- val composite = SRuntimeFactory.eINSTANCE.createCompositeSlot => [
|
|
|
- name = "import"
|
|
|
+ /**
|
|
|
+ * Hook that decides if unused declarations in import scopes should be transformed to execution slots.
|
|
|
+ * Subclasses may override this hook.
|
|
|
+ *
|
|
|
+ * @return - false by default
|
|
|
+ */
|
|
|
+ def isMapUnusedDeclarationRootsInImportScope() { mapUnusedDaclarationRoots }
|
|
|
+
|
|
|
+ def setMapUnusedDeclarationRootsInImportScope(boolean b) { mapUnusedDaclarationRoots = b }
|
|
|
+
|
|
|
+
|
|
|
+ def create it : SRuntimeFactory.eINSTANCE.createCompositeSlot importSlot(ExecutionFlow flow) {
|
|
|
+ it => [
|
|
|
+ name = "imports"
|
|
|
]
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch ExecutionSlot transform(ImportScope scope) {
|
|
|
+
|
|
|
+ val composite = importSlot(scope.flow)
|
|
|
+
|
|
|
+ val usedDeclarations = scope.flow.usedDeclarationRoots
|
|
|
+
|
|
|
// retrieve namespaces from variable names and create corresponding composite slots
|
|
|
- for (Declaration decl : scope.declarations.filter(ImportDeclaration).map[declaration]) {
|
|
|
+ for (Declaration decl : scope.declarations
|
|
|
+ .filter(ImportDeclaration)
|
|
|
+ .map[declaration]
|
|
|
+ .filter(decl | mapUnusedDeclarationRootsInImportScope || usedDeclarations.contains(decl)))
|
|
|
+ {
|
|
|
val pkg = EcoreUtil2.getContainerOfType(decl, Package)
|
|
|
- if (pkg != null) {
|
|
|
+ if (pkg !== null) {
|
|
|
val namespace = pkg.name
|
|
|
val declName = decl.name
|
|
|
val slot = composite.slots.getSlotFor(namespace)
|
|
@@ -79,7 +110,7 @@ class DefaultExecutionContextInitializer implements IExecutionContextInitializer
|
|
|
|
|
|
def getSlotFor(List<ExecutionSlot> slots, String name) {
|
|
|
val existingSlot = slots.findFirst[it.name == name]
|
|
|
- if (existingSlot != null && existingSlot instanceof CompositeSlot) {
|
|
|
+ if (existingSlot !== null && existingSlot instanceof CompositeSlot) {
|
|
|
existingSlot as CompositeSlot
|
|
|
} else {
|
|
|
val newSlot = SRuntimeFactory.eINSTANCE.createCompositeSlot
|
|
@@ -110,7 +141,7 @@ class DefaultExecutionContextInitializer implements IExecutionContextInitializer
|
|
|
if (scope.name !== null) {
|
|
|
name = scope.name
|
|
|
val scopeFqn = scope.fullyQualifiedName.toString
|
|
|
- fqName = if(namespace != null) namespace + "." + scopeFqn else scopeFqn
|
|
|
+ fqName = if(namespace !== null) namespace + "." + scopeFqn else scopeFqn
|
|
|
} else {
|
|
|
name = "default"
|
|
|
}
|
|
@@ -142,7 +173,7 @@ class DefaultExecutionContextInitializer implements IExecutionContextInitializer
|
|
|
SRuntimeFactory.eINSTANCE.createExecutionOperation => [
|
|
|
name = op.fullyQualifiedName.lastSegment
|
|
|
fqName = op.fullyQualifiedName.toString
|
|
|
- type = if(op.type != null) op.type else getType(ITypeSystem.VOID)
|
|
|
+ type = if(op.type !== null) op.type else getType(ITypeSystem.VOID)
|
|
|
value = it.type.defaultValue
|
|
|
]
|
|
|
}
|
|
@@ -156,4 +187,15 @@ class DefaultExecutionContextInitializer implements IExecutionContextInitializer
|
|
|
]
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @return A set of used declaration roots.
|
|
|
+ */
|
|
|
+ def protected usedDeclarationRoots(ExecutionFlow flow) {
|
|
|
+ val Set<Declaration> usedDecls = new HashSet<Declaration>()
|
|
|
+
|
|
|
+ if (flow !== null) flow.eAllContents.filter(typeof(ElementReferenceExpression)).map( ere | ere.reference ).filter(typeof(Declaration)).forEach[ decl | usedDecls += decl]
|
|
|
+
|
|
|
+ return usedDecls
|
|
|
+ }
|
|
|
}
|