Skip to content

Commit 4691d4e

Browse files
committed
Dedupliate library elements
The main change that deduplicates library elements is splitting `Library.exportedAndLocalElements` into `Library._localElements` and `Library._exportedElements`, and then `Library._elementsOfType` into `Library._localElementsOfType` and `Library._exportedElementsOfType`. These two lists are separated so that the ModelElements can be instantiated or fetched from the package graph with the "correct" enclosing library. `_localElementsOfType` fetches elements via `getModelFor(e, this)`, and `exportedElementsOfType` fetches elements via `getModelFor(e, packageGraph.getModelForElement(library))`. Other changes to support this: * Use an element's `canonicalLibrary` instead of `library` in many places, like in each override of `filePath`, and in GeneratorFrontEnd. * There is no longer a distinction between an element's library and its _defining_ library. `ModelElement.definingLibrary` is removed. * Introduce a `canonicalizedQualifiedName` to use when creating `index.json`, which is the same as `fullyQualifiedName` but using the element's canonical library. * The global map of all elements was keyed on a 3-element key, which can now be a 2-element key (ConstructedModelElementsKey). * Remove an assert in Inheritable that no longer makes sense with this new model.
1 parent 0577ca1 commit 4691d4e

30 files changed

+333
-408
lines changed

lib/src/generator/generator_frontend.dart

