use of jetbrick.template.parser.code.Code in project jetbrick-template-1x by subchen.
the class JetTemplateCodeVisitor method visitValue.
@Override
public Code visitValue(ValueContext ctx) {
Code code = ctx.expression().accept(this);
String source = code.toString();
// 如果返回值是 void,那么不需要 print 语句。
if (code instanceof SegmentCode) {
Class<?> klass = ((SegmentCode) code).getKlass();
if (Void.TYPE.equals(klass)) {
return scopeCode.createLineCode(source + "; // line: " + ctx.getStart().getLine());
}
}
Token token = ((TerminalNode) ctx.getChild(0)).getSymbol();
if (token.getType() == JetTemplateParser.VALUE_ESCAPED_OPEN) {
source = "JetUtils.asEscapeHtml(" + source + ")";
}
if ("null".equals(source)) {
// 防止编译出错 (也可以生成一个空行)
source = "(Object)null";
}
return scopeCode.createLineCode("$out.print(" + source + "); // line: " + ctx.getStart().getLine());
}
use of jetbrick.template.parser.code.Code 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);
}
use of jetbrick.template.parser.code.Code in project jetbrick-template-1x by subchen.
the class JetTemplateCodeVisitor method visitBlock.
@Override
public Code visitBlock(BlockContext ctx) {
int size = ctx.getChildCount();
BlockCode code = scopeCode.createBlockCode(size);
if (size == 0)
return code;
for (int i = 0; i < size; i++) {
ParseTree node = ctx.children.get(i);
Code c = node.accept(this);
if (node instanceof TextContext) {
// 文本节点
TextCode textCode = (TextCode) c;
if (trimDirectiveLine || trimDirectiveComments) {
ParseTree prev = (i > 0) ? ctx.children.get(i - 1) : null;
ParseTree next = (i < size - 1) ? ctx.children.get(i + 1) : null;
boolean trimLeft;
boolean keepLeftNewLine = false;
if (prev == null) {
trimLeft = !(ctx.getParent() instanceof TemplateContext);
} else {
trimLeft = prev instanceof DirectiveContext;
if (trimLeft) {
// inline directive, 对于一个内联的 #if, #for 指令,后面有要求保留一个 NewLine
// @see https://github.com/subchen/jetbrick-template/issues/25
ParserRuleContext directive = (ParserRuleContext) ((DirectiveContext) prev).getChild(0);
if (directive instanceof If_directiveContext || directive instanceof For_directiveContext) {
if (directive.getStart().getLine() == directive.getStop().getLine()) {
// 保留一个 NewLine
keepLeftNewLine = true;
}
}
}
}
boolean trimRight;
if (next == null) {
trimRight = !(ctx.getParent() instanceof TemplateContext);
} else {
trimRight = (next instanceof DirectiveContext);
}
// trim 指令两边的注释
if (trimDirectiveComments) {
textCode.trimComments(trimLeft, trimRight, commentsPrefix, commentsSuffix);
}
// trim 指令两边的空白内容
if (trimDirectiveLine) {
textCode.trimEmptyLine(trimLeft, trimRight, keepLeftNewLine);
}
// trim 掉 #tag 和 #macro 指令最后一个多余的 '\n'
if (next == null) {
if (ctx.getParent() instanceof Tag_directiveContext || ctx.getParent() instanceof Macro_directiveContext) {
textCode.trimLastNewLine();
}
}
}
if (!textCode.isEmpty()) {
// 如果有相同内容的Text,则从缓存中读取
TextCode old = textCache.get(textCode.getText());
if (old == null) {
old = textCode;
textCache.put(textCode.getText(), textCode);
// add text into field
tcc.addField(textCode.getId(), textCode.getText());
}
code.addLine(old.toString());
}
} else {
code.addChild(c);
}
}
return code;
}
use of jetbrick.template.parser.code.Code in project jetbrick-template-1x by subchen.
the class JetTemplate method generateJavaSource.
private String generateJavaSource(Resource resource) {
char[] source = resource.getSource();
ANTLRInputStream is = new ANTLRInputStream(source, source.length);
// set source file name, it will be displayed in error report.
is.name = resource.getAbsolutePath();
JetTemplateLexer lexer = new JetTemplateLexer(is);
// remove ConsoleErrorListener
lexer.removeErrorListeners();
lexer.addErrorListener(JetTemplateErrorListener.getInstance());
JetTemplateParser parser = new JetTemplateParser(new CommonTokenStream(lexer));
// remove ConsoleErrorListener
parser.removeErrorListeners();
parser.addErrorListener(JetTemplateErrorListener.getInstance());
parser.setErrorHandler(new JetTemplateErrorStrategy());
TemplateContext templateParseTree = parser.template();
JetTemplateCodeVisitor visitor = new JetTemplateCodeVisitor(engine, engine.getVariableResolver(), engine.getSecurityManager(), parser, resource);
Code code = templateParseTree.accept(visitor);
return code.toString();
}
use of jetbrick.template.parser.code.Code in project jetbrick-template-1x by subchen.
the class JetTemplateCodeVisitor method visitExpr_array_list.
@Override
public Code visitExpr_array_list(Expr_array_listContext ctx) {
String source = "Collections.EMPTY_LIST";
Expression_listContext expression_list = ctx.expression_list();
if (expression_list != null) {
Code code = expression_list.accept(this);
source = "Arrays.asList(" + code.toString() + ")";
}
return new SegmentCode(List.class, source, ctx);
}
Aggregations