ModelElement.from constructor

  1. Element e,
  2. Library library,
  3. PackageGraph packageGraph,
  4. {Container enclosingContainer}

Creates a ModelElement from a non-property-inducing e.

Do not construct any ModelElements except from this constructor or ModelElement.fromPropertyInducingElement. Specify enclosingContainer if and only if this is to be an inherited or extended object.


// TODO(jcollins-g): this way of using the optional parameter is messy,
// clean that up.
// TODO(jcollins-g): Enforce construction restraint.
// TODO(jcollins-g): Allow e to be null and drop extraneous null checks.
// TODO(jcollins-g): Auto-vivify element's defining library for library
// parameter when given a null.
factory ModelElement.from(
    Element e, Library library, PackageGraph packageGraph,
    {Container enclosingContainer}) {
  assert(packageGraph != null);
  assert(e != null);
  assert(library != null ||
      e is ParameterElement ||
      e is TypeParameterElement ||
      e is GenericFunctionTypeElementImpl ||
      e.kind == ElementKind.DYNAMIC ||
      e.kind == ElementKind.NEVER);

  if (e.kind == ElementKind.DYNAMIC) {
    return Dynamic(e, packageGraph);
  if (e.kind == ElementKind.NEVER) {
    return NeverType(e, packageGraph);

  Member originalMember;
  // TODO(jcollins-g): Refactor object model to instantiate 'ModelMembers'
  //                   for members?
  if (e is Member) {
    originalMember = e;
    e = e.declaration;

  // Return the cached ModelElement if it exists.
  var key =
      Tuple3<Element, Library, Container>(e, library, enclosingContainer);
  if (packageGraph.allConstructedModelElements.containsKey(key)) {
    return packageGraph.allConstructedModelElements[key];

  var newModelElement = ModelElement._from(e, library, packageGraph,
      enclosingContainer: enclosingContainer, originalMember: originalMember);

  if (enclosingContainer != null) assert(newModelElement is Inheritable);
  _cacheNewModelElement(e, newModelElement, library,
      enclosingContainer: enclosingContainer);

  assert(newModelElement.element is! MultiplyInheritedExecutableElement);
  return newModelElement;