Skip to content

PackageGraph

class PackageGraph

Constructors

PackageGraph.uninitialized()

PackageGraph.uninitialized(
  DartdocOptionContext config,
  DartSdk sdk,
  bool hasEmbedderSdk,
  PackageMetaProvider packageMetaProvider,
  AnalysisContext _analysisContext,
)
Implementation
dart
PackageGraph.uninitialized(
  this.config,
  DartSdk sdk,
  this.hasEmbedderSdk,
  this.packageMetaProvider,
  this._analysisContext,
)   : packageMeta = config.topLevelPackageMeta,
      sdkLibrarySources = {
        for (var lib in sdk.sdkLibraries) sdk.mapDartUri(lib.shortName): lib
      } {
  // Make sure the default package exists, even if it has no libraries.
  // This can happen for packages that only contain embedder SDKs.
  Package.fromPackageMeta(packageMeta, this);
}

Properties

allConstructedModelElements final

final Map<ConstructedModelElementsKey, ModelElement> allConstructedModelElements

All ModelElements constructed for this package; a superset of the elements gathered in _gatherModelElements.

Implementation
dart
final Map<ConstructedModelElementsKey, ModelElement>
    allConstructedModelElements = {};

allExtensionsAdded read / write

bool allExtensionsAdded

getter:

It is safe to cache values derived from the _extensions table if this is true.

setter:

It is safe to cache values derived from the _extensions table if this is true.

Implementation
dart
bool allExtensionsAdded = false;

allHrefs no setter

Map<String, Set<ModelElement>> get allHrefs

A lookup index for hrefs to allow warnings to indicate where a broken link or orphaned file may have come from.

This is not cached because ModelElements can be created at any time.

Implementation
dart
Map<String, Set<ModelElement>> get allHrefs {
  final hrefMap = <String, Set<ModelElement>>{};
  &#47;&#47; TODO(jcollins-g ): handle calculating hrefs causing new elements better
  &#47;&#47;                    than toList().
  for (final modelElement in allConstructedModelElements.values.toList()) {
    &#47;&#47; Technically speaking we should be able to use canonical model elements
    &#47;&#47; only here, but since the warnings that depend on this debug
    &#47;&#47; canonicalization problems, don't limit ourselves in case an href is
    &#47;&#47; generated for something non-canonical.
    if (modelElement is Dynamic) continue;
    &#47;&#47; TODO: see [Accessor.enclosingCombo]
    if (modelElement is Accessor) continue;
    final href = modelElement.href;
    if (href == null) continue;

    hrefMap.putIfAbsent(href, () => {}).add(modelElement);
    hrefMap
        .putIfAbsent(href.replaceAll(htmlBasePlaceholder, ''), () => {})
        .add(modelElement);
  }

  for (final library in _allLibraries.values) {
    final href = library.href;
    if (href == null) continue;
    hrefMap.putIfAbsent(href, () => {}).add(library);
  }
  return hrefMap;
}

allImplementersAdded read / write

bool allImplementersAdded

getter:

It is safe to cache values derived from the _implementers table if this is true.

setter:

It is safe to cache values derived from the _implementers table if this is true.

Implementation
dart
bool allImplementersAdded = false;

allInheritableElements final

final Map<InheritableElementsKey, Set<ModelElement>> allInheritableElements

Anything that might be inheritable, place here for later lookup.

Implementation
dart
final Map<InheritableElementsKey, Set<ModelElement>> allInheritableElements =
    {};

allLibrariesAdded read / write

bool allLibrariesAdded
Implementation
dart
bool allLibrariesAdded = false;

breadcrumbName no setter

String get breadcrumbName

The name to use in breadcrumbs in the rendered documentation.

Implementation
dart
@override
String get breadcrumbName => throw UnimplementedError();

config final

Dartdoc's configuration flags.

Implementation
dart
final DartdocOptionContext config;

dartCoreObject late final

final late String dartCoreObject

The String name representing the Object type.

Implementation
dart
late final String dartCoreObject = libraries
        .firstWhereOrNull((library) => library.name == 'dart:core')
        ?.classes
        .firstWhereOrNull((c) => c.name == 'Object')
        ?.linkedName ??
    'Object';

defaultPackage late final

