Skip to content

Commit 332d5aa

Browse files
author
Sam Pullara
committed
visitor implementation should be better
1 parent 9a5f709 commit 332d5aa

17 files changed

Lines changed: 231 additions & 164 deletions

compiler/src/main/java/com/github/mustachejava/DefaultMustacheFactory.java

Lines changed: 2 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@
3434
*/
3535
public class DefaultMustacheFactory implements MustacheFactory {
3636

37-
private static final Code EOF = new DefaultCode();
38-
3937
private final MustacheParser mc = new MustacheParser(this);
4038
private final Map<String, Mustache> templateCache = new ConcurrentHashMap<String, Mustache>();
4139
private ObjectHandler oh = new ReflectionObjectHandler();
@@ -64,43 +62,8 @@ public DefaultMustacheFactory(File fileRoot) {
6462
}
6563

6664
@Override
67-
public Code iterable(final String variable, List<Code> codes, final String file, final int start, String sm, String em) {
68-
return new IterableCode(this, codes, variable, sm, em, file);
69-
}
70-
71-
@Override
72-
public Code notIterable(final String variable, List<Code> codes, String file, int start, String sm, String em) {
73-
return new NotIterableCode(this, codes, variable, sm, em);
74-
}
75-
76-
@Override
77-
public Code name(String variable, List<Code> codes, String file, int start, String sm, String em) {
78-
return new ExtendNameCode(this, codes.toArray(new Code[0]), variable, sm, em);
79-
}
80-
81-
@Override
82-
public Code partial(final String variable, String file, int line, String sm, String em) {
83-
return new PartialCode(this, variable, file, sm, em);
84-
}
85-
86-
@Override
87-
public Code value(final String variable, final boolean encoded, final int line, String sm, String em) {
88-
return new ValueCode(this, variable, sm, em, encoded, line);
89-
}
90-
91-
@Override
92-
public Code write(final String text, int line, String sm, String em) {
93-
return new WriteCode(text);
94-
}
95-
96-
@Override
97-
public Code eof(int line) {
98-
return EOF;
99-
}
100-
101-
@Override
102-
public Code extend(String variable, List<Code> codes, String file, int start, String sm, String em) {
103-
return new ExtendCode(this, codes.toArray(new Code[0]), variable, file, sm, em);
65+
public MustacheVisitor createMustacheVisitor() {
66+
return new DefaultMustacheVisitor(this);
10467
}
10568

10669
@Override
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package com.github.mustachejava;
2+
3+
import java.util.LinkedList;
4+
import java.util.List;
5+
6+
import com.github.mustachejava.codes.DefaultCode;
7+
import com.github.mustachejava.codes.DefaultMustache;
8+
import com.github.mustachejava.codes.ExtendCode;
9+
import com.github.mustachejava.codes.ExtendNameCode;
10+
import com.github.mustachejava.codes.IterableCode;
11+
import com.github.mustachejava.codes.NotIterableCode;
12+
import com.github.mustachejava.codes.PartialCode;
13+
import com.github.mustachejava.codes.ValueCode;
14+
import com.github.mustachejava.codes.WriteCode;
15+
16+
/**
17+
* The default implementation that builds up Code lists
18+
*/
19+
public class DefaultMustacheVisitor implements MustacheVisitor {
20+
private static final Code EOF = new DefaultCode();
21+
22+
protected final List<Code> list = new LinkedList<Code>();
23+
protected DefaultMustacheFactory cf;
24+
25+
public DefaultMustacheVisitor(DefaultMustacheFactory cf) {
26+
this.cf = cf;
27+
}
28+
29+
@Override
30+
public Mustache mustache(String file, String sm, String em) {
31+
return new DefaultMustache(cf, list.toArray(new Code[list.size()]), file, sm, em);
32+
}
33+
34+
@Override
35+
public void iterable(final String variable, Mustache mustache, final String file, final int start, String sm, String em) {
36+
list.add(new IterableCode(cf, mustache, variable, sm, em, file));
37+
}
38+
39+
@Override
40+
public void notIterable(final String variable, Mustache mustache, String file, int start, String sm, String em) {
41+
list.add(new NotIterableCode(cf, mustache, variable, sm, em));
42+
}
43+
44+
@Override
45+
public void name(String variable, Mustache mustache, String file, int start, String sm, String em) {
46+
list.add(new ExtendNameCode(cf, mustache, variable, sm, em));
47+
}
48+
49+
@Override
50+
public void partial(final String variable, String file, int line, String sm, String em) {
51+
list.add(new PartialCode(cf, variable, file, sm, em));
52+
}
53+
54+
@Override
55+
public void value(final String variable, final boolean encoded, final int line, String sm, String em) {
56+
list.add(new ValueCode(cf, variable, sm, em, encoded, line));
57+
}
58+
59+
@Override
60+
public void write(final String text, int line, String sm, String em) {
61+
if (text.length() > 0) {
62+
int size = list.size();
63+
if (size > 0) {
64+
Code code = list.get(size - 1);
65+
code.append(text);
66+
} else {
67+
list.add(new WriteCode(text));
68+
}
69+
}
70+
}
71+
72+
@Override
73+
public void eof(int line) {
74+
list.add(EOF);
75+
}
76+
77+
@Override
78+
public void extend(String variable, Mustache mustache, String file, int start, String sm, String em) {
79+
list.add(new ExtendCode(cf, mustache, variable, file, sm, em));
80+
}
81+
82+
}

compiler/src/main/java/com/github/mustachejava/MustacheFactory.java

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,9 @@
88
* Factory for creating codes
99
*/
1010
public interface MustacheFactory {
11-
// Specified
12-
Code iterable(String variable, List<Code> codes, String file, int start, String sm, String em);
13-
Code notIterable(String variable, List<Code> codes, String file, int start, String sm, String em);
14-
Code name(String variable, List<Code> codes, String file, int start, String sm, String em);
15-
Code partial(String variable, String file, int line, String sm, String em);
16-
Code value(String finalName, boolean b, int line, String sm, String em);
17-
Code write(String text, int line, String sm, String em);
11+
// Create a new visitor
12+
MustacheVisitor createMustacheVisitor();
1813

19-
// Internal
20-
Code eof(int line);
21-
22-
// TODO: Extension
23-
Code extend(String variable, List<Code> codes, String file, int start, String sm, String em);
24-
2514
// Get readers
2615
Reader getReader(String file);
2716

compiler/src/main/java/com/github/mustachejava/MustacheParser.java

Lines changed: 28 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import java.io.BufferedReader;
44
import java.io.IOException;
55
import java.io.Reader;
6-
import java.util.LinkedList;
76
import java.util.List;
87
import java.util.concurrent.atomic.AtomicInteger;
98

@@ -39,11 +38,10 @@ public Mustache compile(Reader reader, String file) {
3938
}
4039

4140
public Mustache compile(Reader reader, String file, String sm, String em) {
42-
Code[] codes = compile(reader, null, new AtomicInteger(0), file, sm, em).toArray(new Code[0]);
43-
return new DefaultMustache(cf, codes, file, sm, em);
41+
return compile(reader, null, new AtomicInteger(0), file, sm, em);
4442
}
4543

46-
public List<Code> compile(final Reader reader, String tag, final AtomicInteger currentLine, String file, String sm, String em) throws MustacheException {
44+
public Mustache compile(final Reader reader, String tag, final AtomicInteger currentLine, String file, String sm, String em) throws MustacheException {
4745
if (reader == null) {
4846
throw new MustacheException("Reader is null");
4947
}
@@ -53,7 +51,7 @@ public List<Code> compile(final Reader reader, String tag, final AtomicInteger c
5351
} else {
5452
br = new BufferedReader(reader);
5553
}
56-
final List<Code> list = new LinkedList<Code>();
54+
MustacheVisitor mv = cf.createMustacheVisitor();
5755
// Now we grab the mustache template
5856
boolean onlywhitespace = true;
5957
boolean iterable = currentLine.get() != 0;
@@ -71,7 +69,7 @@ public List<Code> compile(final Reader reader, String tag, final AtomicInteger c
7169
if (!iterable || (iterable && !onlywhitespace)) {
7270
out.append("\n");
7371
}
74-
out = write(list, out, currentLine.intValue());
72+
out = write(mv, out, currentLine.intValue());
7573

7674
iterable = false;
7775
onlywhitespace = true;
@@ -107,24 +105,24 @@ public List<Code> compile(final Reader reader, String tag, final AtomicInteger c
107105
case '<':
108106
case '$': {
109107
int start = currentLine.get();
110-
final List<Code> codes = compile(br, variable, currentLine, file, sm, em);
108+
final Mustache mustache = compile(br, variable, currentLine, file, sm, em);
111109
int lines = currentLine.get() - start;
112110
if (!onlywhitespace || lines == 0) {
113-
write(list, out, currentLine.intValue());
111+
write(mv, out, currentLine.intValue());
114112
}
115113
out = new StringBuilder();
116114
switch (ch) {
117115
case '#':
118-
list.add(cf.iterable(variable, codes, file, start, sm, em));
116+
mv.iterable(variable, mustache, file, start, sm, em);
119117
break;
120118
case '^':
121-
list.add(cf.notIterable(variable, codes, file, start, sm, em));
119+
mv.notIterable(variable, mustache, file, start, sm, em);
122120
break;
123121
case '<':
124-
list.add(cf.extend(variable, codes, file, start, sm, em));
122+
mv.extend(variable, mustache, file, start, sm, em);
125123
break;
126124
case '$':
127-
list.add(cf.name(variable, codes, file, start, sm, em));
125+
mv.name(variable, mustache, file, start, sm, em);
128126
break;
129127
}
130128
iterable = lines != 0;
@@ -133,22 +131,22 @@ public List<Code> compile(final Reader reader, String tag, final AtomicInteger c
133131
case '/': {
134132
// Tag end
135133
if (!onlywhitespace) {
136-
write(list, out, currentLine.intValue());
134+
write(mv, out, currentLine.intValue());
137135
}
138136
if (!variable.equals(tag)) {
139137
throw new MustacheException(
140138
"Mismatched start/end tags: " + tag + " != " + variable + " in " + file + ":" + currentLine);
141139
}
142140

143-
return list;
141+
return mv.mustache(file, sm, em);
144142
}
145143
case '>': {
146-
out = write(list, out, currentLine.intValue());
147-
list.add(cf.partial(variable, file, currentLine.get(), sm, em));
144+
out = write(mv, out, currentLine.intValue());
145+
mv.partial(variable, file, currentLine.get(), sm, em);
148146
break;
149147
}
150148
case '{': {
151-
out = write(list, out, currentLine.intValue());
149+
out = write(mv, out, currentLine.intValue());
152150
// Not escaped
153151
String name = variable;
154152
if (em.charAt(1) != '}') {
@@ -160,26 +158,26 @@ public List<Code> compile(final Reader reader, String tag, final AtomicInteger c
160158
}
161159
}
162160
final String finalName = name;
163-
list.add(cf.value(finalName, false, currentLine.intValue(), sm, em));
161+
mv.value(finalName, false, currentLine.intValue(), sm, em);
164162
break;
165163
}
166164
case '&': {
167165
// Not escaped
168-
out = write(list, out, currentLine.intValue());
169-
list.add(cf.value(variable, false, currentLine.intValue(), sm, em));
166+
out = write(mv, out, currentLine.intValue());
167+
mv.value(variable, false, currentLine.intValue(), sm, em);
170168
break;
171169
}
172170
case '%':
173171
// Pragmas
174-
out = write(list, out, currentLine.intValue());
172+
out = write(mv, out, currentLine.intValue());
175173
break;
176174
case '!':
177175
// Comment
178-
out = write(list, out, currentLine.intValue());
176+
out = write(mv, out, currentLine.intValue());
179177
break;
180178
case '=':
181179
// Change delimiters
182-
out = write(list, out, currentLine.intValue());
180+
out = write(mv, out, currentLine.intValue());
183181
String delimiters = command.replaceAll("\\s+", "");
184182
int length = delimiters.length();
185183
if (length > 6 || length / 2 * 2 != length) {
@@ -194,8 +192,8 @@ public List<Code> compile(final Reader reader, String tag, final AtomicInteger c
194192
"Improperly closed variable in " + file + ":" + currentLine);
195193
}
196194
// Reference
197-
out = write(list, out, currentLine.intValue());
198-
list.add(cf.value(command.trim(), true, currentLine.intValue(), sm, em));
195+
out = write(mv, out, currentLine.intValue());
196+
mv.value(command.trim(), true, currentLine.intValue(), sm, em);
199197
break;
200198
}
201199
}
@@ -208,29 +206,21 @@ public List<Code> compile(final Reader reader, String tag, final AtomicInteger c
208206
onlywhitespace = onlywhitespace && (c == ' ' || c == '\t' || c == '\r');
209207
out.append((char) c);
210208
}
211-
write(list, out, currentLine.intValue());
209+
write(mv, out, currentLine.intValue());
212210
br.close();
213211
} catch (IOException e) {
214212
throw new MustacheException("Failed to read", e);
215213
}
216-
list.add(cf.eof(currentLine.intValue()));
217-
return list;
214+
mv.eof(currentLine.intValue());
215+
return mv.mustache(file, sm, em);
218216
}
219217

220218
/**
221219
* Ignore empty strings and append to the previous code if it was also a write.
222220
*/
223-
private StringBuilder write(List<Code> list, StringBuilder out, int line) {
221+
private StringBuilder write(MustacheVisitor mv, StringBuilder out, int line) {
224222
String text = out.toString();
225-
if (text.length() > 0) {
226-
int size = list.size();
227-
if (size > 0) {
228-
Code code = list.get(size - 1);
229-
code.append(text);
230-
} else {
231-
list.add(cf.write(text, line, null, null));
232-
}
233-
}
223+
mv.write(text, line, null, null);
234224
return new StringBuilder();
235225
}
236226

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.github.mustachejava;
2+
3+
import java.util.List;
4+
5+
/**
6+
* Callbacks from the parser as a mustache template is parsed.
7+
*/
8+
public interface MustacheVisitor {
9+
// Mustache
10+
Mustache mustache(String file, String sm, String em);
11+
12+
// Specified
13+
void iterable(String variable, Mustache mustache, String file, int start, String sm, String em);
14+
void notIterable(String variable, Mustache mustache, String file, int start, String sm, String em);
15+
void partial(String variable, String file, int line, String sm, String em);
16+
void value(String finalName, boolean b, int line, String sm, String em);
17+
void write(String text, int line, String sm, String em);
18+
19+
// Internal
20+
void eof(int line);
21+
22+
// Extension
23+
void extend(String variable, Mustache mustache, String file, int start, String sm, String em);
24+
void name(String variable, Mustache mustache, String file, int start, String sm, String em);
25+
}

0 commit comments

Comments
 (0)