@Override public DirectCompilerResult visit(FunctionDefNode n) { MethodCallExpr list = Expressions.list(); n.getFormalParameters() .stream() .map(fp -> fp.accept(this)) .map(DirectCompilerResult::getExpression) .forEach(list::addArgument); if (n.isExternal()) { List<String> paramNames = n.getFormalParameters().stream() .map(BaseNode::getText) .collect(Collectors.toList()); return Functions.declaration( n, list, Functions.external(paramNames, n.getBody())); } else { DirectCompilerResult body = n.getBody().accept(this); return Functions.declaration(n, list, body.getExpression()).withFD(body); } }
@Override public DirectCompilerResult visit(BetweenNode n) { DirectCompilerResult value = n.getValue().accept(this); DirectCompilerResult start = n.getStart().accept(this); DirectCompilerResult end = n.getEnd().accept(this); return DirectCompilerResult.of( Expressions.between( value.getExpression(), start.getExpression(), end.getExpression()), BuiltInType.BOOLEAN) .withFD(value) .withFD(start) .withFD(end); }
@Override public DirectCompilerResult visit(ContextEntryNode n) { DirectCompilerResult key = n.getName().accept(this); DirectCompilerResult value = n.getValue().accept(this); if (key.resultType != BuiltInType.STRING) { throw new IllegalArgumentException( "a Context Entry Key must be a valid FEEL String type"); } String keyText = key.getExpression().asStringLiteralExpr().getValue(); // .setEntry(key, value) MethodCallExpr setEntryContextCall = FeelCtx.setEntry(keyText, value.getExpression()); return DirectCompilerResult.of( setEntryContextCall, value.resultType, value.getFieldDeclarations()); }
public ProcessedUnaryTest( String expressions, CompilerContext ctx) { super(expressions, ctx, Collections.emptyList()); ParseTree tree = parser.unaryTestsRoot(); BaseNode initialAst = tree.accept(new ASTBuilderVisitor(ctx.getInputVariableTypes())); ast = initialAst.accept(new ASTUnaryTestTransform()).node(); }
@Override public UnaryTestSubexpr visit(UnaryTestListNode n) { List<BaseNode> collect = new ArrayList<>(); for (BaseNode e : n.getElements()) { UnaryTestSubexpr accept = e.accept(this); if (accept.isWildcard()) { collect.add(rewriteToUnaryTestExpr(accept.node)); } else if (!accept.isUnaryTest()) { collect.add(rewriteToUnaryEqInExpr(accept.node)); } else { collect.add(accept.node); } } return new TopLevel( ASTBuilderFactory.newUnaryTestListNode(n.getParserRuleContext(), collect, n.getState())); }
@Override public DirectCompilerResult visit(InfixOpNode n) { DirectCompilerResult left = n.getLeft().accept(this); DirectCompilerResult right = n.getRight().accept(this); MethodCallExpr expr = Expressions.binary( n.getOperator(), left.getExpression(), right.getExpression()); return DirectCompilerResult.of(expr, BuiltInType.UNKNOWN).withFD(left).withFD(right); }
@Override public DirectCompilerResult visit(RangeNode n) { DirectCompilerResult start = n.getStart().accept(this); DirectCompilerResult end = n.getEnd().accept(this); return DirectCompilerResult.of( Expressions.range( n.getLowerBound(), start.getExpression(), end.getExpression(), n.getUpperBound()), BuiltInType.RANGE, DirectCompilerResult.mergeFDs(start, end)); }
@Override public DirectCompilerResult visit(SignedUnaryNode n) { DirectCompilerResult result = n.getExpression().accept(this); if (n.getSign() == SignedUnaryNode.Sign.NEGATIVE) { return DirectCompilerResult.of( Expressions.negate(result.getExpression()), result.resultType, result.getFieldDeclarations()); } else { return result; } }
@Override public DirectCompilerResult visit(FilterExpressionNode n) { DirectCompilerResult expr = n.getExpression().accept(this); DirectCompilerResult filter = n.getFilter().accept(this); Expressions.NamedLambda lambda = Expressions.namedLambda(filter.getExpression(), n.getFilter().getText()); DirectCompilerResult r = DirectCompilerResult.of( Expressions.filter(expr.getExpression(), lambda.name()), // here we could still try to infer the result type, but presently use ANY BuiltInType.UNKNOWN).withFD(expr).withFD(filter); r.addFieldDesclaration(lambda.field()); return r; }
@Override public DirectCompilerResult visit(ListNode n) { MethodCallExpr list = Expressions.list(); DirectCompilerResult result = DirectCompilerResult.of(list, BuiltInType.LIST); for (BaseNode e : n.getElements()) { DirectCompilerResult r = e.accept(this); result.withFD(r.getFieldDeclarations()); list.addArgument(r.getExpression()); } return result; }
@Override public DirectCompilerResult visit(InstanceOfNode n) { DirectCompilerResult expr = n.getExpression().accept(this); DirectCompilerResult type = n.getType().accept(this); return DirectCompilerResult.of( Expressions.isInstanceOf(expr.getExpression(), type.getExpression()), BuiltInType.BOOLEAN, mergeFDs(expr, type)); }
@Override public DirectCompilerResult visit(PathExpressionNode n) { DirectCompilerResult expr = n.getExpression().accept(this); BaseNode nameNode = n.getName(); if (nameNode instanceof QualifiedNameNode) { QualifiedNameNode qualifiedNameNode = (QualifiedNameNode) n.getName(); List<Expression> exprs = qualifiedNameNode.getParts().stream() .map(name -> new StringLiteralExpr(name.getText())) .collect(Collectors.toList()); return DirectCompilerResult.of( Expressions.path(expr.getExpression(), exprs), // here we could still try to infer the result type, but presently use ANY BuiltInType.UNKNOWN).withFD(expr); } else { return DirectCompilerResult.of( Expressions.path(expr.getExpression(), new StringLiteralExpr(nameNode.getText())), // here we could still try to infer the result type, but presently use ANY BuiltInType.UNKNOWN).withFD(expr); } }
private DirectCompilerResult getCompilerResult() { if (compiledExpression == null) { if (errorListener.isError()) { compiledExpression = CompiledFEELSupport.compiledErrorUnaryTest( errorListener.event().getMessage()); } else { try { compiledExpression = ast.accept(new ASTCompilerVisitor()); } catch (FEELCompilationError e) { compiledExpression = CompiledFEELSupport.compiledErrorUnaryTest(e.getMessage()); } } } return compiledExpression; }
@Override public DirectCompilerResult visit(IfExpressionNode n) { DirectCompilerResult condition = n.getCondition().accept(this); DirectCompilerResult thenExpr = n.getThenExpression().accept(this); DirectCompilerResult elseExpr = n.getElseExpression().accept(this); return DirectCompilerResult.of( new ConditionalExpr( new BinaryExpr( Expressions.nativeInstanceOf( Constants.BooleanT, condition.getExpression()), Expressions.reflectiveCastTo( Constants.BooleanT, condition.getExpression()), BinaryExpr.Operator.AND), new EnclosedExpr(thenExpr.getExpression()), new EnclosedExpr(elseExpr.getExpression())), thenExpr.resultType // should find common type between then/else ).withFD(condition).withFD(thenExpr).withFD(elseExpr); }
@Override public DirectCompilerResult visit(FunctionInvocationNode n) { DirectCompilerResult functionName = n.getName().accept(this); DirectCompilerResult params = n.getParams().accept(this); return DirectCompilerResult.of( Expressions.invoke(functionName.getExpression(), params.getExpression()), functionName.resultType) .withFD(functionName) .withFD(params); }
@Override public DirectCompilerResult visit(NamedParameterNode n) { DirectCompilerResult name = n.getName().accept(this); DirectCompilerResult expr = n.getExpression().accept(this); return DirectCompilerResult.of( Expressions.namedParameter(name.getExpression(), expr.getExpression()), BuiltInType.UNKNOWN).withFD(name).withFD(expr); }
private CompiledFEELExpression parse(String input, Map<String, Type> inputTypes) { FEEL_1_1Parser parser = FEELParser.parse(null, input, inputTypes, Collections.emptyMap(), Collections.emptyList(), Collections.emptyList()); ParseTree tree = parser.compilation_unit(); ASTBuilderVisitor v = new ASTBuilderVisitor(inputTypes); BaseNode node = v.visit(tree); DirectCompilerResult directResult = node.accept(new ASTCompilerVisitor()); Expression expr = directResult.getExpression(); CompiledFEELExpression cu = new CompilerBytecodeLoader().makeFromJPExpression(input, expr, directResult.getFieldDeclarations()); return cu; }
@Override public DirectCompilerResult visit(UnaryTestNode n) { DirectCompilerResult value = n.getValue().accept(this); Expression expr = Expressions.unary(n.getOperator(), value.getExpression()); Expressions.NamedLambda namedLambda = Expressions.namedUnaryLambda(expr, n.getText()); DirectCompilerResult r = DirectCompilerResult.of(namedLambda.name(), BuiltInType.UNARY_TEST) .withFD(value); r.addFieldDesclaration(namedLambda.field()); return r; } }
private CompiledFEELUnaryTests parse(String input, Map<String, Type> inputTypes, FEELEventListenersManager mgr, CompiledFEELSupport.SyntaxErrorListener listener) { FEEL_1_1Parser parser = FEELParser.parse(mgr, input, inputTypes, Collections.emptyMap(), Collections.emptyList(), Collections.emptyList()); ParseTree tree = parser.unaryTestsRoot(); DirectCompilerResult directResult; if (listener.isError()) { directResult = CompiledFEELSupport.compiledErrorUnaryTest(listener.event().getMessage()); } else { ASTBuilderVisitor v = new ASTBuilderVisitor(inputTypes); BaseNode node = v.visit(tree); BaseNode transformed = node.accept(new ASTUnaryTestTransform()).node(); directResult = transformed.accept(new ASTCompilerVisitor()); } Expression expr = directResult.getExpression(); CompiledFEELUnaryTests cu = new CompilerBytecodeLoader().makeFromJPUnaryTestsExpression(input, expr, directResult.getFieldDeclarations()); return cu; }
@Override public DirectCompilerResult visit(InNode n) { DirectCompilerResult value = n.getValue().accept(this); DirectCompilerResult exprs = n.getExprs().accept(this); if (exprs.resultType == BuiltInType.LIST) { return DirectCompilerResult.of( Expressions.exists(exprs.getExpression(), value.getExpression()), BuiltInType.BOOLEAN).withFD(value).withFD(exprs); } else if (exprs.resultType == BuiltInType.RANGE) { return DirectCompilerResult.of( Expressions.includes(exprs.getExpression(), value.getExpression()), BuiltInType.BOOLEAN).withFD(value).withFD(exprs); } else { // this should be turned into a tree rewrite return DirectCompilerResult.of( Expressions.exists(exprs.getExpression(), value.getExpression()), BuiltInType.BOOLEAN).withFD(value).withFD(exprs); } }