From feb02ba03476646514b080efe4eb4d8bb317b5b1 Mon Sep 17 00:00:00 2001 From: Konstantin Shcheglov Date: Mon, 18 Sep 2017 19:36:30 +0000 Subject: [PATCH] Resynthesize types of function typed formal parameters. R=brianwilkerson@google.com, paulberry@google.com Bug: Change-Id: I1afb45879afc67806dfb3d6fe18b172fd2b3c01a Reviewed-on: https://dart-review.googlesource.com/6645 Reviewed-by: Paul Berry --- .../lib/src/dart/element/element.dart | 56 ++++++++++++++---- pkg/analyzer/lib/src/kernel/resynthesize.dart | 34 ++++++----- .../non_error_resolver_kernel_test.dart | 59 ------------------- 3 files changed, 64 insertions(+), 85 deletions(-) diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart index f166ef10a15..cb032c1bd3f 100644 --- a/pkg/analyzer/lib/src/dart/element/element.dart +++ b/pkg/analyzer/lib/src/dart/element/element.dart @@ -5322,6 +5322,11 @@ class FunctionTypeAliasElementImpl extends ElementImpl class GenericFunctionTypeElementImpl extends ElementImpl with TypeParameterizedElementMixin implements GenericFunctionTypeElement { + /** + * The kernel type. + */ + final kernel.FunctionType _kernel; + /** * The unlinked representation of the generic function type in the summary. */ @@ -5342,19 +5347,28 @@ class GenericFunctionTypeElementImpl extends ElementImpl */ FunctionType _type; + /** + * Initialize using the given kernel. + */ + GenericFunctionTypeElementImpl.forKernel( + ElementImpl enclosingElement, this._kernel) + : super.forSerialized(enclosingElement); + /** * Initialize a newly created function element to have no name and the given * [nameOffset]. This is used for function expressions, that have no name. */ GenericFunctionTypeElementImpl.forOffset(int nameOffset) - : super("", nameOffset); + : _kernel = null, + super("", nameOffset); /** * Initialize from serialized information. */ GenericFunctionTypeElementImpl.forSerialized( ElementImpl enclosingElement, this._entityRef) - : super.forSerialized(enclosingElement); + : _kernel = null, + super.forSerialized(enclosingElement); @override TypeParameterizedElementMixin get enclosingTypeParameterContext { @@ -5365,16 +5379,29 @@ class GenericFunctionTypeElementImpl extends ElementImpl String get identifier => '-'; @override - List get kernelTypeParams => null; + List get kernelTypeParams => _kernel?.typeParameters; @override ElementKind get kind => ElementKind.GENERIC_FUNCTION_TYPE; @override List get parameters { - if (_entityRef != null) { - _parameters ??= ParameterElementImpl.resynthesizeList( - _entityRef.syntheticParams, this); + if (_parameters == null) { + if (_kernel != null) { + var parameters = + enclosingUnit._kernelContext.getFunctionTypeParameters(_kernel); + var positionalParameters = parameters[0]; + var namedParameters = parameters[1]; + _parameters = ParameterElementImpl.forKernelParameters( + this, + _kernel.requiredParameterCount, + positionalParameters, + namedParameters); + } + if (_entityRef != null) { + _parameters = ParameterElementImpl.resynthesizeList( + _entityRef.syntheticParams, this); + } } return _parameters ?? const []; } @@ -5393,10 +5420,16 @@ class GenericFunctionTypeElementImpl extends ElementImpl @override DartType get returnType { - if (_entityRef != null && _returnType == null) { - _returnType = enclosingUnit.resynthesizerContext.resolveTypeRef( - this, _entityRef.syntheticReturnType, - defaultVoid: false, declaredType: true); + if (_returnType == null) { + if (_kernel != null) { + _returnType = + enclosingUnit._kernelContext.getType(this, _kernel.returnType); + } + if (_entityRef != null) { + _returnType = enclosingUnit.resynthesizerContext.resolveTypeRef( + this, _entityRef.syntheticReturnType, + defaultVoid: false, declaredType: true); + } } return _returnType; } @@ -5412,7 +5445,7 @@ class GenericFunctionTypeElementImpl extends ElementImpl @override FunctionType get type { - if (_entityRef != null) { + if (_kernel != null || _entityRef != null) { _type ??= new FunctionTypeImpl.elementWithNameAndArgs( this, null, allEnclosingTypeParameterTypes, false); } @@ -8463,7 +8496,6 @@ class ParameterElementImpl extends VariableElementImpl * been build yet, build them and remember in the corresponding fields. */ void _resynthesizeTypeAndParameters() { - // TODO(scheglov) Don't resynthesize parameters. if (_kernel != null && _type == null) { kernel.DartType type = _kernel.type; _type = enclosingUnit._kernelContext.getType(this, type); diff --git a/pkg/analyzer/lib/src/kernel/resynthesize.dart b/pkg/analyzer/lib/src/kernel/resynthesize.dart index 626c3352dfe..d19ab783d63 100644 --- a/pkg/analyzer/lib/src/kernel/resynthesize.dart +++ b/pkg/analyzer/lib/src/kernel/resynthesize.dart @@ -826,23 +826,29 @@ class _KernelUnitResynthesizerContextImpl return element.type; } - var functionElement = new FunctionElementImpl.synthetic([], null); - functionElement.enclosingElement = context; + if (context is ParameterElementImpl) { + var typeElement = + new GenericFunctionTypeElementImpl.forKernel(context, kernelType); + return typeElement.type; + } else { + var functionElement = new FunctionElementImpl.synthetic([], null); + functionElement.enclosingElement = context; - functionElement.typeParameters = kernelType.typeParameters.map((k) { - return new TypeParameterElementImpl.forKernel(functionElement, k); - }).toList(growable: false); + functionElement.typeParameters = kernelType.typeParameters.map((k) { + return new TypeParameterElementImpl.forKernel(functionElement, k); + }).toList(growable: false); - var parameters = getFunctionTypeParameters(kernelType); - functionElement.parameters = ParameterElementImpl.forKernelParameters( - functionElement, - kernelType.requiredParameterCount, - parameters[0], - parameters[1]); + var parameters = getFunctionTypeParameters(kernelType); + functionElement.parameters = ParameterElementImpl.forKernelParameters( + functionElement, + kernelType.requiredParameterCount, + parameters[0], + parameters[1]); - functionElement.returnType = - getType(functionElement, kernelType.returnType); - return functionElement.type; + functionElement.returnType = + getType(functionElement, kernelType.returnType); + return functionElement.type; + } } // TODO(scheglov) Support other kernel types. diff --git a/pkg/analyzer/test/generated/non_error_resolver_kernel_test.dart b/pkg/analyzer/test/generated/non_error_resolver_kernel_test.dart index 4db0015a62a..926d622b7ed 100644 --- a/pkg/analyzer/test/generated/non_error_resolver_kernel_test.dart +++ b/pkg/analyzer/test/generated/non_error_resolver_kernel_test.dart @@ -18,14 +18,6 @@ class NonErrorResolverTest_Kernel extends NonErrorResolverTest_Driver { @override bool get enableKernelDriver => true; - @override - @failingTest - test_argumentTypeNotAssignable_invocation_functionParameter_generic() async { - fail('This test fails only in checked mode.'); - return super - .test_argumentTypeNotAssignable_invocation_functionParameter_generic(); - } - @override @failingTest test_async_flattened() async { @@ -165,20 +157,6 @@ class NonErrorResolverTest_Kernel extends NonErrorResolverTest_Driver { return super.test_constWithUndefinedConstructor(); } - @override - @failingTest - test_defaultValueInFunctionTypedParameter_named() async { - fail('This test fails only in checked mode.'); - return super.test_defaultValueInFunctionTypedParameter_named(); - } - - @override - @failingTest - test_defaultValueInFunctionTypedParameter_optional() async { - fail('This test fails only in checked mode.'); - return super.test_defaultValueInFunctionTypedParameter_optional(); - } - @override @failingTest test_deprecatedMemberUse_hide() async { @@ -191,13 +169,6 @@ class NonErrorResolverTest_Kernel extends NonErrorResolverTest_Driver { return super.test_duplicateDefinition_emptyName(); } - @override - @failingTest - test_fieldFormalParameter_functionTyped_named() async { - fail('This test fails only in checked mode.'); - return super.test_fieldFormalParameter_functionTyped_named(); - } - @override @failingTest test_fieldInitializedInInitializerAndDeclaration_fieldNotFinal() async { @@ -217,13 +188,6 @@ class NonErrorResolverTest_Kernel extends NonErrorResolverTest_Driver { return super.test_finalNotInitialized_fieldFormal(); } - @override - @failingTest - test_finalNotInitialized_functionTypedFieldFormal() async { - fail('This test fails only in checked mode.'); - return super.test_finalNotInitialized_functionTypedFieldFormal(); - } - @override @failingTest test_finalNotInitialized_hasNativeClause_hasConstructor() async { @@ -671,29 +635,6 @@ class NonErrorResolverTest_Kernel extends NonErrorResolverTest_Driver { return super.test_staticAccessToInstanceMember_annotation(); } - @override - @failingTest - test_typePromotion_booleanAnd_useInRight_accessedInClosureRight_noAssignment() async { - fail('This test fails only in checked mode.'); - return super - .test_typePromotion_booleanAnd_useInRight_accessedInClosureRight_noAssignment(); - } - - @override - @failingTest - test_typePromotion_conditional_useInThen_accessedInClosure_noAssignment() async { - fail('This test fails only in checked mode.'); - return super - .test_typePromotion_conditional_useInThen_accessedInClosure_noAssignment(); - } - - @override - @failingTest - test_typePromotion_if_accessedInClosure_noAssignment() async { - fail('This test fails only in checked mode.'); - return super.test_typePromotion_if_accessedInClosure_noAssignment(); - } - @override @failingTest test_undefinedConstructorInInitializer_explicit_named() async {