freemarker-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ddek...@apache.org
Subject incubator-freemarker git commit: Continued working on FM2 to FM3 converter...
Date Wed, 12 Jul 2017 00:16:48 GMT
Repository: incubator-freemarker
Updated Branches:
  refs/heads/3 17279ba64 -> ea7a08903


Continued working on 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/ea7a0890
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/ea7a0890
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/ea7a0890

Branch: refs/heads/3
Commit: ea7a08903c20730f4020624cbce756bd31c25f30
Parents: 17279ba
Author: ddekany <ddekany@apache.org>
Authored: Wed Jul 12 02:16:30 2017 +0200
Committer: ddekany <ddekany@apache.org>
Committed: Wed Jul 12 02:16:30 2017 +0200

----------------------------------------------------------------------
 .../core/FM2ASTToFM3SourceConverter.java        | 184 +++++++++++--------
 .../apache/freemarker/converter/Converter.java  |   5 +-
 .../converter/FM2ToFM3ConverterCLI.java         |  20 +-
 .../converter/FM2ToFM3ConverterCLITest.java     |   3 +-
 .../converter/FM2ToFM3ConverterTest.java        |  40 ++++
 5 files changed, 175 insertions(+), 77 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ea7a0890/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 4f7ffef..09fa90b 100644
--- a/freemarker-converter/src/main/java/freemarker/core/FM2ASTToFM3SourceConverter.java
+++ b/freemarker-converter/src/main/java/freemarker/core/FM2ASTToFM3SourceConverter.java
@@ -21,7 +21,6 @@ package freemarker.core;
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
@@ -30,7 +29,6 @@ import java.util.Map;
 import java.util.Set;
 
 import org.apache.freemarker.converter.ConversionMarkers;
-import org.apache.freemarker.converter.ConversionMarkers.Type;
 import org.apache.freemarker.converter.ConverterException;
 import org.apache.freemarker.converter.ConverterUtils;
 import org.apache.freemarker.converter.UnconvertableLegacyFeatureException;
@@ -40,7 +38,8 @@ import org.apache.freemarker.core.util._ClassUtil;
 import org.apache.freemarker.core.util._NullArgumentException;
 import org.apache.freemarker.core.util._StringUtil;
 
-import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
 
 import freemarker.template.Configuration;
 import freemarker.template.Template;
@@ -267,7 +266,7 @@ public class FM2ASTToFM3SourceConverter {
         }
     }
 
