blob: ad76dc5377a9e26bdc62448ee3919efb2a83b6b6 [file] [log] [blame]
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]
}
}