diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 58453558d5..33dce54991 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -19,7 +19,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - sdk: [dev, beta] + sdk: [dev, stable] job: [nnbd, flutter, sdk-analyzer, packages, sdk-docs] include: - os: macos-latest @@ -32,10 +32,12 @@ jobs: # Do not try to run flutter against the "stable" sdk, # it is unlikely to work and produces uninteresting # results. - - sdk: beta + - sdk: stable job: flutter - - sdk: beta + - sdk: stable job: sdk-analyzer + - sdk: stable + job: sdk-docs steps: - name: Store date diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 36f42bf20f..42ea2065bb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -24,7 +24,7 @@ yet in the issue tracker, start by opening an issue. Thanks! 2. When a change is user-facing, please add a new entry to the [changelog](https://github.com/dart-lang/dartdoc/blob/master/CHANGELOG.md) 3. Please include a test for your change. `dartdoc` has both `package:test`-style unittests as well as integration tests. To run the unittests, use `grind test`. 4. For major changes, run `grind compare-sdk-warnings` and `grind compare-flutter-warnings`, and include the summary results in your pull request. -5. Be sure to format your Dart code using `dartfmt -w`, otherwise travis will complain. +5. Be sure to format your Dart code using `dart format`, otherwise travis will complain. 6. Use `grind presubmit` before creating a pull request to quickly check for common problems. 7. Post your change via a pull request for review and integration! diff --git a/lib/dartdoc.dart b/lib/dartdoc.dart index fad967311b..3bf4186b9a 100644 --- a/lib/dartdoc.dart +++ b/lib/dartdoc.dart @@ -143,20 +143,6 @@ class Dartdoc { // ignore: unnecessary_getters_setters set generator(Generator newGenerator) => _generator = newGenerator; - /// An asynchronous factory method that builds Dartdoc's file writers - /// and returns a Dartdoc object with them. - @Deprecated('Prefer fromContext() instead') - static Future withDefaultGenerators( - DartdocGeneratorOptionContext config, - PackageBuilder packageBuilder, - ) async { - return Dartdoc._( - config, - await initHtmlGenerator(config), - packageBuilder, - ); - } - /// Asynchronous factory method that builds Dartdoc with an empty generator. static Future withEmptyGenerator( DartdocOptionContext config, @@ -195,15 +181,10 @@ class Dartdoc { Stream get onCheckProgress => _onCheckProgress.stream; - @Deprecated('Will be removed in 4.0.0. ' - 'Use the return value from generateDocsBase instead.') - PackageGraph packageGraph; - @visibleForTesting Future generateDocsBase() async { var stopwatch = Stopwatch()..start(); var packageGraph = await packageBuilder.buildPackageGraph(); - this.packageGraph = packageGraph; var seconds = stopwatch.elapsedMilliseconds / 1000.0; var libs = packageGraph.libraries.length; logInfo("Initialized dartdoc with $libs librar${libs == 1 ? 'y' : 'ies'} " diff --git a/lib/src/generator/templates.runtime_renderers.dart b/lib/src/generator/templates.runtime_renderers.dart index 5990461e0b..4246a7f637 100644 --- a/lib/src/generator/templates.runtime_renderers.dart +++ b/lib/src/generator/templates.runtime_renderers.dart @@ -69,6 +69,27 @@ class _Renderer_Accessor extends RendererBase { getters: _invisibleGetters['GetterSetterCombo']); }, ), + 'documentationComment': Property( + getValue: (CT_ c) => c.documentationComment, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } + var name = remainingNames.first; + var nextProperty = + _Renderer_String.propertyMap().getValue(name); + return nextProperty.renderVariable(self.getValue(c), + nextProperty, [...remainingNames.skip(1)]); + }, + isNullValue: (CT_ c) => c.documentationComment == null, + renderValue: (CT_ c, RendererBase r, + List ast, StringSink sink) { + _render_String( + c.documentationComment, ast, r.template, sink, + parent: r); + }, + ), 'element': Property( getValue: (CT_ c) => c.element, renderVariable: (CT_ c, Property self, @@ -145,6 +166,13 @@ class _Renderer_Accessor extends RendererBase { parent: r); }, ), + 'hasDocumentationComment': Property( + getValue: (CT_ c) => c.hasDocumentationComment, + renderVariable: (CT_ c, Property self, + List remainingNames) => + self.renderSimpleVariable(c, remainingNames, 'bool'), + getBool: (CT_ c) => c.hasDocumentationComment == true, + ), 'href': Property( getValue: (CT_ c) => c.href, renderVariable: @@ -1118,26 +1146,6 @@ class _Renderer_Category extends RendererBase { parent: r); }, ), - 'fileType': Property( - getValue: (CT_ c) => c.fileType, - renderVariable: - (CT_ c, Property self, List remainingNames) { - if (remainingNames.isEmpty) { - return self.getValue(c).toString(); - } - var name = remainingNames.first; - var nextProperty = - _Renderer_String.propertyMap().getValue(name); - return nextProperty.renderVariable(self.getValue(c), - nextProperty, [...remainingNames.skip(1)]); - }, - isNullValue: (CT_ c) => c.fileType == null, - renderValue: (CT_ c, RendererBase r, - List ast, StringSink sink) { - _render_String(c.fileType, ast, r.template, sink, - parent: r); - }, - ), 'fullyQualifiedName': Property( getValue: (CT_ c) => c.fullyQualifiedName, renderVariable: @@ -3908,6 +3916,26 @@ class _Renderer_DocumentationComment _propertyMapCache.putIfAbsent( CT_, () => { + 'documentationAsHtml': Property( + getValue: (CT_ c) => c.documentationAsHtml, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } + var name = remainingNames.first; + var nextProperty = + _Renderer_String.propertyMap().getValue(name); + return nextProperty.renderVariable(self.getValue(c), + nextProperty, [...remainingNames.skip(1)]); + }, + isNullValue: (CT_ c) => c.documentationAsHtml == null, + renderValue: (CT_ c, RendererBase r, + List ast, StringSink sink) { + _render_String(c.documentationAsHtml, ast, r.template, sink, + parent: r); + }, + ), 'documentationComment': Property( getValue: (CT_ c) => c.documentationComment, renderVariable: @@ -3929,6 +3957,53 @@ class _Renderer_DocumentationComment parent: r); }, ), + 'documentationFrom': Property( + getValue: (CT_ c) => c.documentationFrom, + renderVariable: (CT_ c, Property self, + List remainingNames) => + self.renderSimpleVariable( + c, remainingNames, 'List'), + renderIterable: (CT_ c, RendererBase r, + List ast, StringSink sink) { + return c.documentationFrom.map((e) => renderSimple( + e, ast, r.template, sink, + parent: r, + getters: _invisibleGetters['DocumentationComment'])); + }, + ), + 'documentationLocal': Property( + getValue: (CT_ c) => c.documentationLocal, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } + var name = remainingNames.first; + var nextProperty = + _Renderer_String.propertyMap().getValue(name); + return nextProperty.renderVariable(self.getValue(c), + nextProperty, [...remainingNames.skip(1)]); + }, + isNullValue: (CT_ c) => c.documentationLocal == null, + renderValue: (CT_ c, RendererBase r, + List ast, StringSink sink) { + _render_String(c.documentationLocal, ast, r.template, sink, + parent: r); + }, + ), + 'elementDocumentation': Property( + getValue: (CT_ c) => c.elementDocumentation, + renderVariable: (CT_ c, Property self, + List remainingNames) => + self.renderSimpleVariable( + c, remainingNames, 'Documentation'), + isNullValue: (CT_ c) => c.elementDocumentation == null, + renderValue: (CT_ c, RendererBase r, + List ast, StringSink sink) { + renderSimple(c.elementDocumentation, ast, r.template, sink, + parent: r, getters: _invisibleGetters['Documentation']); + }, + ), 'fullyQualifiedNameWithoutLibrary': Property( getValue: (CT_ c) => c.fullyQualifiedNameWithoutLibrary, renderVariable: @@ -3951,6 +4026,13 @@ class _Renderer_DocumentationComment parent: r); }, ), + 'hasDocumentationComment': Property( + getValue: (CT_ c) => c.hasDocumentationComment, + renderVariable: (CT_ c, Property self, + List remainingNames) => + self.renderSimpleVariable(c, remainingNames, 'bool'), + getBool: (CT_ c) => c.hasDocumentationComment == true, + ), 'hasNodoc': Property( getValue: (CT_ c) => c.hasNodoc, renderVariable: (CT_ c, Property self, @@ -3972,6 +4054,13 @@ class _Renderer_DocumentationComment getters: _invisibleGetters['ModelElementRenderer']); }, ), + 'needsPrecache': Property( + getValue: (CT_ c) => c.needsPrecache, + renderVariable: (CT_ c, Property self, + List remainingNames) => + self.renderSimpleVariable(c, remainingNames, 'bool'), + getBool: (CT_ c) => c.needsPrecache == true, + ), 'pathContext': Property( getValue: (CT_ c) => c.pathContext, renderVariable: (CT_ c, Property self, @@ -5839,17 +5928,39 @@ class _Renderer_GetterSetterCombo extends RendererBase { parent: r); }, ), + 'documentationComment': Property( + getValue: (CT_ c) => c.documentationComment, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } + var name = remainingNames.first; + var nextProperty = + _Renderer_String.propertyMap().getValue(name); + return nextProperty.renderVariable(self.getValue(c), + nextProperty, [...remainingNames.skip(1)]); + }, + isNullValue: (CT_ c) => c.documentationComment == null, + renderValue: (CT_ c, RendererBase r, + List ast, StringSink sink) { + _render_String( + c.documentationComment, ast, r.template, sink, + parent: r); + }, + ), 'documentationFrom': Property( getValue: (CT_ c) => c.documentationFrom, renderVariable: (CT_ c, Property self, List remainingNames) => self.renderSimpleVariable( - c, remainingNames, 'List'), + c, remainingNames, 'List'), renderIterable: (CT_ c, RendererBase r, List ast, StringSink sink) { - return c.documentationFrom.map((e) => _render_ModelElement( + return c.documentationFrom.map((e) => renderSimple( e, ast, r.template, sink, - parent: r)); + parent: r, + getters: _invisibleGetters['DocumentationComment'])); }, ), 'enclosingElement': Property( @@ -5900,28 +6011,6 @@ class _Renderer_GetterSetterCombo extends RendererBase { self.renderSimpleVariable(c, remainingNames, 'bool'), getBool: (CT_ c) => c.getterSetterBothAvailable == true, ), - 'getterSetterDocumentationComment': Property( - getValue: (CT_ c) => c.getterSetterDocumentationComment, - renderVariable: - (CT_ c, Property self, List remainingNames) { - if (remainingNames.isEmpty) { - return self.getValue(c).toString(); - } - var name = remainingNames.first; - var nextProperty = - _Renderer_String.propertyMap().getValue(name); - return nextProperty.renderVariable(self.getValue(c), - nextProperty, [...remainingNames.skip(1)]); - }, - isNullValue: (CT_ c) => - c.getterSetterDocumentationComment == null, - renderValue: (CT_ c, RendererBase r, - List ast, StringSink sink) { - _render_String(c.getterSetterDocumentationComment, ast, - r.template, sink, - parent: r); - }, - ), 'hasAccessorsWithDocs': Property( getValue: (CT_ c) => c.hasAccessorsWithDocs, renderVariable: (CT_ c, Property self, @@ -5929,6 +6018,13 @@ class _Renderer_GetterSetterCombo extends RendererBase { self.renderSimpleVariable(c, remainingNames, 'bool'), getBool: (CT_ c) => c.hasAccessorsWithDocs == true, ), + 'hasDocumentationComment': Property( + getValue: (CT_ c) => c.hasDocumentationComment, + renderVariable: (CT_ c, Property self, + List remainingNames) => + self.renderSimpleVariable(c, remainingNames, 'bool'), + getBool: (CT_ c) => c.hasDocumentationComment == true, + ), 'hasExplicitGetter': Property( getValue: (CT_ c) => c.hasExplicitGetter, renderVariable: (CT_ c, Property self, @@ -7279,18 +7375,6 @@ class _Renderer_Library extends RendererBase { parent: r)); }, ), - 'allOriginalModelElementNames': Property( - getValue: (CT_ c) => c.allOriginalModelElementNames, - renderVariable: (CT_ c, Property self, - List remainingNames) => - self.renderSimpleVariable( - c, remainingNames, 'Iterable'), - renderIterable: (CT_ c, RendererBase r, - List ast, StringSink sink) { - return c.allOriginalModelElementNames.map((e) => - _render_String(e, ast, r.template, sink, parent: r)); - }, - ), 'canonicalFor': Property( getValue: (CT_ c) => c.canonicalFor, renderVariable: (CT_ c, Property self, @@ -9371,19 +9455,6 @@ class _Renderer_ModelElement extends RendererBase { getters: _invisibleGetters['CompilationUnitElement']); }, ), - 'computeDocumentationFrom': Property( - getValue: (CT_ c) => c.computeDocumentationFrom, - renderVariable: (CT_ c, Property self, - List remainingNames) => - self.renderSimpleVariable( - c, remainingNames, 'List'), - renderIterable: (CT_ c, RendererBase r, - List ast, StringSink sink) { - return c.computeDocumentationFrom.map((e) => - _render_ModelElement(e, ast, r.template, sink, - parent: r)); - }, - ), 'config': Property( getValue: (CT_ c) => c.config, renderVariable: (CT_ c, Property self, @@ -9450,41 +9521,8 @@ class _Renderer_ModelElement extends RendererBase { parent: r); }, ), - 'documentationAsHtml': Property( - getValue: (CT_ c) => c.documentationAsHtml, - renderVariable: - (CT_ c, Property self, List remainingNames) { - if (remainingNames.isEmpty) { - return self.getValue(c).toString(); - } - var name = remainingNames.first; - var nextProperty = - _Renderer_String.propertyMap().getValue(name); - return nextProperty.renderVariable(self.getValue(c), - nextProperty, [...remainingNames.skip(1)]); - }, - isNullValue: (CT_ c) => c.documentationAsHtml == null, - renderValue: (CT_ c, RendererBase r, - List ast, StringSink sink) { - _render_String(c.documentationAsHtml, ast, r.template, sink, - parent: r); - }, - ), - 'documentationFrom': Property( - getValue: (CT_ c) => c.documentationFrom, - renderVariable: (CT_ c, Property self, - List remainingNames) => - self.renderSimpleVariable( - c, remainingNames, 'List'), - renderIterable: (CT_ c, RendererBase r, - List ast, StringSink sink) { - return c.documentationFrom.map((e) => _render_ModelElement( - e, ast, r.template, sink, - parent: r)); - }, - ), - 'documentationLocal': Property( - getValue: (CT_ c) => c.documentationLocal, + 'documentationComment': Property( + getValue: (CT_ c) => c.documentationComment, renderVariable: (CT_ c, Property self, List remainingNames) { if (remainingNames.isEmpty) { @@ -9496,10 +9534,11 @@ class _Renderer_ModelElement extends RendererBase { return nextProperty.renderVariable(self.getValue(c), nextProperty, [...remainingNames.skip(1)]); }, - isNullValue: (CT_ c) => c.documentationLocal == null, + isNullValue: (CT_ c) => c.documentationComment == null, renderValue: (CT_ c, RendererBase r, List ast, StringSink sink) { - _render_String(c.documentationLocal, ast, r.template, sink, + _render_String( + c.documentationComment, ast, r.template, sink, parent: r); }, ), @@ -9703,6 +9742,13 @@ class _Renderer_ModelElement extends RendererBase { self.renderSimpleVariable(c, remainingNames, 'bool'), getBool: (CT_ c) => c.hasDocumentation == true, ), + 'hasDocumentationComment': Property( + getValue: (CT_ c) => c.hasDocumentationComment, + renderVariable: (CT_ c, Property self, + List remainingNames) => + self.renderSimpleVariable(c, remainingNames, 'bool'), + getBool: (CT_ c) => c.hasDocumentationComment == true, + ), 'hasExtendedDocumentation': Property( getValue: (CT_ c) => c.hasExtendedDocumentation, renderVariable: (CT_ c, Property self, @@ -11147,13 +11193,6 @@ class _Renderer_Package extends RendererBase { self.renderSimpleVariable(c, remainingNames, 'bool'), getBool: (CT_ c) => c.hasDocumentation == true, ), - 'hasDocumentationFile': Property( - getValue: (CT_ c) => c.hasDocumentationFile, - renderVariable: (CT_ c, Property self, - List remainingNames) => - self.renderSimpleVariable(c, remainingNames, 'bool'), - getBool: (CT_ c) => c.hasDocumentationFile == true, - ), 'hasDocumentedCategories': Property( getValue: (CT_ c) => c.hasDocumentedCategories, renderVariable: (CT_ c, Property self, @@ -11545,7 +11584,7 @@ class _Renderer_Package extends RendererBase { } } -String renderIndex(PackageTemplateData context, Template template) { +String renderError(PackageTemplateData context, Template template) { var buffer = StringBuffer(); _render_PackageTemplateData(context, template.ast, template, buffer); return buffer.toString(); @@ -11747,7 +11786,7 @@ class _Renderer_PackageTemplateData extends RendererBase { } } -String renderError(PackageTemplateData context, Template template) { +String renderIndex(PackageTemplateData context, Template template) { var buffer = StringBuffer(); _render_PackageTemplateData(context, template.ast, template, buffer); return buffer.toString(); @@ -15201,6 +15240,28 @@ const _invisibleGetters = { 'useBaseHref' }, 'DocumentLocation': {'hashCode', 'runtimeType', 'index'}, + 'Documentation': { + 'hashCode', + 'runtimeType', + 'hasExtendedDocs', + 'asHtml', + 'asOneLiner', + 'commentRefs' + }, + 'DocumentationComment': { + 'documentationFrom', + 'documentationAsHtml', + 'elementDocumentation', + 'documentationComment', + 'hasDocumentationComment', + 'hasNodoc', + 'sourceFileName', + 'fullyQualifiedNameWithoutLibrary', + 'pathContext', + 'modelElementRenderer', + 'documentationLocal', + 'needsPrecache' + }, 'Element': { 'hashCode', 'runtimeType', @@ -15409,7 +15470,8 @@ const _invisibleGetters = { 'hasAccessorsWithDocs', 'getterSetterBothAvailable', 'oneLineDoc', - 'getterSetterDocumentationComment', + 'documentationComment', + 'hasDocumentationComment', 'modelType', 'isCallable', 'hasParameters', diff --git a/lib/src/io_utils.dart b/lib/src/io_utils.dart index 35047aa123..2d97f7bda4 100644 --- a/lib/src/io_utils.dart +++ b/lib/src/io_utils.dart @@ -106,17 +106,6 @@ String getFileNameFor(String name) => '${name.replaceAll(_libraryNameRegExp, '-')}.html'; final _libraryNameRegExp = RegExp('[.:]'); -@Deprecated('Public variable intended to be private; will be removed as early ' - 'as Dartdoc 1.0.0') -RegExp get libraryNameRegexp => _libraryNameRegExp; - -@Deprecated('Public variable intended to be private; will be removed as early ' - 'as Dartdoc 1.0.0') -final RegExp partOfRegexp = RegExp('part of '); - -@Deprecated('Public variable intended to be private; will be removed as early ' - 'as Dartdoc 1.0.0') -final RegExp newLinePartOfRegexp = RegExp('\npart of '); typedef TaskQueueClosure = Future Function(); diff --git a/lib/src/model/accessor.dart b/lib/src/model/accessor.dart index d37f70aa2c..a850a0bd5f 100644 --- a/lib/src/model/accessor.dart +++ b/lib/src/model/accessor.dart @@ -74,31 +74,57 @@ class Accessor extends ModelElement implements EnclosedElement { return _sourceCode; } + bool _documentationCommentComputed = false; + String _documentationComment; @override - String computeDocumentationComment() { - String docComment; - if (isSynthetic) { - // If we're a setter, only display something if we have something different than the getter. - // TODO(jcollins-g): modify analyzer to do this itself? - if (isGetter || - definingCombo.hasNodoc || - (isSetter && - definingCombo.hasGetter && - definingCombo.getter.documentationComment != - definingCombo.documentationComment)) { - docComment = definingCombo.documentationComment; - } else { - docComment = ''; + String get documentationComment => _documentationCommentComputed + ? _documentationComment + : _documentationComment ??= () { + _documentationCommentComputed = true; + if (isSynthetic) { + return _syntheticDocumentationComment; + } + return stripComments(super.documentationComment); + }(); + + String /*!*/ __syntheticDocumentationComment; + + /// Build a documentation comment for this accessor assuming it is synthetic. + /// Value here is not useful if [isSynthetic] is false. + String /*!*/ get _syntheticDocumentationComment => + __syntheticDocumentationComment ??= () { + if (_hasSyntheticDocumentationComment) { + return definingCombo.documentationComment ?? ''; + } + return ''; + }(); + + /// If this is a getter, assume we want synthetic documentation. + /// If the definingCombo has a nodoc tag, we want synthetic documentation + /// for a synthetic accessor just in case it is inherited somewhere + /// down the line due to split inheritance. + bool get _hasSyntheticDocumentationComment => + (isGetter || definingCombo.hasNodoc || _comboDocsAreIndependent()) && + definingCombo.hasDocumentationComment; + + // If we're a setter, and a getter exists, do not add synthetic + // documentation if the combo's documentation is actually derived + // from that getter. + bool _comboDocsAreIndependent() { + if (isSetter && definingCombo.hasGetter) { + if (definingCombo.getter.isSynthetic || + !definingCombo.documentationFrom.contains(this)) { + return true; } - } else { - docComment = super.computeDocumentationComment(); - } - if (docComment != null) { - return stripComments(docComment); } - return null; + return false; } + @override + bool get hasDocumentationComment => isSynthetic + ? _hasSyntheticDocumentationComment + : element.documentationComment != null; + @override void warn( PackageWarning kind, { diff --git a/lib/src/model/canonicalization.dart b/lib/src/model/canonicalization.dart index ba6ccba6f8..152db508ec 100644 --- a/lib/src/model/canonicalization.dart +++ b/lib/src/model/canonicalization.dart @@ -28,7 +28,7 @@ abstract class Canonicalization implements Locatable, Documentable { } ScoredCandidate _scoreElementWithLibrary(Library lib) { - var scoredCandidate = ScoredCandidate(this, lib); + var scoredCandidate = ScoredCandidate(lib); Iterable resplit(Set items) sync* { for (var item in items) { for (var subItem in item.split('_')) { @@ -72,12 +72,6 @@ abstract class Canonicalization implements Locatable, Documentable { scoreBoost, 'element location parts start with parts of name'); return scoredCandidate; } - - @Deprecated( - 'Public method intended to be private; will be removed as early as ' - 'Dartdoc 1.0.0') - ScoredCandidate scoreElementWithLibrary(Library lib) => - _scoreElementWithLibrary(lib); } /// This class represents the score for a particular element; how likely @@ -85,31 +79,13 @@ abstract class Canonicalization implements Locatable, Documentable { class ScoredCandidate implements Comparable { final List _reasons = []; - @Deprecated( - 'Public field intended to be private; will be removed as early as ' - 'Dartdoc 1.0.0') - List get reasons => _reasons; - - @Deprecated( - 'Public field intended to be private; will be removed as early as ' - 'Dartdoc 1.0.0') - set reasons(List value) => reasons = value; - - /// The canonicalization element being scored. - final Canonicalization _element; - - @Deprecated( - 'Public getter intended to be private; will be removed as early as ' - 'Dartdoc 1.0.0') - Canonicalization get element => _element; - final Library library; /// The score accumulated so far. Higher means it is more likely that this /// is the intended canonical Library. double score = 0.0; - ScoredCandidate(this._element, this.library); + ScoredCandidate(this.library); void _alterScore(double scoreDelta, String reason) { score += scoreDelta; @@ -119,12 +95,6 @@ class ScoredCandidate implements Comparable { } } - @Deprecated( - 'Public method intended to be private; will be removed as early as ' - 'Dartdoc 1.0.0') - void alterScore(double scoreDelta, String reason) => - _alterScore(scoreDelta, reason); - @override int compareTo(ScoredCandidate other) { //assert(element == other.element); diff --git a/lib/src/model/categorization.dart b/lib/src/model/categorization.dart index f477773af1..08c190a120 100644 --- a/lib/src/model/categorization.dart +++ b/lib/src/model/categorization.dart @@ -10,10 +10,6 @@ final RegExp _categoryRegExp = RegExp( r'[ ]*{@(api|category|subCategory|image|samples) (.+?)}[ ]*\n?', multiLine: true); -@Deprecated('Public variable intended to be private; will be removed as early ' - 'as Dartdoc 1.0.0') -RegExp get categoryRegexp => _categoryRegExp; - /// Mixin implementing dartdoc categorization for ModelElements. abstract class Categorization implements ModelElement { @override diff --git a/lib/src/model/category.dart b/lib/src/model/category.dart index a6c5c9916a..807cde1fca 100644 --- a/lib/src/model/category.dart +++ b/lib/src/model/category.dart @@ -27,30 +27,18 @@ class Category extends Nameable Indexable implements Documentable { /// All libraries in [libraries] must come from [package]. - // TODO(srawlins): To make final, remove public getter, setter, rename to be - // public, and add `final` modifier. - Package _package; + final Package _package; @override Package get package => _package; - @Deprecated('Field intended to be final; setter will be removed as early as ' - 'Dartdoc 1.0.0') - set package(Package value) => _package = value; - final String _name; - // TODO(srawlins): To make final, remove public getter, setter, rename to be - // public, and add `final` modifier. - DartdocOptionContext _config; + final DartdocOptionContext _config; @override DartdocOptionContext get config => _config; - @Deprecated('Field intended to be final; setter will be removed as early as ' - 'Dartdoc 1.0.0') - set config(DartdocOptionContext value) => _config = value; - final Set _allItems = {}; final List _classes = []; @@ -142,11 +130,6 @@ class Category extends Nameable String get _fileType => package.fileType; - @Deprecated( - 'Public field intended to be private; will be removed as early as ' - 'Dartdoc 1.0.0') - String get fileType => _fileType; - String get filePath => 'topics/$name-topic.$_fileType'; @override diff --git a/lib/src/model/container_member.dart b/lib/src/model/container_member.dart index f3ec632515..3e68348229 100644 --- a/lib/src/model/container_member.dart +++ b/lib/src/model/container_member.dart @@ -75,7 +75,7 @@ mixin ContainerMember on ModelElement implements EnclosedElement { // TODO(jcollins-g): split Field documentation up between accessors // and resolve the pieces with different scopes. dart-lang/dartdoc#2693. // Until then, just pretend we're handling this correctly. - yield documentationFrom.first.definingLibrary; + yield (documentationFrom.first as ModelElement).definingLibrary; // TODO(jcollins-g): Wean users off of depending on canonical library // resolution. dart-lang/dartdoc#2696 if (canonicalLibrary != null) yield canonicalLibrary; diff --git a/lib/src/model/documentation_comment.dart b/lib/src/model/documentation_comment.dart index ae8a5335ff..8d52d16f3c 100644 --- a/lib/src/model/documentation_comment.dart +++ b/lib/src/model/documentation_comment.dart @@ -2,7 +2,12 @@ import 'package:args/args.dart'; import 'package:crypto/crypto.dart' as crypto; -import 'package:dartdoc/src/model/model.dart'; +import 'package:dartdoc/src/model/documentable.dart'; +import 'package:dartdoc/src/model/documentation.dart'; +import 'package:dartdoc/src/model/inheritable.dart'; +import 'package:dartdoc/src/model/locatable.dart'; +import 'package:dartdoc/src/model/model_element.dart'; +import 'package:dartdoc/src/model/source_code_mixin.dart'; import 'package:dartdoc/src/render/model_element_renderer.dart'; import 'package:dartdoc/src/utils.dart'; import 'package:dartdoc/src/warnings.dart'; @@ -25,33 +30,68 @@ final _basicToolPattern = RegExp( final _examplePattern = RegExp(r'{@example\s+([^}]+)}'); +final _macroRegExp = RegExp(r'{@macro\s+([^}]+)}'); + +final _htmlInjectRegExp = RegExp(r'([a-f0-9]+)'); + +final RegExp _needsPrecacheRegExp = RegExp(r'{@(template|tool|inject-html)'); + /// Features for processing directives in a documentation comment. /// -/// [processCommentWithoutTools] and [processComment] are the primary +/// [_processCommentWithoutTools] and [processComment] are the primary /// entrypoints. mixin DocumentationComment on Documentable, Warnable, Locatable, SourceCodeMixin { - /// The documentation comment on the Element may be null, so memoization - /// cannot rely on the null-ness of [_documentationComment], it must be - /// more explicit. - bool _documentationCommentComputed = false; - String _documentationComment; - - String get documentationComment { - if (_documentationCommentComputed == false) { - _documentationComment = computeDocumentationComment(); - _documentationCommentComputed = true; - } - return _documentationComment; + List _documentationFrom; + + /// Returns the ModelElement(s) from which we will get documentation. + /// Can be more than one if this is a Field composing documentation from + /// multiple Accessors. + /// + /// This getter will walk up the inheritance hierarchy + /// to find docs, if the current class doesn't have docs + /// for this element. + @override + List get documentationFrom => + _documentationFrom ??= () { + if (!hasDocumentationComment && + this is Inheritable && + (this as Inheritable).overriddenElement != null) { + return (this as Inheritable).overriddenElement.documentationFrom; + } else if (this is Inheritable && (this as Inheritable).isInherited) { + var thisInheritable = (this as Inheritable); + var fromThis = ModelElement.fromElement( + element, thisInheritable.definingEnclosingContainer.packageGraph); + return fromThis.documentationFrom; + } else { + return [this]; + } + }(); + + String _documentationAsHtml; + @override + String get documentationAsHtml { + if (_documentationAsHtml != null) return _documentationAsHtml; + _documentationAsHtml = _injectHtmlFragments(elementDocumentation.asHtml); + return _documentationAsHtml; + } + + Documentation _elementDocumentation; + Documentation get elementDocumentation { + if (_elementDocumentation != null) return _elementDocumentation; + _elementDocumentation = Documentation.forElement(this); + return _elementDocumentation; } - /// Implement to derive the raw documentation comment string from the - /// analyzer. - String computeDocumentationComment(); + String /*!*/ get documentationComment; + + /// True if [this] has a synthetic/inherited or local documentation + /// comment. False otherwise. + bool get hasDocumentationComment; /// Returns true if the raw documentation comment has a nodoc indication. bool get hasNodoc { - if (documentationComment != null && + if (hasDocumentationComment && (documentationComment.contains('@nodoc') || documentationComment.contains(''))) { return true; @@ -61,7 +101,7 @@ mixin DocumentationComment /// Process a [documentationComment], performing various actions based on /// `{@}`-style directives, except `{@tool}`, returning the processed result. - String processCommentWithoutTools(String documentationComment) { + String _processCommentWithoutTools(String documentationComment) { var docs = stripComments(documentationComment); if (!docs.contains('{@')) { _analyzeCodeBlocks(docs); @@ -81,6 +121,7 @@ mixin DocumentationComment /// Process [documentationComment], performing various actions based on /// `{@}`-style directives, returning the processed result. + @visibleForTesting Future processComment(String documentationComment) async { var docs = stripComments(documentationComment); // Must evaluate tools first, in case they insert any other directives. @@ -709,4 +750,145 @@ mixin DocumentationComment } }); } + + /// Returns the documentation for this literal element unless + /// [config.dropTextFrom] indicates it should not be returned. Macro + /// definitions are stripped, but macros themselves are not injected. This + /// is a two stage process to avoid ordering problems. + String _documentationLocal; + + String get documentationLocal => + _documentationLocal ??= _buildDocumentationLocal(); + + /// Unconditionally precache local documentation. + /// + /// Use only in factory for [PackageGraph]. + Future precacheLocalDocs() async { + _documentationLocal = await _buildDocumentationBase(); + } + + bool _needsPrecache; + bool get needsPrecache => _needsPrecache ??= + _needsPrecacheRegExp.hasMatch(documentationComment ?? ''); + + String _rawDocs; + + String _buildDocumentationLocal() => _buildDocumentationBaseSync(); + + /// Override this to add more features to the documentation builder in a + /// subclass. + String buildDocumentationAddition(String docs) => docs ?? ''; + + /// Separate from _buildDocumentationLocal for overriding. + String _buildDocumentationBaseSync() { + assert(_rawDocs == null, + 'reentrant calls to _buildDocumentation* not allowed'); + // Do not use the sync method if we need to evaluate tools or templates. + assert(!isCanonical || !needsPrecache); + if (config.dropTextFrom.contains(element.library.name)) { + _rawDocs = ''; + } else { + _rawDocs = _processCommentWithoutTools(documentationComment ?? ''); + } + _rawDocs = buildDocumentationAddition(_rawDocs); + return _rawDocs; + } + + /// Separate from _buildDocumentationLocal for overriding. Can only be + /// used as part of [PackageGraph.setUpPackageGraph]. + Future _buildDocumentationBase() async { + assert(_rawDocs == null, + 'reentrant calls to _buildDocumentation* not allowed'); + // Do not use the sync method if we need to evaluate tools or templates. + if (config.dropTextFrom.contains(element.library.name)) { + _rawDocs = ''; + } else { + _rawDocs = await processComment(documentationComment ?? ''); + } + _rawDocs = buildDocumentationAddition(_rawDocs); + return _rawDocs; + } + + /// Replace <[digest]> in API comments with + /// the contents of the HTML fragment earlier defined by the + /// {@inject-html} directive. The [digest] is a SHA1 of the contents + /// of the HTML fragment, automatically generated upon parsing the + /// {@inject-html} directive. + /// + /// This markup is generated and inserted by [_stripHtmlAndAddToIndex] when it + /// removes the HTML fragment in preparation for markdown processing. It isn't + /// meant to be used at a user level. + /// + /// Example: + /// + /// You place the fragment in a dartdoc comment: + /// + /// Some comments + /// {@inject-html} + /// <p>[HTML contents!]</p> + /// {@endtemplate} + /// More comments + /// + /// and [_stripHtmlAndAddToIndex] will replace your HTML fragment with this: + /// + /// Some comments + /// <dartdoc-html>4cc02f877240bf69855b4c7291aba8a16e5acce0</dartdoc-html> + /// More comments + /// + /// Which will render in the final HTML output as: + /// + /// Some comments + /// <p>[HTML contents!]</p> + /// More comments + /// + /// And the HTML fragment will not have been processed or changed by Markdown, + /// but just injected verbatim. + String _injectHtmlFragments(String rawDocs) { + if (!config.injectHtml) return rawDocs; + + return rawDocs.replaceAllMapped(_htmlInjectRegExp, (match) { + var fragment = packageGraph.getHtmlFragment(match[1]); + if (fragment == null) { + warn(PackageWarning.unknownHtmlFragment, message: match[1]); + } + return fragment; + }); + } + + /// Replace {@macro ...} in API comments with the contents of the macro + /// + /// Syntax: + /// + /// {@macro NAME} + /// + /// Example: + /// + /// You define the template in any comment for a documentable entity like: + /// + /// {@template foo} + /// Foo contents! + /// {@endtemplate} + /// + /// and them somewhere use it like this: + /// + /// Some comments + /// {@macro foo} + /// More comments + /// + /// Which will render + /// + /// Some comments + /// Foo contents! + /// More comments + /// + String injectMacros(String rawDocs) { + return rawDocs.replaceAllMapped(_macroRegExp, (match) { + var macro = packageGraph.getMacro(match[1]); + if (macro == null) { + warn(PackageWarning.unknownMacro, message: match[1]); + } + macro = processCommentDirectives(macro ?? ''); + return macro; + }); + } } diff --git a/lib/src/model/enum.dart b/lib/src/model/enum.dart index 9f97612bbf..a15cfb6fd4 100644 --- a/lib/src/model/enum.dart +++ b/lib/src/model/enum.dart @@ -56,7 +56,7 @@ class EnumField extends Field { String get constantValueBase => _fieldRenderer.renderValue(this); @override - List get documentationFrom { + List get documentationFrom { if (name == 'values' || name == 'index') return [this]; return super.documentationFrom; } diff --git a/lib/src/model/field.dart b/lib/src/model/field.dart index ba2db45303..a961f4f4d0 100644 --- a/lib/src/model/field.dart +++ b/lib/src/model/field.dart @@ -138,13 +138,6 @@ class Field extends ModelElement return allFeatures; } - @override - String computeDocumentationComment() { - var docs = getterSetterDocumentationComment; - if (docs.isEmpty) return field.documentationComment; - return docs; - } - FieldElement get field => (element as FieldElement); @override diff --git a/lib/src/model/getter_setter_combo.dart b/lib/src/model/getter_setter_combo.dart index 53d353e53a..fba01f1f3e 100644 --- a/lib/src/model/getter_setter_combo.dart +++ b/lib/src/model/getter_setter_combo.dart @@ -111,10 +111,10 @@ mixin GetterSetterCombo on ModelElement { @override bool get isPublic => hasPublicGetter || hasPublicSetter; - List _documentationFrom; + List _documentationFrom; @override - List get documentationFrom { + List get documentationFrom { if (_documentationFrom == null) { _documentationFrom = []; if (hasPublicGetter) { @@ -124,7 +124,7 @@ mixin GetterSetterCombo on ModelElement { } if (_documentationFrom.isEmpty || _documentationFrom.every((e) => e.documentationComment == '')) { - _documentationFrom = computeDocumentationFrom; + _documentationFrom = super.documentationFrom; } } return _documentationFrom; @@ -160,34 +160,56 @@ mixin GetterSetterCombo on ModelElement { return _oneLineDoc; } - String get getterSetterDocumentationComment { - var buffer = StringBuffer(); - - // Check for synthetic before public, always, or stack overflow. - if (hasGetter && !getter.isSynthetic && getter.isPublic) { - assert(getter.documentationFrom.length == 1); - // We have to check against dropTextFrom here since documentationFrom - // doesn't yield the real elements for GetterSetterCombos. - if (!config.dropTextFrom - .contains(getter.documentationFrom.first.element.library.name)) { - var docs = getter.documentationFrom.first.documentationComment; - if (docs != null) buffer.write(docs); - } - } + bool _documentationCommentComputed = false; + String _documentationComment; + @override + String /*!*/ get documentationComment => _documentationCommentComputed + ? _documentationComment + : _documentationComment ??= () { + _documentationCommentComputed = true; + var docs = _getterSetterDocumentationComment; + if (docs.isEmpty) return element.documentationComment ?? ''; + return docs; + }(); - if (hasSetter && !setter.isSynthetic && setter.isPublic) { - assert(setter.documentationFrom.length == 1); - if (!config.dropTextFrom - .contains(setter.documentationFrom.first.element.library.name)) { - var docs = setter.documentationFrom.first.documentationComment; - if (docs != null) { - if (buffer.isNotEmpty) buffer.write('\n\n'); - buffer.write(docs); + @override + bool get hasDocumentationComment => + _getterSetterDocumentationComment.isNotEmpty || + element.documentationComment != null; + + String __getterSetterDocumentationComment; + + /// Derive a documentation comment for the combo by copying documentation + /// from the [getter] and/or [setter]. + String /*!*/ get _getterSetterDocumentationComment => + __getterSetterDocumentationComment ??= () { + var buffer = StringBuffer(); + + // Check for synthetic before public, always, or stack overflow. + if (hasGetter && !getter.isSynthetic && getter.isPublic) { + assert(getter.documentationFrom.length == 1); + var fromGetter = getter.documentationFrom.first; + // We have to check against dropTextFrom here since documentationFrom + // doesn't yield the real elements for GetterSetterCombos. + if (!config.dropTextFrom.contains(fromGetter.element.library.name)) { + if (fromGetter.hasDocumentationComment) { + buffer.write(fromGetter.documentationComment); + } + } } - } - } - return buffer.toString(); - } + + if (hasSetter && !setter.isSynthetic && setter.isPublic) { + assert(setter.documentationFrom.length == 1); + var fromSetter = setter.documentationFrom.first; + if (!config.dropTextFrom.contains(fromSetter.element.library.name)) { + if (fromSetter.hasDocumentationComment) { + if (buffer.isNotEmpty) buffer.write('\n\n'); + buffer.write(fromSetter.documentationComment); + } + } + } + return buffer.toString(); + }(); ElementType get modelType { if (hasGetter) return getter.modelType.returnType; diff --git a/lib/src/model/inheriting_container.dart b/lib/src/model/inheriting_container.dart index 09418f21c9..d0faa9292a 100644 --- a/lib/src/model/inheriting_container.dart +++ b/lib/src/model/inheriting_container.dart @@ -361,11 +361,6 @@ abstract class InheritingContainer extends Container .map((et) => (et.modelElement as InheritingContainer)) .contains(other); - @Deprecated( - 'Public method intended to be private; will be removed as early as ' - 'Dartdoc 1.0.0') - bool isInheritingFrom(InheritingContainer other) => _isInheritingFrom(other); - DefinedElementType _modelType; @override diff --git a/lib/src/model/library.dart b/lib/src/model/library.dart index 120d447403..1a7c187f85 100644 --- a/lib/src/model/library.dart +++ b/lib/src/model/library.dart @@ -114,13 +114,6 @@ class Library extends ModelElement with Categorization, TopLevelContainer { ]); } - @Deprecated( - 'Public method intended to be private; will be removed as early as ' - 'Dartdoc 1.0.0') - static Iterable getDefinedElements( - CompilationUnitElement compilationUnit) => - _getDefinedElements(compilationUnit); - /// Allow scope for Libraries. @override Scope get scope => element.scope; @@ -173,12 +166,6 @@ class Library extends ModelElement with Categorization, TopLevelContainer { return __allOriginalModelElementNames; } - @Deprecated( - 'Public getter intended to be private; will be removed as early as ' - 'Dartdoc 1.0.0') - Iterable get allOriginalModelElementNames => - _allOriginalModelElementNames; - @override CharacterLocation get characterLocation { if (element.nameOffset == -1) { diff --git a/lib/src/model/model_element.dart b/lib/src/model/model_element.dart index bb725b7f76..af5162e064 100644 --- a/lib/src/model/model_element.dart +++ b/lib/src/model/model_element.dart @@ -36,20 +36,6 @@ import 'package:dartdoc/src/warnings.dart'; import 'package:meta/meta.dart'; import 'package:path/path.dart' as path show Context; -/// This doc may need to be processed in case it has a template or html -/// fragment. -final RegExp needsPrecacheRegExp = RegExp(r'{@(template|tool|inject-html)'); - -final _htmlInjectRegExp = RegExp(r'([a-f0-9]+)'); -@Deprecated('Public variable intended to be private; will be removed as early ' - 'as Dartdoc 1.0.0') -RegExp get htmlInjectRegExp => _htmlInjectRegExp; - -final _macroRegExp = RegExp(r'{@macro\s+([^}]+)}'); -@Deprecated('Public variable intended to be private; will be removed as early ' - 'as Dartdoc 1.0.0') -RegExp get macroRegExp => _macroRegExp; - // TODO(jcollins-g): Implement resolution per ECMA-408 4th edition, page 39 #22. /// Resolves this very rare case incorrectly by picking the closest element in /// the inheritance and interface chains from the analyzer. @@ -120,8 +106,6 @@ abstract class ModelElement extends Canonicalization final Member /*?*/ _originalMember; final Library /*?*/ _library; - String _rawDocs; - Documentation __documentation; UnmodifiableListView _parameters; String _linkedName; @@ -508,15 +492,6 @@ abstract class ModelElement extends Canonicalization ModelElement get canonicalModelElement => _canonicalModelElement ??= buildCanonicalModelElement(); - List _documentationFrom; - - // TODO(jcollins-g): untangle when mixins can call super - @override - List get documentationFrom { - _documentationFrom ??= computeDocumentationFrom; - return _documentationFrom; - } - bool get hasSourceHref => sourceHref.isNotEmpty; String _sourceHref; @@ -525,82 +500,6 @@ abstract class ModelElement extends Canonicalization return _sourceHref; } - /// Returns the ModelElement(s) from which we will get documentation. - /// Can be more than one if this is a Field composing documentation from - /// multiple Accessors. - /// - /// This getter will walk up the inheritance hierarchy - /// to find docs, if the current class doesn't have docs - /// for this element. - List get computeDocumentationFrom { - if (documentationComment == null && - _canOverride && - this is Inheritable && - (this as Inheritable).overriddenElement != null) { - return (this as Inheritable).overriddenElement.documentationFrom; - } else if (this is Inheritable && (this as Inheritable).isInherited) { - var thisInheritable = (this as Inheritable); - var fromThis = ModelElement.fromElement( - element, thisInheritable.definingEnclosingContainer.packageGraph); - return fromThis.documentationFrom; - } else { - return [this]; - } - } - - String _buildDocumentationLocal() => _buildDocumentationBaseSync(); - - /// Override this to add more features to the documentation builder in a - /// subclass. - String buildDocumentationAddition(String docs) => docs ??= ''; - - /// Separate from _buildDocumentationLocal for overriding. - String _buildDocumentationBaseSync() { - assert(_rawDocs == null, - 'reentrant calls to _buildDocumentation* not allowed'); - // Do not use the sync method if we need to evaluate tools or templates. - assert(!isCanonical || - !needsPrecacheRegExp.hasMatch(documentationComment ?? '')); - if (config.dropTextFrom.contains(element.library.name)) { - _rawDocs = ''; - } else { - _rawDocs = processCommentWithoutTools(documentationComment ?? ''); - } - _rawDocs = buildDocumentationAddition(_rawDocs); - return _rawDocs; - } - - /// Separate from _buildDocumentationLocal for overriding. Can only be - /// used as part of [PackageGraph.setUpPackageGraph]. - Future _buildDocumentationBase() async { - assert(_rawDocs == null, - 'reentrant calls to _buildDocumentation* not allowed'); - // Do not use the sync method if we need to evaluate tools or templates. - if (config.dropTextFrom.contains(element.library.name)) { - _rawDocs = ''; - } else { - _rawDocs = await processComment(documentationComment ?? ''); - } - _rawDocs = buildDocumentationAddition(_rawDocs); - return _rawDocs; - } - - /// Returns the documentation for this literal element unless - /// [config.dropTextFrom] indicates it should not be returned. Macro - /// definitions are stripped, but macros themselves are not injected. This - /// is a two stage process to avoid ordering problems. - String _documentationLocal; - - String get documentationLocal => - _documentationLocal ??= _buildDocumentationLocal(); - - /// Returns the docs, stripped of their leading comments syntax. - @override - String get documentation { - return _injectMacros( - documentationFrom.map((e) => e.documentationLocal).join('

