use of jetbrick.template.parser.code.SegmentCode in project jetbrick-template-1x by subchen.
the class JetTemplateCodeVisitor method visitStop_directive.
@Override
public Code visitStop_directive(Stop_directiveContext ctx) {
ExpressionContext expression = ctx.expression();
String source;
if (expression != null) {
SegmentCode c = (SegmentCode) expression.accept(this);
source = get_if_expression_source(c);
} else {
source = "true";
}
source = "if (" + source + ") return; // line: " + ctx.getStart().getLine();
return scopeCode.createLineCode(source);
}
use of jetbrick.template.parser.code.SegmentCode 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;
}
use of jetbrick.template.parser.code.SegmentCode in project jetbrick-template-1x by subchen.
the class JetTemplateCodeVisitor method visitType_list.
@Override
public Code visitType_list(Type_listContext ctx) {
List<Type_nameContext> type_name_list = ctx.type_name();
SegmentListCode code = new SegmentListCode(type_name_list.size());
for (Type_nameContext type_name : type_name_list) {
Code c = type_name.accept(this);
code.addChild((SegmentCode) c);
}
return code;
}
use of jetbrick.template.parser.code.SegmentCode in project jetbrick-template-1x by subchen.
the class JetTemplateCodeVisitor method visitInclude_directive.
@Override
public Code visitInclude_directive(Include_directiveContext ctx) {
Expression_listContext expression_list = ctx.expression_list();
SegmentListCode childrenCode = (SegmentListCode) expression_list.accept(this);
if (childrenCode.size() > 2) {
throw reportError("Arguments mismatch for #include directive.", ctx);
}
// argument 1: file
SegmentCode fileCode = childrenCode.getChild(0);
ExpressionContext fileExpression = expression_list.expression(0);
if (!String.class.equals(fileCode.getKlass())) {
throw reportError("Type mismatch: the first argument cannot convert from " + fileCode.getKlassName() + " to String", fileExpression);
}
// argument 2: parameters
SegmentCode parametersCode = null;
if (childrenCode.size() > 1) {
parametersCode = childrenCode.getChild(1);
if (!(Map.class.equals(parametersCode.getKlass()))) {
throw reportError("Type mismatch: the second argument cannot convert from " + parametersCode.getKlassName() + " to Map", expression_list.expression(1));
}
}
// 如果 file 是常量,那么进行 file.exists() 校验
if (fileExpression instanceof Expr_constantContext) {
String file = fileCode.toString();
file = file.substring(1, file.length() - 1);
file = StringEscapeUtils.unescapeJava(file);
file = PathUtils.getAbsolutionName(resource.getName(), file);
if (!engine.lookupResource(file)) {
throw reportError("FileNotFoundException: " + file, fileExpression);
}
}
// 生成代码
StringBuilder source = new StringBuilder();
source.append("JetUtils.asInclude($ctx, ");
source.append(fileCode.toString());
source.append(", (Map<String, Object>)");
source.append((parametersCode != null) ? parametersCode.toString() : "null");
source.append("); // line: ");
source.append(ctx.getStart().getLine());
return scopeCode.createLineCode(source.toString());
}
use of jetbrick.template.parser.code.SegmentCode in project jetbrick-template-1x by subchen.
the class JetTemplateCodeVisitor method visitExpr_math_binary_bitwise.
@Override
public Code visitExpr_math_binary_bitwise(Expr_math_binary_bitwiseContext ctx) {
SegmentCode lhs = (SegmentCode) ctx.expression(0).accept(this);
SegmentCode rhs = (SegmentCode) ctx.expression(1).accept(this);
String op = ctx.getChild(1).getText();
// 类型检查
Class<?> resultKlass = PromotionUtils.get_binary_bitwise(lhs.getKlass(), rhs.getKlass(), op);
if (resultKlass == null) {
throw reportError("The BinaryOperator \"" + op + "\" is not applicable for the operands " + lhs.getKlassName() + " and " + rhs.getKlassName(), ctx);
}
String source = "(" + lhs.toString() + op + rhs.toString() + ")";
return new SegmentCode(resultKlass, source, ctx);
}
Aggregations