Skip to content

Commit

Permalink
Merge pull request #432 from IncQueryLabs/primitive_initialization
Browse files Browse the repository at this point in the history
#430 added default initialization to fields and variables
  • Loading branch information
abelhegedus committed Oct 2, 2015
2 parents 0d03785 + d889bb1 commit 4bd36ce
Show file tree
Hide file tree
Showing 18 changed files with 132 additions and 54 deletions.
1 change: 1 addition & 0 deletions plugins/com.ericsson.xtumlrt.oopl.model/model/oopl.ecore
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="Basic type in OOP languages corresponding to common type {@link org.eclipse.papyrusrt.xtumlrt.common.PrimitiveType}."/>
</eAnnotations>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="defaultValue" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="OOPLEnumType" abstract="true" eSuperTypes="#//OOPLDataType">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
Expand Down
4 changes: 3 additions & 1 deletion plugins/com.ericsson.xtumlrt.oopl.model/model/oopl.genmodel
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@
<genClasses ecoreClass="oopl.ecore#//OOPLExistingNameProvider">
<genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference oopl.ecore#//OOPLExistingNameProvider/commonNamedElement"/>
</genClasses>
<genClasses image="false" ecoreClass="oopl.ecore#//OOPLBasicType"/>
<genClasses image="false" ecoreClass="oopl.ecore#//OOPLBasicType">
<genFeatures createChild="false" ecoreFeature="ecore:EAttribute oopl.ecore#//OOPLBasicType/defaultValue"/>
</genClasses>
<genClasses image="false" ecoreClass="oopl.ecore#//OOPLEnumType">
<genFeatures property="Readonly" notify="false" createChild="false" ecoreFeature="ecore:EReference oopl.ecore#//OOPLEnumType/enumerators"/>
<genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference oopl.ecore#//OOPLEnumType/defaultValue"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.incquerylabs.emdw.cpp.codegeneration.templates
import com.ericsson.xtumlrt.oopl.cppmodel.CPPAttribute
import com.incquerylabs.emdw.cpp.common.TypeConverter
import org.eclipse.incquery.runtime.api.IncQueryEngine
import com.ericsson.xtumlrt.oopl.OOPLBasicType