Lines changed: 81 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -72,66 +72,66 @@ class GeneratorFrontEnd implements Generator {
7272
var indexAccumulator = <Indexable>[];
7373
var multiplePackages = packageGraph.localPackages.length > 1;
7474

75-
void generateConstants(Container container) {
75+
void generateConstants(Container container, Library library) {
7676
for (var constant in container.constantFields.whereDocumented) {
7777
if (!constant.isCanonical) continue;
7878
indexAccumulator.add(constant);
7979
_generatorBackend.generateProperty(
80-
packageGraph, container.library, container, constant);
80+
packageGraph, library, container, constant);
8181
}
8282
}
8383

84-
void generateConstructors(Constructable constructable) {
84+
void generateConstructors(Constructable constructable, Library library) {
8585
for (var constructor in constructable.constructors.whereDocumented) {
8686
if (!constructor.isCanonical) continue;
8787
indexAccumulator.add(constructor);
8888
_generatorBackend.generateConstructor(
89-
packageGraph, constructable.library, constructable, constructor);
89+
packageGraph, library, constructable, constructor);
9090
}
9191
}
9292

93-
void generateInstanceMethods(Container container) {
93+
void generateInstanceMethods(Container container, Library library) {
9494
for (var method in container.instanceMethods.whereDocumented) {
9595
if (!method.isCanonical) continue;
9696
indexAccumulator.add(method);
9797
_generatorBackend.generateMethod(
98-
packageGraph, container.library, container, method);
98+
packageGraph, library, container, method);
9999
}
100100
}
101101

102-
void generateInstanceOperators(Container container) {
102+
void generateInstanceOperators(Container container, Library library) {
103103
for (var operator in container.instanceOperators.whereDocumented) {
104104
if (!operator.isCanonical) continue;
105105
indexAccumulator.add(operator);
106106
_generatorBackend.generateMethod(
107-
packageGraph, container.library, container, operator);
107+
packageGraph, library, container, operator);
108108
}
109109
}
110110

111-
void generateInstanceProperties(Container container) {
111+
void generateInstanceProperties(Container container, Library library) {
112112
for (var property in container.instanceFields.whereDocumented) {
113113
if (!property.isCanonical) continue;
114114
indexAccumulator.add(property);
115115
_generatorBackend.generateProperty(
116-
packageGraph, container.library, container, property);
116+
packageGraph, library, container, property);
117117
}
118118
}
119119

120-
void generateStaticMethods(Container container) {
120+
void generateStaticMethods(Container container, Library library) {
121121
for (var method in container.staticMethods.whereDocumented) {
122122
if (!method.isCanonical) continue;
123123
indexAccumulator.add(method);
124124
_generatorBackend.generateMethod(
125-
packageGraph, container.library, container, method);
125+
packageGraph, library, container, method);
126126
}
127127
}
128128

129-
void generateStaticProperties(Container container) {
129+
void generateStaticProperties(Container container, Library library) {
130130
for (var property in container.variableStaticFields.whereDocumented) {
131131
if (!property.isCanonical) continue;
132132
indexAccumulator.add(property);
133133
_generatorBackend.generateProperty(
134-
packageGraph, container.library, container, property);
134+
packageGraph, library, container, property);
135135
}
136136
}
137137

@@ -157,88 +157,113 @@ class GeneratorFrontEnd implements Generator {
157157
indexAccumulator.add(lib);
158158
_generatorBackend.generateLibrary(packageGraph, lib);
159159

160-
for (var class_ in lib.classesAndExceptions.whereDocumented) {
160+
for (var class_ in lib.classesAndExceptions.whereDocumentedIn(lib)) {
161161
indexAccumulator.add(class_);
162162
_generatorBackend.generateClass(packageGraph, lib, class_);
163163

164-
generateConstants(class_);
165-
generateConstructors(class_);
166-
generateInstanceMethods(class_);
167-
generateInstanceOperators(class_);
168-
generateInstanceProperties(class_);
169-
generateStaticMethods(class_);
170-
generateStaticProperties(class_);
164+
var canonicalLibrary = class_.canonicalLibrary;
165+
if (canonicalLibrary == null) {
166+
throw StateError("Cannot generate docs for '$class_' (in "
167+
"'${class_.library}'), as it has no canonical library");
168+
}
169+
generateConstants(class_, canonicalLibrary);
170+
generateConstructors(class_, canonicalLibrary);
171+
generateInstanceMethods(class_, canonicalLibrary);
172+
generateInstanceOperators(class_, canonicalLibrary);
173+
generateInstanceProperties(class_, canonicalLibrary);
174+
generateStaticMethods(class_, canonicalLibrary);
175+
generateStaticProperties(class_, canonicalLibrary);
171176
}
172177

173-
for (var extension in lib.extensions.whereDocumented) {
178+
for (var extension in lib.extensions.whereDocumentedIn(lib)) {
174179
indexAccumulator.add(extension);
175180
_generatorBackend.generateExtension(packageGraph, lib, extension);
176181

177-
generateConstants(extension);
178-
generateInstanceMethods(extension);
179-
generateInstanceOperators(extension);
180-
generateInstanceProperties(extension);
181-
generateStaticMethods(extension);
182-
generateStaticProperties(extension);
182+
var canonicalLibrary = extension.canonicalLibrary;
183+
if (canonicalLibrary == null) {
184+
throw StateError("Cannot generate docs for '$extension' (in "
185+
"'${extension.library}'), as it has no canonical library");
186+
}
187+
generateConstants(extension, canonicalLibrary);
188+
generateInstanceMethods(extension, canonicalLibrary);
189+
generateInstanceOperators(extension, canonicalLibrary);
190+
generateInstanceProperties(extension, canonicalLibrary);
191+
generateStaticMethods(extension, canonicalLibrary);
192+
generateStaticProperties(extension, canonicalLibrary);
183193
}
184194

185-
for (var extensionType in lib.extensionTypes.whereDocumented) {
195+
for (var extensionType in lib.extensionTypes.whereDocumentedIn(lib)) {
186196
indexAccumulator.add(extensionType);
187197
_generatorBackend.generateExtensionType(
188198
packageGraph, lib, extensionType);
189199

190-
generateConstants(extensionType);
191-
generateConstructors(extensionType);
192-
generateInstanceMethods(extensionType);
193-
generateInstanceOperators(extensionType);
194-
generateInstanceProperties(extensionType);
195-
generateStaticMethods(extensionType);
196-
generateStaticProperties(extensionType);
200+
var canonicalLibrary = extensionType.canonicalLibrary;
201+
if (canonicalLibrary == null) {
202+
throw StateError("Cannot generate docs for '$extensionType' (in "
203+
"'${extensionType.library}'), as it has no canonical library");
204+
}
205+
generateConstants(extensionType, canonicalLibrary);
206+
generateConstructors(extensionType, canonicalLibrary);
207+
generateInstanceMethods(extensionType, canonicalLibrary);
208+
generateInstanceOperators(extensionType, canonicalLibrary);
209+
generateInstanceProperties(extensionType, canonicalLibrary);
210+
generateStaticMethods(extensionType, canonicalLibrary);
211+
generateStaticProperties(extensionType, canonicalLibrary);
197212
}
198213

199-
for (var mixin in lib.mixins.whereDocumented) {
214+
for (var mixin in lib.mixins.whereDocumentedIn(lib)) {
200215
indexAccumulator.add(mixin);
201216
_generatorBackend.generateMixin(packageGraph, lib, mixin);
202217

203-
generateConstants(mixin);
204-
generateInstanceMethods(mixin);
205-
generateInstanceOperators(mixin);
206-
generateInstanceProperties(mixin);
207-
generateStaticMethods(mixin);
208-
generateStaticProperties(mixin);
218+
var canonicalLibrary = mixin.canonicalLibrary;
219+
if (canonicalLibrary == null) {
220+
throw StateError("Cannot generate docs for '$mixin' (in "
221+
"'${mixin.library}'), as it has no canonical library");
222+
}
223+
generateConstants(mixin, canonicalLibrary);
224+
generateInstanceMethods(mixin, canonicalLibrary);
225+
generateInstanceOperators(mixin, canonicalLibrary);
226+
generateInstanceProperties(mixin, canonicalLibrary);
227+
generateStaticMethods(mixin, canonicalLibrary);
228+
generateStaticProperties(mixin, canonicalLibrary);
209229
}
210230

211-
for (var enum_ in lib.enums.whereDocumented) {
231+
for (var enum_ in lib.enums.whereDocumentedIn(lib)) {
212232
indexAccumulator.add(enum_);
213233
_generatorBackend.generateEnum(packageGraph, lib, enum_);
214234

215-
generateConstants(enum_);
216-
generateConstructors(enum_);
217-
generateInstanceMethods(enum_);
218-
generateInstanceOperators(enum_);
219-
generateInstanceProperties(enum_);
220-
generateStaticMethods(enum_);
221-
generateStaticProperties(enum_);
235+
var canonicalLibrary = enum_.canonicalLibrary;
236+
if (canonicalLibrary == null) {
237+
throw StateError("Cannot generate docs for '$enum_' (in "
238+
"'${enum_.library}'), as it has no canonical library");
239+
}
240+
generateConstants(enum_, canonicalLibrary);
241+
generateConstructors(enum_, canonicalLibrary);
242+
generateInstanceMethods(enum_, canonicalLibrary);
243+
generateInstanceOperators(enum_, canonicalLibrary);
244+
generateInstanceProperties(enum_, canonicalLibrary);
245+
generateStaticMethods(enum_, canonicalLibrary);
246+
generateStaticProperties(enum_, canonicalLibrary);
222247
}
223248

224-
for (var constant in lib.constants.whereDocumented) {
249+
for (var constant in lib.constants.whereDocumentedIn(lib)) {
225250
indexAccumulator.add(constant);
226251
_generatorBackend.generateTopLevelProperty(
227252
packageGraph, lib, constant);
228253
}
229254

230-
for (var property in lib.properties.whereDocumented) {
255+
for (var property in lib.properties.whereDocumentedIn(lib)) {
231256
indexAccumulator.add(property);
232257
_generatorBackend.generateTopLevelProperty(
233258
packageGraph, lib, property);
234259
}
235260

236-
for (var function in lib.functions.whereDocumented) {
261+
for (var function in lib.functions.whereDocumentedIn(lib)) {
237262
indexAccumulator.add(function);
238263
_generatorBackend.generateFunction(packageGraph, lib, function);
239264
}
240265

241-
for (var typeDef in lib.typedefs.whereDocumented) {
266+
for (var typeDef in lib.typedefs.whereDocumentedIn(lib)) {
242267
indexAccumulator.add(typeDef);
243268
_generatorBackend.generateTypeDef(packageGraph, lib, typeDef);
244269
}

lib/src/generator/generator_utils.dart

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import 'dart:convert';
77
import 'package:collection/collection.dart';
88
import 'package:dartdoc/src/model/directives/categorization.dart';
99
import 'package:dartdoc/src/model/indexable.dart';
10+
import 'package:dartdoc/src/model/library.dart';
1011
import 'package:dartdoc/src/model/model_element.dart';
1112

1213
String generateCategoryJson(Iterable<Categorization> categories, bool pretty) {
@@ -15,7 +16,7 @@ String generateCategoryJson(Iterable<Categorization> categories, bool pretty) {
1516
in categories.sorted(_compareElementRepresentations))
1617
<String, Object?>{
1718
'name': categorization.name,
18-
'qualifiedName': categorization.fullyQualifiedName,
19+
'qualifiedName': categorization.canonicalQualifiedName,
1920
'href': categorization.href,
2021
// TODO(srawlins): Rename to 'kind'.
2122
'type': categorization.kind.toString(),
@@ -42,7 +43,7 @@ String generateSearchIndexJson(Iterable<Indexable> indexedElements,
4243
for (final item in indexedElements.sorted(_compareElementRepresentations))
4344
{
4445
'name': item.name,
45-
'qualifiedName': item.fullyQualifiedName,
46+
'qualifiedName': item.canonicalQualifiedName,
4647
'href': item.href,
4748
'kind': item.kind.index,
4849
// TODO(srawlins): Only include this for [Inheritable] items.
@@ -112,9 +113,24 @@ final _htmlTagPattern =
112113

113114
// Compares two elements, first by fully qualified name, then by kind.
114115
int _compareElementRepresentations(Indexable a, Indexable b) {
115-
final value = compareNatural(a.fullyQualifiedName, b.fullyQualifiedName);
116+
final value =
117+
compareNatural(a.canonicalQualifiedName, b.canonicalQualifiedName);
116118
if (value == 0) {
117119
return compareNatural(a.kind.toString(), b.kind.toString());
118120
}
119121
return value;
120122
}
123+
124+
extension on Indexable {
125+
/// The fully qualified name of this element, but using the canonical library,
126+
/// if it has one.
127+
String get canonicalQualifiedName {
128+
var self = this;
129+
if (self is Library) return name;
130+
if (self is ModelElement) {
131+
var library = self.canonicalLibrary ?? self.library;
132+
return '${library.name}.${self.qualifiedName}';
133+
}
134+
return name;
135+
}
136+
}

0 commit comments

Comments
 (0)