Skip to content

Commit

Permalink
Make the TemplateProcessingTracer interface slightly more useful.
Browse files Browse the repository at this point in the history
  • Loading branch information
nolaviz committed Feb 4, 2023
1 parent 8756804 commit 66857d9
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 32 deletions.
25 changes: 15 additions & 10 deletions src/main/java/freemarker/core/Environment.java
Original file line number Diff line number Diff line change
Expand Up @@ -302,13 +302,6 @@ private void clearCachedValues() {
cachedURLEscapingCharsetSet = false;
}

/**
* Sets the tracer to use for this environment.
*/
public void setTracer(TemplateProcessingTracer tracer) {
currentTracer = tracer;
}

/**
* Processes the template to which this environment belongs to.
*/
Expand All @@ -320,14 +313,12 @@ public void process() throws TemplateException, IOException {
clearCachedValues();
try {
doAutoImportsAndIncludes(this);
if (currentTracer != null) currentTracer.start();
visit(getTemplate().getRootTreeNode());
// It's here as we must not flush if there was an exception.
if (getAutoFlush()) {
out.flush();
}
} finally {
if (currentTracer != null) currentTracer.end();
// It's just to allow the GC to free memory...
clearCachedValues();
}
Expand Down Expand Up @@ -2882,6 +2873,13 @@ public TemplateModel get(String key) throws TemplateModelException {
};
}

/**
* Sets the tracer to use for this environment.
*/
public void setTracer(TemplateProcessingTracer tracer) {
currentTracer = tracer;
}

private void pushElement(TemplateElement element) {
final int newSize = ++instructionStackSize;
TemplateElement[] instructionStack = this.instructionStack;
Expand All @@ -2895,12 +2893,19 @@ private void pushElement(TemplateElement element) {
}
instructionStack[newSize - 1] = element;
if (currentTracer != null) {
currentTracer.trace(element.getTemplate(), element.getBeginColumn(), element.getBeginLine(),
currentTracer.enterElement(element.getTemplate(),
element.getBeginColumn(), element.getBeginLine(),
element.getEndColumn(), element.getEndLine(), element.isLeaf());
}
}

private void popElement() {
if (currentTracer != null) {
TemplateElement element = instructionStack[instructionStackSize - 1];
currentTracer.exitElement(element.getTemplate(),
element.getBeginColumn(), element.getBeginLine(),
element.getEndColumn(), element.getEndLine());
}
instructionStackSize--;
}

Expand Down
13 changes: 3 additions & 10 deletions src/main/java/freemarker/core/TemplateProcessingTracer.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,28 +36,21 @@
*/
public interface TemplateProcessingTracer {

/**
* Invoked when {@link Template.process()} starts processing the template.
*
* @since 2.3.23
*/
void start();

/**
* Invoked by {@link Environment} whenever it starts processing a new template element. {@code
* isLeafElement} indicates whether this element is a leaf, or whether the tracer should expect
* to receive lower-level elements within the context of this one.
*
* @since 2.3.23
*/
void trace(Template template, int beginColumn, int beginLine, int endColumn, int endLine,
void enterElement(Template template, int beginColumn, int beginLine, int endColumn, int endLine,
boolean isLeafElement);

/**
* Invoked when template processing is finished.
* Invoked by {@link Environment} whenever it completes processing a new template element.
*
* @since 2.3.23
*/
void end();
void exitElement(Template template, int beginColumn, int beginLine, int endColumn, int endLine);

}
27 changes: 15 additions & 12 deletions src/test/java/freemarker/core/TemplateProcessingTracerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public class TemplateProcessingTracerTest {
"Nope.\n" +
"</#list>\n" +
"<#list [] as item>\n" +
"${item}<#else>\n" +
"${item}<#else>" +
"Yup.\n" +
"</#list>\n";

Expand All @@ -50,31 +50,34 @@ public void test() throws Exception {
Configuration cfg = new Configuration(Configuration.VERSION_2_3_32);
Template t = new Template("test.ftl", TEMPLATE_TEXT, cfg);
StringWriter sw = new StringWriter();
Tracer tracer = new Tracer();
Tracer tracer = new Tracer(TEMPLATE_TEXT);
Environment env = t.createProcessingEnvironment(null, sw);
env.setTracer(tracer);
env.process();

List<Integer> expected = Arrays.asList(2, 3, 5, 5, 5, 9);
assertEquals(expected, tracer.linesVisited);
List<String> expected = Arrays.asList("Yup.", "Always.", "${item}", "${item}", "${item}", "Yup.");
assertEquals(expected, tracer.elementsVisited);
}

private static class Tracer implements TemplateProcessingTracer {
ArrayList<Integer> linesVisited;
final ArrayList<String> elementsVisited;
final String[] templateLines;

Tracer() {
linesVisited = new ArrayList<>();
Tracer(String template) {
elementsVisited = new ArrayList<>();
templateLines = template.split("\\n");
}

public void start() {}
public void end() {}

public void trace(Template template, int beginColumn, int beginLine, int endColumn, int endLine,
public void enterElement(Template template, int beginColumn, int beginLine, int endColumn, int endLine,
boolean isLeafElement) {
if (isLeafElement) {
linesVisited.add(beginLine);
String line = templateLines[beginLine - 1];
String elementText = line.substring(beginColumn - 1,
endLine == beginLine ? Math.min(endColumn, line.length()) : line.length());
elementsVisited.add(elementText);
}
}

public void exitElement(Template template, int beginColumn, int beginLine, int endColumn, int endLine) {}
}
}

0 comments on commit 66857d9

Please sign in to comment.