final late Package defaultPackage
Implementation
dart
late final Package defaultPackage =
    Package.fromPackageMeta(packageMeta, this);

defaultPackageName no setter

String get defaultPackageName

Name of the default package.

Implementation
dart
String get defaultPackageName => packageMeta.name;

displayName no setter

String get displayName

The name to use as text in the rendered documentation.

Implementation
dart
@override
String get displayName => throw UnimplementedError();

documentedName no setter inherited

String? get documentedName

Inherited from Referable.

Implementation
dart
String? get documentedName => null;

elementTypeCache final

final Map<Record, ElementType> elementTypeCache

Cache of ElementTypes instantiated during documentation generation.

Key is a record of (DartType, Library?, InstantiatedTypeAliasElement?).

Implementation
dart
final elementTypeCache =
    <(DartType, Library?, InstantiatedTypeAliasElement?), ElementType>{};

extensions no setter

Iterable<Extension> get extensions
Implementation
dart
Iterable<Extension> get extensions {
  assert(allExtensionsAdded);
  return _extensions;
}

fullyQualifiedName no setter inherited

String get fullyQualifiedName

Inherited from Referable.

Implementation
dart
String get fullyQualifiedName => name;

hasEmbedderSdk final

final bool hasEmbedderSdk
Implementation
dart
final bool hasEmbedderSdk;

hasFooterVersion no setter

bool get hasFooterVersion
Implementation
dart
bool get hasFooterVersion => !config.excludeFooterVersion;

hashCode no setter inherited

int get hashCode

The hash code for this object.

A hash code is a single integer which represents the state of the object that affects operator == comparisons.

All objects have hash codes. The default hash code implemented by Object represents only the identity of the object, the same way as the default operator == implementation only considers objects equal if they are identical (see identityHashCode).

If operator == is overridden to use the object state instead, the hash code must also be changed to represent that state, otherwise the object cannot be used in hash based data structures like the default Set and Map implementations.

Hash codes must be the same for objects that are equal to each other according to operator ==. The hash code of an object should only change if the object changes in a way that affects equality. There are no further requirements for the hash codes. They need not be consistent between executions of the same program and there are no distribution guarantees.

Objects that are not equal are allowed to have the same hash code. It is even technically allowed that all instances have the same hash code, but if clashes happen too often, it may reduce the efficiency of hash-based data structures like HashSet or HashMap.

If a subclass overrides hashCode, it should override the operator == operator as well to maintain consistency.

Inherited from Object.

Implementation
dart
external int get hashCode;

href no setter inherited

String? get href

Inherited from Referable.

Implementation
dart
String? get href => null;

implementers no setter

Map<InheritingContainer, List<InheritingContainer>> get implementers
Implementation
dart
Map<InheritingContainer, List<InheritingContainer>> get implementers {
  assert(allImplementersAdded);
  return _implementers;
}

libraries late final

final late List<Library> libraries

The set of all libraries (public and implementation) found across all packages.

Implementation
dart
@visibleForTesting

&#47;&#47;&#47; The set of all libraries (public and implementation) found across all
&#47;&#47;&#47; [packages].
late final List<Library> libraries =
    packages.expand((p) => p.libraries).toList(growable: false)..sort();

library no setter inherited

Library? get library

Inherited from Referable.

Implementation
dart
Library? get library => null;

libraryCount no setter

int get libraryCount
Implementation
dart
int get libraryCount => libraries.length;

libraryExports no setter

Map<LibraryElement, Set<Library>> get libraryExports

A mapping from a LibraryElement to all of the Librarys that export it, which is created if it is not yet populated.

Implementation
dart
Map<LibraryElement, Set<Library>> get libraryExports {
  &#47;&#47; The map must be reset if we're still in the middle of adding libraries
  &#47;&#47; (though this shouldn't happen).
  if (_allLibraries.keys.length != _previousSizeOfAllLibraries) {
    assert(
      _previousSizeOfAllLibraries == 0,
      'Re-entered `libraryExports` while building all libraries',
    );
    _previousSizeOfAllLibraries = _allLibraries.keys.length;
    _libraryExports = {};
    for (var library in publicLibraries) {
      _tagExportsFor(library, library.element);
    }
  }
  return _libraryExports;
}

localPackages no setter

