diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart index f5b2df67ad4..fadc2e2efbb 100644 --- a/pkg/analyzer/lib/src/dart/element/element.dart +++ b/pkg/analyzer/lib/src/dart/element/element.dart @@ -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; diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/analyzer/lib/src/summary/link.dart index 3a674d4b9ee..b7f77030f27 100644 --- a/pkg/analyzer/lib/src/summary/link.dart +++ b/pkg/analyzer/lib/src/summary/link.dart @@ -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 _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. diff --git a/pkg/analyzer/lib/src/summary/resynthesize.dart b/pkg/analyzer/lib/src/summary/resynthesize.dart index 32ce287f805..234f46a3550 100644 --- a/pkg/analyzer/lib/src/summary/resynthesize.dart +++ b/pkg/analyzer/lib/src/summary/resynthesize.dart @@ -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 typeArgumentRefs) { + DartType _createConstructorDefiningType(ElementImpl context, + _ReferenceInfo info, List typeArgumentRefs) { bool isClass = info.element is ClassElement; _ReferenceInfo classInfo = isClass ? info : info.enclosing; if (classInfo == null) { return DynamicTypeImpl.instance; } - List typeArguments = typeArgumentRefs - .map((t) => buildType(t, typeParameterContext)) - .toList(); + List 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); } diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart index 748deea1f0e..aee2ada2824 100644 --- a/pkg/analyzer/test/src/summary/resynthesize_common.dart +++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart @@ -8549,6 +8549,82 @@ class C { } } + 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);