Skip to content

Commit 215ca55

Browse files
authored
Implement new-style mixin support for Dart 2.1 (#1765)
* Implement new-style mixin support * Regenerate package documentation, dropping stable * Fix problem where we created Fields without accessors * Use published analyzer in override * Disable try_publish and make grind more tolerant of preexisting overrides to make travis green * Review comments * dartfmt
1 parent 7970b38 commit 215ca55

File tree

450 files changed

+13011
-152
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

450 files changed

+13011
-152
lines changed

.travis.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ os:
1515
- osx
1616
- linux
1717

18-
1918
install:
2019
- ./tool/install_travis.sh
2120

lib/src/dartdoc_options.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,9 @@ abstract class DartdocOption<T> {
376376
} else if (valueWithContext.value is Map<String, String>) {
377377
resolvedPaths = valueWithContext.resolvedValue.values.toList();
378378
} else {
379-
assert(false, "Trying to ensure existence of unsupported type "
379+
assert(
380+
false,
381+
"Trying to ensure existence of unsupported type "
380382
"${valueWithContext.value.runtimeType}");
381383
}
382384
for (String path in resolvedPaths) {

lib/src/html/html_generator_instance.dart

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,44 @@ class HtmlGeneratorInstance {
169169
}
170170
}
171171

172+
for (var mixin in filterNonDocumented(lib.mixins)) {
173+
generateMixins(_packageGraph, lib, mixin);
174+
for (var constructor in filterNonDocumented(mixin.constructors)) {
175+
if (!constructor.isCanonical) continue;
176+
generateConstructor(_packageGraph, lib, mixin, constructor);
177+
}
178+
179+
for (var constant in filterNonDocumented(mixin.constants)) {
180+
if (!constant.isCanonical) continue;
181+
generateConstant(_packageGraph, lib, mixin, constant);
182+
}
183+
184+
for (var property in filterNonDocumented(mixin.staticProperties)) {
185+
if (!property.isCanonical) continue;
186+
generateProperty(_packageGraph, lib, mixin, property);
187+
}
188+
189+
for (var property in filterNonDocumented(mixin.propertiesForPages)) {
190+
if (!property.isCanonical) continue;
191+
generateProperty(_packageGraph, lib, mixin, property);
192+
}
193+
194+
for (var method in filterNonDocumented(mixin.methodsForPages)) {
195+
if (!method.isCanonical) continue;
196+
generateMethod(_packageGraph, lib, mixin, method);
197+
}
198+
199+
for (var operator in filterNonDocumented(mixin.operatorsForPages)) {
200+
if (!operator.isCanonical) continue;
201+
generateMethod(_packageGraph, lib, mixin, operator);
202+
}
203+
204+
for (var method in filterNonDocumented(mixin.staticMethods)) {
205+
if (!method.isCanonical) continue;
206+
generateMethod(_packageGraph, lib, mixin, method);
207+
}
208+
}
209+
172210
for (var eNum in filterNonDocumented(lib.enums)) {
173211
generateEnum(_packageGraph, lib, eNum);
174212
for (var property in filterNonDocumented(eNum.propertiesForPages)) {
@@ -239,6 +277,13 @@ class HtmlGeneratorInstance {
239277
pathLib.joinAll(clazz.href.split('/')), _templates.classTemplate, data);
240278
}
241279

280+
void generateMixins(PackageGraph packageGraph, Library lib, Mixin mixin) {
281+
TemplateData data =
282+
new MixinTemplateData(_options, packageGraph, lib, mixin);
283+
_build(
284+
pathLib.joinAll(mixin.href.split('/')), _templates.mixinTemplate, data);
285+
}
286+
242287
void generateConstructor(PackageGraph packageGraph, Library lib, Class clazz,
243288
Constructor constructor) {
244289
TemplateData data = new ConstructorTemplateData(

lib/src/html/template_data.dart

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,20 @@ class LibraryTemplateData extends TemplateData<Library> {
209209
Library get self => library;
210210
}
211211

212-
class ClassTemplateData extends TemplateData<Class> {
212+
/// Template data for Dart 2.1-style mixin declarations.
213+
class MixinTemplateData extends ClassTemplateData<Mixin> {
214+
final Mixin mixin;
215+
216+
MixinTemplateData(HtmlOptions htmlOptions, PackageGraph packageGraph,
217+
Library library, this.mixin)
218+
: super(htmlOptions, packageGraph, library, mixin);
219+
220+
@override
221+
Mixin get self => mixin;
222+
}
223+
224+
/// Base template data class for [Class], [Enum], and [Mixin].
225+
class ClassTemplateData<T extends Class> extends TemplateData<T> {
213226
final Class clazz;
214227
final Library library;
215228
Class _objectType;
@@ -219,7 +232,7 @@ class ClassTemplateData extends TemplateData<Class> {
219232
: super(htmlOptions, packageGraph);
220233

221234
@override
222-
Class get self => clazz;
235+
T get self => clazz;
223236
String get linkedObjectType =>
224237
objectType == null ? 'Object' : objectType.linkedName;
225238
@override
@@ -303,28 +316,15 @@ class ConstructorTemplateData extends TemplateData<Constructor> {
303316
'for the Dart programming language.';
304317
}
305318

306-
class EnumTemplateData extends TemplateData<Enum> {
319+
class EnumTemplateData extends ClassTemplateData<Enum> {
307320
EnumTemplateData(HtmlOptions htmlOptions, PackageGraph packageGraph,
308-
this.library, this.eNum)
309-
: super(htmlOptions, packageGraph);
321+
Library library, Enum eNum)
322+
: super(htmlOptions, packageGraph, library, eNum);
310323

311-
final Library library;
312-
final Enum eNum;
324+
Enum get eNum => clazz;
313325
@override
314326
Enum get self => eNum;
315327
@override
316-
String get layoutTitle => _layoutTitle(eNum.name, 'enum', eNum.isDeprecated);
317-
@override
318-
String get title => '${self.name} enum - ${library.name} library - Dart API';
319-
@override
320-
String get metaDescription =>
321-
'API docs for the ${eNum.name} enum from the ${library.name} library, '
322-
'for the Dart programming language.';
323-
@override
324-
List get navLinks => [packageGraph.defaultPackage, library];
325-
@override
326-
String get htmlBase => '..';
327-
@override
328328
Iterable<Subnav> getSubNavItems() => [
329329
new Subnav('Constants', '${eNum.href}#constants'),
330330
new Subnav('Properties', '${eNum.href}#instance-properties'),

lib/src/html/templates.dart

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ const _partials = const <String>[
1919
'footer',
2020
'head',
2121
'library',
22+
'mixin',
2223
'packages',
2324
'property',
2425
'features',
@@ -91,6 +92,7 @@ class Templates {
9192
final TemplateRenderer indexTemplate;
9293
final TemplateRenderer libraryTemplate;
9394
final TemplateRenderer methodTemplate;
95+
final TemplateRenderer mixinTemplate;
9496
final TemplateRenderer propertyTemplate;
9597
final TemplateRenderer topLevelConstantTemplate;
9698
final TemplateRenderer topLevelPropertyTemplate;
@@ -132,6 +134,7 @@ class Templates {
132134
var topLevelPropertyTemplate =
133135
await _loadTemplate('top_level_property.html');
134136
var typeDefTemplate = await _loadTemplate('typedef.html');
137+
var mixinTemplate = await _loadTemplate('mixin.html');
135138

136139
return new Templates._(
137140
indexTemplate,
@@ -147,7 +150,8 @@ class Templates {
147150
constantTemplate,
148151
topLevelConstantTemplate,
149152
topLevelPropertyTemplate,
150-
typeDefTemplate);
153+
typeDefTemplate,
154+
mixinTemplate);
151155
}
152156

153157
Templates._(
@@ -164,5 +168,6 @@ class Templates {
164168
this.constantTemplate,
165169
this.topLevelConstantTemplate,
166170
this.topLevelPropertyTemplate,
167-
this.typeDefTemplate);
171+
this.typeDefTemplate,
172+
this.mixinTemplate);
168173
}

lib/src/markdown_processor.dart

Lines changed: 21 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -185,66 +185,9 @@ ModelElement _getPreferredClass(ModelElement modelElement) {
185185
return null;
186186
}
187187

188-
// TODO: this is in the wrong place
189-
NodeList<CommentReference> _getCommentRefs(Documentable documentable) {
190-
// Documentable items that aren't related to analyzer elements have no
191-
// CommentReference list.
192-
if (documentable is! ModelElement) return null;
193-
ModelElement modelElement = documentable;
194-
195-
if (modelElement.element.documentationComment == null &&
196-
modelElement.canOverride()) {
197-
var node = modelElement.overriddenElement?.element?.computeNode();
198-
if (node is AnnotatedNode) {
199-
if (node.documentationComment != null) {
200-
return node.documentationComment.references;
201-
}
202-
}
203-
}
204-
205-
if (modelElement.element.computeNode() is AnnotatedNode) {
206-
final AnnotatedNode annotatedNode = modelElement.element.computeNode();
207-
if (annotatedNode.documentationComment != null) {
208-
return annotatedNode.documentationComment.references;
209-
}
210-
} else if (modelElement.element is LibraryElement) {
211-
// handle anonymous libraries
212-
if (modelElement.element.computeNode() == null ||
213-
modelElement.element.computeNode().parent == null) {
214-
return null;
215-
}
216-
var node = modelElement.element.computeNode().parent.parent;
217-
if (node is AnnotatedNode) {
218-
if (node.documentationComment != null) {
219-
return node.documentationComment.references;
220-
}
221-
}
222-
}
223-
224-
// Our references might come from somewhere up in the inheritance chain.
225-
// TODO(jcollins-g): rationalize this and all other places where docs are
226-
// inherited to be consistent.
227-
if (modelElement.element is ClassMemberElement) {
228-
var node = modelElement.element
229-
.getAncestor((e) => e is ClassElement)
230-
.computeNode();
231-
if (node is AnnotatedNode) {
232-
if (node.documentationComment != null) {
233-
return node.documentationComment.references;
234-
}
235-
}
236-
}
237-
return null;
238-
}
239-
240188
/// Returns null if element is a parameter.
241189
MatchingLinkResult _getMatchingLinkElement(
242190
String codeRef, Warnable element, List<CommentReference> commentRefs) {
243-
// By debugging inspection, it seems correct to not warn when we don't have
244-
// CommentReferences; there's actually nothing that needs resolving in
245-
// that case.
246-
if (commentRefs == null) return new MatchingLinkResult(null, warn: false);
247-
248191
if (!codeRef.contains(isConstructor) &&
249192
codeRef.contains(notARealDocReference)) {
250193
// Don't waste our time on things we won't ever find.
@@ -254,7 +197,7 @@ MatchingLinkResult _getMatchingLinkElement(
254197
ModelElement refModelElement;
255198

256199
// Try expensive not-scoped lookup.
257-
if (refModelElement == null) {
200+
if (refModelElement == null && element is ModelElement) {
258201
Class preferredClass = _getPreferredClass(element);
259202
refModelElement =
260203
_findRefElementInLibrary(codeRef, element, commentRefs, preferredClass);
@@ -318,22 +261,25 @@ MatchingLinkResult _getMatchingLinkElement(
318261
/// Given a set of commentRefs, return the one whose name matches the codeRef.
319262
Element _getRefElementFromCommentRefs(
320263
List<CommentReference> commentRefs, String codeRef) {
321-
for (CommentReference ref in commentRefs) {
322-
if (ref.identifier.name == codeRef) {
323-
bool isConstrElement = ref.identifier.staticElement is ConstructorElement;
324-
// Constructors are now handled by library search.
325-
if (!isConstrElement) {
326-
Element refElement = ref.identifier.staticElement;
327-
if (refElement is PropertyAccessorElement) {
328-
// yay we found an accessor that wraps a const, but we really
329-
// want the top-level field itself
330-
refElement = (refElement as PropertyAccessorElement).variable;
331-
}
332-
if (refElement is PrefixElement) {
333-
// We found a prefix element, but what we really want is the library element.
334-
refElement = (refElement as PrefixElement).enclosingElement;
264+
if (commentRefs != null) {
265+
for (CommentReference ref in commentRefs) {
266+
if (ref.identifier.name == codeRef) {
267+
bool isConstrElement =
268+
ref.identifier.staticElement is ConstructorElement;
269+
// Constructors are now handled by library search.
270+
if (!isConstrElement) {
271+
Element refElement = ref.identifier.staticElement;
272+
if (refElement is PropertyAccessorElement) {
273+
// yay we found an accessor that wraps a const, but we really
274+
// want the top-level field itself
275+
refElement = (refElement as PropertyAccessorElement).variable;
276+
}
277+
if (refElement is PrefixElement) {
278+
// We found a prefix element, but what we really want is the library element.
279+
refElement = (refElement as PrefixElement).enclosingElement;
280+
}
281+
return refElement;
335282
}
336-
return refElement;
337283
}
338284
}
339285
}
@@ -719,7 +665,7 @@ void _getResultsForClass(Class tryClass, String codeRefChomped,
719665
}
720666

721667
String _linkDocReference(
722-
String codeRef, Warnable warnable, NodeList<CommentReference> commentRefs) {
668+
String codeRef, Warnable warnable, List<CommentReference> commentRefs) {
723669
MatchingLinkResult result;
724670
result = _getMatchingLinkElement(codeRef, warnable, commentRefs);
725671
final ModelElement linkedElement = result.element;
@@ -942,11 +888,7 @@ class Documentation {
942888
return _asOneLiner;
943889
}
944890

945-
NodeList<CommentReference> _commentRefs;
946-
NodeList<CommentReference> get commentRefs {
947-
if (_commentRefs == null) _commentRefs = _getCommentRefs(_element);
948-
return _commentRefs;
949-
}
891+
List<CommentReference> get commentRefs => _element.commentRefs;
950892

951893
void _renderHtmlForDartdoc(bool processAllDocs) {
952894
Tuple3<String, String, bool> renderResults =

0 commit comments

Comments
 (0)