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);
}
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);
}
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);
}
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);
}
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);
}
}
Aggregations