KT-43399 properly erase extension receiver type in property$annotations
This commit is contained in:
@@ -97,8 +97,9 @@ private val lateinitUsageLoweringPhase = makeIrFilePhase(
|
|||||||
internal val propertiesPhase = makeIrFilePhase(
|
internal val propertiesPhase = makeIrFilePhase(
|
||||||
::JvmPropertiesLowering,
|
::JvmPropertiesLowering,
|
||||||
name = "Properties",
|
name = "Properties",
|
||||||
description = "Move fields and accessors for properties to their classes, replace calls to default property accessors " +
|
description = "Move fields and accessors for properties to their classes, " +
|
||||||
"with field accesses, remove unused accessors and create synthetic methods for property annotations",
|
"replace calls to default property accessors with field accesses, " +
|
||||||
|
"remove unused accessors and create synthetic methods for property annotations",
|
||||||
stickyPostconditions = setOf((PropertiesLowering)::checkNoProperties)
|
stickyPostconditions = setOf((PropertiesLowering)::checkNoProperties)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+37
-6
@@ -26,9 +26,8 @@ import org.jetbrains.kotlin.ir.expressions.IrCall
|
|||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrFieldAccessExpression
|
import org.jetbrains.kotlin.ir.expressions.IrFieldAccessExpression
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl
|
||||||
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.types.makeNotNull
|
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
||||||
import org.jetbrains.kotlin.ir.types.typeWith
|
|
||||||
import org.jetbrains.kotlin.ir.util.coerceToUnit
|
import org.jetbrains.kotlin.ir.util.coerceToUnit
|
||||||
import org.jetbrains.kotlin.ir.util.render
|
import org.jetbrains.kotlin.ir.util.render
|
||||||
import org.jetbrains.kotlin.ir.util.resolveFakeOverride
|
import org.jetbrains.kotlin.ir.util.resolveFakeOverride
|
||||||
@@ -69,7 +68,13 @@ class JvmPropertiesLowering(private val backendContext: JvmBackendContext) : IrE
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun IrBuilderWithScope.substituteSetter(irProperty: IrProperty, expression: IrCall): IrExpression =
|
private fun IrBuilderWithScope.substituteSetter(irProperty: IrProperty, expression: IrCall): IrExpression =
|
||||||
patchReceiver(irSetField(expression.dispatchReceiver, irProperty.resolveFakeOverride()!!.backingField!!, expression.getValueArgument(0)!!))
|
patchReceiver(
|
||||||
|
irSetField(
|
||||||
|
expression.dispatchReceiver,
|
||||||
|
irProperty.resolveFakeOverride()!!.backingField!!,
|
||||||
|
expression.getValueArgument(0)!!
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
private fun IrBuilderWithScope.substituteGetter(irProperty: IrProperty, expression: IrCall): IrExpression {
|
private fun IrBuilderWithScope.substituteGetter(irProperty: IrProperty, expression: IrCall): IrExpression {
|
||||||
val backingField = irProperty.resolveFakeOverride()!!.backingField!!
|
val backingField = irProperty.resolveFakeOverride()!!.backingField!!
|
||||||
@@ -131,8 +136,10 @@ class JvmPropertiesLowering(private val backendContext: JvmBackendContext) : IrE
|
|||||||
returnType = backendContext.irBuiltIns.unitType
|
returnType = backendContext.irBuiltIns.unitType
|
||||||
}.apply {
|
}.apply {
|
||||||
declaration.getter?.extensionReceiverParameter?.let { extensionReceiver ->
|
declaration.getter?.extensionReceiverParameter?.let { extensionReceiver ->
|
||||||
// Use raw type of extension receiver to avoid generic signature, which would be useless for this method.
|
extensionReceiverParameter = extensionReceiver.copyTo(
|
||||||
extensionReceiverParameter = extensionReceiver.copyTo(this, type = extensionReceiver.type.classifierOrFail.typeWith())
|
this,
|
||||||
|
type = extensionReceiver.type.erasePropertyAnnotationsExtensionReceiverType()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
body = IrBlockBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET)
|
body = IrBlockBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET)
|
||||||
@@ -142,6 +149,30 @@ class JvmPropertiesLowering(private val backendContext: JvmBackendContext) : IrE
|
|||||||
metadata = declaration.metadata
|
metadata = declaration.metadata
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun IrType.erasePropertyAnnotationsExtensionReceiverType(): IrType {
|
||||||
|
// Use raw type of extension receiver to avoid generic signature,
|
||||||
|
// which should not be generated for '...$annotations' method.
|
||||||
|
val classifier = classifierOrFail
|
||||||
|
return if (this is IrSimpleType && isArray()) {
|
||||||
|
when (val arg0 = arguments[0]) {
|
||||||
|
is IrStarProjection -> {
|
||||||
|
// 'Array<*>' becomes 'Array<*>'
|
||||||
|
this
|
||||||
|
}
|
||||||
|
is IrTypeProjection -> {
|
||||||
|
// 'Array<VARIANCE TYPE>' becomes 'Array<VARIANCE erase(TYPE)>'
|
||||||
|
classifier.typeWithArguments(
|
||||||
|
listOf(makeTypeProjection(arg0.type.erasePropertyAnnotationsExtensionReceiverType(), arg0.variance))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
else ->
|
||||||
|
throw AssertionError("Unexpected type argument: $arg0")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
classifier.typeWith()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun computeSyntheticMethodName(property: IrProperty): String {
|
private fun computeSyntheticMethodName(property: IrProperty): String {
|
||||||
val baseName =
|
val baseName =
|
||||||
if (backendContext.state.languageVersionSettings.supportsFeature(LanguageFeature.UseGetterNameForPropertyAnnotationsMethodOnJvm)) {
|
if (backendContext.state.languageVersionSettings.supportsFeature(LanguageFeature.UseGetterNameForPropertyAnnotationsMethodOnJvm)) {
|
||||||
|
|||||||
@@ -87,8 +87,13 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
|
|||||||
|
|
||||||
override fun KotlinTypeMarker.getArgument(index: Int): TypeArgumentMarker =
|
override fun KotlinTypeMarker.getArgument(index: Int): TypeArgumentMarker =
|
||||||
when (this) {
|
when (this) {
|
||||||
is IrSimpleType -> arguments[index]
|
is IrSimpleType ->
|
||||||
else -> error("Type $this has no arguments")
|
if (index >= arguments.size)
|
||||||
|
error("No argument $index in type '${this.render()}'")
|
||||||
|
else
|
||||||
|
arguments[index]
|
||||||
|
else ->
|
||||||
|
error("Type $this has no arguments")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun KotlinTypeMarker.asTypeArgument() = this as IrTypeArgument
|
override fun KotlinTypeMarker.asTypeArgument() = this as IrTypeArgument
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
interface B {
|
||||||
|
@A
|
||||||
|
val Array<Int>.a: Int
|
||||||
|
|
||||||
|
@A
|
||||||
|
val Array<Array<Int>>.b: Int
|
||||||
|
|
||||||
|
@A
|
||||||
|
val Array<IntArray>.c: Int
|
||||||
|
|
||||||
|
@A
|
||||||
|
val Array<*>.d: Int
|
||||||
|
|
||||||
|
@A
|
||||||
|
val Array<out String>.e: Int
|
||||||
|
|
||||||
|
@A
|
||||||
|
val Array<in String>.f: Int
|
||||||
|
}
|
||||||
|
|
||||||
|
annotation class A
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
@java.lang.annotation.Retention
|
||||||
|
@kotlin.Metadata
|
||||||
|
public annotation class A {
|
||||||
|
// source: 'kt43399.kt'
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
public final class B$DefaultImpls {
|
||||||
|
// source: 'kt43399.kt'
|
||||||
|
public synthetic deprecated static @A method getA$annotations(p0: java.lang.Integer[]): void
|
||||||
|
public synthetic deprecated static @A method getB$annotations(p0: java.lang.Integer[][]): void
|
||||||
|
public synthetic deprecated static @A method getC$annotations(p0: int[][]): void
|
||||||
|
public synthetic deprecated static @A method getD$annotations(p0: java.lang.Object[]): void
|
||||||
|
public synthetic deprecated static @A method getE$annotations(p0: java.lang.String[]): void
|
||||||
|
public synthetic deprecated static @A method getF$annotations(p0: java.lang.Object[]): void
|
||||||
|
public final inner class B$DefaultImpls
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
public interface B {
|
||||||
|
// source: 'kt43399.kt'
|
||||||
|
public abstract method getA(@org.jetbrains.annotations.NotNull p0: java.lang.Integer[]): int
|
||||||
|
public abstract method getB(@org.jetbrains.annotations.NotNull p0: java.lang.Integer[][]): int
|
||||||
|
public abstract method getC(@org.jetbrains.annotations.NotNull p0: int[][]): int
|
||||||
|
public abstract method getD(@org.jetbrains.annotations.NotNull p0: java.lang.Object[]): int
|
||||||
|
public abstract method getE(@org.jetbrains.annotations.NotNull p0: java.lang.String[]): int
|
||||||
|
public abstract method getF(@org.jetbrains.annotations.NotNull p0: java.lang.Object[]): int
|
||||||
|
public final inner class B$DefaultImpls
|
||||||
|
}
|
||||||
+5
@@ -241,6 +241,11 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest {
|
|||||||
runTest("compiler/testData/codegen/bytecodeListing/annotations/kt27895.kt");
|
runTest("compiler/testData/codegen/bytecodeListing/annotations/kt27895.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt43399.kt")
|
||||||
|
public void testKt43399() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeListing/annotations/kt43399.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt9320.kt")
|
@TestMetadata("kt9320.kt")
|
||||||
public void testKt9320() throws Exception {
|
public void testKt9320() throws Exception {
|
||||||
runTest("compiler/testData/codegen/bytecodeListing/annotations/kt9320.kt");
|
runTest("compiler/testData/codegen/bytecodeListing/annotations/kt9320.kt");
|
||||||
|
|||||||
+5
@@ -241,6 +241,11 @@ public class IrBytecodeListingTestGenerated extends AbstractIrBytecodeListingTes
|
|||||||
runTest("compiler/testData/codegen/bytecodeListing/annotations/kt27895.kt");
|
runTest("compiler/testData/codegen/bytecodeListing/annotations/kt27895.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt43399.kt")
|
||||||
|
public void testKt43399() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeListing/annotations/kt43399.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt9320.kt")
|
@TestMetadata("kt9320.kt")
|
||||||
public void testKt9320() throws Exception {
|
public void testKt9320() throws Exception {
|
||||||
runTest("compiler/testData/codegen/bytecodeListing/annotations/kt9320.kt");
|
runTest("compiler/testData/codegen/bytecodeListing/annotations/kt9320.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user