Search in sources :

Example 1 with InvalidExpressionErrorResult

use of org.drools.modelcompiler.builder.errors.InvalidExpressionErrorResult in project drools by kiegroup.

the class DrlxParseUtil method getExpressionType.

public static Class<?> getExpressionType(RuleContext context, TypeResolver typeResolver, Expression expr, Collection<String> usedDeclarations) {
    if (expr instanceof LiteralExpr) {
        return getLiteralExpressionType((LiteralExpr) expr);
    }
    if (expr instanceof ArrayAccessExpr) {
        return getClassFromContext(typeResolver, ((ArrayCreationExpr) ((ArrayAccessExpr) expr).getName()).getElementType().asString());
    }
    if (expr instanceof ArrayCreationExpr) {
        return getClassFromContext(typeResolver, ((ArrayCreationExpr) expr).getElementType().asString());
    }
    if (expr instanceof NameExpr) {
        String name = ((NameExpr) expr).getNameAsString();
        if (usedDeclarations != null) {
            usedDeclarations.add(name);
        }
        return context.getDeclarationById(name).map(DeclarationSpec::getDeclarationClass).get();
    }
    if (expr instanceof MethodCallExpr) {
        MethodCallExpr methodCallExpr = (MethodCallExpr) expr;
        Class<?> scopeType = getExpressionType(context, typeResolver, methodCallExpr.getScope().get(), usedDeclarations);
        return returnTypeOfMethodCallExpr(context, typeResolver, methodCallExpr, scopeType, usedDeclarations);
    }
    if (expr instanceof ObjectCreationExpr) {
        final ClassOrInterfaceType type = ((ObjectCreationExpr) expr).getType();
        return getClassFromContext(typeResolver, type.asString());
    }
    if (expr.isCastExpr()) {
        String typeName = expr.asCastExpr().getType().toString();
        try {
            return typeResolver.resolveType(expr.asCastExpr().getType().toString());
        } catch (ClassNotFoundException e) {
            context.addCompilationError(new InvalidExpressionErrorResult("Unknown type in cast expression: " + typeName));
            throw new RuntimeException("Unknown type in cast expression: " + typeName);
        }
    }
    throw new RuntimeException("Unknown expression type: " + expr);
}
Also used : ObjectCreationExpr(org.drools.javaparser.ast.expr.ObjectCreationExpr) InvalidExpressionErrorResult(org.drools.modelcompiler.builder.errors.InvalidExpressionErrorResult) ArrayAccessExpr(org.drools.javaparser.ast.expr.ArrayAccessExpr) ExpressionTyper.findLeftLeafOfNameExpr(org.drools.modelcompiler.builder.generator.expressiontyper.ExpressionTyper.findLeftLeafOfNameExpr) NameExpr(org.drools.javaparser.ast.expr.NameExpr) LiteralExpr(org.drools.javaparser.ast.expr.LiteralExpr) LongLiteralExpr(org.drools.javaparser.ast.expr.LongLiteralExpr) CharLiteralExpr(org.drools.javaparser.ast.expr.CharLiteralExpr) NullLiteralExpr(org.drools.javaparser.ast.expr.NullLiteralExpr) BooleanLiteralExpr(org.drools.javaparser.ast.expr.BooleanLiteralExpr) IntegerLiteralExpr(org.drools.javaparser.ast.expr.IntegerLiteralExpr) StringLiteralExpr(org.drools.javaparser.ast.expr.StringLiteralExpr) DoubleLiteralExpr(org.drools.javaparser.ast.expr.DoubleLiteralExpr) ClassOrInterfaceType(org.drools.javaparser.ast.type.ClassOrInterfaceType) ArrayCreationExpr(org.drools.javaparser.ast.expr.ArrayCreationExpr) MethodCallExpr(org.drools.javaparser.ast.expr.MethodCallExpr)

Example 2 with InvalidExpressionErrorResult

use of org.drools.modelcompiler.builder.errors.InvalidExpressionErrorResult in project drools by kiegroup.

