use of jetbrick.template.parser.grammer.JetTemplateParser.Expression_listContext 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.grammer.JetTemplateParser.Expression_listContext 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.grammer.JetTemplateParser.Expression_listContext 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.grammer.JetTemplateParser.Expression_listContext in project jetbrick-template-1x by subchen.
the class JetTemplateCodeVisitor method visitExpr_method_invocation.
@Override
public Code visitExpr_method_invocation(Expr_method_invocationContext ctx) {
// 处理参数
Expression_listContext expression_list = ctx.expression_list();
SegmentListCode segmentListCode = (expression_list == null) ? SegmentListCode.EMPTY : (SegmentListCode) expression_list.accept(this);
Class<?>[] parameterTypes = segmentListCode.getParameterTypes();
// 查找方法
SegmentCode code = (SegmentCode) ctx.expression().accept(this);
assert_not_null_constantContext(code.getNode());
code = code.asBoxedSegmentCode();
Class<?> beanClass = code.getKlass();
String name = ctx.IDENTIFIER().getText();
Method bean_method = resolver.resolveMethod(beanClass, name, parameterTypes);
Method tool_method = (bean_method != null) ? null : resolver.resolveToolMethod(beanClass, name, parameterTypes);
boolean tool_advanced = false;
if (bean_method == null && tool_method == null) {
tool_method = resolver.resolveToolMethod_advanced(beanClass, name, parameterTypes);
tool_advanced = true;
}
if (bean_method == null && tool_method == null) {
// reportError
StringBuilder err = new StringBuilder(128);
err.append("The method ").append(getMethodSignature(name, parameterTypes));
err.append(" is undefined for the type ");
err.append(beanClass.getName());
err.append('.');
if (Object.class.equals(beanClass)) {
err.append("\n advise: ");
if (code.getNode() instanceof Expr_identifierContext) {
err.append("Please use #define(type ");
err.append(code.getNode().getText());
err.append(") to define variable type.");
} else {
err.append("Please use #set(type xxx = ");
err.append(code.getNode().getText());
err.append(") to define expression type.");
}
}
throw reportError(err.toString(), ctx.IDENTIFIER());
}
boolean isSafeCall = globalSafeCall || "?.".equals(ctx.getChild(1).getText());
// 得到方法的返回类型
Method method = (bean_method == null) ? tool_method : bean_method;
if (securityManager != null) {
securityManager.checkMemberAccess(method);
}
TypedKlass resultKlass = TypedKlassUtils.getMethodReturnTypedKlass(method);
boolean boxWhenSafeCall = resultKlass.isPrimitive();
if (isSafeCall) {
resultKlass = resultKlass.asBoxedTypedKlass();
}
// 生成code
StringBuilder sb = new StringBuilder(64);
if (tool_method != null) {
// tool method
if (isSafeCall) {
// 安全调用,防止 NullPointException
sb.append('(');
sb.append(code.toString());
sb.append("==null)?(");
sb.append(resultKlass.getSource());
sb.append(")null:");
if (boxWhenSafeCall) {
sb.append(resultKlass.getSource()).append(".valueOf(");
}
}
sb.append(ClassUtils.getShortClassName(tool_method.getDeclaringClass()));
sb.append('.');
sb.append(name);
sb.append('(');
sb.append(code.toString());
if (tool_advanced) {
sb.append(",$ctx");
}
if (segmentListCode.size() > 0) {
sb.append(',');
}
} else {
if (isSafeCall) {
// 安全调用,防止 NullPointException
sb.append('(');
sb.append(code.toString());
sb.append("==null)?(");
sb.append(resultKlass.getSource());
sb.append(")null:");
if (boxWhenSafeCall) {
sb.append(resultKlass.getSource()).append(".valueOf(");
}
}
sb.append(code.toString());
sb.append('.');
sb.append(name);
sb.append('(');
}
if (segmentListCode.size() > 0) {
sb.append(segmentListCode.toString());
}
sb.append(')');
if (isSafeCall) {
// 为了安全起见,用()包起来
if (boxWhenSafeCall) {
sb.append(')');
}
sb.insert(0, '(').append(')');
}
return new SegmentCode(resultKlass, sb.toString(), ctx);
}
use of jetbrick.template.parser.grammer.JetTemplateParser.Expression_listContext 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);
}
Aggregations