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 index dad299cf74b..3e91a78d202 100644 --- 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 @@ -21,6 +21,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; @@ -150,16 +151,22 @@ public class ASTCompilerHelper { private static final Logger LOGGER = LoggerFactory.getLogger(ASTCompilerVisitor.class); + private static final String EXTENDED_FUNCTION_PACKAGE = "org.kie.dmn.feel.runtime.functions.extended"; private final ASTCompilerVisitor astCompilerVisitor; private final BlockStmt toPopulate; private final AtomicInteger variableCounter; + private final Map baseNodeCache; + private final Map typeCache; + private final Map objectCache; 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); + baseNodeCache = new ConcurrentHashMap<>(); + typeCache = new ConcurrentHashMap<>(); + objectCache = new ConcurrentHashMap<>(); } public BlockStmt add(AtLiteralNode n) { @@ -177,6 +184,11 @@ public BlockStmt add(BetweenNode n) { endExpression), n.getText()); } + public BlockStmt add(BooleanNode n) { + Expression valueExpression = new BooleanLiteralExpr(n.getValue()); + return addVariableDeclaratorWithObjectCreation(BOOLEANNODE_CT, NodeList.nodeList(valueExpression), n.getText()); + } + public BlockStmt add(ContextEntryNode n) { Expression nameExpression = getNodeExpression(n.getName()); Expression valueExpression = getNodeExpression(n.getValue()); @@ -473,11 +485,6 @@ public BlockStmt add(UnaryTestNode n) { 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(); } @@ -539,34 +546,41 @@ private BlockStmt addStatement(Statement toAdd) { } private Expression getTypeExpression(Type type) { - if (type instanceof AliasFEELType aliasFEELType) { - return getAliasFEELType(aliasFEELType); - } else 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()); + if (!typeCache.containsKey(type)) { + Expression toPut; + if (type instanceof AliasFEELType aliasFEELType) { + toPut = getAliasFEELType(aliasFEELType); + } else if (type instanceof Enum typeEnum) { + toPut = getEnumExpression(typeEnum); + } else if (type instanceof JavaBackedType javaBackedType) { + toPut = getJavaBackedTypeExpression(javaBackedType); + } else if (type instanceof MapBackedType mapBackedType) { + toPut = getMapBackedTypeExpression(mapBackedType); + } else { + toPut = parseExpression(type.getClass().getCanonicalName()); + } + typeCache.put(type, toPut); } + return typeCache.get(type); } - private Expression getAliasFEELType(AliasFEELType aliasFEELType) { - BuiltInType feelCType = aliasFEELType.getBuiltInType(); - Expression typeExpression = new FieldAccessExpr(BUILTINTYPE_E, feelCType.name()); - // Creating the AliasFEELType - String aliasFeelTypeVariableName = getNextVariableName(); - final VariableDeclarator aliasFeelTypeVariableDeclarator = - new VariableDeclarator(ALIASFEELTYPE_CT, aliasFeelTypeVariableName); - NodeList arguments = NodeList.nodeList(new StringLiteralExpr(aliasFEELType.getName()), typeExpression); - final ObjectCreationExpr objectCreationExpr = new ObjectCreationExpr(null, ALIASFEELTYPE_CT, - arguments); - aliasFeelTypeVariableDeclarator.setInitializer(objectCreationExpr); - VariableDeclarationExpr mapVariableDeclarationExpr = new VariableDeclarationExpr(aliasFeelTypeVariableDeclarator); - addExpression(mapVariableDeclarationExpr, aliasFeelTypeVariableName); - return new NameExpr(aliasFeelTypeVariableName); - } + private Expression getAliasFEELType(AliasFEELType aliasFEELType) { + BuiltInType feelCType = aliasFEELType.getBuiltInType(); + Expression typeExpression = new FieldAccessExpr(BUILTINTYPE_E, feelCType.name()); + // Creating the AliasFEELType + String aliasFeelTypeVariableName = getNextVariableName(); + final VariableDeclarator aliasFeelTypeVariableDeclarator = + new VariableDeclarator(ALIASFEELTYPE_CT, aliasFeelTypeVariableName); + NodeList arguments = NodeList.nodeList(new StringLiteralExpr(aliasFEELType.getName()), + typeExpression); + final ObjectCreationExpr objectCreationExpr = new ObjectCreationExpr(null, ALIASFEELTYPE_CT, + arguments); + aliasFeelTypeVariableDeclarator.setInitializer(objectCreationExpr); + VariableDeclarationExpr mapVariableDeclarationExpr = + new VariableDeclarationExpr(aliasFeelTypeVariableDeclarator); + addExpression(mapVariableDeclarationExpr, aliasFeelTypeVariableName); + return new NameExpr(aliasFeelTypeVariableName); + } private Expression getJavaBackedTypeExpression(JavaBackedType javaBackedType) { // Creating the JavaBackedType @@ -613,16 +627,22 @@ 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); + if (!objectCache.containsKey(object)) { + String variableName = getNextVariableName(); + Expression objectExpression = CodegenUtils.getObjectExpression(object, variableName); + addExpression(objectExpression, variableName); + objectCache.put(object, new NameExpr(lastVariableName.get())); + } + return objectCache.get(object); } private Expression getNodeExpression(BaseNode node) { if (node != null) { - node.accept(astCompilerVisitor); - return new NameExpr(lastVariableName.get()); + if (!baseNodeCache.containsKey(node)) { + node.accept(astCompilerVisitor); + baseNodeCache.put(node, new NameExpr(lastVariableName.get())); + } + return baseNodeCache.get(node); } else { return new NullLiteralExpr(); } 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 2674c7cab2b..0fe22298101 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 @@ -136,7 +136,6 @@ public T compileUnit(String cuPackage, String cuClass, CompilationUnit cu) Class loaded = (Class) new TemplateLoader(Thread.currentThread().getContextClassLoader()).load(pStore, fqnClassName); - return loaded.newInstance(); } catch (Exception e) { LOG.error("Exception", e); diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/BaseNode.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/BaseNode.java index 05a116b26c4..9929e2b0281 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/BaseNode.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/BaseNode.java @@ -18,6 +18,7 @@ */ package org.kie.dmn.feel.lang.ast; +import java.util.Objects; import java.util.function.Supplier; import org.antlr.v4.runtime.ParserRuleContext; @@ -162,4 +163,20 @@ public ASTNode[] getChildrenNode() { public T accept(Visitor v) { return v.visit(this); } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof BaseNode baseNode)) { + return false; + } + return Objects.equals(this.getClass(), o.getClass()) && Objects.equals(text, baseNode.text); + } + + @Override + public int hashCode() { + return Objects.hash(text); + } }