Chromium Code Reviews| 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; |
|
Siggi Cherem (dart-lang)
2016/03/18 20:23:13
sugar:
get mixinType => _mixinType ??= _decoder
Johnni Winther
2016/03/29 08:28:53
Done.
|
| } |
| +} |
| + |
| + |
| +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, |