findCanonicalModelElementFor method
ModelElement?
findCanonicalModelElementFor(
- Element? e, {
- Container? preferredClass,
Tries to find a canonical ModelElement
for this e
. If we know this
element is related to a particular class, pass a preferredClass
to
disambiguate.
This doesn't know anything about PackageGraph.inheritThrough and
probably shouldn't, so using it with Inheritable
s without special casing
is not advised.
Implementation
ModelElement? findCanonicalModelElementFor(Element? e,
{Container? preferredClass}) {
assert(allLibrariesAdded);
if (e == null) return null;
if (preferredClass != null) {
var canonicalClass =
findCanonicalModelElementFor(preferredClass.element) as Container?;
if (canonicalClass != null) preferredClass = canonicalClass;
}
var lib = _findCanonicalLibraryFor(e);
if (lib == null && preferredClass != null) {
lib = _findCanonicalLibraryFor(preferredClass.element);
}
// For elements defined in extensions, they are canonical.
var enclosingElement = e.enclosingElement;
if (enclosingElement is ExtensionElement) {
lib ??= getModelForElement(enclosingElement.library) as Library?;
// TODO(keertip): Find a better way to exclude members of extensions
// when libraries are specified using the "--include" flag.
if (lib != null && lib.isDocumented) {
return getModelFor(e, lib);
}
}
// TODO(jcollins-g): The data structures should be changed to eliminate
// guesswork with member elements.
var declaration = e.declaration;
ModelElement? modelElement;
if (declaration != null &&
(e is ClassMemberElement || e is PropertyAccessorElement)) {
e = declaration;
modelElement = _findCanonicalModelElementForAmbiguous(e, lib,
preferredClass: preferredClass as InheritingContainer?);
} else {
if (lib != null) {
if (e is PropertyInducingElement) {
var getter = e.getter != null ? getModelFor(e.getter!, lib) : null;
var setter = e.setter != null ? getModelFor(e.setter!, lib) : null;
modelElement = getModelForPropertyInducingElement(e, lib,
getter: getter as Accessor?, setter: setter as Accessor?);
} else {
modelElement = getModelFor(e, lib);
}
}
assert(modelElement is! Inheritable);
if (modelElement != null && !modelElement.isCanonical) {
modelElement = null;
}
}
// Prefer fields and top-level variables.
if (e is PropertyAccessorElement && modelElement is Accessor) {
modelElement = modelElement.enclosingCombo;
}
return modelElement;
}