Skip to content

Commit 6d042f5

Browse files
authored
Mustachio: Fix multi-name keys and other bugs encountered so far. (#2452)
Mustachio: Fix multi-name keys and other bugs encountered so far.
1 parent a1d86f2 commit 6d042f5

File tree

7 files changed

+3366
-418
lines changed

7 files changed

+3366
-418
lines changed

lib/src/generator/templates.renderers.dart

Lines changed: 2850 additions & 330 deletions
Large diffs are not rendered by default.

lib/src/mustachio/renderer_base.dart

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -37,24 +37,21 @@ abstract class RendererBase<T> {
3737
}
3838
var property = getProperty(names.first);
3939
if (property != null) {
40-
var value = property.getValue(context);
41-
for (var name in names.skip(1)) {
42-
if (property.getProperties().containsKey(name)) {
43-
property = property.getProperties()[name];
44-
value = property.getValue(value);
45-
} else {
46-
throw MustachioResolutionError(
47-
'Failed to resolve ${names.join('.')} as a property '
48-
'on ${context.runtimeType}');
49-
}
40+
try {
41+
return property.renderVariable(context, property, [...names.skip(1)]);
42+
} on MustachioResolutionError {
43+
// The error thrown by [Property.renderVariable] does not have all of
44+
// the names required for a decent error. We throw a new error here.
45+
throw MustachioResolutionError(
46+
'Failed to resolve $names as a property chain on any types in the '
47+
'current context');
5048
}
51-
return value.toString();
5249
} else if (parent != null) {
5350
return parent.getFields(names);
5451
} else {
5552
throw MustachioResolutionError(
56-
'Failed to resolve ${names.first} as a property '
57-
'on any types in the current context');
53+
'Failed to resolve ${names.first} as a property on any types in the '
54+
'current context');
5855
}
5956
}
6057

@@ -126,9 +123,8 @@ class Property<T> {
126123
/// Gets the value of this property on the object [context].
127124
final Object /*?*/ Function(T context) /*!*/ getValue;
128125

129-
/// Gets the property map of the type of this property.
130-
final Map<String /*!*/, Property<Object> /*!*/ >
131-
Function() /*?*/ getProperties;
126+
final String /*!*/ Function(
127+
T, Property<T>, List<String> /*!*/) /*?*/ renderVariable;
132128

133129
/// Gets the bool value (true or false, never null) of this property on the
134130
/// object [context].
@@ -145,11 +141,9 @@ class Property<T> {
145141
final String /*!*/ Function(
146142
T, RendererBase<T>, List<MustachioNode> /*!*/) /*?*/ renderValue;
147143

148-
// TODO(srawlins): Add functions for rendering other properties.
149-
150144
Property(
151145
{@required this.getValue,
152-
this.getProperties,
146+
this.renderVariable,
153147
this.getBool,
154148
this.isEmptyIterable,
155149
this.renderIterable,
@@ -161,5 +155,5 @@ class Property<T> {
161155
class MustachioResolutionError extends Error {
162156
String message;
163157

164-
MustachioResolutionError(this.message);
158+
MustachioResolutionError([this.message]);
165159
}

test/mustachio/builder_test.dart

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,18 @@ class Bar {}
135135
expect(generatedContent, contains('''
136136
'b1': Property(
137137
getValue: (CT_ c) => c.b1,
138-
getProperties: _Renderer_bool.propertyMap,
138+
renderVariable:
139+
(CT_ c, Property<CT_> self, List<String> remainingNames) {
140+
if (remainingNames.isEmpty) return self.getValue(c).toString();
141+
var name = remainingNames.first;
142+
if (_Renderer_bool.propertyMap().containsKey(name)) {
143+
var nextProperty = _Renderer_bool.propertyMap()[name];
144+
return nextProperty.renderVariable(
145+
self.getValue(c), nextProperty, [...remainingNames.skip(1)]);
146+
} else {
147+
throw MustachioResolutionError();
148+
}
149+
},
139150
getBool: (CT_ c) => c.b1 == true,
140151
),
141152
'''));
@@ -145,7 +156,18 @@ class Bar {}
145156
expect(generatedContent, contains('''
146157
'l1': Property(
147158
getValue: (CT_ c) => c.l1,
148-
getProperties: _Renderer_List.propertyMap,
159+
renderVariable:
160+
(CT_ c, Property<CT_> self, List<String> remainingNames) {
161+
if (remainingNames.isEmpty) return self.getValue(c).toString();
162+
var name = remainingNames.first;
163+
if (_Renderer_List.propertyMap().containsKey(name)) {
164+
var nextProperty = _Renderer_List.propertyMap()[name];
165+
return nextProperty.renderVariable(
166+
self.getValue(c), nextProperty, [...remainingNames.skip(1)]);
167+
} else {
168+
throw MustachioResolutionError();
169+
}
170+
},
149171
isEmptyIterable: (CT_ c) => c.l1?.isEmpty ?? true,
150172
renderIterable:
151173
(CT_ c, RendererBase<CT_> r, List<MustachioNode> ast) {
@@ -163,7 +185,18 @@ class Bar {}
163185
expect(generatedContent, contains('''
164186
's1': Property(
165187
getValue: (CT_ c) => c.s1,
166-
getProperties: _Renderer_String.propertyMap,
188+
renderVariable:
189+
(CT_ c, Property<CT_> self, List<String> remainingNames) {
190+
if (remainingNames.isEmpty) return self.getValue(c).toString();
191+
var name = remainingNames.first;
192+
if (_Renderer_String.propertyMap().containsKey(name)) {
193+
var nextProperty = _Renderer_String.propertyMap()[name];
194+
return nextProperty.renderVariable(
195+
self.getValue(c), nextProperty, [...remainingNames.skip(1)]);
196+
} else {
197+
throw MustachioResolutionError();
198+
}
199+
},
167200
isNullValue: (CT_ c) => c.s1 == null,
168201
renderValue: (CT_ c, RendererBase<CT_> r, List<MustachioNode> ast) {
169202
return _render_String(c.s1, ast, parent: r);

test/mustachio/foo.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
@Renderer(#renderFoo, Context<Foo>())
2+
@Renderer(#renderBar, Context<Bar>())
23
library dartdoc.testing.foo;
34

45
import 'package:dartdoc/src/mustachio/annotations.dart';
@@ -8,3 +9,8 @@ class Foo {
89
bool b1;
910
List<int> l1;
1011
}
12+
13+
class Bar {
14+
Foo foo;
15+
String s2;
16+
}

0 commit comments

Comments
 (0)