Search in sources :

Example 21 with SegmentCode

use of jetbrick.template.parser.code.SegmentCode in project jetbrick-template-1x by subchen.

the class JetTemplateCodeVisitor method visitExpr_method_invocation.

@Override
public Code visitExpr_method_invocation(Expr_method_invocationContext ctx) {
    // 处理参数
    Expression_listContext expression_list = ctx.expression_list();
    SegmentListCode segmentListCode = (expression_list == null) ? SegmentListCode.EMPTY : (SegmentListCode) expression_list.accept(this);
    Class<?>[] parameterTypes = segmentListCode.getParameterTypes();
    // 查找方法
    SegmentCode code = (SegmentCode) ctx.expression().accept(this);
    assert_not_null_constantContext(code.getNode());
    code = code.asBoxedSegmentCode();
    Class<?> beanClass = code.getKlass();
    String name = ctx.IDENTIFIER().getText();
    Method bean_method = resolver.resolveMethod(beanClass, name, parameterTypes);
    Method tool_method = (bean_method != null) ? null : resolver.resolveToolMethod(beanClass, name, parameterTypes);
    boolean tool_advanced = false;
    if (bean_method == null && tool_method == null) {
        tool_method = resolver.resolveToolMethod_advanced(beanClass, name, parameterTypes);
        tool_advanced = true;
    }
    if (bean_method == null && tool_method == null) {
        // reportError
        StringBuilder err = new StringBuilder(128);
        err.append("The method ").append(getMethodSignature(name, parameterTypes));
        err.append(" is undefined for the type ");
        err.append(beanClass.getName());
        err.append('.');
        if (Object.class.equals(beanClass)) {
            err.append("\n advise: ");
            if (code.getNode() instanceof Expr_identifierContext) {
                err.append("Please use #define(type ");
                err.append(code.getNode().getText());
                err.append(") to define variable type.");
            } else {
                err.append("Please use #set(type xxx = ");
                err.append(code.getNode().getText());
                err.append(") to define expression type.");
            }
        }
        throw reportError(err.toString(), ctx.IDENTIFIER());
    }
    boolean isSafeCall = globalSafeCall || "?.".equals(ctx.getChild(1).getText());
    // 得到方法的返回类型
    Method method = (bean_method == null) ? tool_method : bean_method;
    if (securityManager != null) {
        securityManager.checkMemberAccess(method);
    }
    TypedKlass resultKlass = TypedKlassUtils.getMethodReturnTypedKlass(method);
    boolean boxWhenSafeCall = resultKlass.isPrimitive();
    if (isSafeCall) {
        resultKlass = resultKlass.asBoxedTypedKlass();
    }
    // 生成code
    StringBuilder sb = new StringBuilder(64);
    if (tool_method != null) {
        // tool method
        if (isSafeCall) {
            // 安全调用,防止 NullPointException
            sb.append('(');
            sb.append(code.toString());
            sb.append("==null)?(");
            sb.append(resultKlass.getSource());
            sb.append(")null:");
            if (boxWhenSafeCall) {
                sb.append(resultKlass.getSource()).append(".valueOf(");
            }
        }
        sb.append(ClassUtils.getShortClassName(tool_method.getDeclaringClass()));
        sb.append('.');
        sb.append(name);
        sb.append('(');
        sb.append(code.toString());
        if (tool_advanced) {
            sb.append(",$ctx");
        }
        if (segmentListCode.size() > 0) {
            sb.append(',');
        }
    } else {
        if (isSafeCall) {
            // 安全调用,防止 NullPointException
            sb.append('(');
            sb.append(code.toString());
            sb.append("==null)?(");
            sb.append(resultKlass.getSource());
            sb.append(")null:");
            if (boxWhenSafeCall) {
                sb.append(resultKlass.getSource()).append(".valueOf(");
            }
        }
        sb.append(code.toString());
        sb.append('.');
        sb.append(name);
        sb.append('(');
    }
    if (segmentListCode.size() > 0) {
        sb.append(segmentListCode.toString());
    }
    sb.append(')');
    if (isSafeCall) {
        // 为了安全起见,用()包起来
        if (boxWhenSafeCall) {
            sb.append(')');
        }
        sb.insert(0, '(').append(')');
    }
    return new SegmentCode(resultKlass, sb.toString(), ctx);
}
Also used : TypedKlass(jetbrick.template.parser.support.TypedKlass) SegmentCode(jetbrick.template.parser.code.SegmentCode) Expression_listContext(jetbrick.template.parser.grammer.JetTemplateParser.Expression_listContext) Method(java.lang.reflect.Method) SegmentListCode(jetbrick.template.parser.code.SegmentListCode) Expr_identifierContext(jetbrick.template.parser.grammer.JetTemplateParser.Expr_identifierContext)

Example 22 with SegmentCode

use of jetbrick.template.parser.code.SegmentCode in project jetbrick-template-1x by subchen.

the class JetTemplateCodeVisitor method visitExpr_compare_condition.

