@@ -17,6 +17,10 @@ import 'package:dartdoc/src/type_utils.dart';
17
17
import 'package:meta/meta.dart' ;
18
18
import 'package:path/path.dart' as path;
19
19
20
+ /// A list of [_VariableLookup] s used by a renderer constitutes a "context
21
+ /// stack".
22
+ typedef ContextStack = List <_VariableLookup >;
23
+
20
24
/// Compiles all templates specified in [specs] into a Dart library containing
21
25
/// a renderer for each template.
22
26
Future <String > compileTemplatesToRenderers (
@@ -62,8 +66,7 @@ Future<String> compileTemplatesToRenderers(
62
66
// To change the contents of this library, make changes to the builder source
63
67
// files in the tool/mustachio/ directory.
64
68
65
- // There are a few deduplicated render functions which are generated but not
66
- // used.
69
+ // Some deduplicated render functions are generated but not used.
67
70
// TODO(srawlins): Detect these and do not write them.
68
71
// ignore_for_file: unused_element
69
72
// Sometimes we enter a new section which triggers creating a new variable, but
@@ -116,27 +119,23 @@ Future<Map<_AotCompiler, String>> _deduplicateRenderers(
116
119
continue ;
117
120
}
118
121
var firstCompiler = compilers.first;
119
- var contextStacksLength = firstCompiler._usedContexts.length;
120
- if (compilers.any ((c) => c._usedContexts.length != contextStacksLength)) {
121
- // The stack lengths are different, it is impossible to deduplicate such
122
- // partial renderers.
122
+ var contextStacks = compilers.map ((c) => c._usedContextStack).toList ();
123
+ var contextStackTypes = typeSystem.contextStackLub (contextStacks);
124
+ if (contextStackTypes == null ) {
125
+ // The stack lengths are different; it is impossible to fully deduplicate
126
+ // such partial renderers.
123
127
continue ;
124
128
}
125
- // The new list of context types, each of which is the LUB of the associated
126
- // context type of each of the compilers.
127
- var contextStackTypes = < InterfaceType > [];
128
- for (var i = 0 ; i < contextStacksLength; i++ ) {
129
- var types = compilers.map ((c) => c._usedContextStack[i].type);
130
- var lubType = types.fold <DartType >(types.first,
131
- (value, type) => typeSystem.leastUpperBound (value, type))
132
- as InterfaceType ;
133
- contextStackTypes.add (lubType);
134
- }
135
129
136
130
// Each of the render functions generated by a compiler for this asset can
137
131
// be replaced by a more generic renderer which accepts the LUB types. The
138
- // body of each replaced renderer can perform a simple redirect.
132
+ // body of each replaced renderer can perform a simple redirect to the more
133
+ // generic renderer.
139
134
var rendererName = filePath.replaceAll ('.' , '_' ).replaceAll ('/' , '_' );
135
+
136
+ // The names of the renderers which are being replaced all include some
137
+ // reference to the template/partial which referred to them; we must create
138
+ // a new renderer name from scratch.
140
139
var lubCompiler = _AotCompiler ._(
141
140
contextStackTypes.first,
142
141
'_deduplicated_$rendererName ' ,
@@ -250,12 +249,12 @@ class _AotCompiler {
250
249
final Map <_AotCompiler , String > _compiledPartials = {};
251
250
252
251
/// The current stack of context objects (as variable lookups).
253
- final List < _VariableLookup > _contextStack;
252
+ final ContextStack _contextStack;
254
253
255
254
/// The set of context objects which are ultimately used by this compiler.
256
255
final Set <_VariableLookup > _usedContexts = {};
257
256
258
- List < _VariableLookup > get _usedContextStack =>
257
+ ContextStack get _usedContextStack =>
259
258
[..._contextStack.where (_usedContexts.contains)];
260
259
261
260
/// A counter for naming partial render functions.
@@ -276,7 +275,7 @@ class _AotCompiler {
276
275
String rendererName,
277
276
String templatePath,
278
277
_BuildData buildData, {
279
- List < _VariableLookup > contextStack = const [],
278
+ ContextStack contextStack = const [],
280
279
}) async {
281
280
var template =
282
281
await File (path.join (buildData._root, templatePath)).readAsString ();
@@ -292,7 +291,7 @@ class _AotCompiler {
292
291
this ._templatePath,
293
292
this ._syntaxTree,
294
293
this ._buildData, {
295
- required List < _VariableLookup > contextStack,
294
+ required ContextStack contextStack,
296
295
}) : _contextStack = _rename (contextStack),
297
296
_contextNameCounter = contextStack.length;
298
297
@@ -301,7 +300,7 @@ class _AotCompiler {
301
300
///
302
301
/// This ensures that each renderer accepts a simple list of context objects
303
302
/// with predictable names.
304
- static List < _VariableLookup > _rename (List < _VariableLookup > original) {
303
+ static ContextStack _rename (ContextStack original) {
305
304
var result = < _VariableLookup > [];
306
305
var index = original.length - 1 ;
307
306
for (var variable in original) {
@@ -391,7 +390,7 @@ class _AotCompiler {
391
390
class _BlockCompiler {
392
391
final _AotCompiler _templateCompiler;
393
392
394
- final List < _VariableLookup > _contextStack;
393
+ final ContextStack _contextStack;
395
394
396
395
final Set <_VariableLookup > _usedContextTypes = {};
397
396
@@ -756,3 +755,27 @@ extension on StringBuffer {
756
755
return referencedElements;
757
756
}
758
757
}
758
+
759
+ extension on TypeSystem {
760
+ /// Returns a list of types which represents the LUB of each of the types in
761
+ /// the corresponding positions in [contextStacks] .
762
+ List <InterfaceType >? contextStackLub (List <ContextStack > contextStacks) {
763
+ // The length of each and every context stack.
764
+ var contextStacksLength = contextStacks.first.length;
765
+ if (contextStacks.any ((s) => s.length != contextStacksLength)) {
766
+ return null ;
767
+ }
768
+
769
+ // The new list of context types, each of which is the LUB of the associated
770
+ // context type of each of the compilers.
771
+ var contextStackTypes = < InterfaceType > [];
772
+ for (var i = 0 ; i < contextStacksLength; i++ ) {
773
+ var types = contextStacks.map ((s) => s[i].type);
774
+ var lubType =
775
+ types.fold <DartType >(types.first, leastUpperBound) as InterfaceType ;
776
+ contextStackTypes.add (lubType);
777
+ }
778
+
779
+ return contextStackTypes;
780
+ }
781
+ }
0 commit comments