diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SClass.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SClass.scala index e600f6055de2e81573424075aa4ae8fa92d9e1ae..c7e850ec628d087ddbad3d32d03e4408fab063b0 100644 --- a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SClass.scala +++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SClass.scala @@ -100,7 +100,18 @@ class SClass(_name: String, } /** Gets the parents of `this` class. */ - def getAllParents(): Seq[STypedElement] = parentInterfaces :+ parentClass + def getAllParents(): Seq[STypedElement] = { + if (parentInterfaces.isEmpty && parentClass == null) { + return Seq.empty + } + if (parentInterfaces.isEmpty) { + return Seq(parentClass) + } + if (parentClass == null) { + return parentInterfaces + } + parentInterfaces :+ parentClass + } /** Makes `this` class a subclass of `parent`. * @@ -183,18 +194,24 @@ class SClass(_name: String, /** Provides all types `this` classes accesses in some way. */ def getUsedTypes: Set[STypedElement] = { - println(this + " Parents: " + getAllParents) - val parentImport: Seq[STypedElement] = getAllParents() //TODO: weiß nicht ob null mit in der liste steht + //println(this + " Parents: " + getAllParents) + val parentImport: Seq[STypedElement] = getAllParents() val parentConstructorParamImports: Seq[STypedElement] = if (isRootClass) List() else getClassParent match { - case parent: SClass => parent.getStructuralFeatures.map(_.sType) + case parent: SClass => + println(parent.getDeepStructuralFeatures) + println(parent.getDeepStructuralFeatures.map(_.sType)) + parent.getDeepStructuralFeatures.map(_.sType) case _ => List() } + //attribute types val attrTypeImports: Seq[STypedElement] = attributes.map(_.sType) + //reference types val refTypeImports: Seq[STypedElement] = references.map(_.sType) + //method types val methodResultImports: Seq[STypedElement] = methods.map(_.result) val methodParamImports: Seq[STypedElement] = methods.flatMap(_.params).map(_.paramType) @@ -219,55 +236,49 @@ class SClass(_name: String, override def getInheritanceHierarchy: Seq[STypedElement] = if (isRootClass) List(this) else this +: getClassParent.getInheritanceHierarchy - override def getNecessaryImports: Set[SImport] = { - val parentImport: List[SImport] = if (isRootClass) List() else includeImportIfNecessary(getClassParent.getPackage, getClassParent.getName) - - val parentConstructorParamImports: List[SImport] = if (isRootClass) List() else getClassParent match { - case parent: SClass => - parent.attributes - .map(attr => includeImportIfNecessary(attr.sType.getPackage, attr.sType.getName)) - .fold(List())((l1, l2) => l1 ++ l2) - case _ => List() + override def getNecessaryImports: Set[SImport] = { + var allImports: List[SImport] = List.empty + //iterate over all parent types + getAllParents().foreach(p => { + allImports = includeImportIfNecessary(p.sPackage, p.name, allImports) + }) + + //iterate over construction features of parent types + if (!isRootClass) { + getClassParent match { + case parent: SClass => + parent.getStructuralFeatures.foreach(p => { + allImports = includeImportIfNecessary(p.sType.getPackage, p.getType, allImports) + }) + case _ => List() + } } - - val attrTypeImports: List[SImport] = - attributes - .map(attr => includeImportIfNecessary(attr.sType.getPackage, attr.getType)) - .fold(List())((l1, l2) => l1 ++ l2) - - val refTypeImports: List[SImport] = - references - .map(attr => includeImportIfNecessary(attr.sType.getPackage, attr.getType)) - .fold(List())((l1, l2) => l1 ++ l2) - - val methodResultImports: List[SImport] = - methods - .map(_.result) - .map(res => includeImportIfNecessary(res.getPackage, res.getName)) - .fold(List())((l1, l2) => l1 ++ l2) - - val methodParamImports: List[SImport] = - methods - .map(_.params) - .fold(List())((l1, l2) => l1 ++ l2) - .map(param => includeImportIfNecessary(param.paramType.getPackage, param.paramType.getName)) - .fold(List())((l1, l2) => l1 ++ l2) - - val methodImplImports: List[SImport] = - methods - .map(_.getUsedTypes.toList) - .fold(List())((l1, l2) => l1 ++ l2) - .map(typ => includeImportIfNecessary(typ.getPackage, typ.getName)) - .fold(List())((l1, l2) => l1 ++ l2) + + //iterate over all attributes + attributes.foreach(a => { + allImports = includeImportIfNecessary(a.sType.getPackage, a.getType, allImports) + }) + + //iterate over all references + references.foreach(r => { + allImports = includeImportIfNecessary(r.sType.getPackage, r.getType, allImports) + }) + + methods.foreach(m => { + //iterate over result types + allImports = includeImportIfNecessary(m.result.getPackage, m.result.getName, allImports) + //iterate over parameter types + m.params.foreach(p => { + allImports = includeImportIfNecessary(p.paramType.getPackage, p.paramType.getName, allImports) + }) + //iterate over used types in the method + m.getUsedTypes.foreach(t => { + allImports = includeImportIfNecessary(t.getPackage, t.getName, allImports) + }) + }) // create a set to eliminate duplicates - (parentImport - ++ parentConstructorParamImports - ++ attrTypeImports - ++ refTypeImports - ++ methodResultImports - ++ methodParamImports - ++ methodImplImports).toSet + (allImports).toSet } override def accept(visitor: SModelVisitor): Unit = { @@ -287,10 +298,10 @@ class SClass(_name: String, * @return an empty list if the class does not need to be imported, or the necessary import * otherwise */ - private def includeImportIfNecessary(sPackage: String, sClass: String): List[SImport] = { - if (sPackage != this.sPackage && sPackage != "") List(SImport(sPackage, sClass)) else List() + private def includeImportIfNecessary(sPackage: String, sClass: String, list: List[SImport]): List[SImport] = { + if (sPackage != this.sPackage && sPackage != "") list :+ SImport(sPackage, sClass) else list } - + override def equals(other: Any): Boolean = other match { case that: SClass => (that canEqual this) && @@ -304,6 +315,6 @@ class SClass(_name: String, state.map(_.hashCode()).foldLeft(0)((a, b) => 31 * a + b) } - override def toString: String = s"$name(${attributes.map(_.name).mkString(", ")}) A: $isAbstract I: $isInterface" + override def toString: String = s"SC: $name(${attributes.map(_.name).mkString(", ")}, $isAbstract, $isInterface)" } diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SType.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SType.scala index 572a7a9eed0824c0cfc28335230c3ead26d7925d..34301c98549cdf3dfd2bb9e504913655a0f49f39 100644 --- a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SType.scala +++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SType.scala @@ -14,6 +14,8 @@ package org.rosi_project.model_sync.generator.acr_model case class SType(_name: String, _sPackage: String = "", _isInterface: Boolean = true) extends STypedElement (_name, _sPackage, _isInterface) { override def accept(visitor: SModelVisitor): Unit = visitor.visit(this) + + override def toString: String = s"ST: $name($sPackage, $isInterface)" } /** The companion defines frequently used types. diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/STypedElement.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/STypedElement.scala index da3dac090ba5b71ece0c6f1dd205db8b8404d39f..34cb48bea85a5d3006c5835644c2aebbb019fac5 100644 --- a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/STypedElement.scala +++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/STypedElement.scala @@ -14,8 +14,7 @@ abstract class STypedElement (_name: String, val sPackage: String, var isInterface: Boolean) extends SNamedModelElement(_name) { - /** Checks, whether `this` is part of the default package - */ + /** Checks, whether `this` is part of the default package */ def isDefaultPackage: Boolean = sPackage == "" /** The package containing `this` type. @@ -24,8 +23,7 @@ abstract class STypedElement (_name: String, */ def getPackage: String = sPackage - /** The parameters necessary to create an instance of `this` type. - */ + /** The parameters necessary to create an instance of `this` type. */ def getConstructorParameters: Seq[SMethodParameter] = Seq.empty /** The inheritance hierarchy provides information about the types `this` extends. It will start @@ -37,5 +35,7 @@ abstract class STypedElement (_name: String, /** Provides all classes that need to be imported for `this` type. */ def getNecessaryImports: Set[SImport] = Set.empty + + override def toString: String = s"STE: $name($sPackage, $isInterface)" } diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/types/SList.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/types/SList.scala index a7d11b35fa3045539727f7d5ddc5df9ea01603f8..3742d2f08c3dfca0bec25e17ed83cc406216bd65 100644 --- a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/types/SList.scala +++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/types/SList.scala @@ -8,6 +8,7 @@ class SList(elemType: STypedElement) extends SSeq(elemType) { override def getConstructorParameters: Seq[SMethodParameter] = Seq(SMethodParameter("elems", elemType)) + override def toString: String = s"List: $elemType" } /** The companion provides `apply` and `unapply` methods. diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/types/SSeq.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/types/SSeq.scala index e6a9f5ded7b0d289ec384126b9a20c07481f26aa..8744d1a516bba5ad41a0ada1c82de417d59917fa 100644 --- a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/types/SSeq.scala +++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/types/SSeq.scala @@ -8,6 +8,7 @@ class SSeq(val elemType: STypedElement) extends GenericSType(name = "Seq", sPack override def getConstructorParameters: Seq[SMethodParameter] = Seq(SMethodParameter("elems", elemType)) + override def toString: String = s"Seq: $elemType" } /** The companion provides `apply` and `unapply` methods. diff --git a/src/main/scala/org/rosi_project/model_sync/generator/io/SClassWriter.scala b/src/main/scala/org/rosi_project/model_sync/generator/io/SClassWriter.scala index 240b5c3221428b917fc58ca8464f0877ecc223ae..230048131aebe2d78ea9dceec2b2544e3086ff8b 100644 --- a/src/main/scala/org/rosi_project/model_sync/generator/io/SClassWriter.scala +++ b/src/main/scala/org/rosi_project/model_sync/generator/io/SClassWriter.scala @@ -99,11 +99,11 @@ class SClassWriter(val modelClass: SClass) { val constructor: String = s"(${params.mkString(", ")})" - println("params: " + params) + /*println("params: " + params) println("parentConstructorParams: " + parentConstructorParams) println("parentConstructor: " + parentConstructor) println("allInterfaces: " + allInterfaces) - println("constructor: " + constructor) + println("constructor: " + constructor)*/ if (modelClass.isInterface) { baseFixture = s"trait ${modelClass.getName}" diff --git a/src/main/scala/org/rosi_project/model_sync/generator/sync/ConstructorTemplate.scala b/src/main/scala/org/rosi_project/model_sync/generator/sync/ConstructorTemplate.scala index 55d0e5ac9cddb8fd574993cad33c6119be5b0fa6..8a47bd261f5c988efded173791c393528c2e90ab 100644 --- a/src/main/scala/org/rosi_project/model_sync/generator/sync/ConstructorTemplate.scala +++ b/src/main/scala/org/rosi_project/model_sync/generator/sync/ConstructorTemplate.scala @@ -40,7 +40,16 @@ class ConstructorTemplate(modelClass: SClass) extends SClass(_name = s"${modelCl ) ) - override def getNecessaryImports: Set[SImport] = modelClass.getUsedTypes.filter(_.getPackage != "").map(elem => SImport(elem.getPackage, elem.getName)) ++ super.getNecessaryImports + SImport(modelClass.getPackage, modelClass.getName) + override def getNecessaryImports: Set[SImport] = { + println("+++++++++++++++++++++++++") + println(modelClass.getUsedTypes.filter(_.getPackage != "").map(elem => SImport(elem.getPackage, elem.getName))) + println(super.getNecessaryImports) + println(SImport(modelClass.getPackage, modelClass.getName)) + println("+++++++++++++++++++++++++") + (modelClass.getUsedTypes.filter(_.getPackage != "").map(elem => SImport(elem.getPackage, elem.getName)) + ++ super.getNecessaryImports + + SImport(modelClass.getPackage, modelClass.getName)) + } private def generateConstructorParams: String = { modelClass.getDeepStructuralFeatures.map(attr => s"classOf[${attr.getType}]").mkString(", ")