Search in sources :

Example 1 with ForExpressionCode

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

the class JetTemplateCodeVisitor method visitFor_directive.

@Override
public Code visitFor_directive(For_directiveContext ctx) {
    BlockCode code = scopeCode.createBlockCode(16);
    String id_for = getUid("for");
    scopeCode = scopeCode.push();
    // 注意:for循环变量的作用域要放在 for 内部, 防止出现变量重定义错误
    ForExpressionCode for_expr_code = (ForExpressionCode) ctx.for_expression().accept(this);
    // for block
    forStack.push(id_for);
    Code for_block_code = ctx.block().accept(this);
    forStack.pop();
    scopeCode = scopeCode.pop();
    // for-else
    Else_directiveContext else_directive = ctx.else_directive();
    Code for_else_block = (else_directive == null) ? null : else_directive.accept(this);
    // 生成代码
    String id_foritem = getUid("foritem");
    String typeName = for_expr_code.getKlassName();
    String itemName = for_expr_code.getName();
    code.addLine("Object " + id_foritem + " = context.get(\"" + itemName + "\"); // save it");
    code.addLine("JetForIterator " + id_for + " = new JetForIterator(" + for_expr_code.toString() + ");");
    code.addLine("while (" + id_for + ".hasNext()) { // line: " + ctx.getStart().getLine());
    // class item = (class) it.next() ...
    code.addLine("  " + typeName + " " + itemName + " = (" + typeName + ") " + id_for + ".next();");
    code.addLine("  context.put(\"" + itemName + "\", " + itemName + ");");
    code.addChild(for_block_code);
    code.addLine("}");
    code.addLine("context.put(\"" + itemName + "\", " + id_foritem + "); // reset it");
    // for else ...
    if (for_else_block != null) {
        code.addLine("if (" + id_for + ".empty()) { // line: " + ctx.getStart().getLine());
        code.addChild(for_else_block);
        code.addLine("}");
    }
    return code;
}
Also used : BlockCode(jetbrick.template.parser.code.BlockCode) ForExpressionCode(jetbrick.template.parser.code.ForExpressionCode) Else_directiveContext(jetbrick.template.parser.grammer.JetTemplateParser.Else_directiveContext) 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 2 with ForExpressionCode

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

the class JetTemplateCodeVisitor method visitFor_expression.

@Override
public Code visitFor_expression(For_expressionContext ctx) {
    String name = ctx.IDENTIFIER().getText();
    SegmentCode code = (SegmentCode) ctx.expression().accept(this);
    assert_not_void_expression(code);
    TypedKlass resultKlass = null;
    TypeContext type = ctx.type();
    if (type != null) {
        // 手动定义返回变量的类型
        SegmentCode c = (SegmentCode) type.accept(this);
        resultKlass = c.getTypedKlass();
    } else {
        // 根据 expression 来进行自动类型推导
        Class<?> rhsKlass = code.getKlass();
        if (rhsKlass.isArray()) {
            resultKlass = TypedKlass.create(rhsKlass.getComponentType(), code.getTypeArgs());
        } else if (Map.class.isAssignableFrom(rhsKlass)) {
            resultKlass = TypedKlass.create(Map.Entry.class, code.getTypeArgs());
        } else if (Collection.class.isAssignableFrom(rhsKlass)) {
            if (code.getTypeArgs() != null && code.getTypeArgs().length == 1) {
                resultKlass = code.getTypeArgs()[0];
            }
        }
    }
    if (resultKlass == null) {
        resultKlass = TypedKlass.Object;
    }
    // 必须是 Boxed 对象,因为需要强制类型转换 from iterator.next()
    resultKlass = resultKlass.asBoxedTypedKlass();
    if (!scopeCode.define(name, resultKlass)) {
        throw reportError("Duplicate local variable " + name, ctx.IDENTIFIER());
    }
    return new ForExpressionCode(resultKlass, name, code.toString(), ctx);
}
Also used : ForExpressionCode(jetbrick.template.parser.code.ForExpressionCode) TypedKlass(jetbrick.template.parser.support.TypedKlass) SegmentCode(jetbrick.template.parser.code.SegmentCode) TypeContext(jetbrick.template.parser.grammer.JetTemplateParser.TypeContext) Map(java.util.Map) HashMap(java.util.HashMap)

Aggregations

ForExpressionCode (jetbrick.template.parser.code.ForExpressionCode)2 SegmentCode (jetbrick.template.parser.code.SegmentCode)2 HashMap (java.util.HashMap)1 Map (java.util.Map)1 BlockCode (jetbrick.template.parser.code.BlockCode)1 Code (jetbrick.template.parser.code.Code)1 DefineExpressionCode (jetbrick.template.parser.code.DefineExpressionCode)1 MacroCode (jetbrick.template.parser.code.MacroCode)1 ScopeCode (jetbrick.template.parser.code.ScopeCode)1 SegmentListCode (jetbrick.template.parser.code.SegmentListCode)1 TagCode (jetbrick.template.parser.code.TagCode)1 TemplateClassCode (jetbrick.template.parser.code.TemplateClassCode)1 TextCode (jetbrick.template.parser.code.TextCode)1 Else_directiveContext (jetbrick.template.parser.grammer.JetTemplateParser.Else_directiveContext)1 TypeContext (jetbrick.template.parser.grammer.JetTemplateParser.TypeContext)1 TypedKlass (jetbrick.template.parser.support.TypedKlass)1