use of org.drools.javaparser.ast.expr.Expression in project drools by kiegroup.
the class DrlxParseUtil method rescopeNamesToNewScope.
/**
* Mutates expression
* such that, if it contains a NameExpr for any of the <code>names</code>,
* it is replaced with a FieldAccessExpr having <code>newScope</code> as the scope.
*/
public static void rescopeNamesToNewScope(Expression newScope, List<String> names, Expression e) {
if (e instanceof AssignExpr) {
AssignExpr assignExpr = (AssignExpr) e;
rescopeNamesToNewScope(newScope, names, assignExpr.getTarget());
rescopeNamesToNewScope(newScope, names, assignExpr.getValue());
} else if (e instanceof BinaryExpr) {
rescopeNamesToNewScope(newScope, names, ((BinaryExpr) e).getLeft());
rescopeNamesToNewScope(newScope, names, ((BinaryExpr) e).getRight());
} else if (e instanceof UnaryExpr) {
rescopeNamesToNewScope(newScope, names, ((UnaryExpr) e).getExpression());
} else if (e instanceof EnclosedExpr) {
rescopeNamesToNewScope(newScope, names, ((EnclosedExpr) e).getInner());
} else {
Optional<Expression> rootNode = DrlxParseUtil.findRootNodeViaScope(e);
if (rootNode.isPresent() && rootNode.get() instanceof NameExpr) {
NameExpr nameExpr = (NameExpr) rootNode.get();
if (names.contains(nameExpr.getNameAsString())) {
Expression prepend = new FieldAccessExpr(newScope, nameExpr.getNameAsString());
if (e instanceof NameExpr) {
// actually `e` was not composite, it was already the NameExpr node I was looking to replace.
e.getParentNode().get().replace(nameExpr, prepend);
} else {
e.replace(nameExpr, prepend);
}
}
}
}
}
use of org.drools.javaparser.ast.expr.Expression 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));
}
use of org.drools.javaparser.ast.expr.Expression in project drools by kiegroup.
the class OOPathExprGenerator method toFlowExpr.
private void toFlowExpr(String bindingId, List<DrlxParseResult> list) {
final List<DrlxParseSuccess> value = list.stream().filter(r -> r instanceof DrlxParseSuccess).map(DrlxParseSuccess.class::cast).collect(Collectors.toList());
if (value.size() == 1) {
context.addExpression(expressionBuilder.buildExpressionWithIndexing(value.get(0)));
} else {
final MethodCallExpr andDSL = new MethodCallExpr(null, "and");
value.forEach(e -> {
final Expression expression = expressionBuilder.buildExpressionWithIndexing(e);
andDSL.addArgument(expression);
});
context.addExpression(andDSL);
}
}
use of org.drools.javaparser.ast.expr.Expression in project drools by kiegroup.
the class OOPathExprGenerator method visit.
public void visit(Class<?> originalClass, String originalBind, DrlxParseSuccess patternParseResult) {
final OOPathExpr ooPathExpr = (OOPathExpr) patternParseResult.getExpr();
Class<?> previousClass = originalClass;
String previousBind = originalBind;
Map<String, List<DrlxParseResult>> ooPathConditionExpressions = new LinkedHashMap<>();
for (Iterator<OOPathChunk> iterator = ooPathExpr.getChunks().iterator(); iterator.hasNext(); ) {
OOPathChunk chunk = iterator.next();
final String fieldName = chunk.getField().toString();
final TypedExpression callExpr = DrlxParseUtil.nameExprToMethodCallExpr(fieldName, previousClass, null);
Class<?> fieldType = (chunk.getInlineCast() != null) ? DrlxParseUtil.getClassFromContext(context.getTypeResolver(), chunk.getInlineCast().toString()) : callExpr.getType();
if (Iterable.class.isAssignableFrom(fieldType)) {
fieldType = extractGenericType(previousClass, ((MethodCallExpr) callExpr.getExpression()).getName().toString());
}
final String chunkKey = originalBind + fieldName;
final String bindingId;
if (!iterator.hasNext() && patternParseResult.getExprBinding() != null) {
bindingId = patternParseResult.getExprBinding();
context.removeDeclarationById(bindingId);
} else {
bindingId = context.getOOPathId(fieldType, chunkKey);
}
final Expression accessorLambda = generateLambdaWithoutParameters(Collections.emptySortedSet(), prepend(new NameExpr("_this"), callExpr.getExpression()));
final MethodCallExpr reactiveFrom = new MethodCallExpr(null, "reactiveFrom");
reactiveFrom.addArgument(new NameExpr(toVar(previousBind)));
reactiveFrom.addArgument(accessorLambda);
DeclarationSpec newDeclaration = new DeclarationSpec(bindingId, fieldType, reactiveFrom);
context.addDeclaration(newDeclaration);
context.addOOPathDeclaration(newDeclaration);
final List<Expression> conditions = chunk.getConditions();
if (!conditions.isEmpty()) {
Class<?> finalFieldType = fieldType;
final List<DrlxParseResult> conditionParseResult = conditions.stream().map((Expression c) -> new ConstraintParser(context, packageModel).drlxParse(finalFieldType, bindingId, c.toString())).collect(Collectors.toList());
ooPathConditionExpressions.put(bindingId, conditionParseResult);
} else {
if (context.isPatternDSL()) {
ooPathConditionExpressions.put(bindingId, Collections.emptyList());
} else {
final DrlxParseSuccess drlxParseResult = new DrlxParseSuccess(fieldType, "", bindingId, new BooleanLiteralExpr(true), fieldType);
ooPathConditionExpressions.put(bindingId, Collections.singletonList(drlxParseResult));
}
}
previousBind = bindingId;
previousClass = fieldType;
}
ooPathConditionExpressions.forEach(context.isPatternDSL() ? this::toPatternExpr : this::toFlowExpr);
}
use of org.drools.javaparser.ast.expr.Expression in project drools by kiegroup.
the class ExpressionTyper method getOperatorSpec.
private OperatorSpec getOperatorSpec(Expression drlxExpr, NodeList<Expression> rightExpressions, SimpleName expressionOperator) {
for (Expression rightExpr : rightExpressions) {
toTypedExpressionRec(rightExpr);
}
String operator = expressionOperator.asString();
OperatorSpec opSpec = null;
if (ModelGenerator.temporalOperators.contains(operator)) {
opSpec = TemporalOperatorSpec.INSTANCE;
} else if (org.drools.model.functions.Operator.Register.hasOperator(operator)) {
opSpec = CustomOperatorSpec.INSTANCE;
}
if (opSpec == null) {
throw new UnsupportedOperationException("Unknown operator '" + operator + "' in expression: " + toDrlx(drlxExpr));
}
return opSpec;
}
Aggregations