Skip to content

Commit 8e468c4

Browse files
committed
complete refactor of the compilation code into a separate module
1 parent 6094295 commit 8e468c4

24 files changed

Lines changed: 303 additions & 41 deletions

codegen/pom.xml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<parent>
6+
<artifactId>mustache.java</artifactId>
7+
<groupId>com.github.spullara.mustache.java</groupId>
8+
<version>0.8.5-SNAPSHOT</version>
9+
</parent>
10+
<modelVersion>4.0.0</modelVersion>
11+
12+
<artifactId>codegen</artifactId>
13+
14+
<dependencies>
15+
16+
<!-- Compiler -->
17+
<dependency>
18+
<groupId>com.github.spullara.mustache.java</groupId>
19+
<artifactId>compiler</artifactId>
20+
<version>0.8.5-SNAPSHOT</version>
21+
</dependency>
22+
23+
<!-- ASM -->
24+
<dependency>
25+
<groupId>org.ow2.asm</groupId>
26+
<artifactId>asm-commons</artifactId>
27+
<version>4.0</version>
28+
</dependency>
29+
<dependency>
30+
<groupId>org.ow2.asm</groupId>
31+
<artifactId>asm-util</artifactId>
32+
<version>4.0</version>
33+
</dependency>
34+
35+
<!-- Tests -->
36+
<dependency>
37+
<groupId>com.github.spullara.mustache.java</groupId>
38+
<artifactId>compiler</artifactId>
39+
<version>0.8.5-SNAPSHOT</version>
40+
<classifier>tests</classifier>
41+
<scope>test</scope>
42+
</dependency>
43+
<dependency>
44+
<groupId>org.codehaus.jackson</groupId>
45+
<artifactId>jackson-mapper-asl</artifactId>
46+
<version>1.9.3</version>
47+
<scope>test</scope>
48+
</dependency>
49+
<dependency>
50+
<groupId>junit</groupId>
51+
<artifactId>junit</artifactId>
52+
<version>4.8.2</version>
53+
<scope>test</scope>
54+
</dependency>
55+
56+
</dependencies>
57+
</project>

compiler/src/main/java/com/github/mustachejava/asm/CodeCompiler.java renamed to codegen/src/main/java/com/github/mustachejava/codegen/CodeCompiler.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.github.mustachejava.asm;
1+
package com.github.mustachejava.codegen;
22

