freemarker-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ddek...@apache.org
Subject [freemarker] 02/02: (Javadoc improvements, related to LocalContext and fallbackOnNullLoopVariable)
Date Sun, 14 Jul 2019 22:34:19 GMT
This is an automated email from the ASF dual-hosted git repository.

ddekany pushed a commit to branch 2.3-gae
in repository https://gitbox.apache.org/repos/asf/freemarker.git

commit 926f33efdd5cad3e04dc2dd80ddfda1de39df712
Author: ddekany <ddekany@apache.org>
AuthorDate: Mon Jul 15 00:33:19 2019 +0200

    (Javadoc improvements, related to LocalContext and fallbackOnNullLoopVariable)
---
 src/main/java/freemarker/core/Environment.java     | 61 ++++-----------
 src/main/java/freemarker/core/LocalContext.java    | 31 ++++++--
 src/main/java/freemarker/core/Macro.java           | 16 +---
 .../java/freemarker/template/Configuration.java    | 90 ++++------------------
 4 files changed, 53 insertions(+), 145 deletions(-)

diff --git a/src/main/java/freemarker/core/Environment.java b/src/main/java/freemarker/core/Environment.java
index 9553d5b..aba344c 100644
--- a/src/main/java/freemarker/core/Environment.java
+++ b/src/main/java/freemarker/core/Environment.java
@@ -19,64 +19,30 @@
 
 package freemarker.core;
 
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.text.Collator;
-import java.text.DecimalFormat;
-import java.text.DecimalFormatSymbols;
-import java.text.NumberFormat;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.IdentityHashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-import java.util.TimeZone;
-
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import freemarker.cache.TemplateNameFormat;
 import freemarker.cache._CacheAPI;
 import freemarker.ext.beans.BeansWrapper;
 import freemarker.log.Logger;
-import freemarker.template.Configuration;
-import freemarker.template.MalformedTemplateNameException;
-import freemarker.template.ObjectWrapper;
-import freemarker.template.SimpleHash;
-import freemarker.template.SimpleSequence;
-import freemarker.template.Template;
-import freemarker.template.TemplateCollectionModel;
-import freemarker.template.TemplateDateModel;
-import freemarker.template.TemplateDirectiveBody;
-import freemarker.template.TemplateDirectiveModel;
-import freemarker.template.TemplateException;
-import freemarker.template.TemplateExceptionHandler;
-import freemarker.template.TemplateHashModel;
-import freemarker.template.TemplateHashModelEx;
-import freemarker.template.TemplateModel;
-import freemarker.template.TemplateModelException;
-import freemarker.template.TemplateModelIterator;
-import freemarker.template.TemplateNodeModel;
-import freemarker.template.TemplateNumberModel;
-import freemarker.template.TemplateScalarModel;
-import freemarker.template.TemplateSequenceModel;
-import freemarker.template.TemplateTransformModel;
-import freemarker.template.TransformControl;
-import freemarker.template._TemplateAPI;
+import freemarker.template.*;
 import freemarker.template.utility.DateUtil;
 import freemarker.template.utility.DateUtil.DateToISO8601CalendarFactory;
 import freemarker.template.utility.NullWriter;
 import freemarker.template.utility.StringUtil;
 import freemarker.template.utility.UndeclaredThrowableException;
 
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.text.Collator;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.NumberFormat;
+import java.util.*;
+
 /**
  * Object that represents the runtime environment during template processing. For every invocation
of a
  * <tt>Template.process()</tt> method, a new instance of this object is created,
and then discarded when
@@ -708,7 +674,6 @@ public final class Environment extends Configurable {
         }
 
         public TemplateModel getLocalVariable(String name) throws TemplateModelException
{
-            // TODO [lambda] Do not allow fallback (i.e., introduce untransparent null-s)
             return name.equals(lambdaArgName) ? lambdaArgValue : null;
         }
 
diff --git a/src/main/java/freemarker/core/LocalContext.java b/src/main/java/freemarker/core/LocalContext.java
index cc90e0a..734b6cc 100644
--- a/src/main/java/freemarker/core/LocalContext.java
+++ b/src/main/java/freemarker/core/LocalContext.java
@@ -19,20 +19,35 @@
 
 package freemarker.core;
 
-import java.util.Collection;
-
+import freemarker.template.Configuration;
 import freemarker.template.TemplateModel;
 import freemarker.template.TemplateModelException;
 
-/**
-  * An interface that represents a local context. This is used as the abstraction for  
-  * the context of a Macro invocation, a loop, or the nested block call from within 
-  * a macro.
-  * <a href="mailto:jon@revusky.com">Jonathan Revusky</a>
-  */
+import java.util.Collection;
 
