@Override public DirectCompilerResult visitFormalParameters(FEEL_1_1Parser.FormalParametersContext ctx) { List<DirectCompilerResult> exprs = new ArrayList<>(); for (FEEL_1_1Parser.FormalParameterContext fpc : ctx.formalParameter()) { exprs.add(visit(fpc)); } MethodCallExpr list = new MethodCallExpr(null, "list"); exprs.stream().map(DirectCompilerResult::getExpression).forEach(list::addArgument); return DirectCompilerResult.of(list, BuiltInType.LIST, DirectCompilerResult.mergeFDs(exprs.toArray(new DirectCompilerResult[]{}))); }
@Override public DirectCompilerResult visitPositionalParameters(FEEL_1_1Parser.PositionalParametersContext ctx) { List<DirectCompilerResult> exprs = new ArrayList<>(); for (FEEL_1_1Parser.ExpressionContext ec : ctx.expression()) { exprs.add(visit(ec)); } MethodCallExpr list = new MethodCallExpr(null, "list"); exprs.stream().map(DirectCompilerResult::getExpression).forEach(list::addArgument); return DirectCompilerResult.of(list, BuiltInType.LIST, DirectCompilerResult.mergeFDs(exprs.toArray(new DirectCompilerResult[]{}))); }
@Override public DirectCompilerResult visitNamedParameters(FEEL_1_1Parser.NamedParametersContext ctx) { List<DirectCompilerResult> exprs = new ArrayList<>(); for (FEEL_1_1Parser.NamedParameterContext npc : ctx.namedParameter()) { exprs.add(visitNamedParameter(npc)); } MethodCallExpr list = new MethodCallExpr(null, "list"); exprs.stream().map(DirectCompilerResult::getExpression).forEach(list::addArgument); return DirectCompilerResult.of(list, BuiltInType.LIST, DirectCompilerResult.mergeFDs(exprs.toArray(new DirectCompilerResult[]{}))); }
@Override public DirectCompilerResult visitStringLiteral(FEEL_1_1Parser.StringLiteralContext ctx) { StringLiteralExpr expr = new StringLiteralExpr(); String actualStringContent = ParserHelper.getOriginalText(ctx); actualStringContent = actualStringContent.substring(1, actualStringContent.length() - 1); // remove start/end " from the FEEL text expression. String unescaped = EvalHelper.unescapeString(actualStringContent); // unescapes String, FEEL-style expr.setString(unescaped); // setString escapes the contents Java-style return DirectCompilerResult.of(expr, BuiltInType.STRING); }
@Override public DirectCompilerResult visitContext(FEEL_1_1Parser.ContextContext ctx) { if (ctx.contextEntries() == null) { return DirectCompilerResult.of(EMPTY_MAP, BuiltInType.CONTEXT); } else { return visit(ctx.contextEntries()); } }
@Override public DirectCompilerResult visitNameDefinition(FEEL_1_1Parser.NameDefinitionContext ctx) { // this is used by the For loop for the variable name of the iteration contexts. StringLiteralExpr expr = new StringLiteralExpr(EvalHelper.normalizeVariableName(ParserHelper.getOriginalText(ctx))); return DirectCompilerResult.of(expr, BuiltInType.STRING); }
@Override public DirectCompilerResult visitKeyString(FEEL_1_1Parser.KeyStringContext ctx) { // Need to repeat the same impl as visitStringLiteral because is an ANTLR terminal node, so cannot delegate. StringLiteralExpr expr = new StringLiteralExpr(EvalHelper.unescapeString(ParserHelper.getOriginalText(ctx))); return DirectCompilerResult.of(expr, BuiltInType.STRING); }
@Override public DirectCompilerResult visitKeyName(KeyNameContext ctx) { StringLiteralExpr expr = new StringLiteralExpr(EvalHelper.normalizeVariableName(ParserHelper.getOriginalText(ctx))); return DirectCompilerResult.of(expr, BuiltInType.STRING); }
@Override public DirectCompilerResult visitNameRef(FEEL_1_1Parser.NameRefContext ctx) { String nameRefText = ParserHelper.getOriginalText(ctx); Type type = scopeHelper.resolveType(nameRefText).orElse(BuiltInType.UNKNOWN); if (nameRefText.equals("?")) { this.subExpressionContainsWildcard = true; } NameExpr scope = new NameExpr("feelExprCtx"); MethodCallExpr getFromScope = new MethodCallExpr(scope, "getValue"); getFromScope.addArgument(new StringLiteralExpr(nameRefText)); return DirectCompilerResult.of(getFromScope, type); }
@Override public DirectCompilerResult visitType(FEEL_1_1Parser.TypeContext ctx) { String typeAsText = ParserHelper.getOriginalText(ctx); Expression biT = JavaParser.parseExpression("org.kie.dmn.feel.lang.types.BuiltInType"); MethodCallExpr determineCall = new MethodCallExpr(biT, "determineTypeFromName"); determineCall.addArgument(new StringLiteralExpr(typeAsText)); return DirectCompilerResult.of(determineCall, BuiltInType.UNKNOWN); }
@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 visitUnaryTests_empty(FEEL_1_1Parser.UnaryTests_emptyContext ctx) { DirectCompilerResult t = createEmptyUnaryTestExpression(); MethodCallExpr list = new MethodCallExpr( null, "list", new NodeList<>(t.getExpression())); return DirectCompilerResult.of(list, BuiltInType.LIST, t.getFieldDeclarations()); }
private DirectCompilerResult telescopePathAccessor(DirectCompilerResult scopeExpr, List<String> names) { MethodCallExpr pathCall = new MethodCallExpr(new NameExpr(CompiledFEELSupport.class.getSimpleName()), "path"); pathCall.addArgument(new NameExpr("feelExprCtx")); pathCall.addArgument(scopeExpr.getExpression()); MethodCallExpr filterPathCall = new MethodCallExpr(pathCall, "with"); for (String n : names) { filterPathCall.addArgument(new StringLiteralExpr(n)); } // here I could still try to infer the result type, but presently use ANY return DirectCompilerResult.of(filterPathCall, BuiltInType.UNKNOWN).withFD(scopeExpr); }
@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 visitUnaryTests_negated(FEEL_1_1Parser.UnaryTests_negatedContext ctx) { DirectCompilerResult positiveTests = doPositiveUnaryTests(ctx.positiveUnaryTests()); DirectCompilerResult result = createUnaryTestExpression(ctx, positiveTests, UnaryOperator.NOT); MethodCallExpr expression = new MethodCallExpr( null, "list", new NodeList<>(result.getExpression())); return DirectCompilerResult.of(expression, BuiltInType.UNARY_TEST, result.getFieldDeclarations()); }
@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); }
@Override public DirectCompilerResult visitCondOr(FEEL_1_1Parser.CondOrContext ctx) { DirectCompilerResult left = visit( ctx.left ); DirectCompilerResult right = visit( ctx.right ); MethodCallExpr result = new MethodCallExpr(null, "or"); result.addArgument(left.getExpression()); result.addArgument(right.getExpression()); return DirectCompilerResult.of(result, BuiltInType.BOOLEAN).withFD(left).withFD(right); }
@Override public DirectCompilerResult visitCondAnd(FEEL_1_1Parser.CondAndContext ctx) { DirectCompilerResult left = visit( ctx.left ); DirectCompilerResult right = visit( ctx.right ); MethodCallExpr result = new MethodCallExpr(null, "and"); result.addArgument(left.getExpression()); result.addArgument(right.getExpression()); return DirectCompilerResult.of(result, BuiltInType.BOOLEAN).withFD(left).withFD(right); }
@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(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; }