33
import com.github.mustachejava.Code;
44
import org.objectweb.asm.ClassWriter;
@@ -20,10 +20,10 @@ public class CodeCompiler {
2020
private static AtomicInteger id = new AtomicInteger(0);
2121
private static final Method EXECUTE_METHOD = Method.getMethod("java.io.Writer execute(java.io.Writer, Object[])");
2222

23-
public static CompiledCodes compile(Code[] codes, Code[] newcodes) {
23+
public static CompiledCodes compile(Code[] newcodes) {
2424
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
2525
int classId = id.incrementAndGet();
26-
String className = "com.github.mustachejava.asm.RunCodes" + classId;
26+
String className = "com.github.mustachejava.codegen.RunCodes" + classId;
2727
String internalClassName = className.replace(".", "/");
2828
cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, internalClassName, null, "java/lang/Object", new String[]{CompiledCodes.class.getName().replace(".", "/")});
2929
cw.visitSource("runCodes", null);
@@ -90,7 +90,7 @@ public static CompiledCodes compile(Code[] codes, Code[] newcodes) {
9090
cw.visitEnd();
9191
Class<?> aClass = GuardCompiler.defineClass(className, cw.toByteArray());
9292
try {
93-
return (CompiledCodes) aClass.getConstructor(Code[].class).newInstance(new Object[] {codes});
93+
return (CompiledCodes) aClass.getConstructor(Code[].class).newInstance(new Object[] {newcodes});
9494
} catch (Exception e) {
9595
e.printStackTrace();
9696
return null;
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package com.github.mustachejava.codegen;
2+
3+
import com.github.mustachejava.*;
4+
import com.github.mustachejava.codes.DefaultMustache;
5+
6+
import java.io.File;
7+
import java.io.Writer;
8+
9+
/**
10+
* Codegen mustache code execution.
11+
*/
12+
public class CodegenMustacheFactory extends DefaultMustacheFactory {
13+
@Override
14+
public MustacheVisitor createMustacheVisitor() {
15+
return new DefaultMustacheVisitor(this) {
16+
@Override
17+
public Mustache mustache(TemplateContext templateContext) {
18+
return new DefaultMustache(templateContext, cf, list.toArray(new Code[list.size()]), templateContext.file()) {
19+
20+
private CompiledCodes compiledCodes;
21+
22+
@Override
23+
public Writer run(Writer writer, Object[] scopes) {
24+
if (compiledCodes != null) {
25+
return compiledCodes.runCodes(writer, scopes);
26+
}
27+
return super.run(writer, scopes);
28+
}
29+
30+
@Override
31+
public void setCodes(Code[] newcodes) {
32+
super.setCodes(newcodes);
33+
if (newcodes != null) {
34+
compiledCodes = CodeCompiler.compile(newcodes);
35+
}
36+
}
37+
};
38+
}
39+
};
40+
}
41+
42+
public CodegenMustacheFactory() {
43+
super();
44+
setObjectHandler(new CodegenObjectHandler());
45+
}
46+
47+
public CodegenMustacheFactory(File fileRoot) {
48+
super(fileRoot);
49+
setObjectHandler(new CodegenObjectHandler());
50+
}
51+
52+
public CodegenMustacheFactory(String resourceRoot) {
53+
super(resourceRoot);
54+
setObjectHandler(new CodegenObjectHandler());
55+
}
56+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package com.github.mustachejava.codegen;
2+
3+
import com.github.mustachejava.MustacheException;
4+
import com.github.mustachejava.codegen.guards.*;
5+
import com.github.mustachejava.reflect.*;
6+
import com.github.mustachejava.reflect.guards.*;
7+
import com.github.mustachejava.util.GuardException;
8+
import com.github.mustachejava.util.Wrapper;
9+
10+
import java.lang.reflect.AccessibleObject;
11+
import java.util.List;
12+
13+
/**
14+
* Generates code when it can for higher performance. Make sure you have enough
15+
* PermGen to run your application. Each variable will generate at least one guard
16+
* class and each mustache section or partial will as well.
17+
*/
18+
public class CodegenObjectHandler extends ReflectionObjectHandler {
19+
@Override
20+
protected ClassGuard createClassGuard(int i, Object scope) {
21+
return new CompilableClassGuard(i, scope);
22+
}
23+
24+
@Override
25+
protected DepthGuard createDepthGuard(int length) {
26+
return new CompilableDepthGuard(length);
27+
}
28+
29+
@Override
30+
protected DotGuard createDotGuard(int i, Object scope, String lookup) {
31+
return new CompilableDotGuard(lookup, i, scope);
32+
}
33+
34+
@Override
35+
protected MapGuard createMapGuard(int scopeIndex, Wrapper[] wrappers, String name, boolean contains) {
36+
return new CompilableMapGuard(this, scopeIndex, name, contains, wrappers);
37+
}
38+
39+
@Override
40+
protected NullGuard createNullGuard() {
41+
return new CompilableNullGuard();
42+
}
43+
44+
@Override
45+
protected WrappedGuard createWrappedGuard(int i, List<Wrapper> wrappers, List<Guard> wrapperGuard) {
46+
return new CompilableWrappedGuard(this, i, wrappers, wrapperGuard);
47+
}
48+
49+
@Override
50+
protected MissingWrapper createMissingWrapper(List<Guard> guards) {
51+
final Guard compiledGuards = compile(guards);
52+
return new MissingWrapper(guards.toArray(new Guard[guards.size()])) {
53+
@Override
54+
protected void guardCall(Object[] scopes) throws GuardException {
55+
if (!compiledGuards.apply(scopes)) {
56+
throw guardException;
57+
}
58+
}
59+
};
60+
}
61+
62+
@Override
63+
protected Wrapper createWrapper(int scopeIndex, Wrapper[] wrappers, List<? extends Guard> guards, AccessibleObject member, Object[] arguments) {
64+
final Guard compiledGuards = compile(guards);
65+
return new ReflectionWrapper(scopeIndex, wrappers, guards.toArray(new Guard[guards.size()]), member, arguments, this) {
66+
@Override
67+
protected void guardCall(Object[] scopes) throws GuardException {
68+
if (!compiledGuards.apply(scopes)) {
69+
throw guardException;
70+
}
71+
}
72+
};
73+
}
74+
75+
private Guard compile(List<? extends Guard> guard) {
76+
Guard[] compiled = GuardCompiler.compile(guard.toArray(new Guard[guard.size()]));
77+
if (compiled.length != 1) throw new MustacheException("Failed to compile all guards: " + guard);
78+
return compiled[0];
79+
}
80+
}

compiler/src/main/java/com/github/mustachejava/asm/CompilableGuard.java renamed to codegen/src/main/java/com/github/mustachejava/codegen/CompilableGuard.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.github.mustachejava.asm;
1+
package com.github.mustachejava.codegen;
22

33
import com.github.mustachejava.ObjectHandler;
44
import com.github.mustachejava.reflect.Guard;

compiler/src/main/java/com/github/mustachejava/asm/CompiledCodes.java renamed to codegen/src/main/java/com/github/mustachejava/codegen/CompiledCodes.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.github.mustachejava.asm;
1+
package com.github.mustachejava.codegen;
22

33
import java.io.Writer;
44

compiler/src/main/java/com/github/mustachejava/asm/GuardCompiler.java renamed to codegen/src/main/java/com/github/mustachejava/codegen/GuardCompiler.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.github.mustachejava.asm;
1+
package com.github.mustachejava.codegen;
22

33
import com.github.mustachejava.reflect.Guard;
44
import org.objectweb.asm.ClassWriter;
@@ -43,7 +43,7 @@ public static Guard[] compile(Guard[] guards) {
4343
public static Guard compile(String source, Iterable<CompilableGuard> guards) throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
4444
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
4545
int classId = id.incrementAndGet();
46-
String className = "com.github.mustachejava.asm.CompiledGuards" + classId;
46+
String className = "com.github.mustachejava.codegen.CompiledGuards" + classId;
4747
String internalClassName = className.replace(".", "/");
4848
cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, internalClassName, null, "java/lang/Object", new String[]{Guard.class.getName().replace(".", "/")});
4949
cw.visitSource(source, null);

compiler/src/main/java/com/github/mustachejava/asm/guards/CompilableClassGuard.java renamed to codegen/src/main/java/com/github/mustachejava/codegen/guards/CompilableClassGuard.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
package com.github.mustachejava.asm.guards;
1+
package com.github.mustachejava.codegen.guards;
22

3-
import com.github.mustachejava.asm.CompilableGuard;
3+
import com.github.mustachejava.codegen.CompilableGuard;
44
import com.github.mustachejava.reflect.guards.ClassGuard;
55
import org.objectweb.asm.ClassWriter;
66
import org.objectweb.asm.Label;

compiler/src/main/java/com/github/mustachejava/asm/guards/CompilableDepthGuard.java renamed to codegen/src/main/java/com/github/mustachejava/codegen/guards/CompilableDepthGuard.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
package com.github.mustachejava.asm.guards;
1+
package com.github.mustachejava.codegen.guards;
22

3-
import com.github.mustachejava.asm.CompilableGuard;
3+
import com.github.mustachejava.codegen.CompilableGuard;
44
import com.github.mustachejava.reflect.guards.DepthGuard;
55
import org.objectweb.asm.ClassWriter;
66
import org.objectweb.asm.Label;

compiler/src/main/java/com/github/mustachejava/asm/guards/CompilableDotGuard.java renamed to codegen/src/main/java/com/github/mustachejava/codegen/guards/CompilableDotGuard.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
package com.github.mustachejava.asm.guards;
1+
package com.github.mustachejava.codegen.guards;
22

3-
import com.github.mustachejava.asm.CompilableGuard;
3+
import com.github.mustachejava.codegen.CompilableGuard;
44
import com.github.mustachejava.reflect.guards.DotGuard;
55
import org.objectweb.asm.ClassWriter;
66
import org.objectweb.asm.Label;

0 commit comments

Comments
 (0)