From 66b18bce4088f6067a14f20c27687e24fc1b2e68 Mon Sep 17 00:00:00 2001 From: Konstantin Shcheglov Date: Thu, 10 Aug 2023 21:14:04 +0000 Subject: [PATCH] Extension types. Apply substitution when copy superinterface members into extension types. Change-Id: I93d8ab4582491bad262253eedc94dc63d33c5457 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/319900 Reviewed-by: Brian Wilkerson Reviewed-by: Phil Quitslund Commit-Queue: Konstantin Shcheglov --- .../dart/element/inheritance_manager3.dart | 3 +- .../element/inheritance_manager3_test.dart | 58 +++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart b/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart index 64b0cc5e59d..6e1f25c8978 100644 --- a/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart +++ b/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart @@ -692,9 +692,10 @@ class InheritanceManager3 { final extensionCandidates = >{}; final notExtensionCandidates = >{}; for (final interface in augmented.interfaces) { + final substitution = Substitution.fromInterfaceType(interface); for (final entry in getInterface(interface.element).map.entries) { final name = entry.key; - final executable = entry.value; + final executable = ExecutableMember.from2(entry.value, substitution); if (executable.enclosingElement is ExtensionTypeElement) { (extensionCandidates[name] ??= []).add(executable); } else { diff --git a/pkg/analyzer/test/src/dart/element/inheritance_manager3_test.dart b/pkg/analyzer/test/src/dart/element/inheritance_manager3_test.dart index b50829e78d0..7df19da7182 100644 --- a/pkg/analyzer/test/src/dart/element/inheritance_manager3_test.dart +++ b/pkg/analyzer/test/src/dart/element/inheritance_manager3_test.dart @@ -765,6 +765,34 @@ declared '''); } + test_noDeclaration_implementClass_generic_method() async { + final library = await buildLibrary(r''' +class A { + void foo(T a) {} +} + +class B extends A {} + +extension type C(B it) implements A {} +'''); + + final element = library.extensionType('C'); + assertInterfaceText(element, r''' +map + foo: MethodMember + base: self::@class::A::@method::foo + substitution: {T: int} + it: self::@extensionType::C::@getter::it +declared + it: self::@extensionType::C::@getter::it +redeclared + foo + MethodMember + base: self::@class::A::@method::foo + substitution: {T: int} +'''); + } + test_noDeclaration_implementClass_implementExtensionType_hasConflict() async { final library = await buildLibrary(r''' class A { @@ -932,6 +960,36 @@ redeclared '''); } + test_noDeclaration_implementExtensionType_generic_method() async { + final library = await buildLibrary(r''' +extension type A(T it) { + void foo(T a) {} +} + +extension type B(int it) implements A {} +'''); + + final element = library.extensionType('B'); + assertInterfaceText(element, r''' +map + foo: MethodMember + base: self::@extensionType::A::@method::foo + substitution: {T: int} + it: self::@extensionType::B::@getter::it +declared + it: self::@extensionType::B::@getter::it +redeclared + foo + MethodMember + base: self::@extensionType::A::@method::foo + substitution: {T: int} + it + PropertyAccessorMember + base: self::@extensionType::A::@getter::it + substitution: {T: int} +'''); + } + test_noDeclaration_implementExtensionType_method() async { final library = await buildLibrary(r''' extension type A(int it) {