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

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

Issue 1845403003: Begin implementing type inference for AST summaries. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Break a long line. 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/lib/src/task/dart.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 279bd780d13e5e1955230935e4ce58d711dacac8..8e84971dd880055b7de2d236082b5d14255a712e 100644
--- a/pkg/analyzer/lib/src/summary/link.dart
+++ b/pkg/analyzer/lib/src/summary/link.dart
@@ -58,13 +58,18 @@
* checks. E.g. see [ReferenceableElementForLink.asConstructor].
*/
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/constant/value.dart';
+import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary/prelink.dart';
+import 'package:analyzer/src/task/strong_mode.dart';
/**
* Link together the build unit consisting of [libraryUris], using
@@ -72,12 +77,17 @@ import 'package:analyzer/src/summary/prelink.dart';
* build units, and [getUnit] to fetch the [UnlinkedUnit] objects from
* both this build unit and other build units.
*
+ * The [strong] flag controls whether type inference is performed in strong
+ * mode or spec mode. Note that in spec mode, the only types that are inferred
+ * are the types of initializing formals, which are inferred from the types of
+ * the corresponding fields.
+ *
* A map is returned whose keys are the URIs of the libraries in this
* build unit, and whose values are the corresponding
* [LinkedLibraryBuilder]s.
*/
Map<String, LinkedLibraryBuilder> link(Set<String> libraryUris,
- GetDependencyCallback getDependency, GetUnitCallback getUnit) {
+ GetDependencyCallback getDependency, GetUnitCallback getUnit, bool strong) {
Map<String, LinkedLibraryBuilder> linkedLibraries =
<String, LinkedLibraryBuilder>{};
for (String absoluteUri in libraryUris) {
@@ -89,7 +99,7 @@ Map<String, LinkedLibraryBuilder> link(Set<String> libraryUris,
getRelativeUnit,
(String relativeUri) => getRelativeUnit(relativeUri)?.publicNamespace);
}
- relink(linkedLibraries, getDependency, getUnit);
+ relink(linkedLibraries, getDependency, getUnit, strong);
return linkedLibraries;
}
@@ -100,10 +110,39 @@ Map<String, LinkedLibraryBuilder> link(Set<String> libraryUris,
* objects from other build units, and [getUnit] to fetch the
* [UnlinkedUnit] objects from both this build unit and other build
* units.
+ *
+ * The [strong] flag controls whether type inference is performed in strong
+ * mode or spec mode. Note that in spec mode, the only types that are inferred
+ * are the types of initializing formals, which are inferred from the types of
+ * the corresponding fields.
*/
void relink(Map<String, LinkedLibraryBuilder> libraries,
- GetDependencyCallback getDependency, GetUnitCallback getUnit) {
- new _Linker(libraries, getDependency, getUnit).link();
+ GetDependencyCallback getDependency, GetUnitCallback getUnit, bool strong) {
+ new _Linker(libraries, getDependency, getUnit, strong).link();
+}
+
+/**
+ * Create an [EntityRefBuilder] representing the given [type], in a form
+ * suitable for inclusion in [LinkedUnit.types]. [compilationUnit] is the
+ * compilation unit in which the type will be used. If [slot] is provided, it
+ * is stored in [EntityRefBuilder.slot].
+ */
+EntityRefBuilder _createLinkedType(
+ DartType type, CompilationUnitElementInBuildUnit compilationUnit,
+ {int slot}) {
+ EntityRefBuilder result = new EntityRefBuilder(slot: slot);
+ if (type is InterfaceType) {
+ ClassElementForLink element = type.element;
+ int dependency = compilationUnit.library.addDependency(element.library);
+ result.reference = compilationUnit.addReference(dependency, element.name,
+ element.typeParameters.length, element.enclosingElement.unitNum);
+ if (element.typeParameters.isNotEmpty) {
+ // TODO(paulberry): implement.
+ throw new UnimplementedError();
+ }
+ return result;
+ }
+ throw new UnimplementedError('${type.runtimeType}');
}
/**
@@ -123,10 +162,18 @@ typedef UnlinkedUnit GetUnitCallback(String absoluteUri);
* during linking.
*/
abstract class ClassElementForLink
- implements ClassElement, ReferenceableElementForLink {
+ implements ClassElementImpl, ReferenceableElementForLink {
Map<String, ReferenceableElementForLink> _containedNames;
@override
+ final CompilationUnitElementForLink enclosingElement;
+
+ @override
+ bool hasBeenInferred = false;
+
+ ClassElementForLink(this.enclosingElement);
+
+ @override
ConstructorElementForLink get asConstructor => unnamedConstructor;
@override
@@ -149,6 +196,9 @@ abstract class ClassElementForLink
bool get isObject;
@override
+ LibraryElementForLink get library => enclosingElement.library;
+
+ @override
String get name;
@override
@@ -183,6 +233,11 @@ abstract class ClassElementForLink
@override
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+
+ /**
+ * Throw away any information produced by a previous call to [link].
+ */
+ void unlink();
}
/**
@@ -196,18 +251,27 @@ class ClassElementForLink_Class extends ClassElementForLink
*/
final UnlinkedClass _unlinkedClass;
- @override
- final CompilationUnitElementForLink enclosingElement;
-
List<ConstructorElementForLink> _constructors;
ConstructorElementForLink _unnamedConstructor;
bool _unnamedConstructorComputed = false;
List<FieldElementForLink_ClassField> _fields;
InterfaceType _supertype;
InterfaceType _type;
+ List<TypeParameterElementForLink> _typeParameters;
List<TypeParameterType> _typeParameterTypes;
+ List<MethodElementForLink> _methods;
+ List<InterfaceType> _mixins;
+ List<InterfaceType> _interfaces;
- ClassElementForLink_Class(this.enclosingElement, this._unlinkedClass);
+ ClassElementForLink_Class(
+ CompilationUnitElementForLink enclosingElement, this._unlinkedClass)
+ : super(enclosingElement);
+
+ @override
+ List<PropertyAccessorElement> get accessors {
+ // TODO(paulberry): implement
+ return const [];
+ }
@override
List<ConstructorElementForLink> get constructors {
@@ -239,9 +303,35 @@ class ClassElementForLink_Class extends ClassElementForLink
}
@override
+ List<InterfaceType> get interfaces => _interfaces ??=
+ _unlinkedClass.interfaces.map(_computeInterfaceType).toList();
+
+ @override
bool get isObject => _unlinkedClass.hasNoSupertype;
@override
+ LibraryElementForLink get library => enclosingElement.library;
+
+ @override
+ List<MethodElementForLink> get methods {
+ if (_methods == null) {
+ _methods = <MethodElementForLink>[];
+ for (UnlinkedExecutable unlinkedExecutable
+ in _unlinkedClass.executables) {
+ if (unlinkedExecutable.kind ==
+ UnlinkedExecutableKind.functionOrMethod) {
+ _methods.add(new MethodElementForLink(this, unlinkedExecutable));
+ }
+ }
+ }
+ return _methods;
+ }
+
+ @override
+ List<InterfaceType> get mixins =>
+ _mixins ??= _unlinkedClass.mixins.map(_computeInterfaceType).toList();
+
+ @override
String get name => _unlinkedClass.name;
@override
@@ -249,7 +339,17 @@ class ClassElementForLink_Class extends ClassElementForLink
if (isObject) {
return null;
}
- return _supertype ??= _computeSupertype();
+ return _supertype ??= _computeInterfaceType(_unlinkedClass.supertype);
+ }
+
+ @override
+ List<TypeParameterElementForLink> get typeParameters {
+ if (_typeParameters == null) {
+ _typeParameters = _unlinkedClass.typeParameters
+ .map((UnlinkedTypeParam p) => new TypeParameterElementForLink(p))
+ .toList();
+ }
+ return _typeParameters;
}
/**
@@ -258,9 +358,8 @@ class ClassElementForLink_Class extends ClassElementForLink
*/
List<TypeParameterType> get typeParameterTypes {
if (_typeParameterTypes == null) {
- _typeParameterTypes = _unlinkedClass.typeParameters
- .map((UnlinkedTypeParam p) =>
- new TypeParameterTypeImpl(new TypeParameterElementForLink(p)))
+ _typeParameterTypes = typeParameters
+ .map((TypeParameterElementForLink e) => new TypeParameterTypeImpl(e))
.toList();
}
return _typeParameterTypes;
@@ -310,12 +409,25 @@ class ClassElementForLink_Class extends ClassElementForLink
for (ConstructorElementForLink constructorElement in constructors) {
constructorElement.link(linkedUnit);
}
+ for (MethodElementForLink methodElement in methods) {
+ methodElement.link(linkedUnit);
+ }
}
- InterfaceType _computeSupertype() {
+ @override
+ void unlink() {
+ hasBeenInferred = false;
+ for (MethodElementForLink methodElement in methods) {
+ methodElement.unlink();
+ }
+ }
+
+ /**
+ * Convert [typeRef] into an [InterfaceType].
+ */
+ InterfaceType _computeInterfaceType(EntityRef typeRef) {
if (_unlinkedClass.supertype != null) {
- DartType supertype =
- enclosingElement._resolveTypeRef(_unlinkedClass.supertype, this);
+ DartType supertype = enclosingElement._resolveTypeRef(typeRef, this);
if (supertype is InterfaceType) {
return supertype;
}
@@ -323,7 +435,7 @@ class ClassElementForLink_Class extends ClassElementForLink
// happen in the event of erroneous code) just fall through and pretend
// the supertype is `Object`.
}
- return enclosingElement.enclosingElement._linker.objectType;
+ return enclosingElement.enclosingElement._linker.typeProvider.objectType;
}
}
@@ -340,7 +452,15 @@ class ClassElementForLink_Enum extends ClassElementForLink {
InterfaceType _type;
List<FieldElementForLink_EnumField> _fields;
- ClassElementForLink_Enum(this._unlinkedEnum);
+ ClassElementForLink_Enum(
+ CompilationUnitElementForLink enclosingElement, this._unlinkedEnum)
+ : super(enclosingElement);
+
+ @override
+ List<PropertyAccessorElement> get accessors {
+ // TODO(paulberry): do we need to include synthetic accessors?
+ return const [];
+ }
@override
List<ConstructorElementForLink> get constructors => const [];
@@ -361,12 +481,24 @@ class ClassElementForLink_Enum extends ClassElementForLink {
}
@override
+ List<InterfaceType> get interfaces => const [];
+
+ @override
bool get isObject => false;
@override
+ List<MethodElement> get methods => const [];
+
+ @override
+ List<InterfaceType> get mixins => const [];
+
+ @override
String get name => _unlinkedEnum.name;
@override
+ InterfaceType get supertype => library._linker.typeProvider.objectType;
+
+ @override
ConstructorElementForLink get unnamedConstructor => null;
@override
@@ -376,6 +508,9 @@ class ClassElementForLink_Enum extends ClassElementForLink {
@override
void link(LinkedUnitBuilder linkedUnit) {}
+
+ @override
+ void unlink() {}
}
/**
@@ -396,25 +531,30 @@ abstract class CompilationUnitElementForLink implements CompilationUnitElement {
final List<ReferenceableElementForLink> _references;
List<ClassElementForLink_Class> _types;
+
Map<String, ReferenceableElementForLink> _containedNames;
List<TopLevelVariableElementForLink> _topLevelVariables;
List<ClassElementForLink_Enum> _enums;
- @override
- final LibraryElementForLink enclosingElement;
+ /**
+ * Index of this unit in the list of units in the enclosing library.
+ */
+ final int unitNum;
- CompilationUnitElementForLink(
- this.enclosingElement, UnlinkedUnit unlinkedUnit)
+ CompilationUnitElementForLink(UnlinkedUnit unlinkedUnit, this.unitNum)
: _references = new List<ReferenceableElementForLink>(
unlinkedUnit.references.length),
_unlinkedUnit = unlinkedUnit;
@override
+ LibraryElementForLink get enclosingElement;
+
+ @override
List<ClassElementForLink_Enum> get enums {
if (_enums == null) {
_enums = <ClassElementForLink_Enum>[];
for (UnlinkedEnum unlinkedEnum in _unlinkedUnit.enums) {
- _enums.add(new ClassElementForLink_Enum(unlinkedEnum));
+ _enums.add(new ClassElementForLink_Enum(this, unlinkedEnum));
}
}
return _enums;
@@ -427,6 +567,9 @@ abstract class CompilationUnitElementForLink implements CompilationUnitElement {
bool get isInBuildUnit;
@override
+ LibraryElementForLink get library => enclosingElement;
+
+ @override
List<TopLevelVariableElementForLink> get topLevelVariables {
if (_topLevelVariables == null) {
_topLevelVariables = <TopLevelVariableElementForLink>[];
@@ -554,18 +697,59 @@ class CompilationUnitElementInBuildUnit extends CompilationUnitElementForLink {
@override
final LinkedUnitBuilder _linkedUnit;
- CompilationUnitElementInBuildUnit(LibraryElementInBuildUnit libraryElement,
- UnlinkedUnit unlinkedUnit, this._linkedUnit)
- : super(libraryElement, unlinkedUnit);
+ @override
+ final LibraryElementInBuildUnit enclosingElement;
+
+ CompilationUnitElementInBuildUnit(this.enclosingElement,
+ UnlinkedUnit unlinkedUnit, this._linkedUnit, int unitNum)
+ : super(unlinkedUnit, unitNum);
@override
bool get isInBuildUnit => true;
+ @override
+ LibraryElementInBuildUnit get library => enclosingElement;
+
+ /**
+ * If this compilation unit already has a reference in its references table
+ * matching [dependency], [name], [numTypeParameters], and [unitNum], return
+ * its index. Otherwise add a new reference to table and return its index.
+ */
+ int addReference(
+ int dependency, String name, int numTypeParameters, int unitNum) {
+ List<LinkedReferenceBuilder> linkedReferences = _linkedUnit.references;
+ List<UnlinkedReference> unlinkedReferences = _unlinkedUnit.references;
+ for (int i = 0; i < linkedReferences.length; i++) {
+ LinkedReferenceBuilder linkedReference = linkedReferences[i];
+ if (linkedReference.dependency == dependency &&
+ (i < unlinkedReferences.length
+ ? unlinkedReferences[i].name
+ : linkedReference.name) ==
+ name &&
+ linkedReference.numTypeParameters == numTypeParameters &&
+ linkedReference.unit == unitNum) {
+ return i;
+ }
+ }
+ int result = linkedReferences.length;
+ linkedReferences.add(new LinkedReferenceBuilder(
+ dependency: dependency,
+ name: name,
+ numTypeParameters: numTypeParameters,
+ unit: unitNum));
+ return result;
+ }
+
/**
* Perform type inference and const cycle detection on this
* compilation unit.
*/
void link() {
+ if (library._linker.strongMode) {
+ new InstanceMemberInferrer(enclosingElement._linker.typeProvider,
+ enclosingElement.inheritanceManager)
+ .inferCompilationUnit(this);
+ }
for (ClassElementForLink classElement in types) {
classElement.link(_linkedUnit);
}
@@ -578,6 +762,9 @@ class CompilationUnitElementInBuildUnit extends CompilationUnitElementForLink {
_linkedUnit.constCycles.clear();
_linkedUnit.references.length = _unlinkedUnit.references.length;
_linkedUnit.types.clear();
+ for (ClassElementForLink classElement in types) {
+ classElement.unlink();
+ }
}
}
@@ -589,9 +776,12 @@ class CompilationUnitElementInDependency extends CompilationUnitElementForLink {
@override
final LinkedUnit _linkedUnit;
- CompilationUnitElementInDependency(LibraryElementInDependency libraryElement,
- UnlinkedUnit unlinkedUnit, this._linkedUnit)
- : super(libraryElement, unlinkedUnit);
+ @override
+ final LibraryElementInDependency enclosingElement;
+
+ CompilationUnitElementInDependency(this.enclosingElement,
+ UnlinkedUnit unlinkedUnit, this._linkedUnit, int unitNum)
+ : super(unlinkedUnit, unitNum);
@override
bool get isInBuildUnit => false;
@@ -818,7 +1008,7 @@ class ConstParameterNode extends ConstNode {
* during linking.
*/
class ConstructorElementForLink
- implements ConstructorElement, ReferenceableElementForLink {
+ implements ConstructorElementImpl, ReferenceableElementForLink {
/**
* The unlinked representation of the constructor in the summary.
*/
@@ -1096,6 +1286,9 @@ class FieldElementForLink_EnumField extends FieldElementForLink
bool get isStatic => true;
@override
+ bool get isSynthetic => false;
+
+ @override
String get name =>
unlinkedEnumValue == null ? 'values' : unlinkedEnumValue.name;
@@ -1112,6 +1305,23 @@ class FieldElementForLink_EnumField extends FieldElementForLink
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
+class FunctionElementForLink_Initializer implements FunctionElementImpl {
+ @override
+ DartType get returnType {
+ // TODO(paulberry): for type inference, compute and return the type of the
+ // initializer expression.
+ return DynamicTypeImpl.instance;
+ }
+
+ @override
+ void set returnType(DartType newType) {
+ // TODO(paulberry): store inferred type.
+ }
+
+ @override
+ noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
/**
* Element representing a library resynthesied from a summary during
* linking. The type parameter, [UnitElement], represents the type
@@ -1134,15 +1344,25 @@ abstract class LibraryElementForLink<
final Map<String, ReferenceableElementForLink> _containedNames =
<String, ReferenceableElementForLink>{};
final List<LibraryElementForLink> _dependencies = <LibraryElementForLink>[];
+ UnlinkedUnit _definingUnlinkedUnit;
LibraryElementForLink(this._linker, this._absoluteUri) {
_dependencies.length = _linkedLibrary.dependencies.length;
}
+ /**
+ * Get the [UnlinkedUnit] for the defining compilation unit of this library.
+ */
+ UnlinkedUnit get definingUnlinkedUnit =>
+ _definingUnlinkedUnit ??= _linker.getUnit(_absoluteUri.toString());
+
+ @override
+ Element get enclosingElement => null;
+
@override
List<UnitElement> get units {
if (_units == null) {
- UnlinkedUnit definingUnit = _linker.getUnit(_absoluteUri.toString());
+ UnlinkedUnit definingUnit = definingUnlinkedUnit;
_units = <UnitElement>[_makeUnitElement(definingUnit, 0)];
int numParts = definingUnit.parts.length;
for (int i = 0; i < numParts; i++) {
@@ -1169,7 +1389,7 @@ abstract class LibraryElementForLink<
* [name]. If no name is found, return the singleton instance of
* [UndefinedElementForLink].
*/
- ReferenceableElementForLink getContainedName(name) =>
+ ReferenceableElementForLink getContainedName(String name) =>
_containedNames.putIfAbsent(name, () {
for (UnitElement unit in units) {
ReferenceableElementForLink element = unit.getContainedName(name);
@@ -1207,11 +1427,38 @@ class LibraryElementInBuildUnit
@override
final LinkedLibraryBuilder _linkedLibrary;
+ InheritanceManager _inheritanceManager;
+
LibraryElementInBuildUnit(
_Linker linker, Uri absoluteUri, this._linkedLibrary)
: super(linker, absoluteUri);
/**
+ * Get the inheritance manager for this library (creating it if necessary).
+ */
+ InheritanceManager get inheritanceManager =>
+ _inheritanceManager ??= new InheritanceManager(this);
+
+ /**
+ * If this library already has a dependency in its dependencies table matching
+ * [library], return its index. Otherwise add a new dependency to table and
+ * return its index.
+ */
+ int addDependency(LibraryElementForLink library) {
+ for (int i = 0; i < _linkedLibrary.dependencies.length; i++) {
+ if (identical(_getDependency(i), library)) {
+ return i;
+ }
+ }
+ int result = _linkedLibrary.dependencies.length;
+ _linkedLibrary.dependencies.add(new LinkedDependencyBuilder(
+ parts: library.definingUnlinkedUnit.publicNamespace.parts,
+ uri: library._absoluteUri.toString()));
+ _dependencies.add(library);
+ return result;
+ }
+
+ /**
* Perform type inference and const cycle detection on this library.
*/
void link() {
@@ -1235,7 +1482,7 @@ class LibraryElementInBuildUnit
CompilationUnitElementInBuildUnit _makeUnitElement(
UnlinkedUnit unlinkedUnit, int i) =>
new CompilationUnitElementInBuildUnit(
- this, unlinkedUnit, _linkedLibrary.units[i]);
+ this, unlinkedUnit, _linkedLibrary.units[i], i);
}
/**
@@ -1255,7 +1502,120 @@ class LibraryElementInDependency
CompilationUnitElementInDependency _makeUnitElement(
UnlinkedUnit unlinkedUnit, int i) =>
new CompilationUnitElementInDependency(
- this, unlinkedUnit, _linkedLibrary.units[i]);
+ this, unlinkedUnit, _linkedLibrary.units[i], i);
+}
+
+/**
+ * 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;
+
+ @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;
+
+ @override
+ ElementKind get kind => ElementKind.METHOD;
+
+ @override
+ LibraryElementForLink get library => enclosingElement.library;
+
+ @override
+ String get name => _unlinkedExecutable.name;
+
+ @override
+ List<ParameterElementForLink> get parameters {
+ // TODO(paulberry): implement.
+ return const [];
+ }
+
+ @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 [linkedUnit].
+ */
+ void link(LinkedUnitBuilder linkedUnit) {
+ int slot = _unlinkedExecutable.inferredReturnTypeSlot;
+ if (slot != 0) {
+ DartType inferredReturnType = returnType;
+ if (!inferredReturnType.isDynamic) {
+ linkedUnit.types.add(_createLinkedType(
+ inferredReturnType, enclosingElement.enclosingElement,
+ slot: slot));
+ }
+ }
+ }
+
+ @override
+ noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+
+ /**
+ * Throw away any information produced by type inference.
+ */
+ void unlink() {
+ _inferredReturnType = null;
+ }
}
/**
@@ -1439,6 +1799,150 @@ class TypeParameterElementForLink implements TypeParameterElement {
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
+class TypeProviderForLink implements TypeProvider {
+ final _Linker _linker;
+
+ InterfaceType _boolType;
+ InterfaceType _deprecatedType;
+ InterfaceType _doubleType;
+ InterfaceType _functionType;
+ InterfaceType _futureDynamicType;
+ InterfaceType _futureNullType;
+ InterfaceType _futureType;
+ InterfaceType _intType;
+ InterfaceType _iterableDynamicType;
+ InterfaceType _iterableType;
+ InterfaceType _listType;
+ InterfaceType _mapType;
+ InterfaceType _nullType;
+ InterfaceType _numType;
+ InterfaceType _objectType;
+ InterfaceType _stackTraceType;
+ InterfaceType _streamDynamicType;
+ InterfaceType _streamType;
+ InterfaceType _stringType;
+ InterfaceType _symbolType;
+ InterfaceType _typeType;
+
+ TypeProviderForLink(this._linker);
+
+ @override
+ InterfaceType get boolType =>
+ _boolType ??= _buildInterfaceType(_linker.coreLibrary, 'bool');
+
+ @override
+ DartType get bottomType => BottomTypeImpl.instance;
+
+ @override
+ InterfaceType get deprecatedType => _deprecatedType ??=
+ _buildInterfaceType(_linker.coreLibrary, 'Deprecated');
+
+ @override
+ InterfaceType get doubleType =>
+ _doubleType ??= _buildInterfaceType(_linker.coreLibrary, 'double');
+
+ @override
+ DartType get dynamicType => DynamicTypeImpl.instance;
+
+ @override
+ InterfaceType get functionType =>
+ _functionType ??= _buildInterfaceType(_linker.coreLibrary, 'Function');
+
+ @override
+ InterfaceType get futureDynamicType =>
+ _futureDynamicType ??= futureType.instantiate(<DartType>[dynamicType]);
+
+ @override
+ InterfaceType get futureNullType =>
+ _futureNullType ??= futureType.instantiate(<DartType>[nullType]);
+
+ @override
+ InterfaceType get futureType =>
+ _futureType ??= _buildInterfaceType(_linker.asyncLibrary, 'Future');
+
+ @override
+ InterfaceType get intType =>
+ _intType ??= _buildInterfaceType(_linker.coreLibrary, 'int');
+
+ @override
+ InterfaceType get iterableDynamicType => _iterableDynamicType ??=
+ iterableType.instantiate(<DartType>[dynamicType]);
+
+ @override
+ InterfaceType get iterableType =>
+ _iterableType ??= _buildInterfaceType(_linker.coreLibrary, 'Iterable');
+
+ @override
+ InterfaceType get listType =>
+ _listType ??= _buildInterfaceType(_linker.coreLibrary, 'List');
+
+ @override
+ InterfaceType get mapType =>
+ _mapType ??= _buildInterfaceType(_linker.coreLibrary, 'Map');
+
+ @override
+ List<InterfaceType> get nonSubtypableTypes => <InterfaceType>[
+ nullType,
+ numType,
+ intType,
+ doubleType,
+ boolType,
+ stringType
+ ];
+
+ @override
+ DartObjectImpl get nullObject {
+ // TODO(paulberry): implement if needed
+ throw new UnimplementedError();
+ }
+
+ @override
+ InterfaceType get nullType =>
+ _nullType ??= _buildInterfaceType(_linker.coreLibrary, 'Null');
+
+ @override
+ InterfaceType get numType =>
+ _numType ??= _buildInterfaceType(_linker.coreLibrary, 'num');
+
+ @override
+ InterfaceType get objectType =>
+ _objectType ??= _buildInterfaceType(_linker.coreLibrary, 'Object');
+
+ @override
+ InterfaceType get stackTraceType => _stackTraceType ??=
+ _buildInterfaceType(_linker.coreLibrary, 'StackTrace');
+
+ @override
+ InterfaceType get streamDynamicType =>
+ _streamDynamicType ??= streamType.instantiate(<DartType>[dynamicType]);
+
+ @override
+ InterfaceType get streamType =>
+ _streamType ??= _buildInterfaceType(_linker.asyncLibrary, 'Stream');
+
+ @override
+ InterfaceType get stringType =>
+ _stringType ??= _buildInterfaceType(_linker.coreLibrary, 'String');
+
+ @override
+ InterfaceType get symbolType =>
+ _symbolType ??= _buildInterfaceType(_linker.coreLibrary, 'Symbol');
+
+ @override
+ InterfaceType get typeType =>
+ _typeType ??= _buildInterfaceType(_linker.coreLibrary, 'Type');
+
+ @override
+ DartType get undefinedType => UndefinedTypeImpl.instance;
+
+ InterfaceType _buildInterfaceType(
+ LibraryElementForLink library, String name) {
+ return library
+ .getContainedName(name)
+ .buildType((int i) => DynamicTypeImpl.instance, const []);
+ }
+}
+
/**
* Singleton element used for unresolved references.
*/
@@ -1468,7 +1972,7 @@ class UndefinedElementForLink implements ReferenceableElementForLink {
* summary during linking.
*/
class VariableElementForLink
- implements VariableElement, ReferenceableElementForLink {
+ implements VariableElementImpl, ReferenceableElementForLink {
/**
* The unlinked representation of the variable in the summary.
*/
@@ -1481,6 +1985,8 @@ class VariableElementForLink
*/
ConstNode _constNode;
+ FunctionElementForLink_Initializer _initializer;
+
/**
* The compilation unit in which this variable appears.
*/
@@ -1499,6 +2005,13 @@ class VariableElementForLink
ConstVariableNode get asConstVariable => _constNode;
@override
+ bool get hasImplicitType => unlinkedVariable.type != null;
+
+ @override
+ FunctionElementForLink_Initializer get initializer =>
+ _initializer ??= new FunctionElementForLink_Initializer();
+
+ @override
bool get isConst => unlinkedVariable.isConst;
@override
@@ -1508,9 +2021,17 @@ class VariableElementForLink
bool get isStatic;
@override
+ bool get isSynthetic => false;
+
+ @override
String get name => unlinkedVariable.name;
@override
+ void set type(DartType newType) {
+ // TODO(paulberry): store inferred type.
+ }
+
+ @override
DartType buildType(DartType getTypeArgument(int i),
List<int> implicitFunctionTypeIndices) =>
DynamicTypeImpl.instance;
@@ -1554,11 +2075,17 @@ class _Linker {
final List<LibraryElementInBuildUnit> _librariesInBuildUnit =
<LibraryElementInBuildUnit>[];
- InterfaceType _objectType;
+ /**
+ * Indicates whether type inference should use strong mode rules.
+ */
+ final bool strongMode;
+
LibraryElementForLink _coreLibrary;
+ LibraryElementForLink _asyncLibrary;
+ TypeProviderForLink _typeProvider;
_Linker(Map<String, LinkedLibraryBuilder> linkedLibraries, this.getDependency,
- this.getUnit) {
+ this.getUnit, this.strongMode) {
// Create elements for the libraries to be linked. The rest of
// the element model will be created on demand.
linkedLibraries
@@ -1570,17 +2097,22 @@ class _Linker {
}
/**
+ * Get the library element for `dart:async`.
+ */
+ LibraryElementForLink get asyncLibrary =>
+ _asyncLibrary ??= getLibrary(Uri.parse('dart:async'));
+
+ /**
* Get the library element for `dart:core`.
*/
LibraryElementForLink get coreLibrary =>
_coreLibrary ??= getLibrary(Uri.parse('dart:core'));
/**
- * Get the `InterfaceType` for the type `Object`.
+ * Get an instance of [TypeProvider] for use during linking.
*/
- InterfaceType get objectType => _objectType ??= coreLibrary
- .getContainedName('Object')
- .buildType((int i) => DynamicTypeImpl.instance, const []);
+ TypeProviderForLink get typeProvider =>
+ _typeProvider ??= new TypeProviderForLink(this);
/**
* Get the library element for the library having the given [uri].
@@ -1595,6 +2127,7 @@ class _Linker {
* in the build unit being linked.
*/
void link() {
+ // TODO(paulberry): link library cycles in appropriate dependency order.
for (LibraryElementInBuildUnit library in _librariesInBuildUnit) {
library.link();
}
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/task/dart.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698