Serialize more properties of ConstructorElement.
Review URL: https://codereview.chromium.org/1924053003 .
This commit is contained in:
@@ -13,6 +13,7 @@ import 'constant_serialization.dart';
|
||||
import 'keys.dart';
|
||||
import 'modelz.dart';
|
||||
import 'serialization.dart';
|
||||
import 'serialization_util.dart';
|
||||
|
||||
/// Enum kinds used for encoding [Element]s.
|
||||
enum SerializedElementKind {
|
||||
@@ -23,6 +24,7 @@ enum SerializedElementKind {
|
||||
NAMED_MIXIN_APPLICATION,
|
||||
GENERATIVE_CONSTRUCTOR,
|
||||
FACTORY_CONSTRUCTOR,
|
||||
REDIRECTING_FACTORY_CONSTRUCTOR,
|
||||
FORWARDING_CONSTRUCTOR,
|
||||
TOPLEVEL_FIELD,
|
||||
STATIC_FIELD,
|
||||
@@ -346,7 +348,12 @@ class ConstructorSerializer implements ElementSerializer {
|
||||
return SerializedElementKind.GENERATIVE_CONSTRUCTOR;
|
||||
}
|
||||
} else if (element.isFactoryConstructor) {
|
||||
return SerializedElementKind.FACTORY_CONSTRUCTOR;
|
||||
ConstructorElement constructor = element;
|
||||
if (constructor.isRedirectingFactory) {
|
||||
return SerializedElementKind.REDIRECTING_FACTORY_CONSTRUCTOR;
|
||||
} else {
|
||||
return SerializedElementKind.FACTORY_CONSTRUCTOR;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -363,13 +370,37 @@ class ConstructorSerializer implements ElementSerializer {
|
||||
SerializerUtil.serializeParameters(element, encoder);
|
||||
encoder.setBool(Key.IS_CONST, element.isConst);
|
||||
encoder.setBool(Key.IS_EXTERNAL, element.isExternal);
|
||||
if (element.isExternal) return;
|
||||
if (element.isConst && !element.isFromEnvironmentConstructor) {
|
||||
ConstantConstructor constantConstructor = element.constantConstructor;
|
||||
ObjectEncoder constantEncoder = encoder.createObject(Key.CONSTRUCTOR);
|
||||
const ConstantConstructorSerializer()
|
||||
.visit(constantConstructor, constantEncoder);
|
||||
}
|
||||
if (element.definingConstructor != null) {
|
||||
assert(invariant(
|
||||
element,
|
||||
element.definingConstructor.enclosingClass ==
|
||||
element.enclosingClass.superclass,
|
||||
message: "Unexpected defining constructor: "
|
||||
"${element.definingConstructor}"));
|
||||
encoder.setString(
|
||||
Key.DEFINING_CONSTRUCTOR, element.definingConstructor.name);
|
||||
}
|
||||
if (kind == SerializedElementKind.GENERATIVE_CONSTRUCTOR) {
|
||||
encoder.setBool(Key.IS_REDIRECTING, element.isRedirectingGenerative);
|
||||
}
|
||||
encoder.setElement(Key.EFFECTIVE_TARGET, element.effectiveTarget);
|
||||
if (kind == SerializedElementKind.REDIRECTING_FACTORY_CONSTRUCTOR) {
|
||||
encoder.setType(
|
||||
Key.EFFECTIVE_TARGET_TYPE,
|
||||
element
|
||||
.computeEffectiveTargetType(element.enclosingClass.thisType));
|
||||
encoder.setElement(Key.IMMEDIATE_REDIRECTION_TARGET,
|
||||
element.immediateRedirectionTarget);
|
||||
if (element.redirectionDeferredPrefix != null) {
|
||||
encoder.setElement(Key.PREFIX, element.redirectionDeferredPrefix);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -660,6 +691,8 @@ class ElementDeserializer {
|
||||
return new GenerativeConstructorElementZ(decoder);
|
||||
case SerializedElementKind.FACTORY_CONSTRUCTOR:
|
||||
return new FactoryConstructorElementZ(decoder);
|
||||
case SerializedElementKind.REDIRECTING_FACTORY_CONSTRUCTOR:
|
||||
return new RedirectingFactoryConstructorElementZ(decoder);
|
||||
case SerializedElementKind.FORWARDING_CONSTRUCTOR:
|
||||
return new ForwardingConstructorElementZ(
|
||||
decoder.getElement(Key.CLASS), decoder.getElement(Key.ELEMENT));
|
||||
|
||||
@@ -25,7 +25,10 @@ class Key {
|
||||
static const Key DATA = const Key('data');
|
||||
static const Key DEFAULT = const Key('default');
|
||||
static const Key DEFAULTS = const Key('defaults');
|
||||
static const Key DEFINING_CONSTRUCTOR = const Key('definingConstructor');
|
||||
static const Key DYNAMIC_USES = const Key('dynamic-uses');
|
||||
static const Key EFFECTIVE_TARGET = const Key('effectiveTarget');
|
||||
static const Key EFFECTIVE_TARGET_TYPE = const Key('effectiveTargetType');
|
||||
static const Key ELEMENT = const Key('element');
|
||||
static const Key ELEMENTS = const Key('elements');
|
||||
static const Key EXECUTABLE_CONTEXT = const Key('executable-context');
|
||||
@@ -40,6 +43,8 @@ class Key {
|
||||
static const Key GET_OR_SET = const Key('getOrSet');
|
||||
static const Key GETTER = const Key('getter');
|
||||
static const Key ID = const Key('id');
|
||||
static const Key IMMEDIATE_REDIRECTION_TARGET =
|
||||
const Key('immediateRedirectionTarget');
|
||||
static const Key IMPACTS = const Key('impacts');
|
||||
static const Key IMPORT = const Key('import');
|
||||
static const Key IMPORTS = const Key('imports');
|
||||
@@ -58,6 +63,7 @@ class Key {
|
||||
static const Key IS_OPERATOR = const Key('isOperator');
|
||||
static const Key IS_OPTIONAL = const Key('isOptional');
|
||||
static const Key IS_PROXY = const Key('isProxy');
|
||||
static const Key IS_REDIRECTING = const Key('isRedirecting');
|
||||
static const Key IS_SETTER = const Key('isSetter');
|
||||
static const Key IS_UNNAMED_MIXIN_APPLICATION =
|
||||
const Key('isUnnamedMixinApplication');
|
||||
|
||||
@@ -30,6 +30,7 @@ import '../tree/tree.dart';
|
||||
import '../util/util.dart' show Link, LinkBuilder;
|
||||
import 'keys.dart';
|
||||
import 'serialization.dart';
|
||||
import 'serialization_util.dart';
|
||||
|
||||
/// Compute a [Link] from an [Iterable].
|
||||
Link toLink(Iterable iterable) {
|
||||
@@ -1065,6 +1066,7 @@ abstract class ConstructorElementZ extends DeserializedElementZ
|
||||
MemberElementMixin
|
||||
implements ConstructorElement {
|
||||
ConstantConstructor _constantConstructor;
|
||||
ConstructorElement _effectiveTarget;
|
||||
|
||||
ConstructorElementZ(ObjectDecoder decoder) : super(decoder);
|
||||
|
||||
@@ -1102,44 +1104,50 @@ abstract class ConstructorElementZ extends DeserializedElementZ
|
||||
@override
|
||||
AsyncMarker get asyncMarker => AsyncMarker.SYNC;
|
||||
|
||||
@override
|
||||
InterfaceType computeEffectiveTargetType(InterfaceType newType) {
|
||||
return _unsupported('computeEffectiveTargetType');
|
||||
}
|
||||
|
||||
@override
|
||||
ConstructorElement get definingConstructor {
|
||||
return _unsupported('definingConstructor');
|
||||
String name =
|
||||
_decoder.getString(Key.DEFINING_CONSTRUCTOR, isOptional: true);
|
||||
if (name != null) {
|
||||
return enclosingClass.superclass.lookupConstructor(name);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
ConstructorElement get effectiveTarget {
|
||||
return _unsupported('effectiveTarget');
|
||||
if (_effectiveTarget == null) {
|
||||
_effectiveTarget =
|
||||
_decoder.getElement(Key.EFFECTIVE_TARGET, isOptional: true);
|
||||
if (_effectiveTarget == null) {
|
||||
_effectiveTarget = this;
|
||||
}
|
||||
}
|
||||
return _effectiveTarget;
|
||||
}
|
||||
|
||||
@override
|
||||
ConstructorElement get immediateRedirectionTarget {
|
||||
return _unsupported('immediateRedirectionTarget');
|
||||
}
|
||||
ConstructorElement get immediateRedirectionTarget => null;
|
||||
|
||||
@override
|
||||
bool get isEffectiveTargetMalformed {
|
||||
return _unsupported('isEffectiveTargetMalformed');
|
||||
}
|
||||
|
||||
@override
|
||||
bool get isRedirectingFactory => _unsupported('isRedirectingFactory');
|
||||
|
||||
@override
|
||||
bool get isRedirectingGenerative => _unsupported('isRedirectingGenerative');
|
||||
|
||||
@override
|
||||
bool get isCyclicRedirection => _unsupported('isCyclicRedirection');
|
||||
|
||||
@override
|
||||
PrefixElement get redirectionDeferredPrefix {
|
||||
return _unsupported('redirectionDeferredPrefix');
|
||||
}
|
||||
bool get isRedirectingFactory => false;
|
||||
|
||||
@override
|
||||
bool get isRedirectingGenerative => false;
|
||||
|
||||
@override
|
||||
PrefixElement get redirectionDeferredPrefix => null;
|
||||
|
||||
@override
|
||||
InterfaceType computeEffectiveTargetType(InterfaceType newType) => newType;
|
||||
}
|
||||
|
||||
class GenerativeConstructorElementZ extends ConstructorElementZ {
|
||||
@@ -1149,8 +1157,7 @@ class GenerativeConstructorElementZ extends ConstructorElementZ {
|
||||
ElementKind get kind => ElementKind.GENERATIVE_CONSTRUCTOR;
|
||||
|
||||
@override
|
||||
bool get isEffectiveTargetMalformed =>
|
||||
_unsupported('isEffectiveTargetMalformed');
|
||||
bool get isRedirectingGenerative => _decoder.getBool(Key.IS_REDIRECTING);
|
||||
}
|
||||
|
||||
class FactoryConstructorElementZ extends ConstructorElementZ {
|
||||
@@ -1158,10 +1165,66 @@ class FactoryConstructorElementZ extends ConstructorElementZ {
|
||||
|
||||
@override
|
||||
ElementKind get kind => ElementKind.FACTORY_CONSTRUCTOR;
|
||||
}
|
||||
|
||||
class RedirectingFactoryConstructorElementZ extends ConstructorElementZ {
|
||||
InterfaceType _effectiveTargetType;
|
||||
ConstructorElement _immediateRedirectionTarget;
|
||||
PrefixElement _redirectionDeferredPrefix;
|
||||
|
||||
RedirectingFactoryConstructorElementZ(ObjectDecoder decoder) : super(decoder);
|
||||
|
||||
@override
|
||||
bool get isEffectiveTargetMalformed =>
|
||||
_unsupported('isEffectiveTargetMalformed');
|
||||
ElementKind get kind => ElementKind.FACTORY_CONSTRUCTOR;
|
||||
|
||||
@override
|
||||
bool get isRedirectingFactory => true;
|
||||
|
||||
void _ensureEffectiveTarget() {
|
||||
if (_effectiveTarget == null) {
|
||||
_effectiveTarget =
|
||||
_decoder.getElement(Key.EFFECTIVE_TARGET, isOptional: true);
|
||||
if (_effectiveTarget == null) {
|
||||
_effectiveTarget = this;
|
||||
_effectiveTargetType = enclosingClass.thisType;
|
||||
} else {
|
||||
_effectiveTargetType = _decoder.getType(Key.EFFECTIVE_TARGET_TYPE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
ConstructorElement get effectiveTarget {
|
||||
_ensureEffectiveTarget();
|
||||
return _effectiveTarget;
|
||||
}
|
||||
|
||||
@override
|
||||
InterfaceType computeEffectiveTargetType(InterfaceType newType) {
|
||||
_ensureEffectiveTarget();
|
||||
return _effectiveTargetType.substByContext(newType);
|
||||
}
|
||||
|
||||
void _ensureRedirection() {
|
||||
if (_immediateRedirectionTarget == null) {
|
||||
_immediateRedirectionTarget =
|
||||
_decoder.getElement(Key.IMMEDIATE_REDIRECTION_TARGET);
|
||||
_redirectionDeferredPrefix =
|
||||
_decoder.getElement(Key.PREFIX, isOptional: true);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
ConstructorElement get immediateRedirectionTarget {
|
||||
_ensureRedirection();
|
||||
return _immediateRedirectionTarget;
|
||||
}
|
||||
|
||||
@override
|
||||
PrefixElement get redirectionDeferredPrefix {
|
||||
_ensureRedirection();
|
||||
return _redirectionDeferredPrefix;
|
||||
}
|
||||
}
|
||||
|
||||
class ForwardingConstructorElementZ extends ElementZ
|
||||
|
||||
@@ -560,6 +560,24 @@ class ElementPropertyEquivalence extends BaseElementVisitor<dynamic, Element> {
|
||||
element1.constantConstructor,
|
||||
element2.constantConstructor);
|
||||
}
|
||||
check(element1, element2, 'isRedirectingGenerative',
|
||||
element1.isRedirectingGenerative, element2.isRedirectingGenerative);
|
||||
check(element1, element2, 'isRedirectingFactory',
|
||||
element1.isRedirectingFactory, element2.isRedirectingFactory);
|
||||
checkElementIdentities(element1, element2, 'effectiveTarget',
|
||||
element1.effectiveTarget, element2.effectiveTarget);
|
||||
checkElementIdentities(element1, element2, 'definingConstructor',
|
||||
element1.definingConstructor, element2.definingConstructor);
|
||||
check(
|
||||
element1, element2, 'effectiveTargetType',
|
||||
element1.computeEffectiveTargetType(element1.enclosingClass.thisType),
|
||||
element2.computeEffectiveTargetType(element2.enclosingClass.thisType),
|
||||
areTypesEquivalent);
|
||||
checkElementIdentities(element1, element2, 'immediateRedirectionTarget',
|
||||
element1.immediateRedirectionTarget,
|
||||
element2.immediateRedirectionTarget);
|
||||
checkElementIdentities(element1, element2, 'redirectionDeferredPrefix',
|
||||
element1.redirectionDeferredPrefix, element2.redirectionDeferredPrefix);
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
Reference in New Issue
Block a user