the class ConstraintParser method getDrlxParseResult.

private DrlxParseResult getDrlxParseResult(Class<?> patternType, String bindingId, String expression, DrlxExpression drlx, boolean isPositional) {
    Expression drlxExpr = drlx.getExpr();
    boolean isEnclosed = false;
    while (drlxExpr instanceof EnclosedExpr) {
        drlxExpr = ((EnclosedExpr) drlxExpr).getInner();
        isEnclosed = true;
    }
    if (drlxExpr instanceof MethodCallExpr && !((MethodCallExpr) drlxExpr).getScope().isPresent() && ((MethodCallExpr) drlxExpr).getNameAsString().equals("eval")) {
        drlxExpr = ((MethodCallExpr) drlxExpr).getArgument(0);
    }
    String exprId;
    if (GENERATE_EXPR_ID) {
        exprId = context.getExprId(patternType, expression);
    }
    if (drlxExpr instanceof BinaryExpr) {
        BinaryExpr binaryExpr = (BinaryExpr) drlxExpr;
        BinaryExpr.Operator operator = binaryExpr.getOperator();
        IndexUtil.ConstraintType decodeConstraintType = DrlxParseUtil.toConstraintType(operator);
        final ExpressionTyperContext expressionTyperContext = new ExpressionTyperContext();
        final ExpressionTyper expressionTyper = new ExpressionTyper(context, patternType, bindingId, isPositional, expressionTyperContext);
        TypedExpressionResult leftTypedExpressionResult = expressionTyper.toTypedExpression(binaryExpr.getLeft());
        Optional<TypedExpression> optLeft = leftTypedExpressionResult.getTypedExpression();
        if (!optLeft.isPresent()) {
            return new DrlxParseFail();
        }
        List<String> usedDeclarationsOnLeft = drlx.getBind() == null ? null : new ArrayList<>(expressionTyperContext.getUsedDeclarations());
        TypedExpressionResult rightExpressionResult = expressionTyper.toTypedExpression(binaryExpr.getRight());
        Optional<TypedExpression> optRight = rightExpressionResult.getTypedExpression();
        if (!optRight.isPresent()) {
            context.addCompilationError(new ParseExpressionErrorResult(drlxExpr));
            return new DrlxParseFail();
        }
        TypedExpression left = optLeft.get();
        TypedExpression right = optRight.get();
        Expression combo;
        if (left.isPrimitive()) {
            if (!right.getType().isPrimitive() && !Number.class.isAssignableFrom(right.getType()) && !Boolean.class.isAssignableFrom(right.getType()) && !String.class.isAssignableFrom(right.getType())) {
                context.addCompilationError(new InvalidExpressionErrorResult("Comparison operation requires compatible types. Found " + left.getType() + " and " + right.getType()));
                return new DrlxParseFail();
            }
            if (right.getExpression() instanceof StringLiteralExpr) {
                right.setExpression(new IntegerLiteralExpr(((StringLiteralExpr) right.getExpression()).asString()));
            } else if (right.getExpression() instanceof LiteralStringValueExpr) {
                right.setExpression(coerceLiteralExprToType((LiteralStringValueExpr) right.getExpression(), left.getType()));
            }
            combo = new BinaryExpr(left.getExpression(), right.getExpression(), operator);
        } else {
            coerceRightExpression(left, right);
            switch(operator) {
                case EQUALS:
                case NOT_EQUALS:
                    combo = getEqualityExpression(left, right, operator);
                    break;
                default:
                    if (left.getExpression() == null || right.getExpression() == null) {
                        context.addCompilationError(new ParseExpressionErrorResult(drlxExpr));
                        return new DrlxParseFail();
                    }
                    combo = handleSpecialComparisonCases(operator, left, right);
            }
        }
        for (Expression e : leftTypedExpressionResult.getPrefixExpressions()) {
            combo = new BinaryExpr(e, combo, BinaryExpr.Operator.AND);
        }
        boolean isBetaNode = false;
        if (right.getExpression() instanceof BinaryExpr) {
            if (((BinaryExpr) right.getExpression()).getRight() instanceof MethodCallExpr) {
                isBetaNode = true;
            }
        } else if (right.getExpression() instanceof NameExpr) {
            isBetaNode = true;
        }
        if (isEnclosed) {
            combo = new EnclosedExpr(combo);
        }
        return new DrlxParseSuccess(patternType, exprId, bindingId, combo, left.getType()).setDecodeConstraintType(decodeConstraintType).setUsedDeclarations(expressionTyperContext.getUsedDeclarations()).setUsedDeclarationsOnLeft(usedDeclarationsOnLeft).setReactOnProperties(expressionTyperContext.getReactOnProperties()).setLeft(left).setRight(right).setBetaNode(isBetaNode);
    }
    if (drlxExpr instanceof UnaryExpr) {
        UnaryExpr unaryExpr = (UnaryExpr) drlxExpr;
        TypedExpressionResult typedExpressionResult = new ExpressionTyper(context, patternType, bindingId, isPositional).toTypedExpression(unaryExpr);
        return typedExpressionResult.getTypedExpression().<DrlxParseResult>map(left -> {
            return new DrlxParseSuccess(patternType, exprId, bindingId, left.getExpression(), left.getType()).setUsedDeclarations(typedExpressionResult.getUsedDeclarations()).setReactOnProperties(typedExpressionResult.getReactOnProperties()).setLeft(left);
        }).orElse(new DrlxParseFail());
    }
    if (drlxExpr instanceof PointFreeExpr) {
        PointFreeExpr pointFreeExpr = (PointFreeExpr) drlxExpr;
        TypedExpressionResult typedExpressionResult = new ExpressionTyper(context, patternType, bindingId, isPositional).toTypedExpression(pointFreeExpr);
        final Optional<TypedExpression> optTypedExpression = typedExpressionResult.getTypedExpression();
        return optTypedExpression.<DrlxParseResult>map(typedExpression -> {
            final Expression returnExpression = typedExpression.getExpression();
            final Class<?> returnType = typedExpression.getType();
            return new DrlxParseSuccess(patternType, exprId, bindingId, returnExpression, returnType).setUsedDeclarations(typedExpressionResult.getUsedDeclarations()).setReactOnProperties(typedExpressionResult.getReactOnProperties()).setLeft(typedExpression.getLeft()).setStatic(typedExpression.isStatic()).setValidExpression(true);
        }).orElse(new DrlxParseFail());
    }
    if (drlxExpr instanceof MethodCallExpr) {
        MethodCallExpr methodCallExpr = (MethodCallExpr) drlxExpr;
        // when the methodCallExpr will be placed in the model/DSL, any parameter being a "this" need to be implemented as _this by convention.
        List<ThisExpr> rewriteThisExprs = recurseCollectArguments(methodCallExpr).stream().filter(ThisExpr.class::isInstance).map(ThisExpr.class::cast).collect(Collectors.toList());
        for (ThisExpr t : rewriteThisExprs) {
            methodCallExpr.replace(t, new NameExpr("_this"));
        }
        Optional<MethodDeclaration> functionCall = packageModel.getFunctions().stream().filter(m -> m.getName().equals(methodCallExpr.getName())).findFirst();
        if (functionCall.isPresent()) {
            Class<?> returnType = DrlxParseUtil.getClassFromContext(context.getTypeResolver(), functionCall.get().getType().asString());
            NodeList<Expression> arguments = methodCallExpr.getArguments();
            List<String> usedDeclarations = new ArrayList<>();
            for (Expression arg : arguments) {
                if (arg instanceof NameExpr && !arg.toString().equals("_this")) {
                    usedDeclarations.add(arg.toString());
                } else if (arg instanceof MethodCallExpr) {
                    TypedExpressionResult typedExpressionResult = new ExpressionTyper(context, null, bindingId, isPositional).toTypedExpression(arg);
                    usedDeclarations.addAll(typedExpressionResult.getUsedDeclarations());
                }
            }
            return new DrlxParseSuccess(patternType, exprId, bindingId, methodCallExpr, returnType).setUsedDeclarations(usedDeclarations);
        } else if (methodCallExpr.getScope().isPresent() && methodCallExpr.getScope().get() instanceof StringLiteralExpr) {
            TypedExpressionResult typedExpressionResult = new ExpressionTyper(context, String.class, bindingId, isPositional).toTypedExpression(methodCallExpr);
            Optional<TypedExpression> optConverted = typedExpressionResult.getTypedExpression();
            return optConverted.<DrlxParseResult>map(converted -> {
                return new DrlxParseSuccess(String.class, exprId, bindingId, converted.getExpression(), converted.getType()).setLeft(converted).setUsedDeclarations(typedExpressionResult.getUsedDeclarations());
            }).orElse(new DrlxParseFail());
        } else if (patternType != null) {
            NameExpr _this = new NameExpr("_this");
            TypedExpression converted = DrlxParseUtil.toMethodCallWithClassCheck(context, methodCallExpr, bindingId, patternType, context.getTypeResolver());
            Expression withThis = DrlxParseUtil.prepend(_this, converted.getExpression());
            return new DrlxParseSuccess(patternType, exprId, bindingId, withThis, converted.getType()).setLeft(converted);
        } else {
            return new DrlxParseSuccess(patternType, exprId, bindingId, methodCallExpr, null);
        }
    }
    if (drlxExpr instanceof FieldAccessExpr) {
        FieldAccessExpr fieldCallExpr = (FieldAccessExpr) drlxExpr;
        NameExpr _this = new NameExpr("_this");
        TypedExpression converted = DrlxParseUtil.toMethodCallWithClassCheck(context, fieldCallExpr, bindingId, patternType, context.getTypeResolver());
        Expression withThis = DrlxParseUtil.prepend(_this, converted.getExpression());
        return new DrlxParseSuccess(patternType, exprId, bindingId, withThis, converted.getType()).setLeft(converted);
    }
    if (drlxExpr instanceof NameExpr) {
        NameExpr nameExpr = (NameExpr) drlxExpr;
        NameExpr _this = new NameExpr("_this");
        TypedExpression converted = DrlxParseUtil.toMethodCallWithClassCheck(context, nameExpr, bindingId, patternType, context.getTypeResolver());
        Expression withThis = DrlxParseUtil.prepend(_this, converted.getExpression());
        if (drlx.getBind() != null) {
            return new DrlxParseSuccess(patternType, exprId, bindingId, null, converted.getType()).setLeft(new TypedExpression(withThis, converted.getType())).addReactOnProperty(lcFirst(nameExpr.getNameAsString()));
        } else {
            return new DrlxParseSuccess(patternType, exprId, bindingId, withThis, converted.getType()).addReactOnProperty(nameExpr.getNameAsString());
        }
    }
    if (drlxExpr instanceof OOPathExpr) {
        return new DrlxParseSuccess(patternType, exprId, bindingId, drlxExpr, null);
    }
    if (drlxExpr instanceof LiteralExpr) {
        return new DrlxParseSuccess(patternType, exprId, bindingId, drlxExpr, getLiteralExpressionType(((LiteralExpr) drlxExpr)));
    }
    // TODO
    throw new UnsupportedOperationException("Unknown expression: " + toDrlx(drlxExpr));
}
Also used : IntegerLiteralExpr(org.drools.javaparser.ast.expr.IntegerLiteralExpr) Expression(org.drools.javaparser.ast.expr.Expression) ThisExpr(org.drools.javaparser.ast.expr.ThisExpr) ClassUtil.toNonPrimitiveType(org.drools.modelcompiler.util.ClassUtil.toNonPrimitiveType) DeclarationSpec(org.drools.modelcompiler.builder.generator.DeclarationSpec) CastExpr(org.drools.javaparser.ast.expr.CastExpr) LiteralExpr(org.drools.javaparser.ast.expr.LiteralExpr) DrlxParseUtil(org.drools.modelcompiler.builder.generator.DrlxParseUtil) BinaryExpr(org.drools.javaparser.ast.expr.BinaryExpr) InvalidExpressionErrorResult(org.drools.modelcompiler.builder.errors.InvalidExpressionErrorResult) ArrayList(java.util.ArrayList) ExpressionTyperContext(org.drools.modelcompiler.builder.generator.expressiontyper.ExpressionTyperContext) BigDecimal(java.math.BigDecimal) MethodCallExpr(org.drools.javaparser.ast.expr.MethodCallExpr) ParseExpressionErrorResult(org.drools.modelcompiler.builder.errors.ParseExpressionErrorResult) ClassUtil(org.drools.modelcompiler.util.ClassUtil) TypedExpressionResult(org.drools.modelcompiler.builder.generator.expressiontyper.TypedExpressionResult) DrlxParseUtil.getLiteralExpressionType(org.drools.modelcompiler.builder.generator.DrlxParseUtil.getLiteralExpressionType) LiteralStringValueExpr(org.drools.javaparser.ast.expr.LiteralStringValueExpr) MethodDeclaration(org.drools.javaparser.ast.body.MethodDeclaration) FieldAccessExpr(org.drools.javaparser.ast.expr.FieldAccessExpr) PrintUtil.toDrlx(org.drools.javaparser.printer.PrintUtil.toDrlx) GREATER(org.drools.javaparser.ast.expr.BinaryExpr.Operator.GREATER) PackageModel(org.drools.modelcompiler.builder.PackageModel) LESS(org.drools.javaparser.ast.expr.BinaryExpr.Operator.LESS) EnclosedExpr(org.drools.javaparser.ast.expr.EnclosedExpr) IntegerLiteralExpr(org.drools.javaparser.ast.expr.IntegerLiteralExpr) DrlxExpression(org.drools.javaparser.ast.drlx.expr.DrlxExpression) JavaParserUtil.toJavaParserType(org.drools.modelcompiler.util.JavaParserUtil.toJavaParserType) PointFreeExpr(org.drools.javaparser.ast.drlx.expr.PointFreeExpr) LESS_EQUALS(org.drools.javaparser.ast.expr.BinaryExpr.Operator.LESS_EQUALS) Collectors(java.util.stream.Collectors) NameExpr(org.drools.javaparser.ast.expr.NameExpr) StringLiteralExpr(org.drools.javaparser.ast.expr.StringLiteralExpr) ExpressionTyper(org.drools.modelcompiler.builder.generator.expressiontyper.ExpressionTyper) IndexUtil(org.drools.core.util.index.IndexUtil) UnaryExpr(org.drools.javaparser.ast.expr.UnaryExpr) RuleContext(org.drools.modelcompiler.builder.generator.RuleContext) List(java.util.List) OOPathExpr(org.drools.javaparser.ast.drlx.OOPathExpr) TypedExpression(org.drools.modelcompiler.builder.generator.TypedExpression) NodeList(org.drools.javaparser.ast.NodeList) StringUtils.lcFirst(org.drools.core.util.StringUtils.lcFirst) NodeWithArguments(org.drools.javaparser.ast.nodeTypes.NodeWithArguments) NodeWithOptionalScope(org.drools.javaparser.ast.nodeTypes.NodeWithOptionalScope) Optional(java.util.Optional) DrlxParseUtil.coerceLiteralExprToType(org.drools.modelcompiler.builder.generator.DrlxParseUtil.coerceLiteralExprToType) GREATER_EQUALS(org.drools.javaparser.ast.expr.BinaryExpr.Operator.GREATER_EQUALS) DrlxParseUtil.isPrimitiveExpression(org.drools.modelcompiler.builder.generator.DrlxParseUtil.isPrimitiveExpression) IndexUtil(org.drools.core.util.index.IndexUtil) StringLiteralExpr(org.drools.javaparser.ast.expr.StringLiteralExpr) NameExpr(org.drools.javaparser.ast.expr.NameExpr) ArrayList(java.util.ArrayList) ParseExpressionErrorResult(org.drools.modelcompiler.builder.errors.ParseExpressionErrorResult) ExpressionTyperContext(org.drools.modelcompiler.builder.generator.expressiontyper.ExpressionTyperContext) InvalidExpressionErrorResult(org.drools.modelcompiler.builder.errors.InvalidExpressionErrorResult) OOPathExpr(org.drools.javaparser.ast.drlx.OOPathExpr) LiteralExpr(org.drools.javaparser.ast.expr.LiteralExpr) IntegerLiteralExpr(org.drools.javaparser.ast.expr.IntegerLiteralExpr) StringLiteralExpr(org.drools.javaparser.ast.expr.StringLiteralExpr) FieldAccessExpr(org.drools.javaparser.ast.expr.FieldAccessExpr) ExpressionTyper(org.drools.modelcompiler.builder.generator.expressiontyper.ExpressionTyper) TypedExpression(org.drools.modelcompiler.builder.generator.TypedExpression) ThisExpr(org.drools.javaparser.ast.expr.ThisExpr) Optional(java.util.Optional) MethodDeclaration(org.drools.javaparser.ast.body.MethodDeclaration) BinaryExpr(org.drools.javaparser.ast.expr.BinaryExpr) PointFreeExpr(org.drools.javaparser.ast.drlx.expr.PointFreeExpr) LiteralStringValueExpr(org.drools.javaparser.ast.expr.LiteralStringValueExpr) TypedExpressionResult(org.drools.modelcompiler.builder.generator.expressiontyper.TypedExpressionResult) UnaryExpr(org.drools.javaparser.ast.expr.UnaryExpr) Expression(org.drools.javaparser.ast.expr.Expression) DrlxExpression(org.drools.javaparser.ast.drlx.expr.DrlxExpression) TypedExpression(org.drools.modelcompiler.builder.generator.TypedExpression) DrlxParseUtil.isPrimitiveExpression(org.drools.modelcompiler.builder.generator.DrlxParseUtil.isPrimitiveExpression) EnclosedExpr(org.drools.javaparser.ast.expr.EnclosedExpr) MethodCallExpr(org.drools.javaparser.ast.expr.MethodCallExpr)