+/**
+ * Represents a local context (a set of local variables); should be internal, but left public
for backward
+ * compatibility. This is used as the abstraction for accessing the local variables of a
macro/function invocation,
+ * the loops variables of {#code #list}, the nested content variables of a macro call, or
the arguments to a lambda
+ * expression.
+ */
 public interface LocalContext {
+
+    /**
+     * @return {@code null} if the variable doesn't exit. Since 2.3.29, if this context represents
loop variables, this
+     *     is possibly {@code freemarker.core.NullTemplateModel.INSTANCE} (an internal class)
when
+     *     {@link Configuration#setFallbackOnNullLoopVariable(boolean)} was set to {@code
false}, in which
+     *     case the caller must not fall back to higher scopes to find the variable, and
treat the value as
+     *     {@code null} in other respects. While this is in theory an incompatible change
in 2.3.29, it's not a problem,
+     *     it's very unlikely (hopefully impossible with published API-s) that user code
gets a {@link LocalContext}
+     *     that stores loop variables, and also because by default
+     *     {@link Configuration#setFallbackOnNullLoopVariable(boolean)} is {@code true}.
+     */
     TemplateModel getLocalVariable(String name) throws TemplateModelException;
+
+    /**
+     * The names of the local variables that were declared or set in this context.
+     */
     Collection getLocalVariableNames() throws TemplateModelException;
     
 }
diff --git a/src/main/java/freemarker/core/Macro.java b/src/main/java/freemarker/core/Macro.java
index 7829c76..a0e355f 100644
--- a/src/main/java/freemarker/core/Macro.java
+++ b/src/main/java/freemarker/core/Macro.java
@@ -19,17 +19,9 @@
 
 package freemarker.core;
 
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
+import freemarker.template.*;
 
-import freemarker.template.TemplateException;
-import freemarker.template.TemplateModel;
-import freemarker.template.TemplateModelException;
-import freemarker.template.TemplateModelIterator;
-import freemarker.template.TemplateScalarModel;
+import java.util.*;
 
 /**
  * An element representing a macro declaration.
@@ -242,10 +234,6 @@ public final class Macro extends TemplateElement implements TemplateModel
{
             }
         }
 
-        /**
-         * @return the local variable of the given name
-         * or null if it doesn't exist.
-         */ 
         public TemplateModel getLocalVariable(String name) throws TemplateModelException
{
              return localVars.get(name);
         }
diff --git a/src/main/java/freemarker/template/Configuration.java b/src/main/java/freemarker/template/Configuration.java
index 21e02a1..1149879 100644
--- a/src/main/java/freemarker/template/Configuration.java
+++ b/src/main/java/freemarker/template/Configuration.java
@@ -19,6 +19,14 @@
 
 package freemarker.template;
 
+import freemarker.cache.*;
+import freemarker.cache.TemplateCache.MaybeMissingTemplate;
+import freemarker.core.*;
+import freemarker.ext.beans.BeansWrapper;
+import freemarker.ext.beans.BeansWrapperBuilder;
+import freemarker.log.Logger;
+import freemarker.template.utility.*;
+
 import java.io.File;
 import java.io.IOException;
 import java.io.Writer;
@@ -26,79 +34,11 @@ import java.lang.reflect.InvocationTargetException;
 import java.net.URLConnection;
 import java.text.DecimalFormat;
 import java.text.SimpleDateFormat;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
+import java.util.*;
 import java.util.Map.Entry;