List<Package> get localPackages

Local packages are to be documented locally vs. remote or not at all.

Implementation
dart
List<Package> get localPackages =>
    publicPackages.where((p) => p.isLocal).toList(growable: false);

localPublicLibraries late final

final late Set<Library> localPublicLibraries
Implementation
dart
late final Set<Library> localPublicLibraries = () {
  assert(allLibrariesAdded);
  return _localLibraries.wherePublic.toSet();
}();

name no setter

String get name
Implementation
dart
@override
String get name => '';

objectClass read / write

InheritingContainer objectClass

getter:

The Object class declared in the Dart SDK's 'dart:core' library.

setter:

The Object class declared in the Dart SDK's 'dart:core' library.

Implementation
dart
late InheritingContainer objectClass;

packageGraph no setter

PackageGraph get packageGraph
Implementation
dart
@override
PackageGraph get packageGraph => this;

packageMap final

final Map<String, Package> packageMap

Map of package name to Package.

This mapping must be complete before initializePackageGraph is called.

Implementation
dart
final Map<String, Package> packageMap = {};

packageMeta final

final PackageMeta packageMeta

PackageMeta for the default package.

Implementation
dart
final PackageMeta packageMeta;

packageMetaProvider final

final PackageMetaProvider packageMetaProvider

PackageMeta provider for building PackageMetas.

Implementation
dart
final PackageMetaProvider packageMetaProvider;

packages no setter

Iterable<Package> get packages
Implementation
dart
Iterable<Package> get packages => packageMap.values;

packageWarningCounter late final

final late PackageWarningCounter packageWarningCounter

Keep track of warnings.

Implementation
dart
late final PackageWarningCounter packageWarningCounter =
    PackageWarningCounter(this);

publicLibraries late final

final late Set<Library> publicLibraries

The set of public libraries found across all packages.

Implementation
dart
late final Set<Library> publicLibraries = () {
  assert(allLibrariesAdded);
  return libraries.wherePublic.toSet();
}();

publicPackages late final

final late List<Package> publicPackages
Implementation
dart
late final List<Package> publicPackages = () {
  assert(allLibrariesAdded);
  &#47;&#47; Help the user if they pass us a package that doesn't exist.
  var packageNames = packages.map((p) => p.name).toSet();
  for (var packageName in config.packageOrder) {
    if (!packageNames.contains(packageName)) {
      warnOnElement(null, PackageWarning.packageOrderGivesMissingPackageName,
          message: "$packageName, packages: ${packageNames.join(',')}");
    }
  }
  return packages.where((p) => p.isPublic).toList(growable: false)..sort();
}();

referenceChildren late final

final late Map<String, Referable> referenceChildren

Map of referenceName to the elements that are a member of this, but not this model element itself. Can be cached.

There is no need to duplicate references here that can be found via scope.

Implementation
dart
@override
late final Map<String, Referable> referenceChildren = () {
  &#47;&#47; We have to use a stable order or otherwise references depending on
  &#47;&#47; ambiguous resolution (see below) will change where they resolve based on
  &#47;&#47; internal implementation details.
  var sortedPackages = packages.toList(growable: false)..sort(byName);
  var sortedDocumentedPackages = _documentedPackages.toList(growable: false)
    ..sort(byName);
  return {
    &#47;&#47; TODO(jcollins-g): Warn about directly referencing top level items out
    &#47;&#47; of scope?  Doing this will be even more ambiguous and potentially
    &#47;&#47; confusing than doing so with libraries.
    ...sortedDocumentedPackages
        .expand((p) => p.publicLibrariesSorted)
        .expand((l) => [
              ...l.constants.wherePublic,
              ...l.functions.wherePublic,
              ...l.properties.wherePublic,
              ...l.typedefs.wherePublic,
              ...l.extensions.wherePublic,
              ...l.extensionTypes.wherePublic,
              ...l.classes.wherePublic,
              ...l.enums.wherePublic,
              ...l.mixins.wherePublic,
            ])
        .asMapByName,

    &#47;&#47; Libraries are next.
    &#47;&#47; TODO(jcollins-g): Warn about directly referencing libraries out of
    &#47;&#47; scope?  Doing this is always going to be ambiguous and potentially
    &#47;&#47; confusing.
    ...sortedDocumentedPackages
        .expand((p) => p.publicLibrariesSorted)
        .asMapByName,

    &#47;&#47; Packages are the top priority.
    ...sortedPackages.asMapByName,
  };
}();

