From 4cf1a5354b5d7299706afb99cf231829c05ece34 Mon Sep 17 00:00:00 2001 From: Edoardo Vacchi Date: Thu, 7 Jun 2018 16:46:40 +0200 Subject: [PATCH 1/5] DROOLS-1701 fix: ranges cannot be (always) promoted to fields it won't work if boundaries are non-constants! --- .../codegen/feel11/DirectCompilerVisitor.java | 58 ++++++++++--------- .../org/kie/dmn/feel/lang/ast/RangeNode.java | 7 +++ 2 files changed, 39 insertions(+), 26 deletions(-) diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/DirectCompilerVisitor.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/DirectCompilerVisitor.java index 7a799d2543f..adaedd4cd47 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/DirectCompilerVisitor.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/DirectCompilerVisitor.java @@ -75,7 +75,6 @@ import org.kie.dmn.feel.parser.feel11.FEEL_1_1Parser.KeyNameContext; import org.kie.dmn.feel.parser.feel11.FEEL_1_1Parser.NameRefContext; import org.kie.dmn.feel.parser.feel11.ParserHelper; -import org.kie.dmn.feel.runtime.Range; import org.kie.dmn.feel.runtime.UnaryTest; import org.kie.dmn.feel.runtime.impl.RangeImpl; import org.kie.dmn.feel.util.EvalHelper; @@ -91,6 +90,9 @@ public class DirectCompilerVisitor extends FEEL_1_1BaseVisitor"); + private static final Expression BOUNDARY_CLOSED = JavaParser.parseExpression(org.kie.dmn.feel.runtime.Range.RangeBoundary.class.getCanonicalName() + ".CLOSED"); + private static final Expression BOUNDARY_OPEN = JavaParser.parseExpression(org.kie.dmn.feel.runtime.Range.RangeBoundary.class.getCanonicalName() + ".OPEN"); + // TODO as this is now compiled it might not be needed for this compilation strategy, just need the layer 0 of input Types, but to be checked. private ScopeHelper scopeHelper; private boolean replaceEqualForUnaryTest = false; @@ -479,34 +481,38 @@ public DirectCompilerResult visitExpressionList(FEEL_1_1Parser.ExpressionListCon public DirectCompilerResult visitInterval(FEEL_1_1Parser.IntervalContext ctx) { DirectCompilerResult start = visit(ctx.start); DirectCompilerResult end = visit(ctx.end); - RangeNode.IntervalBoundary low = ctx.low.getText().equals("[") ? RangeNode.IntervalBoundary.CLOSED : RangeNode.IntervalBoundary.OPEN; - RangeNode.IntervalBoundary up = ctx.up.getText().equals("]") ? RangeNode.IntervalBoundary.CLOSED : RangeNode.IntervalBoundary.OPEN; - - Expression BOUNDARY_CLOSED = JavaParser.parseExpression(org.kie.dmn.feel.runtime.Range.RangeBoundary.class.getCanonicalName() + ".CLOSED"); - Expression BOUNDARY_OPEN = JavaParser.parseExpression(org.kie.dmn.feel.runtime.Range.RangeBoundary.class.getCanonicalName() + ".OPEN"); - - String originalText = ParserHelper.getOriginalText(ctx); - ObjectCreationExpr initializer = new ObjectCreationExpr(); - initializer.setType(JavaParser.parseClassOrInterfaceType(RangeImpl.class.getCanonicalName())); - initializer.addArgument(low == IntervalBoundary.CLOSED ? BOUNDARY_CLOSED : BOUNDARY_OPEN); - initializer.addArgument(start.getExpression()); - initializer.addArgument(end.getExpression()); - initializer.addArgument(up == IntervalBoundary.CLOSED ? BOUNDARY_CLOSED : BOUNDARY_OPEN); - String constantName = "RANGE_" + CodegenStringUtil.escapeIdentifier(originalText); - VariableDeclarator vd = new VariableDeclarator(JavaParser.parseClassOrInterfaceType(Range.class.getCanonicalName()), constantName); - vd.setInitializer(initializer); - FieldDeclaration fd = new FieldDeclaration(); - fd.setModifier(Modifier.PUBLIC, true); - fd.setModifier(Modifier.STATIC, true); - fd.setModifier(Modifier.FINAL, true); - fd.addVariable(vd); + Expression lowBoundary = boundaryOf( + RangeNode.IntervalBoundary.lowBoundaryOf( + ctx.low.getText())); + Expression highBoundary = + new CastExpr( + JavaParser.parseType(Comparable.class.getCanonicalName()), + start.getExpression()); + Expression lowEndPoint = + new CastExpr( + JavaParser.parseType(Comparable.class.getCanonicalName()), + end.getExpression()); + Expression highEndPoint = boundaryOf( + RangeNode.IntervalBoundary.highBoundaryOf( + ctx.up.getText())); + + ObjectCreationExpr initializer = + new ObjectCreationExpr() + .setType(JavaParser.parseClassOrInterfaceType(RangeImpl.class.getCanonicalName())) + .addArgument(lowBoundary) + .addArgument(highBoundary) + .addArgument(lowEndPoint) + .addArgument(highEndPoint); - fd.setJavadocComment(" FEEL range: " + originalText + " "); + return DirectCompilerResult.of( + initializer, + BuiltInType.RANGE, + DirectCompilerResult.mergeFDs(start, end)); + } - DirectCompilerResult directCompilerResult = DirectCompilerResult.of(new NameExpr(constantName), BuiltInType.RANGE, DirectCompilerResult.mergeFDs(start, end)); - directCompilerResult.addFieldDesclaration(fd); - return directCompilerResult; + private Expression boundaryOf(IntervalBoundary low) { + return low == IntervalBoundary.CLOSED ? BOUNDARY_CLOSED : BOUNDARY_OPEN; } @Override diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/RangeNode.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/RangeNode.java index 284b314590b..0d3a6792a66 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/RangeNode.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/RangeNode.java @@ -33,6 +33,13 @@ public class RangeNode public static enum IntervalBoundary { OPEN, CLOSED; + public static IntervalBoundary lowBoundaryOf(String input) { + return "[".equals(input) ? CLOSED : OPEN; + } + public static IntervalBoundary highBoundaryOf(String input) { + return "]".equals(input) ? CLOSED : OPEN; + } + } private IntervalBoundary lowerBound; From 4681dbdcc51df7e60efd74df3d5800a2f0eeb346 Mon Sep 17 00:00:00 2001 From: Edoardo Vacchi Date: Fri, 8 Jun 2018 10:37:21 +0200 Subject: [PATCH 2/5] DROOLS-1701 fix: use parenthesized expression in cast (ranges) --- .../codegen/feel11/DirectCompilerVisitor.java | 80 ++++++++++++++----- .../org/kie/dmn/feel/lang/ast/RangeNode.java | 8 +- 2 files changed, 64 insertions(+), 24 deletions(-) diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/DirectCompilerVisitor.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/DirectCompilerVisitor.java index adaedd4cd47..0b17bf60b9a 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/DirectCompilerVisitor.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/DirectCompilerVisitor.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Deque; +import java.util.EnumSet; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -75,6 +76,7 @@ import org.kie.dmn.feel.parser.feel11.FEEL_1_1Parser.KeyNameContext; import org.kie.dmn.feel.parser.feel11.FEEL_1_1Parser.NameRefContext; import org.kie.dmn.feel.parser.feel11.ParserHelper; +import org.kie.dmn.feel.runtime.Range; import org.kie.dmn.feel.runtime.UnaryTest; import org.kie.dmn.feel.runtime.impl.RangeImpl; import org.kie.dmn.feel.util.EvalHelper; @@ -93,6 +95,9 @@ public class DirectCompilerVisitor extends FEEL_1_1BaseVisitor fieldDeclarations = + DirectCompilerResult.mergeFDs(start, end); + fieldDeclarations.add(rangeField); + + return DirectCompilerResult.of( + new NameExpr( + rangeField.getVariable(0) + .getName().asString()), + BuiltInType.RANGE, + fieldDeclarations); + } else { + return DirectCompilerResult.of( + initializer, + BuiltInType.RANGE, + DirectCompilerResult.mergeFDs(start, end)); + } - return DirectCompilerResult.of( - initializer, - BuiltInType.RANGE, - DirectCompilerResult.mergeFDs(start, end)); } - private Expression boundaryOf(IntervalBoundary low) { + private FieldDeclaration fieldDeclarationOf(String prefix, String originalText, ObjectCreationExpr initializer) { + String constantName = prefix + "_" + CodegenStringUtil.escapeIdentifier(originalText); + return new FieldDeclaration( + EnumSet.of(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL), + new VariableDeclarator( + JavaParser.parseClassOrInterfaceType(Range.class.getCanonicalName()), + constantName, + initializer)) + .setJavadocComment(" FEEL range: " + originalText + " "); + } + + private Expression expressionBoundaryOf(IntervalBoundary low) { return low == IntervalBoundary.CLOSED ? BOUNDARY_CLOSED : BOUNDARY_OPEN; } + private boolean isNumericConstant(DirectCompilerResult r) { + // FIXME: this is a bit arbitrary, maybe we should turn this into a flag in `r` + return r.getExpression().isNameExpr() && + r.resultType.equals(BuiltInType.NUMBER) && + r.getFieldDeclarations().size() > 0; + } + @Override public DirectCompilerResult visitPositiveUnaryTestIneq(FEEL_1_1Parser.PositiveUnaryTestIneqContext ctx) { DirectCompilerResult endpoint = visit(ctx.endpoint()); diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/RangeNode.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/RangeNode.java index 0d3a6792a66..f72250d9e4b 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/RangeNode.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/RangeNode.java @@ -33,13 +33,9 @@ public class RangeNode public static enum IntervalBoundary { OPEN, CLOSED; - public static IntervalBoundary lowBoundaryOf(String input) { - return "[".equals(input) ? CLOSED : OPEN; + public static IntervalBoundary fromString(String input) { + return "[".equals(input) || "]".equals(input) ? CLOSED : OPEN; } - public static IntervalBoundary highBoundaryOf(String input) { - return "]".equals(input) ? CLOSED : OPEN; - } - } private IntervalBoundary lowerBound; From 4f6a190331d7c9ba0d0289970fd418c6413c52c6 Mon Sep 17 00:00:00 2001 From: Edoardo Vacchi Date: Fri, 8 Jun 2018 11:24:45 +0200 Subject: [PATCH 3/5] DROOLS-1701 Comparable: do not cast in source code, check in RangeImpl -- for now --- .../codegen/feel11/DirectCompilerVisitor.java | 8 ++----- .../kie/dmn/feel/runtime/impl/RangeImpl.java | 22 +++++++++++++++++++ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/DirectCompilerVisitor.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/DirectCompilerVisitor.java index 0b17bf60b9a..9736f2a4a07 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/DirectCompilerVisitor.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/DirectCompilerVisitor.java @@ -490,12 +490,8 @@ public DirectCompilerResult visitInterval(FEEL_1_1Parser.IntervalContext ctx) { Expression lowBoundary = expressionBoundaryOf( RangeNode.IntervalBoundary.fromString( ctx.low.getText())); - Expression lowEndPoint = - new CastExpr(TYPE_COMPARABLE, - new EnclosedExpr(start.getExpression())); - Expression highEndPoint = - new CastExpr(TYPE_COMPARABLE, - new EnclosedExpr(end.getExpression())); + Expression lowEndPoint = start.getExpression(); + Expression highEndPoint = end.getExpression(); Expression highBoundary = expressionBoundaryOf( RangeNode.IntervalBoundary.fromString( ctx.up.getText())); diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/impl/RangeImpl.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/impl/RangeImpl.java index d907e8bc92b..23c3de08d4d 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/impl/RangeImpl.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/impl/RangeImpl.java @@ -16,6 +16,9 @@ package org.kie.dmn.feel.runtime.impl; +import java.time.Period; + +import org.kie.dmn.feel.lang.ast.RangeNode; import org.kie.dmn.feel.runtime.Range; public class RangeImpl @@ -36,6 +39,25 @@ public RangeImpl(RangeBoundary lowBoundary, Comparable lowEndPoint, Comparable h this.highEndPoint = highEndPoint; } + public RangeImpl(RangeBoundary lowBoundary, Object lowEndPoint, Object highEndPoint, RangeBoundary highBoundary) { + this.lowBoundary = lowBoundary; + this.highBoundary = highBoundary; + this.lowEndPoint = asComparable(lowEndPoint); + this.highEndPoint = asComparable(highEndPoint); + } + + private Comparable asComparable(Object s) { + if (s instanceof Comparable) { + return (Comparable) s; + } else if (s instanceof Period) { + // period has special semantics + return new RangeNode.ComparablePeriod((Period) s); + } else { + // FIXME report error + return null; + } + } + @Override public RangeBoundary getLowBoundary() { return lowBoundary; From f6123532fc620c0606dadb8cc231530dc9fcb5cd Mon Sep 17 00:00:00 2001 From: Edoardo Vacchi Date: Fri, 8 Jun 2018 11:57:30 +0200 Subject: [PATCH 4/5] DROOLS-1701 Use ObjectCreation for numeric constants, factory method otherwise --- .../codegen/feel11/DirectCompilerVisitor.java | 29 ++++++++---- .../kie/dmn/feel/runtime/impl/RangeImpl.java | 46 +++++++++++++------ 2 files changed, 51 insertions(+), 24 deletions(-) diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/DirectCompilerVisitor.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/DirectCompilerVisitor.java index 9736f2a4a07..f32600606ee 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/DirectCompilerVisitor.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/DirectCompilerVisitor.java @@ -496,19 +496,18 @@ public DirectCompilerResult visitInterval(FEEL_1_1Parser.IntervalContext ctx) { RangeNode.IntervalBoundary.fromString( ctx.up.getText())); - ObjectCreationExpr initializer = - new ObjectCreationExpr() - .setType(JavaParser.parseClassOrInterfaceType(RangeImpl.class.getCanonicalName())) - .addArgument(lowBoundary) - .addArgument(lowEndPoint) - .addArgument(highEndPoint) - .addArgument(highBoundary); - - // if this is a range of type i..j with i,j numbers: // then we make it a constant; otherwise we fallback // to the general case of creating the Range object at runtime if (isNumericConstant(start) && isNumericConstant(end)) { + ObjectCreationExpr initializer = + new ObjectCreationExpr() + .setType(JavaParser.parseClassOrInterfaceType(RangeImpl.class.getCanonicalName())) + .addArgument(lowBoundary) + .addArgument(new CastExpr(TYPE_COMPARABLE, lowEndPoint)) + .addArgument(new CastExpr(TYPE_COMPARABLE, highEndPoint)) + .addArgument(highBoundary); + FieldDeclaration rangeField = fieldDeclarationOf( "RANGE", @@ -525,6 +524,16 @@ public DirectCompilerResult visitInterval(FEEL_1_1Parser.IntervalContext ctx) { BuiltInType.RANGE, fieldDeclarations); } else { + MethodCallExpr initializer = + new MethodCallExpr( + new NameExpr(RangeImpl.class.getCanonicalName()), + "of", new NodeList<>( + new NameExpr("feelExprCtx"), + lowBoundary, + lowEndPoint, + highEndPoint, + highBoundary)); + return DirectCompilerResult.of( initializer, BuiltInType.RANGE, @@ -533,7 +542,7 @@ public DirectCompilerResult visitInterval(FEEL_1_1Parser.IntervalContext ctx) { } - private FieldDeclaration fieldDeclarationOf(String prefix, String originalText, ObjectCreationExpr initializer) { + private FieldDeclaration fieldDeclarationOf(String prefix, String originalText, Expression initializer) { String constantName = prefix + "_" + CodegenStringUtil.escapeIdentifier(originalText); return new FieldDeclaration( EnumSet.of(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL), diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/impl/RangeImpl.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/impl/RangeImpl.java index 23c3de08d4d..9a523ece3ab 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/impl/RangeImpl.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/impl/RangeImpl.java @@ -18,8 +18,12 @@ import java.time.Period; +import org.kie.dmn.api.feel.runtime.events.FEELEvent; +import org.kie.dmn.feel.lang.EvaluationContext; import org.kie.dmn.feel.lang.ast.RangeNode; import org.kie.dmn.feel.runtime.Range; +import org.kie.dmn.feel.runtime.events.ASTEventBase; +import org.kie.dmn.feel.util.Msg; public class RangeImpl implements Range { @@ -29,24 +33,28 @@ public class RangeImpl private Comparable lowEndPoint; private Comparable highEndPoint; - public RangeImpl() { - } - - public RangeImpl(RangeBoundary lowBoundary, Comparable lowEndPoint, Comparable highEndPoint, RangeBoundary highBoundary) { - this.lowBoundary = lowBoundary; - this.highBoundary = highBoundary; - this.lowEndPoint = lowEndPoint; - this.highEndPoint = highEndPoint; + public static RangeImpl of(EvaluationContext ctx, RangeBoundary lowBoundary, Object lowEndPoint, Object highEndPoint, RangeBoundary highBoundary) { + Comparable left = asComparable(lowEndPoint); + Comparable right = asComparable(highEndPoint); + if (left == null || right == null || !compatible(left, right)) { + ctx.notifyEvt( () -> new ASTEventBase(FEELEvent.Severity.ERROR, Msg.createMessage(Msg.INCOMPATIBLE_TYPE_FOR_RANGE, left.getClass().getSimpleName() ), null)); + return null; + } + return new RangeImpl( + lowBoundary, + left, + right, + highBoundary); } - public RangeImpl(RangeBoundary lowBoundary, Object lowEndPoint, Object highEndPoint, RangeBoundary highBoundary) { - this.lowBoundary = lowBoundary; - this.highBoundary = highBoundary; - this.lowEndPoint = asComparable(lowEndPoint); - this.highEndPoint = asComparable(highEndPoint); + private static boolean compatible(Comparable left, Comparable right) { + Class leftClass = left.getClass(); + Class rightClass = right.getClass(); + return leftClass.isAssignableFrom(rightClass) + || rightClass.isAssignableFrom(leftClass); } - private Comparable asComparable(Object s) { + private static Comparable asComparable(Object s) { if (s instanceof Comparable) { return (Comparable) s; } else if (s instanceof Period) { @@ -58,6 +66,16 @@ private Comparable asComparable(Object s) { } } + public RangeImpl() { + } + + public RangeImpl(RangeBoundary lowBoundary, Comparable lowEndPoint, Comparable highEndPoint, RangeBoundary highBoundary) { + this.lowBoundary = lowBoundary; + this.highBoundary = highBoundary; + this.lowEndPoint = lowEndPoint; + this.highEndPoint = highEndPoint; + } + @Override public RangeBoundary getLowBoundary() { return lowBoundary; From 69d020d2e0388fc5353f41ec1d37409cbd684fa1 Mon Sep 17 00:00:00 2001 From: Edoardo Vacchi Date: Fri, 8 Jun 2018 15:04:48 +0200 Subject: [PATCH 5/5] DROOLS-1701 move range() factory to CompiledFEELSemanticMappings --- .../feel11/CompiledFEELSemanticMappings.java | 56 +++++++++++++++++++ .../codegen/feel11/DirectCompilerVisitor.java | 4 +- .../kie/dmn/feel/runtime/impl/RangeImpl.java | 39 ------------- 3 files changed, 58 insertions(+), 41 deletions(-) diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/CompiledFEELSemanticMappings.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/CompiledFEELSemanticMappings.java index f64b97f4fb8..73488e00c1e 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/CompiledFEELSemanticMappings.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/CompiledFEELSemanticMappings.java @@ -17,18 +17,74 @@ package org.kie.dmn.feel.codegen.feel11; import java.math.BigDecimal; +import java.time.Period; import java.util.ArrayList; import java.util.List; +import org.kie.dmn.api.feel.runtime.events.FEELEvent; +import org.kie.dmn.feel.lang.EvaluationContext; import org.kie.dmn.feel.lang.ast.InfixOpNode; +import org.kie.dmn.feel.lang.ast.RangeNode; +import org.kie.dmn.feel.runtime.Range; import org.kie.dmn.feel.runtime.UnaryTest; +import org.kie.dmn.feel.runtime.events.ASTEventBase; +import org.kie.dmn.feel.runtime.impl.RangeImpl; import org.kie.dmn.feel.util.EvalHelper; +import org.kie.dmn.feel.util.Msg; /** * The purpose of this class is to offer import .* methods to compiled FEEL classes compiling expressions. * Implementing DMN FEEL spec chapter 10.3.2.12 Semantic mappings */ public class CompiledFEELSemanticMappings { + + /** + * Represents a [n..m] construct + */ + public static RangeImpl range( + EvaluationContext ctx, + Range.RangeBoundary lowBoundary, + Object lowEndPoint, + Object highEndPoint, + Range.RangeBoundary highBoundary) { + + Comparable left = asComparable(lowEndPoint); + Comparable right = asComparable(highEndPoint); + if (left == null || right == null || !compatible(left, right)) { + ctx.notifyEvt( () -> new ASTEventBase( + FEELEvent.Severity.ERROR, + Msg.createMessage( + Msg.INCOMPATIBLE_TYPE_FOR_RANGE, + left.getClass().getSimpleName() + ), + null)); + return null; + } + return new RangeImpl( + lowBoundary, + left, + right, + highBoundary); + } + + private static boolean compatible(Comparable left, Comparable right) { + Class leftClass = left.getClass(); + Class rightClass = right.getClass(); + return leftClass.isAssignableFrom(rightClass) + || rightClass.isAssignableFrom(leftClass); + } + + private static Comparable asComparable(Object s) { + if (s instanceof Comparable) { + return (Comparable) s; + } else if (s instanceof Period) { + // period has special semantics + return new RangeNode.ComparablePeriod((Period) s); + } else { + // FIXME report error + return null; + } + } /** * Represent a [e1, e2, e3] construct. diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/DirectCompilerVisitor.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/DirectCompilerVisitor.java index f32600606ee..b18bdd4da0b 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/DirectCompilerVisitor.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/DirectCompilerVisitor.java @@ -526,8 +526,8 @@ public DirectCompilerResult visitInterval(FEEL_1_1Parser.IntervalContext ctx) { } else { MethodCallExpr initializer = new MethodCallExpr( - new NameExpr(RangeImpl.class.getCanonicalName()), - "of", new NodeList<>( + null, + "range", new NodeList<>( new NameExpr("feelExprCtx"), lowBoundary, lowEndPoint, diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/impl/RangeImpl.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/impl/RangeImpl.java index 9a523ece3ab..208b0af8b4b 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/impl/RangeImpl.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/impl/RangeImpl.java @@ -16,14 +16,7 @@ package org.kie.dmn.feel.runtime.impl; -import java.time.Period; - -import org.kie.dmn.api.feel.runtime.events.FEELEvent; -import org.kie.dmn.feel.lang.EvaluationContext; -import org.kie.dmn.feel.lang.ast.RangeNode; import org.kie.dmn.feel.runtime.Range; -import org.kie.dmn.feel.runtime.events.ASTEventBase; -import org.kie.dmn.feel.util.Msg; public class RangeImpl implements Range { @@ -33,38 +26,6 @@ public class RangeImpl private Comparable lowEndPoint; private Comparable highEndPoint; - public static RangeImpl of(EvaluationContext ctx, RangeBoundary lowBoundary, Object lowEndPoint, Object highEndPoint, RangeBoundary highBoundary) { - Comparable left = asComparable(lowEndPoint); - Comparable right = asComparable(highEndPoint); - if (left == null || right == null || !compatible(left, right)) { - ctx.notifyEvt( () -> new ASTEventBase(FEELEvent.Severity.ERROR, Msg.createMessage(Msg.INCOMPATIBLE_TYPE_FOR_RANGE, left.getClass().getSimpleName() ), null)); - return null; - } - return new RangeImpl( - lowBoundary, - left, - right, - highBoundary); - } - - private static boolean compatible(Comparable left, Comparable right) { - Class leftClass = left.getClass(); - Class rightClass = right.getClass(); - return leftClass.isAssignableFrom(rightClass) - || rightClass.isAssignableFrom(leftClass); - } - - private static Comparable asComparable(Object s) { - if (s instanceof Comparable) { - return (Comparable) s; - } else if (s instanceof Period) { - // period has special semantics - return new RangeNode.ComparablePeriod((Period) s); - } else { - // FIXME report error - return null; - } - } public RangeImpl() { }