Browse Source

addInVars and formatter for pretty log output

Cláudio Gomes 3 years ago
parent
commit
ef9a97e9cf

+ 9 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/src/be/uantwerpen/ansymo/semanticadaptation/tests/SemanticAdaptationGeneratorTest.xtend

@@ -18,6 +18,7 @@ import org.eclipse.xtext.xbase.testing.CompilationTestHelper
 import org.eclipse.xtext.xbase.testing.CompilationTestHelper.Result
 import org.junit.Test
 import org.junit.runner.RunWith
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Variable
 
 @RunWith(XtextRunner)
 @InjectWith(SemanticAdaptationInjectorProvider)
@@ -57,6 +58,14 @@ class SemanticAdaptationGeneratorTest extends AbstractSemanticAdaptationTest{
 			}
 		}) }
 	
+	@Test def test_addInVars_sample1() { __generate('input/canonical_generation/sample1.sa', new IAcceptor<CompilationTestHelper.Result>(){
+			override accept(Result t) {
+				var Adaptation sa = t.resourceSet.resources.head.allContents.toIterable.filter(SemanticAdaptation).last.elements.filter(Adaptation).head
+				sa.in.globalInVars.head.declarations.filter[p | p.name=="stored__innerFMU2__input_port2"].head.type == "Bool"
+				sa.in.globalInVars.head.declarations.filter[p | p.name=="stored__innerFMU2__input_port3"].head.expr instanceof Variable
+			}
+		}) }
+	
 	@Test def window_SA_parseNoExceptions() { __generate('input/power_window_case_study/window_sa.BASE.sa', new IAcceptor<CompilationTestHelper.Result>(){
 			override accept(Result t) { }
 		}) }

+ 2 - 1
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/META-INF/MANIFEST.MF

@@ -25,5 +25,6 @@ Export-Package: be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.util,
  be.uantwerpen.ansymo.semanticadaptation.serializer,
  be.uantwerpen.ansymo.semanticadaptation.validation,
  be.uantwerpen.ansymo.semanticadaptation.parser.antlr,
- be.uantwerpen.ansymo.semanticadaptation.generator
+ be.uantwerpen.ansymo.semanticadaptation.generator,
+ be.uantwerpen.ansymo.semanticadaptation.formatting2
 Import-Package: org.apache.log4j

+ 3 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/GenerateSemanticAdaptation.mwe2

