Search in sources :

Example 6 with TypedExpression

use of org.drools.modelcompiler.builder.generator.TypedExpression in project drools by kiegroup.

the class PatternExpressionBuilder method buildIndexedBy.

private Optional<MethodCallExpr> buildIndexedBy(DrlxParseSuccess drlxParseResult) {
    if (!hasIndex(drlxParseResult)) {
        return Optional.empty();
    }
    IndexUtil.ConstraintType decodeConstraintType = drlxParseResult.getDecodeConstraintType();
    TypedExpression left = drlxParseResult.getLeft();
    TypedExpression right = drlxParseResult.getRight();
    Class<?> indexType = Stream.of(left, right).map(TypedExpression::getType).filter(Objects::nonNull).findFirst().get();
    ClassExpr indexedBy_indexedClass = new ClassExpr(JavaParser.parseType(indexType.getCanonicalName()));
    // not 100% accurate as the type in "nameExpr" is actually parsed if it was JavaParsers as a big chain of FieldAccessExpr
    FieldAccessExpr indexedBy_constraintType = new FieldAccessExpr(new NameExpr("org.drools.model.Index.ConstraintType"), decodeConstraintType.toString());
    LambdaExpr indexedBy_leftOperandExtractor = new LambdaExpr();
    indexedBy_leftOperandExtractor.addParameter(new Parameter(new UnknownType(), "_this"));
    boolean leftContainsThis = left.getExpression().toString().contains("_this");
    indexedBy_leftOperandExtractor.setBody(new ExpressionStmt(leftContainsThis ? left.getExpression() : right.getExpression()));
    MethodCallExpr indexedByDSL = new MethodCallExpr(null, drlxParseResult.isBetaNode() ? BETA_INDEXED_BY_CALL : ALPHA_INDEXED_BY_CALL);
    indexedByDSL.addArgument(indexedBy_indexedClass);
    indexedByDSL.addArgument(indexedBy_constraintType);
    indexedByDSL.addArgument("" + indexIdGenerator.getFieldId(drlxParseResult.getPatternType(), left.getFieldName()));
    indexedByDSL.addArgument(indexedBy_leftOperandExtractor);
    Collection<String> usedDeclarations = drlxParseResult.getUsedDeclarations();
    if (isAlphaIndex(usedDeclarations)) {
        indexedByDSL.addArgument(right.getExpression());
    } else if (usedDeclarations.size() == 1) {
        LambdaExpr indexedBy_rightOperandExtractor = new LambdaExpr();
        indexedBy_rightOperandExtractor.addParameter(new Parameter(new UnknownType(), usedDeclarations.iterator().next()));
        indexedBy_rightOperandExtractor.setBody(new ExpressionStmt(!leftContainsThis ? left.getExpression() : right.getExpression()));
        indexedByDSL.addArgument(indexedBy_rightOperandExtractor);
    }
    return Optional.of(indexedByDSL);
}
Also used : IndexUtil(org.drools.core.util.index.IndexUtil) LambdaExpr(org.drools.javaparser.ast.expr.LambdaExpr) NameExpr(org.drools.javaparser.ast.expr.NameExpr) ExpressionStmt(org.drools.javaparser.ast.stmt.ExpressionStmt) UnknownType(org.drools.javaparser.ast.type.UnknownType) Objects(java.util.Objects) Parameter(org.drools.javaparser.ast.body.Parameter) ClassExpr(org.drools.javaparser.ast.expr.ClassExpr) FieldAccessExpr(org.drools.javaparser.ast.expr.FieldAccessExpr) TypedExpression(org.drools.modelcompiler.builder.generator.TypedExpression) MethodCallExpr(org.drools.javaparser.ast.expr.MethodCallExpr)

Example 7 with TypedExpression

use of org.drools.modelcompiler.builder.generator.TypedExpression in project drools by kiegroup.

the class ExpressionTyper method extractPrefixExpressions.

