diff --git a/lib/src/html/html_generator_instance.dart b/lib/src/html/html_generator_instance.dart index cbbfdb463b..2d6658ec04 100644 --- a/lib/src/html/html_generator_instance.dart +++ b/lib/src/html/html_generator_instance.dart @@ -89,76 +89,78 @@ class HtmlGeneratorInstance { generatePackage(); - for (var lib in filterNonDocumented(_packageGraph.libraries)) { - generateLibrary(_packageGraph, lib); - - for (var clazz in filterNonDocumented(lib.allClasses)) { - generateClass(_packageGraph, lib, clazz); - - for (var constructor in filterNonDocumented(clazz.constructors)) { - if (!constructor.isCanonical) continue; - generateConstructor(_packageGraph, lib, clazz, constructor); + for (var package in _packageGraph.localPackages) { + for (var lib in filterNonDocumented(package.libraries)) { + generateLibrary(_packageGraph, lib); + + for (var clazz in filterNonDocumented(lib.allClasses)) { + generateClass(_packageGraph, lib, clazz); + + for (var constructor in filterNonDocumented(clazz.constructors)) { + if (!constructor.isCanonical) continue; + generateConstructor(_packageGraph, lib, clazz, constructor); + } + + for (var constant in filterNonDocumented(clazz.constants)) { + if (!constant.isCanonical) continue; + generateConstant(_packageGraph, lib, clazz, constant); + } + + for (var property in filterNonDocumented(clazz.staticProperties)) { + if (!property.isCanonical) continue; + generateProperty(_packageGraph, lib, clazz, property); + } + + for (var property in filterNonDocumented(clazz.propertiesForPages)) { + if (!property.isCanonical) continue; + generateProperty(_packageGraph, lib, clazz, property); + } + + for (var method in filterNonDocumented(clazz.methodsForPages)) { + if (!method.isCanonical) continue; + generateMethod(_packageGraph, lib, clazz, method); + } + + for (var operator in filterNonDocumented(clazz.operatorsForPages)) { + if (!operator.isCanonical) continue; + generateMethod(_packageGraph, lib, clazz, operator); + } + + for (var method in filterNonDocumented(clazz.staticMethods)) { + if (!method.isCanonical) continue; + generateMethod(_packageGraph, lib, clazz, method); + } } - for (var constant in filterNonDocumented(clazz.constants)) { - if (!constant.isCanonical) continue; - generateConstant(_packageGraph, lib, clazz, constant); + for (var eNum in filterNonDocumented(lib.enums)) { + generateEnum(_packageGraph, lib, eNum); + for (var property in filterNonDocumented(eNum.propertiesForPages)) { + generateProperty(_packageGraph, lib, eNum, property); + } + for (var operator in filterNonDocumented(eNum.operatorsForPages)) { + generateMethod(_packageGraph, lib, eNum, operator); + } + for (var method in filterNonDocumented(eNum.methodsForPages)) { + generateMethod(_packageGraph, lib, eNum, method); + } } - for (var property in filterNonDocumented(clazz.staticProperties)) { - if (!property.isCanonical) continue; - generateProperty(_packageGraph, lib, clazz, property); + for (var constant in filterNonDocumented(lib.constants)) { + generateTopLevelConstant(_packageGraph, lib, constant); } - for (var property in filterNonDocumented(clazz.propertiesForPages)) { - if (!property.isCanonical) continue; - generateProperty(_packageGraph, lib, clazz, property); + for (var property in filterNonDocumented(lib.properties)) { + generateTopLevelProperty(_packageGraph, lib, property); } - for (var method in filterNonDocumented(clazz.methodsForPages)) { - if (!method.isCanonical) continue; - generateMethod(_packageGraph, lib, clazz, method); + for (var function in filterNonDocumented(lib.functions)) { + generateFunction(_packageGraph, lib, function); } - for (var operator in filterNonDocumented(clazz.operatorsForPages)) { - if (!operator.isCanonical) continue; - generateMethod(_packageGraph, lib, clazz, operator); - } - - for (var method in filterNonDocumented(clazz.staticMethods)) { - if (!method.isCanonical) continue; - generateMethod(_packageGraph, lib, clazz, method); - } - } - - for (var eNum in filterNonDocumented(lib.enums)) { - generateEnum(_packageGraph, lib, eNum); - for (var property in filterNonDocumented(eNum.propertiesForPages)) { - generateProperty(_packageGraph, lib, eNum, property); - } - for (var operator in filterNonDocumented(eNum.operatorsForPages)) { - generateMethod(_packageGraph, lib, eNum, operator); - } - for (var method in filterNonDocumented(eNum.methodsForPages)) { - generateMethod(_packageGraph, lib, eNum, method); + for (var typeDef in filterNonDocumented(lib.typedefs)) { + generateTypeDef(_packageGraph, lib, typeDef); } } - - for (var constant in filterNonDocumented(lib.constants)) { - generateTopLevelConstant(_packageGraph, lib, constant); - } - - for (var property in filterNonDocumented(lib.properties)) { - generateTopLevelProperty(_packageGraph, lib, property); - } - - for (var function in filterNonDocumented(lib.functions)) { - generateFunction(_packageGraph, lib, function); - } - - for (var typeDef in filterNonDocumented(lib.typedefs)) { - generateTypeDef(_packageGraph, lib, typeDef); - } } } diff --git a/lib/src/html/template_data.dart b/lib/src/html/template_data.dart index 02134f00dd..bdc7ae0f1f 100644 --- a/lib/src/html/template_data.dart +++ b/lib/src/html/template_data.dart @@ -74,8 +74,7 @@ abstract class TemplateData { } Iterable _gatherSubnavForInvokable(ModelElement element) { - if (element is SourceCodeMixin && - (element as SourceCodeMixin).hasSourceCode) { + if (element.hasSourceCode) { return [new Subnav('Source', '${element.href}#source')]; } else { return []; diff --git a/lib/src/markdown_processor.dart b/lib/src/markdown_processor.dart index 12dda17563..e97ce2a183 100644 --- a/lib/src/markdown_processor.dart +++ b/lib/src/markdown_processor.dart @@ -475,7 +475,7 @@ ModelElement _findRefElementInLibrary(String codeRef, Warnable element, assert(packageGraph.allLibrariesAdded); _findRefElementCache = new Map(); for (final modelElement - in filterNonDocumented(packageGraph.allModelElements)) { + in filterNonDocumented(packageGraph.allLocalModelElements)) { _findRefElementCache.putIfAbsent( modelElement.fullyQualifiedNameWithoutLibrary, () => new Set()); _findRefElementCache.putIfAbsent( diff --git a/lib/src/model.dart b/lib/src/model.dart index 8b29ce48b9..3b9b1d93e8 100644 --- a/lib/src/model.dart +++ b/lib/src/model.dart @@ -268,9 +268,7 @@ class InheritableAccessor extends Accessor with Inheritable { } /// Getters and setters. -class Accessor extends ModelElement - with SourceCodeMixin - implements EnclosedElement { +class Accessor extends ModelElement implements EnclosedElement { GetterSetterCombo _enclosingCombo; Accessor(PropertyAccessorElement element, Library library, @@ -698,8 +696,8 @@ class Class extends ModelElement /// Returns all the implementors of this class. Iterable get publicImplementors { return filterNonPublic(findCanonicalFor( - packageGraph._implementors[href] != null - ? packageGraph._implementors[href] + packageGraph.implementors[href] != null + ? packageGraph.implementors[href] : [])); } @@ -1087,7 +1085,7 @@ class Class extends ModelElement } class Constructor extends ModelElement - with SourceCodeMixin, TypeParameters + with TypeParameters implements EnclosedElement { Constructor( ConstructorElement element, Library library, PackageGraph packageGraph) @@ -1176,7 +1174,6 @@ abstract class Documentable extends Nameable { bool get hasDocumentation; bool get hasExtendedDocumentation; String get oneLineDoc; - Documentable get overriddenDocumentedElement; PackageGraph get packageGraph; bool get isDocumented; } @@ -1216,6 +1213,10 @@ abstract class Canonicalization extends Object bool get isCanonical; Library get canonicalLibrary; + /// Pieces of the location split by [locationSplitter] (removing package: and + /// slashes). + Set get locationPieces; + List scoreCanonicalCandidates(List libraries) { return libraries.map((l) => scoreElementWithLibrary(l)).toList()..sort(); } @@ -1383,7 +1384,7 @@ class EnumField extends Field { } class Field extends ModelElement - with GetterSetterCombo, Inheritable, SourceCodeMixin + with GetterSetterCombo, Inheritable implements EnclosedElement { bool _isInherited = false; Class _enclosingClass; @@ -1745,19 +1746,30 @@ class Library extends ModelElement with Categorization { List _variables; Namespace _exportedNamespace; String _name; + factory Library(LibraryElement element, PackageGraph packageGraph) { return packageGraph.findOrCreateLibraryFor(element); } - Library._(LibraryElement element, PackageGraph packageGraph) + Library._(LibraryElement element, PackageGraph packageGraph, this._package) : super(element, null, packageGraph, null) { if (element == null) throw new ArgumentError.notNull('element'); _exportedNamespace = new NamespaceBuilder().createExportNamespaceForLibrary(element); + _package._allLibraries.add(this); } List _allOriginalModelElementNames; + final Package _package; + @override + Package get package { + // Everything must be in a package. TODO(jcollins-g): Support other things + // that look like packages. + assert(_package != null); + return _package; + } + /// [allModelElements] resolved to their original names. /// /// A collection of [ModelElement.fullyQualifiedNames] for [ModelElement]s @@ -1809,6 +1821,9 @@ class Library extends ModelElement with Categorization { if (sdkLib != null && (sdkLib.isInternal || !sdkLib.isDocumented)) { return false; } + if (packageGraph.isLibraryExcluded(name) || + packageGraph.isLibraryExcluded(element.librarySource.uri.toString())) + return false; return true; } @@ -2318,7 +2333,7 @@ class Library extends ModelElement with Categorization { } class Method extends ModelElement - with SourceCodeMixin, Inheritable, TypeParameters + with Inheritable, TypeParameters implements EnclosedElement { bool _isInherited = false; Class _enclosingClass; @@ -2496,7 +2511,7 @@ abstract class Privacy { /// ModelElement will reference itself as part of the "wrong" [Library] /// from the public interface perspective. abstract class ModelElement extends Canonicalization - with Privacy, Warnable, Nameable + with Privacy, Warnable, Nameable, SourceCodeMixin implements Comparable, Documentable { final Element _element; // TODO(jcollins-g): This really wants a "member that has a type" class. @@ -2763,6 +2778,14 @@ abstract class ModelElement extends Canonicalization return _isPublic; } + @override + Set get locationPieces { + return new Set.from(element.location + .toString() + .split(locationSplitter) + .where((s) => s.isNotEmpty)); + } + Set get features { Set allFeatures = new Set(); allFeatures.addAll(annotations); @@ -2828,29 +2851,10 @@ abstract class ModelElement extends Canonicalization docFrom = [overriddenElement]; } else if (this is Inheritable && (this as Inheritable).isInherited) { Inheritable thisInheritable = (this as Inheritable); - InheritableAccessor newGetter; - InheritableAccessor newSetter; - if (this is GetterSetterCombo) { - GetterSetterCombo thisAsCombo = this as GetterSetterCombo; - if (thisAsCombo.hasGetter) { - newGetter = new ModelElement.from( - thisAsCombo.getter.element, - thisAsCombo.getter.definingLibrary, - thisAsCombo.getter.packageGraph); - } - if (thisAsCombo.hasSetter) { - newSetter = new ModelElement.from( - thisAsCombo.setter.element, - thisAsCombo.setter.definingLibrary, - thisAsCombo.setter.packageGraph); - } - } - ModelElement fromThis = new ModelElement.from( - element, - thisInheritable.definingEnclosingElement.library, - thisInheritable.definingEnclosingElement.packageGraph, - getter: newGetter, - setter: newSetter); + Class definingEnclosingClass = + thisInheritable.definingEnclosingElement as Class; + ModelElement fromThis = new ModelElement.fromElement( + element, definingEnclosingClass.packageGraph); docFrom = fromThis.documentationFrom; } else { docFrom = [this]; @@ -2911,10 +2915,12 @@ abstract class ModelElement extends Canonicalization // just shortcut them out. if (!hasPublicName(element)) { _canonicalLibrary = null; - } else if (!packageGraph.publicLibraries.contains(definingLibrary)) { + } else if (!packageGraph.localPublicLibraries.contains(definingLibrary)) { List candidateLibraries = packageGraph .libraryElementReexportedBy[definingLibrary.element] - ?.where((l) => l.isPublic) + ?.where((l) => + l.isPublic && + l.package.documentedWhere != DocumentLocation.missing) ?.toList(); if (candidateLibraries != null) { @@ -3001,7 +3007,7 @@ abstract class ModelElement extends Canonicalization Element get element => _element; @override - String get elementLocation { + String get location { // Call nothing from here that can emit warnings or you'll cause stack overflows. if (lineAndColumn != null) { return "(${pathLib.toUri(sourceFileName)}:${lineAndColumn.item1}:${lineAndColumn.item2})"; @@ -3122,6 +3128,7 @@ abstract class ModelElement extends Canonicalization /// A human-friendly name for the kind of element this is. String get kind; + @override Library get library => _library; String get linkedName { @@ -3182,26 +3189,6 @@ abstract class ModelElement extends Canonicalization ModelElement get overriddenElement => null; - ModelElement _overriddenDocumentedElement; - bool _overriddenDocumentedElementIsSet = false; - // TODO(jcollins-g): This method prefers canonical elements, but it isn't - // guaranteed and is probably the source of bugs or confusing warnings. - @override - ModelElement get overriddenDocumentedElement { - if (!_overriddenDocumentedElementIsSet) { - ModelElement found = this; - while ((found.element.documentationComment == null || - found.element.documentationComment == "") && - !found.isCanonical && - found.overriddenElement != null) { - found = found.overriddenElement; - } - _overriddenDocumentedElement = found; - _overriddenDocumentedElementIsSet = true; - } - return _overriddenDocumentedElement; - } - int _overriddenDepth; int get overriddenDepth { if (_overriddenDepth == null) { @@ -3219,6 +3206,8 @@ abstract class ModelElement extends Canonicalization @override PackageGraph get packageGraph => _packageGraph; + Package get package => library.package; + bool get isPublicAndPackageDocumented => isPublic && library.packageGraph.packageDocumentedFor(this); @@ -3485,7 +3474,7 @@ abstract class ModelElement extends Canonicalization /// {@example abc/def/xyz_component.dart region=template lang=html} /// String _injectExamples(String rawdocs) { - final dirPath = this.packageGraph.packageMeta.dir.path; + final dirPath = package.packageMeta.dir.path; RegExp exampleRE = new RegExp(r'{@example\s+([^}]+)}'); return rawdocs.replaceAllMapped(exampleRE, (match) { var args = _getExampleArgs(match[1]); @@ -3666,7 +3655,7 @@ class ModelFunctionTypedef extends ModelFunctionTyped { } class ModelFunctionTyped extends ModelElement - with SourceCodeMixin, TypeParameters + with TypeParameters implements EnclosedElement { @override List typeParameters = []; @@ -3781,34 +3770,114 @@ class Operator extends Method { } class PackageGraph extends Canonicalization with Nameable, Warnable { + // TODO(jcollins-g): This constructor is convoluted. Clean this up by + // building Libraries and adding them to Packages, then adding Packages + // to this graph. + PackageGraph( + Iterable libraryElements, + this.packageMeta, + this._packageWarningOptions, + this.driver, + this.sdk, + this.autoIncludeDependencies, + this.excludes, + this.excludePackages) { + assert(_allConstructedModelElements.isEmpty); + assert(allLibraries.isEmpty); + _packageWarningCounter = new PackageWarningCounter(_packageWarningOptions); + + // Build [Package] objects. + libraryElements.forEach((element) {}); + + // Build [Library] objects, and link them to [Package]s. + libraryElements.forEach((element) { + var packageMeta = new PackageMeta.fromElement(element); + var lib = new Library._( + element, this, new Package.fromPackageMeta(packageMeta, this)); + packageMap[packageMeta.name]._libraries.add(lib); + allLibraries[element] = lib; + assert(!_elementToLibrary.containsKey(lib.element)); + _elementToLibrary[element] = lib; + }); + allLibrariesAdded = true; + + // Go through docs of every ModelElement in package to pre-build the macros + // index. + allLocalModelElements.forEach((m) => m.documentationLocal); + _macrosAdded = true; + + // After the allModelElements traversal to be sure that all packages + // are picked up. + documentedPackages.toList().forEach((package) { + package._libraries.sort((a, b) => compareNatural(a.name, b.name)); + package._libraries.forEach((library) { + library._allClasses.forEach(_addToImplementors); + }); + }); + _implementors.values.forEach((l) => l.sort()); + allImplementorsAdded = true; + } + + /// Write files for packages outside the default. + final bool autoIncludeDependencies; + + /// It is safe to cache values derived from the _implementors table if this + /// is true. + bool allImplementorsAdded = false; + + /// A list of library names to treat as private. + final List excludes; + + /// A list of package names to exclude from local documentation. + final List excludePackages; + + // TODO(jcollins-g): refactor to eliminate the duplication with PackageBuilder + // (currently necessary for better use of the analyzer). + bool isLibraryExcluded(String name) => + excludes.any((pattern) => name == pattern); + bool isPackageExcluded(String name) => + excludePackages.any((pattern) => name == pattern); + + Map> get implementors { + assert(allImplementorsAdded); + return _implementors; + } + // All library objects related to this package; a superset of _libraries. final Map allLibraries = new Map(); - // Objects to keep track of warnings. + /// Objects to keep track of warnings. final PackageWarningOptions _packageWarningOptions; PackageWarningCounter _packageWarningCounter; - // All ModelElements constructed for this package; a superset of allModelElements. + /// All ModelElements constructed for this package; a superset of allModelElements. final Map, ModelElement> _allConstructedModelElements = new Map(); - // Anything that might be inheritable, place here for later lookup. + /// Anything that might be inheritable, place here for later lookup. final Map, Set> _allInheritableElements = new Map(); /// Map of Class.href to a list of classes implementing that class final Map> _implementors = new Map(); + /// PackageMeta for the default package. final PackageMeta packageMeta; + @override + Set get locationPieces => new Set(); + @override Library get canonicalLibrary => null; + Package get defaultPackage => + localPackages.firstWhere((p) => p.packageMeta == packageMeta); + @override PackageGraph get packageGraph => this; /// Map of package name to Package. - final Map packages = {}; + final Map packageMap = {}; final AnalysisDriver driver; final DartSdk sdk; @@ -3828,10 +3897,7 @@ class PackageGraph extends Canonicalization with Nameable, Warnable { bool get isDocumented => true; @override - Documentable get overriddenDocumentedElement => this; - - @override - List get documentationFrom => [this]; + List get documentationFrom => [defaultPackage]; @override Warnable get enclosingElement => null; @@ -3845,37 +3911,6 @@ class PackageGraph extends Canonicalization with Nameable, Warnable { bool allLibrariesAdded = false; bool _macrosAdded = false; - PackageGraph(Iterable libraryElements, this.packageMeta, - this._packageWarningOptions, this.driver, - [this.sdk]) { - assert(_allConstructedModelElements.isEmpty); - assert(allLibraries.isEmpty); - _packageWarningCounter = new PackageWarningCounter(_packageWarningOptions); - libraryElements.forEach((element) { - var lib = new Library._(element, this); - packages.putIfAbsent( - lib.packageName, () => new Package(lib.packageName, this)); - packages[lib.packageName]._libraries.add(lib); - allLibraries[element] = lib; - assert(!_elementToLibrary.containsKey(lib.element)); - _elementToLibrary[element] = lib; - }); - - allLibrariesAdded = true; - packages.values.forEach((package) { - package._libraries.sort((a, b) => compareNatural(a.name, b.name)); - package._libraries.forEach((library) { - library._allClasses.forEach(_addToImplementors); - }); - }); - - _implementors.values.forEach((l) => l.sort()); - // Go through docs of every model element in package to prebuild the macros - // index. - allModelElements.forEach((m) => m.documentationLocal); - _macrosAdded = true; - } - /// Returns true if there's at least one library documented in the package /// that has the same package path as the library for the given element. /// Usable as a cross-check for dartdoc's canonicalization to generate @@ -3884,7 +3919,7 @@ class PackageGraph extends Canonicalization with Nameable, Warnable { bool packageDocumentedFor(ModelElement element) { if (_allRootDirs == null) { _allRootDirs = new Set() - ..addAll(libraries.map((l) => l.packageMeta?.resolvedDir)); + ..addAll(publicLibraries.map((l) => l.packageMeta?.resolvedDir)); } return (_allRootDirs.contains(element.library.packageMeta?.resolvedDir)); } @@ -3893,7 +3928,7 @@ class PackageGraph extends Canonicalization with Nameable, Warnable { Element get element => null; @override - String get elementLocation => '(top level package)'; + String get location => '(top level package)'; /// Flush out any warnings we might have collected while /// [_packageWarningOptions.autoFlush] was false. @@ -3901,7 +3936,6 @@ class PackageGraph extends Canonicalization with Nameable, Warnable { _packageWarningCounter.maybeFlush(); } - @override Tuple2 get lineAndColumn => null; @override @@ -3929,7 +3963,7 @@ class PackageGraph extends Canonicalization with Nameable, Warnable { String locatableLocation = ''; if (locatable != null) { locatableName = locatable.fullyQualifiedName.replaceFirst(':', '-'); - locatableLocation = locatable.elementLocation; + locatableLocation = locatable.location; } return new Tuple2(locatableName, locatableLocation); } @@ -4063,15 +4097,15 @@ class PackageGraph extends Canonicalization with Nameable, Warnable { List messageParts = [warningMessage]; if (warnable != null) { - messageParts.add( - "${warnablePrefix} ${warnableName}: ${warnable.elementLocation ?? ''}"); + messageParts + .add("${warnablePrefix} ${warnableName}: ${warnable.location ?? ''}"); } if (referredFrom != null) { for (Locatable referral in referredFrom) { if (referral != warnable) { var referredFromStrings = _safeWarnableName(referral); messageParts.add( - "${referredFromPrefix} ${referredFromStrings}: ${referral.elementLocation ?? ''}"); + "${referredFromPrefix} ${referredFromStrings}: ${referral.location ?? ''}"); } } } @@ -4096,24 +4130,34 @@ class PackageGraph extends Canonicalization with Nameable, Warnable { return locatable.fullyQualifiedName.replaceFirst(':', '-'); } - bool get hasMultiplePackages => publicPackages.length > 1; + bool get hasMultiplePackages => localPackages.length > 1; + + List get packages => packageMap.values.toList(); List _publicPackages; List get publicPackages { if (_publicPackages == null) { + assert(allLibrariesAdded); // Help the user if they pass us a package that doesn't exist. for (String packageName in config.packageOrder) { - if (!packages.containsKey(packageName)) + if (!packageMap.containsKey(packageName)) warnOnElement( null, PackageWarning.packageOrderGivesMissingPackageName, - message: "${packageName}, packages: ${packages.keys.join(',')}"); + message: + "${packageName}, packages: ${packageMap.keys.join(',')}"); } - _publicPackages = packages.values.where((p) => p.isPublic).toList() - ..sort(); + _publicPackages = filterNonPublic(packages).toList()..sort(); } return _publicPackages; } + /// Local packages are to be documented locally vs. remote or not at all. + List get localPackages => + publicPackages.where((p) => p.isLocal).toList(); + + /// Documented packages are documented somewhere (local or remote). + Iterable get documentedPackages => packages.where((p) => p.documentedWhere != DocumentLocation.missing); + // Use only in testing. void resetPublicPackages() => _publicPackages = null; @@ -4148,7 +4192,7 @@ class PackageGraph extends Canonicalization with Nameable, Warnable { /// A lookup index for hrefs to allow warnings to indicate where a broken /// link or orphaned file may have come from. Not cached because /// [ModelElement]s can be created at any time and we're basing this - /// on more than just [allModelElements] to make the error messages + /// on more than just [allLocalModelElements] to make the error messages /// comprehensive. Map> get allHrefs { Map> hrefMap = new Map(); @@ -4167,8 +4211,8 @@ class PackageGraph extends Canonicalization with Nameable, Warnable { hrefMap.putIfAbsent(modelElement.href, () => new Set()); hrefMap[modelElement.href].add(modelElement); } - for (Package package in packages.values) { - for (Library library in package._libraries) { + for (Package package in packageMap.values) { + for (Library library in package.libraries) { if (library.href == null) continue; hrefMap.putIfAbsent(library.href, () => new Set()); hrefMap[library.href].add(library); @@ -4204,6 +4248,7 @@ class PackageGraph extends Canonicalization with Nameable, Warnable { bool get isSdk => packageMeta.isSdk; void _addToImplementors(Class c) { + assert(!allImplementorsAdded); _implementors.putIfAbsent(c.href, () => []); void _checkAndAddClass(Class key, Class implClass) { _implementors.putIfAbsent(key.href, () => []); @@ -4230,8 +4275,35 @@ class PackageGraph extends Canonicalization with Nameable, Warnable { } List get libraries => - packages.values.expand((p) => p.libraries).toList()..sort(); - Iterable get publicLibraries => filterNonPublic(libraries); + packages.expand((p) => p.libraries).toList()..sort(); + + List _publicLibraries; + Iterable get publicLibraries { + if (_publicLibraries == null) { + assert(allLibrariesAdded); + _publicLibraries = filterNonPublic(libraries).toList(); + } + return _publicLibraries; + } + + List _localLibraries; + Iterable get localLibraries { + if (_localLibraries == null) { + assert(allLibrariesAdded); + _localLibraries = localPackages.expand((p) => p.libraries).toList() + ..sort(); + } + return _localLibraries; + } + + List _localPublicLibraries; + Iterable get localPublicLibraries { + if (_localPublicLibraries == null) { + assert(allLibrariesAdded); + _localPublicLibraries = filterNonPublic(localLibraries).toList(); + } + return _localPublicLibraries; + } bool get hasHomepage => packageMeta.homepage != null && packageMeta.homepage.isNotEmpty; @@ -4484,18 +4556,22 @@ class PackageGraph extends Canonicalization with Nameable, Warnable { Library foundLibrary = findLibraryFor(e); if (foundLibrary == null) { - foundLibrary = new Library._(e.library, this); + foundLibrary = new Library._( + e.library, + this, + new Package.fromPackageMeta( + new PackageMeta.fromElement(e.library), packageGraph)); allLibraries[e.library] = foundLibrary; } return foundLibrary; } List _allModelElements; - Iterable get allModelElements { + Iterable get allLocalModelElements { assert(allLibrariesAdded); if (_allModelElements == null) { _allModelElements = []; - this.libraries.forEach((library) { + this.localLibraries.forEach((library) { _allModelElements.addAll(library.allModelElements); }); } @@ -4505,7 +4581,7 @@ class PackageGraph extends Canonicalization with Nameable, Warnable { List _allCanonicalModelElements; Iterable get allCanonicalModelElements { return (_allCanonicalModelElements ??= - allModelElements.where((e) => e.isCanonical).toList()); + allLocalModelElements.where((e) => e.isCanonical).toList()); } String getMacro(String name) { @@ -4576,14 +4652,59 @@ class Category extends LibraryContainer implements Comparable { PackageGraph get packageGraph => package.packageGraph; } +/// For a given package, indicate with this enum whether it should be documented +/// [local]ly, whether we should treat the package as [missing] and any references +/// to it made canonical to this package, or [remote], indicating that +/// we can build hrefs to an external source. +enum DocumentLocation { + local, + missing, + remote, +} + /// A [LibraryContainer] that contains [Library] objects related to a particular /// package. -class Package extends LibraryContainer implements Comparable, Privacy { +class Package extends LibraryContainer + with Locatable + implements Comparable, Privacy { String _name; PackageGraph _packageGraph; + final _isLocal; final Map _nameToCategory = {}; - Package(this._name, this._packageGraph); + + // Creates a package, if necessary, and adds it to the [packageGraph]. + factory Package.fromPackageMeta( + PackageMeta packageMeta, PackageGraph packageGraph) { + String packageName = packageMeta.name; + bool isLocal = packageMeta == packageGraph.packageMeta || + packageGraph.autoIncludeDependencies; + isLocal = isLocal && !packageGraph.isPackageExcluded(packageName); + bool expectNonLocal = false; + + if (!packageGraph.packageMap.containsKey(packageName) && + packageGraph.allLibrariesAdded) expectNonLocal = true; + packageGraph.packageMap.putIfAbsent(packageName, + () => new Package._(packageName, packageGraph, packageMeta, isLocal)); + // Verify that we don't somehow decide to document locally a package picked + // up after all documented libraries are added, because that breaks the + // assumption that we've picked up all documented libraries and packages + // before allLibrariesAdded is true. + assert(!(expectNonLocal && + packageGraph.packageMap[packageName].documentedWhere == + DocumentLocation.local)); + return packageGraph.packageMap[packageName]; + } + + Package._(this._name, this._packageGraph, this._packageMeta, this._isLocal); + + final Set _allLibraries = new Set(); + + /// Returns all libraries added to this package. May include non-documented + /// libraries, but is not guaranteed to include a complete list of + /// non-documented libraries unless they are all referenced by documented ones. + /// Not sorted. + Set get allLibraries => _allLibraries; /// Return true if the code has defined non-default categories for libraries /// in this package. @@ -4591,6 +4712,9 @@ class Package extends LibraryContainer implements Comparable, Privacy { LibraryContainer get defaultCategory => nameToCategory[null]; + @override + List get documentationFrom => [this]; + bool _isPublic; @override bool get isPublic { @@ -4598,6 +4722,25 @@ class Package extends LibraryContainer implements Comparable, Privacy { return _isPublic; } + /// Returns true if this package is being documented locally. If it isn't + /// documented locally, it still might be documented remotely; see documentedWhere. + bool get isLocal => _isLocal; + + DocumentLocation get documentedWhere { + if (!isLocal) return DocumentLocation.missing; + // TODO(jcollins-g): Implement DocumentLocation.remote. + return DocumentLocation.local; + } + + @override + String get fullyQualifiedName => 'package:$name'; + + @override + String get href => 'index.html'; + + @override + String get location => pathLib.toUri(packageMeta.resolvedDir).toString(); + @override String get name => _name; @@ -4607,7 +4750,10 @@ class Package extends LibraryContainer implements Comparable, Privacy { // Workaround for mustache4dart issue where templates do not recognize // inherited properties as being in-context. @override - Iterable get publicLibraries => super.publicLibraries; + Iterable get publicLibraries { + assert(libraries.every((l) => l.packageMeta == _packageMeta)); + return super.publicLibraries; + } /// A map of category name to the category itself. Map get nameToCategory { @@ -4642,7 +4788,7 @@ class Package extends LibraryContainer implements Comparable, Privacy { /// Is this the package at the top of the list? We display the first /// package specially (with "Libraries" rather than the package name). - bool get isFirstPackage => identical(packageGraph.publicPackages.first, this); + bool get isFirstPackage => identical(packageGraph.localPackages.first, this); bool get isSdk => packageMeta.isSdk; @@ -4652,9 +4798,9 @@ class Package extends LibraryContainer implements Comparable, Privacy { if (isSdk) { _packagePath = getSdkDir().path; } else { - assert(_libraries.isNotEmpty); + assert(libraries.isNotEmpty); File file = new File( - pathLib.canonicalize(_libraries.first.element.source.fullName)); + pathLib.canonicalize(libraries.first.element.source.fullName)); Directory dir = file.parent; while (dir.parent.path != dir.path && dir.existsSync()) { File pubspec = new File(pathLib.join(dir.path, 'pubspec.yaml')); @@ -4669,15 +4815,8 @@ class Package extends LibraryContainer implements Comparable, Privacy { return _packagePath; } - PackageMeta _packageMeta; - // TODO(jcollins-g): packageMeta should be passed in with the object rather - // than calculated indirectly from libraries. - PackageMeta get packageMeta { - if (_packageMeta == null) { - _packageMeta = _libraries.first.packageMeta; - } - return _packageMeta; - } + final PackageMeta _packageMeta; + PackageMeta get packageMeta => _packageMeta; @override String toString() => name; @@ -4903,7 +5042,7 @@ abstract class TypeParameters implements ModelElement { /// Top-level variables. But also picks up getters and setters? class TopLevelVariable extends ModelElement - with GetterSetterCombo, SourceCodeMixin + with GetterSetterCombo implements EnclosedElement { @override final Accessor getter; @@ -4984,7 +5123,7 @@ class TopLevelVariable extends ModelElement } class Typedef extends ModelElement - with SourceCodeMixin, TypeParameters + with TypeParameters implements EnclosedElement { Typedef(FunctionTypeAliasElement element, Library library, PackageGraph packageGraph) @@ -5120,8 +5259,8 @@ class PackageBuilder { Future buildPackageGraph() async { Set libraries = await getLibraries(getFiles); - return new PackageGraph( - libraries, packageMeta, getWarningOptions(), driver, sdk); + return new PackageGraph(libraries, packageMeta, getWarningOptions(), driver, + sdk, autoIncludeDependencies, excludes, excludePackages); } DartSdk _sdk; @@ -5304,20 +5443,59 @@ class PackageBuilder { } } + Set _packageMetasForFiles(Iterable files) { + Set metas = new Set(); + for (String filename in files) { + metas.add(new PackageMeta.fromFilename(filename)); + } + return metas; + } + Future> _parseLibraries(Set files) async { Set libraries = new Set(); + Set originalSources; Set sources = new Set(); - files.forEach((filename) => driver.addFile(filename)); + Set lastPass = new Set(); + Set current; + Set addedFiles = new Set(); + do { + lastPass = _packageMetasForFiles(files); + files.difference(addedFiles).forEach((filename) { + driver.addFile(filename); + addedFiles.add(filename); + }); + await Future + .wait(files.map((f) => processLibrary(f, libraries, sources))); + + /// We don't care about upstream analysis errors, so save the first + /// source list. + if (originalSources == null) originalSources = new Set()..addAll(sources); + files.addAll(driver.knownFiles); + current = _packageMetasForFiles(files); + // To get canonicalization correct for non-locally documented packages + // (so we can generate the right hyperlinks), it's vital that we + // add all libraries in dependent packages. So if the analyzer + // discovers some files in a package we haven't seen yet, add files + // for that package. + for (PackageMeta meta in current.difference(lastPass)) { + if (meta.isSdk) { + files.addAll(getSdkFilesToDocument()); + } else { + files.addAll( + findFilesToDocumentInPackage(meta.dir.path, false, false)); + } + } + } while (!lastPass.containsAll(current)); - await Future.wait(files.map((f) => processLibrary(f, libraries, sources))); - await logAnalysisErrors(sources); + await logAnalysisErrors(originalSources); return libraries.toList(); } /// Given a package name, explore the directory and pull out all top level /// library files in the "lib" directory to document. Iterable findFilesToDocumentInPackage( - String basePackageDir, bool autoIncludeDependencies) sync* { + String basePackageDir, bool autoIncludeDependencies, + [bool filterExcludes = true]) sync* { final String sep = pathLib.separator; Set packageDirs = new Set()..add(basePackageDir); @@ -5328,7 +5506,7 @@ class PackageBuilder { new Uri.file(pathLib.join(basePackageDir, 'pubspec.yaml'))) .asMap(); for (String packageName in info.keys) { - if (!excludes.contains(packageName)) { + if (!filterExcludes || !excludes.contains(packageName)) { packageDirs.add(pathLib.dirname(info[packageName].toFilePath())); } } @@ -5370,11 +5548,7 @@ class PackageBuilder { : findFilesToDocumentInPackage(rootDir.path, autoIncludeDependencies)); if (packageMeta.isSdk) { files.addAll(getSdkFilesToDocument()); - } else if (embedderSdk == null || embedderSdk.urlMappings.isEmpty) { - // Always throw in the interceptors; this library is needed for - // canonicalization assuming that the Interceptor class still exists. - files.addAll(getSdkFilesToDocument('dart:_interceptors')); - } else /* embedderSdk.urlMappings.isNotEmpty && !packageMeta.isSdk */ { + } else if (embedderSdk.urlMappings.isNotEmpty && !packageMeta.isSdk) { embedderSdk.urlMappings.keys.forEach((String dartUri) { Source source = embedderSdk.mapDartUri(dartUri); files.add(source.fullName); diff --git a/lib/src/model_utils.dart b/lib/src/model_utils.dart index 25fed99f0e..28c55cec88 100644 --- a/lib/src/model_utils.dart +++ b/lib/src/model_utils.dart @@ -81,6 +81,7 @@ bool hasPrivateName(Element e) { } if (e is LibraryElement && (e.identifier.startsWith('dart:_') || + e.identifier.startsWith('dart:nativewrappers/') || ['dart:nativewrappers'].contains(e.identifier))) { return true; } diff --git a/lib/src/package_meta.dart b/lib/src/package_meta.dart index e14f853c2e..e967b4d82d 100644 --- a/lib/src/package_meta.dart +++ b/lib/src/package_meta.dart @@ -20,14 +20,28 @@ abstract class PackageMeta { PackageMeta(this.dir); + @override + bool operator ==(other) { + if (other is! PackageMeta) return false; + return pathLib.equals(dir.absolute.path, other.dir.absolute.path); + } + + @override + int get hashCode => pathLib.hash(dir.absolute.path); + /// Use this instead of fromDir where possible. factory PackageMeta.fromElement(LibraryElement libraryElement) { // Workaround for dart-lang/sdk#32707. Replace with isInSdk once that works. - if (libraryElement.source.uri.scheme == 'dart') return new PackageMeta.fromDir(getSdkDir()); + if (libraryElement.source.uri.scheme == 'dart') + return new PackageMeta.fromDir(getSdkDir()); return new PackageMeta.fromDir( new File(pathLib.canonicalize(libraryElement.source.fullName)).parent); } + factory PackageMeta.fromFilename(String filename) { + return new PackageMeta.fromDir(new File(filename).parent); + } + /// This factory is guaranteed to return the same object for any given /// [dir.absolute.path]. Multiple [dir.absolute.path]s will resolve to the /// same object if they are part of the same package. Returns null diff --git a/lib/src/warnings.dart b/lib/src/warnings.dart index fd30576749..f8987dc223 100644 --- a/lib/src/warnings.dart +++ b/lib/src/warnings.dart @@ -86,10 +86,12 @@ final Map packageWarningText = const { "Use of <> in a comment for type parameters is being treated as HTML by markdown"), }; -/// Something that package warnings can be called on. +/// Something that package warnings can be called on. Optionally associated +/// with an analyzer [element]. abstract class Warnable implements Canonicalization { void warn(PackageWarning warning, {String message, Iterable referredFrom}); + Element get element; Warnable get enclosingElement; } @@ -97,17 +99,12 @@ abstract class Warnable implements Canonicalization { abstract class Locatable { String get fullyQualifiedName; String get href; + List get documentationFrom; - Element get element; - String get elementLocation; - Tuple2 get lineAndColumn; - - Set get locationPieces { - return new Set.from(element.location - .toString() - .split(locationSplitter) - .where((s) => s.isNotEmpty)); - } + + /// A string indicating the URI of this Locatable, usually derived from + /// [Element.location]. + String get location; } // The kinds of warnings that can be displayed when documenting a package. diff --git a/lib/templates/_packages.html b/lib/templates/_packages.html index 7cc22a4186..7b8b8a1150 100644 --- a/lib/templates/_packages.html +++ b/lib/templates/_packages.html @@ -1,5 +1,5 @@
    - {{#packageGraph.publicPackages}} + {{#packageGraph.localPackages}} {{#isFirstPackage}}
  1. Libraries
  2. {{/isFirstPackage}} @@ -15,5 +15,5 @@
  3. {{{linkedName}}}
  4. {{/publicLibraries}} {{/categories}} - {{/packageGraph.publicPackages}} + {{/packageGraph.localPackages}}
diff --git a/lib/templates/index.html b/lib/templates/index.html index 326ff6822f..684448a3d6 100644 --- a/lib/templates/index.html +++ b/lib/templates/index.html @@ -9,7 +9,7 @@
{{self.name}} { {{#packageGraph}} {{>documentation}} - {{#publicPackages}} + {{#localPackages}}
{{#isFirstPackage}}

Libraries

@@ -29,7 +29,7 @@

{{name}}

{{/categories}}
- {{/publicPackages}} + {{/localPackages}} {{/packageGraph}} diff --git a/pubspec.lock b/pubspec.lock index f8530019e1..90a643ab3c 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -408,4 +408,4 @@ packages: source: hosted version: "2.1.13" sdks: - dart: ">=2.0.0-dev.23.0 <=2.0.0-dev.43.0" + dart: ">=2.0.0-dev.23.0 <=2.0.0-dev.44.0" diff --git a/test/compare_output_test.dart b/test/compare_output_test.dart index 23a52b239e..7474253f26 100644 --- a/test/compare_output_test.dart +++ b/test/compare_output_test.dart @@ -56,7 +56,9 @@ void main() { 'examples', '--hide-sdk-text', '--exclude', - 'dart.async,dart.collection,dart.convert,dart.core,dart.math,dart.typed_data,package:meta/meta.dart', + 'package:meta/meta.dart', + '--exclude-packages', + 'Dart', '--no-include-source', '--pretty-index-json', '--output', diff --git a/test/dartdoc_test.dart b/test/dartdoc_test.dart index c81cdac3b4..df6ff73555 100644 --- a/test/dartdoc_test.dart +++ b/test/dartdoc_test.dart @@ -6,7 +6,6 @@ library dartdoc.dartdoc_test; import 'dart:io'; -import 'package:analyzer/dart/element/element.dart'; import 'package:dartdoc/dartdoc.dart'; import 'package:dartdoc/src/model.dart'; import 'package:dartdoc/src/package_meta.dart'; @@ -41,7 +40,8 @@ void main() { PackageGraph p = results.packageGraph; expect(p.name, 'test_package'); expect(p.hasDocumentationFile, isTrue); - expect(p.publicLibraries, hasLength(10)); + expect(p.defaultPackage.publicLibraries, hasLength(10)); + expect(p.localPackages.length, equals(1)); }); test('generate docs for ${pathLib.basename(testPackageBadDir.path)} fails', @@ -70,7 +70,7 @@ void main() { expect(p.name, 'test_package_small'); expect(p.hasHomepage, isFalse); expect(p.hasDocumentationFile, isFalse); - expect(p.publicLibraries, hasLength(1)); + expect(p.localPublicLibraries, hasLength(1)); }); test('generate docs including a single library', () async { @@ -122,10 +122,10 @@ void main() { expect(p.libraries.map((lib) => lib.name).contains('dart:core'), isTrue); expect(p.libraries.map((lib) => lib.name).contains('dart:async'), isTrue); expect(p.libraries.map((lib) => lib.name).contains('dart:bear'), isTrue); - expect(p.packages.length, equals(1)); + expect(p.packageMap.length, equals(1)); // Things that do not override the core SDK do not belong in their own package. - expect(p.packages["Dart"].isSdk, isTrue); - expect(p.packages["test_package_embedder_yaml"], isNull); + expect(p.packageMap["Dart"].isSdk, isTrue); + expect(p.packageMap["test_package_embedder_yaml"], isNull); // Should be true once dart-lang/sdk#32707 is fixed. //expect( // p.publicLibraries, @@ -138,7 +138,7 @@ void main() { expect(dart_bear, isNotNull); expect( dart_bear.allClasses.map((cls) => cls.name).contains('Bear'), isTrue); - expect(p.packages["Dart"].publicLibraries, hasLength(3)); + expect(p.packageMap["Dart"].publicLibraries, hasLength(3)); }); - }); + }, timeout: new Timeout.factor(4)); } diff --git a/test/model_test.dart b/test/model_test.dart index 8e2f7243a4..dbf6bacb8e 100644 --- a/test/model_test.dart +++ b/test/model_test.dart @@ -31,6 +31,7 @@ void main() { Library twoExportsLib; Library interceptorsLib; PackageGraph sdkAsPackageGraph; + Library dartAsync; setUpAll(() async { await utils.init(); @@ -40,6 +41,8 @@ void main() { exLibrary = packageGraph.libraries.firstWhere((lib) => lib.name == 'ex'); fakeLibrary = packageGraph.libraries.firstWhere((lib) => lib.name == 'fake'); + dartAsync = + packageGraph.libraries.firstWhere((lib) => lib.name == 'dart:async'); twoExportsLib = packageGraph.libraries.firstWhere((lib) => lib.name == 'two_exports'); interceptorsLib = packageGraph.libraries @@ -47,12 +50,48 @@ void main() { sdkAsPackageGraph = utils.testPackageGraphSdk; }); + group('Missing and Remote', () { + test('Verify that SDK libraries are not canonical when missing', () { + expect( + dartAsync.package.documentedWhere, equals(DocumentLocation.missing)); + expect(dartAsync.isCanonical, isFalse); + expect(ginormousPackageGraph.publicPackages, isNotEmpty); + }); + + test( + 'Verify that autoIncludeDependencies makes everything document locally', + () { + expect(ginormousPackageGraph.packages.map((p) => p.documentedWhere), + everyElement((x) => x == DocumentLocation.local)); + }); + + test('Verify that ginormousPackageGraph takes in the SDK', () { + expect( + ginormousPackageGraph.packages + .firstWhere((p) => p.isSdk) + .libraries + .length, + greaterThan(1)); + expect( + ginormousPackageGraph.packages + .firstWhere((p) => p.isSdk) + .documentedWhere, + equals(DocumentLocation.local)); + }); + + test('Verify that packageGraph has an SDK but will not document it locally', + () { + expect(packageGraph.packages.firstWhere((p) => p.isSdk).documentedWhere, + isNot(equals(DocumentLocation.local))); + }); + }); + group('Category', () { test('Verify categories for test_package', () { - expect(packageGraph.publicPackages.length, equals(1)); - expect(packageGraph.publicPackages.first.hasCategories, isTrue); + expect(packageGraph.localPackages.length, equals(1)); + expect(packageGraph.localPackages.first.hasCategories, isTrue); List packageCategories = - packageGraph.publicPackages.first.categories; + packageGraph.localPackages.first.categories; expect(packageCategories.length, equals(3)); expect(packageCategories.map((c) => c.name).toList(), orderedEquals(['Real Libraries', 'Unreal', 'Misc'])); @@ -60,19 +99,19 @@ void main() { orderedEquals([2, 2, 1])); expect( packageGraph - .publicPackages.first.defaultCategory.publicLibraries.length, + .localPackages.first.defaultCategory.publicLibraries.length, equals(3)); }); test('Verify that packages without categories get handled', () { - expect(packageGraphSmall.publicPackages.length, equals(1)); - expect(packageGraphSmall.publicPackages.first.hasCategories, isFalse); + expect(packageGraphSmall.localPackages.length, equals(1)); + expect(packageGraphSmall.localPackages.first.hasCategories, isFalse); List packageCategories = - packageGraphSmall.publicPackages.first.categories; + packageGraphSmall.localPackages.first.categories; expect(packageCategories.length, equals(0)); expect( packageGraph - .publicPackages.first.defaultCategory.publicLibraries.length, + .localPackages.first.defaultCategory.publicLibraries.length, equals(3)); }); }); @@ -95,7 +134,7 @@ void main() { }); test('libraries', () { - expect(packageGraph.libraries, hasLength(9)); + expect(packageGraph.localPublicLibraries, hasLength(8)); expect(interceptorsLib.isPublic, isFalse); }); @@ -104,24 +143,24 @@ void main() { expect(packageGraph.homepage, equals('http://github.com/dart-lang')); }); - test('categories', () { - expect(packageGraph.publicPackages, hasLength(1)); + test('packages', () { + expect(packageGraph.localPackages, hasLength(1)); - Package category = packageGraph.publicPackages.first; - expect(category.name, 'test_package'); - expect(category.libraries, hasLength(8)); + Package package = packageGraph.localPackages.first; + expect(package.name, 'test_package'); + expect(package.publicLibraries, hasLength(8)); }); - test('multiple categories, sorted default', () { - expect(ginormousPackageGraph.publicPackages, hasLength(3)); - expect(ginormousPackageGraph.publicPackages.first.name, + test('multiple packages, sorted default', () { + expect(ginormousPackageGraph.localPackages, hasLength(4)); + expect(ginormousPackageGraph.localPackages.first.name, equals('test_package')); }); - test('multiple categories, specified sort order', () { + test('multiple packages, specified sort order', () { setConfig(packageOrder: ['meta', 'test_package']); - expect(ginormousPackageGraph.publicPackages, hasLength(3)); - expect(ginormousPackageGraph.publicPackages.first.name, equals('meta')); + expect(ginormousPackageGraph.localPackages, hasLength(4)); + expect(ginormousPackageGraph.localPackages.first.name, equals('meta')); }); test('is documented in library', () { @@ -368,7 +407,7 @@ void main() { .firstWhere((m) => m.name == 'withPrivateMacro'); withUndefinedMacro = dog.allInstanceMethods .firstWhere((m) => m.name == 'withUndefinedMacro'); - packageGraph.allModelElements.forEach((m) => m.documentation); + packageGraph.allLocalModelElements.forEach((m) => m.documentation); }); test("renders a macro within the same comment where it's defined", () { diff --git a/tool/grind.dart b/tool/grind.dart index 144ce1064c..cf0c382d37 100644 --- a/tool/grind.dart +++ b/tool/grind.dart @@ -268,7 +268,9 @@ Future> _buildTestPackageDocs( '--json', '--pretty-index-json', '--exclude', - 'dart.async,dart.collection,dart.convert,dart.core,dart.math,dart.typed_data,meta', + 'package:meta/meta.dart', + '--exclude-packages', + 'Dart', ], workingDirectory: testPackage.absolute.path); } @@ -617,7 +619,9 @@ updateTestPackageDocs() async { '--pretty-index-json', '--hide-sdk-text', '--exclude', - 'dart.async,dart.collection,dart.convert,dart.core,dart.math,dart.typed_data,package:meta/meta.dart', + 'package:meta/meta.dart', + '--exclude-packages', + 'Dart', '--output', '../test_package_docs', ],