referenceGrandparentOverrides no setter inherited

Iterable<Referable>? get referenceGrandparentOverrides

Inherited from Referable.

Implementation
dart
Iterable<Referable>? get referenceGrandparentOverrides => null;

referenceName no setter inherited

String get referenceName

Inherited from Referable.

Implementation
dart
String get referenceName => name;

referenceParents no setter

Iterable<Referable> get referenceParents

Iterable of immediate "parents" to try resolving component parts. referenceBy stops at the first parent where a part is found. Can be cached.

Implementation
dart
@override
Iterable<Referable> get referenceParents => const [];

resourceProvider no setter

ResourceProvider get resourceProvider
Implementation
dart
ResourceProvider get resourceProvider => config.resourceProvider;

runtimeType no setter inherited

Type get runtimeType

A representation of the runtime type of the object.

Inherited from Object.

Implementation
dart
external Type get runtimeType;

scope no setter inherited

Scope? get scope

Inherited from Referable.

Implementation
dart
@visibleForOverriding
Scope? get scope => null;

sdkLibrarySources final

final Map<Source?, SdkLibrary> sdkLibrarySources
Implementation
dart
final Map<Source?, SdkLibrary> sdkLibrarySources;

workspacePackageNames final

final Set<String> workspacePackageNames

Names of packages that are workspace members, populated by the builder when workspaceDocs is enabled.

Used by Package.isLocal to determine if a package should be treated as local documentation.

Implementation
dart
final Set<String> workspacePackageNames = {};

Methods

addHtmlFragment()

void addHtmlFragment(String name, String content)
Implementation
dart
void addHtmlFragment(String name, String content) {
  &#47;&#47; TODO(srawlins): We have to add HTML fragments after documentation is
  &#47;&#47; built, in order to include fragments which come from macros which
  &#47;&#47; were generated by a tool. I think the macro&#47;HTML-injection system needs
  &#47;&#47; to be overhauled to allow for this type of looping.
  &#47;&#47;assert(!_localDocumentationBuilt);
  _htmlFragments[name] = content;
}

addLibraryToGraph()

void addLibraryToGraph(DartDocResolvedLibrary resolvedLibrary)

Adds resolvedLibrary to the package graph, adding it to _allLibraries, and to the Package which is created from the PackageMeta for the library.

Call during initialization to add a library to this PackageGraph.

Libraries added in this manner are assumed to be part of documented packages, even if 'includes' or 'embedder.yaml' files cause these to span packages.

Implementation
dart
void addLibraryToGraph(DartDocResolvedLibrary resolvedLibrary) {
  assert(!allLibrariesAdded);
  var libraryElement2 = resolvedLibrary.element;
  var packageMeta =
      packageMetaProvider.fromElement(libraryElement2, config.sdkDir);
  if (packageMeta == null) {
    var libraryPath = libraryElement2.firstFragment.source.fullName;
    var dartOrFlutter = config.flutterRoot == null ? 'dart' : 'flutter';
    throw DartdocFailure(
        "Unknown package for library: '$libraryPath'.  Consider "
        '`$dartOrFlutter pub get` and&#47;or '
        '`$dartOrFlutter pub global deactivate dartdoc` followed by '
        '`$dartOrFlutter pub global activate dartdoc` to fix. Also, be sure '
        'that `$dartOrFlutter analyze` completes without errors.');
  }
  var package = Package.fromPackageMeta(packageMeta, this);
  var library = Library.fromLibraryResult(resolvedLibrary, this, package);
  if (_shouldIncludeLibrary(resolvedLibrary.element)) {
    package.libraries.add(library);
  }
  _allLibraries[libraryElement2.firstFragment.source.fullName] = library;
}

addMacro()

void addMacro(String name, String content)
Implementation
dart
void addMacro(String name, String content) {
  &#47;&#47; TODO(srawlins): We have to add HTML fragments after documentation is
  &#47;&#47; built, in order to include fragments which come from macros which
  &#47;&#47; were generated by a tool. I think the macro&#47;HTML-injection system needs
  &#47;&#47; to be overhauled to allow for this type of looping.
  &#47;&#47;assert(!_localDocumentationBuilt);
  _macros[name] = content;
}