Aggregations

IntegerLiteralExpr (org.drools.javaparser.ast.expr.IntegerLiteralExpr)2 LiteralExpr (org.drools.javaparser.ast.expr.LiteralExpr)2 MethodCallExpr (org.drools.javaparser.ast.expr.MethodCallExpr)2 NameExpr (org.drools.javaparser.ast.expr.NameExpr)2 StringLiteralExpr (org.drools.javaparser.ast.expr.StringLiteralExpr)2 InvalidExpressionErrorResult (org.drools.modelcompiler.builder.errors.InvalidExpressionErrorResult)2 BigDecimal (java.math.BigDecimal)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 Optional (java.util.Optional)1 Collectors (java.util.stream.Collectors)1 StringUtils.lcFirst (org.drools.core.util.StringUtils.lcFirst)1 IndexUtil (org.drools.core.util.index.IndexUtil)1 NodeList (org.drools.javaparser.ast.NodeList)1 MethodDeclaration (org.drools.javaparser.ast.body.MethodDeclaration)1 OOPathExpr (org.drools.javaparser.ast.drlx.OOPathExpr)1 DrlxExpression (org.drools.javaparser.ast.drlx.expr.DrlxExpression)1 PointFreeExpr (org.drools.javaparser.ast.drlx.expr.PointFreeExpr)1 ArrayAccessExpr (org.drools.javaparser.ast.expr.ArrayAccessExpr)1 ArrayCreationExpr (org.drools.javaparser.ast.expr.ArrayCreationExpr)1