Skip to content

Commit fd0b445

Browse files
committed
Add implementation and tests
1 parent bd548bb commit fd0b445

File tree

3 files changed

+49
-25
lines changed

3 files changed

+49
-25
lines changed

lib/src/html/html_generator_instance.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ class HtmlGeneratorInstance {
171171
}
172172
}
173173

174-
for (var extension in filterNonPublic(lib.extensions)) {
174+
for (var extension in filterNonDocumented(lib.extensions)) {
175175
generateExtension(_packageGraph, lib, extension);
176176

177177
for (var constant in filterNonDocumented(extension.constants)) {

lib/src/model.dart

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2415,8 +2415,6 @@ class Library extends ModelElement with Categorization, TopLevelContainer {
24152415
return _allOriginalModelElementNames;
24162416
}
24172417

2418-
List<Class> get allClasses => _allClasses;
2419-
24202418
@override
24212419
CharacterLocation get characterLocation {
24222420
if (element.nameOffset == -1) {
@@ -2430,19 +2428,30 @@ class Library extends ModelElement with Categorization, TopLevelContainer {
24302428
CompilationUnitElement get compilationUnitElement => (element as LibraryElement).definingCompilationUnit;
24312429

24322430
@override
2433-
Iterable<Class> get classes {
2434-
return _allClasses
2435-
.where((c) => !c.isErrorOrException)
2436-
.toList(growable: false);
2437-
}
2431+
Iterable<Class> get classes => allClasses.where((c) => !c.isErrorOrException);
24382432

24392433
@override
24402434
Iterable<Extension> get extensions {
2441-
if (_extensions != null) return _extensions;
2442-
_extensions = _libraryElement.definingCompilationUnit.extensions
2443-
.map((e) => ModelElement.from(e, this, packageGraph) as Extension)
2444-
.toList(growable: false)
2445-
..sort(byName);
2435+
if (_extensions == null) {
2436+
// De-dupe extensions coming from multiple exported libraries at once.
2437+
Set<ExtensionElement> extensionElements = Set();
2438+
extensionElements.addAll(_libraryElement.definingCompilationUnit.extensions);
2439+
for (CompilationUnitElement cu in _libraryElement.parts) {
2440+
extensionElements.addAll(cu.extensions);
2441+
}
2442+
for (LibraryElement le in _libraryElement.exportedLibraries) {
2443+
extensionElements.addAll(le.definingCompilationUnit.extensions
2444+
.where((t) => _exportedNamespace.definedNames.values.contains(t.name)));
2445+
}
2446+
2447+
extensionElements.addAll(_exportedNamespace.definedNames.values
2448+
.whereType<ExtensionElement>());
2449+
2450+
_extensions = extensionElements
2451+
.map((e) => ModelElement.from(e, this, packageGraph) as Extension)
2452+
.toList(growable: false)
2453+
..sort(byName);
2454+
}
24462455
return _extensions;
24472456
}
24482457

@@ -2628,10 +2637,10 @@ class Library extends ModelElement with Categorization, TopLevelContainer {
26282637

26292638
@override
26302639
List<Class> get exceptions {
2631-
return _allClasses
2632-
.where((c) => c.isErrorOrException)
2633-
.toList(growable: false)
2634-
..sort(byName);
2640+
if (_exceptions == null) {
2641+
_exceptions = allClasses.where((c) => c.isErrorOrException).toList(growable: false);
2642+
}
2643+
return _exceptions;
26352644
}
26362645

26372646
@override
@@ -2752,24 +2761,23 @@ class Library extends ModelElement with Categorization, TopLevelContainer {
27522761
return _typedefs;
27532762
}
27542763

2755-
List<Class> get _allClasses {
2764+
List<Class> get allClasses {
27562765
if (_classes != null) return _classes;
27572766

2767+
// De-dupe classes coming from multiple exported libraries at once.
27582768
Set<ClassElement> types = Set();
27592769
types.addAll(_libraryElement.definingCompilationUnit.types);
27602770
for (CompilationUnitElement cu in _libraryElement.parts) {
27612771
types.addAll(cu.types);
27622772
}
27632773
for (LibraryElement le in _libraryElement.exportedLibraries) {
27642774
types.addAll(le.definingCompilationUnit.types
2765-
.where((t) => _exportedNamespace.definedNames.values.contains(t.name))
2766-
.toList());
2775+
.where((t) => _exportedNamespace.definedNames.values.contains(t.name)));
27672776
}
27682777

27692778
types.addAll(_exportedNamespace.definedNames.values
2770-
.where((e) => e is ClassElement && !e.isMixin)
2771-
.cast<ClassElement>()
2772-
.where((element) => !element.isEnum));
2779+
.whereType<ClassElement>()
2780+
.where((e) => !e.isMixin && !e.isEnum));
27732781

27742782
_classes = types
27752783
.map((e) => ModelElement.from(e, this, packageGraph) as Class)
@@ -2783,7 +2791,7 @@ class Library extends ModelElement with Categorization, TopLevelContainer {
27832791
LibraryElement get _libraryElement => (element as LibraryElement);
27842792

27852793
Class getClassByName(String name) {
2786-
return _allClasses.firstWhere((it) => it.name == name, orElse: () => null);
2794+
return allClasses.firstWhere((it) => it.name == name, orElse: () => null);
27872795
}
27882796

27892797
List<TopLevelVariable> _getVariables() {
@@ -5026,7 +5034,7 @@ class PackageGraph {
50265034
documentedPackages.toList().forEach((package) {
50275035
package._libraries.sort((a, b) => compareNatural(a.name, b.name));
50285036
package._libraries.forEach((library) {
5029-
library._allClasses.forEach(_addToImplementors);
5037+
library.allClasses.forEach(_addToImplementors);
50305038
});
50315039
});
50325040
_implementors.values.forEach((l) => l.sort());

test/model_test.dart

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2114,11 +2114,20 @@ void main() {
21142114

21152115
group('Extension', () {
21162116
Extension ext, fancyList;
2117+
Extension documentOnceReexportOne, documentOnceReexportTwo;
2118+
Library reexportOneLib, reexportTwoLib;
21172119
Class extensionReferencer;
21182120
Method doSomeStuff, doStuff, s;
21192121
List<Extension> extensions;
21202122

21212123
setUpAll(() {
2124+
reexportOneLib = packageGraph.libraries
2125+
.firstWhere((lib) => lib.name == 'reexport_one');
2126+
reexportTwoLib = packageGraph.libraries
2127+
.firstWhere((lib) => lib.name == 'reexport_two');
2128+
documentOnceReexportOne = reexportOneLib.extensions.firstWhere((e) => e.name == 'DocumentThisExtensionOnce');
2129+
documentOnceReexportTwo = reexportTwoLib.extensions.firstWhere((e) => e.name == 'DocumentThisExtensionOnce');
2130+
21222131
ext = exLibrary.extensions.firstWhere((e) => e.name == 'AppleExtension');
21232132
extensionReferencer = exLibrary.classes.firstWhere((c) => c.name == 'ExtensionReferencer');
21242133
fancyList = exLibrary.extensions.firstWhere((e) => e.name == 'FancyList');
@@ -2129,6 +2138,12 @@ void main() {
21292138
extensions = exLibrary.publicExtensions.toList();
21302139
});
21312140

2141+
test('basic canonicalization for extensions', () {
2142+
expect(documentOnceReexportOne.isCanonical, isFalse);
2143+
expect(documentOnceReexportOne.href, equals(documentOnceReexportTwo.href));
2144+
expect(documentOnceReexportTwo.isCanonical, isTrue);
2145+
});
2146+
21322147
// TODO(jcollins-g): implement feature and update tests
21332148
test('documentation links do not crash in base cases', () {
21342149
packageGraph.packageWarningCounter.hasWarning(doStuff, PackageWarning.notImplemented,
@@ -2143,6 +2158,7 @@ void main() {
21432158
expect(extensionReferencer.documentationAsHtml, contains('<code>_Shhh</code>'));
21442159
expect(extensionReferencer.documentationAsHtml, contains('<a href="ex/FancyList.html">FancyList</a>'));
21452160
expect(extensionReferencer.documentationAsHtml, contains('<a href="ex/AnExtension/call.html">AnExtension.call</a>'));
2161+
expect(extensionReferencer.documentationAsHtml, contains('<a href="reexport_two/DocumentThisExtensionOnce.html">DocumentThisExtensionOnce</a>'));
21462162
});
21472163

21482164
test('has a fully qualified name', () {

0 commit comments

Comments
 (0)