[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
|
package org.jetbrains.kotlin.fir.resolve.calls
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.*
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
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.synthetic.FirSyntheticProperty
|
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
||||||
import org.jetbrains.kotlin.fir.declarations.synthetic.buildSyntheticProperty
|
import org.jetbrains.kotlin.fir.declarations.synthetic.buildSyntheticProperty
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isStatic
|
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.resolve.transformers.ReturnTypeCalculator
|
||||||
import org.jetbrains.kotlin.fir.scopes.*
|
import org.jetbrains.kotlin.fir.scopes.*
|
||||||
import org.jetbrains.kotlin.fir.symbols.SyntheticSymbol
|
import org.jetbrains.kotlin.fir.symbols.SyntheticSymbol
|
||||||
@@ -248,7 +247,56 @@ class FirSyntheticPropertiesScope private constructor(
|
|||||||
|
|
||||||
ProcessorAction.NEXT
|
ProcessorAction.NEXT
|
||||||
}
|
}
|
||||||
|
result = result || isJavaTypeOnThePath(this.dispatchReceiverType)
|
||||||
return result && !isHiddenEverywhereBesideSuperCalls
|
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
|
// TARGET_BACKEND: JVM_IR
|
||||||
// ISSUE: KT-59550
|
// ISSUE: KT-59550
|
||||||
// IGNORE_BACKEND_K2: ANY
|
|
||||||
// Ignore reason: KT-62393 and KT-62394
|
|
||||||
// FILE: Intermediate.java
|
// FILE: Intermediate.java
|
||||||
public class Intermediate extends Base {
|
public class Intermediate extends Base {
|
||||||
public Intermediate(String foo) {
|
public Intermediate(String foo) {
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
// TARGET_BACKEND: JVM_IR
|
// TARGET_BACKEND: JVM_IR
|
||||||
// ISSUE: KT-59550
|
// ISSUE: KT-59550
|
||||||
// IGNORE_BACKEND_K2: ANY
|
|
||||||
// Ignore reason: KT-62393 and KT-62394
|
|
||||||
|
|
||||||
// FILE: Intermediate.java
|
// FILE: Intermediate.java
|
||||||
public class Intermediate extends Base {
|
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
|
// FILE: KotlinFile.kt
|
||||||
open class KotlinClass1 : JavaClass1() {
|
open class KotlinClass1 : JavaClass1() {
|
||||||
public fun getSomethingKotlin1(): Int = 1
|
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
|
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
|
$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
|
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]
|
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
|
||||||
overridden:
|
overridden:
|
||||||
public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.collections.Map
|
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:
|
overridden:
|
||||||
public open fun toString (): kotlin.String declared in kotlin.collections.Map
|
public open fun toString (): kotlin.String declared in kotlin.collections.Map
|
||||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
$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>]
|
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
|
$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]
|
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
|
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>
|
$this: VALUE_PARAMETER name:<this> type:<root>.ControlFlowInfo<kotlin.String, kotlin.String>
|
||||||
VALUE_PARAMETER name:key index:0 type: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:
|
annotations:
|
||||||
SinceKotlin(version = '1.1')
|
SinceKotlin(version = '1.1')
|
||||||
PlatformDependent
|
PlatformDependent
|
||||||
overridden:
|
overridden:
|
||||||
public open fun getOrDefault (key: K of <root>.ControlFlowInfo, defaultValue: V of <root>.ControlFlowInfo): V of <root>.ControlFlowInfo declared in <root>.ControlFlowInfo
|
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:key index:0 type:kotlin.String
|
||||||
VALUE_PARAMETER name:defaultValue index:1 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]
|
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>()
|
return <this>.#map.<get-values>()
|
||||||
}
|
}
|
||||||
|
|
||||||
val map: Map<K, V>
|
|
||||||
field = map
|
|
||||||
get
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class StringFlowInfo : ControlFlowInfo<String, String> {
|
class StringFlowInfo : ControlFlowInfo<String, String> {
|
||||||
|
|||||||
Reference in New Issue
Block a user