ModelElement.from(Element e, Library library, { Class enclosingClass, int index, ModelElement enclosingCombo })

Do not construct any ModelElements unless they are from this constructor. TODO(jcollins-g): enforce this. Specify enclosingClass only if this is to be an inherited object. Specify index only if this is to be an EnumField.forConstant. Specify enclosingCombo (a GetterSetterCombo) only if this is to be an Accessor. TODO(jcollins-g): this way of using the optional parameter is messy, clean that up.

Source

factory ModelElement.from(Element e, Library library,
    {Class enclosingClass, int index, ModelElement enclosingCombo}) {
  // We don't need index in this key because it isn't a disambiguator.
  // It isn't a disambiguator because EnumFields are not inherited, ever.
  // TODO(jcollins-g): cleanup class hierarchy so that EnumFields aren't
  // Inheritable, somehow?
  if (e is Member) {
    e = Package.getBasestElement(e);
  }
  Tuple4<Element, Library, Class, ModelElement> key =
      new Tuple4(e, library, enclosingClass, enclosingCombo);
  ModelElement newModelElement;
  if (e.kind != ElementKind.DYNAMIC &&
      library.package._allConstructedModelElements.containsKey(key)) {
    newModelElement = library.package._allConstructedModelElements[key];
  } else {
    if (e.kind == ElementKind.DYNAMIC) {
      newModelElement = new Dynamic(e, library);
    }
    if (e is LibraryElement) {
      newModelElement = new Library(e, library.package);
    }
    // Also handles enums
    if (e is ClassElement) {
      if (!e.isEnum) {
        newModelElement = new Class(e, library);
        if (newModelElement.library.name == 'dart:core' &&
            newModelElement.name == 'Object') {
          // We've found Object.  This is an important object, so save it in the package.
          newModelElement.library.package._objectElement = newModelElement;
        }
      } else {
        newModelElement = new Enum(e, library);
      }
    }
    if (e is FunctionElement) {
      newModelElement = new ModelFunction(e, library);
    }
    if (e is FunctionTypeAliasElement) {
      newModelElement = new Typedef(e, library);
    }
    if (e is FieldElement) {
      if (enclosingClass == null) {
        if (index != null) {
          newModelElement = new EnumField.forConstant(index, e, library);
        } else {
          if (e.enclosingElement.isEnum) {
            newModelElement = new EnumField(e, library);
          } else {
            newModelElement = new Field(e, library);
          }
        }
      } else {
        newModelElement = new Field.inherited(e, enclosingClass, library);
      }
    }
    if (e is ConstructorElement) {
      newModelElement = new Constructor(e, library);
    }
    if (e is MethodElement && e.isOperator) {
      if (enclosingClass == null)
        newModelElement = new Operator(e, library);
      else
        newModelElement = new Operator.inherited(e, enclosingClass, library);
    }
    if (e is MethodElement && !e.isOperator) {
      if (enclosingClass == null)
        newModelElement = new Method(e, library);
      else
        newModelElement = new Method.inherited(e, enclosingClass, library);
    }
    if (e is TopLevelVariableElement) {
      newModelElement = new TopLevelVariable(e, library);
    }
    if (e is PropertyAccessorElement) {
      newModelElement = new Accessor(e, library, enclosingCombo);
    }
    if (e is TypeParameterElement) {
      newModelElement = new TypeParameter(e, library);
    }
    if (e is ParameterElement) {
      newModelElement = new Parameter(e, library);
    }
  }
  if (newModelElement == null) throw "Unknown type ${e.runtimeType}";
  if (enclosingClass != null) assert(newModelElement is Inheritable);
  if (library != null) {
    library.package._allConstructedModelElements[key] = newModelElement;
    if (newModelElement is Inheritable) {
      Tuple2<Element, Library> iKey = new Tuple2(e, library);
      library.package._allInheritableElements
          .putIfAbsent(iKey, () => new Set());
      library.package._allInheritableElements[iKey].add(newModelElement);
    }
  }
  if (newModelElement is Accessor) {
    assert(newModelElement.enclosingCombo == enclosingCombo);
  } else {
    assert(enclosingCombo == null);
  }

  return newModelElement;
}