Repository: incubator-freemarker
Updated Branches:
  refs/heads/3 2548f5cdc -> c5feb6328


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

Branch: refs/heads/3
Commit: c5feb6328a6f6dc027c52eda5bfe62ad0d967a87
Parents: 2548f5c
Author: ddekany <ddek...@apache.org>
Authored: Fri Jun 30 01:19:05 2017 +0200
Committer: ddekany <ddek...@apache.org>
Committed: Fri Jun 30 01:19:05 2017 +0200

----------------------------------------------------------------------
 .../core/FM2ASTToFM3SourceConverter.java        | 115 ++++++++++++++++++-
 .../converter/FM2ToFM3ConverterTest.java        |  18 +++
 2 files changed, 129 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/c5feb632/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 7f8a2da..13a80ac 100644
--- 
a/freemarker-converter/src/main/java/freemarker/core/FM2ASTToFM3SourceConverter.java
+++ 
b/freemarker-converter/src/main/java/freemarker/core/FM2ASTToFM3SourceConverter.java
@@ -20,7 +20,9 @@
 package freemarker.core;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.freemarker.converter.ConverterException;
@@ -382,11 +384,101 @@ public class FM2ASTToFM3SourceConverter {
             printExpBuiltinVariable((BuiltinVariable) node);
         } else if (node instanceof Dot) {
             printExpDot((Dot) node);
+        } else if (node instanceof ComparisonExpression) {
+            printExpComparison((ComparisonExpression) node);
+        } else if (node instanceof AndExpression) {
+            printExpAnd((AndExpression) node);
+        } else if (node instanceof OrExpression) {
+            printExpOr((OrExpression) node);
+        } else if (node instanceof NotExpression) {
+            printExpNot((NotExpression) node);
         } else {
-            throw new ConverterException("Unhandled AST node class: " + 
node.getClass().getName());
+            throw new ConverterException("Unhandled AST node expression class: 
" + node.getClass().getName());
         }
     }
 
