FIR: Fix Java scope in case of accessor with getter signature from supertype

^KT-45584 Fixed
This commit is contained in:
Denis.Zharkov
2021-03-25 16:28:48 +03:00
parent 24f35ef281
commit 1f074326bf
21 changed files with 94 additions and 33 deletions
@@ -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 {
@@ -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 -> {
@@ -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(
@@ -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,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// FILE: J.java
@@ -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"
@@ -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"
@@ -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()
@@ -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,3 +1,4 @@
// FIR_IDENTICAL
// FULL_JDK
class C1 : java.util.Hashtable<String, Int>()
@@ -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
@@ -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>'
@@ -61,7 +61,7 @@ fun testImportedObjectMember(): String {
return receiver.importedObjectMemberWithVarargs(xs = [p0])
}
::importedObjectMemberWithVarargs
Host::importedObjectMemberWithVarargs
})
}
@@ -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>'
@@ -19,7 +19,7 @@ class Host {
receiver.withVararg(xs = [p0])
}
Host::withVararg
<this>::withVararg
})
}
@@ -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
@@ -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 {
@@ -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 {
@@ -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");