diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/ASTCompilerHelper.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/ASTCompilerHelper.java new file mode 100644 index 00000000000..ab71f360c3c --- /dev/null +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/ASTCompilerHelper.java @@ -0,0 +1,610 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.dmn.feel.codegen.feel11; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; + +import com.github.javaparser.ast.NodeList; +import com.github.javaparser.ast.body.VariableDeclarator; +import com.github.javaparser.ast.expr.BooleanLiteralExpr; +import com.github.javaparser.ast.expr.Expression; +import com.github.javaparser.ast.expr.FieldAccessExpr; +import com.github.javaparser.ast.expr.MethodCallExpr; +import com.github.javaparser.ast.expr.NameExpr; +import com.github.javaparser.ast.expr.NullLiteralExpr; +import com.github.javaparser.ast.expr.ObjectCreationExpr; +import com.github.javaparser.ast.expr.StringLiteralExpr; +import com.github.javaparser.ast.expr.VariableDeclarationExpr; +import com.github.javaparser.ast.stmt.BlockStmt; +import com.github.javaparser.ast.stmt.Statement; +import com.github.javaparser.ast.stmt.ThrowStmt; +import com.github.javaparser.ast.type.ClassOrInterfaceType; +import org.kie.dmn.feel.lang.Type; +import org.kie.dmn.feel.lang.ast.AtLiteralNode; +import org.kie.dmn.feel.lang.ast.BaseNode; +import org.kie.dmn.feel.lang.ast.BetweenNode; +import org.kie.dmn.feel.lang.ast.BooleanNode; +import org.kie.dmn.feel.lang.ast.CTypeNode; +import org.kie.dmn.feel.lang.ast.ContextEntryNode; +import org.kie.dmn.feel.lang.ast.ContextNode; +import org.kie.dmn.feel.lang.ast.ContextTypeNode; +import org.kie.dmn.feel.lang.ast.DashNode; +import org.kie.dmn.feel.lang.ast.FilterExpressionNode; +import org.kie.dmn.feel.lang.ast.ForExpressionNode; +import org.kie.dmn.feel.lang.ast.FormalParameterNode; +import org.kie.dmn.feel.lang.ast.FunctionDefNode; +import org.kie.dmn.feel.lang.ast.FunctionInvocationNode; +import org.kie.dmn.feel.lang.ast.FunctionTypeNode; +import org.kie.dmn.feel.lang.ast.IfExpressionNode; +import org.kie.dmn.feel.lang.ast.InNode; +import org.kie.dmn.feel.lang.ast.InfixOpNode; +import org.kie.dmn.feel.lang.ast.InstanceOfNode; +import org.kie.dmn.feel.lang.ast.IterationContextNode; +import org.kie.dmn.feel.lang.ast.ListNode; +import org.kie.dmn.feel.lang.ast.ListTypeNode; +import org.kie.dmn.feel.lang.ast.NameDefNode; +import org.kie.dmn.feel.lang.ast.NameRefNode; +import org.kie.dmn.feel.lang.ast.NamedParameterNode; +import org.kie.dmn.feel.lang.ast.NullNode; +import org.kie.dmn.feel.lang.ast.NumberNode; +import org.kie.dmn.feel.lang.ast.PathExpressionNode; +import org.kie.dmn.feel.lang.ast.QualifiedNameNode; +import org.kie.dmn.feel.lang.ast.QuantifiedExpressionNode; +import org.kie.dmn.feel.lang.ast.RangeNode; +import org.kie.dmn.feel.lang.ast.SignedUnaryNode; +import org.kie.dmn.feel.lang.ast.StringNode; +import org.kie.dmn.feel.lang.ast.TemporalConstantNode; +import org.kie.dmn.feel.lang.ast.TypeNode; +import org.kie.dmn.feel.lang.ast.UnaryTestListNode; +import org.kie.dmn.feel.lang.ast.UnaryTestNode; +import org.kie.dmn.feel.lang.impl.JavaBackedType; +import org.kie.dmn.feel.lang.impl.MapBackedType; +import org.kie.dmn.feel.lang.types.BuiltInType; +import org.kie.dmn.feel.runtime.FEELFunction; +import org.kie.dmn.feel.util.CodegenUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static com.github.javaparser.StaticJavaParser.parseClassOrInterfaceType; +import static com.github.javaparser.StaticJavaParser.parseExpression; +import static com.github.javaparser.utils.StringEscapeUtils.escapeJava; +import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.ADDFIELD_S; +import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.HASHMAP_CT; +import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.ILLEGALSTATEEXCEPTION_CT; +import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.INSTANCE_S; +import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.MAP_CT; +import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.OF_S; +import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.PUT_S; +import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.VAR_S; +import static org.kie.dmn.feel.codegen.feel11.Constants.BUILTINTYPE_E; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.ATLITERALNODE_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.BETWEENNODE_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.BOOLEANNODE_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.CONTEXTENTRYNODE_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.CONTEXTNODE_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.CONTEXTTYPENODE_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.CTYPENODE_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.DASHNODE_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.DETERMINEOPERATOR_S; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.FILTEREXPRESSIONNODE_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.FOREXPRESSIONNODE_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.FORMALPARAMETERNODE_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.FUNCTIONDEFNODE_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.FUNCTIONINVOCATIONNODE_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.FUNCTIONTYPENODE_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.GETBIGDECIMALORNULL_S; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.IFEXPRESSIONNODE_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.INFIXOPERATOR_N; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.INFIXOPNODE_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.INNODE_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.INSTANCEOFNODE_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.ITERATIONCONTEXTNODE_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.JAVABACKEDTYPE_N; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.LISTNODE_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.LISTTYPENODE_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.MAPBACKEDTYPE_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.NAMEDEFNODE_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.NAMEDPARAMETERNODE_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.NAMEREFNODE_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.NULLNODE_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.NUMBEREVALHELPER_N; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.NUMBERNODE_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.PATHEXPRESSIONNODE_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.QUALIFIEDNAMENODE_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.QUANTIFIEDEXPRESSIONNODE_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.RANGENODE_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.SIGNEDUNARYNODE_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.STRINGNODE_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.TEMPORALCONSTANTNODE_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.TYPE_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.UNARYTESTLISTNODE_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.UNARYTESTNODE_CT; +import static org.kie.dmn.feel.util.CodegenUtils.getEnumExpression; +import static org.kie.dmn.feel.util.CodegenUtils.getListExpression; +import static org.kie.dmn.feel.util.CodegenUtils.getStringLiteralExpr; +import static org.kie.dmn.feel.util.CodegenUtils.getVariableDeclaratorWithFieldAccessExpr; +import static org.kie.dmn.feel.util.CodegenUtils.getVariableDeclaratorWithObjectCreation; + +public class ASTCompilerHelper { + + private static final Logger LOGGER = LoggerFactory.getLogger(ASTCompilerVisitor.class); + private final ASTCompilerVisitor astCompilerVisitor; + private final BlockStmt toPopulate; + private final AtomicInteger variableCounter; + private AtomicReference lastVariableName = new AtomicReference<>(); + private static final String EXTENDED_FUNCTION_PACKAGE = "org.kie.dmn.feel.runtime.functions.extended"; + + public ASTCompilerHelper(ASTCompilerVisitor astCompilerVisitor) { + this.astCompilerVisitor = astCompilerVisitor; + toPopulate = new BlockStmt(); + variableCounter = new AtomicInteger(0); + } + + public BlockStmt add(AtLiteralNode n) { + Expression stringLiteralExpression = getNodeExpression(n.getStringLiteral()); + return addVariableDeclaratorWithObjectCreation(ATLITERALNODE_CT, NodeList.nodeList(stringLiteralExpression), + n.getText()); + } + + public BlockStmt add(BetweenNode n) { + Expression valueExpression = getNodeExpression(n.getValue()); + Expression startExpression = getNodeExpression(n.getStart()); + Expression endExpression = getNodeExpression(n.getEnd()); + return addVariableDeclaratorWithObjectCreation(BETWEENNODE_CT, NodeList.nodeList(valueExpression, + startExpression, + endExpression), n.getText()); + } + + public BlockStmt add(ContextEntryNode n) { + Expression nameExpression = getNodeExpression(n.getName()); + Expression valueExpression = getNodeExpression(n.getValue()); + return addVariableDeclaratorWithObjectCreation(CONTEXTENTRYNODE_CT, NodeList.nodeList(nameExpression, + valueExpression), + n.getText()); + } + + public BlockStmt add(ContextNode n) { + List entryNodesExpressions = n.getEntries().stream().map(entryNode -> getNodeExpression(entryNode)) + .toList(); + return addVariableDeclaratorWithObjectCreation(CONTEXTNODE_CT, + NodeList.nodeList(getListExpression(entryNodesExpressions)), + n.getText()); + } + + public BlockStmt add(ContextTypeNode n) { + Map genExpressions = new HashMap<>(); // THe key is the StringLiteralExpr of the + // original key; the value is the NameExpr pointing at generated variable + for (Map.Entry kv : n.getGen().entrySet()) { + genExpressions.put(new StringLiteralExpr(kv.getKey()), getNodeExpression(kv.getValue())); + } + // Creating the map + String mapVariableName = getNextVariableName(); + final VariableDeclarator mapVariableDeclarator = + new VariableDeclarator(MAP_CT, mapVariableName); + final ObjectCreationExpr objectCreationExpr = new ObjectCreationExpr(null, HASHMAP_CT, NodeList.nodeList()); + mapVariableDeclarator.setInitializer(objectCreationExpr); + VariableDeclarationExpr mapVariableDeclarationExpr = new VariableDeclarationExpr(mapVariableDeclarator); + addExpression(mapVariableDeclarationExpr, mapVariableName); + // Populating the map + Expression mapVariableExpression = new NameExpr(mapVariableName); + genExpressions.forEach((key, value) -> { + MethodCallExpr putExpression = new MethodCallExpr(mapVariableExpression, PUT_S); + putExpression.addArgument(key); + putExpression.addArgument(value); + addExpression(putExpression); + }); + return addVariableDeclaratorWithObjectCreation(CONTEXTTYPENODE_CT, NodeList.nodeList(mapVariableExpression), + n.getText()); + } + + public BlockStmt add(CTypeNode n) { + if (!(n.getType() instanceof BuiltInType)) { + throw new UnsupportedOperationException(); + } + BuiltInType feelCType = (BuiltInType) n.getType(); + Expression typeExpression = new FieldAccessExpr(BUILTINTYPE_E, feelCType.name()); + return addVariableDeclaratorWithObjectCreation(CTYPENODE_CT, NodeList.nodeList(typeExpression), n.getText()); + } + + public BlockStmt add(DashNode n) { + return addVariableDeclaratorWithObjectCreation(DASHNODE_CT, NodeList.nodeList(), n.getText()); + } + + public BlockStmt add(ForExpressionNode n) { + List iterationContextsExpressions = + n.getIterationContexts().stream().map(elementNode -> getNodeExpression(elementNode)) + .toList(); + Expression expressionExpression = getNodeExpression(n.getExpression()); + return addVariableDeclaratorWithObjectCreation(FOREXPRESSIONNODE_CT, + NodeList.nodeList(getListExpression(iterationContextsExpressions), + expressionExpression), + n.getText()); + } + + public BlockStmt add(FilterExpressionNode n) { + Expression expressionExpression = getNodeExpression(n.getExpression()); + Expression filterExpression = getNodeExpression(n.getFilter()); + return addVariableDeclaratorWithObjectCreation(FILTEREXPRESSIONNODE_CT, NodeList.nodeList(expressionExpression, + filterExpression), + n.getText()); + } + + public BlockStmt add(FormalParameterNode n) { + Expression nameExpression = getNodeExpression(n.getName()); + Expression typeExpression = getNodeExpression(n.getType()); + return addVariableDeclaratorWithObjectCreation(FORMALPARAMETERNODE_CT, NodeList.nodeList(nameExpression, + typeExpression), + n.getText()); + } + + public BlockStmt add(FunctionDefNode n) { + List formalParametersExpressions = n.getFormalParameters().stream() + .map(elementNode -> getNodeExpression(elementNode)) + .toList(); + Expression bodyExpression = getNodeExpression(n.getBody()); + return addVariableDeclaratorWithObjectCreation(FUNCTIONDEFNODE_CT, + NodeList.nodeList(getListExpression(formalParametersExpressions), + new BooleanLiteralExpr(n.isExternal()), + bodyExpression), + n.getText()); + } + + public BlockStmt add(FunctionInvocationNode n) { + Expression nameExpression = getNodeExpression(n.getName()); + Expression paramsExpression = getNodeExpression(n.getParams()); + Expression tcFoldedExpression = getNodeExpression(n.getTcFolded()); + return addVariableDeclaratorWithObjectCreation(FUNCTIONINVOCATIONNODE_CT, NodeList.nodeList(nameExpression, + paramsExpression, + tcFoldedExpression), n.getText()); + } + + public BlockStmt add(FunctionTypeNode n) { + List argTypesExpressions = n.getArgTypes().stream().map(argTypeNode -> getNodeExpression(argTypeNode)) + .toList(); + Expression retTypeExpression = getNodeExpression(n.getRetType()); + return addVariableDeclaratorWithObjectCreation(FUNCTIONTYPENODE_CT, + NodeList.nodeList(getListExpression(argTypesExpressions), + retTypeExpression), + n.getText()); + } + + public BlockStmt add(IfExpressionNode n) { + Expression conditionExpression = getNodeExpression(n.getCondition()); + Expression thenExpression = getNodeExpression(n.getThenExpression()); + Expression elseExpression = getNodeExpression(n.getElseExpression()); + return addVariableDeclaratorWithObjectCreation(IFEXPRESSIONNODE_CT, NodeList.nodeList(conditionExpression, + thenExpression, + elseExpression), + n.getText()); + } + + public BlockStmt add(InfixOpNode n) { + Expression determineOperatorExpression = new MethodCallExpr(INFIXOPERATOR_N, DETERMINEOPERATOR_S, + new NodeList<>(new StringLiteralExpr(n.getOperator().getSymbol()))); + Expression leftExpression = getNodeExpression(n.getLeft()); + Expression rightExpression = getNodeExpression(n.getRight()); + return addVariableDeclaratorWithObjectCreation(INFIXOPNODE_CT, NodeList.nodeList(determineOperatorExpression, + leftExpression, + rightExpression), n.getText()); + } + + public BlockStmt add(InNode n) { + Expression valueExpression = getNodeExpression(n.getValue()); + Expression exprsExpression = getNodeExpression(n.getExprs()); + return addVariableDeclaratorWithObjectCreation(INNODE_CT, NodeList.nodeList(valueExpression, exprsExpression) + , n.getText()); + } + + public BlockStmt add(InstanceOfNode n) { + Expression expressionExpression = getNodeExpression(n.getExpression()); + Expression typeExpression = getNodeExpression(n.getType()); + return addVariableDeclaratorWithObjectCreation(INSTANCEOFNODE_CT, NodeList.nodeList(expressionExpression, + typeExpression), + n.getText()); + } + + public BlockStmt add(IterationContextNode n) { + Expression nameExpression = getNodeExpression(n.getName()); + Expression expressionExpression = getNodeExpression(n.getExpression()); + Expression rangeEndExprExpression = getNodeExpression(n.getRangeEndExpr()); + return addVariableDeclaratorWithObjectCreation(ITERATIONCONTEXTNODE_CT, NodeList.nodeList(nameExpression, + expressionExpression, rangeEndExprExpression), n.getText()); + } + + public BlockStmt add(ListNode n) { + List elements = n.getElements().stream().map(elementNode -> getNodeExpression(elementNode)) + .toList(); + return addVariableDeclaratorWithObjectCreation(LISTNODE_CT, NodeList.nodeList(getListExpression(elements)), + n.getText()); + } + + public BlockStmt add(ListTypeNode n) { + Expression genTypeNodeExpression = getNodeExpression(n.getGenTypeNode()); + return addVariableDeclaratorWithObjectCreation(LISTTYPENODE_CT, NodeList.nodeList(genTypeNodeExpression), + n.getText()); + } + + public BlockStmt add(NameDefNode n) { + List partsExpressions = n.getParts().stream().map(StringLiteralExpr::new) + .toList(); + Expression nameExpression = n.getName() != null ? new StringLiteralExpr(n.getName()) : new NullLiteralExpr(); + return addVariableDeclaratorWithObjectCreation(NAMEDEFNODE_CT, + NodeList.nodeList(getListExpression(partsExpressions), + nameExpression), n.getText()); + } + + public BlockStmt add(NamedParameterNode n) { + Expression nameExpression = getNodeExpression(n.getName()); + Expression expressionExpression = getNodeExpression(n.getExpression()); + return addVariableDeclaratorWithObjectCreation(NAMEDPARAMETERNODE_CT, NodeList.nodeList(nameExpression, + expressionExpression) + , n.getText()); + } + + public BlockStmt add(NameRefNode n) { + Expression typeExpression = getTypeExpression(n.getResultType()); + return addVariableDeclaratorWithObjectCreation(NAMEREFNODE_CT, NodeList.nodeList(typeExpression), n.getText()); + } + + public BlockStmt add(NullNode n) { + return addVariableDeclaratorWithObjectCreation(NULLNODE_CT, NodeList.nodeList(), n.getText()); + } + + public BlockStmt add(NumberNode n) { + MethodCallExpr valueExpression = new MethodCallExpr(NUMBEREVALHELPER_N, GETBIGDECIMALORNULL_S, + NodeList.nodeList(new StringLiteralExpr(n.getText()))); + return addVariableDeclaratorWithObjectCreation(NUMBERNODE_CT, NodeList.nodeList(valueExpression), n.getText()); + } + + public BlockStmt add(PathExpressionNode n) { + Expression expressionExpression = getNodeExpression(n.getExpression()); + Expression nameExpression = getNodeExpression(n.getName()); + return addVariableDeclaratorWithObjectCreation(PATHEXPRESSIONNODE_CT, NodeList.nodeList(expressionExpression, + nameExpression), + n.getText()); + } + + public BlockStmt add(QualifiedNameNode n) { + List partsExpressions = n.getParts().stream().map(partNode -> getNodeExpression(partNode)) + .toList(); + Expression typeExpression = getTypeExpression(n.getResultType()); + return addVariableDeclaratorWithObjectCreation(QUALIFIEDNAMENODE_CT, + NodeList.nodeList(getListExpression(partsExpressions), + typeExpression), + n.getText()); + } + + public BlockStmt add(QuantifiedExpressionNode n) { + Expression quantifierExpression = getEnumExpression(n.getQuantifier()); + List iterationContextsExpressions = + n.getIterationContexts().stream().map(iterationContextNode -> getNodeExpression(iterationContextNode)) + .toList(); + Expression expressionExpression = getNodeExpression(n.getExpression()); + return addVariableDeclaratorWithObjectCreation(QUANTIFIEDEXPRESSIONNODE_CT, + NodeList.nodeList(quantifierExpression, + getListExpression(iterationContextsExpressions), + expressionExpression), n.getText()); + } + + public BlockStmt add(RangeNode n) { + Expression lowerBoundExpression = getEnumExpression(n.getLowerBound()); + Expression upperBoundExpression = getEnumExpression(n.getUpperBound()); + Expression startExpression = getNodeExpression(n.getStart()); + Expression endExpression = getNodeExpression(n.getEnd()); + return addVariableDeclaratorWithObjectCreation(RANGENODE_CT, NodeList.nodeList(lowerBoundExpression, + upperBoundExpression, + startExpression, + endExpression), n.getText()); + } + + public BlockStmt add(SignedUnaryNode n) { + Expression signExpression = getEnumExpression(n.getSign()); + Expression expressionExpression = getNodeExpression(n.getExpression()); + return addVariableDeclaratorWithObjectCreation(SIGNEDUNARYNODE_CT, NodeList.nodeList(signExpression, + expressionExpression), + n.getText()); + } + + public BlockStmt add(StringNode n) { + return addVariableDeclaratorWithObjectCreation(STRINGNODE_CT, NodeList.nodeList(), + n.getText()); + } + + public BlockStmt add(TemporalConstantNode n) { + Expression valueExpression = getObjectExpression(n.getValue()); + FEELFunction fn = n.getFn(); + Expression fnVariableNameExpression; + if (fn != null) { + Class fnClass = fn.getClass(); + ClassOrInterfaceType fn_CT = parseClassOrInterfaceType(fnClass.getCanonicalName()); + Expression fn_N = new NameExpr(fnClass.getCanonicalName()); + if (fnClass.getPackageName().equals(EXTENDED_FUNCTION_PACKAGE)) { + addVariableDeclaratorWithWithFieldAccess(fn_CT, INSTANCE_S, fn_N); + } else { + addVariableDeclaratorWithObjectCreation(fn_CT, + NodeList.nodeList()); + } + fnVariableNameExpression = new NameExpr(lastVariableName.get()); + } else { + fnVariableNameExpression = new NullLiteralExpr(); + } + List paramsExpressions = n.getParams().stream().map(param -> getObjectExpression(param)).toList(); + return addVariableDeclaratorWithObjectCreation(TEMPORALCONSTANTNODE_CT, NodeList.nodeList(valueExpression, + fnVariableNameExpression, getListExpression(paramsExpressions)), n.getText()); + } + + public BlockStmt add(UnaryTestListNode n) { + List elementsExpressions = n.getElements().stream().map(elementNode -> getNodeExpression(elementNode)) + .toList(); + Expression stateExpression = getEnumExpression(n.getState()); + return addVariableDeclaratorWithObjectCreation(UNARYTESTLISTNODE_CT, + NodeList.nodeList(getListExpression(elementsExpressions), + stateExpression), + n.getText()); + } + + public BlockStmt add(UnaryTestNode n) { + Expression opExpression = getEnumExpression(n.getOperator()); + Expression valueExpression = getNodeExpression(n.getValue()); + return addVariableDeclaratorWithObjectCreation(UNARYTESTNODE_CT, NodeList.nodeList(opExpression, + valueExpression), + n.getText()); + } + + public BlockStmt add(BooleanNode n) { + Expression valueExpression = new BooleanLiteralExpr(n.getValue()); + return addVariableDeclaratorWithObjectCreation(BOOLEANNODE_CT, NodeList.nodeList(valueExpression), n.getText()); + } + + public String getLastVariableName() { + return lastVariableName.get(); + } + + public BlockStmt returnError(String errorMessage) { + ObjectCreationExpr illegalStateExceptionExpression = new ObjectCreationExpr(null, ILLEGALSTATEEXCEPTION_CT, + NodeList.nodeList(getStringLiteralExpr(errorMessage))); + ThrowStmt throwStmt = new ThrowStmt(); + throwStmt.setExpression(illegalStateExceptionExpression); + return addStatement(throwStmt); + } + + private String getNextVariableName() { + return String.format("%s_%d", VAR_S, variableCounter.getAndIncrement()); + } + + private BlockStmt addVariableDeclaratorWithObjectCreation(ClassOrInterfaceType variableType, + NodeList arguments, String text) { + Expression textExpression = text != null ? new StringLiteralExpr(escapeJava(text)) : new NullLiteralExpr(); + arguments.add(textExpression); + return addVariableDeclaratorWithObjectCreation(variableType, arguments); + } + + private BlockStmt addVariableDeclaratorWithObjectCreation(ClassOrInterfaceType variableType, + NodeList arguments) { + String variableName = getNextVariableName(); + final VariableDeclarationExpr toAdd = getVariableDeclaratorWithObjectCreation(variableName, variableType, + arguments); + return addExpression(toAdd, variableName); + } + + private BlockStmt addVariableDeclaratorWithWithFieldAccess(ClassOrInterfaceType variableType, + String name, + Expression scope) { + + String variableName = getNextVariableName(); + final VariableDeclarationExpr toAdd = getVariableDeclaratorWithFieldAccessExpr(variableName, + variableType, + name, + scope); + return addExpression(toAdd, variableName); + } + + private BlockStmt addExpression(Expression toAdd, String variableName) { + lastVariableName.set(variableName); + return addExpression(toAdd); + } + + private BlockStmt addExpression(Expression toAdd) { + toPopulate.addStatement(toAdd); + LOGGER.debug(toPopulate.toString()); + return toPopulate; + } + + private BlockStmt addStatement(Statement toAdd) { + toPopulate.addStatement(toAdd); + LOGGER.debug(toPopulate.toString()); + return toPopulate; + } + + private Expression getTypeExpression(Type type) { + if (type instanceof Enum typeEnum) { + return getEnumExpression(typeEnum); + } else if (type instanceof JavaBackedType javaBackedType) { + return getJavaBackedTypeExpression(javaBackedType); + } else if (type instanceof MapBackedType mapBackedType) { + return getMapBackedTypeExpression(mapBackedType); + } else { + return parseExpression(type.getClass().getCanonicalName()); + } + } + + private Expression getJavaBackedTypeExpression(JavaBackedType javaBackedType) { + // Creating the JavaBackedType + String mapVariableName = getNextVariableName(); + final VariableDeclarator mapVariableDeclarator = + new VariableDeclarator(TYPE_CT, mapVariableName); + Expression classExpression = new NameExpr(javaBackedType.getWrapped().getCanonicalName() + ".class"); + final MethodCallExpr methodCallExpr = new MethodCallExpr(JAVABACKEDTYPE_N, OF_S, + NodeList.nodeList(classExpression)); + mapVariableDeclarator.setInitializer(methodCallExpr); + VariableDeclarationExpr mapVariableDeclarationExpr = new VariableDeclarationExpr(mapVariableDeclarator); + addExpression(mapVariableDeclarationExpr, mapVariableName); + return new NameExpr(mapVariableName); + } + + private Expression getMapBackedTypeExpression(MapBackedType mapBackedType) { + Map fieldsExpressions = new HashMap<>(); // The key is the StringLiteralExpr of the + // original key; the value is the Expression pointing at type + for (Map.Entry kv : mapBackedType.getFields().entrySet()) { + fieldsExpressions.put(new StringLiteralExpr(kv.getKey()), getTypeExpression(kv.getValue())); + } + + // Creating the MapBackedType + String mapVariableName = getNextVariableName(); + final VariableDeclarator mapVariableDeclarator = + new VariableDeclarator(MAPBACKEDTYPE_CT, mapVariableName); + final ObjectCreationExpr objectCreationExpr = new ObjectCreationExpr(null, MAPBACKEDTYPE_CT, + NodeList.nodeList(new StringLiteralExpr(mapBackedType.getName()))); + mapVariableDeclarator.setInitializer(objectCreationExpr); + VariableDeclarationExpr mapVariableDeclarationExpr = new VariableDeclarationExpr(mapVariableDeclarator); + addExpression(mapVariableDeclarationExpr, mapVariableName); + // Populating the map + Expression mapVariableExpression = new NameExpr(mapVariableName); + fieldsExpressions.forEach((key, value) -> { + MethodCallExpr putExpression = new MethodCallExpr(mapVariableExpression, ADDFIELD_S); + putExpression.addArgument(key); + putExpression.addArgument(value); + addExpression(putExpression); + }); + return new NameExpr(mapVariableName); + } + + private Expression getObjectExpression(Object object) { + if (object == null) { + return new NullLiteralExpr(); + } + String variableName = getNextVariableName(); + Expression objectExpression = CodegenUtils.getObjectExpression(object, variableName); + addExpression(objectExpression, variableName); + return new NameExpr(variableName); + } + + private Expression getNodeExpression(BaseNode node) { + if (node != null) { + node.accept(astCompilerVisitor); + return new NameExpr(lastVariableName.get()); + } else { + return new NullLiteralExpr(); + } + } +} \ No newline at end of file diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/ASTCompilerVisitor.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/ASTCompilerVisitor.java index 6ec690be497..0a509bca667 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/ASTCompilerVisitor.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/ASTCompilerVisitor.java @@ -18,42 +18,9 @@ */ package org.kie.dmn.feel.codegen.feel11; -import java.time.Duration; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.LocalTime; -import java.time.OffsetTime; -import java.time.ZonedDateTime; -import java.time.temporal.TemporalAccessor; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; - -import com.github.javaparser.ast.NodeList; -import com.github.javaparser.ast.body.VariableDeclarator; -import com.github.javaparser.ast.expr.BooleanLiteralExpr; -import com.github.javaparser.ast.expr.Expression; -import com.github.javaparser.ast.expr.FieldAccessExpr; -import com.github.javaparser.ast.expr.IntegerLiteralExpr; -import com.github.javaparser.ast.expr.MethodCallExpr; -import com.github.javaparser.ast.expr.NameExpr; -import com.github.javaparser.ast.expr.NullLiteralExpr; -import com.github.javaparser.ast.expr.ObjectCreationExpr; -import com.github.javaparser.ast.expr.SimpleName; -import com.github.javaparser.ast.expr.StringLiteralExpr; -import com.github.javaparser.ast.expr.VariableDeclarationExpr; import com.github.javaparser.ast.stmt.BlockStmt; -import com.github.javaparser.ast.stmt.ExpressionStmt; -import com.github.javaparser.ast.stmt.Statement; -import com.github.javaparser.ast.stmt.ThrowStmt; -import com.github.javaparser.ast.type.ClassOrInterfaceType; -import org.kie.dmn.feel.lang.Type; import org.kie.dmn.feel.lang.ast.ASTNode; import org.kie.dmn.feel.lang.ast.AtLiteralNode; -import org.kie.dmn.feel.lang.ast.BaseNode; import org.kie.dmn.feel.lang.ast.BetweenNode; import org.kie.dmn.feel.lang.ast.BooleanNode; import org.kie.dmn.feel.lang.ast.CTypeNode; @@ -86,106 +53,19 @@ import org.kie.dmn.feel.lang.ast.SignedUnaryNode; import org.kie.dmn.feel.lang.ast.StringNode; import org.kie.dmn.feel.lang.ast.TemporalConstantNode; -import org.kie.dmn.feel.lang.ast.TypeNode; import org.kie.dmn.feel.lang.ast.UnaryTestListNode; import org.kie.dmn.feel.lang.ast.UnaryTestNode; import org.kie.dmn.feel.lang.ast.Visitor; -import org.kie.dmn.feel.lang.impl.JavaBackedType; -import org.kie.dmn.feel.lang.impl.MapBackedType; -import org.kie.dmn.feel.lang.types.BuiltInType; -import org.kie.dmn.feel.lang.types.impl.ComparablePeriod; -import org.kie.dmn.feel.runtime.FEELFunction; -import org.kie.dmn.feel.util.DateTimeEvalHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import static com.github.javaparser.StaticJavaParser.parseClassOrInterfaceType; -import static com.github.javaparser.StaticJavaParser.parseExpression; -import static com.github.javaparser.utils.StringEscapeUtils.escapeJava; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.ADDFIELD_S; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.ASLIST_S; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.ATLITERALNODE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.BETWEENNODE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.BOOLEANNODE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.COMPARABLEPERIOD_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.COMPARABLEPERIOD_N; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.CONTEXTENTRYNODE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.CONTEXTNODE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.CONTEXTTYPENODE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.CTYPENODE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.DASHNODE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.DETERMINEOPERATOR_S; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.DURATION_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.DURATION_N; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.FEEL_TIME_S; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.FILTEREXPRESSIONNODE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.FOREXPRESSIONNODE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.FORMALPARAMETERNODE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.FUNCTIONDEFNODE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.FUNCTIONINVOCATIONNODE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.FUNCTIONTYPENODE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.GETBIGDECIMALORNULL_S; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.HASHMAP_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.IFEXPRESSIONNODE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.ILLEGALSTATEEXCEPTION_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.INFIXOPERATOR_N; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.INFIXOPNODE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.INNODE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.INSTANCEOFNODE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.INSTANCE_S; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.ITERATIONCONTEXTNODE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.JAVABACKEDTYPE_N; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.LISTNODE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.LISTTYPENODE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.LOCAL_DATE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.LOCAL_DATE_N; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.LOCAL_DATE_TIME_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.LOCAL_DATE_TIME_N; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.LOCAL_TIME_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.LOCAL_TIME_N; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.MAPBACKEDTYPE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.MAP_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.NAMEDEFNODE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.NAMEDPARAMETERNODE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.NAMEREFNODE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.NULLNODE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.NUMBEREVALHELPER_N; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.NUMBERNODE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.OFFSETTIME_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.OFFSETTIME_N; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.OF_S; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.PARSE_S; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.PATHEXPRESSIONNODE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.PUT_S; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.QUALIFIEDNAMENODE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.QUANTIFIEDEXPRESSIONNODE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.RANGENODE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.SIGNEDUNARYNODE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.STRINGNODE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.TEMPORALACCESSOR_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.TEMPORALCONSTANTNODE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.TIMEFUNCTION_N; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.TYPE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.UNARYTESTLISTNODE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.UNARYTESTNODE_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.VAR_S; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.ZONED_DATE_TIME_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.ZONED_DATE_TIME_N; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.ZONE_ID_N; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.ZONE_OFFSET_N; -import static org.kie.dmn.feel.codegen.feel11.Constants.BUILTINTYPE_E; - public class ASTCompilerVisitor implements Visitor { private static final Logger LOGGER = LoggerFactory.getLogger(ASTCompilerVisitor.class); - private final BlockStmt toPopulate; - private final AtomicInteger variableCounter; - private AtomicReference lastVariableName = new AtomicReference<>(); - private static final String EXTENDED_FUNCTION_PACKAGE = "org.kie.dmn.feel.runtime.functions.extended"; + private final ASTCompilerHelper compilerHelper; public ASTCompilerVisitor() { - toPopulate = new BlockStmt(); - variableCounter = new AtomicInteger(0); + compilerHelper = new ASTCompilerHelper(this); } @Override @@ -195,661 +75,222 @@ public BlockStmt visit(ASTNode n) { @Override public BlockStmt visit(AtLiteralNode n) { - Expression stringLiteralExpression = getNodeExpression(n.getStringLiteral()); - return addVariableDeclaratorWithObjectCreation(ATLITERALNODE_CT, NodeList.nodeList(stringLiteralExpression), - n.getText()); + LOGGER.trace("visit {}", n); + return compilerHelper.add(n); } @Override public BlockStmt visit(BetweenNode n) { - Expression valueExpression = getNodeExpression(n.getValue()); - Expression startExpression = getNodeExpression(n.getStart()); - Expression endExpression = getNodeExpression(n.getEnd()); - return addVariableDeclaratorWithObjectCreation(BETWEENNODE_CT, NodeList.nodeList(valueExpression, - startExpression, - endExpression), n.getText()); + LOGGER.trace("visit {}", n); + return compilerHelper.add(n); } @Override public BlockStmt visit(BooleanNode n) { - Expression valueExpression = new BooleanLiteralExpr(n.getValue()); - return addVariableDeclaratorWithObjectCreation(BOOLEANNODE_CT, NodeList.nodeList(valueExpression), n.getText()); + LOGGER.trace("visit {}", n); + return compilerHelper.add(n); } @Override public BlockStmt visit(ContextEntryNode n) { - Expression nameExpression = getNodeExpression(n.getName()); - Expression valueExpression = getNodeExpression(n.getValue()); - return addVariableDeclaratorWithObjectCreation(CONTEXTENTRYNODE_CT, NodeList.nodeList(nameExpression, - valueExpression), - n.getText()); + LOGGER.trace("visit {}", n); + return compilerHelper.add(n); } @Override public BlockStmt visit(ContextNode n) { - List entryNodesExpressions = n.getEntries().stream().map(entryNode -> getNodeExpression(entryNode)) - .toList(); - return addVariableDeclaratorWithObjectCreation(CONTEXTNODE_CT, - NodeList.nodeList(getListExpression(entryNodesExpressions)), - n.getText()); + LOGGER.trace("visit {}", n); + return compilerHelper.add(n); } @Override public BlockStmt visit(ContextTypeNode n) { - Map genExpressions = new HashMap<>(); // THe key is the StringLiteralExpr of the original key; the value is the NameExpr pointing at generated variable - for (Map.Entry kv : n.getGen().entrySet()) { - genExpressions.put(new StringLiteralExpr(kv.getKey()), getNodeExpression(kv.getValue())); - } - // Creating the map - String mapVariableName = getNextVariableName(); - final VariableDeclarator mapVariableDeclarator = - new VariableDeclarator(MAP_CT, mapVariableName); - final ObjectCreationExpr objectCreationExpr = new ObjectCreationExpr(null, HASHMAP_CT, NodeList.nodeList()); - mapVariableDeclarator.setInitializer(objectCreationExpr); - VariableDeclarationExpr mapVariableDeclarationExpr = new VariableDeclarationExpr(mapVariableDeclarator); - addExpression(mapVariableDeclarationExpr, mapVariableName); - // Populating the map - Expression mapVariableExpression = new NameExpr(mapVariableName); - genExpressions.forEach((key, value) -> { - MethodCallExpr putExpression = new MethodCallExpr(mapVariableExpression, PUT_S); - putExpression.addArgument(key); - putExpression.addArgument(value); - addExpression(putExpression); - }); - return addVariableDeclaratorWithObjectCreation(CONTEXTTYPENODE_CT, NodeList.nodeList(mapVariableExpression), - n.getText()); + LOGGER.trace("visit {}", n); + return compilerHelper.add(n); } @Override public BlockStmt visit(CTypeNode n) { - if (!(n.getType() instanceof BuiltInType)) { - throw new UnsupportedOperationException(); - } - BuiltInType feelCType = (BuiltInType) n.getType(); - Expression typeExpression = new FieldAccessExpr(BUILTINTYPE_E, feelCType.name()); - return addVariableDeclaratorWithObjectCreation(CTYPENODE_CT, NodeList.nodeList(typeExpression), n.getText()); + LOGGER.trace("visit {}", n); + return compilerHelper.add(n); } @Override public BlockStmt visit(DashNode n) { - return addVariableDeclaratorWithObjectCreation(DASHNODE_CT, NodeList.nodeList(), n.getText()); + LOGGER.trace("visit {}", n); + return compilerHelper.add(n); } @Override public BlockStmt visit(ForExpressionNode n) { - List iterationContextsExpressions = - n.getIterationContexts().stream().map(elementNode -> getNodeExpression(elementNode)) - .toList(); - Expression expressionExpression = getNodeExpression(n.getExpression()); - return addVariableDeclaratorWithObjectCreation(FOREXPRESSIONNODE_CT, - NodeList.nodeList(getListExpression(iterationContextsExpressions), - expressionExpression), - n.getText()); + LOGGER.trace("visit {}", n); + return compilerHelper.add(n); } @Override public BlockStmt visit(FilterExpressionNode n) { - Expression expressionExpression = getNodeExpression(n.getExpression()); - Expression filterExpression = getNodeExpression(n.getFilter()); - return addVariableDeclaratorWithObjectCreation(FILTEREXPRESSIONNODE_CT, NodeList.nodeList(expressionExpression, - filterExpression), - n.getText()); + LOGGER.trace("visit {}", n); + return compilerHelper.add(n); } @Override public BlockStmt visit(FormalParameterNode n) { - Expression nameExpression = getNodeExpression(n.getName()); - Expression typeExpression = getNodeExpression(n.getType()); - return addVariableDeclaratorWithObjectCreation(FORMALPARAMETERNODE_CT, NodeList.nodeList(nameExpression, - typeExpression), - n.getText()); + LOGGER.trace("visit {}", n); + return compilerHelper.add(n); } @Override public BlockStmt visit(FunctionDefNode n) { - List formalParametersExpressions = n.getFormalParameters().stream() - .map(elementNode -> getNodeExpression(elementNode)) - .toList(); - Expression bodyExpression = getNodeExpression(n.getBody()); - return addVariableDeclaratorWithObjectCreation(FUNCTIONDEFNODE_CT, - NodeList.nodeList(getListExpression(formalParametersExpressions), - new BooleanLiteralExpr(n.isExternal()), - bodyExpression), - n.getText()); + LOGGER.trace("visit {}", n); + return compilerHelper.add(n); } @Override public BlockStmt visit(FunctionInvocationNode n) { - Expression nameExpression = getNodeExpression(n.getName()); - Expression paramsExpression = getNodeExpression(n.getParams()); - Expression tcFoldedExpression = getNodeExpression(n.getTcFolded()); - return addVariableDeclaratorWithObjectCreation(FUNCTIONINVOCATIONNODE_CT, NodeList.nodeList(nameExpression, - paramsExpression, - tcFoldedExpression), n.getText()); + LOGGER.trace("visit {}", n); + return compilerHelper.add(n); } @Override public BlockStmt visit(FunctionTypeNode n) { - List argTypesExpressions = n.getArgTypes().stream().map(argTypeNode -> getNodeExpression(argTypeNode)) - .toList(); - Expression retTypeExpression = getNodeExpression(n.getRetType()); - return addVariableDeclaratorWithObjectCreation(FUNCTIONTYPENODE_CT, - NodeList.nodeList(getListExpression(argTypesExpressions), - retTypeExpression), - n.getText()); + LOGGER.trace("visit {}", n); + return compilerHelper.add(n); } @Override public BlockStmt visit(IfExpressionNode n) { - Expression conditionExpression = getNodeExpression(n.getCondition()); - Expression thenExpression = getNodeExpression(n.getThenExpression()); - Expression elseExpression = getNodeExpression(n.getElseExpression()); - return addVariableDeclaratorWithObjectCreation(IFEXPRESSIONNODE_CT, NodeList.nodeList(conditionExpression, - thenExpression, - elseExpression), - n.getText()); + LOGGER.trace("visit {}", n); + return compilerHelper.add(n); } @Override public BlockStmt visit(InfixOpNode n) { - Expression determineOperatorExpression = new MethodCallExpr(INFIXOPERATOR_N, DETERMINEOPERATOR_S, - new NodeList<>(new StringLiteralExpr(n.getOperator().getSymbol()))); - Expression leftExpression = getNodeExpression(n.getLeft()); - Expression rightExpression = getNodeExpression(n.getRight()); - return addVariableDeclaratorWithObjectCreation(INFIXOPNODE_CT, NodeList.nodeList(determineOperatorExpression, - leftExpression, - rightExpression), n.getText()); + LOGGER.trace("visit {}", n); + return compilerHelper.add(n); } @Override public BlockStmt visit(InNode n) { - Expression valueExpression = getNodeExpression(n.getValue()); - Expression exprsExpression = getNodeExpression(n.getExprs()); - return addVariableDeclaratorWithObjectCreation(INNODE_CT, NodeList.nodeList(valueExpression, exprsExpression) - , n.getText()); + LOGGER.trace("visit {}", n); + return compilerHelper.add(n); } @Override public BlockStmt visit(InstanceOfNode n) { - Expression expressionExpression = getNodeExpression(n.getExpression()); - Expression typeExpression = getNodeExpression(n.getType()); - return addVariableDeclaratorWithObjectCreation(INSTANCEOFNODE_CT, NodeList.nodeList(expressionExpression, - typeExpression), - n.getText()); + LOGGER.trace("visit {}", n); + return compilerHelper.add(n); } @Override public BlockStmt visit(IterationContextNode n) { - Expression nameExpression = getNodeExpression(n.getName()); - Expression expressionExpression = getNodeExpression(n.getExpression()); - Expression rangeEndExprExpression = getNodeExpression(n.getRangeEndExpr()); - return addVariableDeclaratorWithObjectCreation(ITERATIONCONTEXTNODE_CT, NodeList.nodeList(nameExpression, - expressionExpression, rangeEndExprExpression), n.getText()); + LOGGER.trace("visit {}", n); + return compilerHelper.add(n); } @Override public BlockStmt visit(ListNode n) { - List elements = n.getElements().stream().map(elementNode -> getNodeExpression(elementNode)) - .toList(); - return addVariableDeclaratorWithObjectCreation(LISTNODE_CT, NodeList.nodeList(getListExpression(elements)), - n.getText()); + LOGGER.trace("visit {}", n); + return compilerHelper.add(n); } @Override public BlockStmt visit(ListTypeNode n) { - Expression genTypeNodeExpression = getNodeExpression(n.getGenTypeNode()); - return addVariableDeclaratorWithObjectCreation(LISTTYPENODE_CT, NodeList.nodeList(genTypeNodeExpression), - n.getText()); + LOGGER.trace("visit {}", n); + return compilerHelper.add(n); } @Override public BlockStmt visit(NameDefNode n) { - List partsExpressions = n.getParts().stream().map(StringLiteralExpr::new) - .toList(); - Expression nameExpression = n.getName() != null ? new StringLiteralExpr(n.getName()) : new NullLiteralExpr(); - return addVariableDeclaratorWithObjectCreation(NAMEDEFNODE_CT, - NodeList.nodeList(getListExpression(partsExpressions), - nameExpression), n.getText()); + LOGGER.trace("visit {}", n); + return compilerHelper.add(n); } @Override public BlockStmt visit(NamedParameterNode n) { - Expression nameExpression = getNodeExpression(n.getName()); - Expression expressionExpression = getNodeExpression(n.getExpression()); - return addVariableDeclaratorWithObjectCreation(NAMEDPARAMETERNODE_CT, NodeList.nodeList(nameExpression, - expressionExpression) - , n.getText()); + LOGGER.trace("visit {}", n); + return compilerHelper.add(n); } @Override public BlockStmt visit(NameRefNode n) { - Expression typeExpression = getTypeExpression(n.getResultType()); - return addVariableDeclaratorWithObjectCreation(NAMEREFNODE_CT, NodeList.nodeList(typeExpression), n.getText()); + LOGGER.trace("visit {}", n); + return compilerHelper.add(n); } @Override public BlockStmt visit(NullNode n) { - return addVariableDeclaratorWithObjectCreation(NULLNODE_CT, NodeList.nodeList(), n.getText()); + LOGGER.trace("visit {}", n); + return compilerHelper.add(n); } @Override public BlockStmt visit(NumberNode n) { - MethodCallExpr valueExpression = new MethodCallExpr(NUMBEREVALHELPER_N, GETBIGDECIMALORNULL_S, - NodeList.nodeList(new StringLiteralExpr(n.getText()))); - return addVariableDeclaratorWithObjectCreation(NUMBERNODE_CT, NodeList.nodeList(valueExpression), n.getText()); + LOGGER.trace("visit {}", n); + return compilerHelper.add(n); } @Override public BlockStmt visit(PathExpressionNode n) { - Expression expressionExpression = getNodeExpression(n.getExpression()); - Expression nameExpression = getNodeExpression(n.getName()); - return addVariableDeclaratorWithObjectCreation(PATHEXPRESSIONNODE_CT, NodeList.nodeList(expressionExpression, - nameExpression), - n.getText()); + LOGGER.trace("visit {}", n); + return compilerHelper.add(n); } @Override public BlockStmt visit(QualifiedNameNode n) { - List partsExpressions = n.getParts().stream().map(partNode -> getNodeExpression(partNode)) - .toList(); - Expression typeExpression = getTypeExpression(n.getResultType()); - return addVariableDeclaratorWithObjectCreation(QUALIFIEDNAMENODE_CT, - NodeList.nodeList(getListExpression(partsExpressions), - typeExpression), - n.getText()); + LOGGER.trace("visit {}", n); + return compilerHelper.add(n); } @Override public BlockStmt visit(QuantifiedExpressionNode n) { - Expression quantifierExpression = getEnumExpression(n.getQuantifier()); - List iterationContextsExpressions = - n.getIterationContexts().stream().map(iterationContextNode -> getNodeExpression(iterationContextNode)) - .toList(); - Expression expressionExpression = getNodeExpression(n.getExpression()); - return addVariableDeclaratorWithObjectCreation(QUANTIFIEDEXPRESSIONNODE_CT, - NodeList.nodeList(quantifierExpression, - getListExpression(iterationContextsExpressions), - expressionExpression), n.getText()); + LOGGER.trace("visit {}", n); + return compilerHelper.add(n); } @Override public BlockStmt visit(RangeNode n) { - Expression lowerBoundExpression = getEnumExpression(n.getLowerBound()); - Expression upperBoundExpression = getEnumExpression(n.getUpperBound()); - Expression startExpression = getNodeExpression(n.getStart()); - Expression endExpression = getNodeExpression(n.getEnd()); - return addVariableDeclaratorWithObjectCreation(RANGENODE_CT, NodeList.nodeList(lowerBoundExpression, - upperBoundExpression, - startExpression, - endExpression), n.getText()); + LOGGER.trace("visit {}", n); + return compilerHelper.add(n); } @Override public BlockStmt visit(SignedUnaryNode n) { - Expression signExpression = getEnumExpression(n.getSign()); - Expression expressionExpression = getNodeExpression(n.getExpression()); - return addVariableDeclaratorWithObjectCreation(SIGNEDUNARYNODE_CT, NodeList.nodeList(signExpression, - expressionExpression), - n.getText()); + LOGGER.trace("visit {}", n); + return compilerHelper.add(n); } @Override public BlockStmt visit(StringNode n) { - return addVariableDeclaratorWithObjectCreation(STRINGNODE_CT, NodeList.nodeList(), - n.getText()); + LOGGER.trace("visit {}", n); + return compilerHelper.add(n); } @Override public BlockStmt visit(TemporalConstantNode n) { - Expression valueExpression = getObjectExpression(n.getValue()); - FEELFunction fn = n.getFn(); - Expression fnVariableNameExpression; - if (fn != null) { - Class fnClass = fn.getClass(); - ClassOrInterfaceType fn_CT = parseClassOrInterfaceType(fnClass.getCanonicalName()); - Expression fn_N = new NameExpr(fnClass.getCanonicalName()); - if (fnClass.getPackageName().equals(EXTENDED_FUNCTION_PACKAGE)) { - addVariableDeclaratorWithWithFieldAccess(fn_CT, INSTANCE_S, fn_N); - } else { - addVariableDeclaratorWithObjectCreation(fn_CT, - NodeList.nodeList()); - } - fnVariableNameExpression = new NameExpr(lastVariableName.get()); - } else { - fnVariableNameExpression = new NullLiteralExpr(); - } - List paramsExpressions = n.getParams().stream().map(param -> getObjectExpression(param)).toList(); - return addVariableDeclaratorWithObjectCreation(TEMPORALCONSTANTNODE_CT, NodeList.nodeList(valueExpression, - fnVariableNameExpression, getListExpression(paramsExpressions)), n.getText()); + LOGGER.trace("visit {}", n); + return compilerHelper.add(n); } @Override public BlockStmt visit(UnaryTestListNode n) { - List elementsExpressions = n.getElements().stream().map(elementNode -> getNodeExpression(elementNode)) - .toList(); - Expression stateExpression = getEnumExpression(n.getState()); - return addVariableDeclaratorWithObjectCreation(UNARYTESTLISTNODE_CT, - NodeList.nodeList(getListExpression(elementsExpressions), - stateExpression), - n.getText()); + LOGGER.trace("visit {}", n); + return compilerHelper.add(n); } @Override public BlockStmt visit(UnaryTestNode n) { - Expression opExpression = getEnumExpression(n.getOperator()); - Expression valueExpression = getNodeExpression(n.getValue()); - return addVariableDeclaratorWithObjectCreation(UNARYTESTNODE_CT, NodeList.nodeList(opExpression, - valueExpression), - n.getText()); + LOGGER.trace("visit {}", n); + return compilerHelper.add(n); } public String getLastVariableName() { - return lastVariableName.get(); + LOGGER.trace("getLastVariableName"); + return compilerHelper.getLastVariableName(); } public BlockStmt returnError(String errorMessage) { - ObjectCreationExpr illegalStateExceptionExpression = new ObjectCreationExpr(null, ILLEGALSTATEEXCEPTION_CT, NodeList.nodeList(Expressions.stringLiteral(errorMessage))); - ThrowStmt throwStmt = new ThrowStmt(); - throwStmt.setExpression(illegalStateExceptionExpression); - return addStatement(throwStmt); - } - - private String getNextVariableName() { - return String.format("%s_%d", VAR_S, variableCounter.getAndIncrement()); - } - - private BlockStmt addVariableDeclaratorWithObjectCreation(ClassOrInterfaceType variableType, - NodeList arguments, String text) { - Expression textExpression = text != null ? new StringLiteralExpr(escapeJava(text)) : new NullLiteralExpr(); - arguments.add(textExpression); - return addVariableDeclaratorWithObjectCreation(variableType, arguments); - } - - private BlockStmt addVariableDeclaratorWithObjectCreation(ClassOrInterfaceType variableType, - NodeList arguments) { - String variableName = getNextVariableName(); - final VariableDeclarationExpr toAdd = getVariableDeclaratorWithObjectCreation(variableName, variableType, - arguments); - return addExpression(toAdd, variableName); - } - - private BlockStmt addVariableDeclaratorWithWithMethodCall(ClassOrInterfaceType variableType, - String name, - Expression scope, - NodeList arguments) { - String variableName = getNextVariableName(); - final VariableDeclarationExpr toAdd = getVariableDeclaratorWithMethodCall(variableName, - variableType, - name, - scope, - arguments); - return addExpression(toAdd, variableName); - } - - private BlockStmt addVariableDeclaratorWithWithFieldAccess(ClassOrInterfaceType variableType, - String name, - Expression scope) { - - String variableName = getNextVariableName(); - final VariableDeclarationExpr toAdd = getVariableDeclaratorWithFieldAccessExpr(variableName, - variableType, - name, - scope); - return addExpression(toAdd, variableName); - } - - private BlockStmt addExpression(Expression toAdd, String variableName) { - lastVariableName.set(variableName); - return addExpression(toAdd); - } - - private BlockStmt addExpression(Expression toAdd) { - toPopulate.addStatement(toAdd); - LOGGER.debug(toPopulate.toString()); - return toPopulate; - } - - private BlockStmt addStatement(Statement toAdd) { - toPopulate.addStatement(toAdd); - LOGGER.debug(toPopulate.toString()); - return toPopulate; - } - - private VariableDeclarationExpr getVariableDeclaratorWithObjectCreation(String variableName, - ClassOrInterfaceType variableType, - NodeList arguments) { - final VariableDeclarator variableDeclarator = - new VariableDeclarator(variableType, variableName); - final ObjectCreationExpr objectCreationExpr = new ObjectCreationExpr(null, variableType, arguments); - variableDeclarator.setInitializer(objectCreationExpr); - return new VariableDeclarationExpr(variableDeclarator); - } - - private VariableDeclarationExpr getVariableDeclaratorWithMethodCall(String variableName, - ClassOrInterfaceType variableType, - String name, - Expression scope, - NodeList arguments) { - final VariableDeclarator variableDeclarator = - new VariableDeclarator(variableType, variableName); - final MethodCallExpr methodCallExpr = new MethodCallExpr(scope, name, arguments); - variableDeclarator.setInitializer(methodCallExpr); - return new VariableDeclarationExpr(variableDeclarator); - } - - private VariableDeclarationExpr getVariableDeclaratorWithFieldAccessExpr(String variableName, - ClassOrInterfaceType variableType, - String name, - Expression scope) { - final VariableDeclarator variableDeclarator = - new VariableDeclarator(variableType, variableName); - final FieldAccessExpr methodCallExpr = new FieldAccessExpr(scope, name); - variableDeclarator.setInitializer(methodCallExpr); - return new VariableDeclarationExpr(variableDeclarator); - } - - private Expression getTypeExpression(Type type) { - if (type instanceof Enum typeEnum) { - return getEnumExpression(typeEnum); - } else if (type instanceof JavaBackedType javaBackedType) { - return getJavaBackedTypeExpression(javaBackedType); - } else if (type instanceof MapBackedType mapBackedType) { - return getMapBackedTypeExpression(mapBackedType); - } else { - // TODO gcardosi 1206 - fix - return parseExpression(type.getClass().getCanonicalName()); - } - } - - - private Expression getJavaBackedTypeExpression(JavaBackedType javaBackedType) { - // Creating the JavaBackedType - String mapVariableName = getNextVariableName(); - final VariableDeclarator mapVariableDeclarator = - new VariableDeclarator(TYPE_CT, mapVariableName); - Expression classExpression = new NameExpr(javaBackedType.getWrapped().getCanonicalName() + ".class"); - final MethodCallExpr methodCallExpr = new MethodCallExpr(JAVABACKEDTYPE_N, OF_S, NodeList.nodeList(classExpression)); - mapVariableDeclarator.setInitializer(methodCallExpr); - VariableDeclarationExpr mapVariableDeclarationExpr = new VariableDeclarationExpr(mapVariableDeclarator); - addExpression(mapVariableDeclarationExpr, mapVariableName); - return new NameExpr(mapVariableName); - } - - private Expression getMapBackedTypeExpression(MapBackedType mapBackedType) { - Map fieldsExpressions = new HashMap<>(); // The key is the StringLiteralExpr of the original key; the value is the Expression pointing at type - for (Map.Entry kv : mapBackedType.getFields().entrySet()) { - fieldsExpressions.put(new StringLiteralExpr(kv.getKey()), getTypeExpression(kv.getValue())); - } - - // Creating the MapBackedType - String mapVariableName = getNextVariableName(); - final VariableDeclarator mapVariableDeclarator = - new VariableDeclarator(MAPBACKEDTYPE_CT, mapVariableName); - final ObjectCreationExpr objectCreationExpr = new ObjectCreationExpr(null, MAPBACKEDTYPE_CT, NodeList.nodeList(new StringLiteralExpr(mapBackedType.getName()))); - mapVariableDeclarator.setInitializer(objectCreationExpr); - VariableDeclarationExpr mapVariableDeclarationExpr = new VariableDeclarationExpr(mapVariableDeclarator); - addExpression(mapVariableDeclarationExpr, mapVariableName); - // Populating the map - Expression mapVariableExpression = new NameExpr(mapVariableName); - fieldsExpressions.forEach((key, value) -> { - MethodCallExpr putExpression = new MethodCallExpr(mapVariableExpression, ADDFIELD_S); - putExpression.addArgument(key); - putExpression.addArgument(value); - addExpression(putExpression); - }); - return new NameExpr(mapVariableName); - } - - private Expression getEnumExpression(Enum enumType) { - Expression scopeExpression = parseExpression(enumType.getClass().getCanonicalName()); - return new FieldAccessExpr(scopeExpression, enumType.name()); - } - - private Expression getNodeExpression(BaseNode node) { - if (node != null) { - node.accept(this); - return new NameExpr(lastVariableName.get()); - } else { - return new NullLiteralExpr(); - } - } - - private Expression getObjectExpression(Object object) { - if (object == null) { - return new NullLiteralExpr(); - } - if (object instanceof ComparablePeriod comparablePeriod) { - String variableName = getNextVariableName(); - NodeList arguments = NodeList.nodeList(new StringLiteralExpr(comparablePeriod.asPeriod().toString())); - - VariableDeclarationExpr variableDeclarationExpr = getVariableDeclaratorWithMethodCall(variableName, - COMPARABLEPERIOD_CT, - PARSE_S, - COMPARABLEPERIOD_N, arguments); - addExpression(variableDeclarationExpr, variableName); - return new NameExpr(variableName); - } else if (object instanceof Duration duration) { - String variableName = getNextVariableName(); - NodeList arguments = NodeList.nodeList(new StringLiteralExpr(duration.toString())); - VariableDeclarationExpr variableDeclarationExpr = getVariableDeclaratorWithMethodCall(variableName, - DURATION_CT, - PARSE_S, - DURATION_N, - arguments); - addExpression(variableDeclarationExpr, variableName); - return new NameExpr(variableName); - } else if (object instanceof LocalDate localDate) { - String variableName = getNextVariableName(); - NodeList arguments = NodeList.nodeList(new IntegerLiteralExpr(localDate.getYear()), - new IntegerLiteralExpr(localDate.getMonthValue()), - new IntegerLiteralExpr(localDate.getDayOfMonth())); - - VariableDeclarationExpr variableDeclarationExpr = getVariableDeclaratorWithMethodCall(variableName, - LOCAL_DATE_CT, - OF_S, - LOCAL_DATE_N, - arguments); - addExpression(variableDeclarationExpr, variableName); - return new NameExpr(variableName); - } else if (object instanceof LocalDateTime localDateTime) { - String variableName = getNextVariableName(); - NodeList arguments = NodeList.nodeList(new IntegerLiteralExpr(localDateTime.getYear()), - new IntegerLiteralExpr(localDateTime.getMonthValue()), - new IntegerLiteralExpr(localDateTime.getDayOfMonth()), - new IntegerLiteralExpr(localDateTime.getHour()), - new IntegerLiteralExpr(localDateTime.getMinute()), - new IntegerLiteralExpr(localDateTime.getSecond())); - VariableDeclarationExpr variableDeclarationExpr = getVariableDeclaratorWithMethodCall(variableName, - LOCAL_DATE_TIME_CT, - OF_S, - LOCAL_DATE_TIME_N, - arguments); - addExpression(variableDeclarationExpr, variableName); - return new NameExpr(variableName); - } else if (object instanceof LocalTime localTime) { - String variableName = getNextVariableName(); - NodeList arguments = NodeList.nodeList(new IntegerLiteralExpr(localTime.getHour()), - new IntegerLiteralExpr(localTime.getMinute()), - new IntegerLiteralExpr(localTime.getSecond()), - new IntegerLiteralExpr(localTime.getNano())); - VariableDeclarationExpr variableDeclarationExpr = getVariableDeclaratorWithMethodCall(variableName, - LOCAL_TIME_CT, - OF_S, - LOCAL_TIME_N, - arguments); - addExpression(variableDeclarationExpr, variableName); - return new NameExpr(variableName); - } else if (object instanceof Number number) { - return new IntegerLiteralExpr(number.toString()); - } else if (object instanceof OffsetTime offsetTime) { - String variableName = getNextVariableName(); - Expression zoneOffsetExpression = new MethodCallExpr(ZONE_OFFSET_N, - OF_S, - NodeList.nodeList(new StringLiteralExpr(offsetTime.getOffset().getId()))); - NodeList arguments = NodeList.nodeList(new IntegerLiteralExpr(offsetTime.getHour()), - new IntegerLiteralExpr(offsetTime.getMinute()), - new IntegerLiteralExpr(offsetTime.getSecond()), - new IntegerLiteralExpr(offsetTime.getNano()), - zoneOffsetExpression); - VariableDeclarationExpr variableDeclarationExpr = getVariableDeclaratorWithMethodCall(variableName, - OFFSETTIME_CT, - OF_S, - OFFSETTIME_N, - arguments); - addExpression(variableDeclarationExpr, variableName); - return new NameExpr(variableName); - } else if (object instanceof String string) { - return new StringLiteralExpr(escapeJava(string)); - } else if (object instanceof ZonedDateTime zonedDateTime) { - String variableName = getNextVariableName(); - Expression zoneIdExpression = new MethodCallExpr(ZONE_ID_N, OF_S, - NodeList.nodeList(new StringLiteralExpr(zonedDateTime.getZone().getId()))); - NodeList arguments = NodeList.nodeList(new IntegerLiteralExpr(zonedDateTime.getYear()), - new IntegerLiteralExpr(zonedDateTime.getMonthValue()), - new IntegerLiteralExpr(zonedDateTime.getDayOfMonth()), - new IntegerLiteralExpr(zonedDateTime.getHour()), - new IntegerLiteralExpr(zonedDateTime.getMinute()), - new IntegerLiteralExpr(zonedDateTime.getSecond()), - new IntegerLiteralExpr(zonedDateTime.getNano()), - zoneIdExpression); - VariableDeclarationExpr variableDeclarationExpr = getVariableDeclaratorWithMethodCall(variableName, - ZONED_DATE_TIME_CT, - OF_S, - ZONED_DATE_TIME_N, - arguments); - addExpression(variableDeclarationExpr, variableName); - return new NameExpr(variableName); - } else if (object instanceof TemporalAccessor temporalAccessor) { - // FallBack in case of Parse or other unmanaged classes - keep at the end - String variableName = getNextVariableName(); - String parsedString = DateTimeEvalHelper.toParsableString(temporalAccessor); - Expression feelTimeExpression = new FieldAccessExpr(TIMEFUNCTION_N, FEEL_TIME_S); - VariableDeclarationExpr variableDeclarationExpr = getVariableDeclaratorWithMethodCall(variableName, - TEMPORALACCESSOR_CT, - PARSE_S, - feelTimeExpression, - NodeList.nodeList(new StringLiteralExpr(parsedString))); - addExpression(variableDeclarationExpr, variableName); - return new NameExpr(variableName); - } else { - throw new UnsupportedOperationException("Unexpected Object: " + object + " " + object.getClass()); - } - } - - // Move to a common package - static Expression getListExpression(List expressions) { - ExpressionStmt asListExpression = new ExpressionStmt(); - MethodCallExpr arraysCallExpression = new MethodCallExpr(); - SimpleName arraysName = new SimpleName(Arrays.class.getName()); - arraysCallExpression.setScope(new NameExpr(arraysName)); - arraysCallExpression.setName(new SimpleName(ASLIST_S)); - asListExpression.setExpression(arraysCallExpression); - NodeList arguments = new NodeList<>(); - arguments.addAll(expressions); - arraysCallExpression.setArguments(arguments); - asListExpression.setExpression(arraysCallExpression); - return asListExpression.getExpression(); + LOGGER.trace("returnError {}", errorMessage); + return compilerHelper.returnError(errorMessage); } - } diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/CodegenConstants.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/CodegenConstants.java index cebb96d772f..120e9da37c4 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/CodegenConstants.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/CodegenConstants.java @@ -28,62 +28,13 @@ import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.time.temporal.TemporalAccessor; -import java.util.Arrays; import java.util.HashMap; -import java.util.List; import java.util.Map; import com.github.javaparser.ast.expr.NameExpr; import com.github.javaparser.ast.type.ClassOrInterfaceType; -import com.github.javaparser.ast.type.Type; -import org.kie.dmn.feel.lang.ast.ASTNode; -import org.kie.dmn.feel.lang.ast.AtLiteralNode; -import org.kie.dmn.feel.lang.ast.BetweenNode; -import org.kie.dmn.feel.lang.ast.BooleanNode; -import org.kie.dmn.feel.lang.ast.CTypeNode; -import org.kie.dmn.feel.lang.ast.ContextEntryNode; -import org.kie.dmn.feel.lang.ast.ContextNode; -import org.kie.dmn.feel.lang.ast.ContextTypeNode; -import org.kie.dmn.feel.lang.ast.DashNode; -import org.kie.dmn.feel.lang.ast.FilterExpressionNode; -import org.kie.dmn.feel.lang.ast.ForExpressionNode; -import org.kie.dmn.feel.lang.ast.FormalParameterNode; -import org.kie.dmn.feel.lang.ast.FunctionDefNode; -import org.kie.dmn.feel.lang.ast.FunctionInvocationNode; -import org.kie.dmn.feel.lang.ast.FunctionTypeNode; -import org.kie.dmn.feel.lang.ast.IfExpressionNode; -import org.kie.dmn.feel.lang.ast.InNode; -import org.kie.dmn.feel.lang.ast.InfixOpNode; -import org.kie.dmn.feel.lang.ast.InfixOperator; -import org.kie.dmn.feel.lang.ast.InstanceOfNode; -import org.kie.dmn.feel.lang.ast.IterationContextNode; -import org.kie.dmn.feel.lang.ast.ListNode; -import org.kie.dmn.feel.lang.ast.ListTypeNode; -import org.kie.dmn.feel.lang.ast.NameDefNode; -import org.kie.dmn.feel.lang.ast.NameRefNode; -import org.kie.dmn.feel.lang.ast.NamedParameterNode; -import org.kie.dmn.feel.lang.ast.NullNode; -import org.kie.dmn.feel.lang.ast.NumberNode; -import org.kie.dmn.feel.lang.ast.PathExpressionNode; -import org.kie.dmn.feel.lang.ast.QualifiedNameNode; -import org.kie.dmn.feel.lang.ast.QuantifiedExpressionNode; -import org.kie.dmn.feel.lang.ast.RangeNode; -import org.kie.dmn.feel.lang.ast.SignedUnaryNode; -import org.kie.dmn.feel.lang.ast.StringNode; -import org.kie.dmn.feel.lang.ast.TemporalConstantNode; -import org.kie.dmn.feel.lang.ast.UnaryTestListNode; -import org.kie.dmn.feel.lang.ast.UnaryTestNode; -import org.kie.dmn.feel.lang.impl.JavaBackedType; -import org.kie.dmn.feel.lang.impl.MapBackedType; -import org.kie.dmn.feel.lang.types.impl.ComparablePeriod; -import org.kie.dmn.feel.runtime.FEELFunction; -import org.kie.dmn.feel.runtime.Range; -import org.kie.dmn.feel.runtime.UnaryTest; -import org.kie.dmn.feel.runtime.functions.TimeFunction; -import org.kie.dmn.feel.util.NumberEvalHelper; import static com.github.javaparser.StaticJavaParser.parseClassOrInterfaceType; -import static com.github.javaparser.StaticJavaParser.parseType; /** * Class used to store constant values needed for codegen @@ -94,21 +45,13 @@ public class CodegenConstants { // String public static final String ADDFIELD_S = "addField"; public static final String ASLIST_S = "asList"; - public static final String CREATEBASENODE_S = "createBaseNode"; - public static final String DETERMINEOPERATOR_S = "determineOperator"; - public static final String EVALUATE_S = "evaluate"; - public static final String FEELCTX_S = "feelExprCtx"; - public static final String FEEL_TIME_S = "FEEL_TIME"; - public static final String GETBIGDECIMALORNULL_S = "getBigDecimalOrNull"; public static final String INSTANCE_S = "INSTANCE"; public static final String OF_S = "of"; public static final String PARSE_S = "parse"; public static final String PUT_S = "put"; - public static final String RANGEBOUNDARY_S = Range.RangeBoundary.class.getCanonicalName(); public static final String VAR_S = "var"; // NameExpr - // java types public static final NameExpr DURATION_N = new NameExpr(Duration.class.getCanonicalName()); public static final NameExpr LOCAL_DATE_N = new NameExpr(LocalDate.class.getCanonicalName()); public static final NameExpr LOCAL_DATE_TIME_N = new NameExpr(LocalDateTime.class.getCanonicalName()); @@ -118,71 +61,22 @@ public class CodegenConstants { public static final NameExpr ZONE_ID_N = new NameExpr(ZoneId.class.getCanonicalName()); public static final NameExpr ZONE_OFFSET_N = new NameExpr(ZoneOffset.class.getCanonicalName()); - // DMN - public static final NameExpr INFIXOPERATOR_N = new NameExpr(InfixOperator.class.getCanonicalName()); - public static final NameExpr COMPARABLEPERIOD_N = new NameExpr(ComparablePeriod.class.getCanonicalName()); - public static final NameExpr FEELCTX_N = new NameExpr(FEELCTX_S); - public static final NameExpr JAVABACKEDTYPE_N = new NameExpr(JavaBackedType.class.getCanonicalName()); - public static final NameExpr NUMBEREVALHELPER_N = new NameExpr(NumberEvalHelper.class.getCanonicalName()); - public static final NameExpr TIMEFUNCTION_N = new NameExpr(TimeFunction.class.getCanonicalName()); // ClassOrInterfaceType - // java types public static final ClassOrInterfaceType BIGDECIMAL_CT = parseClassOrInterfaceType(BigDecimal.class.getCanonicalName()); public static final ClassOrInterfaceType DURATION_CT = parseClassOrInterfaceType(Duration.class.getCanonicalName()); public static final ClassOrInterfaceType HASHMAP_CT = parseClassOrInterfaceType(HashMap.class.getCanonicalName()); - public static final ClassOrInterfaceType FUNCTION_CT = parseClassOrInterfaceType("java.util.function.Function"); public static final ClassOrInterfaceType ILLEGALSTATEEXCEPTION_CT = parseClassOrInterfaceType(IllegalStateException.class.getCanonicalName()); + public static final ClassOrInterfaceType INTEGER_CT = parseClassOrInterfaceType(Integer.class.getCanonicalName()); public static final ClassOrInterfaceType LOCAL_DATE_CT = parseClassOrInterfaceType(LocalDate.class.getCanonicalName()); public static final ClassOrInterfaceType LOCAL_DATE_TIME_CT = parseClassOrInterfaceType(LocalDateTime.class.getCanonicalName()); public static final ClassOrInterfaceType LOCAL_TIME_CT = parseClassOrInterfaceType(LocalTime.class.getCanonicalName()); public static final ClassOrInterfaceType OFFSETTIME_CT = parseClassOrInterfaceType(OffsetTime.class.getCanonicalName()); public static final ClassOrInterfaceType MAP_CT = parseClassOrInterfaceType(Map.class.getCanonicalName()); + public static final ClassOrInterfaceType STRING_CT = parseClassOrInterfaceType(String.class.getCanonicalName()); public static final ClassOrInterfaceType TEMPORALACCESSOR_CT = parseClassOrInterfaceType(TemporalAccessor.class.getCanonicalName()); public static final ClassOrInterfaceType ZONED_DATE_TIME_CT = parseClassOrInterfaceType(ZonedDateTime.class.getCanonicalName()); - // DMN - public static final ClassOrInterfaceType COMPARABLEPERIOD_CT = parseClassOrInterfaceType(ComparablePeriod.class.getCanonicalName()); - public static final ClassOrInterfaceType MAPBACKEDTYPE_CT = parseClassOrInterfaceType(MapBackedType.class.getCanonicalName()); - public static final ClassOrInterfaceType TYPE_CT = parseClassOrInterfaceType(org.kie.dmn.feel.lang.Type.class.getCanonicalName()); - public static final ClassOrInterfaceType UNARYTEST_CT = parseClassOrInterfaceType(UnaryTest.class.getCanonicalName()); - - // BaseNode - public static final ClassOrInterfaceType ATLITERALNODE_CT = parseClassOrInterfaceType(AtLiteralNode.class.getCanonicalName()); - public static final ClassOrInterfaceType BETWEENNODE_CT = parseClassOrInterfaceType(BetweenNode.class.getCanonicalName()); - public static final ClassOrInterfaceType BOOLEANNODE_CT = parseClassOrInterfaceType(BooleanNode.class.getCanonicalName()); - public static final ClassOrInterfaceType CONTEXTNODE_CT = parseClassOrInterfaceType(ContextNode.class.getCanonicalName()); - public static final ClassOrInterfaceType CONTEXTENTRYNODE_CT = parseClassOrInterfaceType(ContextEntryNode.class.getCanonicalName()); - public static final ClassOrInterfaceType CONTEXTTYPENODE_CT = parseClassOrInterfaceType(ContextTypeNode.class.getCanonicalName()); - public static final ClassOrInterfaceType CTYPENODE_CT = parseClassOrInterfaceType(CTypeNode.class.getCanonicalName()); - public static final ClassOrInterfaceType DASHNODE_CT = parseClassOrInterfaceType(DashNode.class.getCanonicalName()); - public static final ClassOrInterfaceType FILTEREXPRESSIONNODE_CT = parseClassOrInterfaceType(FilterExpressionNode.class.getCanonicalName()); - public static final ClassOrInterfaceType FOREXPRESSIONNODE_CT = parseClassOrInterfaceType(ForExpressionNode.class.getCanonicalName()); - public static final ClassOrInterfaceType FORMALPARAMETERNODE_CT = parseClassOrInterfaceType(FormalParameterNode.class.getCanonicalName()); - public static final ClassOrInterfaceType FUNCTIONDEFNODE_CT = parseClassOrInterfaceType(FunctionDefNode.class.getCanonicalName()); - public static final ClassOrInterfaceType FUNCTIONTYPENODE_CT = parseClassOrInterfaceType(FunctionTypeNode.class.getCanonicalName()); - public static final ClassOrInterfaceType FUNCTIONINVOCATIONNODE_CT = parseClassOrInterfaceType(FunctionInvocationNode.class.getCanonicalName()); - public static final ClassOrInterfaceType IFEXPRESSIONNODE_CT = parseClassOrInterfaceType(IfExpressionNode.class.getCanonicalName()); - public static final ClassOrInterfaceType INFIXOPNODE_CT = parseClassOrInterfaceType(InfixOpNode.class.getCanonicalName()); - public static final ClassOrInterfaceType INNODE_CT = parseClassOrInterfaceType(InNode.class.getCanonicalName()); - public static final ClassOrInterfaceType INSTANCEOFNODE_CT = parseClassOrInterfaceType(InstanceOfNode.class.getCanonicalName()); - public static final ClassOrInterfaceType ITERATIONCONTEXTNODE_CT = parseClassOrInterfaceType(IterationContextNode.class.getCanonicalName()); - public static final ClassOrInterfaceType LISTNODE_CT = parseClassOrInterfaceType(ListNode.class.getCanonicalName()); - public static final ClassOrInterfaceType LISTTYPENODE_CT = parseClassOrInterfaceType(ListTypeNode.class.getCanonicalName()); - public static final ClassOrInterfaceType NAMEDEFNODE_CT = parseClassOrInterfaceType(NameDefNode.class.getCanonicalName()); - public static final ClassOrInterfaceType NAMEDPARAMETERNODE_CT = parseClassOrInterfaceType(NamedParameterNode.class.getCanonicalName()); - public static final ClassOrInterfaceType NAMEREFNODE_CT = parseClassOrInterfaceType(NameRefNode.class.getCanonicalName()); - public static final ClassOrInterfaceType NULLNODE_CT = parseClassOrInterfaceType(NullNode.class.getCanonicalName()); - public static final ClassOrInterfaceType NUMBERNODE_CT = parseClassOrInterfaceType(NumberNode.class.getCanonicalName()); - public static final ClassOrInterfaceType PATHEXPRESSIONNODE_CT = parseClassOrInterfaceType(PathExpressionNode.class.getCanonicalName()); - public static final ClassOrInterfaceType QUALIFIEDNAMENODE_CT = parseClassOrInterfaceType(QualifiedNameNode.class.getCanonicalName()); - public static final ClassOrInterfaceType QUANTIFIEDEXPRESSIONNODE_CT = parseClassOrInterfaceType(QuantifiedExpressionNode.class.getCanonicalName()); - public static final ClassOrInterfaceType RANGENODE_CT = parseClassOrInterfaceType(RangeNode.class.getCanonicalName()); - public static final ClassOrInterfaceType SIGNEDUNARYNODE_CT = parseClassOrInterfaceType(SignedUnaryNode.class.getCanonicalName()); - public static final ClassOrInterfaceType STRINGNODE_CT = parseClassOrInterfaceType(StringNode.class.getCanonicalName()); - public static final ClassOrInterfaceType TEMPORALCONSTANTNODE_CT = parseClassOrInterfaceType(TemporalConstantNode.class.getCanonicalName()); - public static final ClassOrInterfaceType UNARYTESTLISTNODE_CT = parseClassOrInterfaceType(UnaryTestListNode.class.getCanonicalName()); - public static final ClassOrInterfaceType UNARYTESTNODE_CT = parseClassOrInterfaceType(UnaryTestNode.class.getCanonicalName()); private CodegenConstants() { } diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/CompilerBytecodeLoader.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/CompilerBytecodeLoader.java index 09c174ddce0..2674c7cab2b 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/CompilerBytecodeLoader.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/CompilerBytecodeLoader.java @@ -52,7 +52,7 @@ import static com.github.javaparser.StaticJavaParser.parse; import static org.drools.compiler.compiler.JavaDialectConfiguration.createNativeCompiler; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.CREATEBASENODE_S; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.CREATEBASENODE_S; public class CompilerBytecodeLoader { @@ -125,8 +125,12 @@ public T compileUnit(String cuPackage, String cuClass, CompilationUnit cu) pReader, pStore, Thread.currentThread().getContextClassLoader()); - LOG.error("{}", Arrays.asList(compilationResult.getErrors())); - LOG.warn("{}", Arrays.asList(compilationResult.getWarnings())); + if (compilationResult.getErrors().length > 0) { + LOG.error("{}", Arrays.asList(compilationResult.getErrors())); + } + if (compilationResult.getWarnings().length > 0) { + LOG.warn("{}", Arrays.asList(compilationResult.getWarnings())); + } String fqnClassName = cuPackage + "." + cuClass; Class loaded = diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/Constants.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/Constants.java index e2f32323db3..3cf8efdb44d 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/Constants.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/Constants.java @@ -34,9 +34,9 @@ import static com.github.javaparser.StaticJavaParser.parseClassOrInterfaceType; import static com.github.javaparser.StaticJavaParser.parseExpression; import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.BIGDECIMAL_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.FUNCTION_CT; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.RANGEBOUNDARY_S; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.UNARYTEST_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.FUNCTION_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.RANGEBOUNDARY_S; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.UNARYTEST_CT; public class Constants { diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/DMNCodegenConstants.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/DMNCodegenConstants.java new file mode 100644 index 00000000000..d99876f96c7 --- /dev/null +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/DMNCodegenConstants.java @@ -0,0 +1,172 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.dmn.feel.codegen.feel11; + +import com.github.javaparser.ast.expr.NameExpr; +import com.github.javaparser.ast.type.ClassOrInterfaceType; +import org.kie.dmn.feel.lang.ast.AtLiteralNode; +import org.kie.dmn.feel.lang.ast.BetweenNode; +import org.kie.dmn.feel.lang.ast.BooleanNode; +import org.kie.dmn.feel.lang.ast.CTypeNode; +import org.kie.dmn.feel.lang.ast.ContextEntryNode; +import org.kie.dmn.feel.lang.ast.ContextNode; +import org.kie.dmn.feel.lang.ast.ContextTypeNode; +import org.kie.dmn.feel.lang.ast.DashNode; +import org.kie.dmn.feel.lang.ast.FilterExpressionNode; +import org.kie.dmn.feel.lang.ast.ForExpressionNode; +import org.kie.dmn.feel.lang.ast.FormalParameterNode; +import org.kie.dmn.feel.lang.ast.FunctionDefNode; +import org.kie.dmn.feel.lang.ast.FunctionInvocationNode; +import org.kie.dmn.feel.lang.ast.FunctionTypeNode; +import org.kie.dmn.feel.lang.ast.IfExpressionNode; +import org.kie.dmn.feel.lang.ast.InNode; +import org.kie.dmn.feel.lang.ast.InfixOpNode; +import org.kie.dmn.feel.lang.ast.InfixOperator; +import org.kie.dmn.feel.lang.ast.InstanceOfNode; +import org.kie.dmn.feel.lang.ast.IterationContextNode; +import org.kie.dmn.feel.lang.ast.ListNode; +import org.kie.dmn.feel.lang.ast.ListTypeNode; +import org.kie.dmn.feel.lang.ast.NameDefNode; +import org.kie.dmn.feel.lang.ast.NameRefNode; +import org.kie.dmn.feel.lang.ast.NamedParameterNode; +import org.kie.dmn.feel.lang.ast.NullNode; +import org.kie.dmn.feel.lang.ast.NumberNode; +import org.kie.dmn.feel.lang.ast.PathExpressionNode; +import org.kie.dmn.feel.lang.ast.QualifiedNameNode; +import org.kie.dmn.feel.lang.ast.QuantifiedExpressionNode; +import org.kie.dmn.feel.lang.ast.RangeNode; +import org.kie.dmn.feel.lang.ast.SignedUnaryNode; +import org.kie.dmn.feel.lang.ast.StringNode; +import org.kie.dmn.feel.lang.ast.TemporalConstantNode; +import org.kie.dmn.feel.lang.ast.UnaryTestListNode; +import org.kie.dmn.feel.lang.ast.UnaryTestNode; +import org.kie.dmn.feel.lang.impl.JavaBackedType; +import org.kie.dmn.feel.lang.impl.MapBackedType; +import org.kie.dmn.feel.lang.types.impl.ComparablePeriod; +import org.kie.dmn.feel.runtime.Range; +import org.kie.dmn.feel.runtime.UnaryTest; +import org.kie.dmn.feel.runtime.functions.TimeFunction; +import org.kie.dmn.feel.util.NumberEvalHelper; + +import static com.github.javaparser.StaticJavaParser.parseClassOrInterfaceType; + +/** + * Class used to store constant values needed for codegen + */ +public class DMNCodegenConstants { + + // String + public static final String CREATEBASENODE_S = "createBaseNode"; + public static final String DETERMINEOPERATOR_S = "determineOperator"; + public static final String FEEL_TIME_S = "FEEL_TIME"; + public static final String GETBIGDECIMALORNULL_S = "getBigDecimalOrNull"; + public static final String RANGEBOUNDARY_S = Range.RangeBoundary.class.getCanonicalName(); + + // NameExpr + public static final NameExpr INFIXOPERATOR_N = new NameExpr(InfixOperator.class.getCanonicalName()); + public static final NameExpr COMPARABLEPERIOD_N = new NameExpr(ComparablePeriod.class.getCanonicalName()); + public static final NameExpr JAVABACKEDTYPE_N = new NameExpr(JavaBackedType.class.getCanonicalName()); + public static final NameExpr NUMBEREVALHELPER_N = new NameExpr(NumberEvalHelper.class.getCanonicalName()); + public static final NameExpr TIMEFUNCTION_N = new NameExpr(TimeFunction.class.getCanonicalName()); + + // ClassOrInterfaceType + public static final ClassOrInterfaceType COMPARABLEPERIOD_CT = + parseClassOrInterfaceType(ComparablePeriod.class.getCanonicalName()); + public static final ClassOrInterfaceType FUNCTION_CT = parseClassOrInterfaceType("java.util.function" + + ".Function" + + ""); + public static final ClassOrInterfaceType MAPBACKEDTYPE_CT = + parseClassOrInterfaceType(MapBackedType.class.getCanonicalName()); + public static final ClassOrInterfaceType TYPE_CT = + parseClassOrInterfaceType(org.kie.dmn.feel.lang.Type.class.getCanonicalName()); + public static final ClassOrInterfaceType UNARYTEST_CT = + parseClassOrInterfaceType(UnaryTest.class.getCanonicalName()); + + // BaseNode + public static final ClassOrInterfaceType ATLITERALNODE_CT = + parseClassOrInterfaceType(AtLiteralNode.class.getCanonicalName()); + public static final ClassOrInterfaceType BETWEENNODE_CT = + parseClassOrInterfaceType(BetweenNode.class.getCanonicalName()); + public static final ClassOrInterfaceType BOOLEANNODE_CT = + parseClassOrInterfaceType(BooleanNode.class.getCanonicalName()); + public static final ClassOrInterfaceType CONTEXTNODE_CT = + parseClassOrInterfaceType(ContextNode.class.getCanonicalName()); + public static final ClassOrInterfaceType CONTEXTENTRYNODE_CT = + parseClassOrInterfaceType(ContextEntryNode.class.getCanonicalName()); + public static final ClassOrInterfaceType CONTEXTTYPENODE_CT = + parseClassOrInterfaceType(ContextTypeNode.class.getCanonicalName()); + public static final ClassOrInterfaceType CTYPENODE_CT = + parseClassOrInterfaceType(CTypeNode.class.getCanonicalName()); + public static final ClassOrInterfaceType DASHNODE_CT = parseClassOrInterfaceType(DashNode.class.getCanonicalName()); + public static final ClassOrInterfaceType FILTEREXPRESSIONNODE_CT = + parseClassOrInterfaceType(FilterExpressionNode.class.getCanonicalName()); + public static final ClassOrInterfaceType FOREXPRESSIONNODE_CT = + parseClassOrInterfaceType(ForExpressionNode.class.getCanonicalName()); + public static final ClassOrInterfaceType FORMALPARAMETERNODE_CT = + parseClassOrInterfaceType(FormalParameterNode.class.getCanonicalName()); + public static final ClassOrInterfaceType FUNCTIONDEFNODE_CT = + parseClassOrInterfaceType(FunctionDefNode.class.getCanonicalName()); + public static final ClassOrInterfaceType FUNCTIONTYPENODE_CT = + parseClassOrInterfaceType(FunctionTypeNode.class.getCanonicalName()); + public static final ClassOrInterfaceType FUNCTIONINVOCATIONNODE_CT = + parseClassOrInterfaceType(FunctionInvocationNode.class.getCanonicalName()); + public static final ClassOrInterfaceType IFEXPRESSIONNODE_CT = + parseClassOrInterfaceType(IfExpressionNode.class.getCanonicalName()); + public static final ClassOrInterfaceType INFIXOPNODE_CT = + parseClassOrInterfaceType(InfixOpNode.class.getCanonicalName()); + public static final ClassOrInterfaceType INNODE_CT = parseClassOrInterfaceType(InNode.class.getCanonicalName()); + public static final ClassOrInterfaceType INSTANCEOFNODE_CT = + parseClassOrInterfaceType(InstanceOfNode.class.getCanonicalName()); + public static final ClassOrInterfaceType ITERATIONCONTEXTNODE_CT = + parseClassOrInterfaceType(IterationContextNode.class.getCanonicalName()); + public static final ClassOrInterfaceType LISTNODE_CT = parseClassOrInterfaceType(ListNode.class.getCanonicalName()); + public static final ClassOrInterfaceType LISTTYPENODE_CT = + parseClassOrInterfaceType(ListTypeNode.class.getCanonicalName()); + public static final ClassOrInterfaceType NAMEDEFNODE_CT = + parseClassOrInterfaceType(NameDefNode.class.getCanonicalName()); + public static final ClassOrInterfaceType NAMEDPARAMETERNODE_CT = + parseClassOrInterfaceType(NamedParameterNode.class.getCanonicalName()); + public static final ClassOrInterfaceType NAMEREFNODE_CT = + parseClassOrInterfaceType(NameRefNode.class.getCanonicalName()); + public static final ClassOrInterfaceType NULLNODE_CT = parseClassOrInterfaceType(NullNode.class.getCanonicalName()); + public static final ClassOrInterfaceType NUMBERNODE_CT = + parseClassOrInterfaceType(NumberNode.class.getCanonicalName()); + public static final ClassOrInterfaceType PATHEXPRESSIONNODE_CT = + parseClassOrInterfaceType(PathExpressionNode.class.getCanonicalName()); + public static final ClassOrInterfaceType QUALIFIEDNAMENODE_CT = + parseClassOrInterfaceType(QualifiedNameNode.class.getCanonicalName()); + public static final ClassOrInterfaceType QUANTIFIEDEXPRESSIONNODE_CT = + parseClassOrInterfaceType(QuantifiedExpressionNode.class.getCanonicalName()); + public static final ClassOrInterfaceType RANGENODE_CT = + parseClassOrInterfaceType(RangeNode.class.getCanonicalName()); + public static final ClassOrInterfaceType SIGNEDUNARYNODE_CT = + parseClassOrInterfaceType(SignedUnaryNode.class.getCanonicalName()); + public static final ClassOrInterfaceType STRINGNODE_CT = + parseClassOrInterfaceType(StringNode.class.getCanonicalName()); + public static final ClassOrInterfaceType TEMPORALCONSTANTNODE_CT = + parseClassOrInterfaceType(TemporalConstantNode.class.getCanonicalName()); + public static final ClassOrInterfaceType UNARYTESTLISTNODE_CT = + parseClassOrInterfaceType(UnaryTestListNode.class.getCanonicalName()); + public static final ClassOrInterfaceType UNARYTESTNODE_CT = + parseClassOrInterfaceType(UnaryTestNode.class.getCanonicalName()); + + private DMNCodegenConstants() { + } +} diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/Expressions.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/Expressions.java deleted file mode 100644 index 46d0ab72916..00000000000 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/Expressions.java +++ /dev/null @@ -1,474 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.kie.dmn.feel.codegen.feel11; - -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import com.github.javaparser.ast.NodeList; -import com.github.javaparser.ast.body.FieldDeclaration; -import com.github.javaparser.ast.body.Parameter; -import com.github.javaparser.ast.expr.CastExpr; -import com.github.javaparser.ast.expr.ClassExpr; -import com.github.javaparser.ast.expr.EnclosedExpr; -import com.github.javaparser.ast.expr.Expression; -import com.github.javaparser.ast.expr.LambdaExpr; -import com.github.javaparser.ast.expr.MethodCallExpr; -import com.github.javaparser.ast.expr.MethodReferenceExpr; -import com.github.javaparser.ast.expr.NameExpr; -import com.github.javaparser.ast.expr.ObjectCreationExpr; -import com.github.javaparser.ast.expr.StringLiteralExpr; -import com.github.javaparser.ast.stmt.ExpressionStmt; -import com.github.javaparser.ast.type.ClassOrInterfaceType; -import com.github.javaparser.ast.type.Type; -import com.github.javaparser.ast.type.UnknownType; -import org.kie.dmn.feel.lang.ast.InfixOperator; -import org.kie.dmn.feel.lang.ast.QuantifiedExpressionNode; -import org.kie.dmn.feel.lang.ast.RangeNode; -import org.kie.dmn.feel.lang.ast.UnaryTestNode; -import org.kie.dmn.feel.lang.impl.MapBackedType; -import org.kie.dmn.feel.lang.impl.NamedParameter; -import org.kie.dmn.feel.lang.types.GenFnType; -import org.kie.dmn.feel.lang.types.GenListType; -import org.kie.dmn.feel.runtime.functions.BaseFEELFunction; -import org.kie.dmn.feel.util.StringEvalHelper; - -import static com.github.javaparser.StaticJavaParser.parseClassOrInterfaceType; -import static com.github.javaparser.StaticJavaParser.parseExpression; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.FEELCTX_N; -import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.FEELCTX_S; -import static org.kie.dmn.feel.codegen.feel11.Constants.BUILTINTYPE_E; - -public class Expressions { - - public static final ClassOrInterfaceType NamedParamterT = parseClassOrInterfaceType(NamedParameter.class.getCanonicalName()); - public static final ClassOrInterfaceType FormalParamterT = parseClassOrInterfaceType(BaseFEELFunction.Param.class.getCanonicalName()); - public static final ClassOrInterfaceType GenListTypeT = parseClassOrInterfaceType(GenListType.class.getCanonicalName()); - public static final ClassOrInterfaceType MapBackedTypeT = parseClassOrInterfaceType(MapBackedType.class.getCanonicalName()); - public static final ClassOrInterfaceType GenFnTypeT = parseClassOrInterfaceType(GenFnType.class.getCanonicalName()); - private static final Expression DASH_UNARY_TEST = parseExpression(org.kie.dmn.feel.lang.ast.DashNode.DashUnaryTest.class.getCanonicalName() + ".INSTANCE"); - - public static class NamedLambda { - - private final NameExpr name; - - private final LambdaExpr expr; - private final FieldDeclaration field; - - private NamedLambda(NameExpr name, LambdaExpr expr, FieldDeclaration field) { - this.name = name; - this.expr = expr; - this.field = field; - } - - public NameExpr name() { - return name; - } - - public LambdaExpr expr() { - return expr; - } - - public FieldDeclaration field() { - return field; - } - } - - private static final Expression QUANTIFIER_SOME = parseExpression("org.kie.dmn.feel.lang.ast.QuantifiedExpressionNode.Quantifier.SOME"); - private static final Expression QUANTIFIER_EVERY = parseExpression("org.kie.dmn.feel.lang.ast.QuantifiedExpressionNode.Quantifier.EVERY"); - - public static final String LEFT = "left"; - public static final NameExpr LEFT_EXPR = new NameExpr(LEFT); - public static final UnknownType UNKNOWN_TYPE = new UnknownType(); - // public static final NameExpr STDLIB = new NameExpr(CompiledFEELSupport.class.getCanonicalName()); - -// public static Expression dash() { -// return DASH_UNARY_TEST; -// } -// -// public static Expression negate(Expression expression) { -// return new MethodCallExpr(STDLIB, "negate", NodeList.nodeList(FEELCTX_N, expression)); -// } -// -// public static Expression positive(Expression expression) { -// return new MethodCallExpr(STDLIB, "positive", NodeList.nodeList(FEELCTX_N, expression)); -// } -// -// public static MethodCallExpr binary( -// InfixOperator operator, -// Expression l, -// Expression r) { -// switch (operator) { -// case ADD: -// return arithmetic("add", l, r); -// case SUB: -// return arithmetic("sub", l, r); -// case MULT: -// return arithmetic("mult", l, r); -// case DIV: -// return arithmetic("div", l, r); -// case POW: -// return arithmetic("pow", l, r); -// -// case LTE: -// return comparison("lte", l, r); -// case LT: -// return comparison("lt", l, r); -// case GT: -// return comparison("gt", l, r); -// case GTE: -// return comparison("gte", l, r); -// case EQ: -// return equality("eq", l, r); -// case NE: -// return equality("ne", l, r); -// case AND: -// return booleans("and", l, r); -// case OR: -// return booleans("or", l, r); -// default: -// throw new UnsupportedOperationException(operator.toString()); -// } -// } -// -// private static MethodCallExpr arithmetic(String op, Expression left, Expression right) { -// return new MethodCallExpr(compiledFeelSemanticMappingsFQN(), op) -// .addArgument(left) -// .addArgument(right) -// .addArgument(FEELCTX_N); -// } -// -// private static MethodCallExpr equality(String op, Expression left, Expression right) { -// return new MethodCallExpr(compiledFeelSemanticMappingsFQN(), op, new NodeList<>(left, right)); -// } -// -// private static MethodCallExpr comparison(String op, Expression left, Expression right) { -// return new MethodCallExpr(compiledFeelSemanticMappingsFQN(), op, new NodeList<>(left, right)); -// } -// -// private static MethodCallExpr booleans(String op, Expression left, Expression right) { -// Expression l = coerceToBoolean(left); -// Expression r = supplierLambda(coerceToBoolean(right)); -// -// return new MethodCallExpr(compiledFeelSemanticMappingsFQN(), op, new NodeList<>(l, r)); -// } - -// public static Expression unary( -// UnaryTestNode.UnaryOperator operator, -// Expression right) { -// switch (operator) { -// case LTE: -// return unaryComparison("lte", right); -// case LT: -// return unaryComparison("lt", right); -// case GT: -// return unaryComparison("gt", right); -// case GTE: -// return unaryComparison("gte", right); -// case EQ: -// return new MethodCallExpr(compiledFeelSemanticMappingsFQN(), "gracefulEq", new NodeList<>(FEELCTX_N, right, LEFT_EXPR)); -// case NE: -// return unaryComparison("ne", right); -// case IN: -// // only used in decision tables: refactor? how? -// return new MethodCallExpr(compiledFeelSemanticMappingsFQN(), "includes", new NodeList<>(FEELCTX_N, right, LEFT_EXPR)); -// case NOT: -// return new MethodCallExpr(compiledFeelSemanticMappingsFQN(), "notExists", new NodeList<>(FEELCTX_N, right, LEFT_EXPR)); -// case TEST: -// return coerceToBoolean(right); -// default: -// throw new UnsupportedOperationException(operator.toString()); -// } -// } -// -// public static MethodCallExpr unaryComparison(String operator, Expression right) { -// return new MethodCallExpr(compiledFeelSemanticMappingsFQN(), operator, new NodeList<>(LEFT_EXPR, right)); -// } -// -// public static MethodCallExpr lt(Expression left, Expression right) { -// return new MethodCallExpr(null, "lt") -// .addArgument(left) -// .addArgument(right); -// } -// -// public static MethodCallExpr gt(Expression left, Expression right) { -// return new MethodCallExpr(null, "gt") -// .addArgument(left) -// .addArgument(right); -// } -// -// public static MethodCallExpr between(Expression value, Expression start, Expression end) { -// return new MethodCallExpr(null, "between") -// .addArgument(FEELCTX_N) -// .addArgument(value) -// .addArgument(start) -// .addArgument(end); -// } -// -// public static EnclosedExpr castTo(Type type, Expression expr) { -// return new EnclosedExpr(new CastExpr(type, new EnclosedExpr(expr))); -// } -// -// public static MethodCallExpr reflectiveCastTo(Type type, Expression expr) { -// return new MethodCallExpr(new ClassExpr(type), "cast") -// .addArgument(new EnclosedExpr(expr)); -// } -// -// public static Expression quantifier( -// QuantifiedExpressionNode.Quantifier quantifier, -// Expression condition, -// List iterationContexts) { -// -// // quant({SOME,EVERY}, FEELCTX) -// MethodCallExpr quant = -// new MethodCallExpr(Expressions.STDLIB, "quant") -// .addArgument(quantifier == QuantifiedExpressionNode.Quantifier.SOME ? -// QUANTIFIER_SOME : -// QUANTIFIER_EVERY) -// .addArgument(FEELCTX_N); -// -// // .with(expr) -// // .with(expr) -// Expression chainedCalls = iterationContexts.stream() -// .reduce(quant, (l, r) -> r.asMethodCallExpr().setScope(l)); -// -// return new MethodCallExpr(chainedCalls, "satisfies") -// .addArgument(condition); -// } -// -// public static MethodCallExpr ffor( -// List iterationContexts, -// Expression returnExpr) { -// MethodCallExpr ffor = -// new MethodCallExpr(Expressions.STDLIB, "ffor") -// .addArgument(FEELCTX_N); -// -// // .with(expr) -// // .with(expr) -// Expression chainedCalls = iterationContexts.stream() -// .reduce(ffor, (l, r) -> r.asMethodCallExpr().setScope(l)); -// -// return new MethodCallExpr(chainedCalls, "rreturn") -// .addArgument(returnExpr); -// } -// -// public static NameExpr compiledFeelSemanticMappingsFQN() { -// return new NameExpr("org.kie.dmn.feel.codegen.feel11.CompiledFEELSemanticMappings"); -// } -// -// public static MethodCallExpr list(Expression... exprs) { -// return new MethodCallExpr(compiledFeelSemanticMappingsFQN(), "list", NodeList.nodeList(exprs)); -// } -// -// public static MethodCallExpr range(RangeNode.IntervalBoundary lowBoundary, -// Expression lowEndPoint, -// Expression highEndPoint, -// RangeNode.IntervalBoundary highBoundary) { -// -// return new MethodCallExpr(compiledFeelSemanticMappingsFQN(), "range") -// .addArgument(FEELCTX_N) -// .addArgument(Constants.rangeBoundary(lowBoundary)) -// .addArgument(lowEndPoint) -// .addArgument(highEndPoint) -// .addArgument(Constants.rangeBoundary(highBoundary)); -// } -// -// public static MethodCallExpr includes(Expression range, Expression target) { -// return new MethodCallExpr(compiledFeelSemanticMappingsFQN(), "includes") -// .addArgument(FEELCTX_N) -// .addArgument(range) -// .addArgument(target); -// } -// -// public static MethodCallExpr exists(Expression tests, Expression target) { -// return new MethodCallExpr(compiledFeelSemanticMappingsFQN(), "exists") -// .addArgument(FEELCTX_N) -// .addArgument(tests) -// .addArgument(target); -// } -// -// public static MethodCallExpr notExists(Expression expr) { -// return new MethodCallExpr(compiledFeelSemanticMappingsFQN(), "notExists") -// .addArgument(FEELCTX_N) -// .addArgument(expr) -// .addArgument(LEFT_EXPR); -// } -// -// public static NamedLambda namedLambda(Expression expr, String text) { -// LambdaExpr lambda = Expressions.lambda(expr); -// String name = Constants.functionName(text); -// FieldDeclaration field = Constants.function(name, lambda); -// return new NamedLambda(new NameExpr(name), lambda, field); -// } -// -// public static LambdaExpr lambda(Expression expr) { -// return new LambdaExpr( -// new NodeList<>( -// new Parameter(UNKNOWN_TYPE, FEELCTX_S)), -// new ExpressionStmt(expr), -// true); -// } -// -// public static LambdaExpr supplierLambda(Expression expr) { -// return new LambdaExpr(new NodeList<>(), -// new ExpressionStmt(expr), -// true); -// } -// -// public static NamedLambda namedUnaryLambda(Expression expr, String text) { -// LambdaExpr lambda = Expressions.unaryLambda(expr); -// String name = Constants.unaryTestName(text); -// FieldDeclaration field = Constants.unaryTest(name, lambda); -// return new NamedLambda(new NameExpr(name), lambda, field); -// } -// -// -// public static LambdaExpr unaryLambda(Expression expr) { -// return new LambdaExpr( -// new NodeList<>( -// new Parameter(UNKNOWN_TYPE, FEELCTX_S), -// new Parameter(UNKNOWN_TYPE, "left")), -// new ExpressionStmt(expr), -// true); -// } -// -// public static ObjectCreationExpr namedParameter(Expression name, Expression value) { -// return new ObjectCreationExpr(null, NamedParamterT, new NodeList<>(name, value)); -// } -// -// public static ObjectCreationExpr formalParameter(Expression name, Expression type) { -// return new ObjectCreationExpr(null, FormalParamterT, new NodeList<>(name, type)); -// } -// -// public static MethodCallExpr invoke(Expression functionName, Expression params) { -// return new MethodCallExpr(STDLIB, "invoke") -// .addArgument(FEELCTX_N) -// .addArgument(functionName) -// .addArgument(params); -// } -// -// public static MethodCallExpr filter(Expression expr, Expression filter) { -// return new MethodCallExpr(new MethodCallExpr(STDLIB, "filter") -// .addArgument(FEELCTX_N) -// .addArgument(expr), -// "with") -// .addArgument(filter); -// } -// -// public static MethodCallExpr path(Expression expr, Expression filter) { -// return new MethodCallExpr(new MethodCallExpr(STDLIB, "path") -// .addArgument(FEELCTX_N) -// .addArgument(expr), -// "with") -// .addArgument(filter); -// } -// -// public static MethodCallExpr path(Expression expr, List filters) { -// MethodCallExpr methodCallExpr = new MethodCallExpr(new MethodCallExpr(STDLIB, "path") -// .addArgument(FEELCTX_N) -// .addArgument(expr), -// "with"); -// filters.forEach(methodCallExpr::addArgument); -// return methodCallExpr; -// } -// -// public static MethodCallExpr isInstanceOf(Expression expr, Expression type) { -// return new MethodCallExpr(type, "isInstanceOf") -// .addArgument(expr); -// } -// -// public static MethodCallExpr nativeInstanceOf(Type type, Expression condition) { -// return new MethodCallExpr( -// new ClassExpr(type), -// "isInstance") -// .addArgument(new EnclosedExpr(condition)); -// } -// -// public static MethodCallExpr determineTypeFromName(String typeAsText) { -// return new MethodCallExpr(BUILTINTYPE_E, "determineTypeFromName") -// .addArgument(new StringLiteralExpr(typeAsText)); -// } -// -// public static ObjectCreationExpr genListType(Expression gen) { -// return new ObjectCreationExpr(null, GenListTypeT, new NodeList<>(gen)); -// } -// -// public static Expression genContextType(Map fields) { -// final ClassOrInterfaceType sie = parseClassOrInterfaceType(java.util.AbstractMap.SimpleImmutableEntry.class.getCanonicalName()); -// sie.setTypeArguments(parseClassOrInterfaceType(String.class.getCanonicalName()), -// parseClassOrInterfaceType(org.kie.dmn.feel.lang.Type.class.getCanonicalName())); -// List entryParams = fields.entrySet().stream().map(e -> new ObjectCreationExpr(null, -// sie, -// new NodeList<>(stringLiteral(e.getKey()), -// e.getValue()))) -// .collect(Collectors.toList()); -// MethodCallExpr mOf = new MethodCallExpr(new NameExpr(java.util.stream.Stream.class.getCanonicalName()), "of"); -// entryParams.forEach(mOf::addArgument); -// MethodCallExpr mCollect = new MethodCallExpr(mOf, "collect"); -// mCollect.addArgument(new MethodCallExpr(new NameExpr(java.util.stream.Collectors.class.getCanonicalName()), -// "toMap").addArgument(new MethodReferenceExpr(new NameExpr(java.util.Map.Entry.class.getCanonicalName()), new NodeList<>(), "getKey")) -// .addArgument(new MethodReferenceExpr(new NameExpr(java.util.Map.Entry.class.getCanonicalName()), new NodeList<>(), "getValue"))); -// return new ObjectCreationExpr(null, MapBackedTypeT, new NodeList<>(stringLiteral("[anonymous]"), mCollect)); -// } -// -// public static ObjectCreationExpr genFnType(List args, Expression ret) { -// return new ObjectCreationExpr(null, -// GenFnTypeT, -// new NodeList<>(new MethodCallExpr(new NameExpr(java.util.Arrays.class.getCanonicalName()), -// "asList", -// new NodeList<>(args)), -// ret)); -// } -// -// public static Expression contains(Expression expr, Expression value) { -// return new MethodCallExpr(expr, "contains") -// .addArgument(value); -// } -// - public static StringLiteralExpr stringLiteral(String text) { - if (text.startsWith("\"") && text.endsWith("\"")) { - String actualStringContent = text.substring(1, text.length() - 1); // remove start/end " from the FEEL text expression. - String unescaped = StringEvalHelper.unescapeString(actualStringContent); // unescapes String, FEEL-style - return new StringLiteralExpr().setString(unescaped); // setString escapes the contents Java-style - } else { - return new StringLiteralExpr().setString(text); - } - } -// -// public static Expression coerceToBoolean(Expression expression) { -// return new MethodCallExpr(compiledFeelSemanticMappingsFQN(), "coerceToBoolean") -// .addArgument(FEELCTX_N) -// .addArgument(expression); -// } -// -// public static MethodCallExpr coerceNumber(Expression exprCursor) { -// MethodCallExpr coerceNumberMethodCallExpr = new MethodCallExpr(new NameExpr(CompiledFEELSupport.class.getSimpleName()), "coerceNumber"); -// coerceNumberMethodCallExpr.addArgument(exprCursor); -// return coerceNumberMethodCallExpr; -// } -// -// public static ObjectCreationExpr newIllegalState() { -// return new ObjectCreationExpr(null, -// parseClassOrInterfaceType(IllegalStateException.class.getCanonicalName()), -// new NodeList<>()); -// } -} - - diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/CodegenUtils.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/CodegenUtils.java new file mode 100644 index 00000000000..9eaddf4df80 --- /dev/null +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/CodegenUtils.java @@ -0,0 +1,249 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.dmn.feel.util; + +import java.time.Duration; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.OffsetTime; +import java.time.ZonedDateTime; +import java.time.temporal.TemporalAccessor; +import java.util.Arrays; +import java.util.List; + +import com.github.javaparser.ast.NodeList; +import com.github.javaparser.ast.body.VariableDeclarator; +import com.github.javaparser.ast.expr.Expression; +import com.github.javaparser.ast.expr.FieldAccessExpr; +import com.github.javaparser.ast.expr.IntegerLiteralExpr; +import com.github.javaparser.ast.expr.MethodCallExpr; +import com.github.javaparser.ast.expr.NameExpr; +import com.github.javaparser.ast.expr.ObjectCreationExpr; +import com.github.javaparser.ast.expr.SimpleName; +import com.github.javaparser.ast.expr.StringLiteralExpr; +import com.github.javaparser.ast.expr.VariableDeclarationExpr; +import com.github.javaparser.ast.stmt.ExpressionStmt; +import com.github.javaparser.ast.type.ClassOrInterfaceType; +import org.kie.dmn.feel.lang.types.impl.ComparablePeriod; + +import static com.github.javaparser.StaticJavaParser.parseExpression; +import static com.github.javaparser.utils.StringEscapeUtils.escapeJava; +import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.ASLIST_S; +import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.DURATION_CT; +import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.DURATION_N; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.FEEL_TIME_S; +import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.INTEGER_CT; +import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.LOCAL_DATE_CT; +import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.LOCAL_DATE_N; +import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.LOCAL_DATE_TIME_CT; +import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.LOCAL_DATE_TIME_N; +import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.LOCAL_TIME_CT; +import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.LOCAL_TIME_N; +import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.OFFSETTIME_CT; +import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.OFFSETTIME_N; +import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.OF_S; +import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.PARSE_S; +import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.STRING_CT; +import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.TEMPORALACCESSOR_CT; +import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.ZONED_DATE_TIME_CT; +import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.ZONED_DATE_TIME_N; +import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.ZONE_ID_N; +import static org.kie.dmn.feel.codegen.feel11.CodegenConstants.ZONE_OFFSET_N; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.COMPARABLEPERIOD_CT; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.COMPARABLEPERIOD_N; +import static org.kie.dmn.feel.codegen.feel11.DMNCodegenConstants.TIMEFUNCTION_N; + +/** + * Class meant to provide commons utility methods for codegen. + * This class should not have any reference to dmn-specific classes/methods. + */ +public class CodegenUtils { + + private CodegenUtils() { + } + + public static Expression getEnumExpression(Enum enumType) { + Expression scopeExpression = parseExpression(enumType.getClass().getCanonicalName()); + return new FieldAccessExpr(scopeExpression, enumType.name()); + } + + public static VariableDeclarationExpr getObjectExpression(Object object, String variableName) { + if (object instanceof ComparablePeriod comparablePeriod) { + NodeList arguments = NodeList.nodeList(new StringLiteralExpr(comparablePeriod.asPeriod().toString())); + + return getVariableDeclaratorWithMethodCall(variableName, + COMPARABLEPERIOD_CT, + PARSE_S, + COMPARABLEPERIOD_N, arguments); + } else if (object instanceof Duration duration) { + NodeList arguments = NodeList.nodeList(new StringLiteralExpr(duration.toString())); + return getVariableDeclaratorWithMethodCall(variableName, + DURATION_CT, + PARSE_S, + DURATION_N, + arguments); + } else if (object instanceof LocalDate localDate) { + NodeList arguments = NodeList.nodeList(new IntegerLiteralExpr(localDate.getYear()), + new IntegerLiteralExpr(localDate.getMonthValue()), + new IntegerLiteralExpr(localDate.getDayOfMonth())); + + return getVariableDeclaratorWithMethodCall(variableName, + LOCAL_DATE_CT, + OF_S, + LOCAL_DATE_N, + arguments); + } else if (object instanceof LocalDateTime localDateTime) { + NodeList arguments = NodeList.nodeList(new IntegerLiteralExpr(localDateTime.getYear()), + new IntegerLiteralExpr(localDateTime.getMonthValue()), + new IntegerLiteralExpr(localDateTime.getDayOfMonth()), + new IntegerLiteralExpr(localDateTime.getHour()), + new IntegerLiteralExpr(localDateTime.getMinute()), + new IntegerLiteralExpr(localDateTime.getSecond())); + return getVariableDeclaratorWithMethodCall(variableName, + LOCAL_DATE_TIME_CT, + OF_S, + LOCAL_DATE_TIME_N, + arguments); + } else if (object instanceof LocalTime localTime) { + NodeList arguments = NodeList.nodeList(new IntegerLiteralExpr(localTime.getHour()), + new IntegerLiteralExpr(localTime.getMinute()), + new IntegerLiteralExpr(localTime.getSecond()), + new IntegerLiteralExpr(localTime.getNano())); + return getVariableDeclaratorWithMethodCall(variableName, + LOCAL_TIME_CT, + OF_S, + LOCAL_TIME_N, + arguments); + } else if (object instanceof Number number) { + return getVariableDeclaratorWithInitializerExpression(variableName, INTEGER_CT, + new IntegerLiteralExpr(number.toString())); + } else if (object instanceof OffsetTime offsetTime) { + Expression zoneOffsetExpression = new MethodCallExpr(ZONE_OFFSET_N, + OF_S, + NodeList.nodeList(new StringLiteralExpr(offsetTime.getOffset().getId()))); + NodeList arguments = NodeList.nodeList(new IntegerLiteralExpr(offsetTime.getHour()), + new IntegerLiteralExpr(offsetTime.getMinute()), + new IntegerLiteralExpr(offsetTime.getSecond()), + new IntegerLiteralExpr(offsetTime.getNano()), + zoneOffsetExpression); + return getVariableDeclaratorWithMethodCall(variableName, + OFFSETTIME_CT, + OF_S, + OFFSETTIME_N, + arguments); + } else if (object instanceof String string) { + return getVariableDeclaratorWithInitializerExpression(variableName, STRING_CT, + new StringLiteralExpr(escapeJava(string))); + } else if (object instanceof ZonedDateTime zonedDateTime) { + Expression zoneIdExpression = new MethodCallExpr(ZONE_ID_N, OF_S, + NodeList.nodeList(new StringLiteralExpr(zonedDateTime.getZone().getId()))); + NodeList arguments = NodeList.nodeList(new IntegerLiteralExpr(zonedDateTime.getYear()), + new IntegerLiteralExpr(zonedDateTime.getMonthValue()), + new IntegerLiteralExpr(zonedDateTime.getDayOfMonth()), + new IntegerLiteralExpr(zonedDateTime.getHour()), + new IntegerLiteralExpr(zonedDateTime.getMinute()), + new IntegerLiteralExpr(zonedDateTime.getSecond()), + new IntegerLiteralExpr(zonedDateTime.getNano()), + zoneIdExpression); + return getVariableDeclaratorWithMethodCall(variableName, + ZONED_DATE_TIME_CT, + OF_S, + ZONED_DATE_TIME_N, + arguments); + } else if (object instanceof TemporalAccessor temporalAccessor) { + // FallBack in case of Parse or other unmanaged classes - keep at the end + String parsedString = DateTimeEvalHelper.toParsableString(temporalAccessor); + Expression feelTimeExpression = new FieldAccessExpr(TIMEFUNCTION_N, FEEL_TIME_S); + return getVariableDeclaratorWithMethodCall(variableName, + TEMPORALACCESSOR_CT, + PARSE_S, + feelTimeExpression, + NodeList.nodeList(new StringLiteralExpr(parsedString))); + } else { + throw new UnsupportedOperationException("Unexpected Object: " + object + " " + object.getClass()); + } + } + + public static StringLiteralExpr getStringLiteralExpr(String text) { + if (text.startsWith("\"") && text.endsWith("\"")) { + String actualStringContent = text.substring(1, text.length() - 1); // remove start/end " from the FEEL text expression. + String unescaped = StringEvalHelper.unescapeString(actualStringContent); // unescapes String, FEEL-style + return new StringLiteralExpr().setString(unescaped); // setString escapes the contents Java-style + } else { + return new StringLiteralExpr().setString(text); + } + } + + public static Expression getListExpression(List expressions) { + ExpressionStmt asListExpression = new ExpressionStmt(); + MethodCallExpr arraysCallExpression = new MethodCallExpr(); + SimpleName arraysName = new SimpleName(Arrays.class.getName()); + arraysCallExpression.setScope(new NameExpr(arraysName)); + arraysCallExpression.setName(new SimpleName(ASLIST_S)); + asListExpression.setExpression(arraysCallExpression); + NodeList arguments = new NodeList<>(); + arguments.addAll(expressions); + arraysCallExpression.setArguments(arguments); + asListExpression.setExpression(arraysCallExpression); + return asListExpression.getExpression(); + } + + public static VariableDeclarationExpr getVariableDeclaratorWithObjectCreation(String variableName, + ClassOrInterfaceType variableType, + NodeList arguments) { + final VariableDeclarator variableDeclarator = + new VariableDeclarator(variableType, variableName); + final ObjectCreationExpr objectCreationExpr = new ObjectCreationExpr(null, variableType, arguments); + variableDeclarator.setInitializer(objectCreationExpr); + return new VariableDeclarationExpr(variableDeclarator); + } + + public static VariableDeclarationExpr getVariableDeclaratorWithMethodCall(String variableName, + ClassOrInterfaceType variableType, + String name, + Expression scope, + NodeList arguments) { + final VariableDeclarator variableDeclarator = + new VariableDeclarator(variableType, variableName); + final MethodCallExpr methodCallExpr = new MethodCallExpr(scope, name, arguments); + variableDeclarator.setInitializer(methodCallExpr); + return new VariableDeclarationExpr(variableDeclarator); + } + + public static VariableDeclarationExpr getVariableDeclaratorWithFieldAccessExpr(String variableName, + ClassOrInterfaceType variableType, + String name, + Expression scope) { + final VariableDeclarator variableDeclarator = + new VariableDeclarator(variableType, variableName); + final FieldAccessExpr methodCallExpr = new FieldAccessExpr(scope, name); + variableDeclarator.setInitializer(methodCallExpr); + return new VariableDeclarationExpr(variableDeclarator); + } + + public static VariableDeclarationExpr getVariableDeclaratorWithInitializerExpression(String variableName, + ClassOrInterfaceType variableType, + Expression initializer) { + final VariableDeclarator variableDeclarator = + new VariableDeclarator(variableType, variableName); + variableDeclarator.setInitializer(initializer); + return new VariableDeclarationExpr(variableDeclarator); + } +} \ No newline at end of file