+    private void printExpNot(NotExpression node) throws ConverterException {
+        printWithParamsLeadingSkippedTokens("!", node);
+        printNode(getOnlyParam(node, ParameterRole.RIGHT_HAND_OPERAND, 
Expression.class));
+    }
+
+    private static final Map<String, String> COMPARATOR_OP_MAP;
+    static {
+        COMPARATOR_OP_MAP = new HashMap<String, String>();
+        // For now we leave FM2 ops as is, but later in many cases they will 
be replaced.
+        COMPARATOR_OP_MAP.put("==", "==");
+        COMPARATOR_OP_MAP.put("=", "=");
+        COMPARATOR_OP_MAP.put("!=", "!=");
+        COMPARATOR_OP_MAP.put("<", "<");
+        COMPARATOR_OP_MAP.put("lt", "lt");
+        COMPARATOR_OP_MAP.put("\\lt", "\\lt");
+        COMPARATOR_OP_MAP.put("&lt;", "&lt;");
+        COMPARATOR_OP_MAP.put("<=", "<=");
+        COMPARATOR_OP_MAP.put("lte", "lte");
+        COMPARATOR_OP_MAP.put("\\lte", "\\lte");
+        COMPARATOR_OP_MAP.put("&lt;=", "&lt;=");
+        COMPARATOR_OP_MAP.put(">", ">");
+        COMPARATOR_OP_MAP.put("gt", "gt");
+        COMPARATOR_OP_MAP.put("\\gt", "\\gt");
+        COMPARATOR_OP_MAP.put("&gt;", "&gt;");
+        COMPARATOR_OP_MAP.put(">=", ">=");
+        COMPARATOR_OP_MAP.put("gte", "gte");
+        COMPARATOR_OP_MAP.put("\\gte", "\\gte");
+        COMPARATOR_OP_MAP.put("&gt;=", "&gt;=");
+    }
+
+    private void printExpComparison(ComparisonExpression node) throws 
ConverterException {
+        printExpBinaryWithMappedOperator(node, COMPARATOR_OP_MAP);
+    }
+
+    private static final Map<String, String> AND_OP_MAP;
+    static {
+        AND_OP_MAP = new HashMap<String, String>();
+        // For now we leave FM2 ops as is, but later in many cases they will 
be replaced.
+        AND_OP_MAP.put("&&", "&&");
+        AND_OP_MAP.put("&", "&");
+        AND_OP_MAP.put("\\and", "\\and");
+        AND_OP_MAP.put("&amp;&amp;", "&amp;&amp;");
+    }
+
+    private void printExpAnd(AndExpression node) throws ConverterException {
+        printExpBinaryWithMappedOperator(node, AND_OP_MAP);
+    }
+
+    private static final Map<String, String> OR_OP_MAP;
+    static {
+        OR_OP_MAP = new HashMap<String, String>();
+        // For now we leave FM2 ops as is, but later in many cases they will 
be replaced.
+        OR_OP_MAP.put("||", "||");
+        OR_OP_MAP.put("|", "|");
+    }
+
+    private void printExpOr(OrExpression node) throws ConverterException {
+        printExpBinaryWithMappedOperator(node, OR_OP_MAP);
+    }
+
+    private void printExpBinaryWithMappedOperator(Expression node, Map<String, 
String> operatorMapper) throws
+            ConverterException {
+        assertParamCount(node, 2);
+        Expression lho = getParam(node, 0, ParameterRole.LEFT_HAND_OPERAND, 
Expression.class);
+        Expression rho = getParam(node, 1, ParameterRole.RIGHT_HAND_OPERAND, 
Expression.class);
+
+        printExp(lho);
+
+        int lhoEndExcl = getEndPositionExclusive(lho);
+        int opStart = getPositionAfterWSAndExpComments(lhoEndExcl);
+        printWithConvertedExpComments(src.substring(lhoEndExcl, opStart));
+        final String fm2Op = readUntilWSOrComment(opStart);
+        String fm3Op = operatorMapper.get(fm2Op);
+        if (fm3Op == null) {
+            throw new UnexpectedNodeContentException(node, "Unhandled 
operator: {}", fm2Op);
+        }
+        print(fm3Op);
+        printWithConvertedExpComments(src.substring(opStart + fm2Op.length(), 
getStartPosition(rho)));
+
+        printExp(rho);
+    }
+
     private void printExpBuiltinVariable(BuiltinVariable node) throws 
ConverterException {
         int startPos = getStartPosition(node);
         String sep = readExpWSAndSeparator(startPos, '.', false);
@@ -933,9 +1025,8 @@ public class FM2ASTToFM3SourceConverter {
     private int getPositionAfterWSAndExpComments(int pos) throws 
ConverterException {
         scanForNoWSNoComment: while (pos < src.length()) {
             char c = src.charAt(pos);
-            if ((c == '<' || c == '[')
-                    && (src.startsWith("!--", pos + 1) || 
src.startsWith("#--", pos + 1))) {
-                pos += 4;
+            if (isExpCommentStart(pos)) {
+                pos += 4; // length of "<#--"
                 scanForCommentEnd:
                 while (pos < src.length()) {
                     if (src.startsWith("-->", pos) || src.startsWith("--]", 
pos)) {
@@ -994,4 +1085,20 @@ public class FM2ASTToFM3SourceConverter {
         return src.substring(startPos, pos);
     }
 
+    private String readUntilWSOrComment(int startPos) throws 
ConverterException {
+        int pos = startPos;
+        while (pos < src.length() && !Character.isWhitespace(src.charAt(pos)) 
&& !isExpCommentStart(pos)) {
+            pos++;
+        }
+        return src.substring(startPos, pos);
+    }
+
+    private boolean isExpCommentStart(int pos) {
+        char c = src.charAt(pos);
+        return (c == '<' || c == '[')
+                && (pos + 1 < src.length()
+                && src.startsWith("!--", pos + 1) || src.startsWith("#--", pos 
+ 1));
+
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/c5feb632/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 936c516..54abfd2 100644
--- 
a/freemarker-converter/src/test/java/org/freemarker/converter/FM2ToFM3ConverterTest.java
+++ 
b/freemarker-converter/src/test/java/org/freemarker/converter/FM2ToFM3ConverterTest.java
@@ -106,6 +106,24 @@ public class FM2ToFM3ConverterTest extends ConverterTest {
         assertConvertedSame("${.outputFormat}");
         assertConvertedSame("${. <#-- C --> outputFormat}");
         assertConverted("${.outputFormat}","${.output_format}");
+
+        assertConvertedSame("${a < b}${a <= b}${(a > b)}${(a >= b)}${a == 
b}${a != b}");
+        assertConvertedSame("${a<#-- C1 --><<#-- C2 -->b}${a<#-- C3 --><=<#-- 
C4 -->b}"
+                + "${(a<#-- C7 -->><#-- C8 -->b)}${(a<#-- C9 -->>=<#-- CA 
-->b)}"
+                + "${a<#-- CB -->==<#-- CC -->b}${a<#-- CD -->!=<#-- CE 
-->b}");
+        // "Same" for now, will be different later.
+        assertConvertedSame("${a = b}${a == b}");
+        assertConvertedSame("${a &lt; b}${a lt b}${a \\lt b}");
+        assertConvertedSame("${a &lt;= b}${a lte b}${a \\lte b}");
+        assertConvertedSame("${a &gt; b}${a gt b}${a \\gt b}");
+        assertConvertedSame("${a &gt;= b}${a gte b}${a \\gte b}");
+
+        // [FM3] Add \and and &amp;&amp; tests when 2.3.27 is released
+        assertConvertedSame("${a && b}${a & b}${a || b}${a | b}");
+        assertConvertedSame("${a<#-- C1 -->&&<#-- C2 -->b}${a<#-- C3 -->&<#-- 
C4 -->b}"
+                + "${a<#-- C5 -->||<#-- C6 -->b}${a<#-- C7 -->|<#-- C8 -->b}");
+
+        assertConvertedSame("${!a}${! foo}${! <#-- C1 --> bar}${!!c}");
     }
 
     @Test

Reply via email to