private void extractPrefixExpressions(NullSafeFieldAccessExpr drlxExpr, Expression previous) {
    final BinaryExpr prefixExpression = new BinaryExpr(previous, new NullLiteralExpr(), BinaryExpr.Operator.NOT_EQUALS);
    prefixExpressions.add(prefixExpression);
    final Expression scope = drlxExpr.getScope();
    if (scope != null) {
        final Optional<TypedExpression> typedExpression1 = toTypedExpressionRec(scope);
        typedExpression1.ifPresent(te -> {
            final Expression expression = te.getExpression();
            final BinaryExpr notNullScope = new BinaryExpr(expression, new NullLiteralExpr(), BinaryExpr.Operator.NOT_EQUALS);
            prefixExpressions.add(0, notNullScope);
        });
    }
}
Also used : NullLiteralExpr(org.drools.javaparser.ast.expr.NullLiteralExpr) Expression(org.drools.javaparser.ast.expr.Expression) TypedExpression(org.drools.modelcompiler.builder.generator.TypedExpression) BinaryExpr(org.drools.javaparser.ast.expr.BinaryExpr) HalfBinaryExpr(org.drools.javaparser.ast.drlx.expr.HalfBinaryExpr) TypedExpression(org.drools.modelcompiler.builder.generator.TypedExpression)

Example 8 with TypedExpression

use of org.drools.modelcompiler.builder.generator.TypedExpression in project drools by kiegroup.

the class ExpressionTyper method toTypedExpressionFromMethodCallOrField.

private TypedExpressionResult toTypedExpressionFromMethodCallOrField(Expression drlxExpr) {
    final List<Node> childrenNodes = flattenScope(drlxExpr);
    final Node firstChild = childrenNodes.get(0);
    boolean isInLineCast = firstChild instanceof InlineCastExpr;
    final Class<?> originalTypeCursor;
    final Node firstNode;
    if (isInLineCast) {
        InlineCastExpr inlineCast = (InlineCastExpr) firstChild;
        originalTypeCursor = originalTypeCursorFromInlineCast(inlineCast);
        firstNode = inlineCast.getExpression();
    } else {
        originalTypeCursor = patternType;
        firstNode = firstChild;
    }
    final Optional<TypedExpressionCursor> teCursor = processFirstNode(drlxExpr, childrenNodes, firstNode, isInLineCast, originalTypeCursor);
    Expression previous;
    Class<?> typeCursor;
    if (!teCursor.isPresent()) {
        return new TypedExpressionResult(Optional.empty(), context);
    } else {
        previous = teCursor.get().expressionCursor;
        typeCursor = teCursor.get().typeCursor;
    }
    List<Node> childrenWithoutFirst = childrenNodes.subList(1, childrenNodes.size());
    for (Node part : childrenWithoutFirst) {
        if (typeCursor.isEnum()) {
            previous = drlxExpr;
        } else if (part instanceof SimpleName) {
            String field = part.toString();
            TypedExpression expression = nameExprToMethodCallExpr(field, typeCursor, previous);
            typeCursor = expression.getType();
            previous = expression.getExpression();
        } else if (part instanceof MethodCallExpr) {
            TypedExpressionCursor typedExpr = methodCallExpr((MethodCallExpr) part, typeCursor, previous);
            typeCursor = typedExpr.typeCursor;
            previous = typedExpr.expressionCursor;
        } else if (part instanceof InlineCastExpr && ((InlineCastExpr) part).getExpression() instanceof FieldAccessExpr) {
            InlineCastExpr inlineCastExprPart = (InlineCastExpr) part;
            final FieldAccessExpr fieldAccessExpr = (FieldAccessExpr) inlineCastExprPart.getExpression();
            final TypedExpression toMethodCallExpr = nameExprToMethodCallExpr(fieldAccessExpr.getNameAsString(), typeCursor, previous);
            final Class<?> castClass = getClassFromType(ruleContext.getTypeResolver(), inlineCastExprPart.getType());
            previous = addCastToExpression(castClass, toMethodCallExpr.getExpression(), false);
        } else {
            throw new UnsupportedOperationException();
        }
    }
    return new TypedExpressionResult(of(new TypedExpression().setExpression(previous).setType(typeCursor)), context);
}
Also used : Node(org.drools.javaparser.ast.Node) SimpleName(org.drools.javaparser.ast.expr.SimpleName) InlineCastExpr(org.drools.javaparser.ast.drlx.expr.InlineCastExpr) Expression(org.drools.javaparser.ast.expr.Expression) TypedExpression(org.drools.modelcompiler.builder.generator.TypedExpression) NullSafeFieldAccessExpr(org.drools.javaparser.ast.drlx.expr.NullSafeFieldAccessExpr) FieldAccessExpr(org.drools.javaparser.ast.expr.FieldAccessExpr) TypedExpression(org.drools.modelcompiler.builder.generator.TypedExpression) DrlxParseUtil.nameExprToMethodCallExpr(org.drools.modelcompiler.builder.generator.DrlxParseUtil.nameExprToMethodCallExpr) MethodCallExpr(org.drools.javaparser.ast.expr.MethodCallExpr)