dispose()

void dispose()
Implementation
dart
void dispose() {
  &#47;&#47; Clear out any cached tool snapshots and temporary directories.
  &#47;&#47; TODO(jcollins-g): Consider ownership change for these objects
  &#47;&#47; so they are tied to PackageGraph instead of being global.
  SnapshotCache.instanceFor(config.resourceProvider).dispose();
  ToolTempFileTracker.instanceFor(config.resourceProvider).dispose();
}

findButDoNotCreateLibraryFor()

Library? findButDoNotCreateLibraryFor(Element e)

This is used when we might need a Library object that isn't actually a documentation entry point (for elements that have no Library within the set of canonical Libraries).

Implementation
dart
Library? findButDoNotCreateLibraryFor(Element e) {
  &#47;&#47; This is just a cache to avoid creating lots of libraries over and over.
  return _allLibraries[e.library?.firstFragment.source.fullName];
}

findCanonicalModelElementFor()

ModelElement? findCanonicalModelElementFor(
  ModelElement? modelElement, {
  Container? preferredClass,
})

Tries to find a canonical ModelElement for modelElement.

If we know the element is related to a particular class, pass a preferredClass to disambiguate.

This can return null in a few ways: if modelElement is null, or if it has no canonical library, or if a possible canonical model element has a false value for isCanonical.

Implementation
dart
ModelElement? findCanonicalModelElementFor(ModelElement? modelElement,
    {Container? preferredClass}) {
  assert(allLibrariesAdded);
  if (modelElement == null) return null;
  var e = modelElement.element;
  if (preferredClass != null) {
    var canonicalClass =
        findCanonicalModelElementFor(preferredClass) as Container?;
    if (canonicalClass != null) preferredClass = canonicalClass;
  }
  var library = modelElement.canonicalLibrary;
  if (modelElement is Library) return library;

  if (library == null && preferredClass != null) {
    library = preferredClass.canonicalLibrary;
  }
  &#47;&#47; For elements defined in extensions, they are canonical.
  var enclosingElement = e.enclosingElement;
  if (enclosingElement is ExtensionElement) {
    library ??= getModelForElement(enclosingElement.library) as Library?;
    &#47;&#47; TODO(keertip): Find a better way to exclude members of extensions
    &#47;&#47; when libraries are specified using the "--include" flag.
    if (library != null && library.isDocumented) {
      return getModelFor(e, library, enclosingContainer: preferredClass);
    }
  }
  &#47;&#47; TODO(jcollins-g): The data structures should be changed to eliminate
  &#47;&#47; guesswork with member elements.
  var declaration = e.baseElement;
  ModelElement? canonicalModelElement;
  if (e is ConstructorElement ||
      e is MethodElement ||
      e is FieldElement ||
      e is PropertyAccessorElement) {
    var declarationModelElement = getModelForElement(declaration);
    e = declarationModelElement.element;
    canonicalModelElement = _findCanonicalModelElementForAmbiguous(
        declarationModelElement, library,
        preferredClass: preferredClass as InheritingContainer?);
  } else {
    if (library != null) {
      if (e case PropertyInducingElement(:var getter, :var setter)) {
        var getterElement =
            getter == null ? null : getModelFor(getter, library) as Accessor;
        var setterElement =
            setter == null ? null : getModelFor(setter, library) as Accessor;
        canonicalModelElement = getModelForPropertyInducingElement(e, library,
            getter: getterElement, setter: setterElement);
      } else {
        canonicalModelElement = getModelFor(e, library);
      }
    }
    assert(canonicalModelElement is! Inheritable);
    if (canonicalModelElement != null && !canonicalModelElement.isCanonical) {
      canonicalModelElement = null;
    }
  }
  &#47;&#47; Prefer fields and top-level variables.
  if (e is PropertyAccessorElement && canonicalModelElement is Accessor) {
    canonicalModelElement = canonicalModelElement.enclosingCombo;
  }
  return canonicalModelElement;
}

gatherModelNodes()

void gatherModelNodes(DartDocResolvedLibrary resolvedLibrary)

