import modelicaQVTUtils.ModelicaUtils; import org.omg.eclipse.sysml.UMLUtils; modeltype UML uses 'http://www.eclipse.org/uml2/3.0.0/UML'; modeltype AlgorithmItem uses 'http://www.openmodelica.org/openmodelica.unparsed/AlgorithmItem'; modeltype AlgorithmStatement uses 'http://www.openmodelica.org/openmodelica.abstract.syntax/AlgorithmStatement'; modeltype Annotation uses 'http://www.openmodelica.org/openmodelica.abstract.syntax/Annotation'; modeltype ArrayDim uses 'http://www.openmodelica.org/openmodelica.abstract.syntax/ArrayDim'; modeltype Class uses 'http://www.openmodelica.org/openmodelica.abstract.syntax/Class'; modeltype ClassDef uses 'http://www.openmodelica.org/openmodelica.abstract.syntax/ClassDef'; modeltype ClassPart uses 'http://www.openmodelica.org/openmodelica.abstract.syntax/ClassPart'; modeltype Comment uses 'http://www.openmodelica.org/openmodelica.abstract.syntax/Comment'; modeltype Component uses 'http://www.openmodelica.org/openmodelica.abstract.syntax/Component'; modeltype ComponentCondition uses 'http://www.openmodelica.org/openmodelica.abstract.syntax/ComponentCondition'; modeltype ComponentItem uses 'http://www.openmodelica.org/openmodelica.abstract.syntax/ComponentItem'; modeltype ComponentRef uses 'http://www.openmodelica.org/openmodelica.unparsed/ComponentRef'; modeltype ConstrainClass uses 'http://www.openmodelica.org/openmodelica.abstract.syntax/ConstrainClass'; modeltype Direction uses 'http://www.openmodelica.org/openmodelica.abstract.syntax/Direction'; modeltype Each uses 'http://www.openmodelica.org/openmodelica.abstract.syntax/Each'; modeltype Element uses 'http://www.openmodelica.org/openmodelica.abstract.syntax/Element'; modeltype ElementArg uses 'http://www.openmodelica.org/openmodelica.unparsed/ElementArg'; modeltype ElementAttributes uses 'http://www.openmodelica.org/openmodelica.abstract.syntax/ElementAttributes'; modeltype ElementItem uses 'http://www.openmodelica.org/openmodelica.abstract.syntax/ElementItem'; modeltype ElementSpec uses 'http://www.openmodelica.org/openmodelica.abstract.syntax/ElementSpec'; modeltype EnumDef uses 'http://www.openmodelica.org/openmodelica.abstract.syntax/EnumDef'; modeltype EnumLiteral uses 'http://www.openmodelica.org/openmodelica.abstract.syntax/EnumLiteral'; modeltype Equation uses 'http://www.openmodelica.org/openmodelica.unparsed/Equation'; modeltype EquationItem uses 'http://www.openmodelica.org/openmodelica.abstract.syntax/EquationItem'; modeltype Exp uses 'http://www.openmodelica.org/openmodelica.unparsed/Exp'; modeltype ExternalDecl uses 'http://www.openmodelica.org/openmodelica.abstract.syntax/ExternalDecl'; modeltype FunctionArgs uses 'http://www.openmodelica.org/openmodelica.unparsed/FunctionArgs'; modeltype Import uses 'http://www.openmodelica.org/openmodelica.abstract.syntax/Import'; modeltype InnerOuter uses 'http://www.openmodelica.org/openmodelica.abstract.syntax/InnerOuter'; modeltype Iterators uses 'http://www.openmodelica.org/openmodelica.abstract.syntax/Iterators'; modeltype Modifications uses 'http://www.openmodelica.org/openmodelica.abstract.syntax/Modifications'; modeltype NamedArg uses 'http://www.openmodelica.org/openmodelica.abstract.syntax/NamedArg'; modeltype Operator uses 'http://www.openmodelica.org/openmodelica.abstract.syntax/Operator'; modeltype Path uses 'http://www.openmodelica.org/openmodelica.abstract.syntax/Path'; modeltype Program uses 'http://www.openmodelica.org/openmodelica.abstract.syntax/Program'; modeltype RedeclareKeywords uses 'http://www.openmodelica.org/openmodelica.abstract.syntax/RedeclareKeywords'; modeltype Restriction uses 'http://www.openmodelica.org/openmodelica.abstract.syntax/Restriction'; modeltype Subscript uses 'http://www.openmodelica.org/openmodelica.abstract.syntax/Subscript'; modeltype TypeSpec uses 'http://www.openmodelica.org/openmodelica.abstract.syntax/TypeSpec'; modeltype Variability uses 'http://www.openmodelica.org/openmodelica.abstract.syntax/Variability'; modeltype Within uses 'http://www.openmodelica.org/openmodelica.abstract.syntax/Within'; transformation ModelicaUnparsed2SysML(in modelicaModel:Program, in sysml4ModelicaProfile:UML, out sysmlModel:UML); property sysml4Modelica_profile:UML::Profile = sysml4ModelicaProfile.rootObjects()![UML::Profile]; property ModelicaClassDefinition_stereotype : UML::Stereotype = sysml4Modelica_profile.ownedStereotype![name = "ModelicaClassDefinition"]; property ModelicaClass_stereotype : UML::Stereotype = sysml4Modelica_profile.ownedStereotype![name = "ModelicaClass"]; property ModelicaModel_stereotype : UML::Stereotype = sysml4Modelica_profile.ownedStereotype![name = "ModelicaModel"]; property ModelicaRecord_stereotype : UML::Stereotype = sysml4Modelica_profile.ownedStereotype![name = "ModelicaRecord"]; property ModelicaBlock_stereotype : UML::Stereotype = sysml4Modelica_profile.ownedStereotype![name = "ModelicaBlock"]; property ModelicaConnector_stereotype : UML::Stereotype = sysml4Modelica_profile.ownedStereotype![name = "ModelicaConnector"]; property ModelicaType_stereotype : UML::Stereotype = sysml4Modelica_profile.ownedStereotype![name = "ModelicaType"]; property ModelicaPackage_stereotype : UML::Stereotype = sysml4Modelica_profile.ownedStereotype![name = "ModelicaPackage"]; property ModelicaFunction_stereotype : UML::Stereotype = sysml4Modelica_profile.ownedStereotype![name = "ModelicaFunction"]; property ModelicaExtends_stereotype : UML::Stereotype = sysml4Modelica_profile.ownedStereotype![name = "ModelicaExtends"]; property ModelicaFunctionParameter_stereotype : UML::Stereotype = sysml4Modelica_profile.subobjects()[UML::Stereotype] ->select(name = "ModelicaFunctionParameter")->any(true); property ModelicaPart_stereotype : UML::Stereotype = sysml4Modelica_profile.subobjects()[UML::Stereotype] ->select(name = "ModelicaPart")->any(true); property ModelicaPort_stereotype : UML::Stereotype = sysml4Modelica_profile.subobjects()[UML::Stereotype] ->select(name = "ModelicaPort")->any(true); property ModelicaValueProperty_stereotype : UML::Stereotype = sysml4Modelica_profile.subobjects()[UML::Stereotype] ->select(name = "ModelicaValueProperty")->any(true); property ModelicaAlgorithm_stereotype : UML::Stereotype = sysml4Modelica_profile.subobjects()[UML::Stereotype] ->select(name = "ModelicaAlgorithm")->any(true); property ModelicaConnection_stereotype : UML::Stereotype = sysml4Modelica_profile.subobjects()[UML::Stereotype] ->select(name = "ModelicaConnection")->any(true); property ModelicaEquation_stereotype : UML::Stereotype = sysml4Modelica_profile.subobjects()[UML::Stereotype] ->select(name = "ModelicaEquation")->any(true); property ModelicaAnnotation_stereotype : UML::Stereotype = sysml4Modelica_profile.subobjects()[UML::Stereotype] ->select(name = "ModelicaAnnotation")->any(true); property modelicaTypesClass : UML::Type = sysml4Modelica_profile.nestedPackage![name = "Types"] .ownedType![name = "ModelicaPredefinedTypes"]; property modelicaTypesPackage : UML::Package = sysml4Modelica_profile.nestedPackage![name = "Types"]; property modelicaRealType : UML::Type = modelicaTypesClass.subobjects()[UML::DataType] ->select(name = "ModelicaReal")->any(true); property modelicaIntegerType : UML::Type = modelicaTypesClass.subobjects()[UML::DataType] ->select(name = "ModelicaInteger")->any(true); property modelicaBooleanType : UML::Type = modelicaTypesClass.subobjects()[UML::DataType] ->select(name = "ModelicaBoolean")->any(true); property modelicaStringType : UML::Type = modelicaTypesClass.subobjects()[UML::DataType] ->select(name = "ModelicaString")->any(true); property modelicaStateSelectKind : UML::Enumeration = modelicaTypesClass.subobjects()[UML::Enumeration] ->select(name = "ModelicaStateSelect")->any(true); property modelicaDefaultKind : UML::EnumerationLiteral = modelicaStateSelectKind.subobjects()[UML::EnumerationLiteral] ->select(name = "default")->any(true); property modelicaAlwaysKind : UML::EnumerationLiteral = modelicaStateSelectKind.subobjects()[UML::EnumerationLiteral] ->select(name = "always")->any(true); property modelicaNeverKind : UML::EnumerationLiteral = modelicaStateSelectKind.subobjects()[UML::EnumerationLiteral] ->select(name = "never")->any(true); property modelicaPreferKind : UML::EnumerationLiteral = modelicaStateSelectKind.subobjects()[UML::EnumerationLiteral] ->select(name = "prefer")->any(true); property modelicaAvoidKind : UML::EnumerationLiteral = modelicaStateSelectKind.subobjects()[UML::EnumerationLiteral] ->select(name = "avoid")->any(true); property modelicaScopeKind : UML::Enumeration = sysml4Modelica_profile.nestedPackage![name = "Types"].subobjects()[UML::Enumeration] ->select(name = "ModelicaScopeKind")->any(true); property modelicaInnerKind : UML::EnumerationLiteral = modelicaScopeKind.subobjects()[UML::EnumerationLiteral] ->select(name = "inner")->any(true); property modelicaOuterKind : UML::EnumerationLiteral = modelicaScopeKind.subobjects()[UML::EnumerationLiteral] ->select(name = "outer")->any(true); property modelicaCausalityKind : UML::Enumeration = sysml4Modelica_profile.nestedPackage![name = "Types"].subobjects()[UML::Enumeration] ->select(name = "ModelicaCausalityKind")->any(true); property modelicaInputKind : UML::EnumerationLiteral = modelicaCausalityKind.subobjects()[UML::EnumerationLiteral] ->select(name = "input")->any(true); property modelicaOutputKind : UML::EnumerationLiteral = modelicaCausalityKind.subobjects()[UML::EnumerationLiteral] ->select(name = "output")->any(true); property modelicaVariabilityKind : UML::Enumeration = sysml4Modelica_profile.nestedPackage![name = "Types"].subobjects()[UML::Enumeration] ->select(name = "ModelicaVariabilityKind")->any(true); property modelicaConstantKind : UML::EnumerationLiteral = modelicaVariabilityKind.subobjects()[UML::EnumerationLiteral] ->select(name = "constant")->any(true); property modelicaContinuousKind : UML::EnumerationLiteral = modelicaVariabilityKind.subobjects()[UML::EnumerationLiteral] ->select(name = "continuous")->any(true); property modelicaDiscreteKind : UML::EnumerationLiteral = modelicaVariabilityKind.subobjects()[UML::EnumerationLiteral] ->select(name = "discrete")->any(true); property modelicaParameterKind : UML::EnumerationLiteral = modelicaVariabilityKind.subobjects()[UML::EnumerationLiteral] ->select(name = "parameter")->any(true); property modelicaFlowFlagKind : UML::Enumeration = sysml4Modelica_profile.nestedPackage![name = "Types"].subobjects()[UML::Enumeration] ->select(name = "ModelicaFlowFlagKind")->any(true); property modelicaFlowKind : UML::EnumerationLiteral = modelicaFlowFlagKind.subobjects()[UML::EnumerationLiteral] ->select(name = "flow")->any(true); property modelicaStreamKind : UML::EnumerationLiteral = modelicaFlowFlagKind.subobjects()[UML::EnumerationLiteral] ->select(name = "stream")->any(true); // use Tuple property undefinedGeneralizations : Sequence(UML::Generalization)= Sequence{}; property generalizedClassNames : Sequence(String)= Sequence{}; property unresolvedComponents : OrderedSet(Tuple(source:Element::ELEMENT, target:UML::Classifier)) = OrderedSet{}; property importPackageMappings : OrderedSet(Tuple(source:String, target:String)) = OrderedSet{}; property isLastModelTraversal : Boolean = false; main() { var program : Program::PROGRAM = modelicaModel.rootObjects()![Program::PROGRAM]; program.map toSysML(); setUndefinedGeneralizations(); isLastModelTraversal := true; setUnresolvedComponents(); log("Transformation ModelicaUnparsed2SysML finished"); } mapping Program::PROGRAM::toSysML() : UML::Package { result.applyProfile(sysml4Modelica_profile); result.name := self.classes![Class::CLASS].name; self.classes[Class::CLASS]->map toSysML$ModelicaSpecializedClass(result); } // *********************************** CLASS DEFINITION *********************************** //index : Integer // ****** Mapping Rule 16.1 ****** abstract mapping Class::uClass::toSysML$ModelicaSpecializedClass (inout owningElement : UML::Element) : UML::Classifier disjuncts Class::CLASS::toSysML$ModelicaClass, // Mapping Rule 16.1.2 Class::CLASS::toSysML$ModelicaModel, // Mapping Rule 16.1.3 Class::CLASS::toSysML$ModelicaRecord, // Mapping Rule 16.1.4 Class::CLASS::toSysML$ModelicaBlock, // Mapping Rule 16.1.5 Class::CLASS::toSysML$ModelicaConnector, // Mapping Rule 16.1.6 Class::CLASS::toSysML$ModelicaType, // Mapping Rule 16.1.7 Class::CLASS::toSysML$ModelicaTypeEnum, // Mapping Rule 16.1.7 Class::CLASS::toSysML$ModelicaPackage, // Mapping Rule 16.1.8 Class::CLASS::toSysML$ModelicaFunction{} // Mapping Rule 16.1.9 // ****** Mapping Rule 16.1.10 ****** abstract mapping Class::CLASS::toSysML$ModelicaClassDefinition (inout owningElement : UML::Element) : UML::Classifier { init{ if(not result.getStereotypeApplications()->isEmpty())then{ safeStereotypeSetValue(result, // Mapping Rule 16.1.11 ModelicaClassDefinition_stereotype, "isFinal", self.finalPrefix); safeStereotypeSetValue(result, // Mapping Rule 16.1.12 ModelicaClassDefinition_stereotype,"isModelicaEncapsulated", self.encapsulatedPrefix); safeStereotypeSetValue(result, // Mapping Rule 16.1.13 ModelicaClassDefinition_stereotype, "isPartial", self.partialPrefix); }endif; // mapping to properties and generalizations self.body[ClassDef::PARTS] -> forEach (body){ var classParts : OrderedSet(ClassPart::PUBLIC) := body.classParts[ClassPart::PUBLIC]; var elementItems : Sequence(ElementItem::ELEMENTITEM) := classParts.contents[ElementItem::ELEMENTITEM]; elementItems-> forEach (elementItem){ elementItem.element[Element::ELEMENT].map toSysML$ModelicaComponent(result); elementItem.element[Element::ELEMENT].specification[ElementSpec::EXTENDS]->map toGeneralization(result); elementItem.element[Element::ELEMENT].specification[ElementSpec::IMPORT]->map toPackageImport(result); } ; // support also for protected components var classPartsProtected : OrderedSet(ClassPart::PROTECTED) := body.classParts[ClassPart::PROTECTED]; var elementItemsProtected : Sequence(ElementItem::ELEMENTITEM) := classPartsProtected.contents[ElementItem::ELEMENTITEM]; elementItemsProtected-> forEach (elementItem){ elementItemsProtected.element[Element::ELEMENT].map toSysML$ModelicaComponent(result); elementItemsProtected.element[Element::ELEMENT].specification[ElementSpec::EXTENDS]->map toGeneralization(result); elementItemsProtected.element[Element::ELEMENT].specification[ElementSpec::IMPORT]->map toPackageImport(result); } ; var annotations : Sequence(ElementItem::ANNOTATIONITEM) := classParts.contents[ElementItem::ANNOTATIONITEM]; annotations-> forEach (annotation){ annotation.annotation_[Annotation::ANNOTATION].elementArgs[ElementArg::MODIFICATION]->forEach(modification){ var umlComment : UML::Comment := object UML::Comment{}; umlComment.body := modification.unparsedElementArg->any(true); result.ownedComment += umlComment; safeApplyStereotype(umlComment, ModelicaAnnotation_stereotype); }; } ; } ; self.body[ClassDef::DERIVED] -> forEach (derived_){ derived_->map toGeneralization(result); }; } } abstract mapping Class::CLASS::toSysML$ModelicaEnumDefinition (inout owningElement : UML::Element) : UML::Enumeration { init{ if(not result.getStereotypeApplications()->isEmpty())then{ safeStereotypeSetValue(result, // Mapping Rule 16.1.11 ModelicaClassDefinition_stereotype, "isFinal", self.finalPrefix); safeStereotypeSetValue(result, // Mapping Rule 16.1.12 ModelicaClassDefinition_stereotype,"isModelicaEncapsulated", self.encapsulatedPrefix); safeStereotypeSetValue(result, // Mapping Rule 16.1.13 ModelicaClassDefinition_stereotype, "isPartial", self.partialPrefix); }endif; self.body[ClassDef::ENUMERATION] -> forEach (enumBody){ var enumLiterals : EnumDef::ENUMLITERALS := enumBody.enumLiterals![EnumDef::ENUMLITERALS]; enumLiterals.enumLiterals[EnumLiteral::ENUMLITERAL]-> forEach (enumLiteral){ var StringLiteral : String := enumLiteral._literal; var umlEnumLiteral :UML::EnumerationLiteral := object UML::EnumerationLiteral{}; umlEnumLiteral.name := StringLiteral; result.ownedLiteral += umlEnumLiteral; } ; } } } // ****** Mapping Rule 16.2 ****** mapping Class::CLASS::toSysML$ModelicaClass (inout owningElement : UML::Element) : UML::Class // Mapping Rule 16.2.1 inherits Class::CLASS::setSysML$ClassifierOwner merges Class::CLASS::toSysML$ModelicaClassDefinition, // Mapping Rule 16.2.3 Class::CLASS::setSysML$ModelicaEquations, Class::CLASS::setSysML$ModelicaAlgorithms, Class::CLASS::setSysML$ModelicaConnections when{self.restriction.oclIsKindOf(Restriction::R_CLASS);} { safeApplyStereotype(result, ModelicaClass_stereotype); // Mapping Rule 16.2.2 } // ****** Mapping Rule 16.3 ****** mapping Class::CLASS::toSysML$ModelicaModel (inout owningElement : UML::Element) : UML::Class // Mapping Rule 16.3.1 inherits Class::CLASS::setSysML$ClassifierOwner merges Class::CLASS::toSysML$ModelicaClassDefinition, // Mapping Rule 16.3.3 Class::CLASS::setSysML$ModelicaEquations, Class::CLASS::setSysML$ModelicaAlgorithms, Class::CLASS::setSysML$ModelicaConnections when{self.restriction.oclIsKindOf(Restriction::R_MODEL);} { safeApplyStereotype(result, ModelicaModel_stereotype); // Mapping rule 16.3.2 } // ****** Mapping Rule 16.4 ****** mapping Class::CLASS::toSysML$ModelicaRecord (inout owningElement : UML::Element) : UML::Class // Mapping Rule 16.4.1 inherits Class::CLASS::setSysML$ClassifierOwner merges Class::CLASS::toSysML$ModelicaClassDefinition // Mapping Rule 16.4.3 when{self.restriction.oclIsKindOf(Restriction::R_RECORD);} { safeApplyStereotype(result, ModelicaRecord_stereotype); // Mapping Rule 16.4.2 } // ****** Mapping Rule 16.5 ****** mapping Class::CLASS::toSysML$ModelicaBlock (inout owningElement : UML::Element) : UML::Class // Mapping Rule 16.5.1 inherits Class::CLASS::setSysML$ClassifierOwner merges Class::CLASS::toSysML$ModelicaClassDefinition, // Mapping Rule 16.5.3 Class::CLASS::setSysML$ModelicaEquations, Class::CLASS::setSysML$ModelicaAlgorithms, Class::CLASS::setSysML$ModelicaConnections when{self.restriction.oclIsKindOf(Restriction::R_BLOCK);} { safeApplyStereotype(result, ModelicaBlock_stereotype); // Mapping Rule 16.5.2 } // ****** Mapping Rule 16.6 ****** mapping Class::CLASS::toSysML$ModelicaConnector (inout owningElement : UML::Element) : UML::Class // Mapping Rule 16.6.1 inherits Class::CLASS::setSysML$ClassifierOwner merges Class::CLASS::toSysML$ModelicaClassDefinition // Mapping Rule 16.6.4 when{self.restriction.oclIsKindOf(Restriction::R_CONNECTOR) or self.restriction.oclIsKindOf(Restriction::R_EXP_CONNECTOR);} { safeApplyStereotype(result, ModelicaConnector_stereotype); if(self.restriction.oclIsKindOf(Restriction::R_CONNECTOR)) then{ safeStereotypeSetValue(result, ModelicaConnector_stereotype, "isExpandable", false); // Mapping Rule 16.6.2 } endif; if(self.restriction.oclIsKindOf(Restriction::R_EXP_CONNECTOR)) then{ safeStereotypeSetValue(result, ModelicaConnector_stereotype, "isExpandable", true); // Mapping Rule 16.6.3 } endif; } // ****** Mapping Rule 16.7 ****** mapping Class::CLASS::toSysML$ModelicaType (inout owningElement : UML::Element) : UML::DataType // Mapping Rule 16.7.1 inherits Class::CLASS::setSysML$ClassifierOwner merges Class::CLASS::toSysML$ModelicaClassDefinition // Mapping Rule 16.7.3 when{self.restriction.oclIsKindOf(Restriction::R_TYPE)and(not self.body.oclIsKindOf(ClassDef::ENUMERATION))} { safeApplyStereotype(result, ModelicaType_stereotype); // Mapping Rule 16.7.2 //The Modelica specialized class type is restricted to predefined types, enumerations, arrays of type or classes extending // from type. It is enhanced to allow extension of predefined types. //A «modelicaType» can only specialize other classifiers derived from «modelicaType». The stereotype «modelicaExtends //» must be applied to the generalization relationship. // add extends relationship } mapping Class::CLASS::toSysML$ModelicaTypeEnum (inout owningElement : UML::Element) : UML::Enumeration // Mapping Rule 16.7.1 inherits Class::CLASS::setSysML$ClassifierOwner merges Class::CLASS::toSysML$ModelicaEnumDefinition // Mapping Rule 16.7.3 when{self.restriction.oclIsKindOf(Restriction::R_TYPE)and(self.body.oclIsKindOf(ClassDef::ENUMERATION))} { safeApplyStereotype(result, ModelicaType_stereotype); // Mapping Rule 16.7.2 } // ****** Mapping Rule 16.8 ****** mapping Class::CLASS::toSysML$ModelicaPackage (inout owningElement : UML::Element) : UML::Class // Mapping Rule 16.8.1 inherits Class::CLASS::setSysML$ClassifierOwner merges Class::CLASS::toSysML$ModelicaClassDefinition // Mapping Rule 16.8.3 when{self.restriction.oclIsKindOf(Restriction::R_PACKAGE);} { safeApplyStereotype(result, ModelicaPackage_stereotype); // Mapping Rule 16.8.2 } // ****** Mapping Rule 16.9 ****** mapping Class::CLASS::toSysML$ModelicaFunction (inout owningElement : UML::Element) : UML::FunctionBehavior // Mapping Rule 16.9.1 inherits Class::CLASS::setSysML$ClassifierOwner // Mapping Rule 16.9.5 merges Class::CLASS::toSysML$ModelicaClassDefinition, // Mapping Rule 16.9.9 Class::CLASS::setSysML$ModelicaAlgorithms when{self.restriction.oclIsKindOf(Restriction::R_FUNCTION);} { safeApplyStereotype(result, ModelicaFunction_stereotype); // Mapping Rule 16.9.2 // language var language : String = self.body![ClassDef::PARTS] // Mapping Rule 16.9.4 .classParts![ClassPart::EXTERNAL] .externalDecl![ExternalDecl::EXTERNALDECL].lang; // scope var innerOuter : InnerOuter::INNEROUTER = self.body![ClassDef::PARTS] .classParts![ClassPart::PUBLIC].contents![ElementItem::ELEMENTITEM] .element![Element::ELEMENT].innerOuter![InnerOuter::INNEROUTER]; if(innerOuter.oclIsInvalid()) // Mapping Rule 16.9.6 then{ innerOuter := self.body![ClassDef::PARTS] .classParts![ClassPart::PROTECTED].contents![ElementItem::ELEMENTITEM] .element![Element::ELEMENT].innerOuter![InnerOuter::INNEROUTER]; } endif; if(innerOuter.oclIsKindOf(InnerOuter::INNER)) // Mapping Rule 16.9.6 then{ safeStereotypeSetValue(result, ModelicaFunction_stereotype, "scope", modelicaInnerKind); } endif; if(innerOuter.oclIsKindOf(InnerOuter::OUTER)) then{ safeStereotypeSetValue(result, ModelicaFunction_stereotype, "scope", modelicaOuterKind); } endif; if((language = "C") or (language = "FORTRAN")) // Mapping Rule 16.9.3 then{ // externalLibrary // Mapping Rule 16.9.7 var annotationsStr : OrderedSet(String) = null; self.body![ClassDef::PARTS].classParts![ClassPart::EXTERNAL] .externalDecl![ExternalDecl::EXTERNALDECL].annotation_[Annotation::ANNOTATION] .elementArgs-> forEach ( elementArg | uElementArg){ if(elementArg.unparsedElementArg.match("Library")) then{ annotationsStr += elementArg.unparsedElementArg; } endif; } ; safeStereotypeSetListValue (result, ModelicaFunction_stereotype, "externalLibrary", annotationsStr); // externalInclude // Mapping Rule 16.9.8 self.body![ClassDef::PARTS].classParts![ClassPart::EXTERNAL] .externalDecl![ExternalDecl::EXTERNALDECL] .annotation_[Annotation::ANNOTATION] .elementArgs->forEach ( elementArg | uElementArg) { if(elementArg.unparsedElementArg.match("Include")) then{ safeStereotypeSetValue(result, ModelicaFunction_stereotype, "externalInclude", elementArg.unparsedElementArg); } endif; } } endif; } mapping ElementSpec::IMPORT::toPackageImport (inout class_ : UML::Classifier) : UML::Comment { var importObject : Import::uImport := self.import_; var importStatement : String; var importStatementX : String; if(importObject.oclIsTypeOf(Import::NAMED_IMPORT))then{ var importNAMED_IMPORT : Import::NAMED_IMPORT := importObject.oclAsType(Import::NAMED_IMPORT); importStatementX := "import " + importNAMED_IMPORT.name + " = " + getPath(importNAMED_IMPORT.path, null); importStatement := importStatementX.replace("::", "."); importPackageMappings += Tuple{source=importNAMED_IMPORT.name, target=getPath(importNAMED_IMPORT.path, null)}; }endif; if(importObject.oclIsTypeOf(Import::QUAL_IMPORT))then{ var importQUAL_IMPORT : Import::QUAL_IMPORT := importObject.oclAsType(Import::QUAL_IMPORT); importStatementX := "import " + getPath(importQUAL_IMPORT.path, null); importStatement := importStatementX.replace("::", "."); }endif; if(importObject.oclIsTypeOf(Import::UNQUAL_IMPORT))then{ var importUNQUAL_IMPORT : Import::UNQUAL_IMPORT := importObject.oclAsType(Import::UNQUAL_IMPORT); importStatementX := "import " + getPath(importUNQUAL_IMPORT.path, null); importStatement := importStatementX.replace("::", ".") + ".*"; }endif; result.body := importStatement; class_.ownedComment += result; } // ****** Mapping Rule 16.10 ****** mapping ElementSpec::EXTENDS::toGeneralization (inout class_ : UML::Classifier) : UML::Generalization // Mapping Rule 16.10.1 { //ElementSpec::EXTENDS is used in the TwoTankExample and RobotExample and not ClassDef::CLASS_EXTENDS class_.generalization += result; var upperClassName : String = getPathLastName(self.path); var upperClassQualifiedName : String = getPath(self.path, null); var upperClass : UML::Classifier = sysmlModel.objectsOfType(UML::Classifier)![matchRegex(qualifiedName, "(?<=\\W)" + upperClassQualifiedName +"(?=$)")]; if(upperClassName = "Real") then { upperClass := modelicaRealType.oclAsType(UML::Classifier); } endif; if(upperClassName = "Integer") then { upperClass := modelicaIntegerType.oclAsType(UML::Classifier); } endif; if(upperClassName = "Boolean") then { upperClass := modelicaBooleanType.oclAsType(UML::Classifier); } endif; if(upperClassName = "String") then { upperClass := modelicaStringType.oclAsType(UML::Classifier); } endif; if(upperClass = null)then{ undefinedGeneralizations += result; generalizedClassNames += upperClassName; }else{ result.specific := class_; // Mapping Rule 16.10.2 result.general := upperClass; // Mapping Rule 16.10.3 }endif; // application of stereotype is missing safeApplyStereotype(result, ModelicaExtends_stereotype); // modification var modificationsStr : Set(String); modificationsStr := getModificationStringSet(self); if(modificationsStr != null)then{ if(modificationsStr->size() > 0)then{ var areModValuesOK : Boolean := true; modificationsStr->forEach(mod){ if(mod.oclIsInvalid())then{ areModValuesOK := false; }endif; }; if(areModValuesOK)then{ safeStereotypeSetListValue(result, result.getAppliedStereotypes()[name = "ModelicaExtends"] // Mapping Rule 16.10.4 ->any(true), "modification", modificationsStr); }endif; }endif; }endif; // Mapping Rule 16.10.5: visibility attribute - to be implemented // Mapping Rule 16.10.6: arraysize attribute - to be implemented } mapping ClassDef::DERIVED::toGeneralization (inout class_ : UML::Classifier) : UML::Generalization // Mapping Rule 16.10.1 { class_.generalization += result; result.ownedComment += object UML::Comment{body:= "="}; var upperClassName : String = getPathLastName(self.typeSpec![TypeSpec::TPATH].path); var upperClassQualifiedName : String = getPath(self.typeSpec![TypeSpec::TPATH].path, null); var upperClass : UML::Classifier = sysmlModel.objectsOfType(UML::Classifier)![matchRegex(qualifiedName, "(?<=\\W)" + upperClassQualifiedName +"(?=$)")]; if(upperClassName = "Real") then { upperClass := modelicaRealType.oclAsType(UML::Classifier); } endif; if(upperClassName = "Integer") then { upperClass := modelicaIntegerType.oclAsType(UML::Classifier); } endif; if(upperClassName = "Boolean") then { upperClass := modelicaBooleanType.oclAsType(UML::Classifier); } endif; if(upperClassName = "String") then { upperClass := modelicaStringType.oclAsType(UML::Classifier); } endif; if(upperClass = null)then{ undefinedGeneralizations += result; generalizedClassNames += upperClassName; }else{ result.specific := class_; // Mapping Rule 16.10.2 result.general := upperClass; // Mapping Rule 16.10.3 }endif; // application of stereotype is missing safeApplyStereotype(result, ModelicaExtends_stereotype); // modification var modificationsStr : Set(String); modificationsStr := getModificationStringSet(self); if(modificationsStr != null)then{ if(modificationsStr->size() > 0)then{ var areModValuesOK : Boolean := true; modificationsStr->forEach(mod){ if(mod.oclIsInvalid())then{ areModValuesOK := false; }endif; }; if(areModValuesOK)then{ safeStereotypeSetListValue(result, result.getAppliedStereotypes()[name = "ModelicaExtends"] // Mapping Rule 16.10.4 ->any(true), "modification", modificationsStr); }endif; }endif; }endif; // arrayDim //property of TPATH var arraySize : Set(String); var arrayDim : ArrayDim::ArrayDim := self.typeSpec![TypeSpec::TPATH].arrayDim; var subscriptObject : Subscript::SUBSCRIPT := arrayDim.subscripts![Subscript::SUBSCRIPT]; var expression : String := subscriptObject.subScript.unparsedExp; if(not expression.oclIsInvalid())then{ //log("expression: " + expression); }endif; if((expression != null) and (not expression.oclIsInvalid()))then{ arraySize += expression; safeStereotypeSetListValue(result, result.getAppliedStereotypes()[name = "ModelicaExtends"]->any(true), "arraySize", arraySize); }endif; } // ****** Mapping Rule 16.11 ****** : ModelicaDer - to be implemented // ****** Mapping Rule 16.12 ****** : ConstrainedBy - to be implemented mapping Class::CLASS::toDependency(inout owningElement : UML::Element) : UML::Dependency{} // Mapping rule 16.11 // not implemented // der example exists in TwoTankExample: der(h). However, no ClassDef.PDER element is used. Also not in the RobotExample mapping ConstrainClass::CONSTRAINCLASS::toDependency(inout owningElement : UML::Element) : UML::Dependency{} // Mapping rule 16.12 // not implemented // CONSTRAINCLASS not present in TwoTankExample and RobotExample abstract mapping Class::CLASS::setSysML$ClassifierOwner(inout owningElement : UML::Element) : UML::Classifier { init{ //helper method overloading if(owningElement.oclIsKindOf(UML::Package)) then{ owningElement.oclAsType(UML::Package).packagedElement += result; } endif; if(owningElement.oclIsKindOf(UML::Class)) then{ owningElement.oclAsType(UML::Class).nestedClassifier += result; } endif; if(owningElement.oclIsKindOf(UML::FunctionBehavior)) then{ owningElement.oclAsType(UML::FunctionBehavior).nestedClassifier += result; } endif; if(owningElement.oclIsKindOf(UML::DataType)) then{ // no sub elements are possible (e.g. FunctionBehavior) //owningElement.oclAsType(UML::DataType).ownedElement += result; } endif; result.name := self.name; self.body![ClassDef::PARTS].classParts[ClassPart::PUBLIC] .contents[ElementItem::ELEMENTITEM] .element[Element::ELEMENT]->forEach ( elem ){ elem.specification[ElementSpec::CLASSDEF] .class_[Class::CLASS]->map toSysML$ModelicaSpecializedClass(result); }; self.body![ClassDef::PARTS].classParts[ClassPart::PROTECTED] .contents[ElementItem::ELEMENTITEM] .element[Element::ELEMENT]->forEach ( elem2 ){ elem2.specification[ElementSpec::CLASSDEF] .class_[Class::CLASS]->map toSysML$ModelicaSpecializedClass(result); }; } } // ******************************** COMPONENT DECLARATIONS ******************************** // ****** Mapping Rule 18.1 ****** abstract mapping Element::ELEMENT::toSysML$ModelicaComponent (inout class_ : UML::Classifier) : UML::TypedElement disjuncts Element::ELEMENT::toSysML$ModelicaPart, // Mapping Rule 18.1.1 Element::ELEMENT::toSysML$ModelicaPort, // Mapping Rule 18.1.2 Element::ELEMENT::toSysML$ModelicaValueProperty, // Mapping Rule 18.1.3 Element::ELEMENT::toSysML$ModelicaFunctionParameter{} // Mapping Rule 18.1.4 // ****** Mapping Rule 18.2 ****** mapping Element::ELEMENT::toSysML$ModelicaPart // Mapping Rule 18.2.1 (inout class_ : UML::Class) : UML::Property inherits Element::ELEMENT::setSysML$TypedElementTypeAndName // Mapping Rule 18.2.6 merges Element::ELEMENT::setSysML$ModelicaComponentCommonValues, // Mapping Rule 18.2.9 // Mapping Rule 18.2.10 // Mapping Rule 18.2.11 // Mapping Rule 18.2.12 Element::ELEMENT ::setSysML$ModelicaComponentScopeValue, // Mapping Rule 18.2.7 Element::ELEMENT :: setSysML$ModelicaComponentConditionalExpressionValue // Mapping Rule 18.2.8 when{(isComponentTypeResolved(self, class_) or isLastModelTraversal) and (isStereotypeOnPropertyType(self, ModelicaClass_stereotype) // Mapping Rule 18.2.3 or isStereotypeOnPropertyType(self, ModelicaModel_stereotype) or isStereotypeOnPropertyType(self, ModelicaBlock_stereotype)) and (class_.isStereotypeApplied(ModelicaFunction_stereotype) = false) and (self.specification.oclIsKindOf(ElementSpec::COMPONENTS)) // Mapping Rule 18.2.2 and (self.specification[ElementSpec::COMPONENTS] // Mapping Rule 18.2.4 .components->forAll(e : ComponentItem::uComponentItem | e.oclIsKindOf(ComponentItem::COMPONENTITEM))) and (self.specification[ElementSpec::COMPONENTS] // Mapping Rule 18.2.5 .components[ComponentItem::COMPONENTITEM].component ->forAll(e : Component::uComponent | e.oclIsKindOf(Component::COMPONENT)))} { class_.ownedAttribute += result; safeApplyStereotype(result, ModelicaPart_stereotype); //self.specification[ElementSpec::COMPONENTS].components } // ****** Mapping Rule 18.3 ****** mapping Element::ELEMENT ::toSysML$ModelicaPort // Mapping Rule 18.3.1 (inout class_ : UML::Class) : UML::Port inherits Element::ELEMENT::setSysML$TypedElementTypeAndName // Mapping Rule 18.3.6 merges Element::ELEMENT ::setSysML$ModelicaComponentCommonValues, // Mapping Rule 18.3.9 // Mapping Rule 18.3.10 // Mapping Rule 18.3.11 // Mapping Rule 18.3.12 Element::ELEMENT ::setSysML$ModelicaComponentConditionalExpressionValue, // Mapping Rule 18.3.8 Element::ELEMENT ::setSysML$ModelicaComponentCausalityValue // Mapping Rule 18.3.7 when{(isComponentTypeResolved(self, class_) or isLastModelTraversal) and isStereotypeOnPropertyType(self, ModelicaConnector_stereotype) // Mapping Rule 18.3.3 // java.lang.NullPointerException and (class_.isStereotypeApplied(ModelicaFunction_stereotype) = false) and (self.specification.oclIsKindOf(ElementSpec::COMPONENTS)) // Mapping Rule 18.3.2 and (self.specification[ElementSpec::COMPONENTS] // Mapping Rule 18.3.4 .components->forAll(e : ComponentItem::uComponentItem | e.oclIsKindOf(ComponentItem::COMPONENTITEM))) and (self.specification[ElementSpec::COMPONENTS] // Mapping Rule 18.3.5 .components[ComponentItem::COMPONENTITEM].component ->forAll(e : Component::uComponent | e.oclIsKindOf(Component::COMPONENT)))} { class_.ownedPort += result; safeApplyStereotype(result, ModelicaPort_stereotype); } // ****** Mapping Rule 18.4 ****** mapping Element::ELEMENT::toSysML$ModelicaValueProperty // Mapping Rule 18.4.1 (inout class_ : UML::Class) : UML::Property inherits Element::ELEMENT::setSysML$TypedElementTypeAndName // Mapping Rule 18.4.7 merges Element::ELEMENT ::setSysML$ModelicaComponentCommonValues, // Mapping Rule 18.4.14 // Mapping Rule 18.4.15 // Mapping Rule 18.4.17 // Mapping Rule 18.4.18 Element::ELEMENT:: setSysML$ModelicaComponentDeclarationEquationValue, // Mapping Rule 18.4.16 Element::ELEMENT ::setSysML$ModelicaComponentCausalityValue, // Mapping Rule 18.4.9 Element::ELEMENT ::setSysML$ModelicaComponentVariabilityValue, // Mapping Rule 18.4.10 Element::ELEMENT // Mapping Rule 18.4.13 ::setSysML$ModelicaComponentConditionalExpressionValue, Element::ELEMENT ::setSysML$ModelicaComponentScopeValue, // Mapping Rule 18.4.12 Element::ELEMENT ::setSysML$ModelicaComponentFlowFlagValue // Mapping Rule 18.4.11 when{(isComponentTypeResolved(self, class_) or isLastModelTraversal) and (isStereotypeOnPropertyType(self, ModelicaRecord_stereotype) // Mapping Rule 18.4.3 // java.lang.NullPointerException or isStereotypeOnPropertyType(self, ModelicaType_stereotype) or getSysML$PropertyType(getModelicaComponentTypeName(self)) = modelicaRealType or getSysML$PropertyType(getModelicaComponentTypeName(self)) = modelicaIntegerType or getSysML$PropertyType(getModelicaComponentTypeName(self)) = modelicaBooleanType or getSysML$PropertyType(getModelicaComponentTypeName(self)) = modelicaStringType or getSysML$PropertyType(getModelicaComponentTypeName(self)) = modelicaStateSelectKind) and (class_.isStereotypeApplied(ModelicaFunction_stereotype) = false) and (self.specification.oclIsKindOf(ElementSpec::COMPONENTS)) // Mapping Rule 18.4.2 and (self.specification[ElementSpec::COMPONENTS] // Mapping Rule 18.4.4 .components->forAll(e : ComponentItem::uComponentItem | e.oclIsKindOf(ComponentItem::COMPONENTITEM))) and (self.specification[ElementSpec::COMPONENTS] // Mapping Rule 18.4.5 .components[ComponentItem::COMPONENTITEM].component ->forAll(e : Component::uComponent | e.oclIsKindOf(Component::COMPONENT))) and (self.specification[ElementSpec::COMPONENTS] // Mapping Rule 18.4.6 .attributes ->forAll(e : ElementAttributes::uElementAttributes | e.oclIsKindOf(ElementAttributes::ATTR)))} { class_.ownedAttribute += result; safeApplyStereotype(result, ModelicaValueProperty_stereotype); //visibility // Mapping Rule 18.4.8 // not yet implemented //result.visibility := Type of ClassPart of owning Absyn.Class.Class, depends if component is in the public or protected declaration sections } // ****** Mapping Rule 18.5 ****** mapping Element::ELEMENT::toSysML$ModelicaFunctionParameter // Mapping Rule 18.5.1 (inout class_ : UML::FunctionBehavior) : UML::Parameter inherits Element::ELEMENT::setSysML$TypedElementTypeAndName // Mapping Rule 18.5.8 merges Element::ELEMENT ::setSysML$ModelicaComponentCommonValues, // Mapping Rule 18.4.11 // Mapping Rule 18.5.12 // Mapping Rule 18.5.13 // Mapping Rule 18.4.15 Element::ELEMENT:: setSysML$ModelicaComponentDeclarationEquationValue, // Mapping Rule 18.5.14 Element::ELEMENT ::setSysML$ModelicaComponentCausalityValue, // Mapping Rule 18.5.9 Element::ELEMENT ::setSysML$ModelicaComponentVariabilityValue // Mapping Rule 18.5.10 when{(isComponentTypeResolved(self, class_) or isLastModelTraversal) and (isStereotypeOnPropertyType(self, ModelicaRecord_stereotype) // Mapping Rule 18.5.3 // java.lang.NullPointerException or isStereotypeOnPropertyType(self, ModelicaType_stereotype) or getSysML$PropertyType(getModelicaComponentTypeName(self)) = modelicaRealType or getSysML$PropertyType(getModelicaComponentTypeName(self)) = modelicaIntegerType or getSysML$PropertyType(getModelicaComponentTypeName(self)) = modelicaBooleanType or getSysML$PropertyType(getModelicaComponentTypeName(self)) = modelicaStringType) and class_.isStereotypeApplied(ModelicaFunction_stereotype) // Mapping Rule 18.5.4 and (self.specification.oclIsKindOf(ElementSpec::COMPONENTS)) // Mapping Rule 18.5.2 and (self.specification[ElementSpec::COMPONENTS] // Mapping Rule 18.5.5 .components->forAll(e : ComponentItem::uComponentItem | e.oclIsKindOf(ComponentItem::COMPONENTITEM))) and (self.specification[ElementSpec::COMPONENTS] // Mapping Rule 18.5.6 .components[ComponentItem::COMPONENTITEM].component ->forAll(e : Component::uComponent | e.oclIsKindOf(Component::COMPONENT))) and (self.specification[ElementSpec::COMPONENTS] // Mapping Rule 18.5.7 .attributes ->forAll(e : ElementAttributes::uElementAttributes | e.oclIsKindOf(ElementAttributes::ATTR)))} { class_.ownedParameter += result; safeApplyStereotype(result, ModelicaFunctionParameter_stereotype); } abstract mapping Element::ELEMENT ::setSysML$ModelicaComponentCommonValues (inout class_ : UML::Class) : UML::TypedElement { init{ // common values = modification + idFinal + isReplaceable + arraySize // modification var modificationsStr : Set(String); modificationsStr := getModificationStringSet(self.specification![ElementSpec::COMPONENTS] .components![ComponentItem::COMPONENTITEM] .component![Component::COMPONENT] .modification![Modifications::CLASSMOD]); if(modificationsStr != null)then{ if(modificationsStr->size() > 0)then{ var areModValuesOK : Boolean := true; modificationsStr->forEach(mod){ if(mod.oclIsInvalid())then{ areModValuesOK := false; }endif; }; if(areModValuesOK)then{ safeStereotypeSetListValue(result, result.getAppliedStereotypes() ->any(true), "modification", modificationsStr); }endif; }endif; }endif; // isFinal if(self.finalPrefix) then{ safeStereotypeSetValue(result, result.getAppliedStereotypes() ->any(true), "isFinal", true); } else{ safeStereotypeSetValue(result, result.getAppliedStereotypes() ->any(true), "isFinal", false); }endif; // isReplaceable var replaceable : RedeclareKeywords::REPLACEABLE = self.redeclareKeywords![RedeclareKeywords::REPLACEABLE]; if(replaceable.oclIsInvalid()) then{ safeStereotypeSetValue(result, result.getAppliedStereotypes() ->any(true), "isReplaceable", false); } else{ safeStereotypeSetValue(result, result.getAppliedStereotypes() ->any(true), "isReplaceable", true); }endif; // arraySize var arraySizeStr : Set(String) = null; self.specification![ElementSpec::COMPONENTS] .components![ComponentItem::COMPONENTITEM] .component![Component::COMPONENT].arrayDim.subscripts[Subscript::SUBSCRIPT] .subScript-> forEach ( expression | uExp){ //arraySizeStr += loadExpression(expression); arraySizeStr += expression.unparsedExp; }; safeStereotypeSetListValue (result, result.getAppliedStereotypes() ->any(true), "arraySize", arraySizeStr); // annotation self.specification![ElementSpec::COMPONENTS] .components![ComponentItem::COMPONENTITEM].comment[Comment::COMMENT]-> forEach (comment){ var annotationString : String := comment.annotation_[Annotation::ANNOTATION].elementArgs[ElementArg::MODIFICATION].unparsedElementArg->any(true); if(not(annotationString = null))then{ var umlComment : UML::Comment := object UML::Comment{body := annotationString}; result.ownedComment += umlComment; safeApplyStereotype(umlComment, ModelicaAnnotation_stereotype); }endif; }; } } abstract mapping Element::ELEMENT ::setSysML$ModelicaComponentDeclarationEquationValue (inout class_ : UML::Class) : UML::TypedElement { init{ var expression : Exp::uExp = self.specification![ElementSpec::COMPONENTS] .components![ComponentItem::COMPONENTITEM].component![Component::COMPONENT] .modification![Modifications::CLASSMOD].expOption; if((expression <> null) and (not expression.oclIsInvalid()))then{ if((expression.unparsedExp != null) and (not expression.unparsedExp.oclIsInvalid()))then{ safeStereotypeSetValue(result, result.getAppliedStereotypes() [name = "ModelicaValueProperty" or name = "ModelicaFunctionParameter"] ->any(true), "declarationEquation", expression.unparsedExp); }endif; }endif; } } abstract mapping Element::ELEMENT ::setSysML$ModelicaComponentScopeValue (inout class_ : UML::Class) : UML::TypedElement { init{ if(self.innerOuter.oclIsKindOf(InnerOuter::INNER)) then{ safeStereotypeSetValue(result, result.getAppliedStereotypes() ->any(true), "scope", modelicaInnerKind); } endif; if(self.innerOuter.oclIsKindOf(InnerOuter::OUTER)) then{ safeStereotypeSetValue(result, result.getAppliedStereotypes() ->any(true), "scope", modelicaOuterKind); } endif; } } abstract mapping Element::ELEMENT ::setSysML$ModelicaComponentConditionalExpressionValue (inout class_ : UML::Class) : UML::TypedElement { init{ var condition : Exp::uExp = self.specification![ElementSpec::COMPONENTS] .components![ComponentItem::COMPONENTITEM].condition; safeStereotypeSetValue(result, result.getAppliedStereotypes() ->any(true), "conditionalExpression", condition.unparsedExp); } } abstract mapping Element::ELEMENT ::setSysML$ModelicaComponentCausalityValue (inout class_ : UML::Class) : UML::TypedElement { init{ var direction : Direction::uDirection = self.specification![ElementSpec::COMPONENTS] .attributes![ElementAttributes::ATTR].direction; if(direction.oclIsKindOf(Direction::INPUT)) then{ safeStereotypeSetValue(result, result.getAppliedStereotypes() ->any(true), "causality", modelicaInputKind); } endif; if(direction.oclIsKindOf(Direction::OUTPUT)) then{ safeStereotypeSetValue(result, result.getAppliedStereotypes() ->any(true), "causality", modelicaOutputKind); } endif; } } abstract mapping Element::ELEMENT ::setSysML$ModelicaComponentVariabilityValue (inout class_ : UML::Class) : UML::TypedElement { init{ var variability : Variability::uVariability = self.specification![ElementSpec::COMPONENTS] .attributes![ElementAttributes::ATTR].variability; if(variability.oclIsKindOf(Variability::CONST)) then{ safeStereotypeSetValue(result, result.getAppliedStereotypes() ->any(true), "variability", modelicaConstantKind); } endif; if(variability.oclIsKindOf(Variability::VAR)) then{ safeStereotypeSetValue(result, result.getAppliedStereotypes() ->any(true), "variability", modelicaContinuousKind); } endif; if(variability.oclIsKindOf(Variability::DISCRETE)) then{ safeStereotypeSetValue(result, result.getAppliedStereotypes() ->any(true), "variability", modelicaDiscreteKind); } endif; if(variability.oclIsKindOf(Variability::PARAM)) then{ safeStereotypeSetValue(result, result.getAppliedStereotypes() ->any(true), "variability", modelicaParameterKind); } endif; } } abstract mapping Element::ELEMENT ::setSysML$ModelicaComponentFlowFlagValue (inout class_ : UML::Class) : UML::TypedElement { init{ var flowPrefix : Boolean = self.specification![ElementSpec::COMPONENTS] .attributes![ElementAttributes::ATTR].flowPrefix; if(flowPrefix) then{ safeStereotypeSetValue(result, result.getAppliedStereotypes() ->any(true), "flowFlag", modelicaFlowKind); } endif; var streamPrefix : Boolean = self.specification![ElementSpec::COMPONENTS] .attributes![ElementAttributes::ATTR].streamPrefix; if(streamPrefix) then{ safeStereotypeSetValue(result, result.getAppliedStereotypes() ->any(true), "flowFlag", modelicaStreamKind); } endif; } } abstract mapping Element::ELEMENT::setSysML$TypedElementTypeAndName (inout class_ : UML::Class) : UML::TypedElement { init{ // get last property type name, no qualified name var componentType : Type := getModelicaComponentType(self); if((componentType.oclIsInvalid() or componentType = null) and isLastModelTraversal = true)then{ // add a comment to the property containing the qualified name of the property type var umlComment : UML::Comment := object UML::Comment{}; umlComment.body := getModelicaComponentTypeQualifiedName(self); result.ownedComment += umlComment; }else{ result.type := componentType; }endif; result.name := getModelicaComponentName(self); } } // **************************** EQUATION AND ALGORITHM SECTION **************************** // ****** Mapping Rule 19.2 ****** mapping Class::CLASS::setSysML$ModelicaEquations // Mapping Rule 19.2.1 (inout owningElement : UML::Element) : UML::Class { // mapping to constraints self.body[ClassDef::PARTS].classParts[ClassPart::EQUATIONS] // Mapping Rule 19.2.3 .contents[EquationItem::EQUATIONITEM].equation_ ->select(e : Equation::uEquation | e.oclIsKindOf(Equation::EQ_CONNECT) = false) -> map toSysML$ModelicaEquation(result, false); self.body[ClassDef::PARTS].classParts[ClassPart::INITIALEQUATIONS] .contents[EquationItem::EQUATIONITEM].equation_ // Mapping Rule 19.2.4 ->select(e : Equation::uEquation | e.oclIsKindOf(Equation::EQ_CONNECT) = false) -> map toSysML$ModelicaEquation(result, true); // mapping equation annotations self.body[ClassDef::PARTS].classParts[ClassPart::EQUATIONS] .contents![EquationItem::EQUATIONITEMANN].annotation_![Annotation::ANNOTATION].elementArgs[ElementArg::MODIFICATION]-> map toSysML$ModelicaEquationAnn(result); } mapping ElementArg::MODIFICATION::toSysML$ModelicaEquationAnn (inout class_ : UML::Class) : UML::Comment { class_.ownedComment += result; result.body := self.unparsedElementArg->any(true); safeApplyStereotype(result, ModelicaAnnotation_stereotype); } mapping Equation::uEquation::toSysML$ModelicaEquation (inout class_ : UML::Class, in isInitial : Boolean) : UML::Constraint { class_.ownedRule += result; safeApplyStereotype(result, ModelicaEquation_stereotype); safeStereotypeSetValue(result, ModelicaEquation_stereotype, "isInitial", isInitial.repr()); result.specification := object UML::OpaqueExpression{body := self.unparsedEquation; language := "Modelica"}; } // ****** Mapping Rule 19.3 ****** mapping Class::CLASS::setSysML$ModelicaAlgorithms // Mapping Rule 19.3.1 (inout owningElement : UML::Element) : UML::Class { // mapping to behaviors self.body[ClassDef::PARTS].classParts[ClassPart::ALGORITHMS] // Mapping Rule 19.3.3 .contents-> map toSysML$ModelicaAlgorithm(result, false); self.body[ClassDef::PARTS] // Mapping Rule 19.3.4 .classParts[ClassPart::INITIALALGORITHMS] .contents-> map toSysML$ModelicaAlgorithm(result, true); } mapping AlgorithmItem::uAlgorithmItem::toSysML$ModelicaAlgorithm (inout class_ : UML::Class, in isInitial : Boolean) : UML::OpaqueBehavior { class_.ownedBehavior += result; safeApplyStereotype(result, ModelicaAlgorithm_stereotype); if(isInitial)then{ safeStereotypeSetValue(result, ModelicaAlgorithm_stereotype, "isInitial", true); }endif; if(not isInitial)then{ safeStereotypeSetValue(result, ModelicaAlgorithm_stereotype, "isInitial", false); }endif; //safeStereotypeSetValue(result, ModelicaAlgorithm_stereotype, "isInitial", isInitial); // java.lang.reflect.InvocationTargetException // Caused by: java.lang.ClassCastException: The value of type 'class java.lang.Boolean' // must be of type 'org.eclipse.emf.ecore.impl.EDataTypeImpl@2487b1 (name: Blocks_Boolean) (instanceClassName: Blocks_Boolean) (serializable: true)' // BUG // java.StackOverflowError. result.body += self.unparsedAlgorithmItem; } // ****** Mapping Rule 19.4 ****** mapping Class::CLASS::setSysML$ModelicaConnections (inout owningElement : UML::Element) : UML::Class // Mapping Rule 19.4.1 { // mapping to connectors self.body[ClassDef::PARTS].classParts[ClassPart::EQUATIONS] .contents[EquationItem::EQUATIONITEM].equation_[Equation::EQ_CONNECT] -> map toSysML$ModelicaConnection(result); } mapping Equation::EQ_CONNECT::toSysML$ModelicaConnection (inout class_ : UML::Class) : UML::Connector { class_.ownedConnector += result; // get componentRefs var componentRef1 : String = self.connector1.unparsedComponentRef; var componentRef2 : String = self.connector2.unparsedComponentRef; // get part1, part2, port1, port2 var part1Name : String = componentRef1.substringBefore("."); // java.lang.reflect.InvocationTargetException caused by Caused by: java.lang.StackOverflowError var part1 : UML::Property = class_.ownedAttribute![name = part1Name] .oclAsType(UML::Property); var part1Type : UML::Type = class_.ownedAttribute![name = part1Name].type; var port1 : UML::Property = getPort(componentRef1, part1Type.oclAsType(UML::Class)); var part2Name : String = componentRef2.substringBefore("."); var part2 : UML::Property = class_.ownedAttribute![name = part2Name] .oclAsType(UML::Property); var part2Type : UML::Type = class_.ownedAttribute![name = part2Name].type; var port2 : UML::Property = getPort(componentRef2, part2Type.oclAsType(UML::Class)); result._end += object UML::ConnectorEnd{partWithPort := part1; role := port1}; // Mapping Rule 19.4.2 result._end += object UML::ConnectorEnd{partWithPort := part2; role := port2}; // Mapping Rule 19.4.3 //result.name := "connect (" + componentRef1 + " , " + componentRef2 + ")"; result.name := self.unparsedEquation; safeApplyStereotype(result, ModelicaConnection_stereotype); // annotation } // *********************************** HELPER FUNCTIONS *********************************** -- black-box helper defined in modelicaQVTUtils.ModelicaUtils. -- helper loadComponentRef(in componentReference : ComponentRef::uComponentRef) : String -- black-box helper defined in modelicaQVTUtils.ModelicaUtils. -- helper loadExpression(in expression : Exp::uExp) : String; -- black-box helper defined in modelicaQVTUtils.ModelicaUtils. -- helper loadFunctionArgs(in functionArgs : FunctionArgs::uFunctionArguments) : String -- black-box helper defined in modelicaQVTUtils.ModelicaUtils. -- helper loadEquation(in equation : Equation::uEquation) : String -- black-box helper defined in modelicaQVTUtils.ModelicaUtils. -- helper loadAlgorithmItem(in algorithmItem : AlgorithmItem::uAlgorithmItem) : String -- black-box helper defined in modelicaQVTUtils.ModelicaUtils. -- helper loadElementArg(in elementArg : ElementArg::uElementArg) : String /* helper loadElementArg(in elementArg : ElementArg::uElementArg) : String { // invoke Java black-box method return "TBD"; } */ helper isComponentTypeResolved (in element : Element::ELEMENT, in classifier : UML::Classifier) : Boolean { if(element.specification![ElementSpec::COMPONENTS].oclIsInvalid() or element.specification![ElementSpec::COMPONENTS] = null)then{ return false; }endif; var componentTypeQualifiedName : String := getModelicaComponentTypeQualifiedName(element); if(componentTypeQualifiedName.oclIsInvalid() or componentTypeQualifiedName = null)then{ //log("componentTypeName not found for component: " + element.repr()); //log(element.specification![ElementSpec::COMPONENTS].typeSpec.repr()); return false; }endif; //log(classifier.qualifiedName); var componentType : UML::Type := getSysML$PropertyQualifiedType(componentTypeQualifiedName); if(componentType = null or (componentType.oclIsInvalid()))then{ if(componentTypeQualifiedName != null)then{ unresolvedComponents += Tuple{source=element, target=classifier}; }endif; return false; } endif; return true; } helper isStereotypeOnPropertyType (in element : Element::ELEMENT, in stereotype : UML::Stereotype) : Boolean { // get qualified name instead of name var componentTypeQualifiedName : String := getModelicaComponentTypeQualifiedName(element); if(componentTypeQualifiedName.oclIsInvalid())then{ return false; }endif; var componentTypeName : String := getModelicaComponentTypeName(element); if(componentTypeName.oclIsInvalid())then{ return false; }endif; var componentQualifiedType : UML::Type := getSysML$PropertyQualifiedType(componentTypeQualifiedName); var componentType : UML::Type := getSysML$PropertyType(componentTypeName); if(componentQualifiedType != componentType)then{ //log(componentQualifiedType.qualifiedName); //log(componentType.qualifiedName); //log("Qualified type is NOT equal to normal type!!!"); }endif; if(componentType.oclIsInvalid()) then{ //unresolvedComponents += Tuple{source=self, target=owl2Type}; return false; } endif; //return componentType.isStereotypeApplied(stereotype); return componentQualifiedType.isStereotypeApplied(stereotype); } helper getModelicaComponentTypeName (in element : Element::ELEMENT) : String { //return element.specification![ElementSpec::COMPONENTS].typeSpec![TypeSpec::TPATH] //.path![Path::IDENT].name; // only name return getPathLastName(element.specification![ElementSpec::COMPONENTS].typeSpec![TypeSpec::TPATH] .path); } helper getModelicaComponentTypeQualifiedName (in element : Element::ELEMENT) : String { // qualified name return getPath(element.specification![ElementSpec::COMPONENTS].typeSpec![TypeSpec::TPATH] .path, null); } helper getModelicaComponentName (in element : Element::ELEMENT) : String { return element.specification![ElementSpec::COMPONENTS] .components![ComponentItem::COMPONENTITEM].component![Component::COMPONENT].name; } helper getSysML$PropertyType (in propertyTypeName : String) : UML::Type { if(propertyTypeName = "Real") then { return modelicaRealType } endif; if(propertyTypeName = "Integer") then { return modelicaIntegerType } endif; if(propertyTypeName = "Boolean") then { return modelicaBooleanType } endif; if(propertyTypeName = "String") then { return modelicaStringType } endif; if(propertyTypeName = "StateSelect") then { return modelicaStateSelectKind } endif; //------------------------------------ // only check for name return sysmlModel.objectsOfType(UML::Type)![name = propertyTypeName]; //------------------------------------ } helper getSysML$PropertyQualifiedType (in propertyTypeName : String) : UML::Type { if(propertyTypeName = "Real") then { return modelicaRealType } endif; if(propertyTypeName = "Integer") then { return modelicaIntegerType } endif; if(propertyTypeName = "Boolean") then { return modelicaBooleanType } endif; if(propertyTypeName = "String") then { return modelicaStringType } endif; if(propertyTypeName = "StateSelect") then { return modelicaStateSelectKind } endif; var componentType : UML::Type := sysmlModel.objectsOfType(UML::Type)![matchRegex(qualifiedName, "(?<=\\W)" + propertyTypeName +"(?=$)")]; if(propertyTypeName.equalsIgnoreCase("SI::Voltage"))then{ //log("stop"); }endif; if(componentType = null)then{ // check if the type can be found with another qualified type name according to the import statements importPackageMappings->forEach( tuple ){ var newpropertyTypeName : String := propertyTypeName.replace(tuple.source, tuple.target); componentType := sysmlModel.objectsOfType(UML::Type)![matchRegex(qualifiedName, "(?<=\\W)" + newpropertyTypeName +"(?=$)")]; if(componentType != null)then{ return componentType; }endif; }; }endif; return componentType; } helper getModelicaComponentType(in element : Element::ELEMENT) : UML::Type { var propertyTypeLastName : String := getPathLastName(element.specification![ElementSpec::COMPONENTS].typeSpec![TypeSpec::TPATH] .path); if(propertyTypeLastName = "Real") then { return modelicaRealType } endif; if(propertyTypeLastName = "Integer") then { return modelicaIntegerType } endif; if(propertyTypeLastName = "Boolean") then { return modelicaBooleanType } endif; if(propertyTypeLastName = "String") then { return modelicaStringType } endif; if(propertyTypeLastName = "StateSelect") then { return modelicaStateSelectKind } endif; // no primitive type // get qualified name var propertyTypeQualifiedName : String := getModelicaComponentTypeQualifiedName(element); var componentType : UML::Type := getSysML$PropertyQualifiedType(propertyTypeQualifiedName); return componentType; } helper getPart(in componentReference : String, inout class_ : UML::Class ) : UML::Property { var partName : String = componentReference.substringBefore("\\."); return class_.ownedAttribute![name = partName]; } helper getPort(in componentReference : String, in propertyType : UML::Class) : UML::Property { var portName : String = componentReference.substringAfter("."); var attributes : Set(UML::Property) = null; attributes += propertyType.ownedAttribute; propertyType.inheritedMember->forEach(s) { if(s.oclIsKindOf(UML::Property)) then {attributes += s.oclAsType(UML::Property);} endif; }; return attributes->select(name = portName)->any(true); } helper getPathLastName(in path : Path::uPath ) : String { if(path.oclIsKindOf(Path::IDENT))then{ //return path.oclAsType(Path::IDENT).name; return path.oclAsType(Path::IDENT).name; }endif; if(path.oclIsKindOf(Path::QUALIFIED))then{ // name + path //var path2 := path.oclAsType(Path::QUALIFIED).path; return getPathLastName(path.oclAsType(Path::QUALIFIED).path); }endif; if(path.oclIsKindOf(Path::FULLYQUALIFIED))then{ // just path return getPathLastName(path.oclAsType(Path::FULLYQUALIFIED).path); }endif; return null; } helper getPath(in path : Path::uPath, in qualifiedName : String ) : String { if(not path.oclIsInvalid())then{ var newQualifiedName : String = null; if(path.oclIsKindOf(Path::IDENT))then{ //return path.oclAsType(Path::IDENT).name; //newQualifiedName := path.oclAsType(Path::IDENT).name; if(qualifiedName = null)then{ newQualifiedName := path.oclAsType(Path::IDENT).name; }else{ newQualifiedName := qualifiedName + "::" + path.oclAsType(Path::IDENT).name; }endif; }endif; if(path.oclIsKindOf(Path::QUALIFIED))then{ var qualifiedPath : Path::QUALIFIED := path.oclAsType(Path::QUALIFIED); if(qualifiedName = null)then{ newQualifiedName := qualifiedPath.name; }else{ newQualifiedName := qualifiedName + "::" + qualifiedPath.name; }endif; // name + path //var path2 := path.oclAsType(Path::QUALIFIED).path; return getPath(path.oclAsType(Path::QUALIFIED).path, newQualifiedName); }endif; if(path.oclIsKindOf(Path::FULLYQUALIFIED))then{ // just path return getPath(path.oclAsType(Path::FULLYQUALIFIED).path, null); }endif; return newQualifiedName; } else{ return null; }endif; return null; } helper setUndefinedGeneralizations() { var index : Integer = 1; undefinedGeneralizations->forEach( generalization ){ var generalizedClassName := generalizedClassNames->at(index); var generalizedClass : UML::Class := sysmlModel.objectsOfType(UML::Class)![name = generalizedClassName]; if(generalizedClass != null)then{ //log(generalizedClass.name); generalization.general := generalizedClass; }endif; index := index + 1; }; } helper setUnresolvedComponents() { //log("***********************************+"); unresolvedComponents->forEach( tuple ){ tuple.source->map toSysML$ModelicaComponent(tuple.target); }; } helper safeApplyStereotype(element : UML::Element, stereotype : UML::Stereotype) { assert fatal (not element.oclIsUndefined()) with log('safeApplyStereotype(element=)'); assert fatal (not stereotype.oclIsUndefined()) with log('safeApplyStereotype(stereotype=)'); var nearestPackage := element.getNearestPackage(); assert fatal (not nearestPackage.oclIsUndefined()) with log('safeApplyStereotype(element is not contained in a package!)'); var profile := stereotype.getProfile(); assert fatal (not profile.oclIsUndefined()) with log('safeApplyStereotype(stereotype ' + stereotype.name + ' is not defined in a profile!)'); if (not nearestPackage.getAllAppliedProfiles()->includes(profile)) then { nearestPackage.applyProfile(profile); log('safeApplyStereotype(element=' + element.repr() + ', stereotype=' + stereotype.qualifiedName + ') -- applied profile: ' + profile.qualifiedName + ' to: ' + nearestPackage.qualifiedName); } endif; var sub : Set(UML::Stereotype) = element.getAppliedSubstereotypes(stereotype); if (sub->notEmpty()) then { // a specialization of the stereotype is applied. return; } endif; if (not element.isStereotypeApplicable(stereotype)) then { log('safeApplyStereotype(namedElement=' + element.repr() + ', stereotype=' + stereotype.qualifiedName + ') -- stereotype is not applicable to this element!'); } endif; assert fatal (element.isStereotypeApplicable(stereotype)) with log('safeApplyStereotype(namedElement=' + element.repr() + ', stereotype=' + stereotype.qualifiedName + ') -- stereotype is not applicable to this element!'); if (not element.isStereotypeApplied(stereotype)) then { element.applyStereotype(stereotype); if (not element.isStereotypeApplied(stereotype)) then { log('safeApplyStereotype(namedElement=' + element.repr() + ', stereotype=' + stereotype.qualifiedName + ') -- stereotype application failed!'); assert fatal (element.isStereotypeApplied(stereotype)) with log('safeApplyStereotype(namedElement=' + element.repr() + ', stereotype=' + stereotype.qualifiedName + ') -- stereotype application failed!'); } endif; } endif; return; } helper safeStereotypeSetValue (element : UML::Element, stereotype : UML::Stereotype, tagName : String, value : OclAny) { safeApplyStereotype(element, stereotype); var sub : Set(UML::Stereotype) = element.getAppliedSubstereotypes(stereotype); var s : UML::Stereotype = null; if (sub->notEmpty()) then { sub := sub[getAllAttributes().name->includes(tagName)]; } else { sub := stereotype->asSet(); } endif; assert fatal (sub->size() = 1) with log('safeStereotypeSetValue(element=' + element.repr() + ', stereotype=' + stereotype.qualifiedName + ', tag=' + tagName + ') : the stereotype does not have any tag attribute of this name.)'); s := sub![UML::Stereotype]; element.setValue(s, tagName, value); } helper safeStereotypeSetListValue (element : UML::Element, s : UML::Stereotype, propertyName : String, cv : Collection(OclAny)) { element.clearStereotypeListValue(s, propertyName); cv->forEach(v) { element.addStereotypeListValue(s, propertyName, v); } } helper getModificationStringSet(in classModmodification : Modifications::CLASSMOD) : Set(String) { var modificationsStringSet : Set(String); classModmodification.elementArgLst[ElementArg::MODIFICATION]->forEach(modification){ var modificationsString : String; var uComponentRef_ : uComponentRef= modification.componentRef; var componentRef : String = uComponentRef_.unparsedComponentRef; modificationsString := modificationsString + componentRef; if(modification.modification[Modifications::CLASSMOD].elementArgLst->notEmpty())then{ modificationsString := modificationsString + "("; var index : Integer := 0; modification.modification[Modifications::CLASSMOD].elementArgLst[ElementArg::MODIFICATION]->forEach(nestedclassMod){ if(index > 0)then{ modificationsString := modificationsString + ","; }endif; var newModificationString : String := getModificationString(nestedclassMod, ""); modificationsString := modificationsString + newModificationString; index := index + 1; }; modificationsString := modificationsString + ")"; }else{ var value : String = modification .modification![Modifications::CLASSMOD].expOption.unparsedExp; modificationsString := modificationsString + " = " + value; } endif; modificationsStringSet += modificationsString; }; return modificationsStringSet; } helper getModificationString(in elementArgModmodification : ElementArg::MODIFICATION, in modificationsStr : String ) : String { var modificationsString : String; modificationsString := modificationsStr; var uComponentRef_ : uComponentRef= elementArgModmodification.componentRef; var componentRef : String = uComponentRef_.unparsedComponentRef; modificationsString := modificationsString + componentRef; if(elementArgModmodification.modification[Modifications::CLASSMOD].elementArgLst->notEmpty())then{ modificationsString := modificationsString + "("; var index : Integer := 0; elementArgModmodification.modification[Modifications::CLASSMOD].elementArgLst[ElementArg::MODIFICATION]->forEach(nestedclassMod){ if(index > 0)then{ modificationsString := modificationsString + ","; }endif; var newModificationString : String := getModificationString(nestedclassMod, modificationsString); modificationsString := modificationsString + newModificationString; index := index + 1; }; modificationsString := modificationsString + ")"; }else{ var value : String = elementArgModmodification .modification![Modifications::CLASSMOD].expOption.unparsedExp; modificationsString := modificationsString + " = " + value; } endif; return modificationsString; } helper getModificationStringSet(in elementSpecExtends : ElementSpec::EXTENDS) : Set(String) { var modificationsStringSet : Set(String); elementSpecExtends.elementArg[ElementArg::MODIFICATION]->forEach(modification){ var modificationsString : String; var uComponentRef_ : uComponentRef= modification.componentRef; var componentRef : String = uComponentRef_.unparsedComponentRef; modificationsString := modificationsString + componentRef; if(modification.modification[Modifications::CLASSMOD].elementArgLst->notEmpty())then{ modificationsString := modificationsString + "("; var index : Integer := 0; modification.modification[Modifications::CLASSMOD].elementArgLst[ElementArg::MODIFICATION]->forEach(nestedclassMod){ if(index > 0)then{ modificationsString := modificationsString + ","; }endif; var newModificationString : String := getModificationString(nestedclassMod, ""); modificationsString := modificationsString + newModificationString; index := index + 1; }; modificationsString := modificationsString + ")"; }else{ var value : String = modification .modification![Modifications::CLASSMOD].expOption.unparsedExp; modificationsString := modificationsString + " = " + value; } endif; modificationsStringSet += modificationsString; }; return modificationsStringSet; } helper getModificationStringSet(in classDefDerived : ClassDef::DERIVED) : Set(String) { var modificationsStringSet : Set(String); classDefDerived.arguments[ElementArg::MODIFICATION]->forEach(modification){ var modificationsString : String; var uComponentRef_ : uComponentRef= modification.componentRef; var componentRef : String = uComponentRef_.unparsedComponentRef; modificationsString := modificationsString + componentRef; if(modification.modification[Modifications::CLASSMOD].elementArgLst->notEmpty())then{ modificationsString := modificationsString + "("; var index : Integer := 0; modification.modification[Modifications::CLASSMOD].elementArgLst[ElementArg::MODIFICATION]->forEach(nestedclassMod){ if(index > 0)then{ modificationsString := modificationsString + ","; }endif; var newModificationString : String := getModificationString(nestedclassMod, ""); modificationsString := modificationsString + newModificationString; index := index + 1; }; modificationsString := modificationsString + ")"; }else{ var value : String = modification .modification![Modifications::CLASSMOD].expOption.unparsedExp; modificationsString := modificationsString + " = " + value; } endif; if(modification.finalItem)then{ modificationsString := "final " + modificationsString; }endif; if(modification.each_.oclIsTypeOf(Each::EACH))then{ modificationsString := "each " + modificationsString; }endif; modificationsStringSet += modificationsString; }; return modificationsStringSet; }