Better error message when <#assign x++> and such fails because x doesn't exist 
in the same scope as the target scope.


Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/470971a2
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/470971a2
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/470971a2

Branch: refs/heads/2.3
Commit: 470971a2381fceee421337a7a5070d500c2b0d4a
Parents: afccb10
Author: ddekany <ddek...@apache.org>
Authored: Tue Mar 20 18:55:31 2018 +0100
Committer: ddekany <ddek...@apache.org>
Committed: Tue Mar 20 18:55:31 2018 +0100

----------------------------------------------------------------------
 src/main/java/freemarker/core/Assignment.java          | 13 +++++++++++--
 .../freemarker/core/InvalidReferenceException.java     |  6 +++---
 .../java/freemarker/core/MiscErrorMessagesTest.java    |  7 +++++++
 3 files changed, 21 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/470971a2/src/main/java/freemarker/core/Assignment.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/Assignment.java 
b/src/main/java/freemarker/core/Assignment.java
index 0f15112..0495f14 100644
--- a/src/main/java/freemarker/core/Assignment.java
+++ b/src/main/java/freemarker/core/Assignment.java
@@ -152,7 +152,7 @@ final class Assignment extends TemplateElement {
                     if (env.isClassicCompatible()) {
                         lhoValue = TemplateScalarModel.EMPTY_STRING;
                     } else {
-                        throw InvalidReferenceException.getInstance(
+                        throw InvalidReferenceException.getInstance(scope,
                                 variableName, getOperatorTypeAsString(), env);
                     }
                 }
@@ -171,7 +171,7 @@ final class Assignment extends TemplateElement {
                 if (lhoValue instanceof TemplateNumberModel) {
                     lhoNumber = EvalUtil.modelToNumber((TemplateNumberModel) 
lhoValue, null);
                 } else if (lhoValue == null) {
-                    throw InvalidReferenceException.getInstance(variableName, 
getOperatorTypeAsString(), env);
+                    throw InvalidReferenceException.getInstance(scope, 
variableName, getOperatorTypeAsString(), env);
                 } else {
                     throw new NonNumericalException(variableName, lhoValue, 
null, env);
                 }
@@ -292,4 +292,13 @@ final class Assignment extends TemplateElement {
         }
     }
     
+    static String scopeAsString(int scope) {
+        switch (scope) {
+        case NAMESPACE: return "template namespace";
+        case LOCAL: return "local scope";
+        case GLOBAL: return "global scope";
+        default: throw new AssertionError("Unsupported scope: " + scope);
+        }
+    }
+    
 }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/470971a2/src/main/java/freemarker/core/InvalidReferenceException.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/InvalidReferenceException.java 
b/src/main/java/freemarker/core/InvalidReferenceException.java
index 791263b..d6a75bf 100644
--- a/src/main/java/freemarker/core/InvalidReferenceException.java
+++ b/src/main/java/freemarker/core/InvalidReferenceException.java
@@ -141,7 +141,7 @@ public class InvalidReferenceException extends 
TemplateException {
     /**
      * Used for assignments that use operators like {@code +=}, when the 
target variable was null/missing. 
      */
-    static InvalidReferenceException getInstance(String 
missingAssignedVarName, String assignmentOperator,
+    static InvalidReferenceException getInstance(int scope, String 
missingAssignedVarName, String assignmentOperator,
             Environment env) {
         if (env != null && env.getFastInvalidReferenceExceptions()) {
             return FAST_INSTANCE;
@@ -149,8 +149,8 @@ public class InvalidReferenceException extends 
TemplateException {
             final _ErrorDescriptionBuilder errDescBuilder = new 
_ErrorDescriptionBuilder(
                             "The target variable of the assignment, ",
                             new _DelayedJQuote(missingAssignedVarName),
-                            ", was null or missing, but the \"",
-                            assignmentOperator, "\" operator needs to get its 
value before assigning to it."
+                            ", was null or missing in the " + 
Assignment.scopeAsString(scope) + ", and the \"",
+                            assignmentOperator, "\" operator must get its 
value from there before assigning to it."
                     );
             if (missingAssignedVarName.startsWith("$")) {
                 errDescBuilder.tips(TIP_NO_DOLLAR, 
TIP_MISSING_ASSIGNMENT_TARGET);

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/470971a2/src/test/java/freemarker/core/MiscErrorMessagesTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/core/MiscErrorMessagesTest.java 
b/src/test/java/freemarker/core/MiscErrorMessagesTest.java
index 5799c12..df10fde 100644
--- a/src/test/java/freemarker/core/MiscErrorMessagesTest.java
+++ b/src/test/java/freemarker/core/MiscErrorMessagesTest.java
@@ -56,4 +56,11 @@ public class MiscErrorMessagesTest extends TemplateTest {
         assertEquals((Integer) 2, ((TemplateException) e).getLineNumber());
     }
     
+    @Test
+    public void incrementalAssignmentsTest() throws Exception {
+        assertErrorContains("<#assign x++>", "\"x\"", "++", "template 
namespace");
+        assertErrorContains("<#global x += 2>", "\"x\"", "+=", "global scope");
+        assertErrorContains("<#macro m><#local x--></#macro><@m/>", "\"x\"", 
"--", "local scope");
+    }
+    
 }

Reply via email to