Populate's _modelNodes with elements in resolvedLibrary.

This is done as Library model objects are created, while we are holding onto resolvedLibrary objects.

Implementation
dart
&#47;&#47; TODO(srawlins): I suspect we populate this mapping with way too many
&#47;&#47; objects, too eagerly. They are only needed when writing the source code of
&#47;&#47; an element to HTML, and maybe for resolving doc comments. We should find a
&#47;&#47; way to get this data only when needed. But it's not immediately obvious to
&#47;&#47; me how, because the data is on AST nodes, not the element model.
void gatherModelNodes(DartDocResolvedLibrary resolvedLibrary) {
  for (var unit in resolvedLibrary.units) {
    for (var directive in unit.directives.whereType<LibraryDirective>()) {
      &#47;&#47; There should be only one library directive. If there are more, there
      &#47;&#47; is no harm in grabbing ModelNode for each.
      var commentData = directive.documentationComment?.data;
      _modelNodes.putIfAbsent(
          resolvedLibrary.element,
          () => ModelNode(
                directive,
                resolvedLibrary.element,
                _analysisContext,
                commentData: commentData,
              ));
    }

    for (var declaration in unit.declarations) {
      _populateModelNodeFor(declaration);
      switch (declaration) {
        case ClassDeclaration(body: BlockClassBody(:var members)):
          for (var member in members) {
            _populateModelNodeFor(member);
          }
        case EnumDeclaration():
          if (declaration.declaredFragment?.element.isPublic ?? false) {
            final body = declaration.body;
            for (var constant in body.constants) {
              _populateModelNodeFor(constant);
            }
            for (var member in body.members) {
              _populateModelNodeFor(member);
            }
          }
        case MixinDeclaration(body: BlockClassBody(:var members)):
          for (var member in members) {
            _populateModelNodeFor(member);
          }
        case ExtensionDeclaration():
          if (declaration.declaredFragment?.element.isPublic ?? false) {
            if (declaration.body case BlockClassBody body) {
              for (var member in body.members) {
                _populateModelNodeFor(member);
              }
            }
          }
        case ExtensionTypeDeclaration():
          if (declaration.declaredFragment?.element.isPublic ?? false) {
            if (declaration.body case BlockClassBody(:var members)) {
              for (var member in members) {
                _populateModelNodeFor(member);
              }
            }
          }
      }
    }
  }
}

getHtmlFragment()

String? getHtmlFragment(String? name)
Implementation
dart
String? getHtmlFragment(String? name) {
  assert(_localDocumentationBuilt);
  if (name == null) {
    return null;
  }
  return _htmlFragments[name];
}

getMacro()

String? getMacro(String name)

Returns a macro by name, or null if no macro is found.

Implementation
dart
String? getMacro(String name) {
  assert(_localDocumentationBuilt);
  return _macros[name];
}

getModelFor() inherited

ModelElement getModelFor(
  Element element,
  Library? library, {
  Container? enclosingContainer,
})

Returns the ModelElement for element, instantiating it if needed.

A convenience method for ModelElement.for_, see its documentation.

Inherited from Referable.

Implementation
dart
ModelElement getModelFor(
  Element element,
  Library? library, {
  Container? enclosingContainer,
}) =>
    ModelElement.for_(
      element,
      library,
      packageGraph,
      enclosingContainer: enclosingContainer,
    );

getModelForElement() inherited

ModelElement getModelForElement(Element element)

Returns the ModelElement for element, instantiating it if needed.

A convenience method for ModelElement.forElement, see its documentation.

Inherited from Referable.

Implementation
dart
ModelElement getModelForElement(Element element) =>
    ModelElement.forElement(element, packageGraph);

getModelForPropertyInducingElement() inherited

ModelElement getModelForPropertyInducingElement(
  PropertyInducingElement element,
  Library library, {
  required Accessor? getter,
  required Accessor? setter,
  Container? enclosingContainer,
})

Returns the ModelElement for element, instantiating it if needed.

A convenience method for ModelElement.forPropertyInducingElement, see its documentation.

Inherited from Referable.