-import java.util.Properties;
-import java.util.Set;
-import java.util.TimeZone;
-import java.util.TreeSet;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
-import freemarker.cache.CacheStorage;
-import freemarker.cache.ClassTemplateLoader;
-import freemarker.cache.FileTemplateLoader;
-import freemarker.cache.MruCacheStorage;
-import freemarker.cache.MultiTemplateLoader;
-import freemarker.cache.SoftCacheStorage;
-import freemarker.cache.TemplateCache;
-import freemarker.cache.TemplateCache.MaybeMissingTemplate;
-import freemarker.cache.TemplateConfigurationFactory;
-import freemarker.cache.TemplateLoader;
-import freemarker.cache.TemplateLookupContext;
-import freemarker.cache.TemplateLookupStrategy;
-import freemarker.cache.TemplateNameFormat;
-import freemarker.cache.URLTemplateLoader;
-import freemarker.core.BugException;
-import freemarker.core.CSSOutputFormat;
-import freemarker.core.CombinedMarkupOutputFormat;
-import freemarker.core.Configurable;
-import freemarker.core.Environment;
-import freemarker.core.HTMLOutputFormat;
-import freemarker.core.JSONOutputFormat;
-import freemarker.core.JavaScriptOutputFormat;
-import freemarker.core.MarkupOutputFormat;
-import freemarker.core.OutputFormat;
-import freemarker.core.ParseException;
-import freemarker.core.ParserConfiguration;
-import freemarker.core.PlainTextOutputFormat;
-import freemarker.core.RTFOutputFormat;
-import freemarker.core.TemplateConfiguration;
-import freemarker.core.TemplateMarkupOutputModel;
-import freemarker.core.UndefinedOutputFormat;
-import freemarker.core.UnregisteredOutputFormatException;
-import freemarker.core.XHTMLOutputFormat;
-import freemarker.core.XMLOutputFormat;
-import freemarker.core._CoreAPI;
-import freemarker.core._DelayedJQuote;
-import freemarker.core._MiscTemplateException;
-import freemarker.core._ObjectBuilderSettingEvaluator;
-import freemarker.core._SettingEvaluationEnvironment;
-import freemarker.core._SortedArraySet;
-import freemarker.core._UnmodifiableCompositeSet;
-import freemarker.ext.beans.BeansWrapper;
-import freemarker.ext.beans.BeansWrapperBuilder;
-import freemarker.log.Logger;
-import freemarker.template.utility.CaptureOutput;
-import freemarker.template.utility.ClassUtil;
-import freemarker.template.utility.Constants;
-import freemarker.template.utility.HtmlEscape;
-import freemarker.template.utility.NormalizeNewlines;
-import freemarker.template.utility.NullArgumentException;
-import freemarker.template.utility.SecurityUtilities;
-import freemarker.template.utility.StandardCompress;
-import freemarker.template.utility.StringUtil;
-import freemarker.template.utility.XmlEscape;
-
 /**
  * <b>The main entry point into the FreeMarker API</b>; encapsulates the configuration
settings of FreeMarker,
  * also serves as a central template-loading and caching service.
@@ -2594,17 +2534,17 @@ public class Configuration extends Configurable implements Cloneable,
ParserConf
     }
 
     /**
-     * Specifies the behavior when reading a loop variable (like {@code i} in {@code <#list
items as i>}) that's
-     * {@code null} (missing); if {@code true}, FreeMarker will look for a variable with
the same name in higher
-     * variable scopes, or if {@code false} the variable will be simply {@code null} (missing).
-     * For backward compatibility the default is {@code true}. The recommended value for
new projects is
+     * Specifies the behavior when reading a loop variable (like {@code i} in {@code <#list
items as i>}, or in
+     * {@code <@myMacro items; i>}) that's {@code null} (missing); if {@code true},
FreeMarker will look for a variable
+     * with the same name in higher variable scopes, or if {@code false} the variable will
be simply {@code null}
+     * (missing). For backward compatibility the default is {@code true}. The recommended
value for new projects is
      * {@code false}, as otherwise adding new variables to higher scopes (typically to the
data-model) can
      * unintentionally change the behavior of templates. You have to be quite unlucky for
that to happen though:
      * The newly added variable has to have the same name as the loop variable, and there
must be some null (missing)
      * values in what you loop through.
      *
-     * <p>Note that this doesn't influence the behavior of lambdas, like {@code items?filter(i
-> i?hasContent)},
-     * because reading lambda arguments never fall back to higher scopes.
+     * <p>This setting doesn't influence the behavior of lambdas, like {@code items?filter(i
-> i?hasContent)}, as they
+     * never had this problem. Reading a lambda argument never falls back to higher scopes.
      *
      * @since 2.3.29
      */


Mime
View raw message