use of org.drools.modelcompiler.builder.generator.DeclarationSpec in project drools by kiegroup.
the class Query method buildPattern.
@Override
public void buildPattern() {
NameExpr queryCall = new NameExpr(toQueryDef(pattern.getObjectType()));
MethodCallExpr callCall = new MethodCallExpr(queryCall, QUERY_INVOCATION_CALL);
callCall.addArgument("" + !pattern.isQuery());
for (int i = 0; i < constraintDescrs.size(); i++) {
String itemText = constraintDescrs.get(i).getText();
if (QueryGenerator.isLiteral(itemText)) {
MethodCallExpr valueOfMethod = new MethodCallExpr(null, VALUE_OF_CALL);
valueOfMethod.addArgument(new NameExpr(itemText));
callCall.addArgument(valueOfMethod);
} else {
QueryParameter qp = packageModel.queryVariables(queryName).get(i);
context.addDeclaration(new DeclarationSpec(itemText, qp.getType()));
callCall.addArgument(QueryGenerator.substituteBindingWithQueryParameter(context, itemText));
}
}
context.addExpression(callCall);
}
use of org.drools.modelcompiler.builder.generator.DeclarationSpec in project drools by kiegroup.
the class ExpressionTyper method nameExpr.
private Optional<TypedExpressionCursor> nameExpr(Expression drlxExpr, NameExpr firstNode, boolean isInLineCast, Class<?> originalTypeCursor) {
Optional<TypedExpressionCursor> teCursor;
String firstName = firstNode.getName().getIdentifier();
Optional<DeclarationSpec> declarationById = ruleContext.getDeclarationById(firstName);
if (declarationById.isPresent()) {
// do NOT append any reactOnProperties.
// because reactOnProperties is referring only to the properties of the type of the pattern, not other declarations properites.
context.addUsedDeclarations(firstName);
final Class<?> typeCursor;
if (!isInLineCast) {
typeCursor = declarationById.get().getDeclarationClass();
} else {
typeCursor = originalTypeCursor;
}
teCursor = of(new TypedExpressionCursor(new NameExpr(firstName), typeCursor));
} else if (packageModel.getGlobals().containsKey(firstName)) {
context.addUsedDeclarations(firstName);
return of(new TypedExpressionCursor(new NameExpr(firstName), packageModel.getGlobals().get(firstName)));
} else {
final Class<?> typeCursor;
// In OOPath a declaration is based on a position rather than a name.
// Only an OOPath chunk can have a backreference expression
Optional<DeclarationSpec> backReference = Optional.empty();
if (firstNode.getBackReferencesCount() > 0) {
List<DeclarationSpec> ooPathDeclarations = ruleContext.getOOPathDeclarations();
DeclarationSpec backReferenceDeclaration = ooPathDeclarations.get(ooPathDeclarations.size() - 1 - firstNode.getBackReferencesCount());
typeCursor = backReferenceDeclaration.getDeclarationClass();
backReference = of(backReferenceDeclaration);
context.addUsedDeclarations(backReferenceDeclaration.getBindingId());
} else {
typeCursor = originalTypeCursor;
}
Method firstAccessor = ClassUtils.getAccessor((!isInLineCast) ? typeCursor : patternType, firstName);
if (firstAccessor != null) {
// Hack to review - if a property is upper case it's probably not a react on property
if (!"".equals(firstName) && Character.isLowerCase(firstName.charAt(0))) {
context.addReactOnProperties(firstName);
}
final Class<?> typeOfFirstAccessor;
if (!isInLineCast) {
typeOfFirstAccessor = firstAccessor.getReturnType();
} else {
typeOfFirstAccessor = typeCursor;
}
NameExpr thisAccessor = new NameExpr("_this");
final NameExpr scope = backReference.map(d -> new NameExpr(d.getBindingId())).orElse(thisAccessor);
teCursor = of(new TypedExpressionCursor(new MethodCallExpr(scope, firstAccessor.getName()), typeOfFirstAccessor));
} else {
try {
Class<?> resolvedType = ruleContext.getTypeResolver().resolveType(firstName);
return of(new TypedExpressionCursor(null, resolvedType));
} catch (ClassNotFoundException e) {
// ignore
}
final Optional<Node> rootNode = findRootNodeViaParent(drlxExpr);
rootNode.ifPresent(n -> {
// In the error messages HalfBinary are transformed to Binary
Node withHalfBinaryReplaced = replaceAllHalfBinaryChildren(n);
ruleContext.addCompilationError(new ParseExpressionErrorResult((Expression) withHalfBinaryReplaced));
});
teCursor = Optional.empty();
}
}
return teCursor;
}
use of org.drools.modelcompiler.builder.generator.DeclarationSpec 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.DeclarationSpec in project drools by kiegroup.
the class FlowDSLPattern method buildPattern.
@Override
public void buildPattern() {
generatePatternIdentifierIfMissing();
final Optional<Expression> declarationSource = buildFromDeclaration(pattern);
context.addDeclaration(new DeclarationSpec(pattern.getIdentifier(), patternType, Optional.of(pattern), declarationSource));
if (constraintDescrs.isEmpty() && !(pattern.getSource() instanceof AccumulateDescr)) {
context.addExpression(createInputExpression(pattern));
} else {
if (!context.hasErrors()) {
final List<PatternConstraintParseResult> patternConstraintParseResults = findAllConstraint(pattern, constraintDescrs, patternType);
if (shouldAddInputPattern(patternConstraintParseResults)) {
context.addExpression(createInputExpression(pattern));
}
buildConstraints(pattern, patternType, patternConstraintParseResults, allConstraintsPositional);
}
}
}
use of org.drools.modelcompiler.builder.generator.DeclarationSpec in project drools by kiegroup.
the class PatternDSLPattern method buildPattern.
@Override
public void buildPattern() {
generatePatternIdentifierIfMissing();
final Optional<Expression> declarationSource = buildFromDeclaration(pattern);
context.addDeclaration(new DeclarationSpec(pattern.getIdentifier(), patternType, Optional.of(pattern), declarationSource));
if (constraintDescrs.isEmpty() && !(pattern.getSource() instanceof AccumulateDescr)) {
context.addExpression(addWatchToPattern(createPatternExpression(pattern)));
} else {
if (!context.hasErrors()) {
final List<PatternConstraintParseResult> patternConstraintParseResults = findAllConstraint(pattern, constraintDescrs, patternType);
MethodCallExpr patternExpression = createPatternExpression(pattern);
List<Expression> exprs = new ArrayList<>();
context.pushExprPointer(exprs::add);
buildConstraints(pattern, patternType, patternConstraintParseResults);
context.popExprPointer();
List<Expression> additionalPatterns = new ArrayList<>();
for (Expression expr : exprs) {
Optional<Expression> rootScope = findRootNodeViaScope(expr);
if (rootScope.isPresent() && ((MethodCallExpr) rootScope.get()).getNameAsString().equals("pattern")) {
additionalPatterns.add(expr);
} else {
MethodCallExpr currentExpr = (MethodCallExpr) expr;
((MethodCallExpr) expr).setScope(patternExpression);
patternExpression = currentExpr;
}
}
context.addExpression(addWatchToPattern(patternExpression));
additionalPatterns.forEach(context::addExpression);
}
}
}
Aggregations