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 2017/07/07 23:00:11 UTC
[1/3] incubator-freemarker git commit: (Fixed trim directive AST
class name)
Repository: incubator-freemarker
Updated Branches:
refs/heads/3 92db58918 -> 344b95411
(Fixed trim directive AST class name)
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/8be70ea9
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/8be70ea9
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/8be70ea9
Branch: refs/heads/3
Commit: 8be70ea94410e192236e7d61f9e8d023331efc16
Parents: 92db589
Author: ddekany <dd...@apache.org>
Authored: Sat Jul 8 00:57:49 2017 +0200
Committer: ddekany <dd...@apache.org>
Committed: Sat Jul 8 00:57:49 2017 +0200
----------------------------------------------------------------------
.../freemarker/core/ASTDirTOrRtOrLtOrNt.java | 109 +++++++++++++++++++
.../apache/freemarker/core/ASTDirTOrTrOrTl.java | 109 -------------------
.../apache/freemarker/core/ASTStaticText.java | 10 +-
freemarker-core/src/main/javacc/FTL.jj | 10 +-
4 files changed, 119 insertions(+), 119 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8be70ea9/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirTOrRtOrLtOrNt.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirTOrRtOrLtOrNt.java b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirTOrRtOrLtOrNt.java
new file mode 100644
index 0000000..5b79e30
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirTOrRtOrLtOrNt.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.freemarker.core;
+
+/**
+ * AST directive node: {@code #t}, {@code #tr}, {@code #tl}.
+ */
+final class ASTDirTOrRtOrLtOrNt extends ASTDirective {
+
+ private static final int TYPE_T = 0;
+ private static final int TYPE_LT = 1;
+ private static final int TYPE_RT = 2;
+ private static final int TYPE_NT = 3;
+
+ final boolean left, right;
+
+ ASTDirTOrRtOrLtOrNt(boolean left, boolean right) {
+ this.left = left;
+ this.right = right;
+ }
+
+ @Override
+ ASTElement[] accept(Environment env) {
+ // This instruction does nothing at render-time, only parse-time.
+ return null;
+ }
+
+ @Override
+ protected String dump(boolean canonical) {
+ StringBuilder sb = new StringBuilder();
+ if (canonical) sb.append('<');
+ sb.append(getASTNodeDescriptor());
+ if (canonical) sb.append("/>");
+ return sb.toString();
+ }
+
+ @Override
+ String getASTNodeDescriptor() {
+ if (left && right) {
+ return "#t";
+ } else if (left) {
+ return "#lt";
+ } else if (right) {
+ return "#rt";
+ } else {
+ return "#nt";
+ }
+ }
+
+ @Override
+ boolean isIgnorable(boolean stripWhitespace) {
+ return true;
+ }
+
+ @Override
+ int getParameterCount() {
+ return 1;
+ }
+
+ @Override
+ Object getParameterValue(int idx) {
+ if (idx != 0) throw new IndexOutOfBoundsException();
+ int type;
+ if (left && right) {
+ type = TYPE_T;
+ } else if (left) {
+ type = TYPE_LT;
+ } else if (right) {
+ type = TYPE_RT;
+ } else {
+ type = TYPE_NT;
+ }
+ return Integer.valueOf(type);
+ }
+
+ @Override
+ ParameterRole getParameterRole(int idx) {
+ if (idx != 0) throw new IndexOutOfBoundsException();
+ return ParameterRole.AST_NODE_SUBTYPE;
+ }
+
+ @Override
+ boolean isOutputCacheable() {
+ return true;
+ }
+
+ @Override
+ boolean isNestedBlockRepeater() {
+ return false;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8be70ea9/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirTOrTrOrTl.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirTOrTrOrTl.java b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirTOrTrOrTl.java
deleted file mode 100644
index 3cf4b9d..0000000
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirTOrTrOrTl.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.freemarker.core;
-
-/**
- * AST directive node: {@code #t}, {@code #tr}, {@code #tl}.
- */
-final class ASTDirTOrTrOrTl extends ASTDirective {
-
- private static final int TYPE_T = 0;
- private static final int TYPE_LT = 1;
- private static final int TYPE_RT = 2;
- private static final int TYPE_NT = 3;
-
- final boolean left, right;
-
- ASTDirTOrTrOrTl(boolean left, boolean right) {
- this.left = left;
- this.right = right;
- }
-
- @Override
- ASTElement[] accept(Environment env) {
- // This instruction does nothing at render-time, only parse-time.
- return null;
- }
-
- @Override
- protected String dump(boolean canonical) {
- StringBuilder sb = new StringBuilder();
- if (canonical) sb.append('<');
- sb.append(getASTNodeDescriptor());
- if (canonical) sb.append("/>");
- return sb.toString();
- }
-
- @Override
- String getASTNodeDescriptor() {
- if (left && right) {
- return "#t";
- } else if (left) {
- return "#lt";
- } else if (right) {
- return "#rt";
- } else {
- return "#nt";
- }
- }
-
- @Override
- boolean isIgnorable(boolean stripWhitespace) {
- return true;
- }
-
- @Override
- int getParameterCount() {
- return 1;
- }
-
- @Override
- Object getParameterValue(int idx) {
- if (idx != 0) throw new IndexOutOfBoundsException();
- int type;
- if (left && right) {
- type = TYPE_T;
- } else if (left) {
- type = TYPE_LT;
- } else if (right) {
- type = TYPE_RT;
- } else {
- type = TYPE_NT;
- }
- return Integer.valueOf(type);
- }
-
- @Override
- ParameterRole getParameterRole(int idx) {
- if (idx != 0) throw new IndexOutOfBoundsException();
- return ParameterRole.AST_NODE_SUBTYPE;
- }
-
- @Override
- boolean isOutputCacheable() {
- return true;
- }
-
- @Override
- boolean isNestedBlockRepeater() {
- return false;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8be70ea9/freemarker-core/src/main/java/org/apache/freemarker/core/ASTStaticText.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTStaticText.java b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTStaticText.java
index 5e4b957..4353400 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTStaticText.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTStaticText.java
@@ -144,8 +144,8 @@ final class ASTStaticText extends ASTElement {
for (ASTElement elem = nextTerminalNode();
elem != null && elem.beginLine == endLine;
elem = elem.nextTerminalNode()) {
- if (elem instanceof ASTDirTOrTrOrTl) {
- ASTDirTOrTrOrTl ti = (ASTDirTOrTrOrTl) elem;
+ if (elem instanceof ASTDirTOrRtOrLtOrNt) {
+ ASTDirTOrRtOrLtOrNt ti = (ASTDirTOrRtOrLtOrNt) elem;
if (!ti.left && !ti.right) {
result = true;
}
@@ -182,8 +182,8 @@ final class ASTStaticText extends ASTElement {
for (ASTElement elem = prevTerminalNode();
elem != null && elem.endLine == beginLine;
elem = elem.prevTerminalNode()) {
- if (elem instanceof ASTDirTOrTrOrTl) {
- ASTDirTOrTrOrTl ti = (ASTDirTOrTrOrTl) elem;
+ if (elem instanceof ASTDirTOrRtOrLtOrNt) {
+ ASTDirTOrRtOrLtOrNt ti = (ASTDirTOrRtOrLtOrNt) elem;
if (!ti.left && !ti.right) {
result = true;
}
@@ -219,7 +219,7 @@ final class ASTStaticText extends ASTElement {
if (te.heedsOpeningWhitespace()) {
trimTrailingPart = false;
}
- if (te instanceof ASTDirTOrTrOrTl && ((ASTDirTOrTrOrTl) te).left) {
+ if (te instanceof ASTDirTOrRtOrLtOrNt && ((ASTDirTOrRtOrLtOrNt) te).left) {
trimTrailingPart = true;
break;
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8be70ea9/freemarker-core/src/main/javacc/FTL.jj
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/javacc/FTL.jj b/freemarker-core/src/main/javacc/FTL.jj
index fd07a66..84608ea 100644
--- a/freemarker-core/src/main/javacc/FTL.jj
+++ b/freemarker-core/src/main/javacc/FTL.jj
@@ -2649,17 +2649,17 @@ ASTElement Flush() :
ASTElement Trim() :
{
Token t;
- ASTDirTOrTrOrTl result = null;
+ ASTDirTOrRtOrLtOrNt result = null;
}
{
(
- t = <TRIM> { result = new ASTDirTOrTrOrTl(true, true); }
+ t = <TRIM> { result = new ASTDirTOrRtOrLtOrNt(true, true); }
|
- t = <LTRIM> { result = new ASTDirTOrTrOrTl(true, false); }
+ t = <LTRIM> { result = new ASTDirTOrRtOrLtOrNt(true, false); }
|
- t = <RTRIM> { result = new ASTDirTOrTrOrTl(false, true); }
+ t = <RTRIM> { result = new ASTDirTOrRtOrLtOrNt(false, true); }
|
- t = <NOTRIM> { result = new ASTDirTOrTrOrTl(false, false); }
+ t = <NOTRIM> { result = new ASTDirTOrRtOrLtOrNt(false, false); }
)
{
result.setLocation(template, t, t);
[2/3] incubator-freemarker git commit: Build: Allowed using local
Maven repo and Apache snapshot repo (as far as we are in this early stage at
least).
Posted by dd...@apache.org.
Build: Allowed using local Maven repo and Apache snapshot repo (as far as we are in this early stage at least).
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/a0bc242f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/a0bc242f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/a0bc242f
Branch: refs/heads/3
Commit: a0bc242fb6c52958c903ff88f37431df72c4fb87
Parents: 8be70ea
Author: ddekany <dd...@apache.org>
Authored: Sat Jul 8 00:59:12 2017 +0200
Committer: ddekany <dd...@apache.org>
Committed: Sat Jul 8 00:59:12 2017 +0200
----------------------------------------------------------------------
build.gradle | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/a0bc242f/build.gradle
----------------------------------------------------------------------
diff --git a/build.gradle b/build.gradle
index 8c566af..b5e545b 100644
--- a/build.gradle
+++ b/build.gradle
@@ -200,8 +200,13 @@ subprojects {
// TODO Ensure that JUnit tests run on Java 7, except for the modules that were made for later versions.
repositories {
- // mavenLocal()
+ mavenLocal()
mavenCentral()
+
+ // This is only needed temporarily (remove before first stable release):
+ maven {
+ url "https://repository.apache.org/content/repositories/snapshots"
+ }
}
// Dependencies used in all subprojects:
[3/3] incubator-freemarker git commit: Continued FM2 to FM3
converter...
Posted by dd...@apache.org.
Continued FM2 to FM3 converter...
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/344b9541
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/344b9541
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/344b9541
Branch: refs/heads/3
Commit: 344b9541102b524a810f05b06bed9cdf93b23857
Parents: a0bc242
Author: ddekany <dd...@apache.org>
Authored: Sat Jul 8 00:59:50 2017 +0200
Committer: ddekany <dd...@apache.org>
Committed: Sat Jul 8 00:59:50 2017 +0200
----------------------------------------------------------------------
freemarker-converter/build.gradle | 2 +-
.../core/FM2ASTToFM3SourceConverter.java | 186 ++++++++++++++++---
.../freemarker/converter/FM2ToFM3Converter.java | 2 +
.../converter/FM2ToFM3ConverterTest.java | 28 +++
4 files changed, 192 insertions(+), 26 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/344b9541/freemarker-converter/build.gradle
----------------------------------------------------------------------
diff --git a/freemarker-converter/build.gradle b/freemarker-converter/build.gradle
index c08bad7..ee42afe 100644
--- a/freemarker-converter/build.gradle
+++ b/freemarker-converter/build.gradle
@@ -25,7 +25,7 @@ inAggregateJavadoc = false
dependencies {
compile project(":freemarker-core")
- compile "org.freemarker:freemarker:2.3.26-incubating"
+ compile "org.freemarker:freemarker-gae:2.3.27-incubating-SNAPSHOT"
compile libraries.commonsCli
compile libraries.commonsLang
compile libraries.commonsIo
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/344b9541/freemarker-converter/src/main/java/freemarker/core/FM2ASTToFM3SourceConverter.java
----------------------------------------------------------------------
diff --git a/freemarker-converter/src/main/java/freemarker/core/FM2ASTToFM3SourceConverter.java b/freemarker-converter/src/main/java/freemarker/core/FM2ASTToFM3SourceConverter.java
index 1d6f484..de31532 100644
--- a/freemarker-converter/src/main/java/freemarker/core/FM2ASTToFM3SourceConverter.java
+++ b/freemarker-converter/src/main/java/freemarker/core/FM2ASTToFM3SourceConverter.java
@@ -236,22 +236,45 @@ public class FM2ASTToFM3SourceConverter {
if (node instanceof MixedContent) {
printChildElements(node);
} else if (node instanceof TextBlock) {
- print(getOnlyParam(node, ParameterRole.CONTENT, String.class));
+ printText(node);
} else if (node instanceof DollarVariable) {
printDollarInterpolation((DollarVariable) node);
} else if (node instanceof NumericalOutput) {
printNumericalInterpolation((NumericalOutput) node);
} else if (node instanceof Comment) {
- print(tagBeginChar);
- print("#--");
- print(getOnlyParam(node, ParameterRole.CONTENT, String.class));
- print("--");
- print(tagEndChar);
+ printComment((Comment) node);
} else {
printDir(node);
}
}
+ private void printText(TemplateElement node) throws ConverterException {
+ int startPos = getStartPosition(node);
+ int endPos = getEndPositionExclusive(node);
+ if (startPos < 0 || startPos >= endPos) { // empty text
+ return;
+ }
+
+ boolean isNoParseBlock = src.startsWith(tagBeginChar + "#no", startPos);
+ if (isNoParseBlock) {
+ printCoreDirStartTagParameterless(node, "noParse");
+ }
+ print(getOnlyParam(node, ParameterRole.CONTENT, String.class));
+ if (isNoParseBlock) {
+ printCoreDirEndTag(node, NO_PARSE_FM_2_TAG_NAMES, "noParse");
+ }
+ }
+
+ private static final ImmutableList<String> NO_PARSE_FM_2_TAG_NAMES = ImmutableList.of("noparse", "noParse");
+
+ private void printComment(Comment node) throws UnexpectedNodeContentException {
+ print(tagBeginChar);
+ print("#--");
+ print(getOnlyParam(node, ParameterRole.CONTENT, String.class));
+ print("--");
+ print(tagEndChar);
+ }
+
private void printNumericalInterpolation(NumericalOutput node) throws ConverterException {
printWithParamsLeadingSkippedTokens("${", node);
Expression content = getParam(node, 0, ParameterRole.CONTENT, Expression.class);
@@ -320,8 +343,12 @@ public class FM2ASTToFM3SourceConverter {
printDirCustom((UnifiedCall) node);
} else if (node instanceof Macro) {
printDirMacroOrFunction((Macro) node);
+ } else if (node instanceof BodyInstruction) {
+ printDirNested((BodyInstruction) node);
} else if (node instanceof Assignment) {
printDirAssignmentLonely((Assignment) node);
+ } else if (node instanceof BlockAssignment) {
+ printDirBlockAssignment((BlockAssignment) node);
} else if (node instanceof AssignmentInstruction) {
printDirAssignmentMultiple((AssignmentInstruction) node);
} else if (node instanceof AttemptBlock) {
@@ -356,11 +383,45 @@ public class FM2ASTToFM3SourceConverter {
printDirItems((Items) node);
} else if (node instanceof BreakInstruction) {
printDirBreak((BreakInstruction) node);
+ } else if (node instanceof TrimInstruction) {
+ printDirTOrNtOrLtOrRt((TrimInstruction) node);
} else {
throw new ConverterException("Unhandled AST TemplateElement class: " + node.getClass().getName());
}
}
+ private void printDirTOrNtOrLtOrRt(TrimInstruction node) throws ConverterException {
+ int subtype= getOnlyParam(node, ParameterRole.AST_NODE_SUBTYPE, Integer.class);
+ String tagName;
+ if (subtype == TrimInstruction.TYPE_T) {
+ tagName = "t";
+ } else if (subtype == TrimInstruction.TYPE_LT) {
+ tagName = "lt";
+ } else if (subtype == TrimInstruction.TYPE_RT) {
+ tagName = "rt";
+ } else if (subtype == TrimInstruction.TYPE_NT) {
+ tagName = "nt";
+ } else {
+ throw new UnexpectedNodeContentException(node, "Unhandled subtype {}.", subtype);
+ }
+
+ printCoreDirStartTagParameterless(node, tagName);
+ }
+
+ private void printDirNested(BodyInstruction node) throws ConverterException {
+ int pos = printCoreDirStartTagBeforeParams(node, "nested");
+ int paramCnt = node.getParameterCount();
+ for (int paramIdx = 0; paramIdx < paramCnt; paramIdx++) {
+ Expression passedValue = getParam(node, paramIdx, ParameterRole.PASSED_VALUE, Expression.class);
+ printExp(passedValue);
+ pos = getEndPositionExclusive(passedValue);
+ if (paramIdx < paramCnt - 1) {
+ printOptionalSeparatorAndWSAndExpComments(pos, ",");
+ }
+ }
+ printStartTagEnd(node, pos, true);
+ }
+
private void printDirBreak(BreakInstruction node) throws ConverterException {
printCoreDirStartTagParameterless(node, "break");
}
@@ -489,16 +550,14 @@ public class FM2ASTToFM3SourceConverter {
printChildElements(node);
if (printEndTag) {
- printCoreDirEndTag(node, ImmutableList.of("list", "foreach", "forEach"), "list", false);
+ printCoreDirEndTag(node, LIST_FM_2_TAG_NAMES, "list", false);
}
}
+ private static final ImmutableList<String> LIST_FM_2_TAG_NAMES = ImmutableList.of("list", "foreach", "forEach");
+
private void printDirInclude(Include node) throws ConverterException {
- if (Configuration.getVersion().intValue() != Configuration.VERSION_2_3_26.intValue()) {
- throw new BugException("Fix things at [broken in 2.3.26] comments; version was: "
- + Configuration.getVersion());
- }
- // assertParamCount(node, 4); // [broken in 2.3.26]
+ assertParamCount(node, 4);
printCoreDirStartTagBeforeParams(node, "include");
@@ -521,9 +580,7 @@ public class FM2ASTToFM3SourceConverter {
+ "encoding than the configured default.");
}
- // Can't use as parameterCount is [broken in 2.3.26]:
- // Expression ignoreMissingParam = getParam(node, 3, ParameterRole.IGNORE_MISSING_PARAMETER, Expression.class);
- Expression ignoreMissingParam = (Expression) node.getParameterValue(3);
+ Expression ignoreMissingParam = getParam(node, 3, ParameterRole.IGNORE_MISSING_PARAMETER, Expression.class);
List<Expression> sortedExps =
sortExpressionsByPosition(templateName, parseParam, encodingParam, ignoreMissingParam);
@@ -611,9 +668,11 @@ public class FM2ASTToFM3SourceConverter {
}
private void printDirNoEscape(NoEscapeBlock node) throws ConverterException {
- printDirGenericParameterlessWithNestedContent(node, "noEscape");
+ printDirGenericParameterlessWithNestedContent(node, NO_ESCAPE_FM_2_TAG_NAMES, "noEscape");
}
+ private static final ImmutableList<String> NO_ESCAPE_FM_2_TAG_NAMES = ImmutableList.of("noescape", "noEscape");
+
private void printDirEscape(EscapeBlock node) throws ConverterException {
assertParamCount(node, 2);
@@ -638,20 +697,30 @@ public class FM2ASTToFM3SourceConverter {
}
private void printDirAutoEsc(AutoEscBlock node) throws ConverterException {
- printDirGenericParameterlessWithNestedContent(node, "autoEsc");
+ printDirGenericParameterlessWithNestedContent(node, AUTO_ESC_FM_2_TAG_NAMES, "autoEsc");
}
+ private static final ImmutableList<String> AUTO_ESC_FM_2_TAG_NAMES = ImmutableList.of("autoesc", "autoEsc");
+
private void printDirNoAutoEsc(NoAutoEscBlock node) throws ConverterException {
- printDirGenericParameterlessWithNestedContent(node, "noAutoEsc");
+ printDirGenericParameterlessWithNestedContent(node, NO_AUTO_ESC_FM_2_TAG_NAMES, "noAutoEsc");
+ }
+
+ private static final ImmutableList<String> NO_AUTO_ESC_FM_2_TAG_NAMES = ImmutableList.of("noautoesc", "noAutoEsc");
+
+ private void printDirGenericParameterlessWithNestedContent(TemplateElement node, String fm3TagName)
+ throws ConverterException {
+ printDirGenericParameterlessWithNestedContent(node, Collections.singleton(fm3TagName), fm3TagName);
}
- private void printDirGenericParameterlessWithNestedContent(TemplateElement node, String tagName)
+ private void printDirGenericParameterlessWithNestedContent(TemplateElement node,
+ Collection<String> fm2TagName, String fm3TagName)
throws ConverterException {
assertParamCount(node, 0);
- printCoreDirStartTagParameterless(node, tagName);
+ printCoreDirStartTagParameterless(node, fm3TagName);
printChildElements(node);
- printCoreDirEndTag(node, tagName);
+ printCoreDirEndTag(node, fm2TagName, fm3TagName);
}
private void printDirGenericParameterlessWithoutNestedContent(TemplateElement node, String name)
@@ -674,9 +743,11 @@ public class FM2ASTToFM3SourceConverter {
printChildElements(recoverDir);
// In FM2 this could be </#recover> as well, but we normalize it
- printCoreDirEndTag(node, ImmutableList.of("attempt", "recover"), "attempt", false);
+ printCoreDirEndTag(node, ATTEMPT_RECOVER_FM_2_TAG_NAMES, "attempt", false);
}
+ private static final ImmutableList<String> ATTEMPT_RECOVER_FM_2_TAG_NAMES = ImmutableList.of("attempt", "recover");
+
private void printDirAssignmentMultiple(AssignmentInstruction node) throws ConverterException {
assertParamCount(node, 2);
@@ -702,6 +773,28 @@ public class FM2ASTToFM3SourceConverter {
printDirAssignmentCommonTagAfterLastAssignmentExp(node, 4, pos);
}
+ private void printDirBlockAssignment(BlockAssignment node) throws ConverterException {
+ assertParamCount(node, 3);
+
+ int pos = printDirAssignmentCommonTagTillAssignmentExp(node, 1);
+
+ print(FTLUtil.escapeIdentifier(getParam(node, 0, ParameterRole.ASSIGNMENT_TARGET, String.class)));
+ pos = getPositionAfterAssignmentTargetIdentifier(pos);
+
+ Expression namespace = getParam(node, 2, ParameterRole.NAMESPACE, Expression.class);
+ if (namespace != null) {
+ printSeparatorAndWSAndExpComments(pos, "in");
+ printExp(namespace);
+ pos = getEndPositionExclusive(namespace);
+ }
+
+ printStartTagEnd(node, pos, true);
+
+ printChildElements(node);
+
+ printCoreDirEndTag(node, getAssignmentDirTagName(node, 1));
+ }
+
private void printDirAssignmentCommonTagAfterLastAssignmentExp(TemplateElement node, int nsParamIdx, int pos)
throws ConverterException {
Expression ns = getParam(node, nsParamIdx, ParameterRole.NAMESPACE, Expression.class);
@@ -719,6 +812,11 @@ public class FM2ASTToFM3SourceConverter {
private int printDirAssignmentCommonTagTillAssignmentExp(TemplateElement node, int scopeParamIdx)
throws ConverterException {
+ return printCoreDirStartTagBeforeParams(node, getAssignmentDirTagName(node, scopeParamIdx));
+ }
+
+ private String getAssignmentDirTagName(TemplateElement node, int scopeParamIdx)
+ throws UnexpectedNodeContentException {
int scope = getParam(node, scopeParamIdx, ParameterRole.VARIABLE_SCOPE, Integer.class);
String tagName;
if (scope == Assignment.NAMESPACE) {
@@ -730,7 +828,7 @@ public class FM2ASTToFM3SourceConverter {
} else {
throw new UnexpectedNodeContentException(node, "Unhandled scope: {}", scope);
}
- return printCoreDirStartTagBeforeParams(node, tagName);
+ return tagName;
}
private int printDirAssignmentCommonExp(Assignment node, int pos) throws ConverterException {
@@ -1360,7 +1458,7 @@ public class FM2ASTToFM3SourceConverter {
{
int pos = getStartPosition(node);
quote = src.charAt(pos);
- while ((quote == '\\' || quote == '{' /* 2.3.26 bug workaround */ || quote == 'r')
+ while ((quote == '\\' || quote == '{' /* [broken in 2.3.26] */ || quote == 'r')
&& pos < src.length()) {
pos++;
if (quote == 'r') {
@@ -1459,7 +1557,20 @@ public class FM2ASTToFM3SourceConverter {
}
private void printCoreDirEndTag(TemplateElement node, String tagName) throws UnexpectedNodeContentException {
- printCoreDirEndTag(node, Collections.singleton(tagName), tagName, false);
+ printCoreDirEndTag(node, Collections.singleton(tagName), tagName);
+ }
+
+ private void printCoreDirEndTag(TemplateElement node, Collection<String> fm2TagName, String fm3TagName) throws
+ UnexpectedNodeContentException {
+ if (fm2TagName.size() == 0) {
+ throw new IllegalArgumentException("You must specify at least 1 FM2 tag names");
+ }
+ if (fm2TagName.size() == 1 && containsUpperCaseLetter(fm3TagName)) {
+ throw new IllegalArgumentException(
+ "You must specify multiple FM2 tag names when the FM3 tag name ("
+ + fm3TagName + ") contains upper case letters");
+ }
+ printCoreDirEndTag(node, fm2TagName, fm3TagName, false);
}
private void printCoreDirEndTag(TemplateElement node, Collection<String> fm2TagNames, String fm3TagName,
@@ -1717,6 +1828,9 @@ public class FM2ASTToFM3SourceConverter {
* 1-based row
*/
private int getPosition(int column, int row) {
+ if (row == 0) {
+ return -1;
+ }
if (rowStartPositions == null) {
rowStartPositions = new ArrayList<>();
rowStartPositions.add(0);
@@ -1945,4 +2059,26 @@ public class FM2ASTToFM3SourceConverter {
return i != -1 ? s.substring(0, i + 1) : "";
}
+ private boolean isUpperCaseLetter(char c) {
+ return Character.isUpperCase(c) && Character.isLetter(c);
+ }
+
+ private HashMap<String, Boolean> containsUpperCaseLetterResults = new HashMap<>();
+
+ private boolean containsUpperCaseLetter(String s) {
+ Boolean result = containsUpperCaseLetterResults.get(s);
+ if (result != null) {
+ return result;
+ }
+
+ int i = 0;
+ while (i < s.length() && !isUpperCaseLetter(s.charAt(i))) {
+ i++;
+ }
+ result = i < s.length();
+
+ containsUpperCaseLetterResults.put(s, result);
+ return result;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/344b9541/freemarker-converter/src/main/java/org/apache/freemarker/converter/FM2ToFM3Converter.java
----------------------------------------------------------------------
diff --git a/freemarker-converter/src/main/java/org/apache/freemarker/converter/FM2ToFM3Converter.java b/freemarker-converter/src/main/java/org/apache/freemarker/converter/FM2ToFM3Converter.java
index 4dff35e..1e024e5 100644
--- a/freemarker-converter/src/main/java/org/apache/freemarker/converter/FM2ToFM3Converter.java
+++ b/freemarker-converter/src/main/java/org/apache/freemarker/converter/FM2ToFM3Converter.java
@@ -33,6 +33,7 @@ import org.slf4j.LoggerFactory;
import freemarker.core.FM2ASTToFM3SourceConverter;
import freemarker.template.Configuration;
import freemarker.template.Template;
+import freemarker.template._TemplateAPI;
public class FM2ToFM3Converter extends Converter {
@@ -59,6 +60,7 @@ public class FM2ToFM3Converter extends Converter {
fm2Cfg = new Configuration(Configuration.VERSION_2_3_19 /* To fix ignored initial unknown tags */);
fm2Cfg.setWhitespaceStripping(false);
fm2Cfg.setTabSize(1);
+ _TemplateAPI.setPreventStrippings(fm2Cfg, true);
try {
fm2Cfg.setSettings(freeMarker2Settings);
} catch (Exception e) {
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/344b9541/freemarker-converter/src/test/java/org/freemarker/converter/FM2ToFM3ConverterTest.java
----------------------------------------------------------------------
diff --git a/freemarker-converter/src/test/java/org/freemarker/converter/FM2ToFM3ConverterTest.java b/freemarker-converter/src/test/java/org/freemarker/converter/FM2ToFM3ConverterTest.java
index 138e048..1243251 100644
--- a/freemarker-converter/src/test/java/org/freemarker/converter/FM2ToFM3ConverterTest.java
+++ b/freemarker-converter/src/test/java/org/freemarker/converter/FM2ToFM3ConverterTest.java
@@ -191,6 +191,12 @@ public class FM2ToFM3ConverterTest extends ConverterTest {
assertConvertedSame("<#macro m\\-1 p\\-1></#macro>");
// Only works with " now, as it doesn't keep the literal kind. Later we will escape differently anyway:
assertConvertedSame("<#macro \"m 1\"></#macro>");
+ assertConvertedSame("<#macro m><#nested x + 1, 2, 3></#macro>");
+ assertConvertedSame("<#macro m><#nested <#--1--> x + 1 <#--2-->, <#--3--> 2 <#--4-->></#macro>");
+ // [FM3] Will be different (comma)
+ assertConvertedSame("<#macro m><#nested x + 1 2 3></#macro>");
+ assertConvertedSame("<#macro m><#nested <#--1--> x + 1 <#--2--> 2 <#--3-->></#macro>");
+ assertConverted("<#macro m><#nested x></#macro>", "<#macro m><#nested x /></#macro>");
assertConvertedSame("<#assign x = 1>");
assertConvertedSame("<#global x = 1>");
@@ -207,6 +213,14 @@ public class FM2ToFM3ConverterTest extends ConverterTest {
// Only works with " now, as it doesn't keep the literal kind. Later we will escape differently anyway:
assertConvertedSame("<#assign \"x y\" = 1>");
+ assertConvertedSame("<#assign x>t</#assign>");
+ assertConvertedSame("<#assign x in ns>t</#assign>");
+ assertConvertedSame("<#assign x\\-y>t</#assign>");
+ assertConvertedSame("<#assign \"x y\">t</#assign>");
+ assertConvertedSame("<#global x>t</#global>");
+ assertConvertedSame("<#macro m><#local x>t</#local></#macro>");
+ assertConvertedSame("<#assign <#--1--> x <#--2--> in <#--3--> ns <#--4-->>t</#assign >");
+
assertConvertedSame("<#attempt>a<#recover>r</#attempt>");
assertConvertedSame("<#attempt >a<#recover >r</#attempt >");
assertConverted("<#attempt>a<#recover>r</#attempt>", "<#attempt>a<#recover>r</#recover>");
@@ -225,6 +239,9 @@ public class FM2ToFM3ConverterTest extends ConverterTest {
assertConvertedSame("<#ftl outputFormat='XML'><#noAutoEsc><#autoEsc>${x}</#autoEsc></#noAutoEsc>");
assertConvertedSame("<#ftl outputFormat='XML'><#noAutoEsc ><#autoEsc\t>${x}</#autoEsc\n></#noAutoEsc\r>");
+ assertConverted(
+ "<#ftl outputFormat='XML'><#noAutoEsc>${x}</#noAutoEsc>",
+ "<#ftl output_format='XML'><#noautoesc>${x}</#noautoesc>");
assertConvertedSame("<#compress>x</#compress>");
assertConvertedSame("<#compress >x</#compress >");
@@ -283,6 +300,17 @@ public class FM2ToFM3ConverterTest extends ConverterTest {
"<#list xs>[<#items as <#--1--> k <#--2-->, <#--3--> v <#--4-->>${h}${v}<#sep>, </#items>]</#list>");
assertConvertedSame("<#list xs as x><#if x == 0><#break></#if>${x}</#list>");
assertConvertedSame("<#list xs>[<#items as x>${x}<#sep>, </#sep >|</#items>]<#else>-</#list>");
+
+ assertConvertedSame("<#noParse><#foo>${1}<#----></#noParse>");
+ assertConverted("<#noParse >t</#noParse >", "<#noparse >t</#noparse >");
+
+ assertConvertedSame("<#assign x = 1><#t>");
+ assertConvertedSame("a<#t>\nb");
+ assertConvertedSame("<#t><#nt><#lt><#rt>");
+ assertConvertedSame("<#t ><#nt ><#lt ><#rt >");
+ assertConverted("<#t><#nt><#lt><#rt>", "<#t /><#nt /><#lt /><#rt />");
+
+ assertConvertedSame("<#ftl stripText='true'>\n\n<#macro m>\nx\n</#macro>\n");
}
@Test