diff --git a/lib/src/generator/templates.renderers.dart b/lib/src/generator/templates.renderers.dart index 51fb67ab80..0fda459ac8 100644 --- a/lib/src/generator/templates.renderers.dart +++ b/lib/src/generator/templates.renderers.dart @@ -18,61 +18,90 @@ String renderIndex(PackageTemplateData context, List ast, } class _Renderer_PackageTemplateData extends RendererBase { - static Map> - propertyMap() => { - 'hasHomepage': Property( - getValue: (CT_ c) => c.hasHomepage, - getProperties: _Renderer_bool.propertyMap, - getBool: (CT_ c) => c.hasHomepage == true, - ), - 'homepage': Property( - getValue: (CT_ c) => c.homepage, - getProperties: _Renderer_String.propertyMap, - ), - 'htmlBase': Property( - getValue: (CT_ c) => c.htmlBase, - getProperties: _Renderer_String.propertyMap, - ), - 'includeVersion': Property( - getValue: (CT_ c) => c.includeVersion, - getProperties: _Renderer_bool.propertyMap, - getBool: (CT_ c) => c.includeVersion == true, - ), - 'layoutTitle': Property( - getValue: (CT_ c) => c.layoutTitle, - getProperties: _Renderer_String.propertyMap, - ), - 'metaDescription': Property( - getValue: (CT_ c) => c.metaDescription, - getProperties: _Renderer_String.propertyMap, - ), - 'navLinks': Property( - getValue: (CT_ c) => c.navLinks, - getProperties: _Renderer_List.propertyMap, - 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(_render_Documentable(e, ast, parent: r)); - } - return buffer.toString(); - }, - ), - 'package': Property( - getValue: (CT_ c) => c.package, - getProperties: _Renderer_Package.propertyMap, - ), - 'self': Property( - getValue: (CT_ c) => c.self, - getProperties: _Renderer_Package.propertyMap, - ), - 'title': Property( - getValue: (CT_ c) => c.title, - getProperties: _Renderer_String.propertyMap, - ), - ..._Renderer_TemplateData.propertyMap(), - }; + static Map> propertyMap< + CT_ extends PackageTemplateData>() => + { + 'hasHomepage': Property( + getValue: (CT_ c) => c.hasHomepage, + getProperties: _Renderer_bool.propertyMap, + getBool: (CT_ c) => c.hasHomepage == true, + ), + 'homepage': Property( + getValue: (CT_ c) => c.homepage, + getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.homepage == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.homepage, ast, parent: r); + }, + ), + 'htmlBase': Property( + getValue: (CT_ c) => c.htmlBase, + getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.htmlBase == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.htmlBase, ast, parent: r); + }, + ), + 'includeVersion': Property( + getValue: (CT_ c) => c.includeVersion, + getProperties: _Renderer_bool.propertyMap, + getBool: (CT_ c) => c.includeVersion == true, + ), + 'layoutTitle': Property( + getValue: (CT_ c) => c.layoutTitle, + getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.layoutTitle == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.layoutTitle, ast, parent: r); + }, + ), + 'metaDescription': Property( + getValue: (CT_ c) => c.metaDescription, + getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.metaDescription == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.metaDescription, ast, parent: r); + }, + ), + 'navLinks': Property( + getValue: (CT_ c) => c.navLinks, + getProperties: _Renderer_List.propertyMap, + 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(_render_Documentable(e, ast, parent: r)); + } + return buffer.toString(); + }, + ), + 'package': Property( + getValue: (CT_ c) => c.package, + getProperties: _Renderer_Package.propertyMap, + isNullValue: (CT_ c) => c.package == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_Package(c.package, ast, parent: r); + }, + ), + 'self': Property( + getValue: (CT_ c) => c.self, + getProperties: _Renderer_Package.propertyMap, + isNullValue: (CT_ c) => c.self == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_Package(c.self, ast, parent: r); + }, + ), + 'title': Property( + getValue: (CT_ c) => c.title, + getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.title == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.title, ast, parent: r); + }, + ), + ..._Renderer_TemplateData.propertyMap(), + }; _Renderer_PackageTemplateData( PackageTemplateData context, RendererBase parent) @@ -112,9 +141,17 @@ class _Renderer_Package extends RendererBase { 'baseHref': Property( getValue: (CT_ c) => c.baseHref, getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.baseHref == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.baseHref, ast, parent: r); + }, ), 'canonicalLibrary': Property( getValue: (CT_ c) => c.canonicalLibrary, + isNullValue: (CT_ c) => c.canonicalLibrary == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return null(c.canonicalLibrary, ast, parent: r); + }, ), 'categories': Property( getValue: (CT_ c) => c.categories, @@ -144,6 +181,10 @@ class _Renderer_Package extends RendererBase { ), 'config': Property( getValue: (CT_ c) => c.config, + isNullValue: (CT_ c) => c.config == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return null(c.config, ast, parent: r); + }, ), 'containerOrder': Property( getValue: (CT_ c) => c.containerOrder, @@ -161,17 +202,33 @@ class _Renderer_Package extends RendererBase { 'defaultCategory': Property( getValue: (CT_ c) => c.defaultCategory, getProperties: _Renderer_LibraryContainer.propertyMap, + isNullValue: (CT_ c) => c.defaultCategory == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_LibraryContainer(c.defaultCategory, ast, parent: r); + }, ), 'documentation': Property( getValue: (CT_ c) => c.documentation, getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.documentation == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.documentation, ast, parent: r); + }, ), 'documentationAsHtml': Property( getValue: (CT_ c) => c.documentationAsHtml, getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.documentationAsHtml == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.documentationAsHtml, ast, parent: r); + }, ), 'documentationFile': Property( getValue: (CT_ c) => c.documentationFile, + isNullValue: (CT_ c) => c.documentationFile == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return null(c.documentationFile, ast, parent: r); + }, ), 'documentationFrom': Property( getValue: (CT_ c) => c.documentationFrom, @@ -213,28 +270,56 @@ class _Renderer_Package extends RendererBase { ), 'documentedWhere': Property( getValue: (CT_ c) => c.documentedWhere, + isNullValue: (CT_ c) => c.documentedWhere == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return null(c.documentedWhere, ast, parent: r); + }, ), 'element': Property( getValue: (CT_ c) => c.element, + isNullValue: (CT_ c) => c.element == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return null(c.element, ast, parent: r); + }, ), 'enclosingElement': Property( getValue: (CT_ c) => c.enclosingElement, + isNullValue: (CT_ c) => c.enclosingElement == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return null(c.enclosingElement, ast, parent: r); + }, ), 'enclosingName': Property( getValue: (CT_ c) => c.enclosingName, getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.enclosingName == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.enclosingName, ast, parent: r); + }, ), 'filePath': Property( getValue: (CT_ c) => c.filePath, getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.filePath == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.filePath, ast, parent: r); + }, ), 'fileType': Property( getValue: (CT_ c) => c.fileType, getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.fileType == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.fileType, ast, parent: r); + }, ), 'fullyQualifiedName': Property( getValue: (CT_ c) => c.fullyQualifiedName, getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.fullyQualifiedName == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.fullyQualifiedName, ast, parent: r); + }, ), 'hasCategories': Property( getValue: (CT_ c) => c.hasCategories, @@ -269,10 +354,18 @@ class _Renderer_Package extends RendererBase { 'homepage': Property( getValue: (CT_ c) => c.homepage, getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.homepage == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.homepage, ast, parent: r); + }, ), 'href': Property( getValue: (CT_ c) => c.href, getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.href == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.href, ast, parent: r); + }, ), 'isCanonical': Property( getValue: (CT_ c) => c.isCanonical, @@ -307,10 +400,18 @@ class _Renderer_Package extends RendererBase { 'kind': Property( getValue: (CT_ c) => c.kind, getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.kind == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.kind, ast, parent: r); + }, ), 'location': Property( getValue: (CT_ c) => c.location, getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.location == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.location, ast, parent: r); + }, ), 'locationPieces': Property( getValue: (CT_ c) => c.locationPieces, @@ -327,27 +428,55 @@ class _Renderer_Package extends RendererBase { 'name': Property( getValue: (CT_ c) => c.name, getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.name == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.name, ast, parent: r); + }, ), 'nameToCategory': Property( getValue: (CT_ c) => c.nameToCategory, + isNullValue: (CT_ c) => c.nameToCategory == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return null(c.nameToCategory, ast, parent: r); + }, ), 'oneLineDoc': Property( getValue: (CT_ c) => c.oneLineDoc, getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.oneLineDoc == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.oneLineDoc, ast, parent: r); + }, ), 'package': Property( getValue: (CT_ c) => c.package, getProperties: _Renderer_Package.propertyMap, + isNullValue: (CT_ c) => c.package == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_Package(c.package, ast, parent: r); + }, ), 'packageGraph': Property( getValue: (CT_ c) => c.packageGraph, + isNullValue: (CT_ c) => c.packageGraph == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return null(c.packageGraph, ast, parent: r); + }, ), 'packageMeta': Property( getValue: (CT_ c) => c.packageMeta, + isNullValue: (CT_ c) => c.packageMeta == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return null(c.packageMeta, ast, parent: r); + }, ), 'packagePath': Property( getValue: (CT_ c) => c.packagePath, getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.packagePath == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.packagePath, ast, parent: r); + }, ), 'publicLibraries': Property( getValue: (CT_ c) => c.publicLibraries, @@ -364,13 +493,25 @@ class _Renderer_Package extends RendererBase { 'toolInvocationIndex': Property( getValue: (CT_ c) => c.toolInvocationIndex, getProperties: _Renderer_int.propertyMap, + isNullValue: (CT_ c) => c.toolInvocationIndex == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_int(c.toolInvocationIndex, ast, parent: r); + }, ), 'usedAnimationIdsByHref': Property( getValue: (CT_ c) => c.usedAnimationIdsByHref, + isNullValue: (CT_ c) => c.usedAnimationIdsByHref == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return null(c.usedAnimationIdsByHref, ast, parent: r); + }, ), 'version': Property( getValue: (CT_ c) => c.version, getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.version == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.version, ast, parent: r); + }, ), ..._Renderer_LibraryContainer.propertyMap(), }; @@ -397,82 +538,94 @@ String _render_LibraryContainer( } class _Renderer_LibraryContainer extends RendererBase { - static Map> - propertyMap() => { - 'containerOrder': Property( - getValue: (CT_ c) => c.containerOrder, - getProperties: _Renderer_List.propertyMap, - 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(_render_String(e, ast, parent: r)); - } - return buffer.toString(); - }, - ), - 'enclosingName': Property( - getValue: (CT_ c) => c.enclosingName, - getProperties: _Renderer_String.propertyMap, - ), - 'hasPublicLibraries': Property( - getValue: (CT_ c) => c.hasPublicLibraries, - getProperties: _Renderer_bool.propertyMap, - getBool: (CT_ c) => c.hasPublicLibraries == true, - ), - 'isSdk': Property( - getValue: (CT_ c) => c.isSdk, - getProperties: _Renderer_bool.propertyMap, - getBool: (CT_ c) => c.isSdk == true, - ), - 'libraries': Property( - getValue: (CT_ c) => c.libraries, - getProperties: _Renderer_List.propertyMap, - isEmptyIterable: (CT_ c) => c.libraries?.isEmpty ?? true, - renderIterable: - (CT_ c, RendererBase r, List ast) { - var buffer = StringBuffer(); - for (var e in c.libraries) { - buffer.write(null(e, ast, parent: r)); - } - return buffer.toString(); - }, - ), - 'packageGraph': Property( - getValue: (CT_ c) => c.packageGraph, - ), - 'publicLibraries': Property( - getValue: (CT_ c) => c.publicLibraries, - 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(null(e, ast, parent: r)); - } - return buffer.toString(); - }, - ), - 'publicLibrariesSorted': Property( - getValue: (CT_ c) => c.publicLibrariesSorted, - 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(null(e, ast, parent: r)); - } - return buffer.toString(); - }, - ), - 'sortKey': Property( - getValue: (CT_ c) => c.sortKey, - getProperties: _Renderer_String.propertyMap, - ), - ..._Renderer_Object.propertyMap(), - }; + static Map> propertyMap< + CT_ extends LibraryContainer>() => + { + 'containerOrder': Property( + getValue: (CT_ c) => c.containerOrder, + getProperties: _Renderer_List.propertyMap, + 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(_render_String(e, ast, parent: r)); + } + return buffer.toString(); + }, + ), + 'enclosingName': Property( + getValue: (CT_ c) => c.enclosingName, + getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.enclosingName == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.enclosingName, ast, parent: r); + }, + ), + 'hasPublicLibraries': Property( + getValue: (CT_ c) => c.hasPublicLibraries, + getProperties: _Renderer_bool.propertyMap, + getBool: (CT_ c) => c.hasPublicLibraries == true, + ), + 'isSdk': Property( + getValue: (CT_ c) => c.isSdk, + getProperties: _Renderer_bool.propertyMap, + getBool: (CT_ c) => c.isSdk == true, + ), + 'libraries': Property( + getValue: (CT_ c) => c.libraries, + getProperties: _Renderer_List.propertyMap, + isEmptyIterable: (CT_ c) => c.libraries?.isEmpty ?? true, + renderIterable: + (CT_ c, RendererBase r, List ast) { + var buffer = StringBuffer(); + for (var e in c.libraries) { + buffer.write(null(e, ast, parent: r)); + } + return buffer.toString(); + }, + ), + 'packageGraph': Property( + getValue: (CT_ c) => c.packageGraph, + isNullValue: (CT_ c) => c.packageGraph == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return null(c.packageGraph, ast, parent: r); + }, + ), + 'publicLibraries': Property( + getValue: (CT_ c) => c.publicLibraries, + 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(null(e, ast, parent: r)); + } + return buffer.toString(); + }, + ), + 'publicLibrariesSorted': Property( + getValue: (CT_ c) => c.publicLibrariesSorted, + 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(null(e, ast, parent: r)); + } + return buffer.toString(); + }, + ), + 'sortKey': Property( + getValue: (CT_ c) => c.sortKey, + getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.sortKey == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.sortKey, ast, parent: r); + }, + ), + ..._Renderer_Object.propertyMap(), + }; _Renderer_LibraryContainer( LibraryContainer context, RendererBase parent) @@ -500,6 +653,10 @@ class _Renderer_Object extends RendererBase { 'hashCode': Property( getValue: (CT_ c) => c.hashCode, getProperties: _Renderer_int.propertyMap, + isNullValue: (CT_ c) => c.hashCode == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_int(c.hashCode, ast, parent: r); + }, ), }; @@ -528,6 +685,10 @@ class _Renderer_bool extends RendererBase { 'hashCode': Property( getValue: (CT_ c) => c.hashCode, getProperties: _Renderer_int.propertyMap, + isNullValue: (CT_ c) => c.hashCode == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_int(c.hashCode, ast, parent: r); + }, ), ..._Renderer_Object.propertyMap(), }; @@ -557,6 +718,10 @@ class _Renderer_List extends RendererBase> { 'length': Property( getValue: (CT_ c) => c.length, getProperties: _Renderer_int.propertyMap, + isNullValue: (CT_ c) => c.length == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_int(c.length, ast, parent: r); + }, ), 'reversed': Property( getValue: (CT_ c) => c.reversed, @@ -602,6 +767,10 @@ class _Renderer_String extends RendererBase { 'hashCode': Property( getValue: (CT_ c) => c.hashCode, getProperties: _Renderer_int.propertyMap, + isNullValue: (CT_ c) => c.hashCode == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_int(c.hashCode, ast, parent: r); + }, ), 'isEmpty': Property( getValue: (CT_ c) => c.isEmpty, @@ -616,6 +785,10 @@ class _Renderer_String extends RendererBase { 'length': Property( getValue: (CT_ c) => c.length, getProperties: _Renderer_int.propertyMap, + isNullValue: (CT_ c) => c.length == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_int(c.length, ast, parent: r); + }, ), 'runes': Property( getValue: (CT_ c) => c.runes, @@ -655,114 +828,158 @@ String _render_TemplateData( class _Renderer_TemplateData extends RendererBase> { - static Map> - propertyMap>() => { - 'bareHref': Property( - getValue: (CT_ c) => c.bareHref, - getProperties: _Renderer_String.propertyMap, - ), - 'defaultPackage': Property( - getValue: (CT_ c) => c.defaultPackage, - getProperties: _Renderer_Package.propertyMap, - ), - 'hasFooterVersion': Property( - getValue: (CT_ c) => c.hasFooterVersion, - getProperties: _Renderer_bool.propertyMap, - getBool: (CT_ c) => c.hasFooterVersion == true, - ), - 'hasHomepage': Property( - getValue: (CT_ c) => c.hasHomepage, - getProperties: _Renderer_bool.propertyMap, - getBool: (CT_ c) => c.hasHomepage == true, - ), - 'homepage': Property( - getValue: (CT_ c) => c.homepage, - getProperties: _Renderer_String.propertyMap, - ), - 'htmlBase': Property( - getValue: (CT_ c) => c.htmlBase, - getProperties: _Renderer_String.propertyMap, - ), - 'htmlOptions': Property( - getValue: (CT_ c) => c.htmlOptions, - getProperties: _Renderer_TemplateOptions.propertyMap, - ), - 'includeVersion': Property( - getValue: (CT_ c) => c.includeVersion, - getProperties: _Renderer_bool.propertyMap, - getBool: (CT_ c) => c.includeVersion == true, - ), - 'layoutTitle': Property( - getValue: (CT_ c) => c.layoutTitle, - getProperties: _Renderer_String.propertyMap, - ), - 'localPackages': Property( - getValue: (CT_ c) => c.localPackages, - getProperties: _Renderer_List.propertyMap, - isEmptyIterable: (CT_ c) => c.localPackages?.isEmpty ?? true, - renderIterable: - (CT_ c, RendererBase r, List ast) { - var buffer = StringBuffer(); - for (var e in c.localPackages) { - buffer.write(_render_Package(e, ast, parent: r)); - } - return buffer.toString(); - }, - ), - 'metaDescription': Property( - getValue: (CT_ c) => c.metaDescription, - getProperties: _Renderer_String.propertyMap, - ), - 'navLinks': Property( - getValue: (CT_ c) => c.navLinks, - getProperties: _Renderer_List.propertyMap, - 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(_render_Documentable(e, ast, parent: r)); - } - return buffer.toString(); - }, - ), - 'navLinksWithGenerics': Property( - getValue: (CT_ c) => c.navLinksWithGenerics, - getProperties: _Renderer_List.propertyMap, - isEmptyIterable: (CT_ c) => - c.navLinksWithGenerics?.isEmpty ?? true, - renderIterable: - (CT_ c, RendererBase r, List ast) { - var buffer = StringBuffer(); - for (var e in c.navLinksWithGenerics) { - buffer.write(null(e, ast, parent: r)); - } - return buffer.toString(); - }, - ), - 'parent': Property( - getValue: (CT_ c) => c.parent, - getProperties: _Renderer_Documentable.propertyMap, - ), - 'relCanonicalPrefix': Property( - getValue: (CT_ c) => c.relCanonicalPrefix, - getProperties: _Renderer_String.propertyMap, - ), - 'title': Property( - getValue: (CT_ c) => c.title, - getProperties: _Renderer_String.propertyMap, - ), - 'useBaseHref': Property( - getValue: (CT_ c) => c.useBaseHref, - getProperties: _Renderer_bool.propertyMap, - getBool: (CT_ c) => c.useBaseHref == true, - ), - 'version': Property( - getValue: (CT_ c) => c.version, - getProperties: _Renderer_String.propertyMap, - ), - ..._Renderer_Object.propertyMap(), - }; + static Map> propertyMap>() => + { + 'bareHref': Property( + getValue: (CT_ c) => c.bareHref, + getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.bareHref == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.bareHref, ast, parent: r); + }, + ), + 'defaultPackage': Property( + getValue: (CT_ c) => c.defaultPackage, + getProperties: _Renderer_Package.propertyMap, + isNullValue: (CT_ c) => c.defaultPackage == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_Package(c.defaultPackage, ast, parent: r); + }, + ), + 'hasFooterVersion': Property( + getValue: (CT_ c) => c.hasFooterVersion, + getProperties: _Renderer_bool.propertyMap, + getBool: (CT_ c) => c.hasFooterVersion == true, + ), + 'hasHomepage': Property( + getValue: (CT_ c) => c.hasHomepage, + getProperties: _Renderer_bool.propertyMap, + getBool: (CT_ c) => c.hasHomepage == true, + ), + 'homepage': Property( + getValue: (CT_ c) => c.homepage, + getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.homepage == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.homepage, ast, parent: r); + }, + ), + 'htmlBase': Property( + getValue: (CT_ c) => c.htmlBase, + getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.htmlBase == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.htmlBase, ast, parent: r); + }, + ), + 'htmlOptions': Property( + getValue: (CT_ c) => c.htmlOptions, + getProperties: _Renderer_TemplateOptions.propertyMap, + isNullValue: (CT_ c) => c.htmlOptions == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_TemplateOptions(c.htmlOptions, ast, parent: r); + }, + ), + 'includeVersion': Property( + getValue: (CT_ c) => c.includeVersion, + getProperties: _Renderer_bool.propertyMap, + getBool: (CT_ c) => c.includeVersion == true, + ), + 'layoutTitle': Property( + getValue: (CT_ c) => c.layoutTitle, + getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.layoutTitle == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.layoutTitle, ast, parent: r); + }, + ), + 'localPackages': Property( + getValue: (CT_ c) => c.localPackages, + getProperties: _Renderer_List.propertyMap, + isEmptyIterable: (CT_ c) => c.localPackages?.isEmpty ?? true, + renderIterable: + (CT_ c, RendererBase r, List ast) { + var buffer = StringBuffer(); + for (var e in c.localPackages) { + buffer.write(_render_Package(e, ast, parent: r)); + } + return buffer.toString(); + }, + ), + 'metaDescription': Property( + getValue: (CT_ c) => c.metaDescription, + getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.metaDescription == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.metaDescription, ast, parent: r); + }, + ), + 'navLinks': Property( + getValue: (CT_ c) => c.navLinks, + getProperties: _Renderer_List.propertyMap, + 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(_render_Documentable(e, ast, parent: r)); + } + return buffer.toString(); + }, + ), + 'navLinksWithGenerics': Property( + getValue: (CT_ c) => c.navLinksWithGenerics, + getProperties: _Renderer_List.propertyMap, + isEmptyIterable: (CT_ c) => c.navLinksWithGenerics?.isEmpty ?? true, + renderIterable: + (CT_ c, RendererBase r, List ast) { + var buffer = StringBuffer(); + for (var e in c.navLinksWithGenerics) { + buffer.write(null(e, ast, parent: r)); + } + return buffer.toString(); + }, + ), + 'parent': Property( + getValue: (CT_ c) => c.parent, + getProperties: _Renderer_Documentable.propertyMap, + isNullValue: (CT_ c) => c.parent == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_Documentable(c.parent, ast, parent: r); + }, + ), + 'relCanonicalPrefix': Property( + getValue: (CT_ c) => c.relCanonicalPrefix, + getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.relCanonicalPrefix == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.relCanonicalPrefix, ast, parent: r); + }, + ), + 'title': Property( + getValue: (CT_ c) => c.title, + getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.title == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.title, ast, parent: r); + }, + ), + 'useBaseHref': Property( + getValue: (CT_ c) => c.useBaseHref, + getProperties: _Renderer_bool.propertyMap, + getBool: (CT_ c) => c.useBaseHref == true, + ), + 'version': Property( + getValue: (CT_ c) => c.version, + getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.version == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.version, ast, parent: r); + }, + ), + ..._Renderer_Object.propertyMap(), + }; _Renderer_TemplateData(TemplateData context, RendererBase parent) : super(context, parent); @@ -785,23 +1002,32 @@ String _render_TemplateOptions(TemplateOptions context, List ast, } class _Renderer_TemplateOptions extends RendererBase { - static Map> - propertyMap() => { - 'relCanonicalPrefix': Property( - getValue: (CT_ c) => c.relCanonicalPrefix, - getProperties: _Renderer_String.propertyMap, - ), - 'toolVersion': Property( - getValue: (CT_ c) => c.toolVersion, - getProperties: _Renderer_String.propertyMap, - ), - 'useBaseHref': Property( - getValue: (CT_ c) => c.useBaseHref, - getProperties: _Renderer_bool.propertyMap, - getBool: (CT_ c) => c.useBaseHref == true, - ), - ..._Renderer_Object.propertyMap(), - }; + static Map> propertyMap< + CT_ extends TemplateOptions>() => + { + 'relCanonicalPrefix': Property( + getValue: (CT_ c) => c.relCanonicalPrefix, + getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.relCanonicalPrefix == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.relCanonicalPrefix, ast, parent: r); + }, + ), + 'toolVersion': Property( + getValue: (CT_ c) => c.toolVersion, + getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.toolVersion == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.toolVersion, ast, parent: r); + }, + ), + 'useBaseHref': Property( + getValue: (CT_ c) => c.useBaseHref, + getProperties: _Renderer_bool.propertyMap, + getBool: (CT_ c) => c.useBaseHref == true, + ), + ..._Renderer_Object.propertyMap(), + }; _Renderer_TemplateOptions( TemplateOptions context, RendererBase parent) @@ -828,14 +1054,26 @@ class _Renderer_Documentable extends RendererBase { static Map> propertyMap() => { 'config': Property( getValue: (CT_ c) => c.config, + isNullValue: (CT_ c) => c.config == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return null(c.config, ast, parent: r); + }, ), 'documentation': Property( getValue: (CT_ c) => c.documentation, getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.documentation == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.documentation, ast, parent: r); + }, ), 'documentationAsHtml': Property( getValue: (CT_ c) => c.documentationAsHtml, getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.documentationAsHtml == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.documentationAsHtml, ast, parent: r); + }, ), 'hasDocumentation': Property( getValue: (CT_ c) => c.hasDocumentation, @@ -850,6 +1088,10 @@ class _Renderer_Documentable extends RendererBase { 'href': Property( getValue: (CT_ c) => c.href, getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.href == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.href, ast, parent: r); + }, ), 'isDocumented': Property( getValue: (CT_ c) => c.isDocumented, @@ -859,13 +1101,25 @@ class _Renderer_Documentable extends RendererBase { 'kind': Property( getValue: (CT_ c) => c.kind, getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.kind == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.kind, ast, parent: r); + }, ), 'oneLineDoc': Property( getValue: (CT_ c) => c.oneLineDoc, getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.oneLineDoc == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.oneLineDoc, ast, parent: r); + }, ), 'packageGraph': Property( getValue: (CT_ c) => c.packageGraph, + isNullValue: (CT_ c) => c.packageGraph == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return null(c.packageGraph, ast, parent: r); + }, ), ..._Renderer_Nameable.propertyMap(), }; @@ -895,14 +1149,26 @@ class _Renderer_Nameable extends RendererBase { 'fullyQualifiedName': Property( getValue: (CT_ c) => c.fullyQualifiedName, getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.fullyQualifiedName == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.fullyQualifiedName, ast, parent: r); + }, ), 'name': Property( getValue: (CT_ c) => c.name, getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.name == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.name, ast, parent: r); + }, ), 'namePart': Property( getValue: (CT_ c) => c.namePart, getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.namePart == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.namePart, ast, parent: r); + }, ), 'namePieces': Property( getValue: (CT_ c) => c.namePieces, @@ -944,6 +1210,10 @@ class _Renderer_int extends RendererBase { 'bitLength': Property( getValue: (CT_ c) => c.bitLength, getProperties: _Renderer_int.propertyMap, + isNullValue: (CT_ c) => c.bitLength == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_int(c.bitLength, ast, parent: r); + }, ), 'isEven': Property( getValue: (CT_ c) => c.isEven, @@ -958,6 +1228,10 @@ class _Renderer_int extends RendererBase { 'sign': Property( getValue: (CT_ c) => c.sign, getProperties: _Renderer_int.propertyMap, + isNullValue: (CT_ c) => c.sign == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_int(c.sign, ast, parent: r); + }, ), ..._Renderer_num.propertyMap(), }; @@ -987,6 +1261,10 @@ class _Renderer_num extends RendererBase { 'hashCode': Property( getValue: (CT_ c) => c.hashCode, getProperties: _Renderer_int.propertyMap, + isNullValue: (CT_ c) => c.hashCode == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_int(c.hashCode, ast, parent: r); + }, ), 'isFinite': Property( getValue: (CT_ c) => c.isFinite, @@ -1011,6 +1289,10 @@ class _Renderer_num extends RendererBase { 'sign': Property( getValue: (CT_ c) => c.sign, getProperties: _Renderer_num.propertyMap, + isNullValue: (CT_ c) => c.sign == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_num(c.sign, ast, parent: r); + }, ), ..._Renderer_Object.propertyMap(), }; diff --git a/lib/src/mustachio/parser.dart b/lib/src/mustachio/parser.dart index 6c92bcb41d..23c3ca3309 100644 --- a/lib/src/mustachio/parser.dart +++ b/lib/src/mustachio/parser.dart @@ -82,6 +82,7 @@ class MustachioParser { addTextNode(textStartIndex, textEndIndex); children.add(result.node); textStartIndex = _index; + continue; } } _index++; diff --git a/lib/src/mustachio/renderer_base.dart b/lib/src/mustachio/renderer_base.dart index c88fa184a6..4bb4d432e6 100644 --- a/lib/src/mustachio/renderer_base.dart +++ b/lib/src/mustachio/renderer_base.dart @@ -75,7 +75,44 @@ abstract class RendererBase { } void section(Section node) { - // TODO(srawlins): Implement. + var key = node.key.first; + var property = getProperty(key); + if (property == null) { + if (parent == null) { + throw MustachioResolutionError( + 'Failed to resolve $key as a property on any types in the current ' + 'context'); + } else { + return parent.section(node); + } + } + + if (property.getBool != null) { + var boolResult = property.getBool(context); + if ((boolResult && !node.invert) || (!boolResult && node.invert)) { + renderBlock(node.children); + } + return; + } + + if (property.renderIterable != null) { + // An inverted section is rendered with the current context. + if (node.invert && property.isEmptyIterable(context)) { + renderBlock(node.children); + } + if (!node.invert && !property.isEmptyIterable(context)) { + write(property.renderIterable(context, this, node.children)); + } + return; + } + + // If this section is not a conditional or repeated section, it is a value + // section, regardless of type. + if (node.invert && property.isNullValue(context)) { + renderBlock(node.children); + } else if (!node.invert && !property.isNullValue(context)) { + write(property.renderValue(context, this, node.children)); + } } void partial(Partial node) { @@ -103,6 +140,11 @@ class Property { T, RendererBase, List /*!*/) /*?*/ renderIterable; + final bool /*!*/ Function(T) /*?*/ isNullValue; + + final String /*!*/ Function( + T, RendererBase, List /*!*/) /*?*/ renderValue; + // TODO(srawlins): Add functions for rendering other properties. Property( @@ -110,7 +152,9 @@ class Property { this.getProperties, this.getBool, this.isEmptyIterable, - this.renderIterable}); + this.renderIterable, + this.isNullValue, + this.renderValue}); } /// An error indicating that a renderer failed to resolve a key. diff --git a/test/mustachio/builder_test.dart b/test/mustachio/builder_test.dart index c5eb39f299..e7fd0624fb 100644 --- a/test/mustachio/builder_test.dart +++ b/test/mustachio/builder_test.dart @@ -126,15 +126,6 @@ class Bar {} 'static Map> propertyMap() => {')); }); - test('with a property map with a String property', () { - expect(generatedContent, contains(''' - 's1': Property( - getValue: (CT_ c) => c.s1, - getProperties: _Renderer_String.propertyMap, - ), -''')); - }); - test('with a property map which references the superclass', () { expect(generatedContent, contains('..._Renderer_FooBase.propertyMap(),')); @@ -165,6 +156,19 @@ class Bar {} return buffer.toString(); }, ), +''')); + }); + + test('with a property map with a non-bool, non-Iterable property', () { + expect(generatedContent, contains(''' + 's1': Property( + getValue: (CT_ c) => c.s1, + getProperties: _Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.s1 == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.s1, ast, parent: r); + }, + ), ''')); }); }); diff --git a/test/mustachio/foo.renderers.dart b/test/mustachio/foo.renderers.dart index 6cac66dbb6..de91a79a21 100644 --- a/test/mustachio/foo.renderers.dart +++ b/test/mustachio/foo.renderers.dart @@ -40,6 +40,10 @@ class Renderer_Foo extends RendererBase { 's1': Property( getValue: (CT_ c) => c.s1, getProperties: Renderer_String.propertyMap, + isNullValue: (CT_ c) => c.s1 == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_String(c.s1, ast, parent: r); + }, ), ...Renderer_Object.propertyMap(), }; @@ -82,6 +86,10 @@ class Renderer_String extends RendererBase { 'hashCode': Property( getValue: (CT_ c) => c.hashCode, getProperties: Renderer_int.propertyMap, + isNullValue: (CT_ c) => c.hashCode == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_int(c.hashCode, ast, parent: r); + }, ), 'isEmpty': Property( getValue: (CT_ c) => c.isEmpty, @@ -96,6 +104,10 @@ class Renderer_String extends RendererBase { 'length': Property( getValue: (CT_ c) => c.length, getProperties: Renderer_int.propertyMap, + isNullValue: (CT_ c) => c.length == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_int(c.length, ast, parent: r); + }, ), 'runes': Property( getValue: (CT_ c) => c.runes, @@ -137,6 +149,10 @@ class Renderer_Object extends RendererBase { 'hashCode': Property( getValue: (CT_ c) => c.hashCode, getProperties: Renderer_int.propertyMap, + isNullValue: (CT_ c) => c.hashCode == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_int(c.hashCode, ast, parent: r); + }, ), }; @@ -165,6 +181,10 @@ class Renderer_bool extends RendererBase { 'hashCode': Property( getValue: (CT_ c) => c.hashCode, getProperties: Renderer_int.propertyMap, + isNullValue: (CT_ c) => c.hashCode == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_int(c.hashCode, ast, parent: r); + }, ), ...Renderer_Object.propertyMap(), }; @@ -194,6 +214,10 @@ class Renderer_List extends RendererBase> { 'length': Property( getValue: (CT_ c) => c.length, getProperties: Renderer_int.propertyMap, + isNullValue: (CT_ c) => c.length == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_int(c.length, ast, parent: r); + }, ), 'reversed': Property( getValue: (CT_ c) => c.reversed, @@ -226,6 +250,10 @@ class Renderer_int extends RendererBase { 'bitLength': Property( getValue: (CT_ c) => c.bitLength, getProperties: Renderer_int.propertyMap, + isNullValue: (CT_ c) => c.bitLength == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_int(c.bitLength, ast, parent: r); + }, ), 'isEven': Property( getValue: (CT_ c) => c.isEven, @@ -240,6 +268,10 @@ class Renderer_int extends RendererBase { 'sign': Property( getValue: (CT_ c) => c.sign, getProperties: Renderer_int.propertyMap, + isNullValue: (CT_ c) => c.sign == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_int(c.sign, ast, parent: r); + }, ), ...Renderer_num.propertyMap(), }; @@ -269,6 +301,10 @@ class Renderer_num extends RendererBase { 'hashCode': Property( getValue: (CT_ c) => c.hashCode, getProperties: Renderer_int.propertyMap, + isNullValue: (CT_ c) => c.hashCode == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_int(c.hashCode, ast, parent: r); + }, ), 'isFinite': Property( getValue: (CT_ c) => c.isFinite, @@ -293,6 +329,10 @@ class Renderer_num extends RendererBase { 'sign': Property( getValue: (CT_ c) => c.sign, getProperties: Renderer_num.propertyMap, + isNullValue: (CT_ c) => c.sign == null, + renderValue: (CT_ c, RendererBase r, List ast) { + return _render_num(c.sign, ast, parent: r); + }, ), ...Renderer_Object.propertyMap(), }; diff --git a/test/mustachio/parser_test.dart b/test/mustachio/parser_test.dart index 3138b1dcb6..a9ab19e98d 100644 --- a/test/mustachio/parser_test.dart +++ b/test/mustachio/parser_test.dart @@ -216,6 +216,17 @@ void main() { expect(section.children, isEmpty); }); + test('parses section with variable tag inside', () { + var parser = MustachioParser('Text {{#key}}{{two}}{{/key}}'); + var ast = parser.parse(); + expect(ast, hasLength(2)); + _expectText(ast[0], equals('Text ')); + var section = ast[1] as Section; + _expectSection(section, equals(['key'])); + expect(section.children, hasLength(1)); + _expectVariable(section.children.single, equals(['two'])); + }); + test('parses section with empty key as text', () { var parser = MustachioParser('Text {{#}}{{/key}}'); var ast = parser.parse(); diff --git a/test/mustachio/renderer_test.dart b/test/mustachio/renderer_test.dart index 23add50115..83bfec724d 100644 --- a/test/mustachio/renderer_test.dart +++ b/test/mustachio/renderer_test.dart @@ -1,4 +1,5 @@ import 'package:dartdoc/src/mustachio/parser.dart'; +import 'package:dartdoc/src/mustachio/renderer_base.dart'; import 'package:test/test.dart'; import 'foo.dart'; import 'foo.renderers.dart'; @@ -20,6 +21,8 @@ void main() { expect(propertyMap['b1'].getBool, isNotNull); expect(propertyMap['b1'].isEmptyIterable, isNull); expect(propertyMap['b1'].renderIterable, isNull); + expect(propertyMap['b1'].isNullValue, isNull); + expect(propertyMap['b1'].renderValue, isNull); }); test('property map contains valid Iterable Properties', () { @@ -29,6 +32,8 @@ void main() { expect(propertyMap['l1'].getBool, isNull); expect(propertyMap['l1'].isEmptyIterable, isNotNull); expect(propertyMap['l1'].renderIterable, isNotNull); + expect(propertyMap['l1'].isNullValue, isNull); + expect(propertyMap['l1'].renderValue, isNull); }); test('property map contains valid non-bool, non-Iterable Properties', () { @@ -38,6 +43,8 @@ void main() { expect(propertyMap['s1'].getBool, isNull); expect(propertyMap['s1'].isEmptyIterable, isNull); expect(propertyMap['s1'].renderIterable, isNull); + expect(propertyMap['s1'].isNullValue, isNotNull); + expect(propertyMap['s1'].renderValue, isNotNull); }); test('Property returns a field value by name', () { @@ -70,6 +77,18 @@ void main() { expect(propertyMap['l1'].isEmptyIterable(foo), isTrue); }); + test('isNullValue returns true when a value is null', () { + var propertyMap = Renderer_Foo.propertyMap(); + var foo = Foo()..s1 = null; + expect(propertyMap['s1'].isNullValue(foo), isTrue); + }); + + test('isNullValue returns false when a value is not null', () { + var propertyMap = Renderer_Foo.propertyMap(); + var foo = Foo()..s1 = 'hello'; + expect(propertyMap['s1'].isNullValue(foo), isFalse); + }); + test('Property returns false for a null bool field value', () { var propertyMap = Renderer_Foo.propertyMap(); var foo = Foo()..b1 = null; @@ -96,4 +115,120 @@ void main() { var foo = Foo()..l1 = [1, 2, 3]; expect(renderFoo(foo, ast), equals('Text [1, 2, 3]')); }); + + test('Renderer renders a conditional section node', () { + var parser = MustachioParser('Text {{#b1}}Section{{/b1}}'); + var ast = parser.parse(); + var foo = Foo()..b1 = true; + expect(renderFoo(foo, ast), equals('Text Section')); + }); + + test('Renderer renders a false conditional section node as blank', () { + var parser = MustachioParser('Text {{#b1}}Section{{/b1}}'); + var ast = parser.parse(); + var foo = Foo()..b1 = false; + expect(renderFoo(foo, ast), equals('Text ')); + }); + + test('Renderer renders an inverted conditional section node as empty', () { + var parser = MustachioParser('Text {{^b1}}Section{{/b1}}'); + var ast = parser.parse(); + var foo = Foo()..b1 = true; + expect(renderFoo(foo, ast), equals('Text ')); + }); + + test('Renderer renders an inverted false conditional section node', () { + var parser = MustachioParser('Text {{^b1}}Section{{/b1}}'); + var ast = parser.parse(); + var foo = Foo()..b1 = false; + expect(renderFoo(foo, ast), equals('Text Section')); + }); + + test('Renderer renders a repeated section node', () { + var parser = MustachioParser('Text {{#l1}}Num {{.}}, {{/l1}}'); + var ast = parser.parse(); + var foo = Foo()..l1 = [1, 2, 3]; + expect(renderFoo(foo, ast), equals('Text Num 1, Num 2, Num 3, ')); + }); + + test('Renderer renders an empty repeated section node as blank', () { + var parser = MustachioParser('Text {{#l1}}Num {{.}}, {{/l1}}'); + var ast = parser.parse(); + var foo = Foo()..l1 = []; + expect(renderFoo(foo, ast), equals('Text ')); + }); + + test('Renderer renders an empty inverted repeated section node', () { + var parser = MustachioParser('Text {{^l1}}Empty{{/l1}}'); + var ast = parser.parse(); + var foo = Foo()..l1 = []; + expect(renderFoo(foo, ast), equals('Text Empty')); + }); + + test('Renderer renders an inverted repeated section node as blank', () { + var parser = MustachioParser('Text {{^l1}}Empty{{/l1}}'); + var ast = parser.parse(); + var foo = Foo()..l1 = [1, 2, 3]; + expect(renderFoo(foo, ast), equals('Text ')); + }); + + test('Renderer renders a value section node', () { + var parser = MustachioParser('Text {{#s1}}"{{.}}" ({{length}}){{/s1}}'); + var ast = parser.parse(); + var foo = Foo()..s1 = 'hello'; + expect(renderFoo(foo, ast), equals('Text "hello" (5)')); + }); + + test('Renderer renders a null value section node as blank', () { + var parser = MustachioParser('Text {{#s1}}"{{.}}" ({{length}}){{/s1}}'); + var ast = parser.parse(); + var foo = Foo()..s1 = null; + expect(renderFoo(foo, ast), equals('Text ')); + }); + + test('Renderer renders an inverted value section node as blank', () { + var parser = MustachioParser('Text {{^s1}}Section{{/s1}}'); + var ast = parser.parse(); + var foo = Foo()..s1 = 'hello'; + expect(renderFoo(foo, ast), equals('Text ')); + }); + + test('Renderer renders an inverted null value section node', () { + var parser = MustachioParser('Text {{^s1}}Section{{/s1}}'); + var ast = parser.parse(); + var foo = Foo()..s1 = null; + expect(renderFoo(foo, ast), equals('Text Section')); + }); + + test('Renderer throws when it cannot resolve a variable key', () { + var parser = MustachioParser('Text {{s2}}'); + var ast = parser.parse(); + var foo = Foo(); + expect(() => renderFoo(foo, ast), + throwsA(const TypeMatcher())); + }); + + test('Renderer throws when it cannot resolve a section key', () { + var parser = MustachioParser('Text {{#s2}}Section{{/s2}}'); + var ast = parser.parse(); + var foo = Foo(); + expect(() => renderFoo(foo, ast), + throwsA(const TypeMatcher())); + }); + + test('Renderer throws when it cannot resolve a multi-name variable key', () { + var parser = MustachioParser('Text {{s1.len}}'); + var ast = parser.parse(); + var foo = Foo(); + expect(() => renderFoo(foo, ast), + throwsA(const TypeMatcher())); + }); + + test('Renderer throws when it cannot resolve a multi-name section key', () { + var parser = MustachioParser('Text {{s1.len}}'); + var ast = parser.parse(); + var foo = Foo(); + expect(() => renderFoo(foo, ast), + throwsA(const TypeMatcher())); + }); } diff --git a/tool/mustachio/codegen_runtime_renderer.dart b/tool/mustachio/codegen_runtime_renderer.dart index 0b0713b437..d83aaa6c48 100644 --- a/tool/mustachio/codegen_runtime_renderer.dart +++ b/tool/mustachio/codegen_runtime_renderer.dart @@ -268,7 +268,22 @@ renderIterable: '''); } } else { - // TODO(srawlins): Otherwise, add functions for plain values. + // Don't add Iterable functions for a generic type, for example + // `List.first` has 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. + if (getterName is! TypeParameterType) { + var rendererName = _typeToRenderFunctionName[getterType.element]; + _buffer.writeln(''' +isNullValue: ($_contextTypeVariable c) => c.$getterName == null, + +renderValue: + ($_contextTypeVariable c, RendererBase<$_contextTypeVariable> r, List ast) { + return $rendererName(c.$getterName, ast, parent: r); +}, +'''); + } } _buffer.writeln('),'); }