')); - } - Library get definingLibrary { var library = packageGraph.findButDoNotCreateLibraryFor(element); if (library == null) { @@ -737,13 +636,11 @@ abstract class ModelElement extends Canonicalization return i.enclosingElement == i.canonicalEnclosingContainer; } - String _htmlDocumentation; - + /// Returns the docs, stripped of their leading comments syntax. @override - String get documentationAsHtml { - if (_htmlDocumentation != null) return _htmlDocumentation; - _htmlDocumentation = _injectHtmlFragments(_documentation.asHtml); - return _htmlDocumentation; + String get documentation { + return injectMacros( + documentationFrom.map((e) => e.documentationLocal).join('

')); } @override @@ -826,7 +723,7 @@ abstract class ModelElement extends Canonicalization @override bool get hasExtendedDocumentation => - href != null && _documentation.hasExtendedDocs; + href != null && elementDocumentation.hasExtendedDocs; bool get hasParameters => parameters.isNotEmpty; @@ -931,7 +828,7 @@ abstract class ModelElement extends Canonicalization String get name => _name ??= element.name; @override - String get oneLineDoc => _documentation.asOneLiner; + String get oneLineDoc => elementDocumentation.asOneLiner; Member get originalMember => _originalMember; @@ -1022,32 +919,18 @@ abstract class ModelElement extends Canonicalization } @override - String computeDocumentationComment() => element.documentationComment; + String /*!*/ get documentationComment => element.documentationComment ?? ''; - /// Unconditionally precache local documentation. - /// - /// Use only in factory for [PackageGraph]. - Future precacheLocalDocs() async { - _documentationLocal = await _buildDocumentationBase(); - } - - Documentation get _documentation { - if (__documentation != null) return __documentation; - __documentation = Documentation.forElement(this); - return __documentation; - } + @override + bool get hasDocumentationComment => element.documentationComment != null; String _sourceCode; - @override String get sourceCode { return _sourceCode ??= _sourceCodeRenderer.renderSourceCode(super.sourceCode); } - bool get _canOverride => - element is ClassMemberElement || element is PropertyAccessorElement; - @override int compareTo(dynamic other) { if (other is ModelElement) { @@ -1089,87 +972,4 @@ abstract class ModelElement extends Canonicalization return modelElementRenderer.renderLinkedName(this); } - - /// Replace <[digest]> in API comments with - /// the contents of the HTML fragment earlier defined by the - /// {@inject-html} directive. The [digest] is a SHA1 of the contents - /// of the HTML fragment, automatically generated upon parsing the - /// {@inject-html} directive. - /// - /// This markup is generated and inserted by [_stripHtmlAndAddToIndex] when it - /// removes the HTML fragment in preparation for markdown processing. It isn't - /// meant to be used at a user level. - /// - /// Example: - /// - /// You place the fragment in a dartdoc comment: - /// - /// Some comments - /// {@inject-html} - /// <p>[HTML contents!]</p> - /// {@endtemplate} - /// More comments - /// - /// and [_stripHtmlAndAddToIndex] will replace your HTML fragment with this: - /// - /// Some comments - /// <dartdoc-html>4cc02f877240bf69855b4c7291aba8a16e5acce0</dartdoc-html> - /// More comments - /// - /// Which will render in the final HTML output as: - /// - /// Some comments - /// <p>[HTML contents!]</p> - /// More comments - /// - /// And the HTML fragment will not have been processed or changed by Markdown, - /// but just injected verbatim. - String _injectHtmlFragments(String rawDocs) { - if (!config.injectHtml) return rawDocs; - - return rawDocs.replaceAllMapped(_htmlInjectRegExp, (match) { - var fragment = packageGraph.getHtmlFragment(match[1]); - if (fragment == null) { - warn(PackageWarning.unknownHtmlFragment, message: match[1]); - } - return fragment; - }); - } - - /// Replace {@macro ...} in API comments with the contents of the macro - /// - /// Syntax: - /// - /// {@macro NAME} - /// - /// Example: - /// - /// You define the template in any comment for a documentable entity like: - /// - /// {@template foo} - /// Foo contents! - /// {@endtemplate} - /// - /// and them somewhere use it like this: - /// - /// Some comments - /// {@macro foo} - /// More comments - /// - /// Which will render - /// - /// Some comments - /// Foo contents! - /// More comments - /// - String _injectMacros(String rawDocs) { - return rawDocs.replaceAllMapped(_macroRegExp, (match) { - var macro = packageGraph.getMacro(match[1]); - if (macro == null) { - warn(PackageWarning.unknownMacro, message: match[1]); - } - macro = processCommentDirectives(macro ?? ''); - return macro; - }); - } } diff --git a/lib/src/model/package.dart b/lib/src/model/package.dart index e0bb6e4a8d..c9652c5e36 100644 --- a/lib/src/model/package.dart +++ b/lib/src/model/package.dart @@ -17,10 +17,6 @@ import 'package:meta/meta.dart'; import 'package:path/path.dart' as path show Context; import 'package:pub_semver/pub_semver.dart'; -@Deprecated('Public variable intended to be private; will be removed as early ' - 'as Dartdoc 1.0.0') -RegExp get substituteNameVersion => Package._substituteNameVersion; - // All hrefs are emitted as relative paths from the output root. We are unable // to compute them from the page we are generating, and many properties computed // using hrefs are memoized anyway. To build complete relative hrefs, we emit @@ -33,11 +29,6 @@ RegExp get substituteNameVersion => Package._substituteNameVersion; @internal const String htmlBasePlaceholder = '\%\%__HTMLBASE_dartdoc_internal__\%\%'; -@Deprecated('Public variable intended to be private; will be removed as early ' - 'as Dartdoc 1.0.0') -// ignore: non_constant_identifier_names -const String HTMLBASE_PLACEHOLDER = htmlBasePlaceholder; - /// A [LibraryContainer] that contains [Library] objects related to a particular /// package. class Package extends LibraryContainer @@ -144,10 +135,6 @@ class Package extends LibraryContainer File /*?*/ _documentationFile; - @Deprecated( - 'Instead use [documentationFile] which will be `null` if this package does not have one.') - bool get hasDocumentationFile => documentationFile != null; - File /*?*/ get documentationFile => _documentationFile ??= packageMeta.getReadmeContents(); diff --git a/lib/src/model/package_graph.dart b/lib/src/model/package_graph.dart index 0e84852cc3..72f8b3878b 100644 --- a/lib/src/model/package_graph.dart +++ b/lib/src/model/package_graph.dart @@ -55,17 +55,6 @@ class PackageGraph with CommentReferable, Nameable { @override Element get element => null; - @Deprecated('Use with [PackageGraph.uninitialized] instead') - // ignore: non_constant_identifier_names - factory PackageGraph.UninitializedPackageGraph( - DartdocOptionContext config, - DartSdk sdk, - bool hasEmbedderSdk, - RendererFactory rendererFactory, - PackageMetaProvider packageMetaProvider) => - PackageGraph.uninitialized( - config, sdk, hasEmbedderSdk, rendererFactory, packageMetaProvider); - /// Call during initialization to add a library to this [PackageGraph]. /// /// Libraries added in this manner are assumed to be part of documented @@ -136,9 +125,8 @@ class PackageGraph with CommentReferable, Nameable { Iterable> precacheOneElement(ModelElement m) sync* { for (var d - in m.documentationFrom.where((d) => d.documentationComment != null)) { - if (needsPrecacheRegExp.hasMatch(d.documentationComment) && - !precachedElements.contains(d)) { + in m.documentationFrom.where((d) => d.hasDocumentationComment)) { + if (d.needsPrecache && !precachedElements.contains(d)) { precachedElements.add(d); yield d.precacheLocalDocs(); logProgress(d.name); diff --git a/lib/src/model/top_level_variable.dart b/lib/src/model/top_level_variable.dart index ea61044977..b250db3ee0 100644 --- a/lib/src/model/top_level_variable.dart +++ b/lib/src/model/top_level_variable.dart @@ -79,13 +79,6 @@ class TopLevelVariable extends ModelElement @override Set get features => {...super.features, ...comboFeatures}; - @override - String computeDocumentationComment() { - var docs = getterSetterDocumentationComment; - if (docs.isEmpty) return _variable.documentationComment; - return docs; - } - @override String get fileName => '${isConst ? '$name-constant' : name}.$fileType'; diff --git a/test/end2end/dartdoc_test.dart b/test/end2end/dartdoc_test.dart index 672b48f188..82b754430c 100644 --- a/test/end2end/dartdoc_test.dart +++ b/test/end2end/dartdoc_test.dart @@ -261,8 +261,6 @@ void main() { var packageGraph = results.packageGraph; var p = packageGraph.defaultPackage; expect(p.name, 'test_package'); - // ignore: deprecated_member_use_from_same_package - expect(p.hasDocumentationFile, isTrue); expect(p.documentationFile, isNotNull); // Total number of public libraries in test_package. // +2 since we are not manually excluding anything. @@ -309,8 +307,6 @@ void main() { var p = results.packageGraph; expect(p.defaultPackage.name, 'sky_engine'); - // ignore: deprecated_member_use_from_same_package - expect(p.defaultPackage.hasDocumentationFile, isFalse); expect(p.defaultPackage.documentationFile, isNull); expect(p.libraries, hasLength(3)); expect(p.libraries.map((lib) => lib.name).contains('dart:core'), isTrue); diff --git a/test/end2end/model_test.dart b/test/end2end/model_test.dart index d0bc7db3ad..29249114ee 100644 --- a/test/end2end/model_test.dart +++ b/test/end2end/model_test.dart @@ -632,7 +632,7 @@ void main() { () { // Verify setup of the test is correct. expect(invokeToolParentDoc.isCanonical, isTrue); - expect(invokeToolParentDoc.documentationComment, isNull); + expect(invokeToolParentDoc.hasDocumentationComment, isFalse); // Error message here might look strange due to toString() on Methods, but if this // fails that means we don't have the correct invokeToolParentDoc instance. expect(invokeToolParentDoc.documentationFrom, diff --git a/test/package_test.dart b/test/package_test.dart index 183e00bb35..754bab92d5 100644 --- a/test/package_test.dart +++ b/test/package_test.dart @@ -148,8 +148,6 @@ int x; writeToJoinedPath(['README.md'], 'Readme text.'); var packageGraph = await utils.bootBasicPackage( projectPath, packageMetaProvider, packageConfigProvider); - // ignore: deprecated_member_use_from_same_package - expect(packageGraph.defaultPackage.hasDocumentationFile, true); expect(packageGraph.defaultPackage.documentationFile, isNotNull); expect(packageGraph.defaultPackage.hasDocumentation, true); }); @@ -158,8 +156,6 @@ int x; writeToJoinedPath(['README'], 'Readme text.'); var packageGraph = await utils.bootBasicPackage( projectPath, packageMetaProvider, packageConfigProvider); - // ignore: deprecated_member_use_from_same_package - expect(packageGraph.defaultPackage.hasDocumentationFile, true); expect(packageGraph.defaultPackage.documentationFile, isNotNull); expect(packageGraph.defaultPackage.hasDocumentation, true); }); @@ -464,8 +460,6 @@ int x; projectPath, packageMetaProvider, packageConfigProvider); expect(packageGraph.defaultPackage.hasDocumentation, isFalse); - // ignore: deprecated_member_use_from_same_package - expect(packageGraph.defaultPackage.hasDocumentationFile, isFalse); expect(packageGraph.defaultPackage.documentationFile, isNull); expect(packageGraph.defaultPackage.documentation, isNull); });