[FIR2IR] Fix generation of Any method call on expect receiver

#KT-57583 Fixed
This commit is contained in:
Kirill Rakhman
2023-03-28 11:05:52 +02:00
committed by Space Team
parent ed99f8bcdd
commit ee78c31174
17 changed files with 111 additions and 6 deletions
@@ -1501,13 +1501,21 @@ class Fir2IrDeclarationStorage(
): IrSymbol { ): IrSymbol {
val fir = firSymbol.fir as F val fir = firSymbol.fir as F
val irParent by lazy { findIrParent(fir) } val irParent by lazy { findIrParent(fir) }
val signature by lazy { signatureComposer.composeSignature(fir, fakeOverrideOwnerLookupTag, forceTopLevelPrivate) } val signature by lazy {
signatureComposer.composeSignature(
fir,
fakeOverrideOwnerLookupTag,
forceTopLevelPrivate = forceTopLevelPrivate,
forceExpect = fakeOverrideOwnerLookupTag?.toSymbol(session)?.isExpect == true
)
}
synchronized(symbolTable.lock) { synchronized(symbolTable.lock) {
getCachedIrDeclaration(fir, fakeOverrideOwnerLookupTag.takeIf { it !is ConeClassLookupTagWithFixedSymbol }) { getCachedIrDeclaration(fir, fakeOverrideOwnerLookupTag.takeIf { it !is ConeClassLookupTagWithFixedSymbol }) {
// Parent calculation provokes declaration calculation for some members from IrBuiltIns // Parent calculation provokes declaration calculation for some members from IrBuiltIns
@Suppress("UNUSED_EXPRESSION") irParent @Suppress("UNUSED_EXPRESSION") irParent
signature signature
}?.let { return it.symbol } }?.let { return it.symbol }
val parentOrigin = (irParent as? IrDeclaration)?.origin ?: IrDeclarationOrigin.DEFINED val parentOrigin = (irParent as? IrDeclaration)?.origin ?: IrDeclarationOrigin.DEFINED
val declarationOrigin = computeDeclarationOrigin(firSymbol, parentOrigin) val declarationOrigin = computeDeclarationOrigin(firSymbol, parentOrigin)
// TODO: package fragment members (?) // TODO: package fragment members (?)
@@ -18,6 +18,7 @@ interface Fir2IrSignatureComposer {
declaration: FirDeclaration, declaration: FirDeclaration,
containingClass: ConeClassLikeLookupTag? = null, containingClass: ConeClassLikeLookupTag? = null,
forceTopLevelPrivate: Boolean = false, forceTopLevelPrivate: Boolean = false,
forceExpect: Boolean = false,
): IdSignature? ): IdSignature?
fun composeAccessorSignature( fun composeAccessorSignature(
@@ -26,6 +27,7 @@ interface Fir2IrSignatureComposer {
containingClass: ConeClassLikeLookupTag? = null, containingClass: ConeClassLikeLookupTag? = null,
forceTopLevelPrivate: Boolean = false forceTopLevelPrivate: Boolean = false
): IdSignature? ): IdSignature?
fun composeTypeParameterSignature(typeParameter: FirTypeParameter, index: Int, containerSignature: IdSignature?): IdSignature? fun composeTypeParameterSignature(typeParameter: FirTypeParameter, index: Int, containerSignature: IdSignature?): IdSignature?
fun withFileSignature(sig: IdSignature.FileSignature, body: () -> Unit) fun withFileSignature(sig: IdSignature.FileSignature, body: () -> Unit)
} }
@@ -32,16 +32,16 @@ class FirBasedSignatureComposer(override val mangler: FirMangler) : Fir2IrSignat
fileSignature = null fileSignature = null
} }
private data class FirDeclarationWithParentId(val declaration: FirDeclaration, val classId: ClassId?) private data class FirDeclarationWithParentId(val declaration: FirDeclaration, val classId: ClassId?, val forceExpect: Boolean)
private val signatureCache = mutableMapOf<FirDeclarationWithParentId, IdSignature.CommonSignature>() private val signatureCache = mutableMapOf<FirDeclarationWithParentId, IdSignature.CommonSignature>()
inner class SignatureBuilder : FirVisitor<Unit, Any?>() { inner class SignatureBuilder(private val forceExpect: Boolean) : FirVisitor<Unit, Any?>() {
var hashId: Long? = null var hashId: Long? = null
var mask = 0L var mask = 0L
private fun setExpected(f: Boolean) { private fun setExpected(f: Boolean) {
mask = mask or IdSignature.Flags.IS_EXPECT.encode(f) mask = mask or IdSignature.Flags.IS_EXPECT.encode(f || forceExpect)
} }
override fun visitElement(element: FirElement, data: Any?) { override fun visitElement(element: FirElement, data: Any?) {
@@ -89,6 +89,7 @@ class FirBasedSignatureComposer(override val mangler: FirMangler) : Fir2IrSignat
declaration: FirDeclaration, declaration: FirDeclaration,
containingClass: ConeClassLikeLookupTag?, containingClass: ConeClassLikeLookupTag?,
forceTopLevelPrivate: Boolean, forceTopLevelPrivate: Boolean,
forceExpect: Boolean,
): IdSignature? { ): IdSignature? {
if (declaration is FirAnonymousObject || declaration is FirAnonymousFunction) return null if (declaration is FirAnonymousObject || declaration is FirAnonymousFunction) return null
if (declaration is FirRegularClass && declaration.classId.isLocal) return null if (declaration is FirRegularClass && declaration.classId.isLocal) return null
@@ -98,7 +99,7 @@ class FirBasedSignatureComposer(override val mangler: FirMangler) : Fir2IrSignat
if (declaration.dispatchReceiverClassLookupTagOrNull()?.classId?.isLocal == true || containingClass?.classId?.isLocal == true) return null if (declaration.dispatchReceiverClassLookupTagOrNull()?.classId?.isLocal == true || containingClass?.classId?.isLocal == true) return null
} }
val declarationWithParentId = FirDeclarationWithParentId(declaration, containingClass?.classId) val declarationWithParentId = FirDeclarationWithParentId(declaration, containingClass?.classId, forceExpect)
val publicSignature = signatureCache.getOrPut(declarationWithParentId) { val publicSignature = signatureCache.getOrPut(declarationWithParentId) {
calculatePublicSignature(declarationWithParentId) calculatePublicSignature(declarationWithParentId)
} }
@@ -114,7 +115,7 @@ class FirBasedSignatureComposer(override val mangler: FirMangler) : Fir2IrSignat
private fun calculatePublicSignature(declarationWithParentId: FirDeclarationWithParentId): IdSignature.CommonSignature { private fun calculatePublicSignature(declarationWithParentId: FirDeclarationWithParentId): IdSignature.CommonSignature {
val (declaration, containingClassId) = declarationWithParentId val (declaration, containingClassId) = declarationWithParentId
val builder = SignatureBuilder() val builder = SignatureBuilder(declarationWithParentId.forceExpect)
try { try {
declaration.accept(builder, null) declaration.accept(builder, null)
} catch (t: Throwable) { } catch (t: Throwable) {
@@ -33279,6 +33279,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/k2/basic"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/k2/basic"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
} }
@Test
@TestMetadata("anyMethodInExpect.kt")
public void testAnyMethodInExpect() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/anyMethodInExpect.kt");
}
@Test @Test
@TestMetadata("correctParentForTypeParameter.kt") @TestMetadata("correctParentForTypeParameter.kt")
public void testCorrectParentForTypeParameter() throws Exception { public void testCorrectParentForTypeParameter() throws Exception {
@@ -33279,6 +33279,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/k2/basic"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/k2/basic"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
} }
@Test
@TestMetadata("anyMethodInExpect.kt")
public void testAnyMethodInExpect() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/anyMethodInExpect.kt");
}
@Test @Test
@TestMetadata("correctParentForTypeParameter.kt") @TestMetadata("correctParentForTypeParameter.kt")
public void testCorrectParentForTypeParameter() throws Exception { public void testCorrectParentForTypeParameter() throws Exception {
@@ -0,0 +1,18 @@
// IGNORE_BACKEND_K1: ANY
// !LANGUAGE: +MultiPlatformProjects
// MODULE: common
// FILE: common.kt
expect class Runnable
fun foo(arg: Runnable) {
arg.hashCode()
}
// MODULE: main()()(common)
// FILE: test.kt
actual class Runnable
fun box() = "OK"
@@ -31905,6 +31905,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/k2/basic"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/k2/basic"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
} }
@Test
@TestMetadata("anyMethodInExpect.kt")
public void testAnyMethodInExpect() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/anyMethodInExpect.kt");
}
@Test @Test
@TestMetadata("correctParentForTypeParameter.kt") @TestMetadata("correctParentForTypeParameter.kt")
public void testCorrectParentForTypeParameter() throws Exception { public void testCorrectParentForTypeParameter() throws Exception {
@@ -33279,6 +33279,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/k2/basic"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/k2/basic"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
} }
@Test
@TestMetadata("anyMethodInExpect.kt")
public void testAnyMethodInExpect() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/anyMethodInExpect.kt");
}
@Test @Test
@TestMetadata("correctParentForTypeParameter.kt") @TestMetadata("correctParentForTypeParameter.kt")
public void testCorrectParentForTypeParameter() throws Exception { public void testCorrectParentForTypeParameter() throws Exception {
@@ -33279,6 +33279,12 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/k2/basic"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/k2/basic"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
} }
@Test
@TestMetadata("anyMethodInExpect.kt")
public void testAnyMethodInExpect() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/anyMethodInExpect.kt");
}
@Test @Test
@TestMetadata("correctParentForTypeParameter.kt") @TestMetadata("correctParentForTypeParameter.kt")
public void testCorrectParentForTypeParameter() throws Exception { public void testCorrectParentForTypeParameter() throws Exception {
@@ -27187,6 +27187,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/k2/basic"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/k2/basic"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
} }
@TestMetadata("anyMethodInExpect.kt")
public void testAnyMethodInExpect() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/anyMethodInExpect.kt");
}
@TestMetadata("correctParentForTypeParameter.kt") @TestMetadata("correctParentForTypeParameter.kt")
public void testCorrectParentForTypeParameter() throws Exception { public void testCorrectParentForTypeParameter() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/correctParentForTypeParameter.kt"); runTest("compiler/testData/codegen/box/multiplatform/k2/basic/correctParentForTypeParameter.kt");
@@ -23111,6 +23111,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/k2/basic"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/k2/basic"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
} }
@Test
@TestMetadata("anyMethodInExpect.kt")
public void testAnyMethodInExpect() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/anyMethodInExpect.kt");
}
@Test @Test
@TestMetadata("correctParentForTypeParameter.kt") @TestMetadata("correctParentForTypeParameter.kt")
public void testCorrectParentForTypeParameter() throws Exception { public void testCorrectParentForTypeParameter() throws Exception {
@@ -23225,6 +23225,12 @@ public class FirJsCodegenBoxTestGenerated extends AbstractFirJsCodegenBoxTest {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/k2/basic"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/k2/basic"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
} }
@Test
@TestMetadata("anyMethodInExpect.kt")
public void testAnyMethodInExpect() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/anyMethodInExpect.kt");
}
@Test @Test
@TestMetadata("correctParentForTypeParameter.kt") @TestMetadata("correctParentForTypeParameter.kt")
public void testCorrectParentForTypeParameter() throws Exception { public void testCorrectParentForTypeParameter() throws Exception {
@@ -23225,6 +23225,12 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/k2/basic"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/k2/basic"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
} }
@Test
@TestMetadata("anyMethodInExpect.kt")
public void testAnyMethodInExpect() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/anyMethodInExpect.kt");
}
@Test @Test
@TestMetadata("correctParentForTypeParameter.kt") @TestMetadata("correctParentForTypeParameter.kt")
public void testCorrectParentForTypeParameter() throws Exception { public void testCorrectParentForTypeParameter() throws Exception {
@@ -23225,6 +23225,12 @@ public class IrJsES6CodegenBoxTestGenerated extends AbstractIrJsES6CodegenBoxTes
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/k2/basic"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/k2/basic"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
} }
@Test
@TestMetadata("anyMethodInExpect.kt")
public void testAnyMethodInExpect() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/anyMethodInExpect.kt");
}
@Test @Test
@TestMetadata("correctParentForTypeParameter.kt") @TestMetadata("correctParentForTypeParameter.kt")
public void testCorrectParentForTypeParameter() throws Exception { public void testCorrectParentForTypeParameter() throws Exception {
@@ -26651,6 +26651,12 @@ public class FirNativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTe
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/k2/basic"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.NATIVE, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/k2/basic"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.NATIVE, true);
} }
@Test
@TestMetadata("anyMethodInExpect.kt")
public void testAnyMethodInExpect() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/anyMethodInExpect.kt");
}
@Test @Test
@TestMetadata("correctParentForTypeParameter.kt") @TestMetadata("correctParentForTypeParameter.kt")
public void testCorrectParentForTypeParameter() throws Exception { public void testCorrectParentForTypeParameter() throws Exception {
@@ -26348,6 +26348,12 @@ public class K1NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTes
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/k2/basic"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.NATIVE, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/k2/basic"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.NATIVE, true);
} }
@Test
@TestMetadata("anyMethodInExpect.kt")
public void testAnyMethodInExpect() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/anyMethodInExpect.kt");
}
@Test @Test
@TestMetadata("correctParentForTypeParameter.kt") @TestMetadata("correctParentForTypeParameter.kt")
public void testCorrectParentForTypeParameter() throws Exception { public void testCorrectParentForTypeParameter() throws Exception {
@@ -20705,6 +20705,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/k2/basic"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/k2/basic"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
} }
@TestMetadata("anyMethodInExpect.kt")
public void testAnyMethodInExpect() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/anyMethodInExpect.kt");
}
@TestMetadata("correctParentForTypeParameter.kt") @TestMetadata("correctParentForTypeParameter.kt")
public void testCorrectParentForTypeParameter() throws Exception { public void testCorrectParentForTypeParameter() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/basic/correctParentForTypeParameter.kt"); runTest("compiler/testData/codegen/box/multiplatform/k2/basic/correctParentForTypeParameter.kt");