| Index: pkg/analyzer/lib/src/dart/element/element.dart
|
| diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
|
| index 7c1e056917cbf7af237cbf95e6229ffb651e92c1..690bd04a59fbe08c3cbfcbc966b3c83e193dae87 100644
|
| --- a/pkg/analyzer/lib/src/dart/element/element.dart
|
| +++ b/pkg/analyzer/lib/src/dart/element/element.dart
|
| @@ -527,11 +527,26 @@ class ClassElementImpl extends AbstractClassElementImpl
|
|
|
| @override
|
| List<ConstructorElement> get constructors {
|
| - if (!isMixinApplication) {
|
| - assert(_constructors != null);
|
| - return _constructors ?? ConstructorElement.EMPTY_LIST;
|
| + if (isMixinApplication) {
|
| + return _computeMixinAppConstructors();
|
| }
|
| - return _computeMixinAppConstructors();
|
| + if (_unlinkedClass != null && _constructors == null) {
|
| + _constructors = _unlinkedClass.executables
|
| + .where((e) => e.kind == UnlinkedExecutableKind.constructor)
|
| + .map((e) => new ConstructorElementImpl.forSerialized(e, this))
|
| + .toList(growable: false);
|
| + // Ensure at least implicit default constructor.
|
| + if (_constructors.isEmpty) {
|
| + ConstructorElementImpl constructor = new ConstructorElementImpl('', -1);
|
| + constructor.enclosingElement = this;
|
| + constructor.synthetic = true;
|
| + constructor.type = new FunctionTypeImpl.elementWithNameAndArgs(
|
| + constructor, null, type.typeArguments, false);
|
| + _constructors = <ConstructorElement>[constructor];
|
| + }
|
| + }
|
| + assert(_constructors != null);
|
| + return _constructors ?? const <ConstructorElement>[];
|
| }
|
|
|
| /**
|
| @@ -540,6 +555,7 @@ class ClassElementImpl extends AbstractClassElementImpl
|
| * Should only be used for class elements that are not mixin applications.
|
| */
|
| void set constructors(List<ConstructorElement> constructors) {
|
| + assert(_unlinkedClass == null);
|
| assert(!isMixinApplication);
|
| for (ConstructorElement constructor in constructors) {
|
| (constructor as ConstructorElementImpl).enclosingElement = this;
|
| @@ -1678,11 +1694,6 @@ class ConstLocalVariableElementImpl extends LocalVariableElementImpl
|
| class ConstructorElementImpl extends ExecutableElementImpl
|
| implements ConstructorElement {
|
| /**
|
| - * Set of slots corresponding to const constructors that are part of cycles.
|
| - */
|
| - final Set<int> _constCycles;
|
| -
|
| - /**
|
| * The constructor to which this constructor is redirecting.
|
| */
|
| ConstructorElement _redirectedConstructor;
|
| @@ -1714,22 +1725,18 @@ class ConstructorElementImpl extends ExecutableElementImpl
|
| * Initialize a newly created constructor element to have the given [name] and
|
| * [offset].
|
| */
|
| - ConstructorElementImpl(String name, int offset)
|
| - : _constCycles = null,
|
| - super(name, offset);
|
| + ConstructorElementImpl(String name, int offset) : super(name, offset);
|
|
|
| /**
|
| * Initialize a newly created constructor element to have the given [name].
|
| */
|
| - ConstructorElementImpl.forNode(Identifier name)
|
| - : _constCycles = null,
|
| - super.forNode(name);
|
| + ConstructorElementImpl.forNode(Identifier name) : super.forNode(name);
|
|
|
| /**
|
| * Initialize using the given serialized information.
|
| */
|
| - ConstructorElementImpl.forSerialized(UnlinkedExecutable serializedExecutable,
|
| - this._constCycles, ClassElementImpl enclosingClass)
|
| + ConstructorElementImpl.forSerialized(
|
| + UnlinkedExecutable serializedExecutable, ClassElementImpl enclosingClass)
|
| : super.forSerialized(serializedExecutable, enclosingClass);
|
|
|
| /**
|
| @@ -1782,7 +1789,8 @@ class ConstructorElementImpl extends ExecutableElementImpl
|
| bool get isCycleFree {
|
| if (serializedExecutable != null) {
|
| return serializedExecutable.isConst &&
|
| - !_constCycles.contains(serializedExecutable.constCycleSlot);
|
| + !enclosingUnit.resynthesizerContext
|
| + .isInConstCycle(serializedExecutable.constCycleSlot);
|
| }
|
| return _isCycleFree;
|
| }
|
| @@ -7394,6 +7402,11 @@ abstract class ResynthesizerContext {
|
| UnitExplicitTopLevelVariables buildTopLevelVariables();
|
|
|
| /**
|
| + * Return `true` if the given const constructor [slot] is a part of a cycle.
|
| + */
|
| + bool isInConstCycle(int slot);
|
| +
|
| + /**
|
| * Resolve an [EntityRef] into a constructor. If the reference is
|
| * unresolved, return `null`.
|
| */
|
|
|