use of jetbrick.template.parser.code.SegmentListCode 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.SegmentListCode 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.SegmentListCode in project jetbrick-template-1x by subchen.
the class JetTemplateCodeVisitor method visitTag_directive.
@Override
public Code visitTag_directive(Tag_directiveContext ctx) {
String text = ctx.getChild(0).getText();
String name = text.substring(5, text.length() - 1).trim();
TagCode tagCode = scopeCode.createTagCode();
tagCode.setTagId(getUid("tag"));
scopeCode = tagCode.getMethodCode();
scopeCode.define(Code.CONTEXT_NAME, TypedKlass.JetContext);
// add body content
scopeCode.setBodyCode(ctx.block().accept(this));
scopeCode = scopeCode.pop();
// finding tag function
Expression_listContext expression_list = ctx.expression_list();
SegmentListCode segmentListCode = (expression_list == null) ? SegmentListCode.EMPTY : (SegmentListCode) expression_list.accept(this);
Class<?>[] parameterTypes = segmentListCode.getParameterTypes(JetTagContext.class);
Method method = resolver.resolveTagMethod(name, parameterTypes);
if (method == null) {
throw reportError("Undefined tag definition: " + getMethodSignature(name, parameterTypes), ctx);
}
tagCode.setMethod(method);
tagCode.setExpressionListCode(segmentListCode);
return tagCode;
}
use of jetbrick.template.parser.code.SegmentListCode in project jetbrick-template-1x by subchen.
the class JetTemplateCodeVisitor method visitExpr_static_method_invocation.
@Override
public Code visitExpr_static_method_invocation(Expr_static_method_invocationContext ctx) {
SegmentCode static_type_name_code = (SegmentCode) ctx.static_type_name().accept(this);
String typeName = static_type_name_code.toString();
String name = ctx.IDENTIFIER().getText();
// 获取静态 Class
Class<?> beanClass = resolver.resolveClass(typeName);
if (beanClass == null) {
throw reportError("java.lang.ClassNotFoundException: " + typeName, static_type_name_code.getNode());
}
// 处理参数
Expression_listContext expression_list = ctx.expression_list();
SegmentListCode segmentListCode = (expression_list == null) ? SegmentListCode.EMPTY : (SegmentListCode) expression_list.accept(this);
Class<?>[] parameterTypes = segmentListCode.getParameterTypes();
Method method = resolver.resolveStaticMethod(beanClass, name, parameterTypes);
if (method == null) {
throw reportError("The static method " + getMethodSignature(name, parameterTypes) + " is undefined for the type " + beanClass.getName(), ctx.IDENTIFIER());
}
if (securityManager != null) {
securityManager.checkMemberAccess(method);
}
// 生成代码
StringBuilder sb = new StringBuilder();
sb.append(ClassUtils.getShortClassName(method.getDeclaringClass()));
sb.append('.');
sb.append(name);
sb.append('(');
sb.append(segmentListCode.toString());
sb.append(')');
TypedKlass resultKlass = TypedKlassUtils.getMethodReturnTypedKlass(method);
return new SegmentCode(resultKlass, sb.toString(), ctx);
}
use of jetbrick.template.parser.code.SegmentListCode 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);
}
Aggregations