Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(18)

Unified Diff: pkg/analyzer/lib/src/summary/link.dart

Issue 1853433006: Add more type inference uses cases to AST-based summaries. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
« no previous file with comments | « no previous file | pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698