| package org.eclipse.papyrus.designer.languages.cpp.codegen.xtend |
| |
| /******************************************************************************* |
| * Copyright (c) 2014 CEA LIST. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * CEA LIST - initial API and implementation |
| *******************************************************************************/ |
| |
| import java.util.ArrayList |
| import java.util.HashSet |
| import java.util.List |
| import java.util.Set |
| import org.eclipse.emf.common.util.EList |
| import org.eclipse.papyrus.designer.languages.common.base.GenUtils |
| import org.eclipse.papyrus.designer.languages.common.profile.Codegen.NoCodeGen |
| import org.eclipse.papyrus.designer.languages.cpp.codegen.utils.CppClassUtils |
| import org.eclipse.papyrus.designer.languages.cpp.codegen.utils.CppClassUtils.Position |
| import org.eclipse.papyrus.designer.languages.cpp.codegen.utils.CppGenUtils |
| import org.eclipse.papyrus.designer.languages.cpp.profile.C_Cpp.CppRoot |
| import org.eclipse.papyrus.designer.languages.cpp.profile.C_Cpp.ExternLibrary |
| import org.eclipse.papyrus.designer.languages.cpp.profile.C_Cpp.External |
| import org.eclipse.uml2.uml.Classifier |
| import org.eclipse.uml2.uml.DataType |
| import org.eclipse.uml2.uml.Enumeration |
| import org.eclipse.uml2.uml.Package |
| import org.eclipse.uml2.uml.PrimitiveType |
| |
| /** |
| * @author Önder GÜRCAN (onder.gurcan@cea.fr) |
| */ |
| class CppClassIncludeClassDeclaration { |
| |
| static def cppOwnerPackageIncludePath(Package pkg) { |
| if ((pkg !== null) && (!GenUtils.hasStereotype(pkg, CppRoot))) { |
| return GenUtils.getFullPath(pkg) + '/Pkg_' + pkg.name + '.h' |
| } else { |
| return null |
| } |
| } |
| |
| static def CppClassAllIncludesDeclarationBody(Classifier classifier) { |
| cppClassAllIncludes(classifier, CppClassUtils.includedImplementationClassifiers(classifier)) |
| } |
| |
| static def cppClassAllIncludes(Classifier classifier, EList<Classifier> list) { |
| var List<String> newList = new ArrayList<String>() |
| for (cl : list) { |
| // var String str = null |
| if (cl != classifier && !GenUtils.hasStereotype(cl, NoCodeGen) || GenUtils.hasStereotype(cl, External)) { |
| if ((cl instanceof Enumeration || cl instanceof PrimitiveType) && |
| !GenUtils.hasStereotype(cl, External) && !GenUtils.hasStereotypeTree(cl, ExternLibrary)) { |
| if (cl.owner instanceof Package && cl.owner != classifier.owner) { |
| /* |
| * No additional include is required, if enum and primitive types are in |
| * the same package. The latter is always included. |
| */ |
| var includePath = (cl.owner as Package).cppOwnerPackageIncludePath |
| if(!newList.contains(includePath)) newList.add(includePath) |
| } else { |
| // str = null |
| } |
| } else { |
| for (includePath : CppClassIncludeDeclaration.cppClassIncludes(cl)) { |
| if(!newList.contains(includePath)) newList.add(includePath) |
| } |
| } |
| } else { |
| // str = null |
| } |
| } |
| return newList.filter[str|str !== null] |
| } |
| |
| /** |
| * Provide a forward declaration of used classifiers |
| */ |
| static def CppClassAllDeclares(Classifier clazz) { |
| cppClassAllDeclares(clazz, CppClassUtils.declaredClassifiers(clazz), CppClassUtils.includedClassifiers(clazz)) |
| } |
| |
| /** |
| * Provide a forward declaration for declared classifiers that are NOT already included |
| * |
| * @param declaredClassifiers the list of classifiers to declare |
| * @param includedClassifiers the list of classifiers to include (used to reduce list of classifiers with forwards) |
| */ |
| static def cppClassAllDeclares(Classifier classifier, EList<Classifier> declaredClassifiers, |
| EList<Classifier> includedClassifiers) { |
| var List<String> newList = new ArrayList<String>() |
| |
| if (declaredClassifiers !== null) { |
| if (includedClassifiers !== null) { |
| declaredClassifiers.removeAll(includedClassifiers) |
| } |
| |
| for (cl : declaredClassifiers) { |
| // no need to forward declare externals |
| if (cl != classifier && |
| !(GenUtils.hasStereotype(cl, NoCodeGen) || GenUtils.hasStereotype(cl, External))) { |
| var declaration = ""; |
| |
| if (!(cl instanceof Enumeration) && !(cl instanceof PrimitiveType)) { |
| if (cl instanceof DataType) { |
| declaration = CppGenUtils.openNSMinimal(cl) + "struct " + cl.name + ";" + |
| CppGenUtils.closeNSMinimal(cl); |
| } else { |
| declaration = CppGenUtils.openNSMinimal(cl).replaceAll("\r", "").replaceAll("\n", "") + |
| "class " + cl.name + ";" + |
| CppGenUtils.closeNSMinimal(cl).replaceAll("\r", "").replaceAll("\n", ""); |
| } |
| } |
| |
| if (declaration != "") { |
| if (!newList.contains(declaration)) { |
| newList.add(declaration); |
| } |
| } |
| } |
| } |
| } |
| |
| return newList.filter[str|str !== null] |
| } |
| |
| static def CppClassAllIncludes(Classifier clazz) { |
| cppClassAllIncludes(clazz, CppClassUtils.includedClassifiers(clazz)) |
| } |
| |
| static def CppClassAllUsings(Classifier classifier, Position position) { |
| val usingClasses = CppClassUtils.usingClassifiers(classifier, position) |
| if (position == Position.FOR_BODY) { |
| // in case of BODY, need BOTH in using list, but only emit using statements |
| // that are not already in the header file |
| val bothUsingClasses = CppClassUtils.usingClassifiers(classifier, Position.FOR_BOTH) |
| CppGenUtils.cgu(classifier).using = bothUsingClasses; |
| } else { |
| CppGenUtils.cgu(classifier).using = usingClasses; |
| } |
| cppClassAllUsings(classifier, usingClasses) |
| } |
| |
| static def cppClassAllUsings(Classifier classifier, EList<Classifier> list) { |
| var Set<String> newList = new HashSet<String>() |
| for (cl : list) { |
| // var String str = null |
| if (cl != classifier) { |
| if (cl.owner instanceof Package) { |
| newList.add((cl.owner as Package).qualifiedName) |
| } |
| } |
| } |
| return newList.filter[str|str !== null] |
| } |
| } |