From 5786c9708927d954cb2655db884dd7a0b45a4d9e Mon Sep 17 00:00:00 2001
From: Janice Collins
Date: Wed, 14 Oct 2020 09:10:17 -0700
Subject: [PATCH 1/5] First stage -- include all references that can be
canonicalized
---
lib/src/markdown_processor.dart | 5 ++---
lib/src/model/package_graph.dart | 2 +-
lib/src/model_utils.dart | 4 ++++
3 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/lib/src/markdown_processor.dart b/lib/src/markdown_processor.dart
index 12a66dec2c..faf9e9d102 100644
--- a/lib/src/markdown_processor.dart
+++ b/lib/src/markdown_processor.dart
@@ -785,9 +785,8 @@ class _MarkdownCommentReference {
}
// Add a result, but make it canonical.
- void _addCanonicalResult(ModelElement modelElement, Container tryClass) {
- results.add(packageGraph.findCanonicalModelElementFor(modelElement.element,
- preferredClass: tryClass));
+ void _addCanonicalResult(ModelElement modelElement, Container _) {
+ results.add(modelElement.canonicalModelElement);
}
/// _getResultsForClass assumes codeRefChomped might be a member of tryClass (inherited or not)
diff --git a/lib/src/model/package_graph.dart b/lib/src/model/package_graph.dart
index cca0940719..666641cba6 100644
--- a/lib/src/model/package_graph.dart
+++ b/lib/src/model/package_graph.dart
@@ -190,7 +190,7 @@ class PackageGraph {
assert(packageGraph.allLibrariesAdded);
_findRefElementCache = {};
for (final modelElement
- in utils.filterNonDocumented(packageGraph.allLocalModelElements)) {
+ in utils.filterHasCanonical(packageGraph.allModelElements)) {
_findRefElementCache.putIfAbsent(
modelElement.fullyQualifiedNameWithoutLibrary, () => {});
_findRefElementCache.putIfAbsent(
diff --git a/lib/src/model_utils.dart b/lib/src/model_utils.dart
index 77a143247a..2cbe6c99e3 100644
--- a/lib/src/model_utils.dart
+++ b/lib/src/model_utils.dart
@@ -73,6 +73,10 @@ AstNode getAstNode(
return null;
}
+Iterable filterHasCanonical(Iterable maybeHasCanonicalItems) {
+ return maybeHasCanonicalItems.where((me) => me.canonicalModelElement != null);
+}
+
/// Remove elements that aren't documented.
Iterable filterNonDocumented(
Iterable maybeDocumentedItems) {
From bd0c18893d4e602037a67c5b8f6ae9ec3709d91f Mon Sep 17 00:00:00 2001
From: Janice Collins
Date: Wed, 14 Oct 2020 11:08:41 -0700
Subject: [PATCH 2/5] Cleanups and hashmap conversion
---
lib/src/markdown_processor.dart | 27 ++++++++++-----------------
lib/src/model/class.dart | 3 +--
lib/src/model/library.dart | 27 ++++++++++++---------------
lib/src/model/model_element.dart | 6 ++----
lib/src/model/package_graph.dart | 17 +++++++----------
lib/src/package_config_provider.dart | 3 +--
lib/src/warnings.dart | 3 +--
7 files changed, 34 insertions(+), 52 deletions(-)
diff --git a/lib/src/markdown_processor.dart b/lib/src/markdown_processor.dart
index faf9e9d102..3123ec158c 100644
--- a/lib/src/markdown_processor.dart
+++ b/lib/src/markdown_processor.dart
@@ -648,7 +648,7 @@ class _MarkdownCommentReference {
prefixToLibrary[codeRefChompedParts.first]?.forEach((l) => l
.modelElementsNameMap[lookup]
?.map(_convertConstructors)
- ?.forEach((m) => _addCanonicalResult(m, _getPreferredClass(m))));
+ ?.forEach((m) => _addCanonicalResult(m)));
}
}
}
@@ -661,7 +661,7 @@ class _MarkdownCommentReference {
(modelElement is Library &&
codeRefChomped == modelElement.fullyQualifiedName)) {
_addCanonicalResult(
- _convertConstructors(modelElement), preferredClass);
+ _convertConstructors(modelElement));
}
}
}
@@ -671,7 +671,7 @@ class _MarkdownCommentReference {
// Only look for partially qualified matches if we didn't find a fully qualified one.
if (library.modelElementsNameMap.containsKey(codeRefChomped)) {
for (final modelElement in library.modelElementsNameMap[codeRefChomped]) {
- _addCanonicalResult(_convertConstructors(modelElement), preferredClass);
+ _addCanonicalResult(_convertConstructors(modelElement));
}
}
}
@@ -684,15 +684,8 @@ class _MarkdownCommentReference {
packageGraph.findRefElementCache.containsKey(codeRefChomped)) {
for (var modelElement
in packageGraph.findRefElementCache[codeRefChomped]) {
- // For fully qualified matches, the original preferredClass passed
- // might make no sense. Instead, use the enclosing class from the
- // element in [packageGraph.findRefElementCache], because that element's
- // enclosing class will be preferred from [codeRefChomped]'s perspective.
_addCanonicalResult(
- _convertConstructors(modelElement),
- modelElement.enclosingElement is Class
- ? modelElement.enclosingElement
- : null);
+ _convertConstructors(modelElement));
}
}
}
@@ -785,7 +778,7 @@ class _MarkdownCommentReference {
}
// Add a result, but make it canonical.
- void _addCanonicalResult(ModelElement modelElement, Container _) {
+ void _addCanonicalResult(ModelElement modelElement) {
results.add(modelElement.canonicalModelElement);
}
@@ -803,7 +796,7 @@ class _MarkdownCommentReference {
} else {
// People like to use 'this' in docrefs too.
if (codeRef == 'this') {
- _addCanonicalResult(tryClass, null);
+ _addCanonicalResult(tryClass);
} else {
// TODO(jcollins-g): get rid of reimplementation of identifier resolution
// or integrate into ModelElement in a simpler way.
@@ -815,7 +808,7 @@ class _MarkdownCommentReference {
// Fortunately superChains are short, but optimize this if it matters.
superChain.addAll(tryClass.superChain.map((t) => t.element));
for (final c in superChain) {
- _getResultsForSuperChainElement(c, tryClass);
+ _getResultsForSuperChainElement(c);
if (results.isNotEmpty) break;
}
}
@@ -824,12 +817,12 @@ class _MarkdownCommentReference {
/// Get any possible results for this class in the superChain. Returns
/// true if we found something.
- void _getResultsForSuperChainElement(Class c, Class tryClass) {
+ void _getResultsForSuperChainElement(Class c) {
var membersToCheck = (c.allModelElementsByNamePart[codeRefChomped] ?? [])
.map(_convertConstructors);
for (var modelElement in membersToCheck) {
// [thing], a member of this class
- _addCanonicalResult(modelElement, tryClass);
+ _addCanonicalResult(modelElement);
}
if (codeRefChompedParts.length < 2 ||
codeRefChompedParts[codeRefChompedParts.length - 2] == c.name) {
@@ -837,7 +830,7 @@ class _MarkdownCommentReference {
(c.allModelElementsByNamePart[codeRefChompedParts.last] ??
[])
.map(_convertConstructors);
- membersToCheck.forEach((m) => _addCanonicalResult(m, tryClass));
+ membersToCheck.forEach((m) => _addCanonicalResult(m));
}
results.remove(null);
if (results.isNotEmpty) return;
diff --git a/lib/src/model/class.dart b/lib/src/model/class.dart
index f320658dfb..1d6849b2e2 100644
--- a/lib/src/model/class.dart
+++ b/lib/src/model/class.dart
@@ -401,8 +401,7 @@ class Class extends Container
var accessorMap = >{};
for (var accessorElement in inheritedAccessorElements) {
var name = accessorElement.name.replaceFirst('=', '');
- accessorMap.putIfAbsent(name, () => []);
- accessorMap[name].add(accessorElement);
+ accessorMap.putIfAbsent(name, () => []).add(accessorElement);
}
// For half-inherited fields, the analyzer only links the non-inherited
diff --git a/lib/src/model/library.dart b/lib/src/model/library.dart
index 2b7a0c1640..f8a362e32b 100644
--- a/lib/src/model/library.dart
+++ b/lib/src/model/library.dart
@@ -2,6 +2,8 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'dart:collection';
+
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
@@ -283,8 +285,7 @@ class Library extends ModelElement with Categorization, TopLevelContainer {
for (var i in element.imports) {
// Ignore invalid imports.
if (i.prefix?.name != null && i.importedLibrary != null) {
- _prefixToLibrary.putIfAbsent(i.prefix?.name, () => {});
- _prefixToLibrary[i.prefix?.name]
+ _prefixToLibrary.putIfAbsent(i.prefix?.name, () => {})
.add(ModelElement.from(i.importedLibrary, library, packageGraph));
}
}
@@ -585,29 +586,27 @@ class Library extends ModelElement with Categorization, TopLevelContainer {
static String getLibraryName(LibraryElement element) =>
_getLibraryName(element);
- /*late final*/ Map> _modelElementsNameMap;
+ /*late final*/ HashMap> _modelElementsNameMap;
/// Map of [fullyQualifiedNameWithoutLibrary] to all matching [ModelElement]s
/// in this library. Used for code reference lookups.
- Map> get modelElementsNameMap {
+ HashMap> get modelElementsNameMap {
if (_modelElementsNameMap == null) {
- _modelElementsNameMap = >{};
+ _modelElementsNameMap = HashMap>();
allModelElements.forEach((ModelElement modelElement) {
// [definingLibrary] may be null if [element] has been imported or
// exported with a non-normalized URI, like "src//a.dart".
if (modelElement.definingLibrary == null) return;
_modelElementsNameMap.putIfAbsent(
- modelElement.fullyQualifiedNameWithoutLibrary, () => {});
- _modelElementsNameMap[modelElement.fullyQualifiedNameWithoutLibrary]
- .add(modelElement);
+ modelElement.fullyQualifiedNameWithoutLibrary, () => {}).add(modelElement);
});
}
return _modelElementsNameMap;
}
- /*late final*/ Map> _modelElementsMap;
+ /*late final*/ HashMap> _modelElementsMap;
- Map> get modelElementsMap {
+ HashMap> get modelElementsMap {
if (_modelElementsMap == null) {
var results = quiver.concat(>[
library.constants,
@@ -639,13 +638,11 @@ class Library extends ModelElement with Categorization, TopLevelContainer {
]);
}),
]);
- _modelElementsMap = >{};
+ _modelElementsMap = HashMap>();
results.forEach((modelElement) {
- _modelElementsMap.putIfAbsent(modelElement.element, () => {});
- _modelElementsMap[modelElement.element].add(modelElement);
+ _modelElementsMap.putIfAbsent(modelElement.element, () => {}).add(modelElement);
});
- _modelElementsMap.putIfAbsent(element, () => {});
- _modelElementsMap[element].add(this);
+ _modelElementsMap.putIfAbsent(element, () => {}).add(this);
}
return _modelElementsMap;
}
diff --git a/lib/src/model/model_element.dart b/lib/src/model/model_element.dart
index 6d54836906..e0af555cad 100644
--- a/lib/src/model/model_element.dart
+++ b/lib/src/model/model_element.dart
@@ -299,8 +299,7 @@ abstract class ModelElement extends Canonicalization
library.packageGraph.allConstructedModelElements[key] = newModelElement;
if (newModelElement is Inheritable) {
var iKey = Tuple2(e, library);
- library.packageGraph.allInheritableElements.putIfAbsent(iKey, () => {});
- library.packageGraph.allInheritableElements[iKey].add(newModelElement);
+ library.packageGraph.allInheritableElements.putIfAbsent(iKey, () => {}).add(newModelElement);
}
}
}
@@ -557,10 +556,9 @@ abstract class ModelElement extends Canonicalization
preferredClass: preferredClass);
}
+ ModelElement _canonicalModelElement;
// Returns the canonical ModelElement for this ModelElement, or null
// if there isn't one.
- ModelElement _canonicalModelElement;
-
ModelElement get canonicalModelElement =>
_canonicalModelElement ??= buildCanonicalModelElement();
diff --git a/lib/src/model/package_graph.dart b/lib/src/model/package_graph.dart
index 666641cba6..4e21f085c4 100644
--- a/lib/src/model/package_graph.dart
+++ b/lib/src/model/package_graph.dart
@@ -184,11 +184,11 @@ class PackageGraph {
return _extensions;
}
- Map> _findRefElementCache;
- Map> get findRefElementCache {
+ HashMap> _findRefElementCache;
+ HashMap> get findRefElementCache {
if (_findRefElementCache == null) {
assert(packageGraph.allLibrariesAdded);
- _findRefElementCache = {};
+ _findRefElementCache = HashMap>();
for (final modelElement
in utils.filterHasCanonical(packageGraph.allModelElements)) {
_findRefElementCache.putIfAbsent(
@@ -210,15 +210,13 @@ class PackageGraph {
PackageWarningCounter _packageWarningCounter;
/// All ModelElements constructed for this package; a superset of [allModelElements].
- final Map, ModelElement>
- allConstructedModelElements = {};
+ final allConstructedModelElements = HashMap, ModelElement>();
/// Anything that might be inheritable, place here for later lookup.
- final Map, Set>
- allInheritableElements = {};
+ final allInheritableElements = HashMap, Set>();
/// A mapping of the list of classes which implement each class.
- final Map> _implementors = LinkedHashMap(
+ final _implementors = LinkedHashMap>(
equals: (Class a, Class b) => a.definingClass == b.definingClass,
hashCode: (Class class_) => class_.definingClass.hashCode);
@@ -544,8 +542,7 @@ class PackageGraph {
referredFrom: [topLevelLibrary]);
return;
}
- _libraryElementReexportedBy.putIfAbsent(libraryElement, () => {});
- _libraryElementReexportedBy[libraryElement].add(topLevelLibrary);
+ _libraryElementReexportedBy.putIfAbsent(libraryElement, () => {}).add(topLevelLibrary);
for (var exportedElement in libraryElement.exports) {
_tagReexportsFor(
topLevelLibrary, exportedElement.exportedLibrary, exportedElement);
diff --git a/lib/src/package_config_provider.dart b/lib/src/package_config_provider.dart
index 3221aa4ea8..a2fe502ab5 100644
--- a/lib/src/package_config_provider.dart
+++ b/lib/src/package_config_provider.dart
@@ -27,8 +27,7 @@ class FakePackageConfigProvider implements PackageConfigProvider {
final _packageConfigData = >{};
void addPackageToConfigFor(String location, String name, Uri root) {
- _packageConfigData.putIfAbsent(location, () => []);
- _packageConfigData[location].add(package_config.Package(name, root));
+ _packageConfigData.putIfAbsent(location, () => []).add(package_config.Package(name, root));
}
@override
diff --git a/lib/src/warnings.dart b/lib/src/warnings.dart
index b8a57561c0..de96ee860c 100644
--- a/lib/src/warnings.dart
+++ b/lib/src/warnings.dart
@@ -482,8 +482,7 @@ class PackageWarningCounter {
errorCount += 1;
}
var warningData = Tuple2(kind, message);
- countedWarnings.putIfAbsent(element?.element, () => {});
- countedWarnings[element?.element].add(warningData);
+ countedWarnings.putIfAbsent(element?.element, () => {}).add(warningData);
_writeWarning(kind, warningMode, config.verboseWarnings,
element?.fullyQualifiedName, fullMessage);
}
From 0b13cf0b6cd30bb000c83760d7bde22d11e42365 Mon Sep 17 00:00:00 2001
From: Janice Collins
Date: Mon, 19 Oct 2020 10:51:31 -0700
Subject: [PATCH 3/5] prefer enclosing combos (filtering accessors)
---
lib/src/markdown_processor.dart | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/lib/src/markdown_processor.dart b/lib/src/markdown_processor.dart
index 3123ec158c..04a31d1d47 100644
--- a/lib/src/markdown_processor.dart
+++ b/lib/src/markdown_processor.dart
@@ -459,6 +459,10 @@ class _MarkdownCommentReference {
// conflicts are allowed, but an instance field is allowed to have the
// same name as a named constructor.
_reducePreferConstructorViaIndicators,
+ // Prefer Fields/TopLevelVariables to accessors.
+ // TODO(jcollins-g): Remove after fixing dart-lang/dartdoc#2396 or
+ // exclude Accessors from all lookup tables.
+ _reducePreferCombos,
// Prefer the Dart analyzer's resolution of comment references. We
// can't start from this because of the differences in Dartdoc
// canonicalization.
@@ -547,6 +551,14 @@ class _MarkdownCommentReference {
}
}
+ void _reducePreferCombos() {
+ var accessors = results.whereType().toList();
+ accessors.forEach((a) {
+ results.remove(a);
+ results.add(a.enclosingCombo);
+ });
+ }
+
void _findTypeParameters() {
if (element is TypeParameters) {
results.addAll((element as TypeParameters).typeParameters.where((p) =>
From abc179a0e871ac35fc2ea5e4f2f185d8d9779a83 Mon Sep 17 00:00:00 2001
From: Janice Collins
Date: Mon, 19 Oct 2020 10:54:03 -0700
Subject: [PATCH 4/5] dartfmt
---
lib/src/markdown_processor.dart | 6 ++----
lib/src/model/library.dart | 13 +++++++++----
lib/src/model/model_element.dart | 4 +++-
lib/src/model/package_graph.dart | 10 +++++++---
lib/src/model_utils.dart | 3 ++-
lib/src/package_config_provider.dart | 4 +++-
6 files changed, 26 insertions(+), 14 deletions(-)
diff --git a/lib/src/markdown_processor.dart b/lib/src/markdown_processor.dart
index 04a31d1d47..ca288d9fd3 100644
--- a/lib/src/markdown_processor.dart
+++ b/lib/src/markdown_processor.dart
@@ -672,8 +672,7 @@ class _MarkdownCommentReference {
if (codeRefChomped == modelElement.fullyQualifiedNameWithoutLibrary ||
(modelElement is Library &&
codeRefChomped == modelElement.fullyQualifiedName)) {
- _addCanonicalResult(
- _convertConstructors(modelElement));
+ _addCanonicalResult(_convertConstructors(modelElement));
}
}
}
@@ -696,8 +695,7 @@ class _MarkdownCommentReference {
packageGraph.findRefElementCache.containsKey(codeRefChomped)) {
for (var modelElement
in packageGraph.findRefElementCache[codeRefChomped]) {
- _addCanonicalResult(
- _convertConstructors(modelElement));
+ _addCanonicalResult(_convertConstructors(modelElement));
}
}
}
diff --git a/lib/src/model/library.dart b/lib/src/model/library.dart
index f8a362e32b..2a7b9622e7 100644
--- a/lib/src/model/library.dart
+++ b/lib/src/model/library.dart
@@ -285,7 +285,8 @@ class Library extends ModelElement with Categorization, TopLevelContainer {
for (var i in element.imports) {
// Ignore invalid imports.
if (i.prefix?.name != null && i.importedLibrary != null) {
- _prefixToLibrary.putIfAbsent(i.prefix?.name, () => {})
+ _prefixToLibrary
+ .putIfAbsent(i.prefix?.name, () => {})
.add(ModelElement.from(i.importedLibrary, library, packageGraph));
}
}
@@ -597,8 +598,10 @@ class Library extends ModelElement with Categorization, TopLevelContainer {
// [definingLibrary] may be null if [element] has been imported or
// exported with a non-normalized URI, like "src//a.dart".
if (modelElement.definingLibrary == null) return;
- _modelElementsNameMap.putIfAbsent(
- modelElement.fullyQualifiedNameWithoutLibrary, () => {}).add(modelElement);
+ _modelElementsNameMap
+ .putIfAbsent(
+ modelElement.fullyQualifiedNameWithoutLibrary, () => {})
+ .add(modelElement);
});
}
return _modelElementsNameMap;
@@ -640,7 +643,9 @@ class Library extends ModelElement with Categorization, TopLevelContainer {
]);
_modelElementsMap = HashMap>();
results.forEach((modelElement) {
- _modelElementsMap.putIfAbsent(modelElement.element, () => {}).add(modelElement);
+ _modelElementsMap
+ .putIfAbsent(modelElement.element, () => {})
+ .add(modelElement);
});
_modelElementsMap.putIfAbsent(element, () => {}).add(this);
}
diff --git a/lib/src/model/model_element.dart b/lib/src/model/model_element.dart
index e0af555cad..4164262a41 100644
--- a/lib/src/model/model_element.dart
+++ b/lib/src/model/model_element.dart
@@ -299,7 +299,9 @@ abstract class ModelElement extends Canonicalization
library.packageGraph.allConstructedModelElements[key] = newModelElement;
if (newModelElement is Inheritable) {
var iKey = Tuple2(e, library);
- library.packageGraph.allInheritableElements.putIfAbsent(iKey, () => {}).add(newModelElement);
+ library.packageGraph.allInheritableElements
+ .putIfAbsent(iKey, () => {})
+ .add(newModelElement);
}
}
}
diff --git a/lib/src/model/package_graph.dart b/lib/src/model/package_graph.dart
index 4e21f085c4..db169efd77 100644
--- a/lib/src/model/package_graph.dart
+++ b/lib/src/model/package_graph.dart
@@ -210,10 +210,12 @@ class PackageGraph {
PackageWarningCounter _packageWarningCounter;
/// All ModelElements constructed for this package; a superset of [allModelElements].
- final allConstructedModelElements = HashMap, ModelElement>();
+ final allConstructedModelElements =
+ HashMap, ModelElement>();
/// Anything that might be inheritable, place here for later lookup.
- final allInheritableElements = HashMap, Set>();
+ final allInheritableElements =
+ HashMap, Set>();
/// A mapping of the list of classes which implement each class.
final _implementors = LinkedHashMap>(
@@ -542,7 +544,9 @@ class PackageGraph {
referredFrom: [topLevelLibrary]);
return;
}
- _libraryElementReexportedBy.putIfAbsent(libraryElement, () => {}).add(topLevelLibrary);
+ _libraryElementReexportedBy
+ .putIfAbsent(libraryElement, () => {})
+ .add(topLevelLibrary);
for (var exportedElement in libraryElement.exports) {
_tagReexportsFor(
topLevelLibrary, exportedElement.exportedLibrary, exportedElement);
diff --git a/lib/src/model_utils.dart b/lib/src/model_utils.dart
index 2cbe6c99e3..3890d27107 100644
--- a/lib/src/model_utils.dart
+++ b/lib/src/model_utils.dart
@@ -73,7 +73,8 @@ AstNode getAstNode(
return null;
}
-Iterable filterHasCanonical(Iterable maybeHasCanonicalItems) {
+Iterable filterHasCanonical(
+ Iterable maybeHasCanonicalItems) {
return maybeHasCanonicalItems.where((me) => me.canonicalModelElement != null);
}
diff --git a/lib/src/package_config_provider.dart b/lib/src/package_config_provider.dart
index a2fe502ab5..845137e2f9 100644
--- a/lib/src/package_config_provider.dart
+++ b/lib/src/package_config_provider.dart
@@ -27,7 +27,9 @@ class FakePackageConfigProvider implements PackageConfigProvider {
final _packageConfigData = >{};
void addPackageToConfigFor(String location, String name, Uri root) {
- _packageConfigData.putIfAbsent(location, () => []).add(package_config.Package(name, root));
+ _packageConfigData
+ .putIfAbsent(location, () => [])
+ .add(package_config.Package(name, root));
}
@override
From 4dfd6b62e062506df828729120bed640d6a85bec Mon Sep 17 00:00:00 2001
From: Janice Collins
Date: Mon, 19 Oct 2020 10:56:40 -0700
Subject: [PATCH 5/5] add tests
---
test/end2end/model_test.dart | 19 +++++++++++++++++++
testing/test_package/lib/fake.dart | 5 +++++
testing/test_package/lib/src/somelib.dart | 9 ++++++++-
3 files changed, 32 insertions(+), 1 deletion(-)
diff --git a/test/end2end/model_test.dart b/test/end2end/model_test.dart
index 50bcf175a6..15f56129ba 100644
--- a/test/end2end/model_test.dart
+++ b/test/end2end/model_test.dart
@@ -15,6 +15,7 @@ import 'package:dartdoc/src/render/model_element_renderer.dart';
import 'package:dartdoc/src/render/parameter_renderer.dart';
import 'package:dartdoc/src/render/typedef_renderer.dart';
import 'package:dartdoc/src/special_elements.dart';
+import 'package:dartdoc/src/tuple.dart';
import 'package:dartdoc/src/warnings.dart';
import 'package:test/test.dart';
@@ -882,6 +883,24 @@ void main() {
docsAsHtml = doAwesomeStuff.documentationAsHtml;
});
+ test('Verify links to inherited members inside class', () {
+ expect(
+ docsAsHtml,
+ contains(
+ 'ClassWithUnusualProperties.forInheriting'));
+ expect(
+ docsAsHtml,
+ contains(
+ 'ExtendedBaseReexported.action
'));
+ var doAwesomeStuffWarnings = packageGraph.packageWarningCounter
+ .countedWarnings[doAwesomeStuff.element] ??
+ [];
+ expect(
+ doAwesomeStuffWarnings,
+ isNot(anyElement((Tuple2 e) =>
+ e.item1 == PackageWarning.ambiguousDocReference)));
+ });
+
test('can handle renamed imports', () {
var aFunctionUsingRenamedLib = fakeLibrary.functions
.firstWhere((f) => f.name == 'aFunctionUsingRenamedLib');
diff --git a/testing/test_package/lib/fake.dart b/testing/test_package/lib/fake.dart
index 7aace41f5b..6cccca19b0 100644
--- a/testing/test_package/lib/fake.dart
+++ b/testing/test_package/lib/fake.dart
@@ -858,6 +858,7 @@ class ExtraSpecialList extends SpecialList {}
/// {@subCategory Things and Such}
/// {@image https://flutter.io/images/catalog-widget-placeholder.png}
/// {@samples https://flutter.io}
+///
class BaseForDocComments {
/// Takes a [value] and returns a String.
///
@@ -899,6 +900,10 @@ class BaseForDocComments {
///
/// Reference to something that doesn't exist containing a type parameter [ThisIsNotHereNoWay]
///
+ /// Reference to an inherited member: [ClassWithUnusualProperties.forInheriting]
+ ///
+ /// Reference to an inherited member in another library via class name: [ExtendedBaseReexported.action]
+ ///
/// Link to a nonexistent file (erroneously expects base href): [link](SubForDocComments/localMethod.html)
///
/// Link to an existing file: [link](../SubForDocComments/localMethod.html)
diff --git a/testing/test_package/lib/src/somelib.dart b/testing/test_package/lib/src/somelib.dart
index 697ec1f2b6..921d4eef94 100644
--- a/testing/test_package/lib/src/somelib.dart
+++ b/testing/test_package/lib/src/somelib.dart
@@ -8,6 +8,13 @@ class YetAnotherClass {}
class AUnicornClass {}
+class BaseReexported {
+ String action;
+}
+
+class ExtendedBaseReexported extends BaseReexported {
+}
+
/// A private extension.
extension _Unseen on Object {
void doYouSeeMe() { }
@@ -21,4 +28,4 @@ extension on List {
/// [_Unseen] is not seen, but [DocumentMe] is.
extension DocumentThisExtensionOnce on String {
String get reportOnString => '$this is wonderful';
-}
\ No newline at end of file
+}