Implementation
dart
&#47;&#47; TODO(srawlins): Most callers seem to determine `getter` and `setter`
&#47;&#47; immediately before calling this method, and I imagine could instead just
&#47;&#47; call `getModelFor`.
ModelElement getModelForPropertyInducingElement(
  PropertyInducingElement element,
  Library library, {
  required Accessor? getter,
  required Accessor? setter,
  Container? enclosingContainer,
}) =>
    ModelElement.forPropertyInducingElement(
      element,
      library,
      packageGraph,
      getter: getter,
      setter: setter,
      enclosingContainer: enclosingContainer,
    );

getModelNodeFor()

ModelNode? getModelNodeFor(Element element2)
Implementation
dart
ModelNode? getModelNodeFor(Element element2) => _modelNodes[element2];

getTypeFor() inherited

ElementType getTypeFor(DartType type, Library? library)

Returns the ElementType for type, instantiating it if needed.

Inherited from Referable.

Implementation
dart
ElementType getTypeFor(DartType type, Library? library) =>
    ElementType.for_(type, library, packageGraph);

initializeCategories()

void initializeCategories()

Initializes the category mappings in all packages.

Implementation
dart
void initializeCategories() {
  for (var package in packages) {
    package.initializeCategories();
  }
}

initializePackageGraph()

Future<void> initializePackageGraph()

Call after all libraries are added.

Implementation
dart
Future<void> initializePackageGraph() async {
  assert(!_localDocumentationBuilt);
  allLibrariesAdded = true;
  &#47;&#47; Go through docs of every ModelElement in package to pre-build the macros
  &#47;&#47; index.
  await _precacheLocalDocs().wait;
  _localDocumentationBuilt = true;

  &#47;&#47; Scan all model elements to insure that interceptor and other special
  &#47;&#47; objects are found.
  &#47;&#47; Emit warnings for any local package that has no libraries.
  &#47;&#47; This must be done after the [allModelElements] traversal to be sure that
  &#47;&#47; all packages are picked up.
  for (var package in _documentedPackages) {
    for (var library in package.libraries) {
      _addToImplementers(library.classesAndExceptions);
      _addToImplementers(library.mixins);
      _addToImplementers(library.extensionTypes);
      if (library.isCanonical) {
        _extensions.addAll(library.extensions.whereDocumented);
      }
    }
    if (package.isLocal && !package.hasPublicLibraries) {
      package.warn(PackageWarning.noDocumentableLibrariesInPackage);
    }
  }
  allImplementersAdded = true;
  allExtensionsAdded = true;
}

noSuchMethod() inherited

dynamic noSuchMethod(Invocation invocation)

Invoked when a nonexistent method or property is accessed.

A dynamic member invocation can attempt to call a member which doesn't exist on the receiving object. Example:

dart
dynamic object = 1;
object.add(42); // Statically allowed, run-time error

This invalid code will invoke the noSuchMethod method of the integer 1 with an Invocation representing the .add(42) call and arguments (which then throws).

Classes can override noSuchMethod to provide custom behavior for such invalid dynamic invocations.

A class with a non-default noSuchMethod invocation can also omit implementations for members of its interface. Example:

dart
class MockList<T> implements List<T> {
  noSuchMethod(Invocation invocation) {
    log(invocation);
    super.noSuchMethod(invocation); // Will throw.
  }
}
void main() {
  MockList().add(42);
}

