/******************************************************************************* * Copyright (c) 2011 Draeger Medical GmbH (http://www.draeger.com). * 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: * Peter Karlitschek (initial contribution) * *******************************************************************************/ package org.eclipse.etrice.generator.cpp.gen import com.google.inject.Inject import com.google.inject.Singleton import java.util.List import org.eclipse.etrice.core.genmodel.etricegen.Root import org.eclipse.etrice.generator.base.logging.ILogger import org.eclipse.etrice.core.room.Attribute import org.eclipse.etrice.core.room.ComplexType import org.eclipse.etrice.core.room.DataClass import org.eclipse.etrice.core.room.util.RoomHelpers import org.eclipse.etrice.generator.generic.RoomExtensions import org.eclipse.etrice.generator.base.io.IGeneratorFileIO @Singleton class DataClassGen { @Inject extension IGeneratorFileIO fileIO @Inject extension CppExtensions stdExt @Inject extension RoomExtensions roomExt @Inject extension CppProcedureHelpers helpers // @Inject extension TypeHelpers typeHelpers @Inject Initialization initHelper @Inject extension RoomHelpers @Inject ILogger logger def doGenerate(Root root) { logger.logInfo("generating code") for (dc: root.dataClasses) { var path = dc.getPath // header file fileIO.generateFile("generating DataClass header", path + dc.getCppHeaderFileName, root.generateHeaderFile(dc)) // source file fileIO.generateFile("generating DataClass source", path + dc.getCppSourceFileName, root.generateSourceFile(dc)) } } def generateHeaderFile(Root root, DataClass dc) { //TODO: getReferencedDataClasses does not contain a base class of the own package ''' «generateIncludeGuardBegin(dc, '')» #include "common/etDatatypesCpp.hpp" «IF dc.base!=null»#include "«dc.base.path»«dc.base.name».h"«ENDIF» «FOR classes : root.getReferencedDataClasses(dc)» #include "«classes.path»«classes.name».h" «ENDFOR» «FOR model : root.getReferencedModels(dc)» «FOR classes : model.dataClasses» #include "«classes.path»«classes.name».h" «ENDFOR» «ENDFOR» «dc.userCode1.userCode» using namespace etRuntime; // TODO JH remove «dc.generateNamespaceBegin» class «dc.name»«IF dc.base!=null» : public «dc.base.name»«ENDIF» { public: «helpers.userCode(dc.userCode2)» «helpers.attributes(dc.attributes)» «helpers.attributeSettersGettersImplementation(dc.attributes, dc.name)» «helpers.operationsDeclaration(dc.operations, dc.name)» // default constructor, copy constructor and assignment operator «dc.name»(); «dc.name»(const «dc.name»& rhs); // constructor using fields «IF !dc.allAttributes.empty»«dc.name»(«dc.allAttributes.constArgList»);«ENDIF» «dc.name»& operator=(const «dc.name»& rhs); }; «dc.generateNamespaceEnd» «generateIncludeGuardEnd(dc, '')» ''' } def generateSourceFile(Root root, DataClass dc) { ''' /** * @author generated by eTrice * * Source File of DataClass «dc.name» */ #include "«dc.getCppHeaderFileName»" #include "etUnit/etUnit.h" «dc.generateNamespaceBegin» «helpers.userCode(dc.userCode3)» // default constructor «dc.name»::«dc.name»() «dc.generateDefaultInitalizerList» { «initHelper.genExtraInitializers(dc.attributes)» «dc.userStructorBody(true)» } // copy constructor «dc.name»::«dc.name»(const «dc.name»& rhs) «dc.generateCopyInitalizerList» { } // constructor using fields // TODO «IF !dc.allAttributes.empty» «dc.name»::«dc.name»(«dc.allAttributes.constArgList») «dc.generateFieldInitializerList» { } «ENDIF» // assignment operator «dc.name»& «dc.name»::operator=(const «dc.name»& rhs) { if (this == &rhs) { return *this; }; «IF dc.base!=null»«dc.base.name»::operator=(rhs);«ENDIF» «FOR attr : dc.attributes» this->«attr.name» = rhs.«attr.name»; «ENDFOR» return *this; } «helpers.operationsImplementation(dc.operations, dc.name)» «dc.generateNamespaceEnd» '''} def private generateDefaultInitalizerList(DataClass dataClass){ val extension initHelper = initHelper var initList = newArrayList if(dataClass.base != null) initList += dataClass.base.name + '()' initList += dataClass.attributes.map['''«name»(«initializerListValue»)'''] initList.generateCtorInitializerList } def private generateCopyInitalizerList(DataClass dataClass){ val extension initHelper = initHelper var initList = newArrayList if(dataClass.base != null) initList += dataClass.base.name + '(rhs)' initList += dataClass.attributes.map['''«name»(rhs.«name»)'''] initList.generateCtorInitializerList } def private generateFieldInitializerList(DataClass dataClass){ val extension initHelper = initHelper var initList = newArrayList if(dataClass.base != null) initList += '''«dataClass.base.name»(«dataClass.base.allAttributes.map[name].join(', ')»)''' initList += dataClass.attributes.map['''«name»(«name»)'''] initList.generateCtorInitializerList } // def paramList(DataClass _dc) { // var result = "" // var dc = _dc // while (dc!=null) { // result = dc.attributes.paramList.toString + result // dc = dc.base // if (dc!=null) // result = ", "+result // } // return result // } // def paramList(List attributes) { // '''«FOR a: attributes SEPARATOR ", "»«a.name»_«ENDFOR»''' // } // // def argList(DataClass _dc) { // var result = "" // var dc = _dc // while (dc!=null) { // result = dc.attributes.argListConstructor.toString + result // dc = dc.base // if (dc!=null) // result = ", "+result // } // return result // } // // def argListConstructor(List attributes) { // '''«FOR a : attributes SEPARATOR ", "»«a.type.type.typeName»«IF a.size>1»[]«ENDIF» «a.name»_«ENDFOR»''' // } def deepCopy(DataClass _dc) { var result = "" var dc = _dc while (dc!=null) { result = deepCopy(dc.attributes).toString + result dc = dc.base } return result } def deepCopy(List attributes) { ''' «FOR a : attributes» «IF a.type.type instanceof ComplexType» if («a.name»!=null) { «IF a.size==0» copy.«a.name» = «a.name».deepCopy(); «ELSE» for (int i=0;i<«a.name».length;i++){ copy.«a.name»[i] = «a.name»[i].deepCopy(); } «ENDIF» } «ELSE» «IF a.size==0» copy.«a.name» = «a.name»; «ELSE» for (int i=0;i<«a.name».length;i++){ copy.«a.name»[i] = «a.name»[i]; } «ENDIF» «ENDIF» «ENDFOR» ''' } }