Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShuai Li2015-10-13 13:54:21 +0000
committerGerrit Code Review @ Eclipse.org2015-10-21 08:24:46 +0000
commitdb91561642777b60d42e09d9ad3040d6e2c32968 (patch)
tree47cab62377da65585d4b31187f7225fcc49d48d8 /extraplugins
parentae2c68880f709564816906155158b226878bf01d (diff)
downloadorg.eclipse.papyrus-db91561642777b60d42e09d9ad3040d6e2c32968.tar.gz
org.eclipse.papyrus-db91561642777b60d42e09d9ad3040d6e2c32968.tar.xz
org.eclipse.papyrus-db91561642777b60d42e09d9ad3040d6e2c32968.zip
Bug 478818 - [C++ codegen] Inner classifier generation
- Generate inner classifiers in a classifier (recursive) - Generate body of a class including its inner classifier methods (recursive) - When including a type, include its closest owner who is itself owned by a package Patch set 6: - Copyright Change-Id: I25bf80a7e1cd7c3efa0c3cc9b02aa9b6f19713f7 Signed-off-by: Shuai Li <shuai.li@cea.fr>
Diffstat (limited to 'extraplugins')
-rw-r--r--extraplugins/codegen/org.eclipse.papyrus.codegen.base/src/org/eclipse/papyrus/codegen/base/GenUtils.java113
-rw-r--r--extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/utils/ClassUtils.java23
-rw-r--r--extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/xtend/CppClassOperationsImplementation.xtend4
-rw-r--r--extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/xtend/CppClassTypeAndEnum.xtend11
-rw-r--r--extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/xtend/CppClassifierGenerator.xtend2
-rw-r--r--extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/xtend/CppInnerClassifiers.xtend58
-rw-r--r--extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/xtend/CppOperations.xtend23
7 files changed, 206 insertions, 28 deletions
diff --git a/extraplugins/codegen/org.eclipse.papyrus.codegen.base/src/org/eclipse/papyrus/codegen/base/GenUtils.java b/extraplugins/codegen/org.eclipse.papyrus.codegen.base/src/org/eclipse/papyrus/codegen/base/GenUtils.java
index f71c2d7856d..bf1304e37cb 100644
--- a/extraplugins/codegen/org.eclipse.papyrus.codegen.base/src/org/eclipse/papyrus/codegen/base/GenUtils.java
+++ b/extraplugins/codegen/org.eclipse.papyrus.codegen.base/src/org/eclipse/papyrus/codegen/base/GenUtils.java
@@ -159,10 +159,7 @@ public class GenUtils {
while (attributes.hasNext()) {
Property currentAttribute = attributes.next();
Type type = currentAttribute.getType();
- if (type instanceof Classifier) {
- Classifier attrType = (Classifier) type;
- result.add(attrType);
- }
+ addFarthestOwnerType(type, result);
}
return result;
}
@@ -179,9 +176,7 @@ public class GenUtils {
for (Property currentAttribute : current.getAttributes()) {
Type type = currentAttribute.getType();
- if (type instanceof Classifier) {
- result.add((Classifier) type);
- }
+ addFarthestOwnerType(type, result);
}
return result;
}
@@ -200,10 +195,25 @@ public class GenUtils {
for (Operation operation : current.getOperations()) {
for (Parameter param : operation.getOwnedParameters()) {
Type type = param.getType();
- if (type instanceof Classifier) {
- Classifier paramType = (Classifier) type;
- result.add(paramType);
- }
+ addFarthestOwnerType(type, result);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Retrieves a list of types used by inner classifiers of the current classifier
+ *
+ * @param current
+ * Class on which the attributes are searched
+ * @return collection of classes which are the types of the operations parameters
+ */
+ public static EList<Classifier> getInnerClassifierTypes(Classifier current) {
+ EList<Classifier> result = new UniqueEList<Classifier>();
+ for (Element ownedElement : current.allOwnedElements()) {
+ if (ownedElement instanceof Classifier) {
+ result.addAll(getOwnedAttributeTypes((Classifier) ownedElement));
+ result.addAll(getTypesViaOperations((Classifier) ownedElement));
}
}
return result;
@@ -225,9 +235,7 @@ public class GenUtils {
// there should always be at least one element in the target
// list and it should be a classifier, but better check.
Element element = relationship.getTargets().get(0);
- if (element instanceof Classifier) {
- classifiers.add((Classifier) element);
- }
+ addFarthestOwnerType(element, classifiers);
}
}
return classifiers;
@@ -248,9 +256,7 @@ public class GenUtils {
// there should always be at least one element in the target
// list and it should be a classifier, but better check.
Element element = relationship.getTargets().get(0);
- if (element instanceof Classifier) {
- classifiers.add((Classifier) element);
- }
+ addFarthestOwnerType(element, classifiers);
}
}
}
@@ -273,9 +279,7 @@ public class GenUtils {
// there should always be at least one element in the target
// list and it should be a classifier, but better check.
Element element = relationship.getTargets().get(0);
- if (element instanceof Classifier) {
- classifiers.add((Classifier) element);
- }
+ addFarthestOwnerType(element, classifiers);
}
}
}
@@ -348,12 +352,75 @@ public class GenUtils {
public static EList<Classifier> getUsedClassifiers(Classifier cls) {
EList<Classifier> result = new BasicEList<Classifier>();
for (Element depElement : cls.getClientDependencies()) {
- if (depElement instanceof Classifier) {
- result.add((Classifier) depElement);
- }
+ addFarthestOwnerType(depElement, result);
}
return result;
}
+
+ /**
+ * Adds the first element owned by a package in a classifier's namespace
+ *
+ * @param classifier
+ * @return
+ */
+ private static void addFarthestOwnerType(Element element, EList<Classifier> result) {
+ if (element == null || result == null) {
+ return;
+ }
+
+ if (element.getOwner() instanceof Package && element instanceof Classifier) {
+ result.add((Classifier) element);
+ } else { // Type is an inner class. We want to return a classifier C directly owned by a package since it is "C.h" that should be included
+ addFarthestOwnerType(element.getOwner(), result);
+ }
+ }
+
+ /**
+ * Get the namespace of the farthest classifier owner that owns an operation
+ *
+ * @param op
+ * @return
+ */
+ public static String getNestedOperationFarthestClassifierOwnerNamespace(Operation op) {
+ StringBuffer buffer = new StringBuffer("");
+ if (op != null && op.getOwner() instanceof Classifier) {
+ getFarthestOwnerNamespace(op.getOwner(), buffer);
+ }
+ return buffer.toString();
+ }
+
+ /**
+ * Get the namespace of the farthest classifier owner that owns an operation
+ *
+ * @param behavior
+ * @return
+ */
+ public static String getNestedBehaviorFarthestClassifierOwnerNamespace(OpaqueBehavior behavior) {
+ StringBuffer buffer = new StringBuffer("");
+ if (behavior != null && behavior.getOwner() instanceof Classifier) {
+ getFarthestOwnerNamespace(behavior.getOwner(), buffer);
+ }
+ return buffer.toString();
+ }
+
+ /**
+ * Build a namespace to the farthest owner (i.e. owned by a package) of some element
+ *
+ * @param element
+ * @param result
+ */
+ private static void getFarthestOwnerNamespace(Element element, StringBuffer result) {
+ if (element == null || result == null) {
+ return;
+ }
+
+ if (element.getOwner() instanceof Package) {
+ result.insert(0, ((Classifier) element).getName());
+ } else {
+ result.insert(0, "::" + ((Classifier) element).getName());
+ getFarthestOwnerNamespace(element.getOwner(), result);
+ }
+ }
/**
* Return the qualified name of a package, but use "/" instead of "::" as separator
diff --git a/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/utils/ClassUtils.java b/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/utils/ClassUtils.java
index e4f18d52ecf..7653753411f 100644
--- a/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/utils/ClassUtils.java
+++ b/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/utils/ClassUtils.java
@@ -16,7 +16,9 @@ import org.eclipse.emf.common.util.UniqueEList;
import org.eclipse.papyrus.codegen.base.GenUtils;
import org.eclipse.uml2.uml.Class;
import org.eclipse.uml2.uml.Classifier;
+import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.Interface;
+import org.eclipse.uml2.uml.Operation;
/**
* A set of utility functions related to classes.
@@ -41,6 +43,8 @@ public class ClassUtils {
usedClasses.addAll(GenUtils.getOwnedAttributeTypes(currentClass));
// operation parameters dependencies
usedClasses.addAll(GenUtils.getTypesViaOperations(currentClass));
+ // inner classifier dependencies
+ usedClasses.addAll(GenUtils.getInnerClassifierTypes(currentClass));
// realized interface dependencies
if (currentClass instanceof Class) {
Class clazz = (Class) currentClass;
@@ -55,4 +59,23 @@ public class ClassUtils {
usedClasses.removeAll(GenUtils.getTemplateParameteredElements(currentClass));
return usedClasses;
}
+
+ /**
+ * Retrieve the list of operations of classes nested in the current class
+ * without the operations directly owned by the current class
+ *
+ * @param currentClass
+ * @return
+ */
+ public static EList<Operation> nestedOperations(Classifier currentClass) {
+ EList<Operation> nestedOperations = new UniqueEList<Operation>();
+
+ for (Element element : currentClass.allOwnedElements()) {
+ if (element instanceof Operation && !(element.getOwner().equals(currentClass))) {
+ nestedOperations.add((Operation) element);
+ }
+ }
+
+ return nestedOperations;
+ }
}
diff --git a/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/xtend/CppClassOperationsImplementation.xtend b/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/xtend/CppClassOperationsImplementation.xtend
index 29b1b3916a0..091d40b4f93 100644
--- a/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/xtend/CppClassOperationsImplementation.xtend
+++ b/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/xtend/CppClassOperationsImplementation.xtend
@@ -29,6 +29,10 @@ class CppClassOperationsImplementation {
«CppOperations.CppOperationImplementation(ownedOperation)»
«ENDFOR»
+ «FOR nestedOperation : CppOperations.getNestedOperations(clazz).filter[(!(GenUtils.hasStereotype(it, NoCodeGen) || it.isAbstract)) && (GenUtils.hasStereotype(it, org.eclipse.papyrus.C_Cpp.Inline) == inline)] SEPARATOR "\n"»
+ «CppOperations.CppOperationImplementation(nestedOperation)»
+ «ENDFOR»
+
«FOR b : clazz.eAllContents.toIterable.filter[(it instanceof OpaqueBehavior) && GenUtils.hasStereotype((it as OpaqueBehavior), Inline)==inline]»
«IF (b as OpaqueBehavior).specification == null»
// opaque behavior without specification (typically from state machine)
diff --git a/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/xtend/CppClassTypeAndEnum.xtend b/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/xtend/CppClassTypeAndEnum.xtend
index 0d02c71a5a5..f86b4b8f490 100644
--- a/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/xtend/CppClassTypeAndEnum.xtend
+++ b/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/xtend/CppClassTypeAndEnum.xtend
@@ -21,6 +21,8 @@ import org.eclipse.uml2.uml.Package
import org.eclipse.uml2.uml.PrimitiveType
import org.eclipse.uml2.uml.VisibilityKind
import org.eclipse.papyrus.codegen.base.GenUtils
+import org.eclipse.uml2.uml.DataType
+import org.eclipse.uml2.uml.UMLFactory
/**
* @author Önder GÜRCAN (onder.gurcan@cea.fr)
@@ -56,7 +58,14 @@ class CppClassTypeAndEnum {
return CppEnumerations.CppEnumerationDefinition(element as Enumeration)
} else if (element instanceof PrimitiveType) {
return CppPrimitiveTypes.CppPrimitiveTypeDefinition(element as PrimitiveType)
- }
+ } else if (element instanceof DataType || element.eClass.equals(UMLFactory.eINSTANCE.getUMLPackage().getClass_())) {
+ if (GenUtils.isTemplateBoundElement(element as Classifier)) {
+ return CppInnerClassifiers.CppInnerBindDefinition(element as Classifier)
+ } else {
+ return CppInnerClassifiers.CppInnerClassDefinition(element as Classifier)
+ }
+
+ }
}
}
}
diff --git a/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/xtend/CppClassifierGenerator.xtend b/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/xtend/CppClassifierGenerator.xtend
index 62245140650..41af9c68a4b 100644
--- a/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/xtend/CppClassifierGenerator.xtend
+++ b/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/xtend/CppClassifierGenerator.xtend
@@ -124,7 +124,7 @@ class CppClassifierGenerator {
«CppDocumentation.CppElementDoc(classifier)»
«CppTemplates.templateSignature(classifier)»«classUnionOrStruct(classifier)» «classifier.name»«CppClassInheritedDeclarations.
CppClassInheritedDeclarations(classifier)» {
- «CppClassFriendDeclaration.CppClassIncludeFriendDeclaration(classifier)»«CppClassTypeAndEnum.CppClassTypeAndEnum(classifier)»
+ «CppClassFriendDeclaration.CppClassIncludeFriendDeclaration(classifier)»«CppClassTypeAndEnum.CppClassTypeAndEnum(classifier)»
«var publicVisibility = VisibilityKind.PUBLIC_LITERAL»
«CppGenUtils.getSection(publicVisibility, defaultInitializer(classifier))»
«CppGenUtils.getSection(publicVisibility,
diff --git a/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/xtend/CppInnerClassifiers.xtend b/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/xtend/CppInnerClassifiers.xtend
new file mode 100644
index 00000000000..78938c09623
--- /dev/null
+++ b/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/xtend/CppInnerClassifiers.xtend
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2015 CEA LIST.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA LIST - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.papyrus.cpp.codegen.xtend
+
+import org.eclipse.uml2.uml.Classifier
+import org.eclipse.papyrus.cpp.codegen.utils.CppGenUtils
+import org.eclipse.uml2.uml.VisibilityKind
+import org.eclipse.papyrus.codegen.base.GenUtils
+import org.eclipse.uml2.uml.NamedElement
+
+/**
+ * @author Shuai Li (CEA) <shuai.li@cea.fr>
+ */
+
+class CppInnerClassifiers {
+ static def CppInnerClassDefinition(Classifier classifier) '''
+ «CppDocumentation.CppElementDoc(classifier)»
+ «CppTemplates.templateSignature(classifier)»«CppClassifierGenerator.classUnionOrStruct(classifier)» «classifier.name»«CppClassInheritedDeclarations.
+ CppClassInheritedDeclarations(classifier)» {
+ «CppClassFriendDeclaration.CppClassIncludeFriendDeclaration(classifier)»«CppClassTypeAndEnum.CppClassTypeAndEnum(classifier)»
+ «var publicVisibility = VisibilityKind.PUBLIC_LITERAL»
+ «CppGenUtils.getSection(publicVisibility, CppClassifierGenerator.defaultInitializer(classifier))»
+ «CppGenUtils.getSection(publicVisibility,
+ CppClassAttributesDeclaration.CppClassAttributesDeclaration(classifier, publicVisibility).toString)»
+ «CppGenUtils.getSection(publicVisibility,
+ CppClassOperationsDeclaration.CppClassOperationsDeclaration(classifier, publicVisibility).toString)»
+
+ «var protectedVisibility = VisibilityKind.PROTECTED_LITERAL»
+ «CppGenUtils.getSection(protectedVisibility,
+ CppClassAttributesDeclaration.CppClassAttributesDeclaration(classifier, protectedVisibility).toString)»
+ «CppGenUtils.getSection(protectedVisibility,
+ CppClassOperationsDeclaration.CppClassOperationsDeclaration(classifier, protectedVisibility).toString)»
+
+ «var privateVisibility = VisibilityKind.PRIVATE_LITERAL»
+ «CppGenUtils.getSection(privateVisibility,
+ CppClassAttributesDeclaration.CppClassAttributesDeclaration(classifier, privateVisibility).toString)»
+ «CppGenUtils.getSection(privateVisibility,
+ CppClassOperationsDeclaration.CppClassOperationsDeclaration(classifier, privateVisibility).toString)»
+ };
+ '''
+
+ static def CppInnerBindDefinition(Classifier classifier) '''
+ «var tb = GenUtils.getTemplateBinding(classifier)»
+ «var templateElement = tb.targets.get(0)»
+ /************************************************************/
+ typedef «(templateElement.owner as NamedElement).name»<«FOR ps : tb.parameterSubstitutions SEPARATOR ', '»«
+ CppTemplates.CppTemplateBindingParameter(ps)»«ENDFOR»> «classifier.name»;
+ '''
+} \ No newline at end of file
diff --git a/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/xtend/CppOperations.xtend b/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/xtend/CppOperations.xtend
index 1082ce1be40..de037fb9498 100644
--- a/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/xtend/CppOperations.xtend
+++ b/extraplugins/codegen/org.eclipse.papyrus.cpp.codegen/src/org/eclipse/papyrus/cpp/codegen/xtend/CppOperations.xtend
@@ -28,9 +28,10 @@ import org.eclipse.uml2.uml.profile.standard.Destroy
import org.eclipse.papyrus.C_Cpp.ConstInit
import org.eclipse.uml2.uml.util.UMLUtil
import org.eclipse.papyrus.cpp.codegen.Constants
-import org.eclipse.papyrus.codegen.base.GenUtils
import org.eclipse.uml2.uml.NamedElement
import org.eclipse.uml2.uml.Region
+import org.eclipse.papyrus.cpp.codegen.utils.ClassUtils
+import org.eclipse.papyrus.codegen.base.GenUtils
class CppOperations {
static def CppOperationImplementation(Operation operation) '''
@@ -40,7 +41,7 @@ class CppOperations {
«GenUtils.getBody(operation, Constants.supportedLanguages)»
}
«ELSE»
- «CppTemplates.templateSignature(operation)»«InlineTxt(operation)»«CppReturnSpec(operation)»«operation.featuringClassifiers.get(0).name»«CppTemplates.templateShortSignature(operation)»::«destructor(operation)»«operation.name»(«CppParameter.CppOperationParameters(operation, false)»)«throwss(operation)»«Modifier.modCVQualifier(operation)»«CppConstInit(operation)» {
+ «CppTemplates.templateSignature(operation)»«InlineTxt(operation)»«CppReturnSpec(operation)»«GenUtils.getNestedOperationFarthestClassifierOwnerNamespace(operation)»«CppTemplates.templateShortSignature(operation)»::«destructor(operation)»«operation.name»(«CppParameter.CppOperationParameters(operation, false)»)«throwss(operation)»«Modifier.modCVQualifier(operation)»«CppConstInit(operation)» {
«GenUtils.getBody(operation, Constants.supportedLanguages)»
}
«ENDIF»
@@ -110,9 +111,25 @@ class CppOperations {
}
}
+ static def getNestedOperations(Classifier c1) {
+ val operations = getNestedOperationsWNull(c1)
+ if (operations == null) {
+ emptySet
+ }
+ else {
+ operations
+ }
+ }
+
+ static def getNestedOperationsWNull(Classifier cl) {
+ if (cl instanceof Class || cl instanceof Interface) {
+ ClassUtils.nestedOperations(cl)
+ }
+ }
+
static def CppBehaviorImplementation(OpaqueBehavior behavior) '''
«CppDocumentation.CppBehaviorDoc(behavior)»
- «CppReturnSpec(behavior)»«behavior.context.name»::«behavior.qualifiedBehaviorName»(«CppParameter.CppBehaviorParameters(behavior, false)»)«Modifier.modCVQualifier(behavior)» {
+ «CppReturnSpec(behavior)»«GenUtils.getNestedBehaviorFarthestClassifierOwnerNamespace(behavior)»::«behavior.qualifiedBehaviorName»(«CppParameter.CppBehaviorParameters(behavior, false)»)«Modifier.modCVQualifier(behavior)» {
«GenUtils.getBodyFromOB(behavior, Constants.supportedLanguages)»
}
'''

Back to the top