Search in sources :

Example 31 with SegmentCode

use of jetbrick.template.parser.code.SegmentCode 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)

Example 32 with SegmentCode

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

the class JetTemplateCodeVisitor method visitStatic_type_name.

@Override
public Code visitStatic_type_name(Static_type_nameContext ctx) {
    List<TerminalNode> name_list = ctx.IDENTIFIER();
    StringBuilder sb = new StringBuilder();
    for (TerminalNode node : name_list) {
        if (sb.length() > 0) {
            sb.append('.');
        }
        sb.append(node.getText());
    }
    return new SegmentCode(TypedKlass.NULL, sb.toString(), ctx);
}
Also used : SegmentCode(jetbrick.template.parser.code.SegmentCode) TerminalNode(org.antlr.v4.runtime.tree.TerminalNode)

Example 33 with SegmentCode

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

the class JetTemplateCodeVisitor method visitExpr_group.

@Override
public Code visitExpr_group(Expr_groupContext ctx) {
    SegmentCode code = (SegmentCode) ctx.expression().accept(this);
    String source = "(" + code.toString() + ")";
    return new SegmentCode(code.getTypedKlass(), source, ctx);
}
Also used : SegmentCode(jetbrick.template.parser.code.SegmentCode)

Example 34 with SegmentCode

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

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

the class JetTemplateCodeVisitor method visitConstant.

@Override
public Code visitConstant(ConstantContext ctx) {
    Token token = ((TerminalNode) ctx.getChild(0)).getSymbol();
    String text = token.getText();
    switch(token.getType()) {
        case JetTemplateParser.STRING_DOUBLE:
            return new SegmentCode(String.class, text, ctx);
        case JetTemplateParser.STRING_SINGLE:
            text = StringEscapeUtils.asCanonicalJavaString(text);
            return new SegmentCode(String.class, text, ctx);
        case JetTemplateParser.INTEGER:
        case JetTemplateParser.INTEGER_HEX:
        case JetTemplateParser.FLOATING_POINT:
            Class<?> klass;
            if (text.endsWith("l") || text.endsWith("L")) {
                klass = Long.TYPE;
            } else if (text.endsWith("f") || text.endsWith("F")) {
                klass = Float.TYPE;
            } else if (text.endsWith("d") || text.endsWith("D")) {
                klass = Double.TYPE;
            } else if (token.getType() == JetTemplateParser.FLOATING_POINT) {
                // 浮点数默认是double
                klass = Double.TYPE;
            } else {
                klass = Integer.TYPE;
            }
            return new SegmentCode(klass, text, ctx);
        case JetTemplateParser.KEYWORD_TRUE:
            return new SegmentCode(Boolean.TYPE, text, ctx);
        case JetTemplateParser.KEYWORD_FALSE:
            return new SegmentCode(Boolean.TYPE, text, ctx);
        case JetTemplateParser.KEYWORD_NULL:
            return new SegmentCode(TypedKlass.NULL, text, ctx);
        default:
            throw reportError("Unexpected token type :" + token.getType(), ctx);
    }
}
Also used : SegmentCode(jetbrick.template.parser.code.SegmentCode) Token(org.antlr.v4.runtime.Token) TerminalNode(org.antlr.v4.runtime.tree.TerminalNode)

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