Browse Source

Fixed pro issues 929, 992, and 971 (#1541)

* Filter unused declarations within slot initialization.

* Replace multiple 'import' slots by a single 'imports' slot (pro issue 1075)

* made code null safe

* made filter for unused import declarations configurable
Axel Terfloth 8 years ago
parent
commit
8038a124cd

+ 50 - 8
plugins/org.yakindu.sct.simulation.core.sexec/src/org/yakindu/sct/simulation/core/sexec/container/DefaultExecutionContextInitializer.xtend

@@ -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
+	}
 }