This code has no compile-time warnings or errors even though the MockList class has no concrete implementation of any of the List interface methods. Calls to List methods are forwarded to noSuchMethod, so this code will log an invocation similar to Invocation.method(#add, [42]) and then throw.

If a value is returned from noSuchMethod, it becomes the result of the original invocation. If the value is not of a type that can be returned by the original invocation, a type error occurs at the invocation.

The default behavior is to throw a NoSuchMethodError.

Inherited from Object.

Implementation
dart
@pragma("vm:entry-point")
@pragma("wasm:entry-point")
external dynamic noSuchMethod(Invocation invocation);

referenceBy() inherited

Referable? referenceBy(
  List<String> reference, {
  required bool Function(Referable?) filter,
  bool tryParents = true,
  Iterable<Referable>? parentOverrides,
})

Looks up a comment reference by its component parts.

If tryParents is true, try looking up the same reference in any parents of this. Will skip over results that do not pass a given filter and keep searching.

Inherited from Referable.

Implementation
dart
@nonVirtual
Referable? referenceBy(
  List<String> reference, {
  required bool Function(Referable?) filter,
  bool tryParents = true,
  Iterable<Referable>? parentOverrides,
}) {
  parentOverrides ??= referenceParents;
  if (reference.isEmpty) {
    return tryParents ? null : this;
  }
  for (var referenceLookup in _childLookups(reference)) {
    &#47;&#47; First attempt: Ask analyzer's `Scope.lookup` API.
    var result = _lookupViaScope(referenceLookup, filter: filter);
    if (result != null) {
      if (result is Prefix &&
          result.name == '_' &&
          library!.element.featureSet.isEnabled(Feature.wildcard_variables)) {
        &#47;&#47; A wildcard import prefix is non-binding.
        continue;
      }
      return result;
    }

    &#47;&#47; Second attempt: Look through `referenceChildren`.
    final referenceChildren = this.referenceChildren;
    final childrenResult = referenceChildren[referenceLookup.lookup];
    if (childrenResult != null) {
      var result = _recurseChildrenAndFilter(
        referenceLookup,
        childrenResult,
        filter: filter,
      );
      if (result != null) {
        return result;
      }
    }
  }
  &#47;&#47; If we can't find it in children, try searching parents if allowed.
  if (tryParents) {
    for (var parent in parentOverrides) {
      var result = parent.referenceBy(
        reference,
        tryParents: true,
        parentOverrides: referenceGrandparentOverrides,
        filter: filter,
      );
      if (result != null) return result;
    }
  }
  return null;
}

toString() override

String toString()

A string representation of this object.

Some classes have a default textual representation, often paired with a static parse function (like int.parse). These classes will provide the textual representation as their string representation.

Other classes have no meaningful textual representation that a program will care about. Such classes will typically override toString to provide useful information when inspecting the object, mainly for debugging or logging.

Implementation
dart
@override
String toString() {
  const divider = '=========================================================';
  final buffer = StringBuffer('PackageGraph built from ');
  buffer.writeln(defaultPackageName);
  buffer.writeln(divider);
  buffer.writeln();
  for (final name in packageMap.keys) {
    final package = packageMap[name]!;
    buffer.write('Package $name documented at ${package.documentedWhere} '
        'with libraries: ');
    buffer.writeAll(package.allLibraries);
    buffer.writeln();
  }
  buffer.writeln(divider);
  return buffer.toString();
}

warnOnElement()

void warnOnElement(
  Warnable? warnable,
  PackageWarning kind, {
  String? message,
  Iterable<Warnable> referredFrom = const [],
  Iterable<String> extendedDebug = const [],
})
Implementation
dart
void warnOnElement(Warnable? warnable, PackageWarning kind,
    {String? message,
    Iterable<Warnable> referredFrom = const [],
    Iterable<String> extendedDebug = const []}) {
  var newEntry = (warnable?.element, kind, message);
  if (_warnAlreadySeen.contains(newEntry)) {
    return;
  }
  &#47;&#47; Warnings can cause other warnings.  Queue them up via the stack but don't
  &#47;&#47; allow warnings we're already working on to get in there.
  _warnAlreadySeen.add(newEntry);
  _warnOnElement(warnable, kind,
      message: message ?? '',
      referredFrom: referredFrom,
      extendedDebug: extendedDebug);
  _warnAlreadySeen.remove(newEntry);
}

Operators

operator ==() inherited

bool operator ==(Object other)

The equality operator.

The default behavior for all Objects is to return true if and only if this object and other are the same object.

Override this method to specify a different equality relation on a class. The overriding method must still be an equivalence relation. That is, it must be:

  • Total: It must return a boolean for all arguments. It should never throw.

  • Reflexive: For all objects o, o == o must be true.

  • Symmetric: For all objects o1 and o2, o1 == o2 and o2 == o1 must either both be true, or both be false.

  • Transitive: For all objects o1, o2, and o3, if o1 == o2 and o2 == o3 are true, then o1 == o3 must be true.

The method should also be consistent over time, so whether two objects are equal should only change if at least one of the objects was modified.

If a subclass overrides the equality operator, it should override the hashCode method as well to maintain consistency.

Inherited from Object.

Implementation
dart
external bool operator ==(Object other);