Fix bugs relating to . and this.
First, I missed some reference checks when I stopped interning names. Fixed those. Second, when iterating over an array which contained null elements, the wrong thing was happening.
This commit is contained in:
@@ -35,9 +35,6 @@ public abstract class BasicCollector implements Mustache.Collector
|
||||
}
|
||||
|
||||
public Mustache.VariableFetcher createFetcher (Object ctx, String name) {
|
||||
// support both .name and this.name to fetch members
|
||||
if (name == Template.DOT_NAME || name == Template.THIS_NAME) return THIS_FETCHER;
|
||||
|
||||
if (ctx instanceof Map<?,?>) return MAP_FETCHER;
|
||||
|
||||
// if the name looks like a number, potentially use one of our 'indexing' fetchers
|
||||
@@ -73,7 +70,7 @@ public abstract class BasicCollector implements Mustache.Collector
|
||||
Map<?,?> map = (Map<?,?>)ctx;
|
||||
if (map.containsKey(name)) return map.get(name);
|
||||
// special case to allow map entry set to be iterated over
|
||||
if (name == "entrySet") return map.entrySet();
|
||||
if ("entrySet".equals(name)) return map.entrySet();
|
||||
return Template.NO_FETCHER_FOUND;
|
||||
}
|
||||
@Override public String toString () {
|
||||
@@ -113,15 +110,6 @@ public abstract class BasicCollector implements Mustache.Collector
|
||||
}
|
||||
};
|
||||
|
||||
protected static final Mustache.VariableFetcher THIS_FETCHER = new Mustache.VariableFetcher() {
|
||||
public Object get (Object ctx, String name) throws Exception {
|
||||
return ctx;
|
||||
}
|
||||
@Override public String toString () {
|
||||
return "THIS_FETCHER";
|
||||
}
|
||||
};
|
||||
|
||||
protected static abstract class ArrayHelper implements Mustache.VariableFetcher {
|
||||
public Object get (Object ctx, String name) throws Exception {
|
||||
try {
|
||||
|
||||
@@ -856,8 +856,10 @@ public class Mustache {
|
||||
@Override public void execute (Template tmpl, Template.Context ctx, Writer out) {
|
||||
Object value = tmpl.getValueOrDefault(ctx, _name, _line);
|
||||
if (value == null) {
|
||||
throw new MustacheException.Context("No key, method or field with name '" + _name +
|
||||
"' on line " + _line, _name, _line);
|
||||
String msg = Template.isThisName(_name) ?
|
||||
"Resolved '.' to null (which is disallowed), on line " + _line :
|
||||
"No key, method or field with name '" + _name + "' on line " + _line;
|
||||
throw new MustacheException.Context(msg, _name, _line);
|
||||
}
|
||||
write(out, _escaper.escape(_formatter.format(value)));
|
||||
}
|
||||
|
||||
@@ -240,7 +240,7 @@ public class Template {
|
||||
// if we reach here, we found nothing in this or our parent contexts...
|
||||
|
||||
// if we have a compound key, decompose the value and resolve it step by step
|
||||
if (name != DOT_NAME && name.indexOf(DOT_NAME) != -1) {
|
||||
if (!name.equals(DOT_NAME) && name.indexOf(DOT_NAME) != -1) {
|
||||
return getCompoundValue(ctx, name, line, missingIsNull);
|
||||
} else {
|
||||
// otherwise let checkForMissing() decide what to do
|
||||
@@ -297,6 +297,11 @@ public class Template {
|
||||
}
|
||||
|
||||
protected Object getValueIn (Object data, String name, int line) {
|
||||
// if we're getting `.` or `this` then just return the whole context; we do this before the
|
||||
// null check because it may be valid for the context to be null (if we're iterating over a
|
||||
// list which contains nulls, for example)
|
||||
if (isThisName(name)) return data;
|
||||
|
||||
if (data == null) {
|
||||
throw new NullPointerException(
|
||||
"Null context for variable '" + name + "' on line " + line);
|
||||
@@ -412,6 +417,10 @@ public class Template {
|
||||
}
|
||||
}
|
||||
|
||||
protected static boolean isThisName (String name) {
|
||||
return DOT_NAME.equals(name) || THIS_NAME.equals(name);
|
||||
}
|
||||
|
||||
protected static final String DOT_NAME = ".";
|
||||
protected static final String THIS_NAME = "this";
|
||||
protected static final String FIRST_NAME = "-first";
|
||||
|
||||
@@ -321,6 +321,12 @@ public abstract class SharedTests extends GWTTestCase
|
||||
execute(context("things", Arrays.asList("bar", "baz", "bif"))));
|
||||
}
|
||||
|
||||
@Test public void testNestedNullThis () {
|
||||
check("bar!bif", Mustache.compiler().defaultValue("!").
|
||||
compile("{{#things}}{{.}}{{/things}}").
|
||||
execute(context("things", Arrays.asList("bar", null, "bif"))));
|
||||
}
|
||||
|
||||
@Test public void testNewlineSkipping () {
|
||||
testNewlineSkipping("\n");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user