Pass ElementImpl as a context for resynthesizing types.

We need to do this in order to associate resynthesized
GenericFunctionTypeElementImpl instances with these enclosing ElementImpl
instances. The same enclosing ElementImpl can also be used to get
the TypeParameterizedElementMixin for accessing type parameters.

R=brianwilkerson@google.com, paulberry@google.com
BUG=

Review-Url: https://codereview.chromium.org/2813543007 .
This commit is contained in:
Konstantin Shcheglov
2017-04-12 09:35:53 -07:00
parent 492eab84ec
commit d2a1bdff4a
4 changed files with 155 additions and 88 deletions
+30 -39
View File
@@ -724,7 +724,7 @@ class ClassElementImpl extends AbstractClassElementImpl
if (_unlinkedClass != null && _interfaces == null) {
ResynthesizerContext context = enclosingUnit.resynthesizerContext;
_interfaces = _unlinkedClass.interfaces
.map((EntityRef t) => context.resolveTypeRef(t, this))
.map((EntityRef t) => context.resolveTypeRef(this, t))
.where(_isClassInterfaceType)
.toList(growable: false);
}
@@ -831,7 +831,7 @@ class ClassElementImpl extends AbstractClassElementImpl
if (_unlinkedClass != null && _mixins == null) {
ResynthesizerContext context = enclosingUnit.resynthesizerContext;
_mixins = _unlinkedClass.mixins
.map((EntityRef t) => context.resolveTypeRef(t, this))
.map((EntityRef t) => context.resolveTypeRef(this, t))
.where(_isClassInterfaceType)
.toList(growable: false);
}
@@ -865,7 +865,7 @@ class ClassElementImpl extends AbstractClassElementImpl
if (_unlinkedClass != null && _supertype == null) {
if (_unlinkedClass.supertype != null) {
DartType type = enclosingUnit.resynthesizerContext
.resolveTypeRef(_unlinkedClass.supertype, this);
.resolveTypeRef(this, _unlinkedClass.supertype);
if (_isClassInterfaceType(type)) {
_supertype = type;
} else {
@@ -3879,10 +3879,10 @@ abstract class ExecutableElementImpl extends ElementImpl
_returnType == null) {
bool isSetter =
serializedExecutable.kind == UnlinkedExecutableKind.setter;
_returnType = enclosingUnit.resynthesizerContext.resolveLinkedType(
serializedExecutable.inferredReturnTypeSlot, typeParameterContext);
_returnType = enclosingUnit.resynthesizerContext
.resolveLinkedType(this, serializedExecutable.inferredReturnTypeSlot);
_declaredReturnType = enclosingUnit.resynthesizerContext.resolveTypeRef(
serializedExecutable.returnType, typeParameterContext,
this, serializedExecutable.returnType,
defaultVoid: isSetter && context.analysisOptions.strongMode,
declaredType: true);
}
@@ -4572,7 +4572,7 @@ class FunctionElementImpl_forLUB extends FunctionElementImpl {
@override
DartType get returnType {
return _returnType ??= enclosingUnit.resynthesizerContext
.resolveTypeRef(_entityRef.syntheticReturnType, typeParameterContext);
.resolveTypeRef(this, _entityRef.syntheticReturnType);
}
@override
@@ -4736,7 +4736,7 @@ class FunctionTypeAliasElementImpl extends ElementImpl
DartType get returnType {
if (_unlinkedTypedef != null && _returnType == null) {
_returnType = enclosingUnit.resynthesizerContext.resolveTypeRef(
_unlinkedTypedef.returnType, this,
this, _unlinkedTypedef.returnType,
declaredType: true);
}
return _returnType;
@@ -4858,11 +4858,6 @@ class GenericFunctionTypeElementImpl extends ElementImpl
*/
EntityRef _entityRef;
/**
* The enclosing type parameter context.
*/
TypeParameterizedElementMixin _typeParameterContext;
/**
* The declared return type of the function.
*/
@@ -4889,13 +4884,13 @@ class GenericFunctionTypeElementImpl extends ElementImpl
* Initialize from serialized information.
*/
GenericFunctionTypeElementImpl.forSerialized(
this._entityRef, this._typeParameterContext)
: super.forSerialized(null);
ElementImpl enclosingElement, this._entityRef)
: super.forSerialized(enclosingElement);
@override
TypeParameterizedElementMixin get enclosingTypeParameterContext =>
_typeParameterContext ??
(enclosingElement as ElementImpl).typeParameterContext;
TypeParameterizedElementMixin get enclosingTypeParameterContext {
return _enclosingElement.typeParameterContext;
}
@override
String get identifier => '-';
@@ -4928,7 +4923,7 @@ class GenericFunctionTypeElementImpl extends ElementImpl
DartType get returnType {
if (_entityRef != null && _returnType == null) {
_returnType = enclosingUnit.resynthesizerContext.resolveTypeRef(
_entityRef.syntheticReturnType, typeParameterContext,
this, _entityRef.syntheticReturnType,
defaultVoid: false, declaredType: true);
}
return _returnType;
@@ -5102,7 +5097,7 @@ class GenericTypeAliasElementImpl extends ElementImpl
GenericFunctionTypeElement get function {
if (_function == null && _unlinkedTypedef != null) {
DartType type = enclosingUnit.resynthesizerContext.resolveTypeRef(
_unlinkedTypedef.returnType, this,
this, _unlinkedTypedef.returnType,
declaredType: true);
if (type is FunctionType) {
Element element = type.element;
@@ -7280,11 +7275,10 @@ abstract class NonParameterVariableElementImpl extends VariableElementImpl {
@override
DartType get type {
if (_unlinkedVariable != null && _declaredType == null && _type == null) {
_type = enclosingUnit.resynthesizerContext.resolveLinkedType(
_unlinkedVariable.inferredTypeSlot, typeParameterContext);
declaredType = enclosingUnit.resynthesizerContext.resolveTypeRef(
_unlinkedVariable.type, typeParameterContext,
declaredType: true);
_type = enclosingUnit.resynthesizerContext
.resolveLinkedType(this, _unlinkedVariable.inferredTypeSlot);
declaredType = enclosingUnit.resynthesizerContext
.resolveTypeRef(this, _unlinkedVariable.type, declaredType: true);
}
return super.type;
}
@@ -7786,18 +7780,17 @@ class ParameterElementImpl extends VariableElementImpl
parameterTypeElement.shareParameters(subParameters);
}
parameterTypeElement.returnType = enclosingUnit.resynthesizerContext
.resolveTypeRef(_unlinkedParam.type, typeParameterContext);
.resolveTypeRef(this, _unlinkedParam.type);
FunctionTypeImpl parameterType =
new FunctionTypeImpl.elementWithNameAndArgs(parameterTypeElement,
null, typeParameterContext.allTypeParameterTypes, false);
parameterTypeElement.type = parameterType;
_type = parameterType;
} else {
_type = enclosingUnit.resynthesizerContext.resolveLinkedType(
_unlinkedParam.inferredTypeSlot, typeParameterContext);
declaredType = enclosingUnit.resynthesizerContext.resolveTypeRef(
_unlinkedParam.type, typeParameterContext,
declaredType: true);
_type = enclosingUnit.resynthesizerContext
.resolveLinkedType(this, _unlinkedParam.inferredTypeSlot);
declaredType = enclosingUnit.resynthesizerContext
.resolveTypeRef(this, _unlinkedParam.type, declaredType: true);
}
}
}
@@ -8294,8 +8287,8 @@ abstract class PropertyInducingElementImpl
@override
DartType get propagatedType {
if (_unlinkedVariable != null && _propagatedType == null) {
_propagatedType = enclosingUnit.resynthesizerContext.resolveLinkedType(
_unlinkedVariable.propagatedTypeSlot, typeParameterContext);
_propagatedType = enclosingUnit.resynthesizerContext
.resolveLinkedType(this, _unlinkedVariable.propagatedTypeSlot);
}
return _propagatedType;
}
@@ -8370,14 +8363,13 @@ abstract class ResynthesizerContext {
* unresolved, return `null`.
*/
ConstructorElement resolveConstructorRef(
TypeParameterizedElementMixin typeParameterContext, EntityRef entry);
ElementImpl context, EntityRef entry);
/**
* Build the appropriate [DartType] object corresponding to a slot id in the
* [LinkedUnit.types] table.
*/
DartType resolveLinkedType(
int slot, TypeParameterizedElementMixin typeParameterContext);
DartType resolveLinkedType(ElementImpl context, int slot);
/**
* Resolve an [EntityRef] into a type. If the reference is
@@ -8386,8 +8378,7 @@ abstract class ResynthesizerContext {
* TODO(paulberry): or should we have a class representing an
* unresolved type, for consistency with the full element model?
*/
DartType resolveTypeRef(
EntityRef type, TypeParameterizedElementMixin typeParameterContext,
DartType resolveTypeRef(ElementImpl context, EntityRef type,
{bool defaultVoid: false,
bool instantiateToBoundsAllowed: true,
bool declaredType: false});
@@ -8589,7 +8580,7 @@ class TypeParameterElementImpl extends ElementImpl
return null;
}
return _bound ??= enclosingUnit.resynthesizerContext.resolveTypeRef(
_unlinkedTypeParam.bound, enclosingElement,
this, _unlinkedTypeParam.bound,
instantiateToBoundsAllowed: false, declaredType: true);
}
return _bound;
+25 -16
View File
@@ -683,7 +683,7 @@ class ClassElementForLink_Class extends ClassElementForLink
*/
InterfaceType _computeInterfaceType(EntityRef typeRef) {
if (typeRef != null) {
DartType type = enclosingElement.resolveTypeRef(typeRef, this);
DartType type = enclosingElement.resolveTypeRef(this, typeRef);
if (type is InterfaceType && !type.element.isEnum) {
return type;
}
@@ -1076,8 +1076,7 @@ abstract class CompilationUnitElementForLink
}
@override
DartType resolveTypeRef(
EntityRef type, TypeParameterizedElementMixin typeParameterContext,
DartType resolveTypeRef(ElementImpl context, EntityRef type,
{bool defaultVoid: false,
bool instantiateToBoundsAllowed: true,
bool declaredType: false}) {
@@ -1089,7 +1088,8 @@ abstract class CompilationUnitElementForLink
}
}
if (type.paramReference != 0) {
return typeParameterContext.getTypeParameterType(type.paramReference);
return context.typeParameterContext
.getTypeParameterType(type.paramReference);
} else if (type.syntheticReturnType != null) {
// TODO(paulberry): implement.
throw new UnimplementedError();
@@ -1099,7 +1099,7 @@ abstract class CompilationUnitElementForLink
} else {
DartType getTypeArgument(int i) {
if (i < type.typeArguments.length) {
return resolveTypeRef(type.typeArguments[i], typeParameterContext);
return resolveTypeRef(context, type.typeArguments[i]);
} else if (!instantiateToBoundsAllowed) {
// Do not allow buildType to instantiate the bounds; force dynamic.
return DynamicTypeImpl.instance;
@@ -1409,7 +1409,7 @@ class CompilationUnitElementInDependency extends CompilationUnitElementForLink {
DartType getLinkedType(
int slot, TypeParameterizedElementMixin typeParameterContext) {
if (slot < _linkedTypeRefs.length) {
return resolveTypeRef(_linkedTypeRefs[slot], typeParameterContext);
return resolveTypeRef(this, _linkedTypeRefs[slot]);
} else {
return DynamicTypeImpl.instance;
}
@@ -1832,7 +1832,7 @@ abstract class ExecutableElementForLink extends Object
return null;
} else {
return _declaredReturnType ??=
compilationUnit.resolveTypeRef(_unlinkedExecutable.returnType, this);
compilationUnit.resolveTypeRef(this, _unlinkedExecutable.returnType);
}
}
@@ -2327,8 +2327,7 @@ class ExprTypeComputer {
if (ref.typeArguments.isNotEmpty) {
return constructorElement.enclosingClass.buildType((int i) {
if (i < ref.typeArguments.length) {
return unit.resolveTypeRef(
ref.typeArguments[i], function.typeParameterContext);
return unit.resolveTypeRef(function, ref.typeArguments[i]);
} else {
return null;
}
@@ -2528,7 +2527,7 @@ class ExprTypeComputer {
DartType _getNextTypeRef() {
EntityRef ref = _getNextRef();
return unit.resolveTypeRef(ref, function.typeParameterContext);
return unit.resolveTypeRef(function, ref);
}
List<DartType> _getTypeArguments() {
@@ -2885,7 +2884,7 @@ class FunctionElementForLink_FunctionTypedParam extends Object
_returnType = DynamicTypeImpl.instance;
} else {
_returnType = enclosingElement.compilationUnit.resolveTypeRef(
enclosingElement._unlinkedParam.type, typeParameterContext);
enclosingElement, enclosingElement._unlinkedParam.type);
}
}
return _returnType;
@@ -3200,7 +3199,7 @@ class FunctionTypeAliasElementForLink extends Object
@override
DartType get returnType => _returnType ??=
enclosingElement.resolveTypeRef(_unlinkedTypedef.returnType, this);
enclosingElement.resolveTypeRef(this, _unlinkedTypedef.returnType);
@override
TypeParameterizedElementMixin get typeParameterContext => this;
@@ -4199,8 +4198,8 @@ class ParameterElementForLink implements ParameterElementImpl {
_declaredType = DynamicTypeImpl.instance;
}
} else {
_declaredType = compilationUnit.resolveTypeRef(
_unlinkedParam.type, _typeParameterContext);
_declaredType =
compilationUnit.resolveTypeRef(this, _unlinkedParam.type);
}
}
return _declaredType;
@@ -4212,6 +4211,11 @@ class ParameterElementForLink implements ParameterElementImpl {
_inferredType = inferredType;
}
@override
TypeParameterizedElementMixin get typeParameterContext {
return _typeParameterContext;
}
/**
* Store the results of type inference for this parameter in
* [compilationUnit].
@@ -5186,8 +5190,8 @@ abstract class VariableElementForLink
if (unlinkedVariable.type == null) {
return null;
} else {
return _declaredType ??= compilationUnit.resolveTypeRef(
unlinkedVariable.type, _typeParameterContext);
return _declaredType ??=
compilationUnit.resolveTypeRef(this, unlinkedVariable.type);
}
}
@@ -5285,6 +5289,11 @@ abstract class VariableElementForLink
// TODO(paulberry): store inferred type.
}
@override
TypeParameterizedElementMixin get typeParameterContext {
return _typeParameterContext;
}
/**
* The context in which type parameters should be interpreted, or `null` if
* there are no type parameters in scope.
+24 -33
View File
@@ -594,8 +594,7 @@ class _ConstExprBuilder {
*/
TypeAnnotation _newTypeName() {
EntityRef typeRef = uc.references[refPtr++];
DartType type =
resynthesizer.buildType(typeRef, context?.typeParameterContext);
DartType type = resynthesizer.buildType(context, typeRef);
return _buildTypeAst(type);
}
@@ -643,7 +642,7 @@ class _ConstExprBuilder {
return;
}
InterfaceType definingType = resynthesizer._createConstructorDefiningType(
context?.typeParameterContext, info, ref.typeArguments);
context, info, ref.typeArguments);
constructorElement =
resynthesizer._getConstructorForInfo(definingType, info);
typeNode = _buildTypeAst(definingType);
@@ -1439,24 +1438,21 @@ class _ResynthesizerContext implements ResynthesizerContext {
@override
ConstructorElement resolveConstructorRef(
TypeParameterizedElementMixin typeParameterContext, EntityRef entry) {
return _unitResynthesizer._getConstructorForEntry(
typeParameterContext, entry);
ElementImpl context, EntityRef entry) {
return _unitResynthesizer._getConstructorForEntry(context, entry);
}
@override
DartType resolveLinkedType(
int slot, TypeParameterizedElementMixin typeParameterContext) {
return _unitResynthesizer.buildLinkedType(slot, typeParameterContext);
DartType resolveLinkedType(ElementImpl context, int slot) {
return _unitResynthesizer.buildLinkedType(context, slot);
}
@override
DartType resolveTypeRef(
EntityRef type, TypeParameterizedElementMixin typeParameterContext,
DartType resolveTypeRef(ElementImpl context, EntityRef type,
{bool defaultVoid: false,
bool instantiateToBoundsAllowed: true,
bool declaredType: false}) {
return _unitResynthesizer.buildType(type, typeParameterContext,
return _unitResynthesizer.buildType(context, type,
defaultVoid: defaultVoid,
instantiateToBoundsAllowed: instantiateToBoundsAllowed,
declaredType: declaredType);
@@ -1625,8 +1621,7 @@ class _UnitResynthesizer {
* Build the appropriate [DartType] object corresponding to a slot id in the
* [LinkedUnit.types] table.
*/
DartType buildLinkedType(
int slot, TypeParameterizedElementMixin typeParameterContext) {
DartType buildLinkedType(ElementImpl context, int slot) {
if (slot == 0) {
// A slot id of 0 means there is no [DartType] object to build.
return null;
@@ -1637,7 +1632,7 @@ class _UnitResynthesizer {
// stored in this slot.
return null;
}
return buildType(type, typeParameterContext);
return buildType(context, type);
}
/**
@@ -1646,8 +1641,7 @@ class _UnitResynthesizer {
* deserialized, so handles are used to avoid having to deserialize other
* libraries in the process.
*/
DartType buildType(
EntityRef type, TypeParameterizedElementMixin typeParameterContext,
DartType buildType(ElementImpl context, EntityRef type,
{bool defaultVoid: false,
bool instantiateToBoundsAllowed: true,
bool declaredType: false}) {
@@ -1659,20 +1653,20 @@ class _UnitResynthesizer {
}
}
if (type.paramReference != 0) {
return typeParameterContext.getTypeParameterType(type.paramReference);
return context.typeParameterContext
.getTypeParameterType(type.paramReference);
} else if (type.entityKind == EntityRefKind.genericFunctionType) {
GenericFunctionTypeElement element =
new GenericFunctionTypeElementImpl.forSerialized(
type, typeParameterContext);
new GenericFunctionTypeElementImpl.forSerialized(context, type);
return element.type;
} else if (type.syntheticReturnType != null) {
FunctionElementImpl element =
new FunctionElementImpl_forLUB(unit, typeParameterContext, type);
FunctionElementImpl element = new FunctionElementImpl_forLUB(
unit, context.typeParameterContext, type);
return element.type;
} else {
DartType getTypeArgument(int i) {
if (i < type.typeArguments.length) {
return buildType(type.typeArguments[i], typeParameterContext,
return buildType(context, type.typeArguments[i],
declaredType: declaredType);
} else {
return DynamicTypeImpl.instance;
@@ -1929,18 +1923,15 @@ class _UnitResynthesizer {
* [typeArgumentRefs] to the given linked [info]. Return [DynamicTypeImpl]
* if the [info] is unresolved.
*/
DartType _createConstructorDefiningType(
TypeParameterizedElementMixin typeParameterContext,
_ReferenceInfo info,
List<EntityRef> typeArgumentRefs) {
DartType _createConstructorDefiningType(ElementImpl context,
_ReferenceInfo info, List<EntityRef> typeArgumentRefs) {
bool isClass = info.element is ClassElement;
_ReferenceInfo classInfo = isClass ? info : info.enclosing;
if (classInfo == null) {
return DynamicTypeImpl.instance;
}
List<DartType> typeArguments = typeArgumentRefs
.map((t) => buildType(t, typeParameterContext))
.toList();
List<DartType> typeArguments =
typeArgumentRefs.map((t) => buildType(context, t)).toList();
return classInfo.buildType(true, typeArguments.length, (i) {
if (i < typeArguments.length) {
return typeArguments[i];
@@ -1954,10 +1945,10 @@ class _UnitResynthesizer {
* Return the [ConstructorElement] corresponding to the given [entry].
*/
ConstructorElement _getConstructorForEntry(
TypeParameterizedElementMixin typeParameterContext, EntityRef entry) {
ElementImpl context, EntityRef entry) {
_ReferenceInfo info = getReferenceInfo(entry.reference);
DartType type = _createConstructorDefiningType(
typeParameterContext, info, entry.typeArguments);
DartType type =
_createConstructorDefiningType(context, info, entry.typeArguments);
if (type is InterfaceType) {
return _getConstructorForInfo(type, info);
}
@@ -8549,6 +8549,82 @@ class C<T, U> {
}
}
test_genericFunction_asFunctionReturnType() {
shouldCompareLibraryElements = false;
var library = checkLibrary(r'''
int Function(int a, String b) f() => null;
''');
checkElementText(
library,
r'''
(int, String) int f() {}
''');
}
test_genericFunction_asFunctionTypedParameterReturnType() {
shouldCompareLibraryElements = false;
var library = checkLibrary(r'''
void f(int Function(int a, String b) p(num c)) => null;
''');
checkElementText(
library,
r'''
void f((num) (int, String) int p) {}
''');
}
test_genericFunction_asGenericFunctionReturnType() {
shouldCompareLibraryElements = false;
var library = checkLibrary(r'''
typedef F = void Function(String a) Function(int b);
''');
checkElementText(
library,
r'''
typedef F = (String) void Function(int b);
''');
}
test_genericFunction_asMethodReturnType() {
shouldCompareLibraryElements = false;
var library = checkLibrary(r'''
class C {
int Function(int a, String b) m() => null;
}
''');
checkElementText(
library,
r'''
class C {
(int, String) int m() {}
}
''');
}
test_genericFunction_asParameterType() {
shouldCompareLibraryElements = false;
var library = checkLibrary(r'''
void f(int Function(int a, String b) p) => null;
''');
checkElementText(
library,
r'''
void f((int, String) int p) {}
''');
}
test_genericFunction_asTopLevelVariableType() {
shouldCompareLibraryElements = false;
var library = checkLibrary(r'''
int Function(int a, String b) v;
''');
checkElementText(
library,
r'''
(int, String) int v;
''');
}
test_getElement_constructor_named() {
String text = 'class C { C.named(); }';
Source source = addLibrarySource('/test.dart', text);