Search in sources :

Example 6 with Code

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

the class JetTemplateCodeVisitor method visitValue.

@Override
public Code visitValue(ValueContext ctx) {
    Code code = ctx.expression().accept(this);
    String source = code.toString();
    // 如果返回值是 void,那么不需要 print 语句。
    if (code instanceof SegmentCode) {
        Class<?> klass = ((SegmentCode) code).getKlass();
        if (Void.TYPE.equals(klass)) {
            return scopeCode.createLineCode(source + "; // line: " + ctx.getStart().getLine());
        }
    }
    Token token = ((TerminalNode) ctx.getChild(0)).getSymbol();
    if (token.getType() == JetTemplateParser.VALUE_ESCAPED_OPEN) {
        source = "JetUtils.asEscapeHtml(" + source + ")";
    }
    if ("null".equals(source)) {
        // 防止编译出错 (也可以生成一个空行)
        source = "(Object)null";
    }
    return scopeCode.createLineCode("$out.print(" + source + "); // line: " + ctx.getStart().getLine());
}
Also used : SegmentCode(jetbrick.template.parser.code.SegmentCode) Token(org.antlr.v4.runtime.Token) TerminalNode(org.antlr.v4.runtime.tree.TerminalNode) ScopeCode(jetbrick.template.parser.code.ScopeCode) BlockCode(jetbrick.template.parser.code.BlockCode) SegmentListCode(jetbrick.template.parser.code.SegmentListCode) TemplateClassCode(jetbrick.template.parser.code.TemplateClassCode) TextCode(jetbrick.template.parser.code.TextCode) ForExpressionCode(jetbrick.template.parser.code.ForExpressionCode) SegmentCode(jetbrick.template.parser.code.SegmentCode) MacroCode(jetbrick.template.parser.code.MacroCode) Code(jetbrick.template.parser.code.Code) DefineExpressionCode(jetbrick.template.parser.code.DefineExpressionCode) TagCode(jetbrick.template.parser.code.TagCode)

Example 7 with Code

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

the class JetTemplateCodeVisitor method visitType.

@Override
public Code visitType(TypeContext ctx) {
    StringBuilder name = new StringBuilder();
    for (TerminalNode node : ctx.IDENTIFIER()) {
        if (name.length() > 0) {
            name.append('.');
        }
        name.append(node.getText());
    }
    // 查找 klass
    Class<?> klass = resolver.resolveClass(name.toString());
    if (klass == null) {
        StringBuilder sb = new StringBuilder(128);
        sb.append("java.lang.ClassNotFoundException: ").append(name);
        sb.append("\n advise: Please define package in 'import.packages' or use full qualified class name.");
        throw reportError(sb.toString(), ctx);
    }
    if (securityManager != null) {
        securityManager.checkMemberAccess(klass);
    }
    // 查找泛型类型 typeArgs
    TypedKlass[] typeArgs = TypedKlass.EMPTY_TYPE_ARGS;
    Type_argumentsContext type_arguments = ctx.type_arguments();
    if (type_arguments != null) {
        SegmentListCode c = (SegmentListCode) type_arguments.accept(this);
        typeArgs = new TypedKlass[c.size()];
        for (int i = 0; i < typeArgs.length; i++) {
            typeArgs[i] = c.getChild(i).getTypedKlass();
        }
    }
    // 如果是数组类型,则把 klass 转成数组
    String array_suffix = "";
    List<Type_array_suffixContext> type_array_suffix = ctx.type_array_suffix();
    for (Type_array_suffixContext c : type_array_suffix) {
        Code code = c.accept(this);
        array_suffix = array_suffix + code.toString();
    }
    if (array_suffix.length() > 0) {
        // 转换成 Array Class, 重新 resolve
        String klassName = name.toString() + array_suffix;
        klass = resolver.resolveClass(klassName);
        if (klass == null) {
            throw reportError("java.lang.ClassNotFoundException: " + klassName, ctx);
        }
    }
    // 返回带有的泛型信息的 Class
    TypedKlass typedKlass = TypedKlass.create(klass, typeArgs);
    return new SegmentCode(typedKlass, typedKlass.toString(), ctx);
}
Also used : SegmentListCode(jetbrick.template.parser.code.SegmentListCode) ScopeCode(jetbrick.template.parser.code.ScopeCode) BlockCode(jetbrick.template.parser.code.BlockCode) SegmentListCode(jetbrick.template.parser.code.SegmentListCode) TemplateClassCode(jetbrick.template.parser.code.TemplateClassCode) TextCode(jetbrick.template.parser.code.TextCode) ForExpressionCode(jetbrick.template.parser.code.ForExpressionCode) SegmentCode(jetbrick.template.parser.code.SegmentCode) MacroCode(jetbrick.template.parser.code.MacroCode) Code(jetbrick.template.parser.code.Code) DefineExpressionCode(jetbrick.template.parser.code.DefineExpressionCode) TagCode(jetbrick.template.parser.code.TagCode) Type_argumentsContext(jetbrick.template.parser.grammer.JetTemplateParser.Type_argumentsContext) TypedKlass(jetbrick.template.parser.support.TypedKlass) SegmentCode(jetbrick.template.parser.code.SegmentCode) TerminalNode(org.antlr.v4.runtime.tree.TerminalNode) Type_array_suffixContext(jetbrick.template.parser.grammer.JetTemplateParser.Type_array_suffixContext)