class AttributeTemplates extends CPPTemplate {

Expand All @@ -18,8 +19,10 @@ class AttributeTemplates extends CPPTemplate {

def attributeDeclarationInClassHeader(CPPAttribute attribute) {
val commonAttr = attribute.commonAttribute
// TODO: refactor to method
val initializer = '''«IF commonAttr.^default != null» = «commonAttr.^default»«ELSEIF typeConverter.isPrimitiveType(attribute.type)» = «(attribute.type as OOPLBasicType).defaultValue»«ENDIF»'''
'''
«IF commonAttr.static»static «ENDIF»«generateCPPAttributeType(attribute)» «attribute.cppName»«IF commonAttr.^default != null» = «commonAttr.^default»«ENDIF»;
«IF commonAttr.static»static «ENDIF»«generateCPPAttributeType(attribute)» «attribute.cppName»«initializer»;
'''
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import com.ericsson.xtumlrt.oopl.cppmodel.CPPStructType
import org.eclipse.emf.ecore.EObject
import org.eclipse.papyrusrt.xtumlrt.common.Type
import org.eclipse.xtend.lib.annotations.Data
import com.ericsson.xtumlrt.oopl.OOPLBasicType

class TypeConverter {

Expand Down Expand Up @@ -170,6 +171,13 @@ class TypeConverter {
}
}

def boolean isPrimitiveType(EObject type) {
switch type {
OOPLBasicType: type.commonType.name != "String"
default: false
}
}

def String toConst(CharSequence type){
'''const «type»'''
}
Expand Down Expand Up @@ -218,5 +226,14 @@ class TypeConverter {
static class ValueAndPointerRepresentationPair {
val String pointerRepresentation
val String valueRepresentation
}
}

def getInitialValue(EObject type) {
if(type.isPrimitiveType) {
(type as OOPLBasicType).defaultValue
} else if(type.isReferenceType) {
'''nullptr'''
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,10 @@ interface IUmlSingleVariableDescriptorBuilder extends IValueDescriptorBuilder<S
* The returned SingleVariableDescriptor's stringRepresentation will not necessarily the
* same as the defined name.
*/
def IUmlSingleVariableDescriptorBuilder setIsExistingVariable(boolean isExistingVariable)
def IUmlSingleVariableDescriptorBuilder setIsExistingVariable(boolean isExistingVariable)

/**
* Determines if the created variable requires default initialization.
*/
def IUmlSingleVariableDescriptorBuilder setInitialize(boolean initialize)
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import static com.google.common.base.Preconditions.*
class UmlSingleVariableDescriptorBuilder implements IUmlSingleVariableDescriptorBuilder {
private String name
private Type type
boolean initialize
private boolean isExistingVariable
private UmlValueDescriptorFactory factory

Expand All @@ -21,9 +22,9 @@ class UmlSingleVariableDescriptorBuilder implements IUmlSingleVariableDescriptor
if(isExistingVariable) {
return factory.prepareSingleVariableDescriptorForExistingVariable(type, name)
} else if(name!=null) {
return factory.prepareSingleVariableDescriptorForNewLocalVariable(type, name)
return factory.prepareSingleVariableDescriptorForNewLocalVariable(type, name, initialize)
} else {
return factory.prepareSingleVariableDescriptorForNewLocalVariable(type)
return factory.prepareSingleVariableDescriptorForNewLocalVariable(type, initialize)
}
}

Expand All @@ -42,4 +43,9 @@ class UmlSingleVariableDescriptorBuilder implements IUmlSingleVariableDescriptor
return this
}

override setInitialize(boolean initialize) {
this.initialize = initialize
return this
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -41,39 +41,39 @@ class CppValueDescriptorFactory extends OoplValueDescriptorFactory {



override prepareSingleVariableDescriptorForNewLocalVariable(OOPLType type, String localVariableName) {
override prepareSingleVariableDescriptorForNewLocalVariable(OOPLType type, String localVariableName, boolean initialize) {
checkArgument(type!=null, "OOPLType cannot be null")
val preparedDescriptor = prepareSingleVariableDescriptor(type, localVariableName.qualifiedName)
val preparedDescriptor = prepareSingleVariableDescriptor(type, localVariableName.qualifiedName, initialize)
return preparedDescriptor
}

def prepareSingleVariableDescriptorForNewLocalVariable(CPPEvent cppEvent, String localVariableName) {
checkArgument(cppEvent!=null, "OOPLType cannot be null")
val preparedDescriptor = prepareSingleVariableDescriptor(cppEvent, localVariableName.qualifiedName)
val preparedDescriptor = prepareSingleVariableDescriptor(cppEvent, localVariableName.qualifiedName, false)
return preparedDescriptor
}

override prepareSingleVariableDescriptorForNewLocalVariable(OOPLType type) {
override prepareSingleVariableDescriptorForNewLocalVariable(OOPLType type, boolean initialize) {
checkArgument(type!=null, "OOPLType cannot be null")
val preparedDescriptor = prepareSingleVariableDescriptor(type, (type as CPPQualifiedNamedElement).cppName.escapeName.qualifiedName)
val preparedDescriptor = prepareSingleVariableDescriptor(type, (type as CPPQualifiedNamedElement).cppName.escapeName.qualifiedName, initialize)
return preparedDescriptor
}

def prepareSingleVariableDescriptorForNewLocalVariable(CPPEvent cppEvent) {
checkArgument(cppEvent!=null, "OOPLType cannot be null")
val preparedDescriptor = prepareSingleVariableDescriptor(cppEvent, cppEvent.cppName.escapeName.qualifiedName)
val preparedDescriptor = prepareSingleVariableDescriptor(cppEvent, cppEvent.cppName.escapeName.qualifiedName, false)
return preparedDescriptor
}

override prepareSingleVariableDescriptorForExistingVariable(OOPLType type, String localVariableName) {
checkArgument(type!=null, "OOPLType cannot be null")
val preparedDescriptor = prepareSingleVariableDescriptor(type, localVariableName)
val preparedDescriptor = prepareSingleVariableDescriptor(type, localVariableName, false)
return preparedDescriptor
}

def prepareSingleVariableDescriptorForExistingVariable(CPPEvent cppEvent, String localVariableName) {
checkArgument(cppEvent!=null, "OOPLType cannot be null")
val preparedDescriptor = prepareSingleVariableDescriptor(cppEvent, localVariableName)
val preparedDescriptor = prepareSingleVariableDescriptor(cppEvent, localVariableName, false)
return preparedDescriptor
}

Expand Down Expand Up @@ -124,6 +124,7 @@ class CppValueDescriptorFactory extends OoplValueDescriptorFactory {
checkArgument(collectionType!=null, "OOPLType (collectionType) cannot be null")
checkArgument(elementType!=null, "OOPLType (elementType) cannot be null")
val preparedDescriptor = prepareCollectionVariableDescriptor(collectionType, elementType, localVariableName)
// TODO find out if this is needed
index++
return preparedDescriptor
}
Expand All @@ -132,16 +133,23 @@ class CppValueDescriptorFactory extends OoplValueDescriptorFactory {
checkArgument(collectionType!=null, "OOPLType (collectionType) cannot be null")
checkArgument(elementType!=null, "OOPLType (elementType) cannot be null")
val preparedDescriptor = prepareCollectionVariableDescriptor(collectionType, elementType, localVariableName)
// TODO find out if this is needed
index++
return preparedDescriptor
}

private def prepareSingleVariableDescriptor(EObject type, String localVariableName) {
private def prepareSingleVariableDescriptor(EObject type, String localVariableName, boolean initialize) {

val stringRepresentation = if(initialize) {
'''«localVariableName» = «typeConverter.getInitialValue(type)»'''
} else {
localVariableName
}

val variableRepresentations = localVariableName.createStringRepresentations(type)

val preparedDescriptor = createSingleVariableDescriptor => [
it.stringRepresentation = localVariableName
it.stringRepresentation = stringRepresentation
it.valueRepresentation = variableRepresentations.valueRepresentation
it.pointerRepresentation = variableRepresentations.pointerRepresentation
it.baseType = type.convertToType
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ abstract class OoplValueDescriptorFactory {
* @return The SingleVariableDescriptor with the <code>type</code>
* and with unique name based on <code>localVariableName</code>
*/
def SingleVariableDescriptor prepareSingleVariableDescriptorForNewLocalVariable(OOPLType type, String localVariableName)
def SingleVariableDescriptor prepareSingleVariableDescriptorForNewLocalVariable(OOPLType type, String localVariableName, boolean initialize)

def SingleVariableDescriptor prepareSingleVariableDescriptorForNewLocalVariable(OOPLType type)
def SingleVariableDescriptor prepareSingleVariableDescriptorForNewLocalVariable(OOPLType type, boolean initialize)

def SingleVariableDescriptor prepareSingleVariableDescriptorForExistingVariable(OOPLType type, String localVariableName)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,22 @@ class UmlValueDescriptorFactory implements IUmlDescriptorFactory, IDescriptorCac
* @return The SingleVariableDescriptor with the resolved <code>type</code> based on implementation
* and with unique name based on <code>localVariableName</code>
*/
dispatch def prepareSingleVariableDescriptorForNewLocalVariable(Type type, String localVariableName) {
dispatch def prepareSingleVariableDescriptorForNewLocalVariable(Type type, String localVariableName, boolean initialize) {
val xtumlType = mapper.convertType(type)
return factory.prepareSingleVariableDescriptorForNewLocalVariable(xtumlType, localVariableName).cache(localVariableName)
if(initialize) {
val initializedValueDescriptor = factory.prepareSingleVariableDescriptorForNewLocalVariable(xtumlType, localVariableName, initialize);
// FIXME this should be changed to properly find the generated unique variable name
var SingleVariableDescriptor uninitializedValueDescriptor
if(initializedValueDescriptor.stringRepresentation.startsWith(initializedValueDescriptor.pointerRepresentation)){
uninitializedValueDescriptor = factory.prepareSingleVariableDescriptorForExistingVariable(xtumlType, initializedValueDescriptor.pointerRepresentation);
} else {
uninitializedValueDescriptor = factory.prepareSingleVariableDescriptorForExistingVariable(xtumlType, initializedValueDescriptor.valueRepresentation);
}
uninitializedValueDescriptor.cache(localVariableName)
return initializedValueDescriptor
} else {
return factory.prepareSingleVariableDescriptorForNewLocalVariable(xtumlType, localVariableName, initialize).cache(localVariableName)
}
}

/**
Expand All @@ -121,7 +134,7 @@ class UmlValueDescriptorFactory implements IUmlDescriptorFactory, IDescriptorCac
* @return The SingleVariableDescriptor with the resolved <code>signal</code> based on implementation
* and with unique name based on <code>localVariableName</code>
*/
dispatch def prepareSingleVariableDescriptorForNewLocalVariable(Signal signal, String localVariableName) {
dispatch def prepareSingleVariableDescriptorForNewLocalVariable(Signal signal, String localVariableName, boolean initialize) {
val xtumlSignal = mapper.convertSignal(signal)
return factory.prepareSingleVariableDescriptorForNewLocalVariable(xtumlSignal, localVariableName).cache(localVariableName)
}
Expand All @@ -130,17 +143,17 @@ class UmlValueDescriptorFactory implements IUmlDescriptorFactory, IDescriptorCac
* @return The SingleVariableDescriptor with the resolved type based on implementation and
* with unique name
*/
dispatch def prepareSingleVariableDescriptorForNewLocalVariable(Type type) {
dispatch def prepareSingleVariableDescriptorForNewLocalVariable(Type type, boolean initialize) {
val xtumlType = mapper.convertType(type)
val descriptor = factory.prepareSingleVariableDescriptorForNewLocalVariable(xtumlType)
val descriptor = factory.prepareSingleVariableDescriptorForNewLocalVariable(xtumlType, initialize)
return descriptor.cache(descriptor.stringRepresentation)
}

/**
* @return The SingleVariableDescriptor with the resolved signal based on implementation and
* with unique name
*/
dispatch def prepareSingleVariableDescriptorForNewLocalVariable(Signal signal) {
dispatch def prepareSingleVariableDescriptorForNewLocalVariable(Signal signal, boolean initialize) {
val xtumlEvent = mapper.convertSignal(signal)
val descriptor = factory.prepareSingleVariableDescriptorForNewLocalVariable(xtumlEvent)
return descriptor.cache(descriptor.stringRepresentation)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ class XtumlValueDescriptorFactory {
* @return The SingleVariableDescriptor with the resolved <code>type</code> based on implementation
* and with unique name based on <code>localVariableName</code>
*/
def prepareSingleVariableDescriptorForNewLocalVariable(Type type, String localVariableName) {
def prepareSingleVariableDescriptorForNewLocalVariable(Type type, String localVariableName, boolean initialize) {
checkArgument(type!=null, "Type cannot be null")
val ooplType = mapper.convertType(type)
return factory.prepareSingleVariableDescriptorForNewLocalVariable(ooplType, localVariableName)
return factory.prepareSingleVariableDescriptorForNewLocalVariable(ooplType, localVariableName, initialize)
}

/**
Expand All @@ -76,10 +76,10 @@ class XtumlValueDescriptorFactory {
* @return The SingleVariableDescriptor with the resolved <code>type</code> based on implementation
* and with unique name
*/
dispatch def prepareSingleVariableDescriptorForNewLocalVariable(Type type) {
def prepareSingleVariableDescriptorForNewLocalVariable(Type type, boolean initialize) {
checkArgument(type!=null, "Type cannot be null")
val ooplType = mapper.convertType(type)
return factory.prepareSingleVariableDescriptorForNewLocalVariable(ooplType)
return factory.prepareSingleVariableDescriptorForNewLocalVariable(ooplType, initialize)
}

/**
Expand All @@ -88,7 +88,7 @@ class XtumlValueDescriptorFactory {
* @return The SingleVariableDescriptor with the resolved <code>type</code> based on implementation
* and with unique name
*/
dispatch def prepareSingleVariableDescriptorForNewLocalVariable(XTEvent type) {
def prepareSingleVariableDescriptorForNewLocalVariable(XTEvent type) {
checkArgument(type!=null, "Type cannot be null")
val ooplEvent = mapper.convertEvent(type)
return factory.prepareSingleVariableDescriptorForNewLocalVariable(ooplEvent)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
xmlns:oopl="http://www.ericsson.com/xtumlrt/oopl">
<cpp:CPPPackage>
<subElements
xsi:type="cpp:CPPBasicType">
xsi:type="cpp:CPPBasicType" defaultValue="false">
<commonType
xsi:type="common:PrimitiveType"
href="../../../plugin/org.eclipse.papyrusrt.xtumlrt.common.model/model/umlPrimitiveTypes.common#//@packages.0/@typeDefinitions.0/@type"/>
Expand All @@ -16,7 +16,7 @@
name="bool"/>
</subElements>
<subElements
xsi:type="cpp:CPPBasicType">
xsi:type="cpp:CPPBasicType" defaultValue="0l">
<commonType
xsi:type="common:PrimitiveType"
href="../../../plugin/org.eclipse.papyrusrt.xtumlrt.common.model/model/umlPrimitiveTypes.common#//@packages.0/@typeDefinitions.1/@type"/>
Expand All @@ -25,7 +25,7 @@
name="long"/>
</subElements>
<subElements
xsi:type="cpp:CPPBasicType">
xsi:type="cpp:CPPBasicType" defaultValue="0.0">
<commonType
xsi:type="common:PrimitiveType"
href="../../../plugin/org.eclipse.papyrusrt.xtumlrt.common.model/model/umlPrimitiveTypes.common#//@packages.0/@typeDefinitions.2/@type"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ class SnippetTemplateCompilerUtil {
(descriptorFactory.createSingleVariableDescriptorBuilder => [
name = st.variable.name
type = typeSystem.type(st.variable).value.umlType
// if the statement has no expression, then initialization is also needed
initialize = (st.expression == null)
]).build
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ class StatementVisitor {
if(st.expression instanceof InstanceCreationExpression && (st.expression as InstanceCreationExpression).instance instanceof Signal){
'''«descriptor.fullType» «descriptor.stringRepresentation» = «expressionsnippet»;'''+StringConcatenation.DEFAULT_LINE_DELIMITER+builder.toString
}else{
builder.append('''«descriptor.fullType» «descriptor.stringRepresentation»«IF st.expression != null» = «ELSEIF typeSystem.type(st.variable).value.umlType instanceof org.eclipse.uml2.uml.Class» = nullptr«ENDIF»«expressionsnippet»;''')
builder.append('''«descriptor.fullType» «descriptor.stringRepresentation»«IF st.expression != null» = «ENDIF»«expressionsnippet»;''')
builder.toString
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,29 @@ class OperationConvertingTest extends AbstractSingleConversionTest{
"model::Comp::Pong::sendPing",
ConversionType.Operation,
'''
Boolean b;
b = true;
send new ping_s() to this->ping.one();
''',
'''
::model::Comp::Ping* __ralf__0__Ping = ::xumlrt::select_any(this->R1_ping);
::model::Comp::Pong::ping_s_event* __ralf__1__ping_s = new ::model::Comp::Pong::ping_s_event(false);
bool __ralf__0__b = false;
__ralf__0__b = true;
::model::Comp::Ping* __ralf__1__Ping = ::xumlrt::select_any(this->R1_ping);
::model::Comp::Pong::ping_s_event* __ralf__2__ping_s = new ::model::Comp::Pong::ping_s_event(false);
__ralf__0__Ping->generate_event(__ralf__1__ping_s);'''
__ralf__1__Ping->generate_event(__ralf__2__ping_s);'''
],
#[ "Instances expression test",
"/com.incquerylabs.emdw.cpp.bodyconverter.test/models/PingPongSpecial/model.uml",
"model::Comp::Pong::sendPing",
ConversionType.Operation,
'''
Pong::instances();
Pong p;
p = Pong::instances().one();
''',
'''
::xumlrt::select_many(::model::Comp::Pong::_instances);'''
::model::Comp::Pong* __ralf__0__p = nullptr;
__ralf__0__p = ::xumlrt::select_any(::model::Comp::Pong::_instances);'''
],
#[ "Cast expression test",
"/com.incquerylabs.emdw.cpp.bodyconverter.test/models/PingPongSpecial/model.uml",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class AttributeMappingTest extends TransformationTest<State, CPPClass> {
override protected assertResult(CPPModel result, CPPClass cppObject) {
val files = cppCodeGeneration.generatedCPPSourceFiles
val classHeader = files.get(cppObject.headerFile).toString
assertTrue(classHeader.contains("bool myBool;"))
assertTrue(classHeader.contains("bool myBool = false;"))
assertTrue(classHeader.contains("set< bool > myBools;"))

}
Expand Down
Loading

0 comments on commit 4bd36ce

Please sign in to comment.