FIR2IR: add fallback for a synthetic property override situation
This commit is contained in:
committed by
teamcity
parent
67a05883d6
commit
b50350f6a5
+28
-5
@@ -1191,13 +1191,15 @@ class Fir2IrDeclarationStorage(
|
|||||||
if (fir.isLocal) {
|
if (fir.isLocal) {
|
||||||
return localStorage.getDelegatedProperty(fir)?.symbol ?: getIrVariableSymbol(fir)
|
return localStorage.getDelegatedProperty(fir)?.symbol ?: getIrVariableSymbol(fir)
|
||||||
}
|
}
|
||||||
val unmatchedReceiver = dispatchReceiverLookupTag != firPropertySymbol.containingClass()
|
val containingClassLookupTag = firPropertySymbol.containingClass()
|
||||||
|
val unmatchedReceiver = dispatchReceiverLookupTag != containingClassLookupTag
|
||||||
if (unmatchedReceiver) {
|
if (unmatchedReceiver) {
|
||||||
generateLazyFakeOverrides(fir.name, dispatchReceiverLookupTag)
|
generateLazyFakeOverrides(fir.name, dispatchReceiverLookupTag)
|
||||||
}
|
}
|
||||||
val originalSymbol = getIrCallableSymbol(
|
|
||||||
|
fun ConeClassLikeLookupTag?.getIrCallableSymbol() = getIrCallableSymbol(
|
||||||
firPropertySymbol,
|
firPropertySymbol,
|
||||||
dispatchReceiverLookupTag,
|
dispatchReceiverLookupTag = this,
|
||||||
getCachedIrDeclaration = ::getCachedIrProperty,
|
getCachedIrDeclaration = ::getCachedIrProperty,
|
||||||
createIrDeclaration = { parent, origin -> createIrProperty(fir, parent, predefinedOrigin = origin) },
|
createIrDeclaration = { parent, origin -> createIrProperty(fir, parent, predefinedOrigin = origin) },
|
||||||
createIrLazyDeclaration = { signature, lazyParent, declarationOrigin ->
|
createIrLazyDeclaration = { signature, lazyParent, declarationOrigin ->
|
||||||
@@ -1219,13 +1221,34 @@ class Fir2IrDeclarationStorage(
|
|||||||
return symbol
|
return symbol
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val originalSymbol = dispatchReceiverLookupTag.getIrCallableSymbol()
|
||||||
|
val originalProperty = originalSymbol.owner as IrProperty
|
||||||
|
|
||||||
|
fun IrProperty.isIllegalFakeOverride(): Boolean {
|
||||||
|
if (!isFakeOverride) return false
|
||||||
|
val overriddenSymbols = overriddenSymbols
|
||||||
|
if (overriddenSymbols.isEmpty() || overriddenSymbols.any { it.owner.isIllegalFakeOverride() }) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dispatchReceiverLookupTag != null &&
|
||||||
|
firPropertySymbol is FirSyntheticPropertySymbol &&
|
||||||
|
originalProperty.isIllegalFakeOverride()
|
||||||
|
) {
|
||||||
|
// Fallback for a synthetic property complex case
|
||||||
|
return containingClassLookupTag.getIrCallableSymbol()
|
||||||
|
}
|
||||||
|
|
||||||
return if (dispatchReceiverLookupTag is ConeClassLookupTagWithFixedSymbol &&
|
return if (dispatchReceiverLookupTag is ConeClassLookupTagWithFixedSymbol &&
|
||||||
dispatchReceiverLookupTag != firPropertySymbol.containingClass()
|
dispatchReceiverLookupTag != containingClassLookupTag
|
||||||
) {
|
) {
|
||||||
val dispatchReceiverIrClass =
|
val dispatchReceiverIrClass =
|
||||||
classifierStorage.getIrClassSymbol(dispatchReceiverLookupTag.toSymbol(session) as FirClassSymbol).owner
|
classifierStorage.getIrClassSymbol(dispatchReceiverLookupTag.toSymbol(session) as FirClassSymbol).owner
|
||||||
dispatchReceiverIrClass.declarations.find {
|
dispatchReceiverIrClass.declarations.find {
|
||||||
it is IrProperty && it.isFakeOverride && it.name == fir.name && it.overrides(originalSymbol.owner as IrProperty)
|
it is IrProperty && it.isFakeOverride && it.name == fir.name && it.overrides(originalProperty)
|
||||||
}?.symbol as IrPropertySymbol
|
}?.symbol as IrPropertySymbol
|
||||||
} else {
|
} else {
|
||||||
originalSymbol
|
originalSymbol
|
||||||
|
|||||||
+6
@@ -16342,6 +16342,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
runTest("compiler/testData/codegen/box/fir/ConstValAccess.kt");
|
runTest("compiler/testData/codegen/box/fir/ConstValAccess.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("CustomHashSetSize.kt")
|
||||||
|
public void testCustomHashSetSize() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/fir/CustomHashSetSize.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("CustomThrowableMessage.kt")
|
@TestMetadata("CustomThrowableMessage.kt")
|
||||||
public void testCustomThrowableMessage() throws Exception {
|
public void testCustomThrowableMessage() throws Exception {
|
||||||
|
|||||||
@@ -0,0 +1,65 @@
|
|||||||
|
// TARGET_BACKEND: JVM_IR
|
||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
// MODULE: m1
|
||||||
|
// FILE: m1/THash.java
|
||||||
|
|
||||||
|
package m1;
|
||||||
|
|
||||||
|
public class THash {
|
||||||
|
|
||||||
|
public int size() { return 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: m1/TObjectHash.java
|
||||||
|
|
||||||
|
package m1;
|
||||||
|
|
||||||
|
public class TObjectHash<T> extends THash {}
|
||||||
|
|
||||||
|
// FILE: m1/THashSet.java
|
||||||
|
|
||||||
|
package m1;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class THashSet<T> extends TObjectHash<T> implements Set<T> {
|
||||||
|
public Iterator<T> iterator() { return null; }
|
||||||
|
|
||||||
|
public boolean isEmpty() { return false; }
|
||||||
|
|
||||||
|
public boolean contains(Object o) { return false; }
|
||||||
|
|
||||||
|
public Object[] toArray() { return new Object[1]; }
|
||||||
|
|
||||||
|
public <T> T[] toArray(T[] a) { throw new RuntimeException(); }
|
||||||
|
|
||||||
|
public boolean add(T e) { return false; }
|
||||||
|
|
||||||
|
public boolean remove(Object o) { return false; }
|
||||||
|
|
||||||
|
public boolean containsAll(Collection<?> c) { return false; }
|
||||||
|
|
||||||
|
public boolean addAll(Collection<? extends T> c) { return false; }
|
||||||
|
|
||||||
|
public boolean retainAll(Collection<?> c) { return false; }
|
||||||
|
|
||||||
|
public boolean removeAll(Collection<?> c) { return false; }
|
||||||
|
|
||||||
|
public void clear() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: m2(m1)
|
||||||
|
// FILE: box.kt
|
||||||
|
|
||||||
|
package m2
|
||||||
|
import m1.THashSet
|
||||||
|
|
||||||
|
interface HeaderSet : Set<String>
|
||||||
|
|
||||||
|
class MutableHeaderSet : HeaderSet, MutableSet<String>, THashSet<String>()
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val size1 = THashSet<String>().size
|
||||||
|
val size2 = MutableHeaderSet().size
|
||||||
|
return if (size1 == 1 && size2 == 1) "OK" else "$size1/$size2"
|
||||||
|
}
|
||||||
+6
@@ -16342,6 +16342,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/fir/ConstValAccess.kt");
|
runTest("compiler/testData/codegen/box/fir/ConstValAccess.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("CustomHashSetSize.kt")
|
||||||
|
public void testCustomHashSetSize() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/fir/CustomHashSetSize.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("CustomThrowableMessage.kt")
|
@TestMetadata("CustomThrowableMessage.kt")
|
||||||
public void testCustomThrowableMessage() throws Exception {
|
public void testCustomThrowableMessage() throws Exception {
|
||||||
|
|||||||
Reference in New Issue
Block a user