use of org.drools.modelcompiler.builder.generator.drlxparse.DrlxParseSuccess in project drools by kiegroup.
the class PatternDSL method findAllConstraint.
private List<PatternConstraintParseResult> findAllConstraint(PatternDescr pattern, List<? extends BaseDescr> constraintDescrs, Class<?> patternType) {
ConstraintParser constraintParser = ConstraintParser.defaultConstraintParser(context, packageModel);
List<PatternConstraintParseResult> patternConstraintParseResults = new ArrayList<>();
for (BaseDescr constraint : constraintDescrs) {
List<PatternConstraintParseResult> patternConstraintParseResultsPerConstraintDescr = new ArrayList<>();
String patternIdentifier = pattern.getIdentifier();
boolean isPositional = isPositional(constraint);
ConstraintExpression constraintExpression = ConstraintExpression.createConstraintExpression(context, patternType, constraint, isPositional);
if (constraintExpression == null) {
continue;
}
DrlxParseResult drlxParseResult;
try {
context.setCurrentConstraintDescr(Optional.of(constraint));
drlxParseResult = constraintParser.drlxParse(patternType, patternIdentifier, constraintExpression, isPositional);
} finally {
context.resetCurrentConstraintDescr();
}
String expression = constraintExpression.getExpression();
if (drlxParseResult.isSuccess() && ((DrlxParseSuccess) drlxParseResult).isRequiresSplit() && ((DrlxParseSuccess) drlxParseResult).getExpr().isBinaryExpr()) {
BinaryExpr expr = ((DrlxParseSuccess) drlxParseResult).getExpr().asBinaryExpr();
String leftExpression = printNode(((SingleDrlxParseSuccess) drlxParseResult).getLeft().getExpression());
DrlxParseResult leftExpressionReparsed = constraintParser.drlxParse(patternType, patternIdentifier, leftExpression, isPositional);
patternConstraintParseResultsPerConstraintDescr.add(new PatternConstraintParseResult(leftExpression, patternIdentifier, leftExpressionReparsed));
String rightExpression = printNode(((SingleDrlxParseSuccess) drlxParseResult).getRight().getExpression());
DrlxParseResult rightExpressionReparsed = constraintParser.drlxParse(patternType, patternIdentifier, rightExpression, isPositional);
DrlxParseResult normalizedParseResult = ConstraintUtil.normalizeConstraint(rightExpressionReparsed);
patternConstraintParseResultsPerConstraintDescr.add(new PatternConstraintParseResult(rightExpression, patternIdentifier, normalizedParseResult));
} else {
DrlxParseResult normalizedParseResult = ConstraintUtil.normalizeConstraint(drlxParseResult);
patternConstraintParseResultsPerConstraintDescr.add(new PatternConstraintParseResult(expression, patternIdentifier, normalizedParseResult));
}
// Cast-check should be placed earlier than Null-check (calling the add method later means pushing the constraint earlier)
addNullSafeExpr(constraintParser, pattern.getIdentifier(), patternConstraintParseResultsPerConstraintDescr);
addImplicitCastExpr(constraintParser, pattern.getIdentifier(), patternConstraintParseResultsPerConstraintDescr);
patternConstraintParseResults.addAll(patternConstraintParseResultsPerConstraintDescr);
}
return patternConstraintParseResults;
}
use of org.drools.modelcompiler.builder.generator.drlxparse.DrlxParseSuccess in project drools by kiegroup.
the class AccumulateVisitor method binaryExprParameter.
private Optional<NewBinding> binaryExprParameter(PatternDescr basePattern, AccumulateDescr.AccumulateFunctionCallDescr function, MethodCallExpr functionDSL, String bindingId, String accumulateFunctionParameterStr) {
final DrlxParseResult parseResult = ConstraintParser.defaultConstraintParser(context, packageModel).drlxParse(Object.class, bindingId, accumulateFunctionParameterStr);
Optional<NewBinding> optNewBinding = parseResult.acceptWithReturnValue(new ParseResultVisitor<Optional<NewBinding>>() {
@Override
public Optional<NewBinding> onSuccess(DrlxParseSuccess drlxParseResult) {
SingleDrlxParseSuccess singleResult = (SingleDrlxParseSuccess) drlxParseResult;
Class<?> exprRawClass = singleResult.getExprRawClass();
AccumulateFunction accumulateFunction = getAccumulateFunction(function, exprRawClass);
validateAccFunctionTypeAgainstPatternType(context, basePattern, accumulateFunction);
final String bindExpressionVariable = context.getExprId(accumulateFunction.getResultType(), singleResult.getLeft().toString());
singleResult.setExprBinding(bindExpressionVariable);
context.addDeclarationReplacing(new DeclarationSpec(singleResult.getPatternBinding(), exprRawClass));
context.getExpressions().forEach(expression -> replaceTypeInExprLambda(bindingId, exprRawClass, expression));
functionDSL.addArgument(createAccSupplierExpr(accumulateFunction));
final MethodCallExpr newBindingFromBinary = AccumulateVisitor.this.buildBinding(bindExpressionVariable, singleResult.getUsedDeclarations(), singleResult.getExpr());
context.addDeclarationReplacing(new DeclarationSpec(bindExpressionVariable, exprRawClass));
functionDSL.addArgument(context.getVarExpr(bindExpressionVariable));
return Optional.of(new NewBinding(Collections.emptyList(), newBindingFromBinary));
}
@Override
public Optional<NewBinding> onFail(DrlxParseFail failure) {
return Optional.empty();
}
});
return optNewBinding;
}
use of org.drools.modelcompiler.builder.generator.drlxparse.DrlxParseSuccess in project drools by kiegroup.
the class PatternExpressionBuilder method buildExpressionWithIndexing.
@Override
public MethodCallExpr buildExpressionWithIndexing(DrlxParseSuccess drlxParseResult) {
if (drlxParseResult instanceof MultipleDrlxParseSuccess) {
MultipleDrlxParseSuccess multi = (MultipleDrlxParseSuccess) drlxParseResult;
MethodCallExpr exprDSL = new MethodCallExpr(null, multi.getOperator() == BinaryExpr.Operator.OR ? EXPR_OR_CALL : EXPR_AND_CALL);
for (DrlxParseSuccess child : multi.getResults()) {
MethodCallExpr childExpr = buildExpressionWithIndexing(child);
childExpr.setScope(exprDSL);
exprDSL = childExpr;
if (child instanceof SingleDrlxParseSuccess && child.getExprBinding() != null) {
SingleDrlxParseSuccess singleDrlxChild = (SingleDrlxParseSuccess) child;
context.addDeclaration(child.getExprBinding(), singleDrlxChild.getLeftExprRawClass());
Expression dslExpr = buildBinding(singleDrlxChild);
context.addExpression(dslExpr);
}
}
return new MethodCallExpr(exprDSL, multi.getOperator() == BinaryExpr.Operator.OR ? EXPR_END_OR_CALL : EXPR_END_AND_CALL);
}
return buildSingleExpressionWithIndexing((SingleDrlxParseSuccess) drlxParseResult);
}
use of org.drools.modelcompiler.builder.generator.drlxparse.DrlxParseSuccess 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;
}
use of org.drools.modelcompiler.builder.generator.drlxparse.DrlxParseSuccess in project drools by kiegroup.
the class NamedConsequenceVisitor method whenThenDSL.
private MethodCallExpr whenThenDSL(ConditionalBranchDescr desc, PatternDescr patternRelated, Class<?> patternType, String callMethod, MethodCallExpr parentExpression) {
MethodCallExpr when = parentExpression == null ? createDslTopLevelMethod(callMethod) : new MethodCallExpr(parentExpression, callMethod);
final String condition = desc.getCondition().toString();
if (!condition.equals("true")) {
// Default case
when.addArgument(new StringLiteralExpr(context.getConditionId(patternType, condition)));
String identifier = patternRelated.getIdentifier();
DrlxParseResult parseResult;
if (identifier == null) {
// The accumulate pattern doesn't have an identifier. Let's parse the consequence and use the acc functions
parseResult = ConstraintParser.defaultConstraintParser(context, packageModel).drlxParse(Object.class, "", condition);
parseResult.accept((DrlxParseSuccess parseSuccess) -> {
SingleDrlxParseSuccess parseSuccess1 = (SingleDrlxParseSuccess) parseSuccess;
AccumulateDescr source = (AccumulateDescr) patternRelated.getSource();
for (String usedDeclaration : parseSuccess1.getUsedDeclarations()) {
for (AccumulateDescr.AccumulateFunctionCallDescr functionCallDescr : source.getFunctions()) {
if (functionCallDescr.getBind().equals(usedDeclaration)) {
addVariable(patternRelated, when, functionCallDescr);
}
}
}
when.addArgument(generateLambdaWithoutParameters(parseSuccess1.getUsedDeclarations(), parseSuccess.getExpr(), true, Optional.empty()));
});
} else {
when.addArgument(context.getVarExpr(identifier));
parseResult = ConstraintParser.defaultConstraintParser(context, packageModel).drlxParse(patternType, identifier, condition);
Collection<String> usedDeclarations = ((SingleDrlxParseSuccess) parseResult).getUsedDeclarations();
if (usedDeclarations.isEmpty()) {
// _this
parseResult.accept(parseSuccess -> when.addArgument(generateLambdaWithoutParameters(Collections.emptySortedSet(), parseSuccess.getExpr())));
} else {
parseResult.accept(parseSuccess -> when.addArgument(generateLambdaWithoutParameters(usedDeclarations, parseSuccess.getExpr(), true, Optional.empty())));
}
}
}
MethodCallExpr then = new MethodCallExpr(when, THEN_CALL);
MethodCallExpr rhs = onDSL(desc.getConsequence());
then.addArgument(rhs);
return then;
}
Aggregations