Search in sources :

Example 1 with TypeContext

use of jetbrick.template.parser.grammer.JetTemplateParser.TypeContext in project jetbrick-template-1x by subchen.

the class JetTemplateCodeVisitor method visitSet_expression.

@Override
public Code visitSet_expression(Set_expressionContext ctx) {
    String name = assert_java_identifier(ctx.IDENTIFIER(), true);
    SegmentCode code = (SegmentCode) ctx.expression().accept(this);
    // 是否同时定义一个变量
    boolean defining = false;
    // 变量类型
    TypedKlass lhs = null;
    TypeContext type = ctx.type();
    if (type != null) {
        defining = true;
        // 定义一个变量
        SegmentCode c = (SegmentCode) type.accept(this);
        lhs = c.getTypedKlass();
        if (!scopeCode.define(name, lhs)) {
            throw reportError("Duplicate local variable " + name, ctx.IDENTIFIER());
        }
    } else {
        // 直接赋值,如果变量没有定义,则先定义
        lhs = scopeCode.resolve(name, false);
        defining = (lhs == null);
        if (defining) {
            lhs = code.getTypedKlass();
            scopeCode.define(name, lhs);
        }
    }
    // 进行赋值语句类型检查
    if (!ClassUtils.isAssignable(lhs.getKlass(), code.getKlass())) {
        // 是否支持正常赋值
        if (!ClassUtils.isAssignable(code.getKlass(), lhs.getKlass())) {
            // 是否支持强制类型转换
            throw reportError("Type mismatch: cannot convert from " + code.getTypedKlass().toString() + " to " + lhs.toString(), ctx);
        }
    }
    BlockCode c = scopeCode.createBlockCode(2);
    String source = name + " = (" + lhs.getSource() + ") " + code.toString() + "; // line: " + ctx.getStart().getLine();
    if (defining) {
        source = lhs.getSource() + " " + source;
    }
    c.addLine(source);
    c.addLine(Code.CONTEXT_NAME + ".put(\"" + name + "\", " + name + ");");
    return c;
}
Also used : BlockCode(jetbrick.template.parser.code.BlockCode) TypedKlass(jetbrick.template.parser.support.TypedKlass) SegmentCode(jetbrick.template.parser.code.SegmentCode) TypeContext(jetbrick.template.parser.grammer.JetTemplateParser.TypeContext)

Example 2 with TypeContext

use of jetbrick.template.parser.grammer.JetTemplateParser.TypeContext 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

SegmentCode (jetbrick.template.parser.code.SegmentCode)2 TypeContext (jetbrick.template.parser.grammer.JetTemplateParser.TypeContext)2 TypedKlass (jetbrick.template.parser.support.TypedKlass)2 HashMap (java.util.HashMap)1 Map (java.util.Map)1 BlockCode (jetbrick.template.parser.code.BlockCode)1 ForExpressionCode (jetbrick.template.parser.code.ForExpressionCode)1