diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DelegationResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DelegationResolver.kt index 5ea77980e7518..d50310f1fdace 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DelegationResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DelegationResolver.kt @@ -151,7 +151,11 @@ class DelegationResolver private constructor( // descriptor = Foo // toInterface = Bar // delegateExpressionType = typeof(baz) - // return Map + // + // This method returns a map where keys are members of Foo, and values are members of typeof(baz). + // + // In case delegation is to an error type, which is useful for KAPT stub generation mode, typeof(baz) has no members, so we return + // a map from each element to it (so keys = values in the returned map). fun getDelegates( descriptor: ClassDescriptor, toInterface: ClassDescriptor, @@ -175,18 +179,22 @@ class DelegationResolver private constructor( val actualDelegates = DescriptorUtils.getAllOverriddenDescriptors(delegatingMember) .filter { it.containingDeclaration == toInterface } .map { overriddenDescriptor -> - val name = overriddenDescriptor.name - // this is the actual member of delegateExpressionType that we are delegating to - (scope.getContributedFunctions(name, NoLookupLocation.WHEN_CHECK_OVERRIDES) + - scope.getContributedVariables(name, NoLookupLocation.WHEN_CHECK_OVERRIDES)) - .firstOrNull { - it == overriddenDescriptor || OverridingUtil.overrides( - it, - overriddenDescriptor, - it.module.isTypeRefinementEnabled(), - true - ) - } + if (scopeType.isError) { + overriddenDescriptor + } else { + val name = overriddenDescriptor.name + // This is the actual member of delegateExpressionType that we are delegating to. + (scope.getContributedFunctions(name, NoLookupLocation.WHEN_CHECK_OVERRIDES) + + scope.getContributedVariables(name, NoLookupLocation.WHEN_CHECK_OVERRIDES)) + .firstOrNull { + it == overriddenDescriptor || OverridingUtil.overrides( + it, + overriddenDescriptor, + it.module.isTypeRefinementEnabled(), + true + ) + } + } } actualDelegates.firstOrNull() diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ClassGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ClassGenerator.kt index 5bd1cc7cf5f7a..9c06c7e50ce7a 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ClassGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ClassGenerator.kt @@ -325,7 +325,9 @@ class ClassGenerator( // TODO could possibly refer to scoped type parameters for property accessors irFunction.returnType = delegatedDescriptor.returnType!!.toIrType() - irFunction.body = generateDelegateFunctionBody(irDelegate, delegatedDescriptor, delegateToDescriptor, irFunction) + if (context.configuration.generateBodies) { + irFunction.body = generateDelegateFunctionBody(irDelegate, delegatedDescriptor, delegateToDescriptor, irFunction) + } } private fun generateDelegateFunctionBody( diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/delegationAndCompanionObject.kt b/plugins/kapt3/kapt3-compiler/testData/converter/delegationAndCompanionObject.kt new file mode 100644 index 0000000000000..009f9176a3339 --- /dev/null +++ b/plugins/kapt3/kapt3-compiler/testData/converter/delegationAndCompanionObject.kt @@ -0,0 +1,11 @@ +// CORRECT_ERROR_TYPES + +@Suppress("UNRESOLVED_REFERENCE") +interface A { + fun inject(b: B) + val x: String + + companion object : B() + + abstract class B : A by Unresolved +} diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/delegationAndCompanionObject.txt b/plugins/kapt3/kapt3-compiler/testData/converter/delegationAndCompanionObject.txt new file mode 100644 index 0000000000000..8d5691701e3c9 --- /dev/null +++ b/plugins/kapt3/kapt3-compiler/testData/converter/delegationAndCompanionObject.txt @@ -0,0 +1,39 @@ +@kotlin.Metadata() +@kotlin.Suppress(names = {"UNRESOLVED_REFERENCE"}) +public abstract interface A { + @org.jetbrains.annotations.NotNull() + public static final A.Companion Companion = null; + + public abstract void inject(@org.jetbrains.annotations.NotNull() + A.B b); + + @org.jetbrains.annotations.NotNull() + public abstract java.lang.String getX(); + + @kotlin.Metadata() + public static abstract class B implements A { + + @java.lang.Override() + public void inject(@org.jetbrains.annotations.NotNull() + A.B b) { + } + + @java.lang.Override() + @org.jetbrains.annotations.NotNull() + public java.lang.String getX() { + return null; + } + + public B() { + super(); + } + } + + @kotlin.Metadata() + public static final class Companion extends A.B { + + private Companion() { + super(); + } + } +} diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/delegationAndCompanionObject_ir.txt b/plugins/kapt3/kapt3-compiler/testData/converter/delegationAndCompanionObject_ir.txt new file mode 100644 index 0000000000000..ad476c74242a1 --- /dev/null +++ b/plugins/kapt3/kapt3-compiler/testData/converter/delegationAndCompanionObject_ir.txt @@ -0,0 +1,39 @@ +@kotlin.Metadata() +@kotlin.Suppress(names = {"UNRESOLVED_REFERENCE"}) +public abstract interface A { + @org.jetbrains.annotations.NotNull() + public static final A.Companion Companion = null; + + public abstract void inject(@org.jetbrains.annotations.NotNull() + A.B b); + + @org.jetbrains.annotations.NotNull() + public abstract java.lang.String getX(); + + @kotlin.Metadata() + public static abstract class B implements A { + + public B() { + super(); + } + + @java.lang.Override() + @org.jetbrains.annotations.NotNull() + public java.lang.String getX() { + return null; + } + + @java.lang.Override() + public void inject(@org.jetbrains.annotations.NotNull() + A.B b) { + } + } + + @kotlin.Metadata() + public static final class Companion extends A.B { + + private Companion() { + super(); + } + } +} diff --git a/plugins/kapt3/kapt3-compiler/tests-gen/org/jetbrains/kotlin/kapt3/test/runners/ClassFileToSourceStubConverterTestGenerated.java b/plugins/kapt3/kapt3-compiler/tests-gen/org/jetbrains/kotlin/kapt3/test/runners/ClassFileToSourceStubConverterTestGenerated.java index 62d590f8f13b7..4c52b34e12801 100644 --- a/plugins/kapt3/kapt3-compiler/tests-gen/org/jetbrains/kotlin/kapt3/test/runners/ClassFileToSourceStubConverterTestGenerated.java +++ b/plugins/kapt3/kapt3-compiler/tests-gen/org/jetbrains/kotlin/kapt3/test/runners/ClassFileToSourceStubConverterTestGenerated.java @@ -157,6 +157,12 @@ public void testDelegatedProperties() throws Exception { runTest("plugins/kapt3/kapt3-compiler/testData/converter/delegatedProperties.kt"); } + @Test + @TestMetadata("delegationAndCompanionObject.kt") + public void testDelegationAndCompanionObject() throws Exception { + runTest("plugins/kapt3/kapt3-compiler/testData/converter/delegationAndCompanionObject.kt"); + } + @Test @TestMetadata("deprecated.kt") public void testDeprecated() throws Exception { diff --git a/plugins/kapt3/kapt3-compiler/tests-gen/org/jetbrains/kotlin/kapt3/test/runners/IrClassFileToSourceStubConverterTestGenerated.java b/plugins/kapt3/kapt3-compiler/tests-gen/org/jetbrains/kotlin/kapt3/test/runners/IrClassFileToSourceStubConverterTestGenerated.java index 80558ea7ddae1..999f37cec6820 100644 --- a/plugins/kapt3/kapt3-compiler/tests-gen/org/jetbrains/kotlin/kapt3/test/runners/IrClassFileToSourceStubConverterTestGenerated.java +++ b/plugins/kapt3/kapt3-compiler/tests-gen/org/jetbrains/kotlin/kapt3/test/runners/IrClassFileToSourceStubConverterTestGenerated.java @@ -157,6 +157,12 @@ public void testDelegatedProperties() throws Exception { runTest("plugins/kapt3/kapt3-compiler/testData/converter/delegatedProperties.kt"); } + @Test + @TestMetadata("delegationAndCompanionObject.kt") + public void testDelegationAndCompanionObject() throws Exception { + runTest("plugins/kapt3/kapt3-compiler/testData/converter/delegationAndCompanionObject.kt"); + } + @Test @TestMetadata("deprecated.kt") public void testDeprecated() throws Exception {