Example 8 with Code

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

the class JetTemplateCodeVisitor method visitBlock.

@Override
public Code visitBlock(BlockContext ctx) {
    int size = ctx.getChildCount();
    BlockCode code = scopeCode.createBlockCode(size);
    if (size == 0)
        return code;
    for (int i = 0; i < size; i++) {
        ParseTree node = ctx.children.get(i);
        Code c = node.accept(this);
        if (node instanceof TextContext) {
            // 文本节点
            TextCode textCode = (TextCode) c;
            if (trimDirectiveLine || trimDirectiveComments) {
                ParseTree prev = (i > 0) ? ctx.children.get(i - 1) : null;
                ParseTree next = (i < size - 1) ? ctx.children.get(i + 1) : null;
                boolean trimLeft;
                boolean keepLeftNewLine = false;
                if (prev == null) {
                    trimLeft = !(ctx.getParent() instanceof TemplateContext);
                } else {
                    trimLeft = prev instanceof DirectiveContext;
                    if (trimLeft) {
                        // inline directive, 对于一个内联的 #if, #for 指令,后面有要求保留一个 NewLine
                        // @see https://github.com/subchen/jetbrick-template/issues/25
                        ParserRuleContext directive = (ParserRuleContext) ((DirectiveContext) prev).getChild(0);
                        if (directive instanceof If_directiveContext || directive instanceof For_directiveContext) {
                            if (directive.getStart().getLine() == directive.getStop().getLine()) {
                                // 保留一个 NewLine
                                keepLeftNewLine = true;
                            }
                        }
                    }
                }
                boolean trimRight;
                if (next == null) {
                    trimRight = !(ctx.getParent() instanceof TemplateContext);
                } else {
                    trimRight = (next instanceof DirectiveContext);
                }
                // trim 指令两边的注释
                if (trimDirectiveComments) {
                    textCode.trimComments(trimLeft, trimRight, commentsPrefix, commentsSuffix);
                }
                // trim 指令两边的空白内容
                if (trimDirectiveLine) {
                    textCode.trimEmptyLine(trimLeft, trimRight, keepLeftNewLine);
                }
                // trim 掉 #tag 和 #macro 指令最后一个多余的 '\n'
                if (next == null) {
                    if (ctx.getParent() instanceof Tag_directiveContext || ctx.getParent() instanceof Macro_directiveContext) {
                        textCode.trimLastNewLine();
                    }
                }
            }
            if (!textCode.isEmpty()) {
                // 如果有相同内容的Text,则从缓存中读取
                TextCode old = textCache.get(textCode.getText());
                if (old == null) {
                    old = textCode;
                    textCache.put(textCode.getText(), textCode);
                    // add text into field
                    tcc.addField(textCode.getId(), textCode.getText());
                }
                code.addLine(old.toString());
            }
        } else {
            code.addChild(c);
        }
    }
    return code;
}
Also used : ParserRuleContext(org.antlr.v4.runtime.ParserRuleContext) For_directiveContext(jetbrick.template.parser.grammer.JetTemplateParser.For_directiveContext) TemplateContext(jetbrick.template.parser.grammer.JetTemplateParser.TemplateContext) ScopeCode(jetbrick.template.parser.code.ScopeCode) BlockCode(jetbrick.template.parser.code.BlockCode) SegmentListCode(jetbrick.template.parser.code.SegmentListCode) TemplateClassCode(jetbrick.template.parser.code.TemplateClassCode) TextCode(jetbrick.template.parser.code.TextCode) ForExpressionCode(jetbrick.template.parser.code.ForExpressionCode) SegmentCode(jetbrick.template.parser.code.SegmentCode) MacroCode(jetbrick.template.parser.code.MacroCode) Code(jetbrick.template.parser.code.Code) DefineExpressionCode(jetbrick.template.parser.code.DefineExpressionCode) TagCode(jetbrick.template.parser.code.TagCode) BlockCode(jetbrick.template.parser.code.BlockCode) If_directiveContext(jetbrick.template.parser.grammer.JetTemplateParser.If_directiveContext) TextContext(jetbrick.template.parser.grammer.JetTemplateParser.TextContext) Macro_directiveContext(jetbrick.template.parser.grammer.JetTemplateParser.Macro_directiveContext) DirectiveContext(jetbrick.template.parser.grammer.JetTemplateParser.DirectiveContext) TextCode(jetbrick.template.parser.code.TextCode) Tag_directiveContext(jetbrick.template.parser.grammer.JetTemplateParser.Tag_directiveContext) ParseTree(org.antlr.v4.runtime.tree.ParseTree)

