Serialize more properties of ConstructorElement.

Review URL: https://codereview.chromium.org/1924053003 .
This commit is contained in:
Johnni Winther
2016-04-29 10:00:53 +02:00
parent 664f8e1e03
commit 4c563fecbf
4 changed files with 145 additions and 25 deletions
@@ -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');
+86 -23
View File
@@ -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