Search in sources :

Example 1 with MacroCode

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

the class JetTemplateCodeVisitor method visitExpr_function_call.

@Override
public Code visitExpr_function_call(Expr_function_callContext ctx) {
    // 处理参数
    Expression_listContext expression_list = ctx.expression_list();
    SegmentListCode segmentListCode = (expression_list == null) ? SegmentListCode.EMPTY : (SegmentListCode) expression_list.accept(this);
    Class<?>[] parameterTypes = segmentListCode.getParameterTypes();
    // 查找方法
    String name = ctx.IDENTIFIER().getText();
    // 优先查找 macro
    MacroCode macroCode = null;
    if (macroMap != null) {
        macroCode = macroMap.get(name);
        if (macroCode != null) {
            // macro 参数匹配
            SegmentListCode defineListCode = macroCode.getDefineListCode();
            int size = (defineListCode == null) ? 0 : defineListCode.size();
            if (parameterTypes.length != size) {
                throw reportError("Arguments mismatch for #macro " + getMethodSignature(name, parameterTypes) + ".", ctx.IDENTIFIER());
            }
            for (int i = 0; i < parameterTypes.length; i++) {
                if (!ClassUtils.isAssignable(parameterTypes[i], defineListCode.getChild(i).getKlass())) {
                    throw reportError("Arguments mismatch for #macro " + getMethodSignature(name, parameterTypes) + ".", ctx.IDENTIFIER());
                }
            }
            // 生成 macro 调用 code
            StringBuilder sb = new StringBuilder(64);
            sb.append("$macro_").append(name);
            sb.append("($ctx");
            if (segmentListCode.size() > 0) {
                sb.append(',').append(segmentListCode.toString());
            }
            sb.append(')');
            return new SegmentCode(TypedKlass.VOID, sb.toString(), ctx);
        }
    }
    // 查找扩展方法
    boolean advanced = false;
    Method method = resolver.resolveFunction(name, parameterTypes);
    if (method == null) {
        method = resolver.resolveFunction_advanced(name, parameterTypes);
        advanced = true;
    }
    if (method == null) {
        throw reportError("Undefined function or arguments mismatch: " + getMethodSignature(name, parameterTypes) + ".", ctx.IDENTIFIER());
    }
    if (securityManager != null) {
        securityManager.checkMemberAccess(method);
    }
    // 生成code
    StringBuilder sb = new StringBuilder(64);
    sb.append(ClassUtils.getShortClassName(method.getDeclaringClass()));
    sb.append('.');
    sb.append(name);
    sb.append('(');
    if (advanced) {
        sb.append("$ctx");
    }
    if (segmentListCode.size() > 0) {
        if (advanced)
            sb.append(',');
        sb.append(segmentListCode.toString());
    }
    sb.append(')');
    TypedKlass typedKlass = TypedKlassUtils.getMethodReturnTypedKlass(method);
    return new SegmentCode(typedKlass, 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) MacroCode(jetbrick.template.parser.code.MacroCode)

Example 2 with MacroCode

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

the class JetTemplateCodeVisitor method visitMacro_directive.

@Override
public Code visitMacro_directive(Macro_directiveContext ctx) {
    String text = ctx.getChild(0).getText();
    String name = text.substring(7, text.length() - 1).trim();
    MacroCode macroCode = scopeCode.createMacroCode();
    macroCode.setName(name);
    scopeCode = macroCode.getMethodCode();
    scopeCode.define(Code.CONTEXT_NAME, TypedKlass.JetContext);
    // 处理参数
    Define_expression_listContext define_expression_list = ctx.define_expression_list();
    if (define_expression_list != null) {
        SegmentListCode define_list_code = (SegmentListCode) define_expression_list.accept(this);
        macroCode.setDefineListCode(define_list_code);
        // 设置参数 Context
        for (SegmentCode node : define_list_code.getChildren()) {
            DefineExpressionCode c = (DefineExpressionCode) node;
            scopeCode.define(c.getName(), c.getTypedKlass());
        }
    }
    // 需要先定义 macro,这样可以支持 macro 的递归调用 (issue 102)
    if (macroMap == null) {
        macroMap = new HashMap<String, MacroCode>(8);
    }
    MacroCode old = macroMap.put(name, macroCode);
    if (old != null) {
        throw reportError("Duplicated macro defination " + name, ctx);
    }
    tcc.addMacro(macroCode);
    // 访问 macro body
    // add body content
    scopeCode.setBodyCode(ctx.block().accept(this));
    scopeCode = scopeCode.pop();
    return Code.EMPTY;
}
Also used : SegmentCode(jetbrick.template.parser.code.SegmentCode) DefineExpressionCode(jetbrick.template.parser.code.DefineExpressionCode) MacroCode(jetbrick.template.parser.code.MacroCode) SegmentListCode(jetbrick.template.parser.code.SegmentListCode) Define_expression_listContext(jetbrick.template.parser.grammer.JetTemplateParser.Define_expression_listContext)

Aggregations

MacroCode (jetbrick.template.parser.code.MacroCode)2 SegmentCode (jetbrick.template.parser.code.SegmentCode)2 SegmentListCode (jetbrick.template.parser.code.SegmentListCode)2 Method (java.lang.reflect.Method)1 DefineExpressionCode (jetbrick.template.parser.code.DefineExpressionCode)1 Define_expression_listContext (jetbrick.template.parser.grammer.JetTemplateParser.Define_expression_listContext)1 Expression_listContext (jetbrick.template.parser.grammer.JetTemplateParser.Expression_listContext)1 TypedKlass (jetbrick.template.parser.support.TypedKlass)1