Example 9 with Code

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

the class JetTemplate method generateJavaSource.

private String generateJavaSource(Resource resource) {
    char[] source = resource.getSource();
    ANTLRInputStream is = new ANTLRInputStream(source, source.length);
    // set source file name, it will be displayed in error report.
    is.name = resource.getAbsolutePath();
    JetTemplateLexer lexer = new JetTemplateLexer(is);
    // remove ConsoleErrorListener
    lexer.removeErrorListeners();
    lexer.addErrorListener(JetTemplateErrorListener.getInstance());
    JetTemplateParser parser = new JetTemplateParser(new CommonTokenStream(lexer));
    // remove ConsoleErrorListener
    parser.removeErrorListeners();
    parser.addErrorListener(JetTemplateErrorListener.getInstance());
    parser.setErrorHandler(new JetTemplateErrorStrategy());
    TemplateContext templateParseTree = parser.template();
    JetTemplateCodeVisitor visitor = new JetTemplateCodeVisitor(engine, engine.getVariableResolver(), engine.getSecurityManager(), parser, resource);
    Code code = templateParseTree.accept(visitor);
    return code.toString();
}
Also used : CommonTokenStream(org.antlr.v4.runtime.CommonTokenStream) TemplateContext(jetbrick.template.parser.grammer.JetTemplateParser.TemplateContext) Code(jetbrick.template.parser.code.Code) ANTLRInputStream(org.antlr.v4.runtime.ANTLRInputStream)

Example 10 with Code

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

the class JetTemplateCodeVisitor method visitExpr_array_list.

@Override
public Code visitExpr_array_list(Expr_array_listContext ctx) {
    String source = "Collections.EMPTY_LIST";
    Expression_listContext expression_list = ctx.expression_list();
    if (expression_list != null) {
        Code code = expression_list.accept(this);
        source = "Arrays.asList(" + code.toString() + ")";
    }
    return new SegmentCode(List.class, source, ctx);
}
Also used : SegmentCode(jetbrick.template.parser.code.SegmentCode) Expression_listContext(jetbrick.template.parser.grammer.JetTemplateParser.Expression_listContext) ScopeCode(jetbrick.template.parser.code.ScopeCode) BlockCode(jetbrick.template.parser.code.BlockCode) SegmentListCode(jetbrick.template.parser.code.SegmentListCode) TemplateClassCode(jetbrick.template.parser.code.TemplateClassCode) TextCode(jetbrick.template.parser.code.TextCode) ForExpressionCode(jetbrick.template.parser.code.ForExpressionCode) SegmentCode(jetbrick.template.parser.code.SegmentCode) MacroCode(jetbrick.template.parser.code.MacroCode) Code(jetbrick.template.parser.code.Code) DefineExpressionCode(jetbrick.template.parser.code.DefineExpressionCode) TagCode(jetbrick.template.parser.code.TagCode)

Aggregations

Code (jetbrick.template.parser.code.Code)10 BlockCode (jetbrick.template.parser.code.BlockCode)9 DefineExpressionCode (jetbrick.template.parser.code.DefineExpressionCode)9 ForExpressionCode (jetbrick.template.parser.code.ForExpressionCode)9 MacroCode (jetbrick.template.parser.code.MacroCode)9 ScopeCode (jetbrick.template.parser.code.ScopeCode)9 SegmentCode (jetbrick.template.parser.code.SegmentCode)9 SegmentListCode (jetbrick.template.parser.code.SegmentListCode)9 TagCode (jetbrick.template.parser.code.TagCode)9 TemplateClassCode (jetbrick.template.parser.code.TemplateClassCode)9 TextCode (jetbrick.template.parser.code.TextCode)9 TemplateContext (jetbrick.template.parser.grammer.JetTemplateParser.TemplateContext)2 TerminalNode (org.antlr.v4.runtime.tree.TerminalNode)2 DirectiveContext (jetbrick.template.parser.grammer.JetTemplateParser.DirectiveContext)1 Else_directiveContext (jetbrick.template.parser.grammer.JetTemplateParser.Else_directiveContext)1 Expression_listContext (jetbrick.template.parser.grammer.JetTemplateParser.Expression_listContext)1 For_directiveContext (jetbrick.template.parser.grammer.JetTemplateParser.For_directiveContext)1 Hash_map_entry_listContext (jetbrick.template.parser.grammer.JetTemplateParser.Hash_map_entry_listContext)1 If_directiveContext (jetbrick.template.parser.grammer.JetTemplateParser.If_directiveContext)1 Macro_directiveContext (jetbrick.template.parser.grammer.JetTemplateParser.Macro_directiveContext)1