@Override
public Code visitExpr_compare_condition(Expr_compare_conditionContext ctx) {
    SegmentCode lhs = (SegmentCode) ctx.expression(0).accept(this);
    SegmentCode rhs = (SegmentCode) ctx.expression(1).accept(this);
    String op = ctx.getChild(1).getText();
    assert_not_void_expression(lhs);
    assert_not_void_expression(rhs);
    String source = "(" + get_if_expression_source(lhs) + op + get_if_expression_source(rhs) + ")";
    return new SegmentCode(Boolean.TYPE, source, ctx);
}
Also used : SegmentCode(jetbrick.template.parser.code.SegmentCode)

Example 23 with SegmentCode

use of jetbrick.template.parser.code.SegmentCode in project jetbrick-template-1x by subchen.

the class JetTemplateCodeVisitor method visitIf_directive.

@Override
public Code visitIf_directive(If_directiveContext ctx) {
    BlockCode code = scopeCode.createBlockCode(16);
    SegmentCode expr_code = (SegmentCode) ctx.expression().accept(this);
    code.addLine("if (" + get_if_expression_source(expr_code) + ") { // line: " + ctx.getStart().getLine());
    scopeCode = scopeCode.push();
    code.addChild(ctx.block().accept(this));
    scopeCode = scopeCode.pop();
    code.addLine("}");
    // elseif ...
    List<Elseif_directiveContext> elseif_directive_list = ctx.elseif_directive();
    for (Elseif_directiveContext elseif_directive : elseif_directive_list) {
        code.addChild(elseif_directive.accept(this));
    }
    // else ...
    Else_directiveContext else_directive = ctx.else_directive();
    if (else_directive != null) {
        code.addChild(else_directive.accept(this));
    }
    return code;
}
Also used : BlockCode(jetbrick.template.parser.code.BlockCode) Elseif_directiveContext(jetbrick.template.parser.grammer.JetTemplateParser.Elseif_directiveContext) Else_directiveContext(jetbrick.template.parser.grammer.JetTemplateParser.Else_directiveContext) SegmentCode(jetbrick.template.parser.code.SegmentCode)

Example 24 with SegmentCode

use of jetbrick.template.parser.code.SegmentCode in project jetbrick-template-1x by subchen.

the class JetTemplateCodeVisitor method visitExpr_math_unary_suffix.

@Override
public Code visitExpr_math_unary_suffix(Expr_math_unary_suffixContext ctx) {
    ExpressionContext expression = ctx.expression();
    SegmentCode code = (SegmentCode) expression.accept(this);
    String op = ctx.getChild(1).getText();
    assert_not_null_constantContext(expression);
    // ++, --
    if (expression.getChildCount() == 1 && expression.getChild(0) instanceof ConstantContext) {
        throw reportError("Invalid argument to operation " + op + ", required: variable, found Value", expression);
    }
    // 类型检查
    Class<?> resultKlass = PromotionUtils.get_unary_inc_dec(code.getKlass(), op);
    if (resultKlass == null) {
        throw reportError("The UnaryOperator \"" + op + "\" is not applicable for the operand " + code.getKlassName(), ctx.getChild(1));
    }
    String source = "(" + code.toString() + op + ")";
    return new SegmentCode(code.getTypedKlass(), source, ctx);
}
Also used : ExpressionContext(jetbrick.template.parser.grammer.JetTemplateParser.ExpressionContext) SegmentCode(jetbrick.template.parser.code.SegmentCode) ConstantContext(jetbrick.template.parser.grammer.JetTemplateParser.ConstantContext)

Example 25 with SegmentCode

use of jetbrick.template.parser.code.SegmentCode in project jetbrick-template-1x by subchen.

the class JetTemplateCodeVisitor method visitExpr_compare_not.

@Override
public Code visitExpr_compare_not(Expr_compare_notContext ctx) {
    SegmentCode code = (SegmentCode) ctx.expression().accept(this);
    String source = "(!" + get_if_expression_source(code) + ")";
    return new SegmentCode(Boolean.TYPE, source, ctx);
}
Also used : SegmentCode(jetbrick.template.parser.code.SegmentCode)

Aggregations

SegmentCode (jetbrick.template.parser.code.SegmentCode)42 SegmentListCode (jetbrick.template.parser.code.SegmentListCode)14 TypedKlass (jetbrick.template.parser.support.TypedKlass)12 BlockCode (jetbrick.template.parser.code.BlockCode)11 DefineExpressionCode (jetbrick.template.parser.code.DefineExpressionCode)9 ExpressionContext (jetbrick.template.parser.grammer.JetTemplateParser.ExpressionContext)9 MacroCode (jetbrick.template.parser.code.MacroCode)8 ForExpressionCode (jetbrick.template.parser.code.ForExpressionCode)7 TerminalNode (org.antlr.v4.runtime.tree.TerminalNode)7 Code (jetbrick.template.parser.code.Code)6 ScopeCode (jetbrick.template.parser.code.ScopeCode)6 TagCode (jetbrick.template.parser.code.TagCode)6 TemplateClassCode (jetbrick.template.parser.code.TemplateClassCode)6 TextCode (jetbrick.template.parser.code.TextCode)6 Expression_listContext (jetbrick.template.parser.grammer.JetTemplateParser.Expression_listContext)6 Method (java.lang.reflect.Method)4 HashMap (java.util.HashMap)3 Map (java.util.Map)3 Field (java.lang.reflect.Field)2 ConstantContext (jetbrick.template.parser.grammer.JetTemplateParser.ConstantContext)2