Skip to content

Commit

Permalink
DROOLS-1701 fixes to between and in (esp. with null handling) (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
evacchi authored and mariofusco committed Jul 5, 2018
1 parent a75cf2a commit 200b1ae
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,27 @@ public static RangeImpl range(
highBoundary);
}

public static Boolean includes(
EvaluationContext ctx,
Object range,
Object param) {
if (range instanceof Range) {
return ((Range) range).includes(param);
} else if (range instanceof List) {
return ((List) range).contains(param);
} else if (range == null){
ctx.notifyEvt( () -> new ASTEventBase(
FEELEvent.Severity.ERROR,
Msg.createMessage(
Msg.IS_NULL,
"range"),
null));
return null;
} else {
return list(range).contains(param);
}
}

private static boolean compatible(Comparable left, Comparable right) {
Class<?> leftClass = left.getClass();
Class<?> rightClass = right.getClass();
Expand Down Expand Up @@ -220,18 +241,23 @@ public static Boolean eq(Object left, Object right) {
return EvalHelper.isEqual(left, right, null);
}

public static Boolean between(Object val, Object s, Object e) {
if (!val.getClass().isAssignableFrom(s.getClass())) {
// TODO here in the original code "interpreted" there was an error reporting utility.
public static Boolean between(EvaluationContext ctx,
Object value, Object start, Object end) {
if ( value == null ) { ctx.notifyEvt(() -> new ASTEventBase(FEELEvent.Severity.ERROR, Msg.createMessage(Msg.IS_NULL, "value"), null) ); return null; }
if ( start == null ) { ctx.notifyEvt(() -> new ASTEventBase(FEELEvent.Severity.ERROR, Msg.createMessage(Msg.IS_NULL, "start"), null) ); return null; }
if ( end == null ) { ctx.notifyEvt(() -> new ASTEventBase(FEELEvent.Severity.ERROR, Msg.createMessage(Msg.IS_NULL, "end"), null) ); return null; }

if (!value.getClass().isAssignableFrom(start.getClass())) {
ctx.notifyEvt(() -> new ASTEventBase(FEELEvent.Severity.ERROR, Msg.createMessage(Msg.X_TYPE_INCOMPATIBLE_WITH_Y_TYPE, "value", "start"), null) );
return null;
}

if (!val.getClass().isAssignableFrom(e.getClass())) {
// TODO here in the original code "interpreted" there was an error reporting utility.
if (!value.getClass().isAssignableFrom(end.getClass())) {
ctx.notifyEvt(() -> new ASTEventBase(FEELEvent.Severity.ERROR, Msg.createMessage(Msg.X_TYPE_INCOMPATIBLE_WITH_Y_TYPE, "value", "end"), null) );
return null;
}

return gte(val, s) && lte(val, e);
return gte(value, start) && lte(value, end);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@
import org.drools.javaparser.ast.type.UnknownType;
import org.kie.dmn.feel.lang.CompositeType;
import org.kie.dmn.feel.lang.Type;
import org.kie.dmn.feel.lang.ast.BaseNode;
import org.kie.dmn.feel.lang.ast.InfixOpNode.InfixOperator;
import org.kie.dmn.feel.lang.ast.RangeNode;
import org.kie.dmn.feel.lang.ast.RangeNode.IntervalBoundary;
Expand Down Expand Up @@ -98,6 +97,8 @@ public class DirectCompilerVisitor extends FEEL_1_1BaseVisitor<DirectCompilerRes

private static final org.drools.javaparser.ast.type.Type TYPE_COMPARABLE =
JavaParser.parseType(Comparable.class.getCanonicalName());
private static final org.drools.javaparser.ast.type.Type TYPE_LIST =
JavaParser.parseType(List.class.getCanonicalName());

// 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;
Expand Down Expand Up @@ -435,11 +436,11 @@ public DirectCompilerResult visitRelExpressionBetween(FEEL_1_1Parser.RelExpressi
DirectCompilerResult start = visit(ctx.start);
DirectCompilerResult end = visit(ctx.end);
MethodCallExpr betweenCall = new MethodCallExpr(null, "between");
betweenCall.addArgument(new NameExpr("feelExprCtx"));
betweenCall.addArgument(value.getExpression());
betweenCall.addArgument(start.getExpression());
betweenCall.addArgument(end.getExpression());
Expression result = groundToNullIfAnyIsNull(betweenCall, value.getExpression(), start.getExpression(), end.getExpression());
return DirectCompilerResult.of(result, BuiltInType.BOOLEAN).withFD(value).withFD(start).withFD(end);
return DirectCompilerResult.of(betweenCall, BuiltInType.BOOLEAN).withFD(value).withFD(start).withFD(end);
}

/**
Expand Down Expand Up @@ -483,10 +484,11 @@ public DirectCompilerResult visitRelExpressionValueList(FEEL_1_1Parser.RelExpres
DirectCompilerResult value = visit(ctx.val);
DirectCompilerResult list = visit(ctx.expressionList());

MethodCallExpr expression = new MethodCallExpr(
list.getExpression(),
"contains",
new NodeList<>(value.getExpression()));
MethodCallExpr expression =
new MethodCallExpr(
list.getExpression(),
"contains",
new NodeList<>(value.getExpression()));

return DirectCompilerResult.of(
expression,
Expand Down Expand Up @@ -700,17 +702,23 @@ public DirectCompilerResult visitRelExpressionValue(FEEL_1_1Parser.RelExpression
DirectCompilerResult value = visit(ctx.val);
DirectCompilerResult expr = visit(ctx.expression());

MethodCallExpr expression;
Expression expression;
if (expr.resultType.equals(BuiltInType.LIST)) {
expression = new MethodCallExpr(
expr.getExpression(),
new EnclosedExpr(
new CastExpr(
TYPE_LIST,
expr.getExpression())),
"contains",
new NodeList<>(value.getExpression()));
} else {
expression = new MethodCallExpr(
expr.getExpression(),
"equals",
new NodeList<>(value.getExpression()));
null,
"includes",
new NodeList<>(
new NameExpr("feelExprCtx"),
expr.getExpression(),
value.getExpression()));
}

return DirectCompilerResult.of(
Expand Down

0 comments on commit 200b1ae

Please sign in to comment.