Example 9 with TypedExpression

use of org.drools.modelcompiler.builder.generator.TypedExpression in project drools by kiegroup.

the class CustomOperatorSpec method getExpression.

public Expression getExpression(RuleContext context, PointFreeExpr pointFreeExpr, TypedExpression left) {
    MethodCallExpr methodCallExpr = new MethodCallExpr(null, "eval");
    String opName = pointFreeExpr.getOperator().asString();
    Operator operator = Operator.Register.getOperator(opName);
    try {
        // if the operator has an INSTANCE field avoid the operator lookup at runtime
        operator.getClass().getField("INSTANCE");
        methodCallExpr.addArgument(operator.getClass().getCanonicalName() + ".INSTANCE");
    } catch (NoSuchFieldException e) {
        methodCallExpr.addArgument(new StringLiteralExpr(opName));
    }
    methodCallExpr.addArgument(left.getExpression());
    for (Expression rightExpr : pointFreeExpr.getRight()) {
        if (rightExpr instanceof LiteralExpr) {
            methodCallExpr.addArgument(rightExpr);
        } else {
            TypedExpression typedExpression = DrlxParseUtil.toMethodCallWithClassCheck(context, rightExpr, null, null, context.getTypeResolver());
            methodCallExpr.addArgument(typedExpression.getExpression());
        }
    }
    return pointFreeExpr.isNegated() ? new UnaryExpr(methodCallExpr, UnaryExpr.Operator.LOGICAL_COMPLEMENT) : methodCallExpr;
}
Also used : Operator(org.drools.model.functions.Operator) TypedExpression(org.drools.modelcompiler.builder.generator.TypedExpression) Expression(org.drools.javaparser.ast.expr.Expression) StringLiteralExpr(org.drools.javaparser.ast.expr.StringLiteralExpr) LiteralExpr(org.drools.javaparser.ast.expr.LiteralExpr) StringLiteralExpr(org.drools.javaparser.ast.expr.StringLiteralExpr) TypedExpression(org.drools.modelcompiler.builder.generator.TypedExpression) UnaryExpr(org.drools.javaparser.ast.expr.UnaryExpr) MethodCallExpr(org.drools.javaparser.ast.expr.MethodCallExpr)

Example 10 with TypedExpression

use of org.drools.modelcompiler.builder.generator.TypedExpression in project drools by kiegroup.

the class AccumulateVisitor method visit.