-    private static final ImmutableList<String> NO_PARSE_FM_2_TAG_NAMES = ImmutableList.of("noparse",
"noParse");
+    private static final Set<String> NO_PARSE_FM_2_TAG_NAMES = ImmutableSet.of("noparse",
"noParse");
 
     private void printComment(Comment node) throws UnexpectedNodeContentException, UnconvertableLegacyFeatureException
{
         print(tagBeginChar);
@@ -342,6 +341,7 @@ public class FM2ASTToFM3SourceConverter {
      * Prints a directive
      */
     private void printDir(TemplateElement node) throws ConverterException {
+        _NullArgumentException.check("node", node);
         if (node instanceof IfBlock) {
             printDirIfElseElseIfContainer((IfBlock) node);
         } else if (node instanceof ConditionalBlock) {
@@ -408,11 +408,26 @@ public class FM2ASTToFM3SourceConverter {
             printDirFallback((FallbackInstruction) node);
         } else if (node instanceof TransformBlock) {
             printDirTransform((TransformBlock) node);
+        } else if (node instanceof OutputFormatBlock) {
+            printDirOutputFormat((OutputFormatBlock) node);
         } else {
             throw new ConverterException("Unhandled AST TemplateElement class: " + node.getClass().getName());
         }
     }
 
+    private void printDirOutputFormat(OutputFormatBlock node) throws ConverterException {
+        printDirStartTagPartBeforeParams(node, "outputFormat");
+        Expression value = getParam(node, 0, ParameterRole.VALUE, Expression.class);
+        printExp(value);
+        printDirStartTagEnd(node, value, false);
+
+        printChildElements(node);
+
+        printDirEndTag(node, OUTPUT_FORMAT_FM2_TAG_NAMES, "outputFormat");
+    }
+
+    private static final Set<String> OUTPUT_FORMAT_FM2_TAG_NAMES = ImmutableSet.of("outputFormat",
"outputformat");
+
     private void printDirTransform(TransformBlock node) throws ConverterException {
         Expression callee = getParam(node, 0, ParameterRole.CALLEE, Expression.class);
 
@@ -440,7 +455,7 @@ public class FM2ASTToFM3SourceConverter {
             pos = printWSAndExpComments(getEndPositionExclusive(paramValue));
         }
 
-        printStartTagEnd(node, pos, false);
+        printDirStartTagEnd(node, pos, false);
 
         printChildElements(node);
 
@@ -482,7 +497,7 @@ public class FM2ASTToFM3SourceConverter {
             lastParam = ns;
         }
 
-        printStartTagEnd(node, lastParam, false);
+        printDirStartTagEnd(node, lastParam, false);
     }
 
     private void printDirCase(Case node) throws ConverterException {
@@ -506,7 +521,7 @@ public class FM2ASTToFM3SourceConverter {
             pos = getEndPositionExclusive(value);
         }
 
-        printStartTagEnd(node, pos, false);
+        printDirStartTagEnd(node, pos, false);
 
         printChildElements(node);
 
@@ -521,7 +536,7 @@ public class FM2ASTToFM3SourceConverter {
         Expression param = getOnlyParam(node, ParameterRole.VALUE, Expression.class);
         printExp(param);
 
-        printStartTagEnd(node, param, false);
+        printDirStartTagEnd(node, param, false);
 
         // FM2 have allowed #case after #default, FM3 doesn't:
         boolean pastDefault = false;
@@ -552,7 +567,7 @@ public class FM2ASTToFM3SourceConverter {
             printExp(message);
             pos = getEndPositionExclusive(message);
         }
-        printStartTagEnd(node, pos, false);
+        printDirStartTagEnd(node, pos, false);
     }
 
     private void printDirSetting(PropertySetting node) throws ConverterException {
@@ -570,7 +585,7 @@ public class FM2ASTToFM3SourceConverter {
         Expression paramValue = getParam(node, 1, ParameterRole.ITEM_VALUE, Expression.class);
         printExp(paramValue);
 
-        printStartTagEnd(node, paramValue, false);
+        printDirStartTagEnd(node, paramValue, false);
     }
 
     private String convertSettingName(String name, TemplateObject node) throws ConverterException
{
@@ -618,7 +633,7 @@ public class FM2ASTToFM3SourceConverter {
                 printOptionalSeparatorAndWSAndExpComments(pos, ",");
             }
         }
-        printStartTagEnd(node, pos, true);
+        printDirStartTagEnd(node, pos, true);
     }
 
     private void printDirBreak(BreakInstruction node) throws ConverterException {
@@ -642,7 +657,7 @@ public class FM2ASTToFM3SourceConverter {
             pos = getPositionAfterIdentifier(pos);
         }
 
-        printStartTagEnd(node, pos, false);
+        printDirStartTagEnd(node, pos, false);
 
         printChildElements(node);
 
@@ -753,7 +768,7 @@ public class FM2ASTToFM3SourceConverter {
         }
     }
 
-    private static final ImmutableList<String> LIST_FM_2_TAG_NAMES = ImmutableList.of("list",
"foreach", "forEach");
+    private static final Set<String> LIST_FM_2_TAG_NAMES = ImmutableSet.of("list",
"foreach", "forEach");
 
     private void printDirInclude(Include node) throws ConverterException {
         assertParamCount(node, 4);
@@ -765,7 +780,8 @@ public class FM2ASTToFM3SourceConverter {
 
         Expression parseParam = getParam(node, 1, ParameterRole.PARSE_PARAMETER, Expression.class);
         if (parseParam != null) {
-            markers.markInSource(parseParam.getBeginLine(), parseParam.getBeginColumn(),
Type.WARN,
+            markers.markInSource(parseParam.getBeginLine(), parseParam.getBeginColumn(),
+                    ConversionMarkers.Type.WARN,
                     "The \"parse\" parameter of #include was removed, as it's not supported
anymore. Use the "
                             + "templateConfigurations configuration setting to specify which
files are not parsed.");
 
@@ -773,7 +789,8 @@ public class FM2ASTToFM3SourceConverter {
 
         Expression encodingParam = getParam(node, 2, ParameterRole.ENCODING_PARAMETER, Expression.class);
         if (encodingParam != null) {
-            markers.markInSource(encodingParam.getBeginLine(), encodingParam.getBeginColumn(),
Type.WARN,
+            markers.markInSource(encodingParam.getBeginLine(), encodingParam.getBeginColumn(),
+                    ConversionMarkers.Type.WARN,
                     "The \"encoding\" parameter of #include was removed, as it's not supported
anymore. Use the "
                             + "templateConfigurations configuration setting to specify which
files has a different "
                             + "encoding than the configured default.");
@@ -851,15 +868,18 @@ public class FM2ASTToFM3SourceConverter {
         print(FTLUtil.escapeIdentifier(getParam(node, 1, ParameterRole.NAMESPACE, String.class)));
         pos = getPositionAfterIdentifier(pos);
 
-        printStartTagEnd(node, pos, false);
+        printDirStartTagEnd(node, pos, false);
     }
 
     private void printDirReturn(ReturnInstruction node) throws ConverterException {
-        printDirStartTagPartBeforeParams(node, "return");
+        int pos = printDirStartTagPartBeforeParams(node, "return");
 
         Expression value = getOnlyParam(node, ParameterRole.VALUE, Expression.class);
-        printExp(value);
-        printStartTagEnd(node, value, false);
+        if (value != null) {
+            printExp(value);
+            pos = getEndPositionExclusive(value);
+        }
+        printDirStartTagEnd(node, pos, false);
     }
 
     private void printDirFlush(FlushInstruction node) throws ConverterException {
@@ -870,7 +890,7 @@ public class FM2ASTToFM3SourceConverter {
         printDirGenericNoParamsHasNested(node, NO_ESCAPE_FM_2_TAG_NAMES, "noEscape");
     }
 
-    private static final ImmutableList<String> NO_ESCAPE_FM_2_TAG_NAMES = ImmutableList.of("noescape",
"noEscape");
+    private static final Set<String> NO_ESCAPE_FM_2_TAG_NAMES = ImmutableSet.of("noescape",
"noEscape");
 
     private void printDirEscape(EscapeBlock node) throws ConverterException {
         assertParamCount(node, 2);
@@ -884,7 +904,7 @@ public class FM2ASTToFM3SourceConverter {
 
         Expression expTemplate = getParam(node, 1, ParameterRole.EXPRESSION_TEMPLATE, Expression.class);
         printExp(expTemplate);
-        printStartTagEnd(node, expTemplate, false);
+        printDirStartTagEnd(node, expTemplate, false);
 
         printChildElements(node);
 
@@ -899,27 +919,26 @@ public class FM2ASTToFM3SourceConverter {
         printDirGenericNoParamsHasNested(node, AUTO_ESC_FM_2_TAG_NAMES, "autoEsc");
     }
 
-    private static final ImmutableList<String> AUTO_ESC_FM_2_TAG_NAMES = ImmutableList.of("autoesc",
"autoEsc");
+    private static final Set<String> AUTO_ESC_FM_2_TAG_NAMES = ImmutableSet.of("autoesc",
"autoEsc");
 
     private void printDirNoAutoEsc(NoAutoEscBlock node) throws ConverterException {
         printDirGenericNoParamsHasNested(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 static final Set<String> NO_AUTO_ESC_FM_2_TAG_NAMES = ImmutableSet.of("noautoesc",
"noAutoEsc");
 
     private void printDirGenericNoParamsHasNested(TemplateElement node, String fm3TagName)
             throws ConverterException {
         printDirGenericNoParamsHasNested(node, Collections.singleton(fm3TagName), fm3TagName);
     }
 
-    private void printDirGenericNoParamsHasNested(TemplateElement node,
-            Collection<String> fm2TagName, String fm3TagName)
+    private void printDirGenericNoParamsHasNested(TemplateElement node, Set<String>
fm2TagNames, String fm3TagName)
             throws ConverterException {
         assertParamCount(node, 0);
 
         printDirStartTagNoParamsHasNested(node, fm3TagName);
         printChildElements(node);
-        printDirEndTag(node, fm2TagName, fm3TagName);
+        printDirEndTag(node, fm2TagNames, fm3TagName);
     }
 
     private void printDirGenericNoParamsNoNested(TemplateElement node, String name)
@@ -945,7 +964,7 @@ public class FM2ASTToFM3SourceConverter {
         printDirEndTag(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 static final Set<String> ATTEMPT_RECOVER_FM_2_TAG_NAMES = ImmutableSet.of("attempt",
"recover");
 
     private void printDirAssignmentMultiple(AssignmentInstruction node) throws ConverterException
{
         assertParamCount(node, 2);
@@ -987,7 +1006,7 @@ public class FM2ASTToFM3SourceConverter {
             pos = getEndPositionExclusive(namespace);
         }
 
-        printStartTagEnd(node, pos, true);
+        printDirStartTagEnd(node, pos, true);
 
         printChildElements(node);
 
@@ -1002,11 +1021,8 @@ public class FM2ASTToFM3SourceConverter {
             printExp(ns);
             pos = getEndPositionExclusive(ns);
         }
-        pos = printWSAndExpComments(pos);
 
-        char c = src.charAt(pos);
-        assertNodeContent(c == tagEndChar, node, "End of tag was expected, but found {}",
c);
-        print(tagEndChar);
+        printDirStartTagEnd(node, pos, false);
     }
 
     private int printDirAssignmentCommonTagTillAssignmentExp(TemplateElement node, int scopeParamIdx)
@@ -1229,7 +1245,7 @@ public class FM2ASTToFM3SourceConverter {
         if (legacyCallDirMode) {
             print('/');
         }
-        int startTagEndPos = printStartTagEnd(node, pos, false);
+        int startTagEndPos = printDirStartTagEnd(node, pos, false);
 
         int elementEndPos = getEndPositionInclusive(node);
         {
@@ -1282,7 +1298,7 @@ public class FM2ASTToFM3SourceConverter {
         if (conditionExp != null) {
             printDirStartTagPartBeforeParams(node, tagName);
             printNode(conditionExp);
-            printStartTagEnd(node, conditionExp, true);
+            printDirStartTagEnd(node, conditionExp, true);
         } else {
             printDirStartTagNoParamsHasNested(node, tagName);
         }
@@ -1304,6 +1320,7 @@ public class FM2ASTToFM3SourceConverter {
      * Prints an expression
      */
     private void printExp(Expression node) throws ConverterException {
+        _NullArgumentException.check("node", node);
         if (node instanceof Identifier) {
             printExpIdentifier((Identifier) node);
         } else if (node instanceof NumberLiteral) {
@@ -1349,6 +1366,7 @@ public class FM2ASTToFM3SourceConverter {
         } else if (node instanceof ExistsExpression) {
             printExpExists((ExistsExpression) node);
         } else {
+
             throw new ConverterException("Unhandled AST node expression class: " + node.getClass().getName());
         }
     }
@@ -1650,37 +1668,39 @@ public class FM2ASTToFM3SourceConverter {
     }
 
     private void printExpBuiltIn(BuiltIn node) throws ConverterException {
-        assertParamCount(node, 2);
         Expression lho = getParam(node, 0, ParameterRole.LEFT_HAND_OPERAND, Expression.class);
         String rho = getParam(node, 1, ParameterRole.RIGHT_HAND_OPERAND, String.class);
 
-        printExp(lho); // [lho]?biName
+        // <lho>?biName
+        printExp(lho);
+        int pos = getEndPositionExclusive(lho);
+
+        // lho<?>biName
+        pos = printSeparatorAndWSAndExpComments(pos, "?");
 
-        int postLHOPos = getEndPositionExclusive(lho);
-        int endPos = getEndPositionInclusive(node);
-        boolean foundQuestionMark = false;
-        int pos = postLHOPos;
-        scanForRHO:
-        while (pos < endPos) {
-            char c = src.charAt(pos);
-            if (c == '?') {
-                foundQuestionMark = true;
-                pos++;
-            } else if (Character.isWhitespace(c)) {
-                pos++;
-            } else if (isCoreNameChar(c)) {
-                break scanForRHO;
-            } else {
-                throw new UnexpectedNodeContentException(node,
-                        "Unexpected character when scanning for for built-in key: {}", c);
+        // lho?<biName>
+        print(convertBuiltInName(rho));
+
+        if (node instanceof BuiltInWithParseTimeParameters) {
+            // lho?biName<(>
+            pos = getPositionAfterIdentifier(pos);
+            pos = printSeparatorAndWSAndExpComments(pos, "(");
+            int paramCnt = node.getParameterCount();
+            for (int paramIdx = 2; paramIdx < paramCnt; paramIdx++) {
+                Expression argValue = getParam(node, paramIdx, ParameterRole.ARGUMENT_VALUE,
Expression.class);
+                printExp(argValue);
+                pos = getEndPositionExclusive(argValue);
+
+                if (paramIdx + 1 < paramCnt) {
+                    printSeparatorAndWSAndExpComments(pos, ",");
+                }
             }
+            pos = printSeparatorAndWSAndExpComments(pos, ")");
+            assertNodeContent(pos == getEndPositionExclusive(node), node,
+                    "Actual end position doesn't match node end position.");
+        } else {
+            assertParamCount(node, 2);
         }
-        if (pos == endPos || !foundQuestionMark) {
-            throw new UnexpectedNodeContentException(node, "Couldn't find built-in key in
source", null);
-        }
-        print(src.substring(postLHOPos, pos)); // lho[?]biName
-
-        print(convertBuiltInName(rho));
     }
 
     private void printExpStringLiteral(StringLiteral node) throws ConverterException {
@@ -1740,10 +1760,9 @@ public class FM2ASTToFM3SourceConverter {
     }
 
     private String convertBuiltInName(String name) throws ConverterException {
-        String converted = name.indexOf('_') == -1 ? name : ConverterUtils.snakeCaseToCamelCase(name);
-
-        if (converted.equals("webSafe")) {
-            return "html";
+        String converted = IRREGULAR_BUILT_IN_NAME_CONVERSIONS.get(name);
+        if (converted == null) {
+            converted = name.indexOf('_') == -1 ? name : ConverterUtils.snakeCaseToCamelCase(name);
         }
 
         if (!fm3BuiltInNames.contains(converted)) {
@@ -1753,6 +1772,24 @@ public class FM2ASTToFM3SourceConverter {
         return converted;
     }
 
+    private static Map<String, String> IRREGULAR_BUILT_IN_NAME_CONVERSIONS = new ImmutableMap.Builder<String,
String>()
+            .put("webSafe", "html")
+            .put("web_safe", "html")
+            .put("iso_utc_fz", "isoUtcFZ")
+            .put("iso_utc_nz", "isoUtcNZ")
+            .put("iso_utc_ms_nz", "isoUtcMsNZ")
+            .put("iso_utc_m_nz", "isoUtcMNZ")
+            .put("iso_utc_h_nz", "isoUtcHNZ")
+            .put("iso_local_nz", "isoLocalNZ")
+            .put("iso_local_ms_nz", "isoLocalMsNZ")
+            .put("iso_local_m_nz", "isoLocalMNZ")
+            .put("iso_local_h_nz", "isoLocalHNZ")
+            .put("iso_nz", "isoNZ")
+            .put("iso_ms_nz", "isoMsNZ")
+            .put("iso_m_nz", "isoMNZ")
+            .put("iso_h_nz", "isoHNZ")
+            .build();
+
     private void printParameterSeparatorSource(Expression lho, Expression rho) {
         print(getSrcSectionExclEnd(
                 lho.getEndColumn() + 1, lho.getEndLine(),
@@ -1793,7 +1830,7 @@ public class FM2ASTToFM3SourceConverter {
     private int printDirStartTagNoParams(TemplateElement node, String fm3TagName, boolean
removeSlash)
             throws ConverterException {
         int pos = printDirStartTagPartBeforeParams(node, fm3TagName);
-        printStartTagEnd(node, pos, removeSlash);
+        printDirStartTagEnd(node, pos, removeSlash);
         return pos + 1;
     }
 
@@ -1801,21 +1838,20 @@ public class FM2ASTToFM3SourceConverter {
         printDirEndTag(node, Collections.singleton(tagName), tagName);
     }
 
-    private void printDirEndTag(TemplateElement node, Collection<String> fm2TagName,
String fm3TagName) throws
+    private void printDirEndTag(TemplateElement node, Set<String> fm2TagNames, String
fm3TagName) throws
             UnexpectedNodeContentException {
-        if (fm2TagName.size() == 0) {
+        if (fm2TagNames.size() == 0) {
             throw new IllegalArgumentException("You must specify at least 1 FM2 tag names");
         }
-        if (fm2TagName.size() == 1 && containsUpperCaseLetter(fm3TagName)) {
+        if (fm2TagNames.size() == 1 && containsUpperCaseLetter(fm3TagName)) {
             throw new IllegalArgumentException(
                     "You must specify multiple FM2 tag names when the FM3 tag name ("
                     + fm3TagName + ") contains upper case letters");
         }
-        printDirEndTag(node, fm2TagName, fm3TagName, false);
+        printDirEndTag(node, fm2TagNames, fm3TagName, false);
     }
 
-    private void printDirEndTag(TemplateElement node, Collection<String> fm2TagNames,
String fm3TagName,
-            boolean optional)
+    private void printDirEndTag(TemplateElement node, Set<String> fm2TagNames, String
fm3TagName, boolean optional)
             throws UnexpectedNodeContentException {
         int tagEndPos = getEndPositionInclusive(node);
         {
@@ -1900,10 +1936,10 @@ public class FM2ASTToFM3SourceConverter {
      * @return The position of the last character of the start tag. Note that the printed
string never includes this
      * character.
      */
-    private int printStartTagEnd(TemplateElement node, Expression lastParam, boolean trimSlash)
+    private int printDirStartTagEnd(TemplateElement node, Expression lastParam, boolean trimSlash)
             throws ConverterException {
         _NullArgumentException.check("lastParam", lastParam);
-        return printStartTagEnd(
+        return printDirStartTagEnd(
                 node,
                 getPosition(lastParam.getEndColumn() + 1, lastParam.getEndLine()),
                 trimSlash);
@@ -1932,13 +1968,13 @@ public class FM2ASTToFM3SourceConverter {
     }
 
     /**
-     * Similar to {@link #printStartTagEnd(TemplateElement, Expression, boolean)}, but with
explicitly
+     * Similar to {@link #printDirStartTagEnd(TemplateElement, Expression, boolean)}, but
with explicitly
      * specified scan start position.
      *
      * @param pos
      *         The position where the first skipped character can occur (or the tag end character).
      */
-    private int printStartTagEnd(TemplateElement node, int pos, boolean removeSlash)
+    private int printDirStartTagEnd(TemplateElement node, int pos, boolean removeSlash)
             throws ConverterException {
         final int startPos = pos;
 

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ea7a0890/freemarker-converter/src/main/java/org/apache/freemarker/converter/Converter.java
----------------------------------------------------------------------
diff --git a/freemarker-converter/src/main/java/org/apache/freemarker/converter/Converter.java
b/freemarker-converter/src/main/java/org/apache/freemarker/converter/Converter.java
index 3d4d4f6..514ffe0 100644
--- a/freemarker-converter/src/main/java/org/apache/freemarker/converter/Converter.java
+++ b/freemarker-converter/src/main/java/org/apache/freemarker/converter/Converter.java
@@ -179,7 +179,10 @@ public abstract class Converter {
 
         prepare();
         LOG.debug("Source: {}", source);
-        LOG.debug("Destination directory: {}", destinationDirectory);
+        LOG.debug("DestinationDirectory: {}", destinationDirectory);
+        LOG.debug("CreateDestinationDirectory: {}", createDestinationDirectory);
+        LOG.debug("Include: {}", include);
+        LOG.debug("Exclude: {}", exclude);
 
         // Just so that no confusing marker file remains there:
         File markerFile = new File(destinationDirectory, CONVERSION_MARKERS_FILE_NAME);

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ea7a0890/freemarker-converter/src/main/java/org/apache/freemarker/converter/FM2ToFM3ConverterCLI.java
----------------------------------------------------------------------
diff --git a/freemarker-converter/src/main/java/org/apache/freemarker/converter/FM2ToFM3ConverterCLI.java
b/freemarker-converter/src/main/java/org/apache/freemarker/converter/FM2ToFM3ConverterCLI.java
index d17c113..208a727 100644
--- a/freemarker-converter/src/main/java/org/apache/freemarker/converter/FM2ToFM3ConverterCLI.java
+++ b/freemarker-converter/src/main/java/org/apache/freemarker/converter/FM2ToFM3ConverterCLI.java
@@ -23,6 +23,8 @@ import java.io.File;
 import java.io.PrintWriter;
 import java.util.Arrays;
 import java.util.List;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
 
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.DefaultParser;
@@ -126,6 +128,12 @@ public class FM2ToFM3ConverterCLI {
                 if (cl.hasOption(CREATE_DESTINATION_OPTION)) {
                     converter.setCreateDestinationDirectory(true);
                 }
+                if (cl.hasOption(INCLUDE_OPTION)) {
+                    converter.setInclude(getRegexpOption(cl, INCLUDE_OPTION));
+                }
+                if (cl.hasOption(EXCLUDE_OPTION)) {
+                    converter.setExclude(getRegexpOption(cl, EXCLUDE_OPTION));
+                }
                 converter.setFreeMarker2Settings(cl.getOptionProperties(FREEMARKER_2_SETTING_OPTION_SHORT));
                 try {
                     converter.execute();
@@ -136,7 +144,7 @@ public class FM2ToFM3ConverterCLI {
                         printWrapped("Conversion was finished successfully. "
                                 + "Converted " + converter.getConvertedFileCount() + " file(s).");
                     }
-                } catch (Throwable e) {
+                } catch (ConverterException e) {
                     printWrapped("Conversion was terminated with error. See details in the
Java stack "
                             + "trace:\n");
                     printConciseStackTrace(e);
@@ -152,6 +160,16 @@ public class FM2ToFM3ConverterCLI {
         return SUCCESS_EXIT_STATUS;
     }
 
+    private Pattern getRegexpOption(CommandLine cl, String optionName) throws ParseException
{
+        String optionValue = cl.getOptionValue(optionName);
+        try {
+            return Pattern.compile(optionValue);
+        } catch (PatternSyntaxException e) {
+            throw new ParseException(
+                    "The value of the \"" + optionName + "\" is not a valid regular expression:
" + optionValue);
+        }
+    }
+
     private void printConciseStackTrace(Throwable e) {
         boolean first = true;
         while (e != null) {

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ea7a0890/freemarker-converter/src/test/java/org/freemarker/converter/FM2ToFM3ConverterCLITest.java
----------------------------------------------------------------------
diff --git a/freemarker-converter/src/test/java/org/freemarker/converter/FM2ToFM3ConverterCLITest.java
b/freemarker-converter/src/test/java/org/freemarker/converter/FM2ToFM3ConverterCLITest.java
index 982cccf..2d794d6 100644
--- a/freemarker-converter/src/test/java/org/freemarker/converter/FM2ToFM3ConverterCLITest.java
+++ b/freemarker-converter/src/test/java/org/freemarker/converter/FM2ToFM3ConverterCLITest.java
@@ -77,7 +77,8 @@ public class FM2ToFM3ConverterCLITest extends ConverterTest {
                 srcDir.toString(), "-d", dstDir.toString(),
                 "--include", ".*", "--exclude", ".*2\\.ftl");
         assertTrue(new File(dstDir, "1.fm3").exists());
-        assertFalse(new File(dstDir, "3.txt").exists());
+        assertFalse(new File(dstDir, "2.fm3").exists());
+        assertTrue(new File(dstDir, "3.txt").exists());
     }
 
     public void assertCLIResult(int expectedExitStatus, String stdoutContains, String stdoutNotContains,
String...

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ea7a0890/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 07af58b..4852604 100644
--- a/freemarker-converter/src/test/java/org/freemarker/converter/FM2ToFM3ConverterTest.java
+++ b/freemarker-converter/src/test/java/org/freemarker/converter/FM2ToFM3ConverterTest.java
@@ -25,7 +25,9 @@ import static org.junit.Assert.*;
 
 import java.io.File;
 import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
 import java.util.Properties;
+import java.util.Set;
 
 import org.apache.commons.io.FileUtils;
 import org.apache.freemarker.converter.ConverterException;
@@ -34,6 +36,8 @@ import org.apache.freemarker.converter.UnconvertableLegacyFeatureException;
 import org.freemarker.converter.test.ConverterTest;
 import org.junit.Test;
 
+import com.google.common.collect.ImmutableSet;
+
 import freemarker.template.Configuration;
 
 public class FM2ToFM3ConverterTest extends ConverterTest {
@@ -198,6 +202,7 @@ public class FM2ToFM3ConverterTest extends ConverterTest {
         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("<#macro m><#return><#return ></#macro>");
 
         assertConvertedSame("<#assign x = 1>");
         assertConvertedSame("<#global x = 1>");
@@ -213,6 +218,7 @@ public class FM2ToFM3ConverterTest extends ConverterTest {
         assertConvertedSame("<#assign <#--0-->x = 1<#--1-->,<#--2-->y++<#--3-->z/=2<#--4-->>");
         // 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 = 1/>");
 
         assertConvertedSame("<#assign x>t</#assign>");
         assertConvertedSame("<#assign x in ns>t</#assign>");
@@ -362,6 +368,8 @@ public class FM2ToFM3ConverterTest extends ConverterTest {
         assertConvertedSame("<#recurse node <#--1--> using <#--2--> ns <#--3-->>");
         assertConvertedSame("<#macro m><#fallback></#macro>");
         assertConvertedSame("<#macro m><#fallback /></#macro>");
+
+        assertConvertedSame("<#outputFormat 'HTML'>${x}</#outputFormat>");
     }
 
     @Test
@@ -412,6 +420,35 @@ public class FM2ToFM3ConverterTest extends ConverterTest {
         assertConverted("${s?upperCase} ${s?leftPad(123)}", "${s?upper_case} ${s?left_pad(123)}");
         assertConverted("${s?html}", "${s?web_safe}");
         assertConvertedSame("${s  ?   upperCase\t?\t\tleftPad(5)}");
+        assertConvertedSame("${s <#--1--> ? <#--2--> upperCase}");
+        // Runtime params:
+        assertConvertedSame("${s?leftPad(9)}");
+        // Parse time params:
+        assertConvertedSame("${s?then(1, 2)}");
+        assertConvertedSame("${s?switch(1, 'one', 2, 'two', 'more')}");
+        assertConvertedSame("${s?then <#--1--> ( <#--2--> 1 <#--3-->, <#--5-->
2 <#--6--> )}");
+    }
+
+    /** Tests if the names of all current FM2 built-ins can be converted to FM3 names. */
+    @Test
+    public void testBuiltInNameConversion()
+            throws NoSuchMethodException, InvocationTargetException, IllegalAccessException,
IOException,
+            ConverterException {
+        Configuration cfg = new Configuration(Configuration.getVersion());
+
+        StringBuilder sb = new StringBuilder();
+        sb.append("<#outputformat 'HTML'><#list xs as x>");
+        for (String builtInName : cfg.getSupportedBuiltInNames(Configuration.LEGACY_NAMING_CONVENTION))
{
+            if (!LEGACY_ESCAPING_BUTILT_INS.contains(builtInName)) {
+                sb.append("${x?").append(builtInName).append("(1, 2)").append("}");
+            }
+        }
+        sb.append("</#list></#outputformat>");
+        for (String builtInName : LEGACY_ESCAPING_BUTILT_INS) {
+            sb.append("${x?").append(builtInName).append("}");
+        }
+
+        convert(sb.toString());
     }
 
     @Test
@@ -476,6 +513,9 @@ public class FM2ToFM3ConverterTest extends ConverterTest {
         assertTrue(new File(dstDir, "t10.Foo3").exists());
     }
 
+    private static final Set<String> LEGACY_ESCAPING_BUTILT_INS = ImmutableSet.of(
+            "html", "xml", "xhtml", "rtf", "web_safe");
+
     private void assertConvertedSame(String ftl2) throws IOException, ConverterException
{
         assertConverted(ftl2, ftl2);
     }


Mime
View raw message