| /******************************************************************************* |
| * 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 v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * 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.core.genmodel.fsm.base.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.generator.generic.ProcedureHelpers |
| import org.eclipse.etrice.generator.generic.RoomExtensions |
| import org.eclipse.xtext.generator.JavaIoFileSystemAccess |
| import org.eclipse.etrice.core.room.util.RoomHelpers |
| |
| @Singleton |
| class DataClassGen { |
| |
| @Inject extension JavaIoFileSystemAccess fileAccess |
| @Inject extension CppExtensions stdExt |
| @Inject extension RoomExtensions roomExt |
| @Inject extension ProcedureHelpers 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.usedDataClasses) { |
| var path = dc.generationTargetPath + dc.getPath |
| |
| // header file |
| logger.logInfo("generating DataClass header '"+dc.getCppHeaderFileName+"' in '"+path+"'") |
| fileAccess.setOutputPath(path) |
| fileAccess.generateFile(dc.getCppHeaderFileName, root.generateHeaderFile(dc)) |
| |
| // source file |
| logger.logInfo("generating DataClass source '"+dc.getCppSourceFileName+"' in '"+path+"'") |
| fileAccess.setOutputPath(path) |
| fileAccess.generateFile(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); |
| «dc.name»& operator=(const «dc.name»& rhs); |
| |
| // constructor using fields |
| «IF !dc.allAttributes.empty»«dc.name»(«dc.allAttributes.argList»);«ENDIF» |
| }; |
| |
| «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.argList») |
| «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 = <CharSequence>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 = <CharSequence>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 = <CharSequence>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<Attribute> 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<Attribute> 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<Attribute> 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» |
| ''' |
| } |
| |
| } |