protected Optional<AccumulateVisitorPatternDSL.NewBinding> visit(RuleContext context, AccumulateDescr.AccumulateFunctionCallDescr function, MethodCallExpr accumulateDSL, PatternDescr basePattern, boolean inputPatternHasConstraints) {
    context.pushExprPointer(accumulateDSL::addArgument);
    final MethodCallExpr functionDSL = new MethodCallExpr(null, "accFunction");
    final String expression = function.getParams()[0];
    final Expression expr = DrlxParseUtil.parseExpression(expression).getExpr();
    final String bindingId = Optional.ofNullable(function.getBind()).orElse(basePattern.getIdentifier());
    Optional<AccumulateVisitorPatternDSL.NewBinding> newBinding = Optional.empty();
    if (expr instanceof BinaryExpr) {
        final DrlxParseResult parseResult = new ConstraintParser(context, packageModel).drlxParse(Object.class, bindingId, expression);
        newBinding = parseResult.acceptWithReturnValue(new ParseResultVisitor<Optional<AccumulateVisitorPatternDSL.NewBinding>>() {

            @Override
            public Optional<AccumulateVisitorPatternDSL.NewBinding> onSuccess(DrlxParseSuccess drlxParseResult) {
                final AccumulateFunction accumulateFunction = AccumulateVisitor.this.getAccumulateFunction(function, drlxParseResult.getExprType());
                final String bindExpressionVariable = context.getExprId(accumulateFunction.getResultType(), drlxParseResult.getLeft().toString());
                drlxParseResult.setExprBinding(bindExpressionVariable);
                context.addDeclarationReplacing(new DeclarationSpec(drlxParseResult.getPatternBinding(), drlxParseResult.getExprType()));
                functionDSL.addArgument(new ClassExpr(toType(accumulateFunction.getClass())));
                final MethodCallExpr newBindingFromBinary = AccumulateVisitor.this.buildBinding(bindExpressionVariable, drlxParseResult.getUsedDeclarations(), drlxParseResult.getExpr());
                context.addDeclarationReplacing(new DeclarationSpec(bindExpressionVariable, drlxParseResult.getExprType()));
                functionDSL.addArgument(new NameExpr(toVar(bindExpressionVariable)));
                return Optional.of(new AccumulateVisitorPatternDSL.NewBinding(Optional.empty(), newBindingFromBinary));
            }

            @Override
            public Optional<AccumulateVisitorPatternDSL.NewBinding> onFail(DrlxParseFail failure) {
                return Optional.empty();
            }
        });
    } else if (expr instanceof MethodCallExpr) {
        final DrlxParseUtil.RemoveRootNodeResult methodCallWithoutRootNode = DrlxParseUtil.removeRootNode(expr);
        final String rootNodeName = getRootNodeName(methodCallWithoutRootNode);
        final TypedExpression typedExpression = parseMethodCallType(context, rootNodeName, methodCallWithoutRootNode.getWithoutRootNode());
        final Class<?> methodCallExprType = typedExpression.getType();
        final AccumulateFunction accumulateFunction = getAccumulateFunction(function, methodCallExprType);
        final Class accumulateFunctionResultType = accumulateFunction.getResultType();
        functionDSL.addArgument(new ClassExpr(toType(accumulateFunction.getClass())));
        // Every expression in an accumulate function gets transformed in a bind expression with a generated id
        // Then the accumulate function will have that binding expression as a source
        final String bindExpressionVariable = context.getExprId(accumulateFunctionResultType, typedExpression.toString());
        Expression withThis = DrlxParseUtil.prepend(DrlxParseUtil._THIS_EXPR, typedExpression.getExpression());
        DrlxParseSuccess result = new DrlxParseSuccess(accumulateFunctionResultType, "", rootNodeName, withThis, accumulateFunctionResultType).setLeft(typedExpression).setExprBinding(bindExpressionVariable);
        final MethodCallExpr binding = expressionBuilder.buildBinding(result);
        newBinding = Optional.of(new AccumulateVisitorPatternDSL.NewBinding(Optional.of(result.getPatternBinding()), binding));
        context.addDeclarationReplacing(new DeclarationSpec(bindExpressionVariable, methodCallExprType));
        functionDSL.addArgument(new NameExpr(toVar(bindExpressionVariable)));
        context.addDeclarationReplacing(new DeclarationSpec(bindingId, accumulateFunctionResultType));
    } else if (expr instanceof NameExpr) {
        final Class<?> declarationClass = context.getDeclarationById(expr.toString()).orElseThrow(RuntimeException::new).getDeclarationClass();
        final String nameExpr = ((NameExpr) expr).getName().asString();
        final AccumulateFunction accumulateFunction = getAccumulateFunction(function, declarationClass);
        functionDSL.addArgument(new ClassExpr(toType(accumulateFunction.getClass())));
        functionDSL.addArgument(new NameExpr(toVar(nameExpr)));
        Class accumulateFunctionResultType = accumulateFunction.getResultType();
        if (accumulateFunctionResultType == Comparable.class && (Comparable.class.isAssignableFrom(declarationClass) || declarationClass.isPrimitive())) {
            accumulateFunctionResultType = declarationClass;
        }
        context.addDeclarationReplacing(new DeclarationSpec(bindingId, accumulateFunctionResultType));
    } else {
        throw new UnsupportedOperationException("Unsupported expression " + expr);
    }
    final MethodCallExpr asDSL = new MethodCallExpr(functionDSL, "as");
    asDSL.addArgument(new NameExpr(toVar(bindingId)));
    accumulateDSL.addArgument(asDSL);
    context.popExprPointer();
    return newBinding;
}
Also used : ConstraintParser(org.drools.modelcompiler.builder.generator.drlxparse.ConstraintParser) BinaryExpr(org.drools.javaparser.ast.expr.BinaryExpr) NameExpr(org.drools.javaparser.ast.expr.NameExpr) DrlxParseFail(org.drools.modelcompiler.builder.generator.drlxparse.DrlxParseFail) DeclarationSpec(org.drools.modelcompiler.builder.generator.DeclarationSpec) Expression(org.drools.javaparser.ast.expr.Expression) TypedExpression(org.drools.modelcompiler.builder.generator.TypedExpression) DrlxParseSuccess(org.drools.modelcompiler.builder.generator.drlxparse.DrlxParseSuccess) ParseResultVisitor(org.drools.modelcompiler.builder.generator.drlxparse.ParseResultVisitor) DrlxParseResult(org.drools.modelcompiler.builder.generator.drlxparse.DrlxParseResult) ClassExpr(org.drools.javaparser.ast.expr.ClassExpr) AccumulateFunction(org.kie.api.runtime.rule.AccumulateFunction) TypedExpression(org.drools.modelcompiler.builder.generator.TypedExpression) MethodCallExpr(org.drools.javaparser.ast.expr.MethodCallExpr)