@@ -36,6 +36,9 @@ Workflow {
 			serializer = {
 				generateStub = false
 			}
+			formatter={
+				generateStub=true
+			}
 			validator = {
 				// composedCheck = "org.eclipse.xtext.validation.NamesAreUniqueValidator"
 			}

+ 60 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/formatting2/SemanticAdaptationFormatter.xtend

@@ -0,0 +1,60 @@
+/*
+ * generated by Xtext 2.11.0
+ */
+package be.uantwerpen.ansymo.semanticadaptation.formatting2
+
+import be.uantwerpen.ansymo.semanticadaptation.generator.Log
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Adaptation
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SemanticAdaptation
+import org.eclipse.xtext.formatting2.AbstractFormatter2
+import org.eclipse.xtext.formatting2.IFormattableDocument
+import org.eclipse.xtext.util.Strings
+
+class SemanticAdaptationFormatter extends AbstractFormatter2 {
+	
+	//@Inject extension SemanticAdaptationGrammarAccess
+
+	def dispatch void format(SemanticAdaptation semanticAdaptation, extension IFormattableDocument document) {
+		Log.push("Formatting document")
+		
+		val adaptations = semanticAdaptation.elements.filter(Adaptation)
+		if (adaptations.size == 0){
+			Log.println("Warning: document has no adaptation declared. This is not supported yet.")
+			return
+		}
+		
+		val sa = adaptations.head
+		
+		Log.println("Adaptation: " + sa)
+		sa.format
+		
+		Log.pop("Formatting document")	
+	}
+	
+	def dispatch void format(Adaptation sa, extension IFormattableDocument document){
+		Log.push("Formatting adaptation")
+		
+		sa.regionFor.keyword('input').prepend[newLine]
+		sa.regionFor.keyword('output').prepend[newLine]
+		sa.regionFor.keyword('param').prepend[newLine]
+		sa.regionFor.keyword('param').prepend[newLine]
+		
+		if (sa.in !== null){
+			sa.in.allRegionsFor.keyword('in').prepend[newLine]
+		}
+		
+		
+		/*
+		for (inPort : sa.inports){
+			Log.push("Formatting inPort " + inPort.name)
+			
+			inPort.regionFor.feature(SemanticAdaptationPackage.Literals.PORT__TYPE).prepend[newLine]
+			
+			Log.pop("Formatting inPort " + inPort.name)	
+		}
+		 */
+		
+		Log.pop("Formatting adaptation")	
+	}
+	
+}

+ 81 - 6
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/generator/SemanticAdaptationCanonicalGenerator.xtend

@@ -28,12 +28,14 @@ import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Variable
 import java.io.ByteArrayOutputStream
 import java.util.HashMap
 import java.util.LinkedList
+import java.util.Map
 import org.eclipse.emf.ecore.EObject
 import org.eclipse.emf.ecore.resource.Resource
 import org.eclipse.xtext.EcoreUtil2
 import org.eclipse.xtext.generator.AbstractGenerator
 import org.eclipse.xtext.generator.IFileSystemAccess2
 import org.eclipse.xtext.generator.IGeneratorContext
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Declaration
 
 /**
  * Generates code from your model files on save.
@@ -102,8 +104,7 @@ class SemanticAdaptationCanonicalGenerator extends AbstractGenerator {
 		return outputByteArray.toString()
 	}
 	
-	def canonicalize(Adaptation sa){
-		Log.push("Canonicalize")
+	def inferUnits(Adaptation sa){
 		// Unit inference
 		var unitlessElements = genericDeclarationInferenceAlgorithm(sa , 
 			[// getField
@@ -152,7 +153,9 @@ class SemanticAdaptationCanonicalGenerator extends AbstractGenerator {
 		if (unitlessElements > 0){
 			Log.println("Could not infer all element units. There are " + unitlessElements + " unitless elements.")
 		}
-		
+	}
+	
+	def inferTypes(Adaptation sa){
 		// Type inference
 		var untypedElements = genericDeclarationInferenceAlgorithm(sa , 
 			[// getField
@@ -204,16 +207,88 @@ class SemanticAdaptationCanonicalGenerator extends AbstractGenerator {
 			
 			throw new Exception("Could not infer all types. There are " + untypedElements + " untyped elements.")
 		}
+	}
+	
+	def canonicalize(Adaptation sa){
+		Log.push("Canonicalize")
+		
+		inferUnits(sa)
+		
+		inferTypes(sa)
 		
-		// Add input ports
 		addInPorts(sa)
 		
-		// Add in params
-		addInParams(sa)
+		val inputPort2parameterDeclaration = addInParams(sa)
+		
+		val inputPort2InVarDeclaration = addInVars(sa, inputPort2parameterDeclaration)
 		
 		Log.pop("Canonicalize")
 	}
 	
+	def addInVars(Adaptation sa, Map<Port, SingleParamDeclaration> inputPort2parameterDeclaration){
+		Log.push("addInVars")
+		
+		var inputPort2InVarDeclaration = new HashMap<Port, SingleVarDeclaration>()
+		
+		for(inputPort : inputPort2parameterDeclaration.keySet){
+			Log.println("Processing port " + inputPort.name)
+			val paramDecl = inputPort2parameterDeclaration.get(inputPort)
+			
+			val varDeclarationName = getGeneratedInVarDeclarationName(inputPort)			
+			
+			if (!varDeclarationExists(varDeclarationName, sa)){
+				Log.println("Creating new input variable declaration " + varDeclarationName)
+				
+				val varDeclaration = addNewInputVarDeclaration(inputPort, paramDecl, sa)
+				
+				inputPort2InVarDeclaration.put(inputPort, varDeclaration)
+			} else {
+				Log.println("Input variable declaration " + varDeclarationName + " already exists.")
+			}
+		}
+		
+		Log.pop("addInVars")
+		return inputPort2InVarDeclaration
+	}
+	
+	def addNewInputVarDeclaration(Port externalInputPort, SingleParamDeclaration paramDecl, Adaptation sa) {
+		if (sa.in === null){
+			sa.in = SemanticAdaptationFactory.eINSTANCE.createInRulesBlock()
+		}
+		if (sa.in.globalInVars.size == 0){
+			sa.in.globalInVars.add(SemanticAdaptationFactory.eINSTANCE.createDeclaration())
+		}
+		
+		val newSingleVarDecl = SemanticAdaptationFactory.eINSTANCE.createSingleVarDeclaration()
+		newSingleVarDecl.name = getGeneratedInVarDeclarationName(externalInputPort)
+		newSingleVarDecl.type = externalInputPort.type
+		val initValue = SemanticAdaptationFactory.eINSTANCE.createVariable()
+		initValue.ref = paramDecl
+		newSingleVarDecl.expr = initValue
+		
+		sa.in.globalInVars.head.declarations.add(newSingleVarDecl)
+		
+		Log.println("New input variable declaration created: " + newSingleVarDecl.name + " := " + paramDecl.name)
+		return newSingleVarDecl
+	}
+	
+	def varDeclarationExists(String invarName, Adaptation sa) {
+		if (sa.in !== null){
+			for (declarations : sa.in.globalInVars){
+				for (decl : declarations.declarations){
+					if (decl.name == invarName){
+						return true
+					}
+				}
+			}
+		}
+		return false
+	}
+	
+	def getGeneratedInVarDeclarationName(Port externalInputPort) {
+		return "stored__" + externalInputPort.name;
+	}
+	
 	def genericDeclarationInferenceAlgorithm(Adaptation sa, 
 												(EObject)=>Object getField, 
 												(EObject, Object)=>void setField,