Search in sources :

Example 6 with SegmentListCode

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

the class JetTemplateCodeVisitor method visitHash_map_entry_list.

@Override
public Code visitHash_map_entry_list(Hash_map_entry_listContext ctx) {
    List<ExpressionContext> expression_list = ctx.expression();
    SegmentListCode code = new SegmentListCode(expression_list.size());
    for (ExpressionContext expression : expression_list) {
        code.addChild((SegmentCode) expression.accept(this));
    }
    return code;
}
Also used : ExpressionContext(jetbrick.template.parser.grammer.JetTemplateParser.ExpressionContext) SegmentListCode(jetbrick.template.parser.code.SegmentListCode)

Example 7 with SegmentListCode

use of jetbrick.template.parser.code.SegmentListCode 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 8 with SegmentListCode

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

the class JetTemplateCodeVisitor method visitExpression_list.

@Override
public Code visitExpression_list(Expression_listContext ctx) {
    List<ExpressionContext> expression_list = ctx.expression();
    SegmentListCode code = new SegmentListCode(expression_list.size());
    for (ExpressionContext expression : expression_list) {
        SegmentCode c = (SegmentCode) expression.accept(this);
        assert_not_void_expression(c);
        code.addChild(c);
    }
    return code;
}
Also used : ExpressionContext(jetbrick.template.parser.grammer.JetTemplateParser.ExpressionContext) SegmentCode(jetbrick.template.parser.code.SegmentCode) SegmentListCode(jetbrick.template.parser.code.SegmentListCode)

Example 9 with SegmentListCode

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

the class JetTemplateCodeVisitor method visitDefine_directive.

@Override
public Code visitDefine_directive(Define_directiveContext ctx) {
    SegmentListCode define_expression_list = (SegmentListCode) ctx.define_expression_list().accept(this);
    BlockCode code = scopeCode.createBlockCode(define_expression_list.size());
    for (SegmentCode node : define_expression_list.getChildren()) {
        DefineExpressionCode c = (DefineExpressionCode) node;
        String name = c.getName();
        if (!scopeCode.define(name, c.getTypedKlass())) {
            throw reportError("Duplicate local variable " + name, c.getNode());
        }
        String typeName = c.getTypedKlass().asBoxedTypedKlass().toString();
        code.addLine(typeName + " " + name + " = (" + typeName + ") " + Code.CONTEXT_NAME + ".get(\"" + name + "\"); // line: " + c.getNode().getStart().getLine());
    }
    return code;
}
Also used : BlockCode(jetbrick.template.parser.code.BlockCode) SegmentCode(jetbrick.template.parser.code.SegmentCode) DefineExpressionCode(jetbrick.template.parser.code.DefineExpressionCode) SegmentListCode(jetbrick.template.parser.code.SegmentListCode)

Example 10 with SegmentListCode

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

the class JetTemplateCodeVisitor method visitExpr_new_object.

@Override
public Code visitExpr_new_object(Expr_new_objectContext ctx) {
    SegmentCode code = (SegmentCode) ctx.type().accept(this);
    Expression_listContext expression_list = ctx.expression_list();
    SegmentListCode segmentListCode = (expression_list == null) ? SegmentListCode.EMPTY : (SegmentListCode) expression_list.accept(this);
    Class<?>[] parameterTypes = segmentListCode.getParameterTypes();
    // 查找对应的构造函数
    Class<?> beanClass = code.getKlass();
    Constructor<?> constructor = resolver.resolveConstructor(beanClass, parameterTypes);
    if (constructor == null) {
        // reportError
        StringBuilder err = new StringBuilder(128);
        err.append("The constructor ");
        err.append(getMethodSignature(beanClass.getSimpleName(), parameterTypes));
        err.append(" is undefined for the type ");
        err.append(beanClass.getName());
        err.append('.');
        throw reportError(err.toString(), ctx.type());
    }
    // 生成代码
    StringBuilder source = new StringBuilder(32);
    source.append("(new ").append(code.toString()).append('(');
    if (segmentListCode.size() > 0) {
        source.append(segmentListCode.toString());
    }
    source.append("))");
    return new SegmentCode(code.getTypedKlass(), source.toString(), ctx);
}
Also used : SegmentCode(jetbrick.template.parser.code.SegmentCode) Expression_listContext(jetbrick.template.parser.grammer.JetTemplateParser.Expression_listContext) SegmentListCode(jetbrick.template.parser.code.SegmentListCode)

Aggregations

SegmentListCode (jetbrick.template.parser.code.SegmentListCode)13 SegmentCode (jetbrick.template.parser.code.SegmentCode)10 Expression_listContext (jetbrick.template.parser.grammer.JetTemplateParser.Expression_listContext)6 Method (java.lang.reflect.Method)4 DefineExpressionCode (jetbrick.template.parser.code.DefineExpressionCode)4 MacroCode (jetbrick.template.parser.code.MacroCode)4 TypedKlass (jetbrick.template.parser.support.TypedKlass)4 BlockCode (jetbrick.template.parser.code.BlockCode)3 TagCode (jetbrick.template.parser.code.TagCode)3 ExpressionContext (jetbrick.template.parser.grammer.JetTemplateParser.ExpressionContext)3 Code (jetbrick.template.parser.code.Code)2 ForExpressionCode (jetbrick.template.parser.code.ForExpressionCode)2 ScopeCode (jetbrick.template.parser.code.ScopeCode)2 TemplateClassCode (jetbrick.template.parser.code.TemplateClassCode)2 TextCode (jetbrick.template.parser.code.TextCode)2 Define_expressionContext (jetbrick.template.parser.grammer.JetTemplateParser.Define_expressionContext)1 Define_expression_listContext (jetbrick.template.parser.grammer.JetTemplateParser.Define_expression_listContext)1 Expr_constantContext (jetbrick.template.parser.grammer.JetTemplateParser.Expr_constantContext)1 Expr_identifierContext (jetbrick.template.parser.grammer.JetTemplateParser.Expr_identifierContext)1 Type_argumentsContext (jetbrick.template.parser.grammer.JetTemplateParser.Type_argumentsContext)1