Aggregations

TypedExpression (org.drools.modelcompiler.builder.generator.TypedExpression)10 Expression (org.drools.javaparser.ast.expr.Expression)7 MethodCallExpr (org.drools.javaparser.ast.expr.MethodCallExpr)7 FieldAccessExpr (org.drools.javaparser.ast.expr.FieldAccessExpr)5 NameExpr (org.drools.javaparser.ast.expr.NameExpr)5 BinaryExpr (org.drools.javaparser.ast.expr.BinaryExpr)4 ClassExpr (org.drools.javaparser.ast.expr.ClassExpr)3 LiteralExpr (org.drools.javaparser.ast.expr.LiteralExpr)3 StringLiteralExpr (org.drools.javaparser.ast.expr.StringLiteralExpr)3 UnaryExpr (org.drools.javaparser.ast.expr.UnaryExpr)3 DeclarationSpec (org.drools.modelcompiler.builder.generator.DeclarationSpec)3 ArrayList (java.util.ArrayList)2 List (java.util.List)2 Objects (java.util.Objects)2 Optional (java.util.Optional)2 IndexUtil (org.drools.core.util.index.IndexUtil)2 Node (org.drools.javaparser.ast.Node)2 NodeList (org.drools.javaparser.ast.NodeList)2 Parameter (org.drools.javaparser.ast.body.Parameter)2 HalfBinaryExpr (org.drools.javaparser.ast.drlx.expr.HalfBinaryExpr)2