From 1b84c84b982bb8d1d3157351553aaa512f5b9a56 Mon Sep 17 00:00:00 2001 From: Sam Rawlins Date: Mon, 1 Feb 2021 15:29:27 -0800 Subject: [PATCH 1/3] Mustachio: generate renderer code for mixed in types --- analysis_options.yaml | 1 + test/mustachio/builder_test.dart | 15 +++- tool/mustachio/codegen_runtime_renderer.dart | 84 +++++++++++++++----- 3 files changed, 79 insertions(+), 21 deletions(-) diff --git a/analysis_options.yaml b/analysis_options.yaml index 7681950262..5e12339745 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -6,6 +6,7 @@ analyzer: errors: unused_import: warning unused_shown_name: warning + todo: ignore exclude: - 'doc/**' - 'lib/src/third_party/pkg/**' diff --git a/test/mustachio/builder_test.dart b/test/mustachio/builder_test.dart index 0dcf6a8374..ce3dcebdff 100644 --- a/test/mustachio/builder_test.dart +++ b/test/mustachio/builder_test.dart @@ -79,7 +79,10 @@ abstract class FooBase2 { abstract class FooBase extends FooBase2 { Bar get bar; } -abstract class Foo extends FooBase { +mixin Mix on FooBase { + String get field => 'Mix.field'; +} +abstract class Foo extends FooBase with Mix { String s1 = "s1"; bool b1 = false; List l1 = [1, 2, 3]; @@ -122,6 +125,11 @@ class Baz {} expect(renderersLibrary.getType('_Renderer_FooBase'), isNotNull); }); + test('for a class which is mixed into a rendered class', () { + expect(renderersLibrary.getTopLevelFunction('_render_Mix'), isNotNull); + expect(renderersLibrary.getType('_Renderer_Mix'), isNotNull); + }); + test('for a type found in a getter', () { expect(renderersLibrary.getTopLevelFunction('_render_Bar'), isNotNull); expect(renderersLibrary.getType('_Renderer_Bar'), isNotNull); @@ -144,6 +152,11 @@ class Baz {} contains('..._Renderer_FooBase.propertyMap(),')); }); + test('with a property map which references a mixed in class', () { + expect(generatedContent, + contains('..._Renderer_Mix.propertyMap(),')); + }); + test('with a property map with a bool property', () { expect(generatedContent, contains(''' 'b1': Property( diff --git a/tool/mustachio/codegen_runtime_renderer.dart b/tool/mustachio/codegen_runtime_renderer.dart index 9e85bd56f1..82995e955d 100644 --- a/tool/mustachio/codegen_runtime_renderer.dart +++ b/tool/mustachio/codegen_runtime_renderer.dart @@ -128,10 +128,18 @@ String _simpleResolveErrorMessage(List key, String type) => _typeToRendererClassName[element] = rendererInfo._rendererClassName; spec._contextType.accessors.forEach(_addPropertyToProcess); + + for (var mixin in spec._contextType.element.mixins) { + _addTypeToProcess(mixin.element, isFullRenderer: true); + } var superclass = spec._contextType.element.supertype; + while (superclass != null) { // Any type specified with a renderer spec (`@Renderer`) is full. _addTypeToProcess(superclass.element, isFullRenderer: true); + for (var mixin in superclass.element.mixins) { + _addTypeToProcess(mixin.element, isFullRenderer: true); + } superclass.accessors.forEach(_addPropertyToProcess); superclass = superclass.element.supertype; } @@ -159,34 +167,50 @@ String _simpleResolveErrorMessage(List key, String type) => } type = bound; } - var isFullRenderer = _isVisibleToMustache(type.element); - if (_typeSystem.isAssignableTo(type, _typeProvider.iterableDynamicType)) { - var iterableElement = _typeProvider.iterableElement; - var iterableType = type.asInstanceOf(iterableElement); - var innerType = iterableType.typeArguments.first; - // Don't add Iterable functions for a generic type, for example - // `List.reversed` has inner type `E`, which we don't have a specific - // renderer for. - // TODO(srawlins): Find a solution for this. We can track all of the - // concrete types substituted for `E` for example. - var isFullRenderer = _isVisibleToMustache(innerType.element); - while (innerType != null && innerType is InterfaceType) { - _addTypeToProcess((innerType as InterfaceType).element, - isFullRenderer: isFullRenderer); - innerType = (innerType as InterfaceType).superclass; + if (type is InterfaceType) { + if (_typeSystem.isAssignableTo(type, _typeProvider.iterableDynamicType)) { + var iterableElement = _typeProvider.iterableElement; + var iterableType = type.asInstanceOf(iterableElement); + var innerType = iterableType.typeArguments.first; + if (innerType is InterfaceType) { + // Don't add Iterable functions for a generic type, for example + // `List.reversed` has inner type `E`, which we don't have a + // specific renderer for. + // TODO(srawlins): Find a solution for this. We can track all of the + // concrete types substituted for `E` for example. + var isFullRenderer = _isVisibleToMustache(innerType.element); + _addTypeHierarchyToProcess(innerType, isFullRenderer: isFullRenderer); + } } + + var isFullRenderer = _isVisibleToMustache(type.element); + _addTypeHierarchyToProcess(type, isFullRenderer: isFullRenderer); } + } - while (type != null && type is InterfaceType) { - _addTypeToProcess((type as InterfaceType).element, - isFullRenderer: isFullRenderer); - type = (type as InterfaceType).superclass; + /// Adds [type] to the queue of types to process, as well as its supertypes + /// (if a class), mixed in types, and superclass constraints (if a mixin). + void _addTypeHierarchyToProcess(InterfaceType type, + {@required bool isFullRenderer}) { + while (type != null) { + _addTypeToProcess(type.element, isFullRenderer: isFullRenderer); + for (var mixin in type.element.mixins) { + _addTypeToProcess(mixin.element, isFullRenderer: isFullRenderer); + } + if (type.element.isMixin) { + for (var constraint in type.element.superclassConstraints) { + _addTypeToProcess(constraint.element, isFullRenderer: isFullRenderer); + } + } else { + type = type.superclass; + } } } /// Adds [type] to the [_typesToProcess] queue, if it is not already there. - void _addTypeToProcess(ClassElement element, {@required isFullRenderer}) { + void _addTypeToProcess(ClassElement element, + {@required bool isFullRenderer}) { var types = _typesToProcess.where((rs) => rs._contextClass == element); if (types.isEmpty) { var rendererInfo = _RendererInfo(element, @@ -316,6 +340,26 @@ class ${renderer._rendererClassName}${renderer._typeParametersString} _buffer.writeln(' ...$superMapName$generics(),'); } } + if (contextClass.mixins != null) { + // Mixins are spread into the property map _after_ the super class, so + // that they override any values which need to be overridden. Superclass + // and mixins override from left to right, as do spreads: + // `class C extends E with M, N` first takes members from N, then M, then + // E. Similarly, `{...a, ...b, ...c}` will feature elements from `c` which + // override `b` and `a`. + for (var mixin in contextClass.mixins) { + var mixinRendererName = _typeToRendererClassName[mixin.element]; + if (mixinRendererName != null) { + var mixinMapName = '$mixinRendererName.propertyMap'; + var generics = _asGenerics([ + ...mixin.typeArguments + .map((e) => e.getDisplayString(withNullability: false)), + _contextTypeVariable + ]); + _buffer.writeln(' ...$mixinMapName$generics(),'); + } + } + } _buffer.writeln('};'); _buffer.writeln(''); } From 93692116b48ed8196e9b5c92e7ed0f7f110968f0 Mon Sep 17 00:00:00 2001 From: Sam Rawlins Date: Mon, 1 Feb 2021 15:30:36 -0800 Subject: [PATCH 2/3] Whoops analysis_options --- analysis_options.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/analysis_options.yaml b/analysis_options.yaml index 5e12339745..7681950262 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -6,7 +6,6 @@ analyzer: errors: unused_import: warning unused_shown_name: warning - todo: ignore exclude: - 'doc/**' - 'lib/src/third_party/pkg/**' From 34f398bed82f935eb6e60fccdaeae47a082ea5ff Mon Sep 17 00:00:00 2001 From: Sam Rawlins Date: Mon, 1 Feb 2021 15:38:13 -0800 Subject: [PATCH 3/3] Re-generate --- lib/src/generator/templates.dart | 2 +- lib/src/generator/templates.renderers.dart | 1575 +++++++++++++++++- test/mustachio/foo.renderers.dart | 3 +- tool/mustachio/codegen_runtime_renderer.dart | 3 +- 4 files changed, 1507 insertions(+), 76 deletions(-) diff --git a/lib/src/generator/templates.dart b/lib/src/generator/templates.dart index 1e53a5f6e2..1fdcd0102b 100644 --- a/lib/src/generator/templates.dart +++ b/lib/src/generator/templates.dart @@ -4,7 +4,7 @@ // TODO(srawlins): Add Renderer annotations for more types as the mustachio // implementation matures. -@Renderer(#renderIndex, Context()) +@Renderer(#renderIndex, Context(), visibleTypes: {Package}) library dartdoc.templates; import 'package:analyzer/file_system/file_system.dart'; diff --git a/lib/src/generator/templates.renderers.dart b/lib/src/generator/templates.renderers.dart index 892af00e22..378e908647 100644 --- a/lib/src/generator/templates.renderers.dart +++ b/lib/src/generator/templates.renderers.dart @@ -5,35 +5,1317 @@ // ignore_for_file: camel_case_types, unnecessary_cast, unused_element, unused_import import 'package:analyzer/file_system/file_system.dart'; -import 'package:dartdoc/src/generator/template_data.dart'; import 'package:dartdoc/dartdoc.dart'; +import 'package:dartdoc/src/generator/template_data.dart'; import 'package:dartdoc/src/mustachio/renderer_base.dart'; import 'package:dartdoc/src/mustachio/parser.dart'; +import 'package:dartdoc/src/warnings.dart'; import 'templates.dart'; -String _simpleResolveErrorMessage(List key, String type) => - 'Failed to resolve $key property chain on $type using a simple renderer; ' - 'expose the properties of $type by adding it to the @Renderer ' - "annotation's 'visibleTypes' list"; +String _simpleResolveErrorMessage(List key, String type) => + 'Failed to resolve $key property chain on $type using a simple renderer; ' + 'expose the properties of $type by adding it to the @Renderer ' + "annotation's 'visibleTypes' list"; + +String renderIndex(PackageTemplateData context, Template template) { + return _render_PackageTemplateData(context, template.ast, template); +} + +String _render_PackageTemplateData( + PackageTemplateData context, List ast, Template template, + {RendererBase parent}) { + var renderer = _Renderer_PackageTemplateData(context, parent, template); + renderer.renderBlock(ast); + return renderer.buffer.toString(); +} + +class _Renderer_PackageTemplateData extends RendererBase { + static Map> propertyMap< + CT_ extends PackageTemplateData>() => + { + 'hasHomepage': Property( + getValue: (CT_ c) => c.hasHomepage, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'bool*')); + } + }, + getBool: (CT_ c) => c.hasHomepage == true, + ), + 'homepage': Property( + getValue: (CT_ c) => c.homepage, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'String*')); + } + }, + isNullValue: (CT_ c) => c.homepage == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return renderSimple(c.homepage, ast, r.template, parent: r); + }, + ), + 'htmlBase': Property( + getValue: (CT_ c) => c.htmlBase, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'String*')); + } + }, + isNullValue: (CT_ c) => c.htmlBase == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return renderSimple(c.htmlBase, ast, r.template, parent: r); + }, + ), + 'includeVersion': Property( + getValue: (CT_ c) => c.includeVersion, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'bool*')); + } + }, + getBool: (CT_ c) => c.includeVersion == true, + ), + 'layoutTitle': Property( + getValue: (CT_ c) => c.layoutTitle, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'String*')); + } + }, + isNullValue: (CT_ c) => c.layoutTitle == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return renderSimple(c.layoutTitle, ast, r.template, parent: r); + }, + ), + 'metaDescription': Property( + getValue: (CT_ c) => c.metaDescription, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'String*')); + } + }, + isNullValue: (CT_ c) => c.metaDescription == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return renderSimple(c.metaDescription, ast, r.template, parent: r); + }, + ), + 'navLinks': Property( + getValue: (CT_ c) => c.navLinks, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError(_simpleResolveErrorMessage( + remainingNames, 'List*')); + } + }, + isEmptyIterable: (CT_ c) => c.navLinks?.isEmpty ?? true, + renderIterable: + (CT_ c, RendererBase r, List ast) { + var buffer = StringBuffer(); + for (var e in c.navLinks) { + buffer.write(renderSimple(e, ast, r.template, parent: r)); + } + return buffer.toString(); + }, + ), + 'package': Property( + getValue: (CT_ c) => c.package, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) return self.getValue(c).toString(); + var name = remainingNames.first; + if (_Renderer_Package.propertyMap().containsKey(name)) { + var nextProperty = _Renderer_Package.propertyMap()[name]; + return nextProperty.renderVariable( + self.getValue(c), nextProperty, [...remainingNames.skip(1)]); + } else { + throw PartialMustachioResolutionError(name, CT_); + } + }, + isNullValue: (CT_ c) => c.package == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_Package(c.package, ast, r.template, parent: r); + }, + ), + 'self': Property( + getValue: (CT_ c) => c.self, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) return self.getValue(c).toString(); + var name = remainingNames.first; + if (_Renderer_Package.propertyMap().containsKey(name)) { + var nextProperty = _Renderer_Package.propertyMap()[name]; + return nextProperty.renderVariable( + self.getValue(c), nextProperty, [...remainingNames.skip(1)]); + } else { + throw PartialMustachioResolutionError(name, CT_); + } + }, + isNullValue: (CT_ c) => c.self == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_Package(c.self, ast, r.template, parent: r); + }, + ), + 'title': Property( + getValue: (CT_ c) => c.title, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'String*')); + } + }, + isNullValue: (CT_ c) => c.title == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return renderSimple(c.title, ast, r.template, parent: r); + }, + ), + ..._Renderer_TemplateData.propertyMap(), + }; + + _Renderer_PackageTemplateData(PackageTemplateData context, + RendererBase parent, Template template) + : super(context, parent, template); + + @override + Property getProperty(String key) { + if (propertyMap().containsKey(key)) { + return propertyMap()[key]; + } else { + return null; + } + } +} + +String _render_Package( + Package context, List ast, Template template, + {RendererBase parent}) { + var renderer = _Renderer_Package(context, parent, template); + renderer.renderBlock(ast); + return renderer.buffer.toString(); +} + +class _Renderer_Package extends RendererBase { + static Map> propertyMap() => { + 'allLibraries': Property( + getValue: (CT_ c) => c.allLibraries, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'Set*')); + } + }, + isEmptyIterable: (CT_ c) => c.allLibraries?.isEmpty ?? true, + renderIterable: + (CT_ c, RendererBase r, List ast) { + var buffer = StringBuffer(); + for (var e in c.allLibraries) { + buffer.write(renderSimple(e, ast, r.template, parent: r)); + } + return buffer.toString(); + }, + ), + 'baseHref': Property( + getValue: (CT_ c) => c.baseHref, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'String*')); + } + }, + isNullValue: (CT_ c) => c.baseHref == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return renderSimple(c.baseHref, ast, r.template, parent: r); + }, + ), + 'canonicalLibrary': Property( + getValue: (CT_ c) => c.canonicalLibrary, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'Library*')); + } + }, + isNullValue: (CT_ c) => c.canonicalLibrary == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return renderSimple(c.canonicalLibrary, ast, r.template, parent: r); + }, + ), + 'categories': Property( + getValue: (CT_ c) => c.categories, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError(_simpleResolveErrorMessage( + remainingNames, 'List*')); + } + }, + isEmptyIterable: (CT_ c) => c.categories?.isEmpty ?? true, + renderIterable: + (CT_ c, RendererBase r, List ast) { + var buffer = StringBuffer(); + for (var e in c.categories) { + buffer.write(renderSimple(e, ast, r.template, parent: r)); + } + return buffer.toString(); + }, + ), + 'categoriesWithPublicLibraries': Property( + getValue: (CT_ c) => c.categoriesWithPublicLibraries, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError(_simpleResolveErrorMessage( + remainingNames, 'Iterable*')); + } + }, + isEmptyIterable: (CT_ c) => + c.categoriesWithPublicLibraries?.isEmpty ?? true, + renderIterable: + (CT_ c, RendererBase r, List ast) { + var buffer = StringBuffer(); + for (var e in c.categoriesWithPublicLibraries) { + buffer.write( + _render_LibraryContainer(e, ast, r.template, parent: r)); + } + return buffer.toString(); + }, + ), + 'config': Property( + getValue: (CT_ c) => c.config, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError(_simpleResolveErrorMessage( + remainingNames, 'DartdocOptionContext*')); + } + }, + isNullValue: (CT_ c) => c.config == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return renderSimple(c.config, ast, r.template, parent: r); + }, + ), + 'containerOrder': Property( + getValue: (CT_ c) => c.containerOrder, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'List*')); + } + }, + isEmptyIterable: (CT_ c) => c.containerOrder?.isEmpty ?? true, + renderIterable: + (CT_ c, RendererBase r, List ast) { + var buffer = StringBuffer(); + for (var e in c.containerOrder) { + buffer.write(renderSimple(e, ast, r.template, parent: r)); + } + return buffer.toString(); + }, + ), + 'defaultCategory': Property( + getValue: (CT_ c) => c.defaultCategory, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) return self.getValue(c).toString(); + var name = remainingNames.first; + if (_Renderer_LibraryContainer.propertyMap().containsKey(name)) { + var nextProperty = _Renderer_LibraryContainer.propertyMap()[name]; + return nextProperty.renderVariable( + self.getValue(c), nextProperty, [...remainingNames.skip(1)]); + } else { + throw PartialMustachioResolutionError(name, CT_); + } + }, + isNullValue: (CT_ c) => c.defaultCategory == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_LibraryContainer(c.defaultCategory, ast, r.template, + parent: r); + }, + ), + 'documentation': Property( + getValue: (CT_ c) => c.documentation, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'String*')); + } + }, + isNullValue: (CT_ c) => c.documentation == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return renderSimple(c.documentation, ast, r.template, parent: r); + }, + ), + 'documentationAsHtml': Property( + getValue: (CT_ c) => c.documentationAsHtml, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'String*')); + } + }, + isNullValue: (CT_ c) => c.documentationAsHtml == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return renderSimple(c.documentationAsHtml, ast, r.template, + parent: r); + }, + ), + 'documentationFile': Property( + getValue: (CT_ c) => c.documentationFile, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'File*')); + } + }, + isNullValue: (CT_ c) => c.documentationFile == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return renderSimple(c.documentationFile, ast, r.template, + parent: r); + }, + ), + 'documentationFrom': Property( + getValue: (CT_ c) => c.documentationFrom, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError(_simpleResolveErrorMessage( + remainingNames, 'List*')); + } + }, + isEmptyIterable: (CT_ c) => c.documentationFrom?.isEmpty ?? true, + renderIterable: + (CT_ c, RendererBase r, List ast) { + var buffer = StringBuffer(); + for (var e in c.documentationFrom) { + buffer.write(_render_Locatable(e, ast, r.template, parent: r)); + } + return buffer.toString(); + }, + ), + 'documentedCategories': Property( + getValue: (CT_ c) => c.documentedCategories, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError(_simpleResolveErrorMessage( + remainingNames, 'Iterable*')); + } + }, + isEmptyIterable: (CT_ c) => c.documentedCategories?.isEmpty ?? true, + renderIterable: + (CT_ c, RendererBase r, List ast) { + var buffer = StringBuffer(); + for (var e in c.documentedCategories) { + buffer.write(renderSimple(e, ast, r.template, parent: r)); + } + return buffer.toString(); + }, + ), + 'documentedCategoriesSorted': Property( + getValue: (CT_ c) => c.documentedCategoriesSorted, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError(_simpleResolveErrorMessage( + remainingNames, 'Iterable*')); + } + }, + isEmptyIterable: (CT_ c) => + c.documentedCategoriesSorted?.isEmpty ?? true, + renderIterable: + (CT_ c, RendererBase r, List ast) { + var buffer = StringBuffer(); + for (var e in c.documentedCategoriesSorted) { + buffer.write(renderSimple(e, ast, r.template, parent: r)); + } + return buffer.toString(); + }, + ), + 'documentedWhere': Property( + getValue: (CT_ c) => c.documentedWhere, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError(_simpleResolveErrorMessage( + remainingNames, 'DocumentLocation*')); + } + }, + isNullValue: (CT_ c) => c.documentedWhere == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return renderSimple(c.documentedWhere, ast, r.template, parent: r); + }, + ), + 'element': Property( + getValue: (CT_ c) => c.element, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'Element*')); + } + }, + isNullValue: (CT_ c) => c.element == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return renderSimple(c.element, ast, r.template, parent: r); + }, + ), + 'enclosingElement': Property( + getValue: (CT_ c) => c.enclosingElement, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) return self.getValue(c).toString(); + var name = remainingNames.first; + if (_Renderer_Warnable.propertyMap().containsKey(name)) { + var nextProperty = _Renderer_Warnable.propertyMap()[name]; + return nextProperty.renderVariable( + self.getValue(c), nextProperty, [...remainingNames.skip(1)]); + } else { + throw PartialMustachioResolutionError(name, CT_); + } + }, + isNullValue: (CT_ c) => c.enclosingElement == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_Warnable(c.enclosingElement, ast, r.template, + parent: r); + }, + ), + 'enclosingName': Property( + getValue: (CT_ c) => c.enclosingName, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'String*')); + } + }, + isNullValue: (CT_ c) => c.enclosingName == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return renderSimple(c.enclosingName, ast, r.template, parent: r); + }, + ), + 'filePath': Property( + getValue: (CT_ c) => c.filePath, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'String*')); + } + }, + isNullValue: (CT_ c) => c.filePath == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return renderSimple(c.filePath, ast, r.template, parent: r); + }, + ), + 'fileType': Property( + getValue: (CT_ c) => c.fileType, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'String*')); + } + }, + isNullValue: (CT_ c) => c.fileType == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return renderSimple(c.fileType, ast, r.template, parent: r); + }, + ), + 'fullyQualifiedName': Property( + getValue: (CT_ c) => c.fullyQualifiedName, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'String*')); + } + }, + isNullValue: (CT_ c) => c.fullyQualifiedName == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return renderSimple(c.fullyQualifiedName, ast, r.template, + parent: r); + }, + ), + 'hasCategories': Property( + getValue: (CT_ c) => c.hasCategories, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'bool*')); + } + }, + getBool: (CT_ c) => c.hasCategories == true, + ), + 'hasDocumentation': Property( + getValue: (CT_ c) => c.hasDocumentation, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'bool*')); + } + }, + getBool: (CT_ c) => c.hasDocumentation == true, + ), + 'hasDocumentationFile': Property( + getValue: (CT_ c) => c.hasDocumentationFile, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'bool*')); + } + }, + getBool: (CT_ c) => c.hasDocumentationFile == true, + ), + 'hasDocumentedCategories': Property( + getValue: (CT_ c) => c.hasDocumentedCategories, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'bool*')); + } + }, + getBool: (CT_ c) => c.hasDocumentedCategories == true, + ), + 'hasExtendedDocumentation': Property( + getValue: (CT_ c) => c.hasExtendedDocumentation, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'bool*')); + } + }, + getBool: (CT_ c) => c.hasExtendedDocumentation == true, + ), + 'hasHomepage': Property( + getValue: (CT_ c) => c.hasHomepage, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'bool*')); + } + }, + getBool: (CT_ c) => c.hasHomepage == true, + ), + 'homepage': Property( + getValue: (CT_ c) => c.homepage, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'String*')); + } + }, + isNullValue: (CT_ c) => c.homepage == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return renderSimple(c.homepage, ast, r.template, parent: r); + }, + ), + 'href': Property( + getValue: (CT_ c) => c.href, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'String*')); + } + }, + isNullValue: (CT_ c) => c.href == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return renderSimple(c.href, ast, r.template, parent: r); + }, + ), + 'isCanonical': Property( + getValue: (CT_ c) => c.isCanonical, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'bool*')); + } + }, + getBool: (CT_ c) => c.isCanonical == true, + ), + 'isDocumented': Property( + getValue: (CT_ c) => c.isDocumented, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'bool*')); + } + }, + getBool: (CT_ c) => c.isDocumented == true, + ), + 'isFirstPackage': Property( + getValue: (CT_ c) => c.isFirstPackage, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'bool*')); + } + }, + getBool: (CT_ c) => c.isFirstPackage == true, + ), + 'isLocal': Property( + getValue: (CT_ c) => c.isLocal, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'bool*')); + } + }, + getBool: (CT_ c) => c.isLocal == true, + ), + 'isPublic': Property( + getValue: (CT_ c) => c.isPublic, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'bool*')); + } + }, + getBool: (CT_ c) => c.isPublic == true, + ), + 'isSdk': Property( + getValue: (CT_ c) => c.isSdk, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'bool*')); + } + }, + getBool: (CT_ c) => c.isSdk == true, + ), + 'kind': Property( + getValue: (CT_ c) => c.kind, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'String*')); + } + }, + isNullValue: (CT_ c) => c.kind == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return renderSimple(c.kind, ast, r.template, parent: r); + }, + ), + 'location': Property( + getValue: (CT_ c) => c.location, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'String*')); + } + }, + isNullValue: (CT_ c) => c.location == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return renderSimple(c.location, ast, r.template, parent: r); + }, + ), + 'locationPieces': Property( + getValue: (CT_ c) => c.locationPieces, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'Set*')); + } + }, + isEmptyIterable: (CT_ c) => c.locationPieces?.isEmpty ?? true, + renderIterable: + (CT_ c, RendererBase r, List ast) { + var buffer = StringBuffer(); + for (var e in c.locationPieces) { + buffer.write(renderSimple(e, ast, r.template, parent: r)); + } + return buffer.toString(); + }, + ), + 'name': Property( + getValue: (CT_ c) => c.name, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'String*')); + } + }, + isNullValue: (CT_ c) => c.name == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return renderSimple(c.name, ast, r.template, parent: r); + }, + ), + 'nameToCategory': Property( + getValue: (CT_ c) => c.nameToCategory, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError(_simpleResolveErrorMessage( + remainingNames, 'Map*')); + } + }, + isNullValue: (CT_ c) => c.nameToCategory == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return renderSimple(c.nameToCategory, ast, r.template, parent: r); + }, + ), + 'oneLineDoc': Property( + getValue: (CT_ c) => c.oneLineDoc, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'String*')); + } + }, + isNullValue: (CT_ c) => c.oneLineDoc == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return renderSimple(c.oneLineDoc, ast, r.template, parent: r); + }, + ), + 'package': Property( + getValue: (CT_ c) => c.package, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) return self.getValue(c).toString(); + var name = remainingNames.first; + if (_Renderer_Package.propertyMap().containsKey(name)) { + var nextProperty = _Renderer_Package.propertyMap()[name]; + return nextProperty.renderVariable( + self.getValue(c), nextProperty, [...remainingNames.skip(1)]); + } else { + throw PartialMustachioResolutionError(name, CT_); + } + }, + isNullValue: (CT_ c) => c.package == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_Package(c.package, ast, r.template, parent: r); + }, + ), + 'packageGraph': Property( + getValue: (CT_ c) => c.packageGraph, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'PackageGraph*')); + } + }, + isNullValue: (CT_ c) => c.packageGraph == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return renderSimple(c.packageGraph, ast, r.template, parent: r); + }, + ), + 'packageMeta': Property( + getValue: (CT_ c) => c.packageMeta, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'PackageMeta*')); + } + }, + isNullValue: (CT_ c) => c.packageMeta == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return renderSimple(c.packageMeta, ast, r.template, parent: r); + }, + ), + 'packagePath': Property( + getValue: (CT_ c) => c.packagePath, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'String*')); + } + }, + isNullValue: (CT_ c) => c.packagePath == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return renderSimple(c.packagePath, ast, r.template, parent: r); + }, + ), + 'publicLibraries': Property( + getValue: (CT_ c) => c.publicLibraries, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError(_simpleResolveErrorMessage( + remainingNames, 'Iterable*')); + } + }, + isEmptyIterable: (CT_ c) => c.publicLibraries?.isEmpty ?? true, + renderIterable: + (CT_ c, RendererBase r, List ast) { + var buffer = StringBuffer(); + for (var e in c.publicLibraries) { + buffer.write(renderSimple(e, ast, r.template, parent: r)); + } + return buffer.toString(); + }, + ), + 'toolInvocationIndex': Property( + getValue: (CT_ c) => c.toolInvocationIndex, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'int*')); + } + }, + isNullValue: (CT_ c) => c.toolInvocationIndex == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return renderSimple(c.toolInvocationIndex, ast, r.template, + parent: r); + }, + ), + 'usedAnimationIdsByHref': Property( + getValue: (CT_ c) => c.usedAnimationIdsByHref, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError(_simpleResolveErrorMessage( + remainingNames, 'Map*>*')); + } + }, + isNullValue: (CT_ c) => c.usedAnimationIdsByHref == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return renderSimple(c.usedAnimationIdsByHref, ast, r.template, + parent: r); + }, + ), + 'version': Property( + getValue: (CT_ c) => c.version, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'String*')); + } + }, + isNullValue: (CT_ c) => c.version == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return renderSimple(c.version, ast, r.template, parent: r); + }, + ), + ..._Renderer_LibraryContainer.propertyMap(), + ..._Renderer_Nameable.propertyMap(), + ..._Renderer_Locatable.propertyMap(), + ..._Renderer_Canonicalization.propertyMap(), + ..._Renderer_Warnable.propertyMap(), + }; + + _Renderer_Package( + Package context, RendererBase parent, Template template) + : super(context, parent, template); + + @override + Property getProperty(String key) { + if (propertyMap().containsKey(key)) { + return propertyMap()[key]; + } else { + return null; + } + } +} + +String _render_Nameable( + Nameable context, List ast, Template template, + {RendererBase parent}) { + var renderer = _Renderer_Nameable(context, parent, template); + renderer.renderBlock(ast); + return renderer.buffer.toString(); +} + +class _Renderer_Nameable extends RendererBase { + static Map> propertyMap() => { + 'fullyQualifiedName': Property( + getValue: (CT_ c) => c.fullyQualifiedName, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'String*')); + } + }, + isNullValue: (CT_ c) => c.fullyQualifiedName == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return renderSimple(c.fullyQualifiedName, ast, r.template, + parent: r); + }, + ), + 'name': Property( + getValue: (CT_ c) => c.name, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'String*')); + } + }, + isNullValue: (CT_ c) => c.name == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return renderSimple(c.name, ast, r.template, parent: r); + }, + ), + 'namePart': Property( + getValue: (CT_ c) => c.namePart, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'String*')); + } + }, + isNullValue: (CT_ c) => c.namePart == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return renderSimple(c.namePart, ast, r.template, parent: r); + }, + ), + 'namePieces': Property( + getValue: (CT_ c) => c.namePieces, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'Set*')); + } + }, + isEmptyIterable: (CT_ c) => c.namePieces?.isEmpty ?? true, + renderIterable: + (CT_ c, RendererBase r, List ast) { + var buffer = StringBuffer(); + for (var e in c.namePieces) { + buffer.write(renderSimple(e, ast, r.template, parent: r)); + } + return buffer.toString(); + }, + ), + ..._Renderer_Object.propertyMap(), + }; + + _Renderer_Nameable( + Nameable context, RendererBase parent, Template template) + : super(context, parent, template); + + @override + Property getProperty(String key) { + if (propertyMap().containsKey(key)) { + return propertyMap()[key]; + } else { + return null; + } + } +} + +String _render_Locatable( + Locatable context, List ast, Template template, + {RendererBase parent}) { + var renderer = _Renderer_Locatable(context, parent, template); + renderer.renderBlock(ast); + return renderer.buffer.toString(); +} + +class _Renderer_Locatable extends RendererBase { + static Map> propertyMap() => { + 'documentationFrom': Property( + getValue: (CT_ c) => c.documentationFrom, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError(_simpleResolveErrorMessage( + remainingNames, 'List*')); + } + }, + isEmptyIterable: (CT_ c) => c.documentationFrom?.isEmpty ?? true, + renderIterable: + (CT_ c, RendererBase r, List ast) { + var buffer = StringBuffer(); + for (var e in c.documentationFrom) { + buffer.write(_render_Locatable(e, ast, r.template, parent: r)); + } + return buffer.toString(); + }, + ), + 'documentationIsLocal': Property( + getValue: (CT_ c) => c.documentationIsLocal, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'bool*')); + } + }, + getBool: (CT_ c) => c.documentationIsLocal == true, + ), + 'fullyQualifiedName': Property( + getValue: (CT_ c) => c.fullyQualifiedName, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'String*')); + } + }, + isNullValue: (CT_ c) => c.fullyQualifiedName == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return renderSimple(c.fullyQualifiedName, ast, r.template, + parent: r); + }, + ), + 'href': Property( + getValue: (CT_ c) => c.href, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'String*')); + } + }, + isNullValue: (CT_ c) => c.href == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return renderSimple(c.href, ast, r.template, parent: r); + }, + ), + 'location': Property( + getValue: (CT_ c) => c.location, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'String*')); + } + }, + isNullValue: (CT_ c) => c.location == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return renderSimple(c.location, ast, r.template, parent: r); + }, + ), + ..._Renderer_Object.propertyMap(), + }; + + _Renderer_Locatable( + Locatable context, RendererBase parent, Template template) + : super(context, parent, template); -String renderIndex(PackageTemplateData context, Template template) { - return _render_PackageTemplateData(context, template.ast, template); + @override + Property getProperty(String key) { + if (propertyMap().containsKey(key)) { + return propertyMap()[key]; + } else { + return null; + } + } } -String _render_PackageTemplateData( - PackageTemplateData context, List ast, Template template, +String _render_Canonicalization( + Canonicalization context, List ast, Template template, {RendererBase parent}) { - var renderer = _Renderer_PackageTemplateData(context, parent, template); + var renderer = _Renderer_Canonicalization(context, parent, template); renderer.renderBlock(ast); return renderer.buffer.toString(); } -class _Renderer_PackageTemplateData extends RendererBase { +class _Renderer_Canonicalization extends RendererBase { static Map> propertyMap< - CT_ extends PackageTemplateData>() => + CT_ extends Canonicalization>() => { - 'hasHomepage': Property( - getValue: (CT_ c) => c.hasHomepage, + 'canonicalLibrary': Property( + getValue: (CT_ c) => c.canonicalLibrary, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'Library*')); + } + }, + isNullValue: (CT_ c) => c.canonicalLibrary == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return renderSimple(c.canonicalLibrary, ast, r.template, parent: r); + }, + ), + 'commentRefs': Property( + getValue: (CT_ c) => c.commentRefs, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError(_simpleResolveErrorMessage( + remainingNames, 'List*')); + } + }, + isEmptyIterable: (CT_ c) => c.commentRefs?.isEmpty ?? true, + renderIterable: + (CT_ c, RendererBase r, List ast) { + var buffer = StringBuffer(); + for (var e in c.commentRefs) { + buffer.write(renderSimple(e, ast, r.template, parent: r)); + } + return buffer.toString(); + }, + ), + 'isCanonical': Property( + getValue: (CT_ c) => c.isCanonical, renderVariable: (CT_ c, Property self, List remainingNames) { if (remainingNames.isEmpty) { @@ -43,55 +1325,162 @@ class _Renderer_PackageTemplateData extends RendererBase { _simpleResolveErrorMessage(remainingNames, 'bool*')); } }, - getBool: (CT_ c) => c.hasHomepage == true, + getBool: (CT_ c) => c.isCanonical == true, ), - 'homepage': Property( - getValue: (CT_ c) => c.homepage, + 'locationPieces': Property( + getValue: (CT_ c) => c.locationPieces, renderVariable: (CT_ c, Property self, List remainingNames) { if (remainingNames.isEmpty) { return self.getValue(c).toString(); } else { throw MustachioResolutionError( - _simpleResolveErrorMessage(remainingNames, 'String*')); + _simpleResolveErrorMessage(remainingNames, 'Set*')); } }, - isNullValue: (CT_ c) => c.homepage == null, - renderValue: (CT_ c, RendererBase r, List ast) { - return renderSimple(c.homepage, ast, r.template, parent: r); + isEmptyIterable: (CT_ c) => c.locationPieces?.isEmpty ?? true, + renderIterable: + (CT_ c, RendererBase r, List ast) { + var buffer = StringBuffer(); + for (var e in c.locationPieces) { + buffer.write(renderSimple(e, ast, r.template, parent: r)); + } + return buffer.toString(); }, ), - 'htmlBase': Property( - getValue: (CT_ c) => c.htmlBase, + ..._Renderer_Object.propertyMap(), + }; + + _Renderer_Canonicalization( + Canonicalization context, RendererBase parent, Template template) + : super(context, parent, template); + + @override + Property getProperty(String key) { + if (propertyMap().containsKey(key)) { + return propertyMap()[key]; + } else { + return null; + } + } +} + +String _render_Warnable( + Warnable context, List ast, Template template, + {RendererBase parent}) { + var renderer = _Renderer_Warnable(context, parent, template); + renderer.renderBlock(ast); + return renderer.buffer.toString(); +} + +class _Renderer_Warnable extends RendererBase { + static Map> propertyMap() => { + 'element': Property( + getValue: (CT_ c) => c.element, renderVariable: (CT_ c, Property self, List remainingNames) { if (remainingNames.isEmpty) { return self.getValue(c).toString(); } else { throw MustachioResolutionError( - _simpleResolveErrorMessage(remainingNames, 'String*')); + _simpleResolveErrorMessage(remainingNames, 'Element*')); } }, - isNullValue: (CT_ c) => c.htmlBase == null, + isNullValue: (CT_ c) => c.element == null, renderValue: (CT_ c, RendererBase r, List ast) { - return renderSimple(c.htmlBase, ast, r.template, parent: r); + return renderSimple(c.element, ast, r.template, parent: r); }, ), - 'includeVersion': Property( - getValue: (CT_ c) => c.includeVersion, + 'enclosingElement': Property( + getValue: (CT_ c) => c.enclosingElement, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) return self.getValue(c).toString(); + var name = remainingNames.first; + if (_Renderer_Warnable.propertyMap().containsKey(name)) { + var nextProperty = _Renderer_Warnable.propertyMap()[name]; + return nextProperty.renderVariable( + self.getValue(c), nextProperty, [...remainingNames.skip(1)]); + } else { + throw PartialMustachioResolutionError(name, CT_); + } + }, + isNullValue: (CT_ c) => c.enclosingElement == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_Warnable(c.enclosingElement, ast, r.template, + parent: r); + }, + ), + 'package': Property( + getValue: (CT_ c) => c.package, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) return self.getValue(c).toString(); + var name = remainingNames.first; + if (_Renderer_Package.propertyMap().containsKey(name)) { + var nextProperty = _Renderer_Package.propertyMap()[name]; + return nextProperty.renderVariable( + self.getValue(c), nextProperty, [...remainingNames.skip(1)]); + } else { + throw PartialMustachioResolutionError(name, CT_); + } + }, + isNullValue: (CT_ c) => c.package == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_Package(c.package, ast, r.template, parent: r); + }, + ), + }; + + _Renderer_Warnable( + Warnable context, RendererBase parent, Template template) + : super(context, parent, template); + + @override + Property getProperty(String key) { + if (propertyMap().containsKey(key)) { + return propertyMap()[key]; + } else { + return null; + } + } +} + +String _render_LibraryContainer( + LibraryContainer context, List ast, Template template, + {RendererBase parent}) { + var renderer = _Renderer_LibraryContainer(context, parent, template); + renderer.renderBlock(ast); + return renderer.buffer.toString(); +} + +class _Renderer_LibraryContainer extends RendererBase { + static Map> propertyMap< + CT_ extends LibraryContainer>() => + { + 'containerOrder': Property( + getValue: (CT_ c) => c.containerOrder, renderVariable: (CT_ c, Property self, List remainingNames) { if (remainingNames.isEmpty) { return self.getValue(c).toString(); } else { throw MustachioResolutionError( - _simpleResolveErrorMessage(remainingNames, 'bool*')); + _simpleResolveErrorMessage(remainingNames, 'List*')); } }, - getBool: (CT_ c) => c.includeVersion == true, + isEmptyIterable: (CT_ c) => c.containerOrder?.isEmpty ?? true, + renderIterable: + (CT_ c, RendererBase r, List ast) { + var buffer = StringBuffer(); + for (var e in c.containerOrder) { + buffer.write(renderSimple(e, ast, r.template, parent: r)); + } + return buffer.toString(); + }, ), - 'layoutTitle': Property( - getValue: (CT_ c) => c.layoutTitle, + 'enclosingName': Property( + getValue: (CT_ c) => c.enclosingName, renderVariable: (CT_ c, Property self, List remainingNames) { if (remainingNames.isEmpty) { @@ -101,82 +1490,118 @@ class _Renderer_PackageTemplateData extends RendererBase { _simpleResolveErrorMessage(remainingNames, 'String*')); } }, - isNullValue: (CT_ c) => c.layoutTitle == null, + isNullValue: (CT_ c) => c.enclosingName == null, renderValue: (CT_ c, RendererBase r, List ast) { - return renderSimple(c.layoutTitle, ast, r.template, parent: r); + return renderSimple(c.enclosingName, ast, r.template, parent: r); }, ), - 'metaDescription': Property( - getValue: (CT_ c) => c.metaDescription, + 'hasPublicLibraries': Property( + getValue: (CT_ c) => c.hasPublicLibraries, renderVariable: (CT_ c, Property self, List remainingNames) { if (remainingNames.isEmpty) { return self.getValue(c).toString(); } else { throw MustachioResolutionError( - _simpleResolveErrorMessage(remainingNames, 'String*')); + _simpleResolveErrorMessage(remainingNames, 'bool*')); } }, - isNullValue: (CT_ c) => c.metaDescription == null, - renderValue: (CT_ c, RendererBase r, List ast) { - return renderSimple(c.metaDescription, ast, r.template, parent: r); + getBool: (CT_ c) => c.hasPublicLibraries == true, + ), + 'isSdk': Property( + getValue: (CT_ c) => c.isSdk, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError( + _simpleResolveErrorMessage(remainingNames, 'bool*')); + } }, + getBool: (CT_ c) => c.isSdk == true, ), - 'navLinks': Property( - getValue: (CT_ c) => c.navLinks, + 'libraries': Property( + getValue: (CT_ c) => c.libraries, renderVariable: (CT_ c, Property self, List remainingNames) { if (remainingNames.isEmpty) { return self.getValue(c).toString(); } else { throw MustachioResolutionError(_simpleResolveErrorMessage( - remainingNames, 'List*')); + remainingNames, 'List*')); } }, - isEmptyIterable: (CT_ c) => c.navLinks?.isEmpty ?? true, + isEmptyIterable: (CT_ c) => c.libraries?.isEmpty ?? true, renderIterable: (CT_ c, RendererBase r, List ast) { var buffer = StringBuffer(); - for (var e in c.navLinks) { + for (var e in c.libraries) { buffer.write(renderSimple(e, ast, r.template, parent: r)); } return buffer.toString(); }, ), - 'package': Property( - getValue: (CT_ c) => c.package, + 'packageGraph': Property( + getValue: (CT_ c) => c.packageGraph, renderVariable: (CT_ c, Property self, List remainingNames) { if (remainingNames.isEmpty) { return self.getValue(c).toString(); } else { throw MustachioResolutionError( - _simpleResolveErrorMessage(remainingNames, 'Package*')); + _simpleResolveErrorMessage(remainingNames, 'PackageGraph*')); } }, - isNullValue: (CT_ c) => c.package == null, + isNullValue: (CT_ c) => c.packageGraph == null, renderValue: (CT_ c, RendererBase r, List ast) { - return renderSimple(c.package, ast, r.template, parent: r); + return renderSimple(c.packageGraph, ast, r.template, parent: r); }, ), - 'self': Property( - getValue: (CT_ c) => c.self, + 'publicLibraries': Property( + getValue: (CT_ c) => c.publicLibraries, renderVariable: (CT_ c, Property self, List remainingNames) { if (remainingNames.isEmpty) { return self.getValue(c).toString(); } else { - throw MustachioResolutionError( - _simpleResolveErrorMessage(remainingNames, 'Package*')); + throw MustachioResolutionError(_simpleResolveErrorMessage( + remainingNames, 'Iterable*')); } }, - isNullValue: (CT_ c) => c.self == null, - renderValue: (CT_ c, RendererBase r, List ast) { - return renderSimple(c.self, ast, r.template, parent: r); + isEmptyIterable: (CT_ c) => c.publicLibraries?.isEmpty ?? true, + renderIterable: + (CT_ c, RendererBase r, List ast) { + var buffer = StringBuffer(); + for (var e in c.publicLibraries) { + buffer.write(renderSimple(e, ast, r.template, parent: r)); + } + return buffer.toString(); }, ), - 'title': Property( - getValue: (CT_ c) => c.title, + 'publicLibrariesSorted': Property( + getValue: (CT_ c) => c.publicLibrariesSorted, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } else { + throw MustachioResolutionError(_simpleResolveErrorMessage( + remainingNames, 'Iterable*')); + } + }, + isEmptyIterable: (CT_ c) => c.publicLibrariesSorted?.isEmpty ?? true, + renderIterable: + (CT_ c, RendererBase r, List ast) { + var buffer = StringBuffer(); + for (var e in c.publicLibrariesSorted) { + buffer.write(renderSimple(e, ast, r.template, parent: r)); + } + return buffer.toString(); + }, + ), + 'sortKey': Property( + getValue: (CT_ c) => c.sortKey, renderVariable: (CT_ c, Property self, List remainingNames) { if (remainingNames.isEmpty) { @@ -186,22 +1611,22 @@ class _Renderer_PackageTemplateData extends RendererBase { _simpleResolveErrorMessage(remainingNames, 'String*')); } }, - isNullValue: (CT_ c) => c.title == null, + isNullValue: (CT_ c) => c.sortKey == null, renderValue: (CT_ c, RendererBase r, List ast) { - return renderSimple(c.title, ast, r.template, parent: r); + return renderSimple(c.sortKey, ast, r.template, parent: r); }, ), - ..._Renderer_TemplateData.propertyMap(), + ..._Renderer_Object.propertyMap(), }; - _Renderer_PackageTemplateData(PackageTemplateData context, - RendererBase parent, Template template) + _Renderer_LibraryContainer( + LibraryContainer context, RendererBase parent, Template template) : super(context, parent, template); @override - Property getProperty(String key) { - if (propertyMap().containsKey(key)) { - return propertyMap()[key]; + Property getProperty(String key) { + if (propertyMap().containsKey(key)) { + return propertyMap()[key]; } else { return null; } @@ -283,16 +1708,20 @@ class _Renderer_TemplateData getValue: (CT_ c) => c.defaultPackage, renderVariable: (CT_ c, Property self, List remainingNames) { - if (remainingNames.isEmpty) { - return self.getValue(c).toString(); + if (remainingNames.isEmpty) return self.getValue(c).toString(); + var name = remainingNames.first; + if (_Renderer_Package.propertyMap().containsKey(name)) { + var nextProperty = _Renderer_Package.propertyMap()[name]; + return nextProperty.renderVariable( + self.getValue(c), nextProperty, [...remainingNames.skip(1)]); } else { - throw MustachioResolutionError( - _simpleResolveErrorMessage(remainingNames, 'Package*')); + throw PartialMustachioResolutionError(name, CT_); } }, isNullValue: (CT_ c) => c.defaultPackage == null, renderValue: (CT_ c, RendererBase r, List ast) { - return renderSimple(c.defaultPackage, ast, r.template, parent: r); + return _render_Package(c.defaultPackage, ast, r.template, + parent: r); }, ), 'hasFooterVersion': Property( @@ -414,7 +1843,7 @@ class _Renderer_TemplateData (CT_ c, RendererBase r, List ast) { var buffer = StringBuffer(); for (var e in c.localPackages) { - buffer.write(renderSimple(e, ast, r.template, parent: r)); + buffer.write(_render_Package(e, ast, r.template, parent: r)); } return buffer.toString(); }, diff --git a/test/mustachio/foo.renderers.dart b/test/mustachio/foo.renderers.dart index b9fa51794c..c9a0b5f32f 100644 --- a/test/mustachio/foo.renderers.dart +++ b/test/mustachio/foo.renderers.dart @@ -5,10 +5,11 @@ // ignore_for_file: camel_case_types, unnecessary_cast, unused_element, unused_import import 'package:analyzer/file_system/file_system.dart'; -import 'package:dartdoc/src/generator/template_data.dart'; import 'package:dartdoc/dartdoc.dart'; +import 'package:dartdoc/src/generator/template_data.dart'; import 'package:dartdoc/src/mustachio/renderer_base.dart'; import 'package:dartdoc/src/mustachio/parser.dart'; +import 'package:dartdoc/src/warnings.dart'; import 'foo.dart'; String _simpleResolveErrorMessage(List key, String type) => diff --git a/tool/mustachio/codegen_runtime_renderer.dart b/tool/mustachio/codegen_runtime_renderer.dart index 82995e955d..16f491891f 100644 --- a/tool/mustachio/codegen_runtime_renderer.dart +++ b/tool/mustachio/codegen_runtime_renderer.dart @@ -87,10 +87,11 @@ class RuntimeRenderersBuilder { // ignore_for_file: camel_case_types, unnecessary_cast, unused_element, unused_import import 'package:analyzer/file_system/file_system.dart'; -import 'package:dartdoc/src/generator/template_data.dart'; import 'package:dartdoc/dartdoc.dart'; +import 'package:dartdoc/src/generator/template_data.dart'; import 'package:dartdoc/src/mustachio/renderer_base.dart'; import 'package:dartdoc/src/mustachio/parser.dart'; +import 'package:dartdoc/src/warnings.dart'; import '${p.basename(_sourceUri.path)}'; String _simpleResolveErrorMessage(List key, String type) =>