Skip to content

Commit

Permalink
JNG-4181 Fix astype (#108)
Browse files Browse the repository at this point in the history
* JNG-4184 Initial feature commit

* JNG-4184 Optimization and error-free trivial casting

* JNG-4184 typeof fix

* JNG-4184 [Release] Updating versions
  • Loading branch information
bencegelei authored Nov 9, 2022
1 parent 8acd0df commit 659d33e
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@
public class JqlTransformers<NE, P extends NE, E extends P, C extends NE, PTE, RTE, TO extends NE, TA, TR, S, M, U>
implements ExpressionTransformer, ExpressionMeasureProvider {

public static final String CAST_FUNCTION_INVALID_TYPES = "Invalid %s function call: %s cannot be casted to %s";
public static final String INVALID_CONTAINER_TYPE = "%s type is not a container type of %s";

private final JqlExpressionBuilder<NE, P, E, C, PTE, RTE, TO, TA, TR, S, M, U> expressionBuilder;
private final Map<Class<? extends JqlExpression>, JqlExpressionTransformerFunction> transformers = new LinkedHashMap<>();
private final Map<String, JqlFunctionTransformer> functionTransformers = new LinkedHashMap<>();
Expand All @@ -92,79 +95,134 @@ public JqlTransformers(JqlExpressionBuilder<NE, P, E, C, PTE, RTE, TO, TA, TR, S
private void objectFunctions() {
functionTransformers.put("isundefined", new JqlIsDefinedFunctionTransformer(this, false));
functionTransformers.put("isdefined", new JqlIsDefinedFunctionTransformer(this, true));

functionTransformers.put(
"kindof",
new JqlParameterizedFunctionTransformer<ObjectExpression, QualifiedName, InstanceOfExpression>(
this,
(expression, parameter) -> newInstanceOfExpressionBuilder()
.withObjectExpression(expression)
.withElementName(getKindOfParameterTypeName(expression, parameter))
.build(),
jqlExpression -> ((NavigationExpression) jqlExpression).getQName()));
functionTransformers.put(
"typeof",
new JqlParameterizedFunctionTransformer<ObjectExpression, QualifiedName, TypeOfExpression>(
this,
(expression, parameter) -> newTypeOfExpressionBuilder()
functionTransformers.put("kindof", getKindOfTransformer());
functionTransformers.put("typeof", getTypeOfTransformer());
functionTransformers.put("astype", getAsTypeTransformer());
functionTransformers.put("container", getContainerTransformer());
}

private JqlParameterizedFunctionTransformer<ObjectExpression, QualifiedName, LogicalExpression> getKindOfTransformer() {
return new JqlParameterizedFunctionTransformer<>(
this,
(expression, parameter) -> {
Optional<TypeName> typeName = getKindOfTypeName(expression, parameter);
if (typeName.isPresent()) {
return newInstanceOfExpressionBuilder()
.withObjectExpression(expression)
.withElementName(getTypeOfParameterTypeName(expression, parameter))
.build(),
jqlExpression -> ((NavigationExpression) jqlExpression).getQName()));
functionTransformers.put(
"astype",
new JqlParameterizedFunctionTransformer<ObjectExpression, QualifiedName, CastObject>(
this,
(expression, parameter) -> newCastObjectBuilder()
.withElementName(typeName.get())
.build();
} else {
return newBooleanConstantBuilder().withValue(true).build();
}
},
jqlExpression -> ((NavigationExpression) jqlExpression).getQName());
}

private JqlParameterizedFunctionTransformer<ObjectExpression, QualifiedName, LogicalExpression> getTypeOfTransformer() {
return new JqlParameterizedFunctionTransformer<>(
this,
(expression, parameter) -> {
Optional<TypeName> typeName = getTypeOfTypeName(expression, parameter);
if (typeName.isPresent()) {
return newTypeOfExpressionBuilder()
.withObjectExpression(expression)
.withElementName(getAsTypeTypeName(expression, parameter))
.build(),
jqlExpression -> ((NavigationExpression) jqlExpression).getQName()));
functionTransformers.put(
"container",
new JqlParameterizedFunctionTransformer<ObjectExpression, QualifiedName, ContainerExpression>(
this,
(expression, parameter) -> newContainerExpressionBuilder()
.withElementName(typeName.get())
.build();
} else {
return newBooleanConstantBuilder().withValue(false).build();
}
},
jqlExpression -> ((NavigationExpression) jqlExpression).getQName());
}

private JqlParameterizedFunctionTransformer<ObjectExpression, QualifiedName, ObjectExpression> getAsTypeTransformer() {
return new JqlParameterizedFunctionTransformer<>(
this,
(expression, parameter) -> {
Optional<TypeName> typeName = getAsTypeTypeName(expression, parameter);
if (typeName.isPresent()) {
return newCastObjectBuilder()
.withObjectExpression(expression)
.withElementName(getContainerTypeName(expression, parameter))
.build(),
jqlExpression -> ((NavigationExpression) jqlExpression).getQName()));
.withElementName(typeName.get())
.build();
} else {
return expression;
}
},
jqlExpression -> ((NavigationExpression) jqlExpression).getQName());
}

private TypeName getKindOfParameterTypeName(ObjectExpression expression, QualifiedName parameter) {
return getParameterTypeName(expression, parameter, true);
private JqlParameterizedFunctionTransformer<ObjectExpression, QualifiedName, ContainerExpression> getContainerTransformer() {
return new JqlParameterizedFunctionTransformer<>(
this,
(expression, parameter) -> newContainerExpressionBuilder()
.withObjectExpression(expression)
.withElementName(getContainerTypeName(expression, parameter))
.build(),
jqlExpression -> ((NavigationExpression) jqlExpression).getQName());
}

private TypeName getTypeOfParameterTypeName(ObjectExpression expression, QualifiedName parameter) {
return getParameterTypeName(expression, parameter, false);
private Optional<TypeName> getKindOfTypeName(ObjectExpression expression, QualifiedName parameter) {
TypeName typeNameFromResource = getTypeNameOf(parameter, () -> expressionBuilder.getTypeNameFromResource(parameter));

C objectType = (C) expression.getObjectType(getModelAdapter());
C parameterType = (C) getModelAdapter().get(typeNameFromResource).orElseThrow();

Collection<?> objectSuperTypes = getModelAdapter().getSuperTypes(objectType);
if (parameterType.equals(objectType) || objectSuperTypes.contains(parameterType)) {
return Optional.empty(); // trivial
}

Collection<?> parameterSuperTypes = getModelAdapter().getSuperTypes(parameterType);
if (!parameterSuperTypes.contains(objectType)) {
String objectFqName = getModelAdapter().getFqName(objectType);
String parameterFqName = getModelAdapter().getFqName(parameterType);
throw new IllegalArgumentException(String.format(CAST_FUNCTION_INVALID_TYPES, "kindof", objectFqName, parameterFqName));
}

return Optional.of(typeNameFromResource);
}

private TypeName getParameterTypeName(ObjectExpression expression, QualifiedName parameter, boolean kindOf) {
private Optional<TypeName> getTypeOfTypeName(ObjectExpression expression, QualifiedName parameter) {
TypeName typeNameFromResource = getTypeNameOf(parameter, () -> expressionBuilder.getTypeNameFromResource(parameter));

C objectType = (C) expression.getObjectType(getModelAdapter());
C parameterType = (C) getModelAdapter().get(typeNameFromResource).get();
if (!(getModelAdapter().getSuperTypes(parameterType).contains(objectType) || objectType.equals(parameterType))) {
String objectName = getModelAdapter().getName(objectType).orElse(objectType.toString());
String parameterName = getModelAdapter().getName(parameterType).orElse(parameterType.toString());
throw new IllegalArgumentException("Element type " + parameterName + " is not " + (kindOf ? "compatible with " : "") + objectName);
C parameterType = (C) getModelAdapter().get(typeNameFromResource).orElseThrow();

Collection<?> objectSuperTypes = getModelAdapter().getSuperTypes(objectType);
if (objectSuperTypes.contains(parameterType)) {
return Optional.empty(); // trivial
}

return typeNameFromResource;
Collection<?> parameterSuperTypes = getModelAdapter().getSuperTypes(parameterType);
if (!(parameterSuperTypes.contains(objectType) || parameterType.equals(objectType))) {
String objectFqName = getModelAdapter().getFqName(objectType);
String parameterFqName = getModelAdapter().getFqName(parameterType);
throw new IllegalArgumentException(String.format(CAST_FUNCTION_INVALID_TYPES, "typeof", objectFqName, parameterFqName));
}

return Optional.of(typeNameFromResource);
}

private TypeName getAsTypeTypeName(ObjectExpression expression, QualifiedName parameter) {
private Optional<TypeName> getAsTypeTypeName(ObjectExpression expression, QualifiedName parameter) {
TypeName typeNameFromResource = getTypeNameOf(parameter, () -> expressionBuilder.getTypeNameFromResource(parameter));

C objectType = (C) expression.getObjectType(getModelAdapter());
C parameterType = (C) getModelAdapter().get(typeNameFromResource).get();
if (!getModelAdapter().getSuperTypes(parameterType).contains(objectType)) {
String objectName = getModelAdapter().getName(objectType).orElse(objectType.toString());
String parameterName = getModelAdapter().getName(parameterType).orElse(parameterType.toString());
throw new IllegalArgumentException("Invalid casting type: " + objectName + " is not supertype of " + parameterName);
C parameterType = (C) getModelAdapter().get(typeNameFromResource).orElseThrow();

Collection<?> objectSuperTypes = getModelAdapter().getSuperTypes(objectType);
if (parameterType.equals(objectType) || objectSuperTypes.contains(parameterType)) {
return Optional.empty(); // trivial
}

return typeNameFromResource;
Collection<?> parameterSuperTypes = getModelAdapter().getSuperTypes(parameterType);
if (!parameterSuperTypes.contains(objectType)) {
String objectFqName = getModelAdapter().getFqName(objectType);
String parameterFqName = getModelAdapter().getFqName(parameterType);
throw new IllegalArgumentException(String.format(CAST_FUNCTION_INVALID_TYPES, "astype", objectFqName, parameterFqName));
}

return Optional.of(typeNameFromResource);
}

private TypeName getContainerTypeName(ObjectExpression expression, QualifiedName parameter) {
Expand All @@ -173,9 +231,9 @@ private TypeName getContainerTypeName(ObjectExpression expression, QualifiedName
C objectType = (C) expression.getObjectType(getModelAdapter());
C parameterType = (C) getModelAdapter().get(typeNameFromResource).get();
if (!getModelAdapter().getContainerTypesOf(objectType).contains(parameterType)) {
String objectName = getModelAdapter().getName(objectType).orElse(objectType.toString());
String parameterName = getModelAdapter().getName(parameterType).orElse(parameterType.toString());
throw new IllegalArgumentException(parameterName + " type is not a container of " + objectName);
String objectName = getModelAdapter().getFqName(objectType);
String parameterName = getModelAdapter().getFqName(parameterType);
throw new IllegalArgumentException(String.format(INVALID_CONTAINER_TYPE, parameterName, objectName));
}

return typeNameFromResource;
Expand Down Expand Up @@ -251,12 +309,19 @@ private void collectionFunctions() {
}));
functionTransformers.put(
"ascollection",
new JqlParameterizedFunctionTransformer<CollectionExpression, QualifiedName, CastCollection>(
new JqlParameterizedFunctionTransformer<CollectionExpression, QualifiedName, CollectionExpression>(
this,
(expression, parameter) -> newCastCollectionBuilder()
.withElementName(getAsCollectionTypeName(expression, parameter))
.withCollectionExpression(expression)
.build(),
(expression, parameter) -> {
Optional<TypeName> typeName = getAsCollectionTypeName(expression, parameter);
if (typeName.isPresent()) {
return newCastCollectionBuilder()
.withElementName(typeName.get())
.withCollectionExpression(expression)
.build();
} else {
return expression;
}
},
jqlExpression -> ((NavigationExpression) jqlExpression).getQName()));
}

Expand All @@ -272,18 +337,25 @@ private void checkContainsOrMemberOfTypeName(IterableExpression expression, Iter
}
}

private TypeName getAsCollectionTypeName(CollectionExpression expression, QualifiedName parameter) {
private Optional<TypeName> getAsCollectionTypeName(CollectionExpression expression, QualifiedName parameter) {
TypeName typeNameFromResource = getTypeNameOf(parameter, () -> expressionBuilder.getTypeNameFromResource(parameter));

C objectType = (C) expression.getObjectType(getModelAdapter());
C parameterType = (C) getModelAdapter().get(typeNameFromResource).get();
if (!getModelAdapter().getSuperTypes(parameterType).contains(objectType)) {
String objectName = getModelAdapter().getName(objectType).orElse(objectType.toString());
String parameterName = getModelAdapter().getName(parameterType).orElse(parameterType.toString());
throw new IllegalArgumentException("Invalid casting: " + objectName + " as " + parameterName + ". " + objectName + " is not supertype of " + parameterName);
C parameterType = (C) getModelAdapter().get(typeNameFromResource).orElseThrow();
Collection<?> objectSuperTypes = getModelAdapter().getSuperTypes(objectType);

String objectFqName = getModelAdapter().getFqName(objectType);
if (parameterType.equals(objectType) || objectSuperTypes.contains(parameterType)) {
return Optional.empty(); // trivial
}

return typeNameFromResource;
Collection<?> parameterSuperTypes = getModelAdapter().getSuperTypes(parameterType);
if (!parameterSuperTypes.contains(objectType)) {
String parameterFqName = getModelAdapter().getFqName(parameterType);
throw new IllegalArgumentException(String.format(CAST_FUNCTION_INVALID_TYPES, "astype", objectFqName, parameterFqName));
}

return Optional.of(typeNameFromResource);
}

@Deprecated
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@
<pax-exam-version>4.13.4</pax-exam-version>

<judo-meta-asm-version>1.1.2</judo-meta-asm-version>
<judo-meta-jql-version>1.0.2</judo-meta-jql-version>
<judo-meta-jql-version>1.0.3.20221027_013031_d715ebc3_develop</judo-meta-jql-version>
<judo-meta-measure-version>1.0.1</judo-meta-measure-version>

<!-- Define overridable properties for tycho-surefire-plugin -->
Expand Down
4 changes: 2 additions & 2 deletions site/category.xml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
<!--
<repository-reference location="https://nexus.judo.technology/repository/p2/judo-epp-common/4.23.1" enabled="true" />
<repository-reference location="https://nexus.judo.technology/repository/p2/epsilon-runtime-eclipse/1.5.3" enabled="true" />
<repository-reference location="https://nexus.judo.technology/repository/p2/judo-meta-measure/1.0.1.20221027_003339_c4dc6832_develop" enabled="true" />
<repository-reference location="https://nexus.judo.technology/repository/p2/judo-meta-jql/1.0.2.20221027_003437_240a9f79_develop" enabled="true" />
<repository-reference location="https://nexus.judo.technology/repository/p2/judo-meta-measure/1.0.1" enabled="true" />
<repository-reference location="https://nexus.judo.technology/repository/p2/judo-meta-jql/1.0.3.20221027_013031_d715ebc3_develop" enabled="true" />
-->
</site>
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<target includeMode="feature" name="hu.blackbelt.judo.meta.expression.targetdefinition.target" sequenceNumber="1664744663152">
<target includeMode="feature" name="hu.blackbelt.judo.meta.expression.targetdefinition.target" sequenceNumber="1667820997747">
<locations>

<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
Expand All @@ -25,11 +25,11 @@
<unit id="hu.blackbelt.epsilon.runtime.feature.feature.group" version="0.0.0"/>
</location>
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
<repository location="https://nexus.judo.technology/repository/p2/judo-meta-measure/1.0.1.20221027_003339_c4dc6832_develop"/>
<repository location="https://nexus.judo.technology/repository/p2/judo-meta-measure/1.0.1"/>
<unit id="hu.blackbelt.judo.meta.measure.feature.feature.group" version="0.0.0"/>
</location>
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
<repository location="https://nexus.judo.technology/repository/p2/judo-meta-jql/1.0.2.20221027_003437_240a9f79_develop"/>
<repository location="https://nexus.judo.technology/repository/p2/judo-meta-jql/1.0.3.20221027_013031_d715ebc3_develop"/>
<unit id="hu.blackbelt.judo.meta.jql.feature.feature.group" version="0.0.0"/>
</location>
</locations>
Expand Down

0 comments on commit 659d33e

Please sign in to comment.