FIR2IR: add fallback for a synthetic property override situation

This commit is contained in:
Mikhail Glukhikh
2021-10-28 19:28:24 +03:00
committed by teamcity
parent 67a05883d6
commit b50350f6a5
4 changed files with 105 additions and 5 deletions
@@ -1191,13 +1191,15 @@ class Fir2IrDeclarationStorage(
if (fir.isLocal) {
return localStorage.getDelegatedProperty(fir)?.symbol ?: getIrVariableSymbol(fir)
}
val unmatchedReceiver = dispatchReceiverLookupTag != firPropertySymbol.containingClass()
val containingClassLookupTag = firPropertySymbol.containingClass()
val unmatchedReceiver = dispatchReceiverLookupTag != containingClassLookupTag
if (unmatchedReceiver) {
generateLazyFakeOverrides(fir.name, dispatchReceiverLookupTag)
}
val originalSymbol = getIrCallableSymbol(
fun ConeClassLikeLookupTag?.getIrCallableSymbol() = getIrCallableSymbol(
firPropertySymbol,
dispatchReceiverLookupTag,
dispatchReceiverLookupTag = this,
getCachedIrDeclaration = ::getCachedIrProperty,
createIrDeclaration = { parent, origin -> createIrProperty(fir, parent, predefinedOrigin = origin) },
createIrLazyDeclaration = { signature, lazyParent, declarationOrigin ->
@@ -1219,13 +1221,34 @@ class Fir2IrDeclarationStorage(
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 &&
dispatchReceiverLookupTag != firPropertySymbol.containingClass()
dispatchReceiverLookupTag != containingClassLookupTag
) {
val dispatchReceiverIrClass =
classifierStorage.getIrClassSymbol(dispatchReceiverLookupTag.toSymbol(session) as FirClassSymbol).owner
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
} else {
originalSymbol
@@ -16342,6 +16342,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
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
@TestMetadata("CustomThrowableMessage.kt")
public void testCustomThrowableMessage() throws Exception {
+65
View File
@@ -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"
}
@@ -16342,6 +16342,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
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
@TestMetadata("CustomThrowableMessage.kt")
public void testCustomThrowableMessage() throws Exception {