| Index: pkg/analyzer/lib/src/summary/link.dart
|
| diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/analyzer/lib/src/summary/link.dart
|
| index c3c63e33a8fe36e91efca11e9c80d902e50a2055..ad9fb88861e6a1a1bd705dd7a89b88da335505b2 100644
|
| --- a/pkg/analyzer/lib/src/summary/link.dart
|
| +++ b/pkg/analyzer/lib/src/summary/link.dart
|
| @@ -141,6 +141,9 @@ EntityRefBuilder _createLinkedType(
|
| throw new UnimplementedError();
|
| }
|
| return result;
|
| + } else if (type is VoidTypeImpl) {
|
| + result.reference = compilationUnit.addReference(0, 'void', 0, 0);
|
| + return result;
|
| }
|
| throw new UnimplementedError('${type.runtimeType}');
|
| }
|
| @@ -247,7 +250,7 @@ abstract class ClassElementForLink
|
| * linking.
|
| */
|
| class ClassElementForLink_Class extends ClassElementForLink
|
| - implements TypeParameterContext {
|
| + with TypeParameterizedElementForLink {
|
| /**
|
| * The unlinked representation of the class in the summary.
|
| */
|
| @@ -259,20 +262,45 @@ class ClassElementForLink_Class extends ClassElementForLink
|
| List<FieldElementForLink_ClassField> _fields;
|
| InterfaceType _supertype;
|
| InterfaceType _type;
|
| - List<TypeParameterElementForLink> _typeParameters;
|
| - List<TypeParameterType> _typeParameterTypes;
|
| List<MethodElementForLink> _methods;
|
| List<InterfaceType> _mixins;
|
| List<InterfaceType> _interfaces;
|
| + List<PropertyAccessorElementForLink> _accessors;
|
|
|
| ClassElementForLink_Class(
|
| CompilationUnitElementForLink enclosingElement, this._unlinkedClass)
|
| : super(enclosingElement);
|
|
|
| @override
|
| - List<PropertyAccessorElement> get accessors {
|
| - // TODO(paulberry): implement
|
| - return const [];
|
| + List<PropertyAccessorElementForLink> get accessors {
|
| + if (_accessors == null) {
|
| + _accessors = <PropertyAccessorElementForLink>[];
|
| + Map<String, SyntheticVariableElementForLink> syntheticVariables =
|
| + <String, SyntheticVariableElementForLink>{};
|
| + for (UnlinkedExecutable unlinkedExecutable
|
| + in _unlinkedClass.executables) {
|
| + if (unlinkedExecutable.kind == UnlinkedExecutableKind.getter ||
|
| + unlinkedExecutable.kind == UnlinkedExecutableKind.setter) {
|
| + String name = unlinkedExecutable.name;
|
| + if (unlinkedExecutable.kind == UnlinkedExecutableKind.setter) {
|
| + assert(name.endsWith('='));
|
| + name = name.substring(0, name.length - 1);
|
| + }
|
| + SyntheticVariableElementForLink syntheticVariable = syntheticVariables
|
| + .putIfAbsent(name, () => new SyntheticVariableElementForLink());
|
| + PropertyAccessorElementForLink accessor =
|
| + new PropertyAccessorElementForLink(
|
| + this, unlinkedExecutable, syntheticVariable);
|
| + _accessors.add(accessor);
|
| + if (unlinkedExecutable.kind == UnlinkedExecutableKind.getter) {
|
| + syntheticVariable._getter = accessor;
|
| + } else {
|
| + syntheticVariable._setter = accessor;
|
| + }
|
| + }
|
| + }
|
| + }
|
| + return _accessors;
|
| }
|
|
|
| @override
|
| @@ -294,6 +322,9 @@ class ClassElementForLink_Class extends ClassElementForLink
|
| String get displayName => _unlinkedClass.name;
|
|
|
| @override
|
| + TypeParameterContext get enclosingTypeParameterContext => null;
|
| +
|
| + @override
|
| List<FieldElementForLink_ClassField> get fields {
|
| if (_fields == null) {
|
| _fields = <FieldElementForLink_ClassField>[];
|
| @@ -345,29 +376,6 @@ class ClassElementForLink_Class extends ClassElementForLink
|
| }
|
|
|
| @override
|
| - List<TypeParameterElementForLink> get typeParameters {
|
| - if (_typeParameters == null) {
|
| - _typeParameters = _unlinkedClass.typeParameters
|
| - .map((UnlinkedTypeParam p) => new TypeParameterElementForLink(p))
|
| - .toList();
|
| - }
|
| - return _typeParameters;
|
| - }
|
| -
|
| - /**
|
| - * Get a list of [TypeParameterType] objects corresponding to the
|
| - * class's type parameters.
|
| - */
|
| - List<TypeParameterType> get typeParameterTypes {
|
| - if (_typeParameterTypes == null) {
|
| - _typeParameterTypes = typeParameters
|
| - .map((TypeParameterElementForLink e) => new TypeParameterTypeImpl(e))
|
| - .toList();
|
| - }
|
| - return _typeParameterTypes;
|
| - }
|
| -
|
| - @override
|
| ConstructorElementForLink get unnamedConstructor {
|
| if (!_unnamedConstructorComputed) {
|
| for (ConstructorElementForLink constructor in constructors) {
|
| @@ -382,6 +390,10 @@ class ClassElementForLink_Class extends ClassElementForLink
|
| }
|
|
|
| @override
|
| + List<UnlinkedTypeParam> get _unlinkedTypeParams =>
|
| + _unlinkedClass.typeParameters;
|
| +
|
| + @override
|
| DartType buildType(
|
| DartType getTypeArgument(int i), List<int> implicitFunctionTypeIndices) {
|
| int numTypeParameters = _unlinkedClass.typeParameters.length;
|
| @@ -401,12 +413,6 @@ class ClassElementForLink_Class extends ClassElementForLink
|
| }
|
|
|
| @override
|
| - TypeParameterType getTypeParameterType(int index) {
|
| - List<TypeParameterType> types = typeParameterTypes;
|
| - return types[types.length - index];
|
| - }
|
| -
|
| - @override
|
| void link(CompilationUnitElementInBuildUnit compilationUnit) {
|
| for (ConstructorElementForLink constructorElement in constructors) {
|
| constructorElement.link(compilationUnit);
|
| @@ -414,6 +420,12 @@ class ClassElementForLink_Class extends ClassElementForLink
|
| for (MethodElementForLink methodElement in methods) {
|
| methodElement.link(compilationUnit);
|
| }
|
| + for (PropertyAccessorElementForLink propertyAccessorElement in accessors) {
|
| + propertyAccessorElement.link(compilationUnit);
|
| + }
|
| + for (FieldElementForLink_ClassField fieldElement in fields) {
|
| + fieldElement.link(compilationUnit);
|
| + }
|
| }
|
|
|
| @override
|
| @@ -422,6 +434,12 @@ class ClassElementForLink_Class extends ClassElementForLink
|
| for (MethodElementForLink methodElement in methods) {
|
| methodElement.unlink();
|
| }
|
| + for (PropertyAccessorElementForLink propertyAccessorElement in accessors) {
|
| + propertyAccessorElement.unlink();
|
| + }
|
| + for (FieldElementForLink_ClassField fieldElement in fields) {
|
| + fieldElement.unlink();
|
| + }
|
| }
|
|
|
| /**
|
| @@ -1260,6 +1278,129 @@ abstract class DependencyWalker<NodeType extends Node<NodeType>> {
|
| }
|
|
|
| /**
|
| + * Base class for executable elements resynthesized from a summary during
|
| + * linking.
|
| + */
|
| +abstract class ExecutableElementForLink extends Object
|
| + with TypeParameterizedElementForLink
|
| + implements ExecutableElementImpl, TypeParameterContext {
|
| + /**
|
| + * The unlinked representation of the method in the summary.
|
| + */
|
| + final UnlinkedExecutable _unlinkedExecutable;
|
| +
|
| + DartType _declaredReturnType;
|
| + DartType _inferredReturnType;
|
| + FunctionTypeImpl _type;
|
| + List<TypeParameterElementForLink> _typeParameters;
|
| + List<ParameterElementForLink> _parameters;
|
| +
|
| + /**
|
| + * TODO(paulberry): this won't always be a class element.
|
| + */
|
| + @override
|
| + final ClassElementForLink_Class enclosingElement;
|
| +
|
| + ExecutableElementForLink(this.enclosingElement, this._unlinkedExecutable);
|
| +
|
| + @override
|
| + TypeParameterContext get enclosingTypeParameterContext => enclosingElement;
|
| +
|
| + @override
|
| + bool get hasImplicitReturnType => _unlinkedExecutable.returnType == null;
|
| +
|
| + @override
|
| + bool get isStatic => _unlinkedExecutable.isStatic;
|
| +
|
| + @override
|
| + bool get isSynthetic => false;
|
| +
|
| + @override
|
| + LibraryElementForLink get library => enclosingElement.library;
|
| +
|
| + @override
|
| + String get name => _unlinkedExecutable.name;
|
| +
|
| + @override
|
| + List<ParameterElementForLink> get parameters {
|
| + if (_parameters == null) {
|
| + _parameters = <ParameterElementForLink>[];
|
| + for (UnlinkedParam unlinkedParam in _unlinkedExecutable.parameters) {
|
| + _parameters.add(new ParameterElementForLink(
|
| + unlinkedParam, this, enclosingElement.enclosingElement));
|
| + }
|
| + }
|
| + return _parameters;
|
| + }
|
| +
|
| + @override
|
| + DartType get returnType {
|
| + if (_inferredReturnType != null) {
|
| + return _inferredReturnType;
|
| + } else if (_declaredReturnType == null) {
|
| + if (_unlinkedExecutable.returnType == null) {
|
| + // In strong mode, setters without an explicit return type are
|
| + // considered to return `void`.
|
| + if (_unlinkedExecutable.kind == UnlinkedExecutableKind.setter &&
|
| + library._linker.strongMode) {
|
| + _declaredReturnType = VoidTypeImpl.instance;
|
| + } else {
|
| + _declaredReturnType = DynamicTypeImpl.instance;
|
| + }
|
| + } else {
|
| + _declaredReturnType = enclosingElement.enclosingElement
|
| + ._resolveTypeRef(_unlinkedExecutable.returnType, this);
|
| + }
|
| + }
|
| + return _declaredReturnType;
|
| + }
|
| +
|
| + @override
|
| + void set returnType(DartType inferredType) {
|
| + assert(_inferredReturnType == null);
|
| + _inferredReturnType = inferredType;
|
| + }
|
| +
|
| + @override
|
| + FunctionTypeImpl get type => _type ??= new FunctionTypeImpl(this);
|
| +
|
| + @override
|
| + List<TypeParameterElementForLink> get typeParameters {
|
| + if (_typeParameters == null) {
|
| + _typeParameters = _unlinkedExecutable.typeParameters
|
| + .map((UnlinkedTypeParam p) => new TypeParameterElementForLink(p))
|
| + .toList();
|
| + }
|
| + return _typeParameters;
|
| + }
|
| +
|
| + @override
|
| + bool isAccessibleIn(LibraryElement library) =>
|
| + !Identifier.isPrivateName(name) || identical(this.library, library);
|
| +
|
| + /**
|
| + * Store the results of type inference for this method in [compilationUnit].
|
| + */
|
| + void link(CompilationUnitElementInBuildUnit compilationUnit) {
|
| + compilationUnit._storeLinkedType(
|
| + _unlinkedExecutable.inferredReturnTypeSlot, returnType);
|
| + for (ParameterElementForLink parameterElement in parameters) {
|
| + parameterElement.link(compilationUnit);
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Throw away any information produced by type inference.
|
| + */
|
| + void unlink() {
|
| + for (ParameterElementForLink parameterElement in parameters) {
|
| + parameterElement.unlink();
|
| + }
|
| + _inferredReturnType = null;
|
| + }
|
| +}
|
| +
|
| +/**
|
| * Element representing a field resynthesized from a summary during
|
| * linking.
|
| */
|
| @@ -1274,6 +1415,9 @@ class FieldElementForLink_ClassField extends VariableElementForLink
|
| @override
|
| final ClassElementForLink_Class enclosingElement;
|
|
|
| + DartType _inferredType;
|
| + DartType _declaredType;
|
| +
|
| FieldElementForLink_ClassField(ClassElementForLink_Class enclosingElement,
|
| UnlinkedVariable unlinkedVariable)
|
| : enclosingElement = enclosingElement,
|
| @@ -1281,6 +1425,43 @@ class FieldElementForLink_ClassField extends VariableElementForLink
|
|
|
| @override
|
| bool get isStatic => unlinkedVariable.isStatic;
|
| +
|
| + @override
|
| + DartType get type {
|
| + if (_inferredType != null) {
|
| + return _inferredType;
|
| + } else if (_declaredType == null) {
|
| + if (unlinkedVariable.type == null) {
|
| + _declaredType = DynamicTypeImpl.instance;
|
| + } else {
|
| + _declaredType = compilationUnit._resolveTypeRef(
|
| + unlinkedVariable.type, enclosingElement);
|
| + }
|
| + }
|
| + return _declaredType;
|
| + }
|
| +
|
| + @override
|
| + void set type(DartType inferredType) {
|
| + assert(_inferredType == null);
|
| + _inferredType = inferredType;
|
| + }
|
| +
|
| + /**
|
| + * Store the results of type inference for this field in
|
| + * [compilationUnit].
|
| + */
|
| + void link(CompilationUnitElementInBuildUnit compilationUnit) {
|
| + compilationUnit._storeLinkedType(
|
| + unlinkedVariable.inferredTypeSlot, _inferredType);
|
| + }
|
| +
|
| + /**
|
| + * Throw away any information produced by type inference.
|
| + */
|
| + void unlink() {
|
| + _inferredType = null;
|
| + }
|
| }
|
|
|
| /**
|
| @@ -1533,120 +1714,17 @@ class LibraryElementInDependency
|
| /**
|
| * Element representing a method resynthesized from a summary during linking.
|
| */
|
| -class MethodElementForLink implements MethodElementImpl, TypeParameterContext {
|
| - /**
|
| - * The unlinked representation of the method in the summary.
|
| - */
|
| - final UnlinkedExecutable _unlinkedExecutable;
|
| -
|
| - DartType _declaredReturnType;
|
| - DartType _inferredReturnType;
|
| - FunctionTypeImpl _type;
|
| - List<TypeParameterElementForLink> _typeParameters;
|
| - List<ParameterElementForLink> _parameters;
|
| -
|
| - @override
|
| - final ClassElementForLink_Class enclosingElement;
|
| -
|
| - MethodElementForLink(this.enclosingElement, this._unlinkedExecutable);
|
| -
|
| - @override
|
| - bool get hasImplicitReturnType => _unlinkedExecutable.returnType == null;
|
| -
|
| - @override
|
| - bool get isStatic => _unlinkedExecutable.isStatic;
|
| -
|
| - @override
|
| - bool get isSynthetic => false;
|
| +class MethodElementForLink extends ExecutableElementForLink
|
| + implements MethodElementImpl {
|
| + MethodElementForLink(ClassElementForLink_Class enclosingElement,
|
| + UnlinkedExecutable unlinkedExecutable)
|
| + : super(enclosingElement, unlinkedExecutable);
|
|
|
| @override
|
| ElementKind get kind => ElementKind.METHOD;
|
|
|
| @override
|
| - LibraryElementForLink get library => enclosingElement.library;
|
| -
|
| - @override
|
| - String get name => _unlinkedExecutable.name;
|
| -
|
| - @override
|
| - List<ParameterElementForLink> get parameters {
|
| - if (_parameters == null) {
|
| - _parameters = <ParameterElementForLink>[];
|
| - for (UnlinkedParam unlinkedParam in _unlinkedExecutable.parameters) {
|
| - _parameters.add(new ParameterElementForLink(
|
| - unlinkedParam, this, enclosingElement.enclosingElement));
|
| - }
|
| - }
|
| - return _parameters;
|
| - }
|
| -
|
| - @override
|
| - DartType get returnType {
|
| - if (_inferredReturnType != null) {
|
| - return _inferredReturnType;
|
| - } else if (_declaredReturnType == null) {
|
| - if (_unlinkedExecutable.returnType == null) {
|
| - _declaredReturnType = DynamicTypeImpl.instance;
|
| - } else {
|
| - _declaredReturnType = enclosingElement.enclosingElement
|
| - ._resolveTypeRef(_unlinkedExecutable.returnType, this);
|
| - }
|
| - }
|
| - return _declaredReturnType;
|
| - }
|
| -
|
| - @override
|
| - void set returnType(DartType inferredType) {
|
| - assert(_inferredReturnType == null);
|
| - _inferredReturnType = inferredType;
|
| - }
|
| -
|
| - @override
|
| - FunctionTypeImpl get type => _type ??= new FunctionTypeImpl(this);
|
| -
|
| - @override
|
| - List<TypeParameterElementForLink> get typeParameters {
|
| - if (_typeParameters == null) {
|
| - _typeParameters = _unlinkedExecutable.typeParameters
|
| - .map((UnlinkedTypeParam p) => new TypeParameterElementForLink(p))
|
| - .toList();
|
| - }
|
| - return _typeParameters;
|
| - }
|
| -
|
| - @override
|
| - TypeParameterType getTypeParameterType(int index) {
|
| - // TODO(paulberry): implement.
|
| - throw new UnimplementedError();
|
| - }
|
| -
|
| - @override
|
| - bool isAccessibleIn(LibraryElement library) =>
|
| - !Identifier.isPrivateName(name) || identical(this.library, library);
|
| -
|
| - /**
|
| - * Store the results of type inference for this method in [compilationUnit].
|
| - */
|
| - void link(CompilationUnitElementInBuildUnit compilationUnit) {
|
| - compilationUnit._storeLinkedType(
|
| - _unlinkedExecutable.inferredReturnTypeSlot, _inferredReturnType);
|
| - for (ParameterElementForLink parameterElement in parameters) {
|
| - parameterElement.link(compilationUnit);
|
| - }
|
| - }
|
| -
|
| - @override
|
| noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
|
| -
|
| - /**
|
| - * Throw away any information produced by type inference.
|
| - */
|
| - void unlink() {
|
| - for (ParameterElementForLink parameterElement in parameters) {
|
| - parameterElement.unlink();
|
| - }
|
| - _inferredReturnType = null;
|
| - }
|
| }
|
|
|
| /**
|
| @@ -1815,6 +1893,38 @@ class ParameterElementForLink implements ParameterElementImpl {
|
| }
|
|
|
| /**
|
| + * Element representing a getter or setter resynthesized from a summary during
|
| + * linking.
|
| + */
|
| +class PropertyAccessorElementForLink extends ExecutableElementForLink
|
| + implements PropertyAccessorElementImpl {
|
| + @override
|
| + SyntheticVariableElementForLink variable;
|
| +
|
| + PropertyAccessorElementForLink(ClassElementForLink_Class enclosingElement,
|
| + UnlinkedExecutable unlinkedExecutable, this.variable)
|
| + : super(enclosingElement, unlinkedExecutable);
|
| +
|
| + @override
|
| + PropertyAccessorElementForLink get correspondingGetter => variable.getter;
|
| +
|
| + @override
|
| + bool get isGetter =>
|
| + _unlinkedExecutable.kind == UnlinkedExecutableKind.getter;
|
| +
|
| + @override
|
| + bool get isSetter =>
|
| + _unlinkedExecutable.kind == UnlinkedExecutableKind.setter;
|
| +
|
| + @override
|
| + ElementKind get kind => _unlinkedExecutable.kind ==
|
| + UnlinkedExecutableKind.getter ? ElementKind.GETTER : ElementKind.SETTER;
|
| +
|
| + @override
|
| + noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
|
| +}
|
| +
|
| +/**
|
| * Abstract base class representing an element which can be the target
|
| * of a reference.
|
| */
|
| @@ -1852,6 +1962,27 @@ abstract class ReferenceableElementForLink {
|
| }
|
|
|
| /**
|
| + * Element representing a synthetic variable resynthesized from a summary during
|
| + * linking.
|
| + */
|
| +class SyntheticVariableElementForLink implements PropertyInducingElementImpl {
|
| + PropertyAccessorElementForLink _getter;
|
| + PropertyAccessorElementForLink _setter;
|
| +
|
| + @override
|
| + PropertyAccessorElementForLink get getter => _getter;
|
| +
|
| + @override
|
| + PropertyAccessorElementForLink get setter => _setter;
|
| +
|
| + @override
|
| + void set type(DartType inferredType) {}
|
| +
|
| + @override
|
| + noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
|
| +}
|
| +
|
| +/**
|
| * Element representing a top level variable resynthesized from a
|
| * summary during linking.
|
| */
|
| @@ -1895,6 +2026,63 @@ class TypeParameterElementForLink implements TypeParameterElement {
|
| noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
|
| }
|
|
|
| +/**
|
| + * Mixin representing an element which can have type parameters.
|
| + */
|
| +abstract class TypeParameterizedElementForLink
|
| + implements TypeParameterizedElement, TypeParameterContext {
|
| + List<TypeParameterType> _typeParameterTypes;
|
| + List<TypeParameterElementForLink> _typeParameters;
|
| +
|
| + /**
|
| + * Get the type parameter context enclosing this one, if any.
|
| + */
|
| + TypeParameterContext get enclosingTypeParameterContext;
|
| +
|
| + List<TypeParameterElementForLink> get typeParameters {
|
| + if (_typeParameters == null) {
|
| + _typeParameters = _unlinkedTypeParams
|
| + .map((UnlinkedTypeParam p) => new TypeParameterElementForLink(p))
|
| + .toList();
|
| + }
|
| + return _typeParameters;
|
| + }
|
| +
|
| + /**
|
| + * Get a list of [TypeParameterType] objects corresponding to the
|
| + * element's type parameters.
|
| + */
|
| + List<TypeParameterType> get typeParameterTypes {
|
| + if (_typeParameterTypes == null) {
|
| + _typeParameterTypes = typeParameters
|
| + .map((TypeParameterElementForLink e) => new TypeParameterTypeImpl(e))
|
| + .toList();
|
| + }
|
| + return _typeParameterTypes;
|
| + }
|
| +
|
| + /**
|
| + * Get the [UnlinkedTypeParam]s representing the type parameters declared by
|
| + * this element.
|
| + */
|
| + List<UnlinkedTypeParam> get _unlinkedTypeParams;
|
| +
|
| + @override
|
| + TypeParameterType getTypeParameterType(int index) {
|
| + List<TypeParameterType> types = typeParameterTypes;
|
| + if (index <= types.length) {
|
| + return types[types.length - index];
|
| + } else if (enclosingTypeParameterContext != null) {
|
| + return enclosingTypeParameterContext
|
| + .getTypeParameterType(index - types.length);
|
| + } else {
|
| + // If we get here, it means that a summary contained a type parameter index
|
| + // that was out of range.
|
| + throw new RangeError('Invalid type parameter index');
|
| + }
|
| + }
|
| +}
|
| +
|
| class TypeProviderForLink implements TypeProvider {
|
| final _Linker _linker;
|
|
|
|
|