| Index: pkg/compiler/lib/src/serialization/modelz.dart
|
| diff --git a/pkg/compiler/lib/src/serialization/modelz.dart b/pkg/compiler/lib/src/serialization/modelz.dart
|
| index 9b825cea0b0c0499ba84acec39bfb42bd9fd80c4..264b2f88b56f84acc99de99ff0646fae58d0062c 100644
|
| --- a/pkg/compiler/lib/src/serialization/modelz.dart
|
| +++ b/pkg/compiler/lib/src/serialization/modelz.dart
|
| @@ -75,11 +75,6 @@ abstract class ElementZ extends Element with ElementCommon {
|
| Scope buildScope() => _unsupported('analyzableElement');
|
|
|
| @override
|
| - CompilationUnitElement get compilationUnit {
|
| - return _unsupported('compilationUnit');
|
| - }
|
| -
|
| - @override
|
| ClassElement get enclosingClass => null;
|
|
|
| @override
|
| @@ -333,6 +328,11 @@ class AbstractFieldElementZ extends ElementZ implements AbstractFieldElement {
|
| LibraryElement get library => _canonicalElement.library;
|
|
|
| @override
|
| + CompilationUnitElement get compilationUnit {
|
| + return _canonicalElement.compilationUnit;
|
| + }
|
| +
|
| + @override
|
| Element get enclosingElement => _canonicalElement.enclosingElement;
|
|
|
| @override
|
| @@ -376,6 +376,9 @@ class LibraryElementZ extends DeserializedElementZ
|
| LibraryElement get library => this;
|
|
|
| @override
|
| + CompilationUnitElement get compilationUnit => entryCompilationUnit;
|
| +
|
| + @override
|
| Uri get canonicalUri {
|
| if (_canonicalUri == null) {
|
| _canonicalUri = _decoder.getUri(Key.CANONICAL_URI);
|
| @@ -734,6 +737,73 @@ abstract class FunctionTypedElementMixin
|
| }
|
| }
|
|
|
| +abstract class ClassElementMixin implements ElementZ, ClassElement {
|
| +
|
| + InterfaceType _createType(List<DartType> typeArguments) {
|
| + return new InterfaceType(this, typeArguments);
|
| + }
|
| +
|
| + @override
|
| + ElementKind get kind => ElementKind.CLASS;
|
| +
|
| + @override
|
| + void addBackendMember(Element element) => _unsupported('addBackendMember');
|
| +
|
| + @override
|
| + void forEachBackendMember(void f(Element member)) {
|
| + _unsupported('forEachBackendMember');
|
| + }
|
| +
|
| + @override
|
| + bool get hasBackendMembers => _unsupported('hasBackendMembers');
|
| +
|
| + @override
|
| + bool get hasConstructor => _unsupported('hasConstructor');
|
| +
|
| + @override
|
| + bool hasFieldShadowedBy(Element fieldMember) => _unsupported('');
|
| +
|
| + @override
|
| + bool get hasIncompleteHierarchy => _unsupported('hasIncompleteHierarchy');
|
| +
|
| + @override
|
| + bool get hasLocalScopeMembers => _unsupported('hasLocalScopeMembers');
|
| +
|
| + @override
|
| + bool implementsFunction(CoreClasses coreClasses) {
|
| + return _unsupported('implementsFunction');
|
| + }
|
| +
|
| + @override
|
| + bool get isEnumClass => false;
|
| +
|
| + @override
|
| + Element lookupBackendMember(String memberName) {
|
| + return _unsupported('lookupBackendMember');
|
| + }
|
| +
|
| + @override
|
| + ConstructorElement lookupDefaultConstructor() {
|
| + ConstructorElement constructor = lookupConstructor("");
|
| + if (constructor != null && constructor.parameters.isEmpty) {
|
| + return constructor;
|
| + }
|
| + return null;
|
| + }
|
| +
|
| + @override
|
| + void reverseBackendMembers() => _unsupported('reverseBackendMembers');
|
| +
|
| + @override
|
| + ClassElement get superclass => supertype != null ? supertype.element : null;
|
| +
|
| + @override
|
| + void ensureResolved(Resolution resolution) {
|
| + resolution.registerClass(this);
|
| + }
|
| +
|
| +}
|
| +
|
| class ClassElementZ extends DeserializedElementZ
|
| with AnalyzableElementMixin,
|
| AstElementMixin,
|
| @@ -741,7 +811,8 @@ class ClassElementZ extends DeserializedElementZ
|
| class_members.ClassMemberMixin,
|
| ContainerMixin,
|
| LibraryMemberMixin,
|
| - TypeDeclarationMixin<InterfaceType>
|
| + TypeDeclarationMixin<InterfaceType>,
|
| + ClassElementMixin
|
| implements ClassElement {
|
| bool _isObject;
|
| DartType _supertype;
|
| @@ -751,12 +822,38 @@ class ClassElementZ extends DeserializedElementZ
|
| ClassElementZ(ObjectDecoder decoder)
|
| : super(decoder);
|
|
|
| - InterfaceType _createType(List<DartType> typeArguments) {
|
| - return new InterfaceType(this, typeArguments);
|
| + @override
|
| + List<DartType> _getTypeVariables() {
|
| + return _decoder.getTypes(Key.TYPE_VARIABLES, isOptional: true);
|
| }
|
|
|
| - @override
|
| - ElementKind get kind => ElementKind.CLASS;
|
| + void _ensureSuperHierarchy() {
|
| + if (_interfaces == null) {
|
| + InterfaceType supertype =
|
| + _decoder.getType(Key.SUPERTYPE, isOptional: true);
|
| + if (supertype == null) {
|
| + _isObject = true;
|
| + _allSupertypesAndSelf = new OrderedTypeSet.singleton(thisType);
|
| + _interfaces = const Link<DartType>();
|
| + } else {
|
| + _isObject = false;
|
| + _interfaces = toLink(
|
| + _decoder.getTypes(Key.INTERFACES, isOptional: true));
|
| + List<InterfaceType> mixins =
|
| + _decoder.getTypes(Key.MIXINS, isOptional: true);
|
| + for (InterfaceType mixin in mixins) {
|
| + MixinApplicationElement mixinElement =
|
| + new UnnamedMixinApplicationElementZ(this, supertype, mixin);
|
| + supertype = mixinElement.thisType.subst(
|
| + typeVariables, mixinElement.typeVariables);
|
| + }
|
| + _supertype = supertype;
|
| + _allSupertypesAndSelf =
|
| + new OrderedTypeSetBuilder(this)
|
| + .createOrderedTypeSet(_supertype, _interfaces);
|
| + }
|
| + }
|
| + }
|
|
|
| @override
|
| accept(ElementVisitor visitor, arg) {
|
| @@ -765,10 +862,7 @@ class ClassElementZ extends DeserializedElementZ
|
|
|
| @override
|
| DartType get supertype {
|
| - if (_isObject == null) {
|
| - _supertype = _decoder.getType(Key.SUPERTYPE, isOptional: true);
|
| - _isObject = _supertype == null;
|
| - }
|
| + _ensureSuperHierarchy();
|
| return _supertype;
|
| }
|
|
|
| @@ -777,113 +871,159 @@ class ClassElementZ extends DeserializedElementZ
|
|
|
| @override
|
| bool get isObject {
|
| - return supertype == null;
|
| + _ensureSuperHierarchy();
|
| + return _isObject;
|
| }
|
|
|
| @override
|
| - void addBackendMember(Element element) => _unsupported('addBackendMember');
|
| -
|
| - @override
|
| OrderedTypeSet get allSupertypesAndSelf {
|
| - if (_allSupertypesAndSelf == null) {
|
| - ObjectDecoder supertypesDeserializer =
|
| - _decoder.getObject(Key.SUPERTYPES);
|
| - List<int> offsets = supertypesDeserializer.getInts(Key.OFFSETS);
|
| - List<Link<DartType>> levels = new List<Link<DartType>>(offsets.length);
|
| - LinkBuilder<DartType> typesBuilder = new LinkBuilder<DartType>();
|
| - int offset = 0;
|
| - int depth = offsets.length - 1;
|
| - for (DartType type in supertypesDeserializer.getTypes(Key.TYPES)) {
|
| - Link<DartType> link = typesBuilder.addLast(type);
|
| - if (offsets[depth] == offset) {
|
| - levels[depth] = link;
|
| - depth--;
|
| - }
|
| - offset++;
|
| - }
|
| - LinkBuilder<DartType> supertypesBuilder = new LinkBuilder<DartType>();
|
| - for (DartType supertype in
|
| - supertypesDeserializer.getTypes(Key.SUPERTYPES, isOptional: true)) {
|
| - supertypesBuilder.addLast(supertype);
|
| - }
|
| - Link<DartType> types = typesBuilder.toLink();
|
| - Link<DartType> supertypes = supertypesBuilder.toLink();
|
| - _allSupertypesAndSelf = new OrderedTypeSet.internal(
|
| - levels, types, supertypes);
|
| - }
|
| + _ensureSuperHierarchy();
|
| return _allSupertypesAndSelf;
|
| }
|
|
|
| @override
|
| - void forEachBackendMember(void f(Element member)) {
|
| - _unsupported('forEachBackendMember');
|
| + Link<DartType> get interfaces {
|
| + _ensureSuperHierarchy();
|
| + return _interfaces;
|
| }
|
|
|
| @override
|
| - bool get hasBackendMembers => _unsupported('hasBackendMembers');
|
| + bool get isProxy => _decoder.getBool(Key.IS_PROXY);
|
|
|
| @override
|
| - bool get hasConstructor => _unsupported('hasConstructor');
|
| + bool get isUnnamedMixinApplication => false;
|
| +}
|
|
|
| - @override
|
| - bool hasFieldShadowedBy(Element fieldMember) => _unsupported('');
|
| +abstract class MixinApplicationElementMixin
|
| + implements ElementZ, MixinApplicationElement {
|
| + Link<ConstructorElement> _constructors;
|
|
|
| @override
|
| - bool get hasIncompleteHierarchy => _unsupported('hasIncompleteHierarchy');
|
| + bool get isMixinApplication => false;
|
|
|
| @override
|
| - bool get hasLocalScopeMembers => _unsupported('hasLocalScopeMembers');
|
| + ClassElement get mixin => mixinType.element;
|
|
|
| - @override
|
| - bool implementsFunction(CoreClasses coreClasses) {
|
| - return _unsupported('implementsFunction');
|
| + Link<ConstructorElement> get constructors {
|
| + if (_constructors == null) {
|
| + LinkBuilder<ConstructorElement> builder =
|
| + new LinkBuilder<ConstructorElement>();
|
| + for (ConstructorElement definingConstructor in superclass.constructors) {
|
| + if (definingConstructor.isGenerativeConstructor &&
|
| + definingConstructor.memberName.isAccessibleFrom(library)) {
|
| + builder.addLast(
|
| + new ForwardingConstructorElementZ(this, definingConstructor));
|
| + }
|
| + }
|
| + _constructors = builder.toLink();
|
| + }
|
| + return _constructors;
|
| }
|
| +}
|
| +
|
| +
|
| +class NamedMixinApplicationElementZ extends ClassElementZ
|
| + with MixinApplicationElementCommon,
|
| + MixinApplicationElementMixin {
|
| + InterfaceType _mixinType;
|
| +
|
| + NamedMixinApplicationElementZ(ObjectDecoder decoder)
|
| + : super(decoder);
|
|
|
| @override
|
| - Link<DartType> get interfaces {
|
| - if (_interfaces == null) {
|
| - _interfaces = toLink(
|
| - _decoder.getTypes(Key.INTERFACES, isOptional: true));
|
| + InterfaceType get mixinType {
|
| + if (_mixinType == null) {
|
| + _mixinType = _decoder.getType(Key.MIXIN);
|
| }
|
| - return _interfaces;
|
| + return _mixinType;
|
| }
|
| +}
|
| +
|
| +
|
| +class UnnamedMixinApplicationElementZ extends ElementZ
|
| + with ClassElementCommon,
|
| + ClassElementMixin,
|
| + class_members.ClassMemberMixin,
|
| + TypeDeclarationMixin<InterfaceType>,
|
| + AnalyzableElementMixin,
|
| + AstElementMixin,
|
| + MixinApplicationElementCommon,
|
| + MixinApplicationElementMixin {
|
| + final String name;
|
| + final ClassElement _subclass;
|
| + final InterfaceType supertype;
|
| + final Link<DartType> interfaces;
|
| + OrderedTypeSet _allSupertypesAndSelf;
|
| +
|
| + UnnamedMixinApplicationElementZ(
|
| + ClassElement subclass,
|
| + InterfaceType supertype, InterfaceType mixin)
|
| + : this._subclass = subclass,
|
| + this.supertype = supertype,
|
| + this.interfaces = const Link<DartType>().prepend(mixin),
|
| + this.name = "${supertype.name}+${mixin.name}";
|
|
|
| @override
|
| - bool get isEnumClass => false;
|
| + CompilationUnitElement get compilationUnit => _subclass.compilationUnit;
|
|
|
| @override
|
| - bool get isProxy => _decoder.getBool(Key.IS_PROXY);
|
| + bool get isUnnamedMixinApplication => true;
|
|
|
| @override
|
| - bool get isUnnamedMixinApplication {
|
| - return _decoder.getBool(Key.IS_UNNAMED_MIXIN_APPLICATION,
|
| - isOptional: true, defaultValue: false);
|
| + List<DartType> _getTypeVariables() {
|
| + // Create synthetic type variables for the mixin application.
|
| + List<DartType> typeVariables = <DartType>[];
|
| + int index = 0;
|
| + for (TypeVariableType type in _subclass.typeVariables) {
|
| + SyntheticTypeVariableElementZ typeVariableElement =
|
| + new SyntheticTypeVariableElementZ(this, index, type.name);
|
| + TypeVariableType typeVariable = new TypeVariableType(typeVariableElement);
|
| + typeVariables.add(typeVariable);
|
| + index++;
|
| + }
|
| + // Setup bounds on the synthetic type variables.
|
| + for (TypeVariableType type in _subclass.typeVariables) {
|
| + TypeVariableType typeVariable = typeVariables[type.element.index];
|
| + SyntheticTypeVariableElementZ typeVariableElement = typeVariable.element;
|
| + typeVariableElement._type = typeVariable;
|
| + typeVariableElement._bound =
|
| + type.element.bound.subst(typeVariables, _subclass.typeVariables);
|
| + }
|
| + return typeVariables;
|
| }
|
|
|
| @override
|
| - Element lookupBackendMember(String memberName) {
|
| - return _unsupported('lookupBackendMember');
|
| + accept(ElementVisitor visitor, arg) {
|
| + return visitor.visitMixinApplicationElement(this, arg);
|
| }
|
|
|
| @override
|
| - ConstructorElement lookupDefaultConstructor() {
|
| - ConstructorElement constructor = lookupConstructor("");
|
| - if (constructor != null && constructor.parameters.isEmpty) {
|
| - return constructor;
|
| + OrderedTypeSet get allSupertypesAndSelf {
|
| + if (_allSupertypesAndSelf == null) {
|
| + _allSupertypesAndSelf =
|
| + new OrderedTypeSetBuilder(this)
|
| + .createOrderedTypeSet(supertype, interfaces);
|
| }
|
| - return null;
|
| + return _allSupertypesAndSelf;
|
| }
|
|
|
| @override
|
| - void reverseBackendMembers() => _unsupported('reverseBackendMembers');
|
| + Element get enclosingElement => _subclass.enclosingElement;
|
|
|
| @override
|
| - ClassElement get superclass => supertype != null ? supertype.element : null;
|
| + bool get isObject => false;
|
|
|
| @override
|
| - void ensureResolved(Resolution resolution) {
|
| - resolution.registerClass(this);
|
| - }
|
| + bool get isProxy => false;
|
| +
|
| + @override
|
| + LibraryElement get library => enclosingElement.library;
|
| +
|
| + @override
|
| + InterfaceType get mixinType => interfaces.head;
|
| +
|
| + @override
|
| + SourceSpan get sourcePosition => _subclass.sourcePosition;
|
| }
|
|
|
|
|
| @@ -1018,6 +1158,117 @@ class FactoryConstructorElementZ extends ConstructorElementZ {
|
| _unsupported('isEffectiveTargetMalformed');
|
| }
|
|
|
| +class ForwardingConstructorElementZ extends ElementZ
|
| + with AnalyzableElementMixin,
|
| + AstElementMixin
|
| + implements ConstructorElement {
|
| + final MixinApplicationElement enclosingClass;
|
| + final ConstructorElement definingConstructor;
|
| +
|
| + ForwardingConstructorElementZ(this.enclosingClass, this.definingConstructor);
|
| +
|
| + @override
|
| + CompilationUnitElement get compilationUnit => enclosingClass.compilationUnit;
|
| +
|
| + @override
|
| + accept(ElementVisitor visitor, arg) {
|
| + return visitor.visitConstructorElement(this, arg);
|
| + }
|
| +
|
| + @override
|
| + AsyncMarker get asyncMarker => AsyncMarker.SYNC;
|
| +
|
| + @override
|
| + InterfaceType computeEffectiveTargetType(InterfaceType newType) {
|
| + return enclosingClass.thisType;
|
| + }
|
| +
|
| + @override
|
| + DartType computeType(Resolution resolution) => type;
|
| +
|
| + @override
|
| + bool get isConst => false;
|
| +
|
| + @override
|
| + ConstantConstructor get constantConstructor => null;
|
| +
|
| + @override
|
| + ConstructorElement get effectiveTarget => this;
|
| +
|
| + @override
|
| + Element get enclosingElement => enclosingClass;
|
| +
|
| + @override
|
| + FunctionSignature get functionSignature {
|
| + return _unsupported('functionSignature');
|
| + }
|
| +
|
| + @override
|
| + bool get hasFunctionSignature {
|
| + return _unsupported('hasFunctionSignature');
|
| + }
|
| +
|
| + @override
|
| + ConstructorElement get immediateRedirectionTarget => null;
|
| +
|
| + @override
|
| + bool get isCyclicRedirection => false;
|
| +
|
| + @override
|
| + bool get isEffectiveTargetMalformed => false;
|
| +
|
| + @override
|
| + bool get isExternal => false;
|
| +
|
| + @override
|
| + bool get isFromEnvironmentConstructor => false;
|
| +
|
| + @override
|
| + bool get isRedirectingFactory => false;
|
| +
|
| + @override
|
| + bool get isRedirectingGenerative => false;
|
| +
|
| + @override
|
| + ElementKind get kind => ElementKind.GENERATIVE_CONSTRUCTOR;
|
| +
|
| + @override
|
| + LibraryElement get library => enclosingClass.library;
|
| +
|
| + @override
|
| + MemberElement get memberContext => this;
|
| +
|
| + @override
|
| + Name get memberName => definingConstructor.memberName;
|
| +
|
| + @override
|
| + String get name => definingConstructor.name;
|
| +
|
| + @override
|
| + List<FunctionElement> get nestedClosures => const <FunctionElement>[];
|
| +
|
| + @override
|
| + List<ParameterElement> get parameters {
|
| + // TODO(johnniwinther): We need to create synthetic parameters that
|
| + // substitute type variables.
|
| + return definingConstructor.parameters;
|
| + }
|
| +
|
| + // TODO: implement redirectionDeferredPrefix
|
| + @override
|
| + PrefixElement get redirectionDeferredPrefix => null;
|
| +
|
| + @override
|
| + SourceSpan get sourcePosition => enclosingClass.sourcePosition;
|
| +
|
| + @override
|
| + FunctionType get type {
|
| + // TODO(johnniwinther): Ensure that the function type substitutes type
|
| + // variables correctly.
|
| + return definingConstructor.type;
|
| + }
|
| +}
|
| +
|
| abstract class MemberElementMixin
|
| implements DeserializedElementZ, MemberElement {
|
|
|
| @@ -1260,7 +1511,7 @@ class InstanceSetterElementZ extends SetterElementZ
|
| }
|
|
|
| abstract class TypeDeclarationMixin<T extends GenericType>
|
| - implements DeserializedElementZ, TypeDeclarationElement {
|
| + implements ElementZ, TypeDeclarationElement {
|
| List<DartType> _typeVariables;
|
| T _rawType;
|
| T _thisType;
|
| @@ -1273,10 +1524,11 @@ abstract class TypeDeclarationMixin<T extends GenericType>
|
| return _memberName;
|
| }
|
|
|
| + List<DartType> _getTypeVariables();
|
| +
|
| void _ensureTypes() {
|
| if (_typeVariables == null) {
|
| - _typeVariables = _decoder.getTypes(
|
| - Key.TYPE_VARIABLES, isOptional: true);
|
| + _typeVariables = _getTypeVariables();
|
| _rawType = _createType(new List<DartType>.filled(
|
| _typeVariables.length, const DynamicType()));
|
| _thisType = _createType(_typeVariables);
|
| @@ -1327,6 +1579,11 @@ class TypedefElementZ extends DeserializedElementZ
|
| }
|
|
|
| @override
|
| + List<DartType> _getTypeVariables() {
|
| + return _decoder.getTypes(Key.TYPE_VARIABLES, isOptional: true);
|
| + }
|
| +
|
| + @override
|
| ElementKind get kind => ElementKind.TYPEDEF;
|
|
|
| @override
|
| @@ -1411,6 +1668,68 @@ class TypeVariableElementZ extends DeserializedElementZ
|
| LibraryElement get library => typeDeclaration.library;
|
| }
|
|
|
| +class SyntheticTypeVariableElementZ extends ElementZ
|
| + with AnalyzableElementMixin,
|
| + AstElementMixin
|
| + implements TypeVariableElement {
|
| + final TypeDeclarationElement typeDeclaration;
|
| + final int index;
|
| + final String name;
|
| + TypeVariableType _type;
|
| + DartType _bound;
|
| + Name _memberName;
|
| +
|
| + SyntheticTypeVariableElementZ(this.typeDeclaration, this.index, this.name);
|
| +
|
| + Name get memberName {
|
| + if (_memberName == null) {
|
| + _memberName = new Name(name, library);
|
| + }
|
| + return _memberName;
|
| + }
|
| +
|
| + @override
|
| + ElementKind get kind => ElementKind.TYPE_VARIABLE;
|
| +
|
| + @override
|
| + accept(ElementVisitor visitor, arg) {
|
| + return visitor.visitTypeVariableElement(this, arg);
|
| + }
|
| +
|
| + @override
|
| + CompilationUnitElement get compilationUnit {
|
| + return typeDeclaration.compilationUnit;
|
| + }
|
| +
|
| + @override
|
| + TypeVariableType get type {
|
| + assert(invariant(this, _type != null,
|
| + message: "Type variable type has not been set on $this."));
|
| + return _type;
|
| + }
|
| +
|
| + @override
|
| + TypeVariableType computeType(Resolution resolution) => type;
|
| +
|
| + @override
|
| + Element get enclosingElement => typeDeclaration;
|
| +
|
| + @override
|
| + Element get enclosingClass => typeDeclaration;
|
| +
|
| + DartType get bound {
|
| + assert(invariant(this, _bound != null,
|
| + message: "Type variable bound has not been set on $this."));
|
| + return _bound;
|
| + }
|
| +
|
| + @override
|
| + LibraryElement get library => typeDeclaration.library;
|
| +
|
| + @override
|
| + SourceSpan get sourcePosition => typeDeclaration.sourcePosition;
|
| +}
|
| +
|
| class ParameterElementZ extends DeserializedElementZ
|
| with AnalyzableElementMixin,
|
| AstElementMixin,
|
|
|