[FIR] Check supertypes hierarchy for java classes during creation of synhtetic properies
^KT-62394 Fixed
This commit is contained in:
committed by
Space Team
parent
16ab36e167
commit
c3f3a4192c
@@ -6,13 +6,12 @@
|
||||
package org.jetbrains.kotlin.fir.resolve.calls
|
||||
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.getDeprecationsProviderFromAccessors
|
||||
import org.jetbrains.kotlin.fir.declarations.isHiddenEverywhereBesideSuperCalls
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.synthetic.buildSyntheticProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isStatic
|
||||
import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
|
||||
import org.jetbrains.kotlin.fir.scopes.*
|
||||
import org.jetbrains.kotlin.fir.symbols.SyntheticSymbol
|
||||
@@ -248,7 +247,56 @@ class FirSyntheticPropertiesScope private constructor(
|
||||
|
||||
ProcessorAction.NEXT
|
||||
}
|
||||
|
||||
result = result || isJavaTypeOnThePath(this.dispatchReceiverType)
|
||||
return result && !isHiddenEverywhereBesideSuperCalls
|
||||
}
|
||||
|
||||
/*
|
||||
* We should check the whole hierarchy between dispatch receiver type of found getter and our dispatch receiver type, because
|
||||
* synthetic properly should be created if there is a java class on this way (KT-62394)
|
||||
*
|
||||
* // FILE: Base.kt
|
||||
* abstract class Base(private val x: String) {
|
||||
* fun getFoo() = x
|
||||
* }
|
||||
*
|
||||
* // FILE: Intermediate.java
|
||||
* public class Intermediate extends Base {
|
||||
* public Intermediate(String x) {
|
||||
* super(x);
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* // FILE: Final.kt
|
||||
* class Final(x: String) : Intermediate(x)
|
||||
*
|
||||
* fun test(f: Final) {
|
||||
* f.foo // <-------
|
||||
* }
|
||||
*/
|
||||
private fun isJavaTypeOnThePath(baseType: ConeSimpleKotlinType?): Boolean {
|
||||
val lookupTagToStop = (baseType as? ConeLookupTagBasedType)?.lookupTag ?: return false
|
||||
val dispatchReceiverClass = (dispatchReceiverType as? ConeLookupTagBasedType)?.lookupTag?.toSymbol(session) ?: return false
|
||||
|
||||
val typeContext = session.typeContext
|
||||
fun checkType(type: ConeClassLikeType): Boolean {
|
||||
val state = typeContext.newTypeCheckerState(errorTypesEqualToAnything = false, stubTypesEqualToAnything = false)
|
||||
if (type.toRegularClassSymbol(session)?.isJavaOrEnhancement == true) {
|
||||
if (AbstractTypeChecker.isSubtypeOfClass(state, type.lookupTag, lookupTagToStop)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
if (dispatchReceiverType is ConeClassLikeType && checkType(dispatchReceiverType)) {
|
||||
return true
|
||||
}
|
||||
|
||||
val superTypes = lookupSuperTypes(dispatchReceiverClass, lookupInterfaces = true, deep = true, session)
|
||||
for (superType in superTypes) {
|
||||
if (checkType(superType)) return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// ISSUE: KT-59550
|
||||
// IGNORE_BACKEND_K2: ANY
|
||||
// Ignore reason: KT-62393 and KT-62394
|
||||
// FILE: Intermediate.java
|
||||
public class Intermediate extends Base {
|
||||
public Intermediate(String foo) {
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// ISSUE: KT-59550
|
||||
// IGNORE_BACKEND_K2: ANY
|
||||
// Ignore reason: KT-62393 and KT-62394
|
||||
|
||||
// FILE: Intermediate.java
|
||||
public class Intermediate extends Base {
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
// FILE: KotlinFile.kt
|
||||
open class KotlinClass1 : JavaClass1() {
|
||||
public fun getSomethingKotlin1(): Int = 1
|
||||
}
|
||||
|
||||
class KotlinClass2 : JavaClass2() {
|
||||
public fun getSomethingKotlin2(): Int = 1
|
||||
}
|
||||
|
||||
fun foo(k: KotlinClass2) {
|
||||
useInt(k.getSomething1())
|
||||
useInt(k.something1)
|
||||
useInt(k.getSomething2())
|
||||
useInt(k.something2)
|
||||
useInt(k.getSomethingKotlin1())
|
||||
useInt(k.getSomethingKotlin2())
|
||||
k.somethingKotlin1
|
||||
k.<!UNRESOLVED_REFERENCE!>somethingKotlin2<!>
|
||||
}
|
||||
|
||||
fun useInt(i: Int) {}
|
||||
|
||||
// FILE: JavaClass1.java
|
||||
public class JavaClass1 {
|
||||
public int getSomething1() { return 1; }
|
||||
}
|
||||
|
||||
// FILE: JavaClass2.java
|
||||
public class JavaClass2 extends KotlinClass1 {
|
||||
public int getSomething2() { return 1; }
|
||||
}
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// FIR_IDENTICAL
|
||||
// FILE: KotlinFile.kt
|
||||
open class KotlinClass1 : JavaClass1() {
|
||||
public fun getSomethingKotlin1(): Int = 1
|
||||
|
||||
+11
-6
@@ -113,6 +113,15 @@ FILE fqName:<root> fileName:/kt43342.kt
|
||||
CALL 'public abstract fun <get-values> (): kotlin.collections.Collection<V of kotlin.collections.Map> declared in kotlin.collections.Map' type=kotlin.collections.Collection<V of kotlin.collections.Map> origin=null
|
||||
$this: GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:map type:kotlin.collections.Map<K of <root>.ControlFlowInfo, V of <root>.ControlFlowInfo> visibility:private [final]' type=kotlin.collections.Map<K of <root>.ControlFlowInfo, V of <root>.ControlFlowInfo> origin=null
|
||||
receiver: GET_VAR '<this>: <root>.ControlFlowInfo<K of <root>.ControlFlowInfo, V of <root>.ControlFlowInfo> declared in <root>.ControlFlowInfo.<get-values>' type=<root>.ControlFlowInfo<K of <root>.ControlFlowInfo, V of <root>.ControlFlowInfo> origin=null
|
||||
FUN FAKE_OVERRIDE name:getOrDefault visibility:public modality:OPEN <> ($this:kotlin.collections.Map<K of <root>.ControlFlowInfo, V of <root>.ControlFlowInfo>, key:K of <root>.ControlFlowInfo, defaultValue:V of <root>.ControlFlowInfo) returnType:V of <root>.ControlFlowInfo [fake_override]
|
||||
annotations:
|
||||
SinceKotlin(version = '1.1')
|
||||
PlatformDependent
|
||||
overridden:
|
||||
public open fun getOrDefault (key: K of kotlin.collections.Map, defaultValue: V of kotlin.collections.Map): V of kotlin.collections.Map declared in kotlin.collections.Map
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.collections.Map<K of <root>.ControlFlowInfo, V of <root>.ControlFlowInfo>
|
||||
VALUE_PARAMETER name:key index:0 type:K of <root>.ControlFlowInfo
|
||||
VALUE_PARAMETER name:defaultValue index:1 type:V of <root>.ControlFlowInfo
|
||||
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
|
||||
overridden:
|
||||
public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.collections.Map
|
||||
@@ -126,10 +135,6 @@ FILE fqName:<root> fileName:/kt43342.kt
|
||||
overridden:
|
||||
public open fun toString (): kotlin.String declared in kotlin.collections.Map
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
FUN name:getOrDefault visibility:public modality:OPEN <> ($this:<root>.ControlFlowInfo<K of <root>.ControlFlowInfo, V of <root>.ControlFlowInfo>, key:K of <root>.ControlFlowInfo, defaultValue:V of <root>.ControlFlowInfo) returnType:V of <root>.ControlFlowInfo
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.ControlFlowInfo<K of <root>.ControlFlowInfo, V of <root>.ControlFlowInfo>
|
||||
VALUE_PARAMETER name:key index:0 type:K of <root>.ControlFlowInfo
|
||||
VALUE_PARAMETER name:defaultValue index:1 type:V of <root>.ControlFlowInfo
|
||||
CLASS CLASS name:StringFlowInfo modality:FINAL visibility:public superTypes:[<root>.ControlFlowInfo<kotlin.String, kotlin.String>]
|
||||
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.StringFlowInfo
|
||||
CONSTRUCTOR visibility:public <> (map:kotlin.collections.Map<kotlin.String, kotlin.String>) returnType:<root>.StringFlowInfo [primary]
|
||||
@@ -173,13 +178,13 @@ FILE fqName:<root> fileName:/kt43342.kt
|
||||
public open fun get (key: K of <root>.ControlFlowInfo): V of <root>.ControlFlowInfo? declared in <root>.ControlFlowInfo
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.ControlFlowInfo<kotlin.String, kotlin.String>
|
||||
VALUE_PARAMETER name:key index:0 type:kotlin.String
|
||||
FUN FAKE_OVERRIDE name:getOrDefault visibility:public modality:OPEN <> ($this:<root>.ControlFlowInfo<kotlin.String, kotlin.String>, key:kotlin.String, defaultValue:kotlin.String) returnType:kotlin.String [fake_override]
|
||||
FUN FAKE_OVERRIDE name:getOrDefault visibility:public modality:OPEN <> ($this:kotlin.collections.Map<kotlin.String, kotlin.String>, key:kotlin.String, defaultValue:kotlin.String) returnType:kotlin.String [fake_override]
|
||||
annotations:
|
||||
SinceKotlin(version = '1.1')
|
||||
PlatformDependent
|
||||
overridden:
|
||||
public open fun getOrDefault (key: K of <root>.ControlFlowInfo, defaultValue: V of <root>.ControlFlowInfo): V of <root>.ControlFlowInfo declared in <root>.ControlFlowInfo
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.ControlFlowInfo<kotlin.String, kotlin.String>
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.collections.Map<kotlin.String, kotlin.String>
|
||||
VALUE_PARAMETER name:key index:0 type:kotlin.String
|
||||
VALUE_PARAMETER name:defaultValue index:1 type:kotlin.String
|
||||
FUN FAKE_OVERRIDE name:isEmpty visibility:public modality:OPEN <> ($this:<root>.ControlFlowInfo<kotlin.String, kotlin.String>) returnType:kotlin.Boolean [fake_override]
|
||||
|
||||
@@ -45,10 +45,6 @@ open class ControlFlowInfo<K : Any?, V : Any?> : Map<K, V> {
|
||||
return <this>.#map.<get-values>()
|
||||
}
|
||||
|
||||
val map: Map<K, V>
|
||||
field = map
|
||||
get
|
||||
|
||||
}
|
||||
|
||||
class StringFlowInfo : ControlFlowInfo<String, String> {
|
||||
|
||||
Reference in New Issue
Block a user