Repository: incubator-freemarker Updated Branches: refs/heads/3 0d21cbb77 -> 421f4747b
Forward ported from 2.3-gae: 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/1af2e0c2 Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/1af2e0c2 Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/1af2e0c2 Branch: refs/heads/3 Commit: 1af2e0c219e4cb0ef37252412275a5c7eab525ab Parents: 0d21cbb Author: ddekany <[email protected]> Authored: Tue Mar 20 18:56:44 2018 +0100 Committer: ddekany <[email protected]> Committed: Tue Mar 20 18:56:44 2018 +0100 ---------------------------------------------------------------------- .../apache/freemarker/core/MiscErrorMessagesTest.java | 7 +++++++ .../org/apache/freemarker/core/ASTDirAssignment.java | 13 +++++++++++-- .../freemarker/core/InvalidReferenceException.java | 10 +++++----- 3 files changed, 23 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1af2e0c2/freemarker-core-test/src/test/java/org/apache/freemarker/core/MiscErrorMessagesTest.java ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/MiscErrorMessagesTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/MiscErrorMessagesTest.java index 9f73968..81b9710 100644 --- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/MiscErrorMessagesTest.java +++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/MiscErrorMessagesTest.java @@ -55,4 +55,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"); + } + } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1af2e0c2/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirAssignment.java ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirAssignment.java b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirAssignment.java index 7efa95c..26a6d69 100644 --- a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirAssignment.java +++ b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirAssignment.java @@ -149,7 +149,7 @@ final class ASTDirAssignment extends ASTDirective { if (operatorType == OPERATOR_TYPE_PLUS_EQUALS) { // Add or concat operation if (lhoValue == null) { throw InvalidReferenceException.getInstance( - variableName, getOperatorTypeAsString(), env); + scope, variableName, getOperatorTypeAsString(), env); } value = valueExp.eval(env); @@ -160,7 +160,7 @@ final class ASTDirAssignment extends ASTDirective { if (lhoValue instanceof TemplateNumberModel) { lhoNumber = _EvalUtils.modelToNumber((TemplateNumberModel) lhoValue, null); } else if (lhoValue == null) { - throw InvalidReferenceException.getInstance(variableName, getOperatorTypeAsString(), env); + throw InvalidReferenceException.getInstance(scope, variableName, getOperatorTypeAsString(), env); } else { throw MessageUtils.newUnexpectedAssignmentTargetTypeException( variableName, lhoValue, TemplateNumberModel.class, env); @@ -281,4 +281,13 @@ final class ASTDirAssignment extends ASTDirective { } } + 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/1af2e0c2/freemarker-core/src/main/java/org/apache/freemarker/core/InvalidReferenceException.java ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/InvalidReferenceException.java b/freemarker-core/src/main/java/org/apache/freemarker/core/InvalidReferenceException.java index 2cd4fd1..7edd087 100644 --- a/freemarker-core/src/main/java/org/apache/freemarker/core/InvalidReferenceException.java +++ b/freemarker-core/src/main/java/org/apache/freemarker/core/InvalidReferenceException.java @@ -139,16 +139,16 @@ 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; } else { 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." + "The target variable of the assignment, ", + new _DelayedJQuote(missingAssignedVarName), + ", was null or missing in the " + ASTDirAssignment.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);
