FIR: Fix Java scope in case of accessor with getter signature from supertype
^KT-45584 Fixed
This commit is contained in:
+6
@@ -21220,6 +21220,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/javaInterop/conflictingOverloadsForThrowableInheritors.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("conflictingOverloadsForThrowableInheritors2.kt")
|
||||
public void testConflictingOverloadsForThrowableInheritors2() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/javaInterop/conflictingOverloadsForThrowableInheritors2.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("genericSamProjectedOut.kt")
|
||||
public void testGenericSamProjectedOut() throws Exception {
|
||||
|
||||
+1
@@ -137,6 +137,7 @@ class FirSignatureEnhancement(
|
||||
symbol = FirAccessorSymbol(accessorSymbol.callableId, accessorSymbol.accessorId)
|
||||
delegateGetter = enhancedGetterSymbol.fir as FirSimpleFunction
|
||||
delegateSetter = enhancedSetterSymbol?.fir as FirSimpleFunction?
|
||||
status = firElement.status
|
||||
}.symbol
|
||||
}
|
||||
else -> {
|
||||
|
||||
+31
-11
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.java.scopes
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
||||
@@ -57,22 +58,33 @@ class JavaClassUseSiteMemberScope(
|
||||
private fun generateAccessorSymbol(
|
||||
getterSymbol: FirNamedFunctionSymbol,
|
||||
setterSymbol: FirNamedFunctionSymbol?,
|
||||
syntheticPropertyName: Name,
|
||||
property: FirProperty,
|
||||
): FirAccessorSymbol {
|
||||
return accessorByNameMap.getOrPut(syntheticPropertyName) {
|
||||
return accessorByNameMap.getOrPut(property.name) {
|
||||
buildSyntheticProperty {
|
||||
session = this@JavaClassUseSiteMemberScope.session
|
||||
name = syntheticPropertyName
|
||||
name = property.name
|
||||
symbol = FirAccessorSymbol(
|
||||
accessorId = getterSymbol.callableId,
|
||||
callableId = CallableId(getterSymbol.callableId.packageName, getterSymbol.callableId.className, syntheticPropertyName)
|
||||
callableId = CallableId(getterSymbol.callableId.packageName, getterSymbol.callableId.className, property.name)
|
||||
)
|
||||
delegateGetter = getterSymbol.fir
|
||||
delegateSetter = setterSymbol?.fir
|
||||
status = getterSymbol.fir.status.copy(newModality = chooseModalityForAccessor(property, delegateGetter))
|
||||
}.symbol
|
||||
}
|
||||
}
|
||||
|
||||
private fun chooseModalityForAccessor(property: FirProperty, getter: FirSimpleFunction): Modality? {
|
||||
val a = property.modality
|
||||
val b = getter.modality
|
||||
|
||||
if (a == null) return b
|
||||
if (b == null) return a
|
||||
|
||||
return minOf(a, b)
|
||||
}
|
||||
|
||||
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
|
||||
val fields = mutableSetOf<FirCallableSymbol<*>>()
|
||||
val fieldNames = mutableSetOf<Name>()
|
||||
@@ -95,7 +107,9 @@ class JavaClassUseSiteMemberScope(
|
||||
continue
|
||||
}
|
||||
if (propertyFromSupertype !is FirPropertySymbol) continue
|
||||
val overrideInClass = propertyFromSupertype.createOverridePropertyIfExists(declaredMemberScope)
|
||||
val overrideInClass =
|
||||
propertyFromSupertype.createOverridePropertyIfExists(declaredMemberScope)
|
||||
?: propertyFromSupertype.createOverridePropertyIfExists(superTypesScope)
|
||||
when {
|
||||
overrideInClass != null -> {
|
||||
directOverriddenProperties.getOrPut(overrideInClass) { mutableListOf() }.add(propertyFromSupertype)
|
||||
@@ -117,7 +131,7 @@ class JavaClassUseSiteMemberScope(
|
||||
null
|
||||
if (setterSymbol != null && setterSymbol.fir.modality != getterSymbol.fir.modality) return null
|
||||
|
||||
return generateAccessorSymbol(getterSymbol, setterSymbol, fir.name)
|
||||
return generateAccessorSymbol(getterSymbol, setterSymbol, fir)
|
||||
}
|
||||
|
||||
private fun FirPropertySymbol.findGetterOverride(
|
||||
@@ -227,10 +241,10 @@ class JavaClassUseSiteMemberScope(
|
||||
|
||||
val overrideCandidates = result.toMutableSet()
|
||||
|
||||
superTypesScope.processFunctionsByName(name) {
|
||||
val overriddenBy = it.getOverridden(overrideCandidates)
|
||||
if (overriddenBy == null) {
|
||||
result += it
|
||||
superTypesScope.processFunctionsByName(name) { functionSymbol ->
|
||||
val overriddenBy = functionSymbol.getOverridden(overrideCandidates)
|
||||
if (overriddenBy == null && overriddenProperties.none { it.isOverriddenInClassBy(functionSymbol) }) {
|
||||
result += functionSymbol
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,7 +254,13 @@ class JavaClassUseSiteMemberScope(
|
||||
private fun FirPropertySymbol.isOverriddenInClassBy(functionSymbol: FirNamedFunctionSymbol): Boolean {
|
||||
val fir = fir as? FirSyntheticProperty ?: return false
|
||||
|
||||
return fir.getter.delegate.symbol == functionSymbol || fir.setter?.delegate?.symbol == functionSymbol
|
||||
if (fir.getter.delegate.symbol == functionSymbol || fir.setter?.delegate?.symbol == functionSymbol) return true
|
||||
|
||||
val currentJvmDescriptor = functionSymbol.fir.computeJvmDescriptor(includeReturnType = false)
|
||||
val getterJvmDescriptor = fir.getter.delegate.computeJvmDescriptor(includeReturnType = false)
|
||||
val setterJvmDescriptor = fir.setter?.delegate?.computeJvmDescriptor(includeReturnType = false)
|
||||
|
||||
return currentJvmDescriptor == getterJvmDescriptor || currentJvmDescriptor == setterJvmDescriptor
|
||||
}
|
||||
|
||||
private fun addOverriddenSpecialMethods(
|
||||
|
||||
+4
-1
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.fir.declarations.synthetic
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationStatus
|
||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
|
||||
import org.jetbrains.kotlin.fir.declarations.modality
|
||||
@@ -18,11 +19,13 @@ class FirSyntheticPropertyBuilder {
|
||||
lateinit var name: Name
|
||||
lateinit var symbol: FirAccessorSymbol
|
||||
lateinit var delegateGetter: FirSimpleFunction
|
||||
|
||||
var status: FirDeclarationStatus? = null
|
||||
var delegateSetter: FirSimpleFunction? = null
|
||||
|
||||
fun build(): FirSyntheticProperty = FirSyntheticProperty(
|
||||
session, name, isVar = delegateSetter != null, symbol = symbol,
|
||||
status = delegateGetter.status,
|
||||
status = status ?: delegateGetter.status,
|
||||
resolvePhase = delegateGetter.resolvePhase,
|
||||
getter = FirSyntheticPropertyAccessor(delegateGetter, isGetter = true),
|
||||
setter = delegateSetter?.let { FirSyntheticPropertyAccessor(it, isGetter = false) }
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_RUNTIME
|
||||
// FULL_JDK
|
||||
@@ -9,4 +8,4 @@ class A : Hashtable<String, String>()
|
||||
fun box(): String {
|
||||
val sz = A().size
|
||||
return "OK"
|
||||
}
|
||||
}
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// FILE: J.java
|
||||
|
||||
+5
-4
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
// FULL_JDK
|
||||
// ISSUE: KT-45584
|
||||
@@ -11,10 +10,12 @@ public interface PlaceholderExceptionSupport {
|
||||
|
||||
// FILE: PlaceholderException.java
|
||||
|
||||
public class PlaceholderException extends RuntimeException implements PlaceholderExceptionSupport {}
|
||||
public class PlaceholderException extends RuntimeException implements PlaceholderExceptionSupport {
|
||||
public PlaceholderException(String x) { super(x); }
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
class KotlinTestFailure : PlaceholderException() {} // <-- CONFLICTING_INHERITED_JVM_DECLARATIONS
|
||||
class KotlinTestFailure : PlaceholderException("OK") {} // <-- CONFLICTING_INHERITED_JVM_DECLARATIONS
|
||||
|
||||
fun box(): String = "OK"
|
||||
fun box(): String = KotlinTestFailure().message ?: "fail"
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// FULL_JDK
|
||||
// ISSUE: KT-45584
|
||||
|
||||
// FILE: PlaceholderExceptionSupport.java
|
||||
|
||||
public interface PlaceholderExceptionSupport {
|
||||
String getMessage();
|
||||
}
|
||||
|
||||
// FILE: PlaceholderException.java
|
||||
|
||||
public class PlaceholderException extends RuntimeException implements PlaceholderExceptionSupport {
|
||||
public PlaceholderException(String x) { super(x); }
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
class KotlinTestFailure : PlaceholderException("OK") {} // <-- CONFLICTING_INHERITED_JVM_DECLARATIONS
|
||||
|
||||
fun box(): String = KotlinTestFailure().message ?: "fail"
|
||||
Vendored
+1
-1
@@ -108,7 +108,7 @@ public class A extends AImpl implements List<String> {
|
||||
}
|
||||
|
||||
// FILE: X.kt
|
||||
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class X<!> : A()
|
||||
<!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class X<!> : A()
|
||||
|
||||
fun main() {
|
||||
val x = X()
|
||||
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
// FULL_JDK
|
||||
|
||||
<!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class C1<!> : java.util.Hashtable<String, Int>()
|
||||
<!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class C2<!> : java.util.Hashtable<String, Int>() {
|
||||
override fun get(key: String) = 123
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// FULL_JDK
|
||||
|
||||
class C1 : java.util.Hashtable<String, Int>()
|
||||
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
// FULL_JDK
|
||||
|
||||
import java.security.Provider
|
||||
|
||||
<!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class Example<!> : Provider("A", 1.0, "B")
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// FULL_JDK
|
||||
|
||||
import java.security.Provider
|
||||
|
||||
Vendored
+1
@@ -46,6 +46,7 @@ FILE fqName:<root> fileName:/varargFunImportedFromObject.kt
|
||||
x: VARARG type=kotlin.Array<out kotlin.String> varargElementType=kotlin.String
|
||||
GET_VAR 'p0: kotlin.String declared in <root>.test1.foo' type=kotlin.String origin=null
|
||||
FUNCTION_REFERENCE 'local final fun foo (p0: kotlin.String): kotlin.String declared in <root>.test1' type=kotlin.Function1<kotlin.String, kotlin.String> origin=ADAPTED_FUNCTION_REFERENCE reflectionTarget=null
|
||||
$receiver: GET_OBJECT 'CLASS OBJECT name:Host modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.Host
|
||||
FUN name:test2 visibility:public modality:FINAL <> () returnType:kotlin.String
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun test2 (): kotlin.String declared in <root>'
|
||||
|
||||
+1
-1
@@ -61,7 +61,7 @@ fun testImportedObjectMember(): String {
|
||||
return receiver.importedObjectMemberWithVarargs(xs = [p0])
|
||||
}
|
||||
|
||||
::importedObjectMemberWithVarargs
|
||||
Host::importedObjectMemberWithVarargs
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -111,6 +111,7 @@ FILE fqName:<root> fileName:/withAdaptedArguments.kt
|
||||
xs: VARARG type=kotlin.IntArray varargElementType=kotlin.Int
|
||||
GET_VAR 'p0: kotlin.Int declared in <root>.testImportedObjectMember.importedObjectMemberWithVarargs' type=kotlin.Int origin=null
|
||||
FUNCTION_REFERENCE 'local final fun importedObjectMemberWithVarargs (p0: kotlin.Int): kotlin.String declared in <root>.testImportedObjectMember' type=kotlin.Function1<kotlin.Int, kotlin.String> origin=ADAPTED_FUNCTION_REFERENCE reflectionTarget=null
|
||||
$receiver: GET_OBJECT 'CLASS OBJECT name:Host modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.Host
|
||||
FUN name:testDefault0 visibility:public modality:FINAL <> () returnType:kotlin.String
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun testDefault0 (): kotlin.String declared in <root>'
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ class Host {
|
||||
receiver.withVararg(xs = [p0])
|
||||
}
|
||||
|
||||
Host::withVararg
|
||||
<this>::withVararg
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
compiler/testData/ir/irText/expressions/callableReferences/withArgumentAdaptationAndReceiver.fir.txt
Vendored
+1
@@ -31,6 +31,7 @@ FILE fqName:<root> fileName:/withArgumentAdaptationAndReceiver.kt
|
||||
xs: VARARG type=kotlin.IntArray varargElementType=kotlin.Int
|
||||
GET_VAR 'p0: kotlin.Int declared in <root>.Host.testImplicitThis.withVararg' type=kotlin.Int origin=null
|
||||
FUNCTION_REFERENCE 'local final fun withVararg (p0: kotlin.Int): kotlin.Unit declared in <root>.Host.testImplicitThis' type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=ADAPTED_FUNCTION_REFERENCE reflectionTarget=null
|
||||
$receiver: GET_VAR '<this>: <root>.Host declared in <root>.Host.testImplicitThis' type=<root>.Host origin=null
|
||||
FUN name:testBoundReceiverLocalVal visibility:public modality:FINAL <> ($this:<root>.Host) returnType:kotlin.Unit
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.Host
|
||||
BLOCK_BODY
|
||||
|
||||
+6
@@ -21202,6 +21202,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/javaInterop/conflictingOverloadsForThrowableInheritors.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("conflictingOverloadsForThrowableInheritors2.kt")
|
||||
public void testConflictingOverloadsForThrowableInheritors2() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/javaInterop/conflictingOverloadsForThrowableInheritors2.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("genericSamProjectedOut.kt")
|
||||
public void testGenericSamProjectedOut() throws Exception {
|
||||
|
||||
+6
@@ -21220,6 +21220,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/javaInterop/conflictingOverloadsForThrowableInheritors.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("conflictingOverloadsForThrowableInheritors2.kt")
|
||||
public void testConflictingOverloadsForThrowableInheritors2() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/javaInterop/conflictingOverloadsForThrowableInheritors2.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("genericSamProjectedOut.kt")
|
||||
public void testGenericSamProjectedOut() throws Exception {
|
||||
|
||||
+5
@@ -17757,6 +17757,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/javaInterop/conflictingOverloadsForThrowableInheritors.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("conflictingOverloadsForThrowableInheritors2.kt")
|
||||
public void testConflictingOverloadsForThrowableInheritors2() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/javaInterop/conflictingOverloadsForThrowableInheritors2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("genericSamProjectedOut.kt")
|
||||
public void testGenericSamProjectedOut() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/javaInterop/genericSamProjectedOut.kt");
|
||||
|
||||
Reference in New Issue
Block a user