You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@freemarker.apache.org by dd...@apache.org on 2015/12/13 17:02:27 UTC
[10/15] incubator-freemarker git commit: [unfinished] Getting rid of
nestedBlock VS regulatedChildren
[unfinished] Getting rid of nestedBlock VS regulatedChildren
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/808ddadd
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/808ddadd
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/808ddadd
Branch: refs/heads/2.3-gae
Commit: 808ddadd382a5ce116b249ee4ae14c683c96ba91
Parents: 83eca1b
Author: ddekany <dd...@apache.org>
Authored: Mon Dec 7 21:56:32 2015 +0100
Committer: ddekany <dd...@apache.org>
Committed: Wed Dec 9 00:00:05 2015 +0100
----------------------------------------------------------------------
.../freemarker/core/AssignmentInstruction.java | 14 +-
src/main/java/freemarker/core/AttemptBlock.java | 6 +-
src/main/java/freemarker/core/AutoEscBlock.java | 11 +-
.../java/freemarker/core/BlockAssignment.java | 9 +-
src/main/java/freemarker/core/Case.java | 6 +-
.../java/freemarker/core/CompressedBlock.java | 14 +-
.../java/freemarker/core/ConditionalBlock.java | 8 +-
src/main/java/freemarker/core/DebugBreak.java | 10 +-
src/main/java/freemarker/core/ElseOfList.java | 8 +-
src/main/java/freemarker/core/Environment.java | 66 ++--
src/main/java/freemarker/core/EscapeBlock.java | 8 +-
src/main/java/freemarker/core/IfBlock.java | 20 +-
src/main/java/freemarker/core/Items.java | 6 +-
.../java/freemarker/core/IteratorBlock.java | 40 +--
.../java/freemarker/core/ListElseContainer.java | 10 +-
src/main/java/freemarker/core/Macro.java | 17 +-
src/main/java/freemarker/core/MixedContent.java | 23 +-
.../NestedContentNotSupportedException.java | 5 +-
.../java/freemarker/core/NoAutoEscBlock.java | 11 +-
.../java/freemarker/core/NoEscapeBlock.java | 6 +-
.../java/freemarker/core/OutputFormatBlock.java | 11 +-
.../java/freemarker/core/RecoveryBlock.java | 8 +-
.../java/freemarker/core/ReturnInstruction.java | 12 +-
src/main/java/freemarker/core/Sep.java | 6 +-
src/main/java/freemarker/core/SwitchBlock.java | 12 +-
.../java/freemarker/core/TemplateElement.java | 312 ++++++++-----------
src/main/java/freemarker/core/TextBlock.java | 32 +-
...nterruptionSupportTemplatePostProcessor.java | 33 +-
.../java/freemarker/core/TransformBlock.java | 8 +-
.../java/freemarker/core/TrimInstruction.java | 2 +-
src/main/java/freemarker/core/UnifiedCall.java | 18 +-
src/test/java/freemarker/core/ASTPrinter.java | 43 +--
32 files changed, 348 insertions(+), 447 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/808ddadd/src/main/java/freemarker/core/AssignmentInstruction.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/AssignmentInstruction.java b/src/main/java/freemarker/core/AssignmentInstruction.java
index c3526fb..87a7d56 100644
--- a/src/main/java/freemarker/core/AssignmentInstruction.java
+++ b/src/main/java/freemarker/core/AssignmentInstruction.java
@@ -35,24 +35,24 @@ final class AssignmentInstruction extends TemplateElement {
AssignmentInstruction(int scope) {
this.scope = scope;
- setRegulatedChildBufferCapacity(1);
+ setChildBufferCapacity(1);
}
void addAssignment(Assignment assignment) {
- addRegulatedChild(assignment);
+ addChild(assignment);
}
void setNamespaceExp(Expression namespaceExp) {
this.namespaceExp = namespaceExp;
- int ln = getRegulatedChildCount();
+ int ln = getChildCount();
for (int i = 0; i < ln; i++) {
- ((Assignment) getRegulatedChild(i)).setNamespaceExp(namespaceExp);
+ ((Assignment) getChild(i)).setNamespaceExp(namespaceExp);
}
}
@Override
TemplateElement[] accept(Environment env) throws TemplateException, IOException {
- return getRegulatedChildren();
+ return getChildBuffer();
}
@Override
@@ -62,12 +62,12 @@ final class AssignmentInstruction extends TemplateElement {
buf.append(Assignment.getDirectiveName(scope));
if (canonical) {
buf.append(' ');
- int ln = getRegulatedChildCount();
+ int ln = getChildCount();
for (int i = 0; i < ln; i++) {
if (i != 0) {
buf.append(", ");
}
- Assignment assignment = (Assignment) getRegulatedChild(i);
+ Assignment assignment = (Assignment) getChild(i);
buf.append(assignment.getCanonicalForm());
}
} else {
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/808ddadd/src/main/java/freemarker/core/AttemptBlock.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/AttemptBlock.java b/src/main/java/freemarker/core/AttemptBlock.java
index 390fc92..586cf05 100644
--- a/src/main/java/freemarker/core/AttemptBlock.java
+++ b/src/main/java/freemarker/core/AttemptBlock.java
@@ -34,9 +34,9 @@ final class AttemptBlock extends TemplateElement {
AttemptBlock(TemplateElement attemptBlock, RecoveryBlock recoveryBlock) {
this.attemptBlock = attemptBlock;
this.recoveryBlock = recoveryBlock;
- setRegulatedChildBufferCapacity(2);
- addRegulatedChild(attemptBlock);
- addRegulatedChild(recoveryBlock);
+ setChildBufferCapacity(2);
+ addChild(attemptBlock);
+ addChild(recoveryBlock);
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/808ddadd/src/main/java/freemarker/core/AutoEscBlock.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/AutoEscBlock.java b/src/main/java/freemarker/core/AutoEscBlock.java
index 303aba0..5bcc555 100644
--- a/src/main/java/freemarker/core/AutoEscBlock.java
+++ b/src/main/java/freemarker/core/AutoEscBlock.java
@@ -29,19 +29,18 @@ import freemarker.template.TemplateException;
final class AutoEscBlock extends TemplateElement {
AutoEscBlock(TemplateElement nestedBlock) {
- setNestedBlock(nestedBlock);
+ setChildrenFromElement(nestedBlock);
}
@Override
TemplateElement[] accept(Environment env) throws TemplateException, IOException {
- return getRegulatedChildren();
+ return getChildBuffer();
}
@Override
protected String dump(boolean canonical) {
if (canonical) {
- String nested = getNestedBlock() != null ? getNestedBlock().getCanonicalForm() : "";
- return "<" + getNodeTypeSymbol() + "\">" + nested + "</" + getNodeTypeSymbol() + ">";
+ return "<" + getNodeTypeSymbol() + "\">" + getChildrenCanonicalForm() + "</" + getNodeTypeSymbol() + ">";
} else {
return getNodeTypeSymbol();
}
@@ -68,8 +67,8 @@ final class AutoEscBlock extends TemplateElement {
}
@Override
- boolean isIgnorable() {
- return getNestedBlock() == null || getNestedBlock().isIgnorable();
+ boolean isIgnorable(boolean stripWhitespace) {
+ return getChildCount() == 0;
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/808ddadd/src/main/java/freemarker/core/BlockAssignment.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/BlockAssignment.java b/src/main/java/freemarker/core/BlockAssignment.java
index 58f3404..a4f88d1 100644
--- a/src/main/java/freemarker/core/BlockAssignment.java
+++ b/src/main/java/freemarker/core/BlockAssignment.java
@@ -41,7 +41,7 @@ final class BlockAssignment extends TemplateElement {
private final MarkupOutputFormat<?> markupOutputFormat;
BlockAssignment(TemplateElement nestedBlock, String varName, int scope, Expression namespaceExp, MarkupOutputFormat<?> markupOutputFormat) {
- setNestedBlock(nestedBlock);
+ setChildrenFromElement(nestedBlock);
this.varName = varName;
this.namespaceExp = namespaceExp;
this.scope = scope;
@@ -50,8 +50,9 @@ final class BlockAssignment extends TemplateElement {
@Override
TemplateElement[] accept(Environment env) throws TemplateException, IOException {
- if (getNestedBlock() != null) {
- env.visitAndTransform(getNestedBlock(), new CaptureOutput(env), null);
+ TemplateElement[] children = getChildBuffer();
+ if (children != null) {
+ env.visitAndTransform(children, new CaptureOutput(env), null);
} else {
TemplateModel value = capturedStringToModel("");
if (namespaceExp != null) {
@@ -135,7 +136,7 @@ final class BlockAssignment extends TemplateElement {
}
if (canonical) {
sb.append('>');
- sb.append(getNestedBlock() == null ? "" : getNestedBlock().getCanonicalForm());
+ sb.append(getChildrenCanonicalForm());
sb.append("</");
sb.append(getNodeTypeSymbol());
sb.append('>');
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/808ddadd/src/main/java/freemarker/core/Case.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/Case.java b/src/main/java/freemarker/core/Case.java
index baba698..4b13cfb 100644
--- a/src/main/java/freemarker/core/Case.java
+++ b/src/main/java/freemarker/core/Case.java
@@ -31,12 +31,12 @@ final class Case extends TemplateElement {
Case(Expression matchingValue, TemplateElement nestedBlock) {
this.condition = matchingValue;
- setNestedBlock(nestedBlock);
+ setChildrenFromElement(nestedBlock);
}
@Override
TemplateElement[] accept(Environment env) {
- return getRegulatedChildren();
+ return getChildBuffer();
}
@Override
@@ -50,7 +50,7 @@ final class Case extends TemplateElement {
}
if (canonical) {
sb.append('>');
- if (getNestedBlock() != null) sb.append(getNestedBlock().getCanonicalForm());
+ sb.append(getChildrenCanonicalForm());
}
return sb.toString();
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/808ddadd/src/main/java/freemarker/core/CompressedBlock.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/CompressedBlock.java b/src/main/java/freemarker/core/CompressedBlock.java
index e405e0f..2ecde74 100644
--- a/src/main/java/freemarker/core/CompressedBlock.java
+++ b/src/main/java/freemarker/core/CompressedBlock.java
@@ -32,13 +32,14 @@ import freemarker.template.utility.StandardCompress;
final class CompressedBlock extends TemplateElement {
CompressedBlock(TemplateElement nestedBlock) {
- setNestedBlock(nestedBlock);
+ setChildrenFromElement(nestedBlock);
}
@Override
TemplateElement[] accept(Environment env) throws TemplateException, IOException {
- if (getNestedBlock() != null) {
- env.visitAndTransform(getNestedBlock(), StandardCompress.INSTANCE, null);
+ TemplateElement[] childBuffer = getChildBuffer();
+ if (childBuffer != null) {
+ env.visitAndTransform(childBuffer, StandardCompress.INSTANCE, null);
}
return null;
}
@@ -46,8 +47,7 @@ final class CompressedBlock extends TemplateElement {
@Override
protected String dump(boolean canonical) {
if (canonical) {
- String nested = getNestedBlock() != null ? getNestedBlock().getCanonicalForm() : "";
- return "<" + getNodeTypeSymbol() + ">" + nested + "</" + getNodeTypeSymbol() + ">";
+ return "<" + getNodeTypeSymbol() + ">" + getChildrenCanonicalForm() + "</" + getNodeTypeSymbol() + ">";
} else {
return getNodeTypeSymbol();
}
@@ -74,8 +74,8 @@ final class CompressedBlock extends TemplateElement {
}
@Override
- boolean isIgnorable() {
- return getNestedBlock() == null || getNestedBlock().isIgnorable();
+ boolean isIgnorable(boolean stripWhitespace) {
+ return getChildCount() == 0 && getParameterCount() == 0;
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/808ddadd/src/main/java/freemarker/core/ConditionalBlock.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/ConditionalBlock.java b/src/main/java/freemarker/core/ConditionalBlock.java
index 97563cb..00dafdc 100644
--- a/src/main/java/freemarker/core/ConditionalBlock.java
+++ b/src/main/java/freemarker/core/ConditionalBlock.java
@@ -39,14 +39,14 @@ final class ConditionalBlock extends TemplateElement {
ConditionalBlock(Expression condition, TemplateElement nestedBlock, int type) {
this.condition = condition;
- setNestedBlock(nestedBlock);
+ setChildrenFromElement(nestedBlock);
this.type = type;
}
@Override
TemplateElement[] accept(Environment env) throws TemplateException, IOException {
if (condition == null || condition.evalToBoolean(env)) {
- return getRegulatedChildren();
+ return getChildBuffer();
}
return null;
}
@@ -62,9 +62,7 @@ final class ConditionalBlock extends TemplateElement {
}
if (canonical) {
buf.append(">");
- if (getNestedBlock() != null) {
- buf.append(getNestedBlock().getCanonicalForm());
- }
+ buf.append(getChildrenCanonicalForm());
if (!(getParent() instanceof IfBlock)) {
buf.append("</#if>");
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/808ddadd/src/main/java/freemarker/core/DebugBreak.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/DebugBreak.java b/src/main/java/freemarker/core/DebugBreak.java
index cea2b77..2fa1cf3 100644
--- a/src/main/java/freemarker/core/DebugBreak.java
+++ b/src/main/java/freemarker/core/DebugBreak.java
@@ -33,15 +33,15 @@ import freemarker.template.TemplateException;
@Deprecated
public class DebugBreak extends TemplateElement {
public DebugBreak(TemplateElement nestedBlock) {
- setNestedBlock(nestedBlock);
+ addChild(nestedBlock);
copyLocationFrom(nestedBlock);
}
@Override
protected TemplateElement[] accept(Environment env) throws TemplateException, IOException {
if (!DebuggerService.suspendEnvironment(
- env, this.getTemplate().getSourceName(), getNestedBlock().getBeginLine())) {
- return getNestedBlock().accept(env);
+ env, this.getTemplate().getSourceName(), getChild(0).getBeginLine())) {
+ return getChild(0).accept(env);
} else {
throw new StopException(env, "Stopped by debugger");
}
@@ -53,11 +53,11 @@ public class DebugBreak extends TemplateElement {
StringBuilder sb = new StringBuilder();
sb.append("<#-- ");
sb.append("debug break");
- if (getNestedBlock() == null) {
+ if (getChildCount() == 0) {
sb.append(" /-->");
} else {
sb.append(" -->");
- sb.append(getNestedBlock().getCanonicalForm());
+ sb.append(getChild(0).getCanonicalForm());
sb.append("<#--/ debug break -->");
}
return sb.toString();
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/808ddadd/src/main/java/freemarker/core/ElseOfList.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/ElseOfList.java b/src/main/java/freemarker/core/ElseOfList.java
index 8aa6462..8e0bbeb 100644
--- a/src/main/java/freemarker/core/ElseOfList.java
+++ b/src/main/java/freemarker/core/ElseOfList.java
@@ -29,12 +29,12 @@ import freemarker.template.TemplateException;
final class ElseOfList extends TemplateElement {
ElseOfList(TemplateElement block) {
- setNestedBlock(block);
+ setChildrenFromElement(block);
}
@Override
TemplateElement[] accept(Environment env) throws TemplateException, IOException {
- return getRegulatedChildren();
+ return getChildBuffer();
}
@Override
@@ -42,9 +42,7 @@ final class ElseOfList extends TemplateElement {
if (canonical) {
StringBuilder buf = new StringBuilder();
buf.append('<').append(getNodeTypeSymbol()).append('>');
- if (getNestedBlock() != null) {
- buf.append(getNestedBlock().getCanonicalForm());
- }
+ buf.append(getChildrenCanonicalForm());
return buf.toString();
} else {
return getNodeTypeSymbol();
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/808ddadd/src/main/java/freemarker/core/Environment.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/Environment.java b/src/main/java/freemarker/core/Environment.java
index dcc178a..bf89fbb 100644
--- a/src/main/java/freemarker/core/Environment.java
+++ b/src/main/java/freemarker/core/Environment.java
@@ -337,6 +337,24 @@ public final class Environment extends Configurable {
popElement();
}
}
+
+ /**
+ * @param elementBuffer
+ * The elements to visit; might contains trailing {@code null}-s. Can be {@code null}.
+ *
+ * @since 2.3.24
+ */
+ void visit(TemplateElement[] elementBuffer) throws IOException, TemplateException {
+ if (elementBuffer == null) {
+ return;
+ }
+ for (TemplateElement el : elementBuffer) {
+ if (el == null) {
+ break; // Skip unused trailing buffer capacity
+ }
+ visit(el);
+ }
+ }
@SuppressFBWarnings(value = "RANGE_ARRAY_INDEX", justification = "Not called when stack is empty")
private TemplateElement replaceTopElement(TemplateElement element) {
@@ -345,14 +363,24 @@ public final class Environment extends Configurable {
private static final TemplateModel[] NO_OUT_ARGS = new TemplateModel[0];
+ /**
+ * @deprecated Should be internal API
+ */
+ @Deprecated
public void visit(final TemplateElement element,
TemplateDirectiveModel directiveModel, Map args,
final List bodyParameterNames) throws TemplateException, IOException {
+ visit(new TemplateElement[] { element }, directiveModel, args, bodyParameterNames);
+ }
+
+ void visit(final TemplateElement[] childBuffer,
+ TemplateDirectiveModel directiveModel, Map args,
+ final List bodyParameterNames) throws TemplateException, IOException {
TemplateDirectiveBody nested;
- if (element == null) {
+ if (childBuffer == null) {
nested = null;
} else {
- nested = new NestedElementTemplateDirectiveBody(element);
+ nested = new NestedElementTemplateDirectiveBody(childBuffer);
}
final TemplateModel[] outArgs;
if (bodyParameterNames == null || bodyParameterNames.isEmpty()) {
@@ -385,14 +413,14 @@ public final class Environment extends Configurable {
/**
* "Visit" the template element, passing the output through a TemplateTransformModel
*
- * @param element
- * the element to visit through a transform
+ * @param elementBuffer
+ * the element to visit through a transform; might contains trailing {@code null}-s
* @param transform
* the transform to pass the element output through
* @param args
* optional arguments fed to the transform
*/
- void visitAndTransform(TemplateElement element,
+ void visitAndTransform(TemplateElement[] elementBuffer,
TemplateTransformModel transform,
Map args)
throws TemplateException, IOException {
@@ -408,9 +436,7 @@ public final class Environment extends Configurable {
try {
if (tc == null || tc.onStart() != TransformControl.SKIP_BODY) {
do {
- if (element != null) {
- visit(element);
- }
+ visit(elementBuffer);
} while (tc != null && tc.afterBody() == TransformControl.REPEAT_EVALUATION);
}
} catch (Throwable t) {
@@ -501,8 +527,8 @@ public final class Environment extends Configurable {
void invokeNestedContent(BodyInstruction.Context bodyCtx) throws TemplateException, IOException {
Macro.Context invokingMacroContext = getCurrentMacroContext();
LocalContextStack prevLocalContextStack = localContextStack;
- TemplateElement nestedContent = invokingMacroContext.nestedContent;
- if (nestedContent != null) {
+ TemplateElement[] nestedContentBuffer = invokingMacroContext.nestedContentBuffer;
+ if (nestedContentBuffer != null) {
this.currentMacroContext = invokingMacroContext.prevMacroContext;
currentNamespace = invokingMacroContext.nestedContentNamespace;
@@ -520,7 +546,7 @@ public final class Environment extends Configurable {
pushLocalContext(bodyCtx);
}
try {
- visit(nestedContent);
+ visit(nestedContentBuffer);
} finally {
if (invokingMacroContext.nestedContentParameterNames != null) {
localContextStack.pop();
@@ -642,14 +668,14 @@ public final class Environment extends Configurable {
*/
void invoke(Macro macro,
Map namedArgs, List positionalArgs,
- List bodyParameterNames, TemplateElement nestedBlock) throws TemplateException, IOException {
+ List bodyParameterNames, TemplateElement[] childBuffer) throws TemplateException, IOException {
if (macro == Macro.DO_NOTHING_MACRO) {
return;
}
pushElement(macro);
try {
- final Macro.Context macroCtx = macro.new Context(this, nestedBlock, bodyParameterNames);
+ final Macro.Context macroCtx = macro.new Context(this, childBuffer, bodyParameterNames);
setMacroContextLocalsFromArguments(macroCtx, macro, namedArgs, positionalArgs);
final Macro.Context prevMacroCtx = currentMacroContext;
@@ -2662,24 +2688,24 @@ public final class Environment extends Configurable {
final class NestedElementTemplateDirectiveBody implements TemplateDirectiveBody {
- private final TemplateElement element;
+ private final TemplateElement[] childBuffer;
- private NestedElementTemplateDirectiveBody(TemplateElement element) {
- this.element = element;
+ private NestedElementTemplateDirectiveBody(TemplateElement[] childBuffer) {
+ this.childBuffer = childBuffer;
}
public void render(Writer newOut) throws TemplateException, IOException {
Writer prevOut = out;
out = newOut;
try {
- visit(element);
+ visit(childBuffer);
} finally {
out = prevOut;
}
}
-
- public TemplateElement getElement() {
- return element;
+
+ TemplateElement[] getChildrenBuffer() {
+ return childBuffer;
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/808ddadd/src/main/java/freemarker/core/EscapeBlock.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/EscapeBlock.java b/src/main/java/freemarker/core/EscapeBlock.java
index a9be235..b5d40ab 100644
--- a/src/main/java/freemarker/core/EscapeBlock.java
+++ b/src/main/java/freemarker/core/EscapeBlock.java
@@ -41,14 +41,14 @@ class EscapeBlock extends TemplateElement {
}
void setContent(TemplateElement nestedBlock) {
- setNestedBlock(nestedBlock);
+ setChildrenFromElement(nestedBlock);
// We don't need it anymore at this point
this.escapedExpr = null;
}
@Override
TemplateElement[] accept(Environment env) throws TemplateException, IOException {
- return getRegulatedChildren();
+ return getChildBuffer();
}
Expression doEscape(Expression expression) {
@@ -64,9 +64,7 @@ class EscapeBlock extends TemplateElement {
.append(" as ").append(expr.getCanonicalForm());
if (canonical) {
sb.append('>');
- if (getNestedBlock() != null) {
- sb.append(getNestedBlock().getCanonicalForm());
- }
+ sb.append(getChildrenCanonicalForm());
sb.append("</").append(getNodeTypeSymbol()).append('>');
}
return sb.toString();
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/808ddadd/src/main/java/freemarker/core/IfBlock.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/IfBlock.java b/src/main/java/freemarker/core/IfBlock.java
index 61e046e..42526f3 100644
--- a/src/main/java/freemarker/core/IfBlock.java
+++ b/src/main/java/freemarker/core/IfBlock.java
@@ -31,25 +31,23 @@ import freemarker.template.TemplateException;
final class IfBlock extends TemplateElement {
IfBlock(ConditionalBlock block) {
- setRegulatedChildBufferCapacity(1);
+ setChildBufferCapacity(1);
addBlock(block);
}
void addBlock(ConditionalBlock block) {
- addRegulatedChild(block);
+ addChild(block);
}
@Override
TemplateElement[] accept(Environment env) throws TemplateException, IOException {
- int ln = getRegulatedChildCount();
+ int ln = getChildCount();
for (int i = 0; i < ln; i++) {
- ConditionalBlock cblock = (ConditionalBlock) getRegulatedChild(i);
+ ConditionalBlock cblock = (ConditionalBlock) getChild(i);
Expression condition = cblock.condition;
env.replaceElementStackTop(cblock);
if (condition == null || condition.evalToBoolean(env)) {
- if (cblock.getNestedBlock() != null) {
- return cblock.getRegulatedChildren();
- }
+ return cblock.getChildBuffer();
}
}
return null;
@@ -58,8 +56,8 @@ final class IfBlock extends TemplateElement {
@Override
TemplateElement postParseCleanup(boolean stripWhitespace)
throws ParseException {
- if (getRegulatedChildCount() == 1) {
- ConditionalBlock cblock = (ConditionalBlock) getRegulatedChild(0);
+ if (getChildCount() == 1) {
+ ConditionalBlock cblock = (ConditionalBlock) getChild(0);
cblock.setLocation(getTemplate(), cblock, this);
return cblock.postParseCleanup(stripWhitespace);
} else {
@@ -71,9 +69,9 @@ final class IfBlock extends TemplateElement {
protected String dump(boolean canonical) {
if (canonical) {
StringBuilder buf = new StringBuilder();
- int ln = getRegulatedChildCount();
+ int ln = getChildCount();
for (int i = 0; i < ln; i++) {
- ConditionalBlock cblock = (ConditionalBlock) getRegulatedChild(i);
+ ConditionalBlock cblock = (ConditionalBlock) getChild(i);
buf.append(cblock.dump(canonical));
}
buf.append("</#if>");
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/808ddadd/src/main/java/freemarker/core/Items.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/Items.java b/src/main/java/freemarker/core/Items.java
index d48c013..ccc0223 100644
--- a/src/main/java/freemarker/core/Items.java
+++ b/src/main/java/freemarker/core/Items.java
@@ -32,7 +32,7 @@ class Items extends TemplateElement {
public Items(String loopVariableName, TemplateElement nestedBlock) {
this.loopVarName = loopVariableName;
- setNestedBlock(nestedBlock);
+ setChildrenFromElement(nestedBlock);
}
@Override
@@ -44,7 +44,7 @@ class Items extends TemplateElement {
getNodeTypeSymbol(), " without iteraton in context");
}
- iterCtx.loopForItemsElement(env, getNestedBlock(), loopVarName);
+ iterCtx.loopForItemsElement(env, getChildBuffer(), loopVarName);
return null;
}
@@ -62,7 +62,7 @@ class Items extends TemplateElement {
sb.append(loopVarName);
if (canonical) {
sb.append('>');
- if (getNestedBlock() != null) sb.append(getNestedBlock().getCanonicalForm());
+ sb.append(getChildrenCanonicalForm());
sb.append("</");
sb.append(getNodeTypeSymbol());
sb.append('>');
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/808ddadd/src/main/java/freemarker/core/IteratorBlock.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/IteratorBlock.java b/src/main/java/freemarker/core/IteratorBlock.java
index 62c6e34..8f629dd 100644
--- a/src/main/java/freemarker/core/IteratorBlock.java
+++ b/src/main/java/freemarker/core/IteratorBlock.java
@@ -58,7 +58,7 @@ final class IteratorBlock extends TemplateElement {
boolean isForEach) {
this.listExp = listExp;
this.loopVarName = loopVarName;
- setNestedBlock(nestedBlock);
+ setChildrenFromElement(nestedBlock);
this.isForEach = isForEach;
}
@@ -122,9 +122,7 @@ final class IteratorBlock extends TemplateElement {
}
if (canonical) {
buf.append(">");
- if (getNestedBlock() != null) {
- buf.append(getNestedBlock().getCanonicalForm());
- }
+ buf.append(getChildrenCanonicalForm());
if (!(getParentElement() instanceof ListElseContainer)) {
buf.append("</");
buf.append(getNodeTypeSymbol());
@@ -199,10 +197,10 @@ final class IteratorBlock extends TemplateElement {
}
boolean accept(Environment env) throws TemplateException, IOException {
- return executeNestedBlock(env, getNestedBlock());
+ return executeNestedContent(env, getChildBuffer());
}
- void loopForItemsElement(Environment env, TemplateElement nestedBlock, String loopVarName)
+ void loopForItemsElement(Environment env, TemplateElement[] childBuffer, String loopVarName)
throws NonSequenceOrCollectionException, TemplateModelException, InvalidReferenceException,
TemplateException, IOException {
try {
@@ -212,7 +210,7 @@ final class IteratorBlock extends TemplateElement {
}
alreadyEntered = true;
this.loopVarName = loopVarName;
- executeNestedBlock(env, nestedBlock);
+ executeNestedContent(env, childBuffer);
} finally {
this.loopVarName = null;
}
@@ -222,13 +220,7 @@ final class IteratorBlock extends TemplateElement {
* Executes the given block for the {@link #listValue}: if {@link #loopVarName} is non-{@code null}, then for
* each list item once, otherwise once if {@link #listValue} isn't empty.
*/
- private boolean executeNestedBlock(Environment env, TemplateElement nestedBlock)
- throws TemplateModelException, TemplateException, IOException,
- NonSequenceOrCollectionException, InvalidReferenceException {
- return executeNestedBlockInner(env, nestedBlock);
- }
-
- private boolean executeNestedBlockInner(Environment env, TemplateElement nestedBlock)
+ private boolean executeNestedContent(Environment env, TemplateElement[] childBuffer)
throws TemplateModelException, TemplateException, IOException, NonSequenceOrCollectionException,
InvalidReferenceException {
final boolean listNotEmpty;
@@ -244,9 +236,7 @@ final class IteratorBlock extends TemplateElement {
while (hasNext) {
loopVar = iterModel.next();
hasNext = iterModel.hasNext();
- if (nestedBlock != null) {
- env.visit(nestedBlock);
- }
+ env.visit(childBuffer);
index++;
}
} catch (BreakInstruction.Break br) {
@@ -257,9 +247,7 @@ final class IteratorBlock extends TemplateElement {
// We must reuse this later, because TemplateCollectionModel-s that wrap an Iterator only
// allow one iterator() call.
openedIteratorModel = iterModel;
- if (nestedBlock != null) {
- env.visit(nestedBlock);
- }
+ env.visit(childBuffer);
}
}
} else if (listValue instanceof TemplateSequenceModel) {
@@ -272,17 +260,13 @@ final class IteratorBlock extends TemplateElement {
for (index = 0; index < size; index++) {
loopVar = seqModel.get(index);
hasNext = (size > index + 1);
- if (nestedBlock != null) {
- env.visit(nestedBlock);
- }
+ env.visit(childBuffer);
}
} catch (BreakInstruction.Break br) {
// Silently exit loop
}
} else {
- if (nestedBlock != null) {
- env.visit(nestedBlock);
- }
+ env.visit(childBuffer);
}
}
} else if (env.isClassicCompatible()) {
@@ -292,9 +276,7 @@ final class IteratorBlock extends TemplateElement {
hasNext = false;
}
try {
- if (nestedBlock != null) {
- env.visit(nestedBlock);
- }
+ env.visit(childBuffer);
} catch (BreakInstruction.Break br) {
// Silently exit "loop"
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/808ddadd/src/main/java/freemarker/core/ListElseContainer.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/ListElseContainer.java b/src/main/java/freemarker/core/ListElseContainer.java
index d296719..1065e9e 100644
--- a/src/main/java/freemarker/core/ListElseContainer.java
+++ b/src/main/java/freemarker/core/ListElseContainer.java
@@ -28,9 +28,9 @@ class ListElseContainer extends TemplateElement {
private final ElseOfList elsePart;
public ListElseContainer(IteratorBlock listPart, ElseOfList elsePart) {
- setRegulatedChildBufferCapacity(2);
- addRegulatedChild(listPart);
- addRegulatedChild(elsePart);
+ setChildBufferCapacity(2);
+ addChild(listPart);
+ addChild(elsePart);
this.listPart = listPart;
this.elsePart = elsePart;
}
@@ -52,9 +52,9 @@ class ListElseContainer extends TemplateElement {
protected String dump(boolean canonical) {
if (canonical) {
StringBuilder buf = new StringBuilder();
- int ln = getRegulatedChildCount();
+ int ln = getChildCount();
for (int i = 0; i < ln; i++) {
- TemplateElement element = getRegulatedChild(i);
+ TemplateElement element = getChild(i);
buf.append(element.dump(canonical));
}
buf.append("</#list>");
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/808ddadd/src/main/java/freemarker/core/Macro.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/Macro.java b/src/main/java/freemarker/core/Macro.java
index d639d4f..0cb0159 100644
--- a/src/main/java/freemarker/core/Macro.java
+++ b/src/main/java/freemarker/core/Macro.java
@@ -65,7 +65,7 @@ public final class Macro extends TemplateElement implements TemplateModel {
this.function = function;
this.catchAllParamName = catchAllParamName;
- this.setNestedBlock(nestedBlock);
+ this.setChildrenFromElement(nestedBlock);
}
public String getCatchAll() {
@@ -137,9 +137,7 @@ public final class Macro extends TemplateElement implements TemplateModel {
if (function) sb.append(')');
if (canonical) {
sb.append('>');
- if (getNestedBlock() != null) {
- sb.append(getNestedBlock().getCanonicalForm());
- }
+ sb.append(getChildrenCanonicalForm());
sb.append("</").append(getNodeTypeSymbol()).append('>');
}
return sb.toString();
@@ -156,17 +154,17 @@ public final class Macro extends TemplateElement implements TemplateModel {
class Context implements LocalContext {
final Environment.Namespace localVars;
- final TemplateElement nestedContent;
+ final TemplateElement[] nestedContentBuffer;
final Environment.Namespace nestedContentNamespace;
final List nestedContentParameterNames;
final LocalContextStack prevLocalContextStack;
final Context prevMacroContext;
Context(Environment env,
- TemplateElement nestedContent,
+ TemplateElement[] nestedContentBuffer,
List nestedContentParameterNames) {
this.localVars = env.new Namespace();
- this.nestedContent = nestedContent;
+ this.nestedContentBuffer = nestedContentBuffer;
this.nestedContentNamespace = env.getCurrentNamespace();
this.nestedContentParameterNames = nestedContentParameterNames;
this.prevLocalContextStack = env.getLocalContextStack();
@@ -180,10 +178,7 @@ public final class Macro extends TemplateElement implements TemplateModel {
void runMacro(Environment env) throws TemplateException, IOException {
sanityCheck(env);
- // Set default values for unspecified parameters
- if (getNestedBlock() != null) {
- env.visit(getNestedBlock());
- }
+ env.visit(getChildBuffer());
}
// Set default parameters, check if all the required parameters are defined.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/808ddadd/src/main/java/freemarker/core/MixedContent.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/MixedContent.java b/src/main/java/freemarker/core/MixedContent.java
index e0ddb89..5b515d8 100644
--- a/src/main/java/freemarker/core/MixedContent.java
+++ b/src/main/java/freemarker/core/MixedContent.java
@@ -31,18 +31,18 @@ final class MixedContent extends TemplateElement {
MixedContent() { }
void addElement(TemplateElement element) {
- addRegulatedChild(element);
+ addChild(element);
}
void addElement(int index, TemplateElement element) {
- addRegulatedChild(index, element);
+ addChild(index, element);
}
@Override
TemplateElement postParseCleanup(boolean stripWhitespace)
throws ParseException {
super.postParseCleanup(stripWhitespace);
- return getRegulatedChildCount() == 1 ? getRegulatedChild(0) : this;
+ return getChildCount() == 1 ? getChild(0) : this;
}
/**
@@ -52,18 +52,13 @@ final class MixedContent extends TemplateElement {
@Override
TemplateElement[] accept(Environment env)
throws TemplateException, IOException {
- return getRegulatedChildren();
+ return getChildBuffer();
}
@Override
protected String dump(boolean canonical) {
if (canonical) {
- StringBuilder buf = new StringBuilder();
- int ln = getRegulatedChildCount();
- for (int i = 0; i < ln; i++) {
- buf.append(getRegulatedChild(i).getCanonicalForm());
- }
- return buf.toString();
+ return getChildrenCanonicalForm();
} else {
if (getParentElement() == null) {
return "root";
@@ -74,9 +69,9 @@ final class MixedContent extends TemplateElement {
@Override
protected boolean isOutputCacheable() {
- int ln = getRegulatedChildCount();
+ int ln = getChildCount();
for (int i = 0; i < ln; i++) {
- if (!getRegulatedChild(i).isOutputCacheable()) {
+ if (!getChild(i).isOutputCacheable()) {
return false;
}
}
@@ -104,8 +99,8 @@ final class MixedContent extends TemplateElement {
}
@Override
- boolean isIgnorable() {
- return getRegulatedChildCount() == 0;
+ boolean isIgnorable(boolean stripWhitespace) {
+ return getChildCount() == 0;
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/808ddadd/src/main/java/freemarker/core/NestedContentNotSupportedException.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/NestedContentNotSupportedException.java b/src/main/java/freemarker/core/NestedContentNotSupportedException.java
index 926fab1..a667af1 100644
--- a/src/main/java/freemarker/core/NestedContentNotSupportedException.java
+++ b/src/main/java/freemarker/core/NestedContentNotSupportedException.java
@@ -37,8 +37,9 @@ class NestedContentNotSupportedException extends TemplateException {
return;
}
if (body instanceof NestedElementTemplateDirectiveBody) {
- TemplateElement te = ((NestedElementTemplateDirectiveBody) body).getElement();
- if (te == null || te instanceof ThreadInterruptionCheck) {
+ TemplateElement[] tes = ((NestedElementTemplateDirectiveBody) body).getChildrenBuffer();
+ if (tes == null || tes.length == 0
+ || tes[0] instanceof ThreadInterruptionCheck && (tes.length == 1 || tes[1] == null)) {
return;
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/808ddadd/src/main/java/freemarker/core/NoAutoEscBlock.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/NoAutoEscBlock.java b/src/main/java/freemarker/core/NoAutoEscBlock.java
index acc336a..14980b2 100644
--- a/src/main/java/freemarker/core/NoAutoEscBlock.java
+++ b/src/main/java/freemarker/core/NoAutoEscBlock.java
@@ -29,19 +29,18 @@ import freemarker.template.TemplateException;
final class NoAutoEscBlock extends TemplateElement {
NoAutoEscBlock(TemplateElement nestedBlock) {
- setNestedBlock(nestedBlock);
+ setChildrenFromElement(nestedBlock);
}
@Override
TemplateElement[] accept(Environment env) throws TemplateException, IOException {
- return getRegulatedChildren();
+ return getChildBuffer();
}
@Override
protected String dump(boolean canonical) {
if (canonical) {
- String nested = getNestedBlock() != null ? getNestedBlock().getCanonicalForm() : "";
- return "<" + getNodeTypeSymbol() + "\">" + nested + "</" + getNodeTypeSymbol() + ">";
+ return "<" + getNodeTypeSymbol() + "\">" + getChildrenCanonicalForm() + "</" + getNodeTypeSymbol() + ">";
} else {
return getNodeTypeSymbol();
}
@@ -68,8 +67,8 @@ final class NoAutoEscBlock extends TemplateElement {
}
@Override
- boolean isIgnorable() {
- return getNestedBlock() == null || getNestedBlock().isIgnorable();
+ boolean isIgnorable(boolean stripWhitespace) {
+ return getChildCount() == 0;
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/808ddadd/src/main/java/freemarker/core/NoEscapeBlock.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/NoEscapeBlock.java b/src/main/java/freemarker/core/NoEscapeBlock.java
index eb2081a..0722b91 100644
--- a/src/main/java/freemarker/core/NoEscapeBlock.java
+++ b/src/main/java/freemarker/core/NoEscapeBlock.java
@@ -28,18 +28,18 @@ import freemarker.template.TemplateException;
class NoEscapeBlock extends TemplateElement {
NoEscapeBlock(TemplateElement nestedBlock) {
- setNestedBlock(nestedBlock);
+ setChildrenFromElement(nestedBlock);
}
@Override
TemplateElement[] accept(Environment env) throws TemplateException, IOException {
- return getRegulatedChildren();
+ return getChildBuffer();
}
@Override
protected String dump(boolean canonical) {
if (canonical) {
- return "<" + getNodeTypeSymbol() + '>' + getNestedBlock().getCanonicalForm()
+ return "<" + getNodeTypeSymbol() + '>' + getChildrenCanonicalForm()
+ "</" + getNodeTypeSymbol() + '>';
} else {
return getNodeTypeSymbol();
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/808ddadd/src/main/java/freemarker/core/OutputFormatBlock.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/OutputFormatBlock.java b/src/main/java/freemarker/core/OutputFormatBlock.java
index c0660aa..cc3ef4b 100644
--- a/src/main/java/freemarker/core/OutputFormatBlock.java
+++ b/src/main/java/freemarker/core/OutputFormatBlock.java
@@ -32,20 +32,19 @@ final class OutputFormatBlock extends TemplateElement {
OutputFormatBlock(TemplateElement nestedBlock, Expression paramExp) {
this.paramExp = paramExp;
- setNestedBlock(nestedBlock);
+ setChildrenFromElement(nestedBlock);
}
@Override
TemplateElement[] accept(Environment env) throws TemplateException, IOException {
- return getRegulatedChildren();
+ return getChildBuffer();
}
@Override
protected String dump(boolean canonical) {
if (canonical) {
- String nested = getNestedBlock() != null ? getNestedBlock().getCanonicalForm() : "";
return "<" + getNodeTypeSymbol() + " \"" + paramExp.getCanonicalForm() + "\">"
- + nested + "</" + getNodeTypeSymbol() + ">";
+ + getChildrenCanonicalForm() + "</" + getNodeTypeSymbol() + ">";
} else {
return getNodeTypeSymbol();
}
@@ -76,8 +75,8 @@ final class OutputFormatBlock extends TemplateElement {
}
@Override
- boolean isIgnorable() {
- return getNestedBlock() == null || getNestedBlock().isIgnorable();
+ boolean isIgnorable(boolean stripWhitespace) {
+ return getChildCount() == 0;
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/808ddadd/src/main/java/freemarker/core/RecoveryBlock.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/RecoveryBlock.java b/src/main/java/freemarker/core/RecoveryBlock.java
index 8c483b6..31038e2 100644
--- a/src/main/java/freemarker/core/RecoveryBlock.java
+++ b/src/main/java/freemarker/core/RecoveryBlock.java
@@ -26,12 +26,12 @@ import freemarker.template.TemplateException;
final class RecoveryBlock extends TemplateElement {
RecoveryBlock(TemplateElement block) {
- setNestedBlock(block);
+ setChildrenFromElement(block);
}
@Override
TemplateElement[] accept(Environment env) throws TemplateException, IOException {
- return getRegulatedChildren();
+ return getChildBuffer();
}
@Override
@@ -39,9 +39,7 @@ final class RecoveryBlock extends TemplateElement {
if (canonical) {
StringBuilder buf = new StringBuilder();
buf.append('<').append(getNodeTypeSymbol()).append('>');
- if (getNestedBlock() != null) {
- buf.append(getNestedBlock().getCanonicalForm());
- }
+ buf.append(getChildrenCanonicalForm());
return buf.toString();
} else {
return getNodeTypeSymbol();
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/808ddadd/src/main/java/freemarker/core/ReturnInstruction.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/ReturnInstruction.java b/src/main/java/freemarker/core/ReturnInstruction.java
index 09852e8..51feab7 100644
--- a/src/main/java/freemarker/core/ReturnInstruction.java
+++ b/src/main/java/freemarker/core/ReturnInstruction.java
@@ -37,15 +37,11 @@ public final class ReturnInstruction extends TemplateElement {
if (exp != null) {
env.setLastReturnValue(exp.eval(env));
}
- if (nextSibling() != null) {
- // We need to jump out using an exception.
- throw Return.INSTANCE;
+ if (nextSibling() == null && getParentElement() instanceof Macro) {
+ // Avoid unnecessary exception throwing
+ return null;
}
- if (!(getParentElement() instanceof Macro || getParentElement().getParentElement() instanceof Macro)) {
- // Here also, we need to jump out using an exception.
- throw Return.INSTANCE;
- }
- return null;
+ throw Return.INSTANCE;
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/808ddadd/src/main/java/freemarker/core/Sep.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/Sep.java b/src/main/java/freemarker/core/Sep.java
index 7691bfa..d30b3e9 100644
--- a/src/main/java/freemarker/core/Sep.java
+++ b/src/main/java/freemarker/core/Sep.java
@@ -29,7 +29,7 @@ import freemarker.template.TemplateException;
class Sep extends TemplateElement {
public Sep(TemplateElement nestedBlock) {
- setNestedBlock(nestedBlock);
+ setChildrenFromElement(nestedBlock);
}
@Override
@@ -42,7 +42,7 @@ class Sep extends TemplateElement {
}
if (iterCtx.hasNext()) {
- return getRegulatedChildren();
+ return getChildBuffer();
}
return null;
}
@@ -59,7 +59,7 @@ class Sep extends TemplateElement {
sb.append(getNodeTypeSymbol());
if (canonical) {
sb.append('>');
- if (getNestedBlock() != null) sb.append(getNestedBlock().getCanonicalForm());
+ sb.append(getChildrenCanonicalForm());
sb.append("</");
sb.append(getNodeTypeSymbol());
sb.append('>');
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/808ddadd/src/main/java/freemarker/core/SwitchBlock.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/SwitchBlock.java b/src/main/java/freemarker/core/SwitchBlock.java
index 4f3f461..2cef5ce 100644
--- a/src/main/java/freemarker/core/SwitchBlock.java
+++ b/src/main/java/freemarker/core/SwitchBlock.java
@@ -36,7 +36,7 @@ final class SwitchBlock extends TemplateElement {
*/
SwitchBlock(Expression searched) {
this.searched = searched;
- setRegulatedChildBufferCapacity(4);
+ setChildBufferCapacity(4);
}
/**
@@ -46,17 +46,17 @@ final class SwitchBlock extends TemplateElement {
if (cas.condition == null) {
defaultCase = cas;
}
- addRegulatedChild(cas);
+ addChild(cas);
}
@Override
TemplateElement[] accept(Environment env)
throws TemplateException, IOException {
boolean processedCase = false;
- int ln = getRegulatedChildCount();
+ int ln = getChildCount();
try {
for (int i = 0; i < ln; i++) {
- Case cas = (Case) getRegulatedChild(i);
+ Case cas = (Case) getChild(i);
boolean processCase = false;
// Fall through if a previous case tested true.
@@ -92,9 +92,9 @@ final class SwitchBlock extends TemplateElement {
buf.append(searched.getCanonicalForm());
if (canonical) {
buf.append('>');
- int ln = getRegulatedChildCount();
+ int ln = getChildCount();
for (int i = 0; i < ln; i++) {
- Case cas = (Case) getRegulatedChild(i);
+ Case cas = (Case) getChild(i);
buf.append(cas.getCanonicalForm());
}
buf.append("</").append(getNodeTypeSymbol()).append('>');
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/808ddadd/src/main/java/freemarker/core/TemplateElement.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/TemplateElement.java b/src/main/java/freemarker/core/TemplateElement.java
index 7501588..61e3150 100644
--- a/src/main/java/freemarker/core/TemplateElement.java
+++ b/src/main/java/freemarker/core/TemplateElement.java
@@ -45,28 +45,19 @@ abstract public class TemplateElement extends TemplateObject {
private TemplateElement parent;
/**
- * Used by elements that has no fixed schema for its child elements. For example, a {@code #case} can enclose any
- * kind of elements. Only one of {@link #nestedBlock} and {@link #regulatedChildBuffer} can be non-{@code null}
- * before {@link #postParseCleanup(boolean)}. After {@link #postParseCleanup(boolean)}, the
- * {@link #regulatedChildBuffer} is always filled and used for execution. This element is typically a
- * {@link MixedContent}, at least before {@link #postParseCleanup(boolean)} (which optimizes out
- * {@link MixedContent} with child count less than 2).
+ * Contains 1 or more nested elements with optional trailing {@code null}-s, or is {@code null} exactly if there
+ * are no nested elements.
*/
- private TemplateElement nestedBlock;
+ private TemplateElement[] childBuffer;
/**
- * Before {@link #postParseCleanup(boolean)}, it's only used by elements that has a fixed schema for its child
- * elements. For example, {@code #switch} can only have {@code #case} and {@code #default} child elements. Before
- * {@link #postParseCleanup(boolean)}, only one of {@link #nestedBlock} and {@link #regulatedChildBuffer} can be
- * non-{@code null}. After {@link #postParseCleanup(boolean)}, the {@link #regulatedChildBuffer} is always filled
- * and used for execution.
+ * Contains the number of elements in the {@link #childBuffer}, not counting the trailing {@code null}-s.
+ * If this is 0, then and only then {@link #childBuffer} must be {@code null}.
*/
- private TemplateElement[] regulatedChildBuffer;
- private int regulatedChildCount;
+ private int childCount;
/**
- * The index of the element in the parent's {@link #regulatedChildBuffer} array, or 0 if this is the
- * {@link #nestedBlock} of the parent.
+ * The index of the element in the parent's {@link #childBuffer} array.
*
* @since 2.3.23
*/
@@ -111,6 +102,18 @@ abstract public class TemplateElement extends TemplateObject {
return dump(true);
}
+ final String getChildrenCanonicalForm() {
+ int ln = childCount;
+ if (ln == 0) {
+ return "";
+ }
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < ln; i++) {
+ sb.append(childBuffer[i].getCanonicalForm());
+ }
+ return sb.toString();
+ }
+
/**
* Tells if the element should show up in error stack traces. Note that this will be ignored for the top (current)
* element of a stack trace, as that's always shown.
@@ -120,10 +123,10 @@ abstract public class TemplateElement extends TemplateObject {
}
/**
- * Tells if this element possibly executes its {@link #nestedBlock} for many times. This flag is useful when
- * a template AST is modified for running time limiting (see {@link ThreadInterruptionSupportTemplatePostProcessor}).
- * Elements that use {@link #regulatedChildBuffer} should not need this, as the insertion of the timeout checks is
- * impossible there, given their rigid nested element schema.
+ * Tells if this element possibly executes its nested content for many times. This flag is useful when a template
+ * AST is modified for running time limiting (see {@link ThreadInterruptionSupportTemplatePostProcessor}). Elements
+ * that use {@link #childBuffer} should not need this, as the insertion of the timeout checks is impossible
+ * there, given their rigid nested element schema.
*/
abstract boolean isNestedBlockRepeater();
@@ -153,16 +156,12 @@ abstract public class TemplateElement extends TemplateObject {
public TemplateSequenceModel getChildNodes() {
SimpleSequence result = new SimpleSequence(1);
- if (nestedBlock != null) {
- result.add(nestedBlock);
- } else {
- if (regulatedChildBuffer != null) {
- final SimpleSequence seq = new SimpleSequence(regulatedChildCount);
- for (int i = 0; i < regulatedChildCount; i++) {
- seq.add(regulatedChildBuffer[i]);
- }
- return seq;
+ if (childBuffer != null) {
+ final SimpleSequence seq = new SimpleSequence(childCount);
+ for (int i = 0; i < childCount; i++) {
+ seq.add(childBuffer[i]);
}
+ return seq;
}
return result;
}
@@ -176,7 +175,7 @@ abstract public class TemplateElement extends TemplateObject {
// Methods so that we can implement the Swing TreeNode API.
public boolean isLeaf() {
- return nestedBlock == null && regulatedChildCount == 0;
+ return childCount == 0;
}
/**
@@ -188,31 +187,16 @@ abstract public class TemplateElement extends TemplateObject {
}
public int getIndex(TemplateElement node) {
- if (nestedBlock instanceof MixedContent) {
- return nestedBlock.getIndex(node);
- }
- if (nestedBlock != null) {
- if (node == nestedBlock) {
- return 0;
- }
- } else {
- for (int i = 0; i < regulatedChildCount; i++) {
- if (regulatedChildBuffer[i].equals(node)) {
- return i;
- }
+ for (int i = 0; i < childCount; i++) {
+ if (childBuffer[i].equals(node)) {
+ return i;
}
}
return -1;
}
public int getChildCount() {
- // Note: regulatedChildren is possibly filled for optimization despite that nestedBlock is filled too, but then
- // it should only be utilized for execution, as those children might skip a MixedContent parent.
- if (nestedBlock != null) {
- return nestedBlock instanceof MixedContent ? nestedBlock.getChildCount() : 1;
- } else {
- return regulatedChildCount;
- }
+ return childCount;
}
/**
@@ -220,61 +204,30 @@ abstract public class TemplateElement extends TemplateObject {
* {@link MixedContent}.
*/
public Enumeration children() {
- // Note: regulatedChildren is possibly filled for optimization despite that nestedBlock is filled too, but then
- // it should only be utilized for execution, as those children might skip a MixedContent parent.
- if (nestedBlock != null) {
- return nestedBlock instanceof MixedContent
- ? nestedBlock.children() : Collections.enumeration(Collections.singletonList(nestedBlock));
- } else if (regulatedChildBuffer != null) {
- return new _ArrayEnumeration(regulatedChildBuffer, regulatedChildCount);
- }
- return Collections.enumeration(Collections.EMPTY_LIST);
+ return childBuffer != null
+ ? new _ArrayEnumeration(childBuffer, childCount)
+ : Collections.enumeration(Collections.EMPTY_LIST);
}
public TemplateElement getChildAt(int index) {
- // Note: regulatedChildren is possibly filled for optimization despite that nestedBlock is filled too, but then
- // it should only be utilized for execution, as those children might skip a MixedContent parent.
- if (nestedBlock instanceof MixedContent) {
- return nestedBlock.getChildAt(index);
- } else if (nestedBlock != null) {
- if (index == 0) {
- return nestedBlock;
- }
- throw new ArrayIndexOutOfBoundsException("invalid index");
- } else if (regulatedChildCount != 0) {
- try {
- return regulatedChildBuffer[index];
- } catch (ArrayIndexOutOfBoundsException e) {
- // nestedElements was a List earlier, so we emulate the same kind of exception
- throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + regulatedChildCount);
- }
+ if (childCount == 0) {
+ throw new IndexOutOfBoundsException("Template element has no children");
+ }
+ try {
+ return childBuffer[index];
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // nestedElements was a List earlier, so we emulate the same kind of exception
+ throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + childCount);
}
- throw new ArrayIndexOutOfBoundsException("Template element has no children");
}
public void setChildAt(int index, TemplateElement element) {
- if (nestedBlock instanceof MixedContent) {
- nestedBlock.setChildAt(index, element);
- if (regulatedChildBuffer != null) {
- regulatedChildBuffer[index] = element;
- }
- } else if (nestedBlock != null) {
- if (index == 0) {
- nestedBlock = element;
- element.index = 0;
- element.parent = this;
- if (regulatedChildBuffer != null) {
- regulatedChildBuffer[0] = element;
- }
- } else {
- throw new IndexOutOfBoundsException("invalid index");
- }
- } else if (regulatedChildBuffer != null) {
- regulatedChildBuffer[index] = element;
+ if (index < childCount && index >= 0) {
+ childBuffer[index] = element;
element.index = index;
element.parent = this;
} else {
- throw new IndexOutOfBoundsException("element has no children");
+ throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + childCount);
}
}
@@ -288,29 +241,35 @@ abstract public class TemplateElement extends TemplateObject {
return parent;
}
- final void setRegulatedChildBufferCapacity(int capacity) {
- int ln = regulatedChildCount;
+ final void setChildBufferCapacity(int capacity) {
+ int ln = childCount;
TemplateElement[] newRegulatedChildBuffer = new TemplateElement[capacity];
for (int i = 0; i < ln; i++) {
- newRegulatedChildBuffer[i] = regulatedChildBuffer[i];
+ newRegulatedChildBuffer[i] = childBuffer[i];
}
- regulatedChildBuffer = newRegulatedChildBuffer;
+ childBuffer = newRegulatedChildBuffer;
}
- final void addRegulatedChild(TemplateElement nestedElement) {
- addRegulatedChild(regulatedChildCount, nestedElement);
+ /**
+ * Inserts a new nested element after the last nested element.
+ */
+ final void addChild(TemplateElement nestedElement) {
+ addChild(childCount, nestedElement);
}
- final void addRegulatedChild(int index, TemplateElement nestedElement) {
- final int lRegulatedChildCount = regulatedChildCount;
+ /**
+ * Inserts a new nested element at the given index, which can also be one higher than the current highest index.
+ */
+ final void addChild(int index, TemplateElement nestedElement) {
+ final int lRegulatedChildCount = childCount;
- TemplateElement[] lRegulatedChildBuffer = regulatedChildBuffer;
+ TemplateElement[] lRegulatedChildBuffer = childBuffer;
if (lRegulatedChildBuffer == null) {
lRegulatedChildBuffer = new TemplateElement[INITIAL_REGULATED_CHILD_BUFFER_CAPACITY];
- regulatedChildBuffer = lRegulatedChildBuffer;
+ childBuffer = lRegulatedChildBuffer;
} else if (lRegulatedChildCount == lRegulatedChildBuffer.length) {
- setRegulatedChildBufferCapacity(lRegulatedChildCount != 0 ? lRegulatedChildCount * 2 : 1);
- lRegulatedChildBuffer = regulatedChildBuffer;
+ setChildBufferCapacity(lRegulatedChildCount != 0 ? lRegulatedChildCount * 2 : 1);
+ lRegulatedChildBuffer = childBuffer;
}
// At this point: nestedElements == this.nestedElements, and has sufficient capacity.
@@ -322,19 +281,37 @@ abstract public class TemplateElement extends TemplateObject {
nestedElement.index = index;
nestedElement.parent = this;
lRegulatedChildBuffer[index] = nestedElement;
- regulatedChildCount = lRegulatedChildCount + 1;
+ childCount = lRegulatedChildCount + 1;
}
- final int getRegulatedChildCount() {
- return regulatedChildCount;
+ final TemplateElement getChild(int index) {
+ return childBuffer[index];
}
- final TemplateElement getRegulatedChild(int index) {
- return regulatedChildBuffer[index];
+ /**
+ * @return Array containing 1 or more nested elements with optional trailing {@code null}-s, or is {@code null}
+ * exactly if there are no nested elements.
+ */
+ final TemplateElement[] getChildBuffer(){
+ return childBuffer;
}
-
- final TemplateElement[] getRegulatedChildren(){
- return regulatedChildBuffer;
+
+ // TODO Workaround until the parser doesn't emit TemplateElement[]-s for "blocks"
+ final void setChildrenFromElement(TemplateElement nestedBlock) {
+ if (nestedBlock == null) {
+ childBuffer = null;
+ childCount = 0;
+ } else if (nestedBlock instanceof MixedContent) {
+ MixedContent mixedContent = (MixedContent) nestedBlock;
+ childBuffer = mixedContent.getChildBuffer();
+ childCount = mixedContent.getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ childBuffer[i].parent = this;
+ }
+ } else {
+ childBuffer = new TemplateElement[] { nestedBlock };
+ childCount = 1;
+ }
}
final int getIndex() {
@@ -348,18 +325,6 @@ abstract public class TemplateElement extends TemplateObject {
return parent;
}
- final TemplateElement getNestedBlock() {
- return nestedBlock;
- }
-
- final void setNestedBlock(TemplateElement nestedBlock) {
- if (nestedBlock != null) {
- nestedBlock.parent = this;
- nestedBlock.index = 0;
- }
- this.nestedBlock = nestedBlock;
- }
-
/**
* This is a special case, because a root element is not contained in another element, so we couldn't set the
* private fields.
@@ -381,62 +346,45 @@ abstract public class TemplateElement extends TemplateObject {
* is the duty of the caller, not of this method.
*/
TemplateElement postParseCleanup(boolean stripWhitespace) throws ParseException {
- int regulatedChildCount = this.regulatedChildCount;
- if (nestedBlock != null) {
- nestedBlock = nestedBlock.postParseCleanup(stripWhitespace);
- if (nestedBlock.isIgnorable()) {
- nestedBlock = null;
- } else {
- nestedBlock.parent = this;
- if (nestedBlock instanceof MixedContent) {
- // As MixedContent.accept does nothing but return its regulatedChildren, while it will be present as
- // a child, the parent element also will have regularedChildren that contains the children of the
- // MixedContent directly.
- this.regulatedChildBuffer = nestedBlock.getRegulatedChildren();
- this.regulatedChildCount = nestedBlock.getRegulatedChildCount();
- } else {
- // Because execution will use regularChildren only.
- this.regulatedChildBuffer = new TemplateElement[] { nestedBlock };
- this.regulatedChildCount = 1;
- }
- }
- } else if (regulatedChildCount != 0) {
+ int regulatedChildCount = this.childCount;
+ if (regulatedChildCount != 0) {
for (int i = 0; i < regulatedChildCount; i++) {
- TemplateElement te = regulatedChildBuffer[i];
+ TemplateElement te = childBuffer[i];
te = te.postParseCleanup(stripWhitespace);
- regulatedChildBuffer[i] = te;
+ childBuffer[i] = te;
te.parent = this;
te.index = i;
}
- if (stripWhitespace) {
- for (int i = 0; i < regulatedChildCount; i++) {
- TemplateElement te = regulatedChildBuffer[i];
- if (te.isIgnorable()) {
- regulatedChildCount--;
- for (int j = i; j < regulatedChildCount; j++) {
- final TemplateElement te2 = regulatedChildBuffer[j + 1];
- regulatedChildBuffer[j] = te2;
- te2.index = j;
- }
- regulatedChildBuffer[regulatedChildCount] = null;
- this.regulatedChildCount = regulatedChildCount;
- i--;
+ for (int i = 0; i < regulatedChildCount; i++) {
+ TemplateElement te = childBuffer[i];
+ if (te.isIgnorable(stripWhitespace)) {
+ // TODO Optimize this...
+ regulatedChildCount--;
+ for (int j = i; j < regulatedChildCount; j++) {
+ final TemplateElement te2 = childBuffer[j + 1];
+ childBuffer[j] = te2;
+ te2.index = j;
}
+ childBuffer[regulatedChildCount] = null;
+ this.childCount = regulatedChildCount;
+ i--;
}
}
- if (regulatedChildCount < regulatedChildBuffer.length
- && regulatedChildCount <= regulatedChildBuffer.length * 3 / 4) {
+ if (regulatedChildCount == 0) {
+ childBuffer = null;
+ } else if (regulatedChildCount < childBuffer.length
+ && regulatedChildCount <= childBuffer.length * 3 / 4) {
TemplateElement[] trimmedregulatedChildBuffer = new TemplateElement[regulatedChildCount];
for (int i = 0; i < regulatedChildCount; i++) {
- trimmedregulatedChildBuffer[i] = regulatedChildBuffer[i];
+ trimmedregulatedChildBuffer[i] = childBuffer[i];
}
- regulatedChildBuffer = trimmedregulatedChildBuffer;
+ childBuffer = trimmedregulatedChildBuffer;
}
}
return this;
}
- boolean isIgnorable() {
+ boolean isIgnorable(boolean stripWhitespace) {
return false;
}
@@ -467,35 +415,23 @@ abstract public class TemplateElement extends TemplateObject {
if (parent == null) {
return null;
}
- return index > 0 ? parent.regulatedChildBuffer[index - 1] : null;
+ return index > 0 ? parent.childBuffer[index - 1] : null;
}
TemplateElement nextSibling() {
if (parent == null) {
return null;
}
- return index + 1 < parent.regulatedChildCount ? parent.regulatedChildBuffer[index + 1] : null;
+ return index + 1 < parent.childCount ? parent.childBuffer[index + 1] : null;
}
private TemplateElement getFirstChild() {
- if (nestedBlock != null) {
- return nestedBlock;
- }
- if (regulatedChildCount == 0) {
- return null;
- }
- return regulatedChildBuffer[0];
+ return childCount == 0 ? null : childBuffer[0];
}
private TemplateElement getLastChild() {
- if (nestedBlock != null) {
- return nestedBlock;
- }
- final int regulatedChildCount = this.regulatedChildCount;
- if (regulatedChildCount == 0) {
- return null;
- }
- return regulatedChildBuffer[regulatedChildCount - 1];
+ final int regulatedChildCount = this.childCount;
+ return regulatedChildCount == 0 ? null : childBuffer[regulatedChildCount - 1];
}
private TemplateElement getFirstLeaf() {
@@ -524,6 +460,16 @@ abstract public class TemplateElement extends TemplateObject {
return false;
}
+ boolean isChildrenOutputCacheable() {
+ int ln = childCount;
+ for (int i = 0; i < ln; i++) {
+ if (!childBuffer[i].isOutputCacheable()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
/**
* determines whether this element's presence on a line
* indicates that we should not strip opening whitespace
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/808ddadd/src/main/java/freemarker/core/TextBlock.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/TextBlock.java b/src/main/java/freemarker/core/TextBlock.java
index 2ddf143..d245d24 100644
--- a/src/main/java/freemarker/core/TextBlock.java
+++ b/src/main/java/freemarker/core/TextBlock.java
@@ -108,7 +108,13 @@ public final class TextBlock extends TemplateElement {
if (!stripWhitespace || text.length == 0 ) {
return this;
}
- if (getParentElement().getParentElement() == null && previousSibling() == null) return this;
+ TemplateElement parentElement = getParentElement();
+ if (
+ (parentElement == null
+ || parentElement.getParentElement() == null && parentElement instanceof MixedContent)
+ && previousSibling() == null) {
+ return this;
+ }
if (!deliberateLeftTrim) {
trailingCharsToStrip = trailingCharsToStrip();
}
@@ -306,7 +312,7 @@ public final class TextBlock extends TemplateElement {
@Override
boolean heedsTrailingWhitespace() {
- if (isIgnorable()) {
+ if (isIgnorable(true)) {
return false;
}
for (int i = 0; i < text.length; i++) {
@@ -323,7 +329,7 @@ public final class TextBlock extends TemplateElement {
@Override
boolean heedsOpeningWhitespace() {
- if (isIgnorable()) {
+ if (isIgnorable(true)) {
return false;
}
for (int i = text.length - 1; i >= 0; i--) {
@@ -339,18 +345,24 @@ public final class TextBlock extends TemplateElement {
}
@Override
- boolean isIgnorable() {
+ boolean isIgnorable(boolean stripWhitespace) {
if (text == null || text.length == 0) {
return true;
}
- if (!StringUtil.isTrimmableToEmpty(text)) {
+ if (stripWhitespace) {
+ if (!StringUtil.isTrimmableToEmpty(text)) {
+ return false;
+ }
+ TemplateElement parentElement = getParentElement();
+ boolean atTopLevel = (parentElement == null
+ || parentElement.getParentElement() == null && parentElement instanceof MixedContent);
+ TemplateElement prevSibling = previousSibling();
+ TemplateElement nextSibling = nextSibling();
+ return ((prevSibling == null && atTopLevel) || nonOutputtingType(prevSibling))
+ && ((nextSibling == null && atTopLevel) || nonOutputtingType(nextSibling));
+ } else {
return false;
}
- boolean atTopLevel = (getParentElement().getParentElement() == null);
- TemplateElement prevSibling = previousSibling();
- TemplateElement nextSibling = nextSibling();
- return ((prevSibling == null && atTopLevel) || nonOutputtingType(prevSibling))
- && ((nextSibling == null && atTopLevel) || nonOutputtingType(nextSibling));
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/808ddadd/src/main/java/freemarker/core/ThreadInterruptionSupportTemplatePostProcessor.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/ThreadInterruptionSupportTemplatePostProcessor.java b/src/main/java/freemarker/core/ThreadInterruptionSupportTemplatePostProcessor.java
index 7a0e545..26d54aa 100644
--- a/src/main/java/freemarker/core/ThreadInterruptionSupportTemplatePostProcessor.java
+++ b/src/main/java/freemarker/core/ThreadInterruptionSupportTemplatePostProcessor.java
@@ -58,41 +58,14 @@ class ThreadInterruptionSupportTemplatePostProcessor extends TemplatePostProcess
return;
}
- final TemplateElement nestedBlock = te.getNestedBlock();
-
- // Deepest-first recursion:
- if (nestedBlock != null) {
- addInterruptionChecks(nestedBlock);
- }
- final int regulatedChildrenCount = te.getRegulatedChildCount();
+ final int regulatedChildrenCount = te.getChildCount();
for (int i = 0; i < regulatedChildrenCount; i++) {
- addInterruptionChecks(te.getRegulatedChild(i));
+ addInterruptionChecks(te.getChild(i));
}
- // Because nestedElements (means fixed schema for the children) and nestedBlock (means no fixed schema) are
- // mutually exclusive, and we only care about the last kind:
if (te.isNestedBlockRepeater()) {
- if (nestedBlock == null && regulatedChildrenCount != 0) {
- // Only elements that use nestedBlock instead of regulatedChildren should be block repeaters.
- // Note that nestedBlock and nestedElements are (should be) mutually exclusive.
- throw new BugException();
- }
try {
- final ThreadInterruptionCheck interruptedChk = new ThreadInterruptionCheck(te);
- if (nestedBlock == null) {
- te.setNestedBlock(interruptedChk);
- } else {
- final MixedContent nestedMixedC;
- if (nestedBlock instanceof MixedContent) {
- nestedMixedC = (MixedContent) nestedBlock;
- } else {
- nestedMixedC = new MixedContent();
- nestedMixedC.setLocation(te.getTemplate(), 0, 0, 0, 0);
- nestedMixedC.addElement(nestedBlock);
- te.setNestedBlock(nestedMixedC);
- }
- nestedMixedC.addElement(0, interruptedChk);
- }
+ te.addChild(0, new ThreadInterruptionCheck(te));
} catch (ParseException e) {
throw new TemplatePostProcessorException("Unexpected error; see cause", e);
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/808ddadd/src/main/java/freemarker/core/TransformBlock.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/TransformBlock.java b/src/main/java/freemarker/core/TransformBlock.java
index 8bde8cf..4412664 100644
--- a/src/main/java/freemarker/core/TransformBlock.java
+++ b/src/main/java/freemarker/core/TransformBlock.java
@@ -51,7 +51,7 @@ final class TransformBlock extends TemplateElement {
TemplateElement nestedBlock) {
this.transformExpression = transformExpression;
this.namedArgs = namedArgs;
- setNestedBlock(nestedBlock);
+ setChildrenFromElement(nestedBlock);
}
@Override
@@ -72,7 +72,7 @@ final class TransformBlock extends TemplateElement {
} else {
args = EmptyMap.instance;
}
- env.visitAndTransform(getNestedBlock(), ttm, args);
+ env.visitAndTransform(getChildBuffer(), ttm, args);
} else {
TemplateModel tm = transformExpression.eval(env);
throw new UnexpectedTypeException(
@@ -100,9 +100,7 @@ final class TransformBlock extends TemplateElement {
}
if (canonical) {
sb.append(">");
- if (getNestedBlock() != null) {
- sb.append(getNestedBlock().getCanonicalForm());
- }
+ sb.append(getChildrenCanonicalForm());
sb.append("</").append(getNodeTypeSymbol()).append('>');
}
return sb.toString();
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/808ddadd/src/main/java/freemarker/core/TrimInstruction.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/TrimInstruction.java b/src/main/java/freemarker/core/TrimInstruction.java
index a974e0f..7e48367 100644
--- a/src/main/java/freemarker/core/TrimInstruction.java
+++ b/src/main/java/freemarker/core/TrimInstruction.java
@@ -66,7 +66,7 @@ final class TrimInstruction extends TemplateElement {
}
@Override
- boolean isIgnorable() {
+ boolean isIgnorable(boolean stripWhitespace) {
return true;
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/808ddadd/src/main/java/freemarker/core/UnifiedCall.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/UnifiedCall.java b/src/main/java/freemarker/core/UnifiedCall.java
index fde6451..831b7bc 100644
--- a/src/main/java/freemarker/core/UnifiedCall.java
+++ b/src/main/java/freemarker/core/UnifiedCall.java
@@ -54,7 +54,7 @@ final class UnifiedCall extends TemplateElement implements DirectiveCallPlace {
List bodyParameterNames) {
this.nameExp = nameExp;
this.namedArgs = namedArgs;
- setNestedBlock(nestedBlock);
+ setChildrenFromElement(nestedBlock);
this.bodyParameterNames = bodyParameterNames;
}
@@ -67,7 +67,7 @@ final class UnifiedCall extends TemplateElement implements DirectiveCallPlace {
if (nestedBlock == TextBlock.EMPTY_BLOCK) {
nestedBlock = null;
}
- setNestedBlock(nestedBlock);
+ setChildrenFromElement(nestedBlock);
this.bodyParameterNames = bodyParameterNames;
}
@@ -83,8 +83,7 @@ final class UnifiedCall extends TemplateElement implements DirectiveCallPlace {
+ "Functions can only be called from expressions, like in ${f()}, ${x + f()} or ",
"<@someDirective someParam=f() />", ".");
}
- env.invoke(macro, namedArgs, positionalArgs, bodyParameterNames,
- getNestedBlock());
+ env.invoke(macro, namedArgs, positionalArgs, bodyParameterNames, getChildBuffer());
} else {
boolean isDirectiveModel = tm instanceof TemplateDirectiveModel;
if (isDirectiveModel || tm instanceof TemplateTransformModel) {
@@ -102,9 +101,9 @@ final class UnifiedCall extends TemplateElement implements DirectiveCallPlace {
args = EmptyMap.instance;
}
if (isDirectiveModel) {
- env.visit(getNestedBlock(), (TemplateDirectiveModel) tm, args, bodyParameterNames);
+ env.visit(getChildBuffer(), (TemplateDirectiveModel) tm, args, bodyParameterNames);
} else {
- env.visitAndTransform(getNestedBlock(), (TemplateTransformModel) tm, args);
+ env.visitAndTransform(getChildBuffer(), (TemplateTransformModel) tm, args);
}
} else if (tm == null) {
throw InvalidReferenceException.getInstance(nameExp, env);
@@ -152,11 +151,11 @@ final class UnifiedCall extends TemplateElement implements DirectiveCallPlace {
}
}
if (canonical) {
- if (getNestedBlock() == null) {
+ if (getChildCount() == 0) {
sb.append("/>");
} else {
sb.append('>');
- sb.append(getNestedBlock().getCanonicalForm());
+ sb.append(getChildrenCanonicalForm());
sb.append("</@");
if (!nameIsInParen
&& (nameExp instanceof Identifier
@@ -303,8 +302,7 @@ final class UnifiedCall extends TemplateElement implements DirectiveCallPlace {
}
public boolean isNestedOutputCacheable() {
- if (getNestedBlock() == null) return true;
- return getNestedBlock().isOutputCacheable();
+ return isChildrenOutputCacheable();
}
/*