Skip to content

Commit

Permalink
fix: Worked hard on getting the conditions for typeSwitches strongly …
Browse files Browse the repository at this point in the history
…typed. (WIP ... currently all Java modules work, C and Go still need some polishing)
  • Loading branch information
chrisdutz committed Nov 26, 2021
1 parent 7e289bd commit b99a88a
Show file tree
Hide file tree
Showing 19 changed files with 313 additions and 254 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -784,8 +784,9 @@ private Optional<TypeReference> getDiscriminatorType(TypeReference typeReference
// If we found something but there's a "rest" left, we got to use the type we
// found in this level, get that type's definition and continue from there.
if (!variableLiteral.getChild().isPresent()) {
return Optional.empty();
return Optional.of(typeReference);
}
// If we're accessing a child, then the root must be a complex type.
if (!(typeReference instanceof ComplexTypeReference)) {
return Optional.empty();
}
Expand Down Expand Up @@ -841,7 +842,7 @@ public Map<String, TypeReference> getDiscriminatorTypes() {
Function<String, TypeReference> typeRefRetriever = null;
if (thisType instanceof DiscriminatedComplexTypeDefinition) {
switchField = ((ComplexTypeDefinition) thisType.getParentType()).getSwitchField().orElse(null);
typeRefRetriever = propertyName -> getTypeReferenceForProperty((ComplexTypeDefinition) thisType, propertyName).orElse(null);
typeRefRetriever = propertyName -> getTypeReferenceForProperty((ComplexTypeDefinition) thisType.getParentType(), propertyName).orElse(null);
} else if (thisType instanceof ComplexTypeDefinition) {
switchField = ((ComplexTypeDefinition) thisType).getSwitchField().orElse(null);
typeRefRetriever = propertyName -> getTypeReferenceForProperty((ComplexTypeDefinition) thisType, propertyName).orElse(null);
Expand All @@ -864,7 +865,8 @@ public Map<String, TypeReference> getDiscriminatorTypes() {
for (VariableLiteral variableLiteral : switchField.getDiscriminatorExpressions()) {
// Get some symbolic name we can use.
String discriminatorName = variableLiteral.getDiscriminatorName();
Optional<TypeReference> discriminatorType = getDiscriminatorType(typeRefRetriever.apply(variableLiteral.getName()), variableLiteral);
final TypeReference typeReference = typeRefRetriever.apply(variableLiteral.getName());
Optional<TypeReference> discriminatorType = getDiscriminatorType(typeReference, variableLiteral);
discriminatorTypes.put(discriminatorName, discriminatorType.orElse(null));
}
return discriminatorTypes;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -381,9 +381,9 @@ plc4c_return_code ${helper.getCTypeName(type.name)}_parse(plc4c_spi_read_buffer*
<#if indentContent> </#if> // Switch Field (Depending on the discriminator values, passes the instantiation to a sub-type)
<#list switchField.cases as case>
<#if !helper.isComplexTypeReference(helper.getDiscriminatorTypes()[field.discriminatorExpressions[0].name])>
<#if indentContent> </#if> <#if case.discriminatorValues?has_content>if(<#list case.discriminatorValues as discriminatorValue><#if case.discriminatorValues?size &gt; 1>(</#if>${helper.toVariableParseExpression(baseType, switchField, switchField.discriminatorExpressions[discriminatorValue?index].asLiteral().orElseThrow().asVariableLiteral().orElseThrow(), parserArguments)} == ${discriminatorValue}<#if case.discriminatorValues?size &gt; 1>)</#if><#sep> && </#sep></#list>) </#if>{ /* ${case.name} */
<#if indentContent> </#if> <#if case.discriminatorValueTerms?has_content>if(<#list case.discriminatorValueTerms as discriminatorValueTerm><#if case.discriminatorValueTerms?size &gt; 1>(</#if>${helper.toVariableParseExpression(baseType, switchField, switchField.discriminatorExpressions[discriminatorValueTerm?index].asLiteral().orElseThrow().asVariableLiteral().orElseThrow(), parserArguments)} == ${discriminatorValueTerm}<#if case.discriminatorValueTerms?size &gt; 1>)</#if><#sep> && </#sep></#list>) </#if>{ /* ${case.name} */
<#else>
<#if indentContent> </#if> <#if case.discriminatorValues?has_content>if(<#list case.discriminatorValues as discriminatorValue><#if case.discriminatorValues?size &gt; 1>(</#if>${helper.toVariableParseExpression(baseType, switchField, switchField.discriminatorExpressions[discriminatorValue?index].asLiteral().orElseThrow().asVariableLiteral().orElseThrow(), parserArguments)} == ${helper.getLanguageTypeNameForTypeReference(helper.getDiscriminatorTypes()[field.discriminatorExpressions[discriminatorValue?index].name])}_${discriminatorValue}<#if case.discriminatorValues?size &gt; 1>)</#if><#sep> && </#sep></#list>) </#if>{ /* ${case.name} */
<#if indentContent> </#if> <#if case.discriminatorValueTerms?has_content>if(<#list case.discriminatorValueTerms as discriminatorValueTerm><#if case.discriminatorValueTerms?size &gt; 1>(</#if>${helper.toVariableParseExpression(baseType, switchField, switchField.discriminatorExpressions[discriminatorValueTerm?index].asLiteral().orElseThrow().asVariableLiteral().orElseThrow(), parserArguments)} == ${helper.getLanguageTypeNameForTypeReference(helper.getDiscriminatorTypes()[field.discriminatorExpressions[discriminatorValueTerm?index].name])}_${discriminatorValueTerm}<#if case.discriminatorValueTerms?size &gt; 1>)</#if><#sep> && </#sep></#list>) </#if>{ /* ${case.name} */
</#if>
<#if baseType.isDiscriminatedChildTypeDefinition()>
<#assign discriminatedChildType = type.asDiscriminatedComplexTypeDefinition().orElseThrow()>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -615,7 +615,24 @@ private String toLiteralTermExpression(Field field, TypeReference resultType, Li
return tracer + Boolean.toString(((BooleanLiteral) literal).getValue());
} else if (literal instanceof NumericLiteral) {
tracer = tracer.dive("numeric literal instanceOf");
return tracer + ((NumericLiteral) literal).getNumber().toString();
final String numberString = ((NumericLiteral) literal).getNumber().toString();
if(resultType.isIntegerTypeReference()) {
final IntegerTypeReference integerTypeReference = resultType.asIntegerTypeReference().orElseThrow(RuntimeException::new);
if(integerTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.UINT && integerTypeReference.getSizeInBits() >= 32) {
tracer = tracer.dive("uint >= 32bit");
return tracer + numberString + "L";
} else if(integerTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.INT && integerTypeReference.getSizeInBits() > 32) {
tracer = tracer.dive("int > 32bit");
return tracer + numberString + "L";
}
} else if(resultType.isFloatTypeReference()) {
final FloatTypeReference floatTypeReference = resultType.asFloatTypeReference().orElseThrow(RuntimeException::new);
if(floatTypeReference.getSizeInBits() < 32) {
tracer = tracer.dive("float < 32bit");
return tracer + numberString + "F";
}
}
return tracer + numberString;
} else if (literal instanceof HexadecimalLiteral) {
tracer = tracer.dive("hexadecimal literal instanceOf");
final String hexString = ((HexadecimalLiteral) literal).getHexString();
Expand All @@ -625,7 +642,7 @@ private String toLiteralTermExpression(Field field, TypeReference resultType, Li
tracer = tracer.dive("uint >= 32bit");
return tracer + hexString + "L";
} else if(integerTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.INT && integerTypeReference.getSizeInBits() > 32) {
tracer = tracer.dive("uint > 32bit");
tracer = tracer.dive("int > 32bit");
return tracer + hexString + "L";
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,20 @@ public class ${type.name}IO {
if(
<#list case.discriminatorValueTerms as discriminatorValueTerm>
<#assign discriminatorExpression=dataIoTypeDefinition.switchField.discriminatorExpressions[discriminatorValueTerm?index].asLiteral().orElseThrow().asVariableLiteral().orElseThrow()>
<#assign typeRef=helper.getDiscriminatorTypes()[discriminatorExpression.name]>
<#assign discriminatorType=helper.getDiscriminatorTypes()[discriminatorExpression.name]>
EvaluationHelper.equals(
${helper.toParseExpression(dataIoTypeDefinition.switchField, typeRef, discriminatorExpression, parserArguments)},
${helper.toParseExpression(dataIoTypeDefinition.switchField, typeRef, discriminatorValueTerm, parserArguments)}
)
${helper.toParseExpression(dataIoTypeDefinition.switchField, discriminatorType, discriminatorExpression, parserArguments)},
<#if helper.isEnumTypeReference(discriminatorType)>
${helper.getLanguageTypeNameForTypeReference(discriminatorType)}.${helper.toParseExpression(dataIoTypeDefinition.switchField, discriminatorType, discriminatorValueTerm, parserArguments)}
<#else>
${helper.toParseExpression(dataIoTypeDefinition.switchField, discriminatorType, discriminatorValueTerm, parserArguments)}
</#if>
)
<#sep> && </#sep>
</#list>
) {
)
<#else>
<#assign defaultCaseOutput=true>
</#if>
</@compress> { // ${case.name}
<#assign valueDefined=false>
Expand Down Expand Up @@ -330,7 +336,28 @@ public class ${type.name}IO {
public static WriteBufferByteBased staticSerialize(PlcValue _value<#if type.parserArguments.isPresent()>, <#list type.parserArguments.orElseThrow() as parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type, false)} ${parserArgument.name}<#sep>, </#sep></#list></#if>, ByteOrder byteOrder) throws SerializationException {
<#assign defaultCaseOutput=false>
<#assign dataIoTypeDefinition=type.asDataIoTypeDefinition().orElseThrow()>
<#list dataIoTypeDefinition.switchField.cases as case><#if case.discriminatorValues?has_content>if(<#list case.discriminatorValues as discriminatorValue>EvaluationHelper.equals(${helper.toParseExpression(null, helper.anyTypeReference, dataIoTypeDefinition.switchField.discriminatorExpressions[discriminatorValue?index], type.parserArguments.orElseThrow())},<#if helper.isComplexTypeReference(dataIoTypeDefinition.parserArguments.orElseThrow()[discriminatorValue?index].type)><#if helper.isEnumTypeReference(dataIoTypeDefinition.parserArguments.orElseThrow()[discriminatorValue?index].type)>${helper.getLanguageTypeNameForTypeReference(dataIoTypeDefinition.parserArguments.orElseThrow()[discriminatorValue?index].type, false)}.${discriminatorValue}<#else>${discriminatorValue}</#if><#else>${discriminatorValue}</#if>)<#sep> && </#sep></#list>) <#else><#assign defaultCaseOutput=true></#if>{ // ${case.name}
<#list dataIoTypeDefinition.switchField.cases as case>
<@compress single_line=true>
<#if case.discriminatorValueTerms?has_content>
if(
<#list case.discriminatorValueTerms as discriminatorValueTerm>
<#assign discriminatorExpression=dataIoTypeDefinition.switchField.discriminatorExpressions[discriminatorValueTerm?index].asLiteral().orElseThrow().asVariableLiteral().orElseThrow()>
<#assign discriminatorType=helper.getDiscriminatorTypes()[discriminatorExpression.name]>
EvaluationHelper.equals(
${helper.toParseExpression(dataIoTypeDefinition.switchField, discriminatorType, discriminatorExpression, parserArguments)},
<#if helper.isEnumTypeReference(discriminatorType)>
${helper.getLanguageTypeNameForTypeReference(discriminatorType)}.${helper.toParseExpression(dataIoTypeDefinition.switchField, discriminatorType, discriminatorValueTerm, parserArguments)}
<#else>
${helper.toParseExpression(dataIoTypeDefinition.switchField, discriminatorType, discriminatorValueTerm, parserArguments)}
</#if>
)
<#sep> && </#sep>
</#list>
)
<#else>
<#assign defaultCaseOutput=true>
</#if>
</@compress> { // ${case.name}
WriteBufferByteBased writeBuffer = new WriteBufferByteBased((int) Math.ceil(((float) ${helper.getSizeInBits(case,parserArguments)}) / 8.0f), byteOrder);

<#list case.fields as field>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,10 +244,14 @@ public class ${type.name}IO implements MessageInput<${type.name}> {
if(
<#list case.discriminatorValueTerms as discriminatorValueTerm>
<#assign discriminatorExpression=switchField.discriminatorExpressions[discriminatorValueTerm?index].asLiteral().orElseThrow().asVariableLiteral().orElseThrow()>
<#assign typeRef=helper.getDiscriminatorTypes()[discriminatorExpression.name]>
<#assign discriminatorType=helper.getDiscriminatorTypes()[discriminatorExpression.discriminatorName]>
EvaluationHelper.equals(
${helper.toParseExpression(switchField, typeRef, discriminatorExpression, parserArguments)},
${helper.toParseExpression(switchField, typeRef, discriminatorValueTerm, parserArguments)}
${helper.toParseExpression(switchField, discriminatorType, discriminatorExpression, parserArguments)},
<#if helper.isEnumTypeReference(discriminatorType)>
${helper.getLanguageTypeNameForTypeReference(discriminatorType)}.${helper.toParseExpression(switchField, discriminatorType, discriminatorValueTerm, parserArguments)}
<#else>
${helper.toParseExpression(switchField, discriminatorType, discriminatorValueTerm, parserArguments)}
</#if>
)
<#sep> && </#sep>
</#list>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,18 @@ public<#if type.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${ty
// Accessors for discriminator values.
<#list discriminatedChildType.getDiscriminatorMap() as discriminatorName, discriminatorValue>
<#-- If the discriminator name matches that of another field, suppress the methods generation -->
<#if !discriminatedChildType.isNonDiscriminatorField(discriminatorName)>
public ${helper.getLanguageTypeNameForTypeReference(helper.getDiscriminatorTypes()[discriminatorName])} get${discriminatorName?cap_first}() {
return ${helper.toParseExpression(null, helper.getDiscriminatorTypes()[discriminatorName], discriminatorValue, parserArguments)};
<#if !discriminatedChildType.isNonDiscriminatorField(discriminatorName)><#--&& !discriminatedChildType.isParserArgument(discriminatorName)-->
<#assign discriminatorType = helper.getDiscriminatorTypes()[discriminatorName]>
public ${helper.getLanguageTypeNameForTypeReference(discriminatorType)} get${discriminatorName?cap_first}() {
<#if discriminatorValue??>
<#if helper.isEnumTypeReference(discriminatorType)>
return ${helper.getLanguageTypeNameForTypeReference(discriminatorType)}.${helper.toParseExpression(null, discriminatorType, discriminatorValue, parserArguments)};
<#else>
return ${helper.toParseExpression(null, discriminatorType, discriminatorValue, parserArguments)};
</#if>
<#else>
return ${helper.getNullValueForTypeReference(discriminatorType)};
</#if>
}
</#if>
</#list>
Expand All @@ -97,7 +106,7 @@ public<#if type.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${ty
// Abstract accessors for discriminator values.
<#list helper.discriminatorTypes as discriminatorName, discriminatorType>
<#-- If the discriminator name matches that of another field, suppress the methods generation -->
<#if !type.isNonDiscriminatorField(discriminatorName)>
<#if !type.isNonDiscriminatorField(discriminatorName)><#-- && !type.isParserArgument(discriminatorName)-->
public abstract ${helper.getLanguageTypeNameForTypeReference(discriminatorType)} get${discriminatorName?cap_first}();
</#if>
</#list>
Expand Down
Loading

0 comments on commit b99a88a

Please sign in to comment.