Handle Java base class field read properly in IR converters

For FE 1.0, we just change super qualifier symbol to
base class, if it's possible.
For FIR, we introduce using of super qualifier symbols for
field accesses and repeat FE 1.0 behavior here.

#KT-49507 Fixed
This commit is contained in:
Mikhail Glukhikh
2022-06-08 14:45:52 +02:00
committed by Space
parent c2ae74c7cd
commit b0a6508d4b
23 changed files with 370 additions and 18 deletions
@@ -40,10 +40,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.dump
import org.jetbrains.kotlin.ir.util.isFunctionTypeOrSubtype
import org.jetbrains.kotlin.ir.util.isInterface
import org.jetbrains.kotlin.ir.util.isMethodOfAny
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi2ir.generators.hasNoSideEffects
import org.jetbrains.kotlin.psi2ir.generators.isUnchanging
@@ -256,6 +253,28 @@ class CallAndReferenceGenerator(
return null
}
// Note: I don't like using super qualifier symbols to determine field receivers in bytecode properly.
// Would be much better to use super qualifiers only in case when it's used explicitly.
// However, FE 1.0 does it, and currently we have no better way to provide these receivers.
// See KT-49507 and KT-48954 as good examples for cases we try to handle here
private fun FirExpression.superQualifierSymbolForField(fieldSymbol: IrFieldSymbol): IrClassSymbol? {
if (this !is FirQualifiedAccess) return null
if (calleeReference is FirSuperReference) return superQualifierSymbol()
if (fieldSymbol.owner.correspondingPropertySymbol != null) return null
val originalContainingClass = fieldSymbol.owner.parentClassOrNull ?: return null
val ownContainingClass = typeRef.toIrType().classifierOrNull?.owner as? IrClass ?: return null
// For static field, we shouldn't unwrap fake override in any case
if (fieldSymbol.owner.isStatic) return ownContainingClass.symbol
// This means own containing class exposes original containing class, which is possible only in Java (Kotlin forbids it)
// In this case we take own containing class as qualifier symbol to avoid visibility problems (see testKt48954 as an example)
// Otherwise we should take original containing class to avoid possible clash with Kotlin backing field
if (ownContainingClass.visibility.compareTo(
originalContainingClass.visibility
).let { it == null || it > 0 }
) return ownContainingClass.symbol
return originalContainingClass.symbol
}
private fun FirExpression.superQualifierSymbol(): IrClassSymbol? {
if (this !is FirQualifiedAccess) {
return null
@@ -462,7 +481,7 @@ class CallAndReferenceGenerator(
is IrFieldSymbol -> IrGetFieldImpl(
startOffset, endOffset, symbol, type,
origin = IrStatementOrigin.GET_PROPERTY.takeIf { calleeReference !is FirDelegateFieldReference },
superQualifierSymbol = dispatchReceiver.superQualifierSymbol()
superQualifierSymbol = dispatchReceiver.superQualifierSymbolForField(symbol)
)
is IrValueSymbol -> {
IrGetValueImpl(
@@ -17347,6 +17347,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/fieldRename/genericPropertyWithItself.kt");
}
@Test
@TestMetadata("javaFieldAndKotlinProperty.kt")
public void testJavaFieldAndKotlinProperty() throws Exception {
runTest("compiler/testData/codegen/box/fieldRename/javaFieldAndKotlinProperty.kt");
}
@Test
@TestMetadata("jvmFieldNoClash1.kt")
public void testJvmFieldNoClash1() throws Exception {
@@ -1118,6 +1118,12 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/ir/irText/expressions"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
}
@Test
@TestMetadata("ambiguousFieldAccess.kt")
public void testAmbiguousFieldAccess() throws Exception {
runTest("compiler/testData/ir/irText/expressions/ambiguousFieldAccess.kt");
}
@Test
@TestMetadata("argumentMappedWithError.kt")
public void testArgumentMappedWithError() throws Exception {
@@ -1118,6 +1118,12 @@ public class LightTreeFir2IrTextTestGenerated extends AbstractLightTreeFir2IrTex
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/ir/irText/expressions"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
}
@Test
@TestMetadata("ambiguousFieldAccess.kt")
public void testAmbiguousFieldAccess() throws Exception {
runTest("compiler/testData/ir/irText/expressions/ambiguousFieldAccess.kt");
}
@Test
@TestMetadata("argumentMappedWithError.kt")
public void testArgumentMappedWithError() throws Exception {
@@ -193,6 +193,21 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator
}
}
private fun PropertyDescriptor.containingClassForField(): ClassDescriptor? {
val ownContainingClass = containingDeclaration as? ClassDescriptor ?: return null
// For static field, we shouldn't unwrap fake override in any case
if (dispatchReceiverParameter == null) return ownContainingClass
val originalContainingClass = resolveFakeOverride().containingDeclaration as? ClassDescriptor ?: return ownContainingClass
// This means own containing class exposes original containing class, which is possible only in Java (Kotlin forbids it)
// In this case we take own containing class as qualifier symbol to avoid visibility problems (see testKt48954 as an example)
// Otherwise we should take original containing class to avoid possible clash with Kotlin backing field
if (ownContainingClass.visibility.compareTo(
originalContainingClass.visibility
).let { it == null || it > 0 }
) return ownContainingClass
return originalContainingClass
}
private fun generatePropertyGetterCall(
descriptor: PropertyDescriptor,
startOffset: Int,
@@ -203,10 +218,11 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator
val irType = descriptor.type.toIrType()
return if (getMethodDescriptor == null) {
val superQualifierSymbol = (call.superQualifier ?: descriptor.containingDeclaration as? ClassDescriptor)?.let {
if (it is ScriptDescriptor) null // otherwise it creates a reference to script as class; TODO: check if correct
else context.symbolTable.referenceClass(it)
}
val superQualifierSymbol =
(call.superQualifier ?: descriptor.containingClassForField())?.let {
if (it is ScriptDescriptor) null // otherwise it creates a reference to script as class; TODO: check if correct
else context.symbolTable.referenceClass(it)
}
val fieldSymbol =
context.symbolTable.referenceField(context.extensions.remapDebuggerFieldPropertyDescriptor(descriptor.resolveFakeOverride().original))
call.callReceiver.call { dispatchReceiverValue, extensionReceiverValue, _ ->
@@ -0,0 +1,36 @@
FILE fqName:<root> fileName:/Derived.kt
CLASS CLASS name:Derived modality:FINAL visibility:public superTypes:[<root>.BaseJava]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.Derived
CONSTRUCTOR visibility:public <> () returnType:<root>.Derived [primary]
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in <root>.BaseJava'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Derived modality:FINAL visibility:public superTypes:[<root>.BaseJava]'
PROPERTY name:a visibility:public modality:FINAL [val]
FIELD PROPERTY_BACKING_FIELD name:a type:kotlin.String visibility:private [final]
EXPRESSION_BODY
CONST String type=kotlin.String value="FAIL"
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-a> visibility:public modality:FINAL <> ($this:<root>.Derived) returnType:kotlin.String
correspondingProperty: PROPERTY name:a visibility:public modality:FINAL [val]
$this: VALUE_PARAMETER name:<this> type:<root>.Derived
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun <get-a> (): kotlin.String declared in <root>.Derived'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:a type:kotlin.String visibility:private [final]' type=kotlin.String origin=null
receiver: GET_VAR '<this>: <root>.Derived declared in <root>.Derived.<get-a>' type=<root>.Derived origin=null
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 [fake_override,operator] declared in <root>.BaseJava
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
overridden:
public open fun hashCode (): kotlin.Int [fake_override] declared in <root>.BaseJava
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
overridden:
public open fun toString (): kotlin.String [fake_override] declared in <root>.BaseJava
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN name:box visibility:public modality:FINAL <> () returnType:@[FlexibleNullability] kotlin.String?
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun box (): @[FlexibleNullability] kotlin.String? declared in <root>'
GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:a type:@[FlexibleNullability] kotlin.String? visibility:public' type=@[FlexibleNullability] kotlin.String? origin=GET_PROPERTY
receiver: CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in <root>.Derived' type=<root>.Derived origin=null
@@ -0,0 +1,39 @@
FILE fqName:<root> fileName:/Derived.kt
CLASS CLASS name:Derived modality:FINAL visibility:public superTypes:[<root>.BaseJava]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.Derived
CONSTRUCTOR visibility:public <> () returnType:<root>.Derived [primary]
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in <root>.BaseJava'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Derived modality:FINAL visibility:public superTypes:[<root>.BaseJava]'
PROPERTY name:a visibility:public modality:FINAL [val]
FIELD PROPERTY_BACKING_FIELD name:a type:kotlin.String visibility:private [final]
EXPRESSION_BODY
CONST String type=kotlin.String value="FAIL"
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-a> visibility:public modality:FINAL <> ($this:<root>.Derived) returnType:kotlin.String
correspondingProperty: PROPERTY name:a visibility:public modality:FINAL [val]
$this: VALUE_PARAMETER name:<this> type:<root>.Derived
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun <get-a> (): kotlin.String declared in <root>.Derived'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:a type:kotlin.String visibility:private [final]' type=kotlin.String origin=null
receiver: GET_VAR '<this>: <root>.Derived declared in <root>.Derived.<get-a>' type=<root>.Derived origin=null
PROPERTY FAKE_OVERRIDE name:a visibility:public modality:FINAL [fake_override,var]
overridden:
public final a: @[FlexibleNullability] kotlin.String? [var]
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 [fake_override,operator] declared in <root>.BaseJava
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
overridden:
public open fun hashCode (): kotlin.Int [fake_override] declared in <root>.BaseJava
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
overridden:
public open fun toString (): kotlin.String [fake_override] declared in <root>.BaseJava
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN name:box visibility:public modality:FINAL <> () returnType:@[FlexibleNullability] kotlin.String?
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun box (): @[FlexibleNullability] kotlin.String? declared in <root>'
GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:a type:@[FlexibleNullability] kotlin.String? visibility:public' type=@[FlexibleNullability] kotlin.String? origin=GET_PROPERTY
receiver: CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in <root>.Derived' type=<root>.Derived origin=null
@@ -0,0 +1,14 @@
// TARGET_BACKEND: JVM_IR
// DUMP_IR
// FILE: BaseJava.java
public class BaseJava {
public String a = "OK";
}
// FILE: Derived.kt
class Derived : BaseJava() {
val a = "FAIL"
}
fun box() = Derived().a
+1 -1
View File
@@ -20,4 +20,4 @@ fun test1(j: Kotlin2) = j.f
// 1 GETFIELD Java2.f : I
// @TestKt.class:
// 1 GETFIELD Kotlin2.f : I
// 1 GETFIELD Java2.f : I
@@ -31,7 +31,13 @@ fun test(b : Boolean) {
}
// @TestKt.class:
// 1 GETFIELD JFieldOwner.f : I
// 1 PUTFIELD JFieldOwner.f : I
// 1 GETFIELD Mid.f : I
// 1 PUTFIELD Mid.f : I
// JVM_IR_TEMPLATES
// 2 GETFIELD JFieldOwner.f : I
// 0 GETFIELD Mid.f : I
// JVM_TEMPLATES
// 1 GETFIELD JFieldOwner.f : I
// 1 GETFIELD Mid.f : I
@@ -0,0 +1,51 @@
FILE fqName:test fileName:/test.kt
FUN name:eval visibility:public modality:FINAL <T> (f:kotlin.Function0<T of test.eval>) returnType:T of test.eval
TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?] reified:false
VALUE_PARAMETER name:f index:0 type:kotlin.Function0<T of test.eval>
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun eval <T> (f: kotlin.Function0<T of test.eval>): T of test.eval declared in test'
CALL 'public abstract fun invoke (): R of kotlin.Function0 [operator] declared in kotlin.Function0' type=T of test.eval origin=INVOKE
$this: GET_VAR 'f: kotlin.Function0<T of test.eval> declared in test.eval' type=kotlin.Function0<T of test.eval> origin=VARIABLE_AS_FUNCTION
CLASS CLASS name:C modality:FINAL visibility:public superTypes:[<root>.A.B]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:test.C
CONSTRUCTOR visibility:public <> () returnType:test.C [primary]
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in <root>.A.B'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:C modality:FINAL visibility:public superTypes:[<root>.A.B]'
FUN name:f visibility:public modality:FINAL <> ($this:test.C) returnType:@[FlexibleNullability] kotlin.String?
$this: VALUE_PARAMETER name:<this> type:test.C
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun f (): @[FlexibleNullability] kotlin.String? declared in test.C'
CALL 'public final fun eval <T> (f: kotlin.Function0<T of test.eval>): T of test.eval declared in test' type=@[FlexibleNullability] kotlin.String? origin=null
<T>: @[FlexibleNullability] kotlin.String?
f: FUN_EXPR type=kotlin.Function0<@[FlexibleNullability] kotlin.String?> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:@[FlexibleNullability] kotlin.String?
BLOCK_BODY
RETURN type=kotlin.Nothing from='local final fun <anonymous> (): @[FlexibleNullability] kotlin.String? declared in test.C.f'
GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:x type:@[FlexibleNullability] kotlin.String? visibility:protected/*protected and package*/' type=@[FlexibleNullability] kotlin.String? origin=GET_PROPERTY
receiver: GET_VAR '<this>: test.C declared in test.C.f' type=test.C origin=null
FUN name:g visibility:public modality:FINAL <> ($this:test.C) returnType:@[FlexibleNullability] kotlin.String?
$this: VALUE_PARAMETER name:<this> type:test.C
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun g (): @[FlexibleNullability] kotlin.String? declared in test.C'
CALL 'public final fun eval <T> (f: kotlin.Function0<T of test.eval>): T of test.eval declared in test' type=@[FlexibleNullability] kotlin.String? origin=null
<T>: @[FlexibleNullability] kotlin.String?
f: FUN_EXPR type=kotlin.Function0<@[FlexibleNullability] kotlin.String?> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:@[FlexibleNullability] kotlin.String?
BLOCK_BODY
RETURN type=kotlin.Nothing from='local final fun <anonymous> (): @[FlexibleNullability] kotlin.String? declared in test.C.g'
GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:y type:@[FlexibleNullability] kotlin.String? visibility:protected/*protected and package*/' type=@[FlexibleNullability] kotlin.String? origin=GET_PROPERTY
receiver: GET_VAR '<this>: test.C declared in test.C.g' type=test.C origin=null
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 [fake_override,operator] declared in <root>.A.B
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
overridden:
public open fun hashCode (): kotlin.Int [fake_override] declared in <root>.A.B
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
overridden:
public open fun toString (): kotlin.String [fake_override] declared in <root>.A.B
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
@@ -0,0 +1,28 @@
package test
fun <T : Any?> eval(f: Function0<T>): T {
return f.invoke()
}
class C : B {
constructor() /* primary */ {
super/*B*/()
/* <init>() */
}
fun f(): @FlexibleNullability String? {
return eval<@FlexibleNullability String?>(f = local fun <anonymous>(): @FlexibleNullability String? {
return <this>super.#x
}
)
}
fun g(): @FlexibleNullability String? {
return eval<@FlexibleNullability String?>(f = local fun <anonymous>(): @FlexibleNullability String? {
return <this>super.#y
}
)
}
}
@@ -0,0 +1,57 @@
FILE fqName:test fileName:/test.kt
FUN name:eval visibility:public modality:FINAL <T> (f:kotlin.Function0<T of test.eval>) returnType:T of test.eval
TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?] reified:false
VALUE_PARAMETER name:f index:0 type:kotlin.Function0<T of test.eval>
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun eval <T> (f: kotlin.Function0<T of test.eval>): T of test.eval declared in test'
CALL 'public abstract fun invoke (): R of kotlin.Function0 [operator] declared in kotlin.Function0' type=T of test.eval origin=INVOKE
$this: GET_VAR 'f: kotlin.Function0<T of test.eval> declared in test.eval' type=kotlin.Function0<T of test.eval> origin=VARIABLE_AS_FUNCTION
CLASS CLASS name:C modality:FINAL visibility:public superTypes:[<root>.A.B]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:test.C
CONSTRUCTOR visibility:public <> () returnType:test.C [primary]
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in <root>.A.B'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:C modality:FINAL visibility:public superTypes:[<root>.A.B]'
FUN name:f visibility:public modality:FINAL <> ($this:test.C) returnType:@[FlexibleNullability] kotlin.String?
$this: VALUE_PARAMETER name:<this> type:test.C
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun f (): @[FlexibleNullability] kotlin.String? declared in test.C'
CALL 'public final fun eval <T> (f: kotlin.Function0<T of test.eval>): T of test.eval declared in test' type=@[FlexibleNullability] kotlin.String? origin=null
<T>: @[FlexibleNullability] kotlin.String?
f: FUN_EXPR type=kotlin.Function0<@[FlexibleNullability] kotlin.String?> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:@[FlexibleNullability] kotlin.String?
BLOCK_BODY
RETURN type=kotlin.Nothing from='local final fun <anonymous> (): @[FlexibleNullability] kotlin.String? declared in test.C.f'
GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:x type:@[FlexibleNullability] kotlin.String? visibility:protected/*protected and package*/' type=@[FlexibleNullability] kotlin.String? origin=GET_PROPERTY
receiver: GET_VAR '<this>: test.C declared in test.C.f' type=test.C origin=null
FUN name:g visibility:public modality:FINAL <> ($this:test.C) returnType:@[FlexibleNullability] kotlin.String?
$this: VALUE_PARAMETER name:<this> type:test.C
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun g (): @[FlexibleNullability] kotlin.String? declared in test.C'
CALL 'public final fun eval <T> (f: kotlin.Function0<T of test.eval>): T of test.eval declared in test' type=@[FlexibleNullability] kotlin.String? origin=null
<T>: @[FlexibleNullability] kotlin.String?
f: FUN_EXPR type=kotlin.Function0<@[FlexibleNullability] kotlin.String?> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:@[FlexibleNullability] kotlin.String?
BLOCK_BODY
RETURN type=kotlin.Nothing from='local final fun <anonymous> (): @[FlexibleNullability] kotlin.String? declared in test.C.g'
GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:y type:@[FlexibleNullability] kotlin.String? visibility:protected/*protected and package*/' type=@[FlexibleNullability] kotlin.String? origin=GET_PROPERTY
receiver: GET_VAR '<this>: test.C declared in test.C.g' type=test.C origin=null
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 [fake_override,operator] declared in <root>.A.B
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
overridden:
public open fun hashCode (): kotlin.Int [fake_override] declared in <root>.A.B
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
overridden:
public open fun toString (): kotlin.String [fake_override] declared in <root>.A.B
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
PROPERTY FAKE_OVERRIDE name:y visibility:protected/*protected and package*/ modality:FINAL [fake_override,var]
overridden:
protected/*protected and package*/ final y: @[FlexibleNullability] kotlin.String? [var]
PROPERTY FAKE_OVERRIDE name:x visibility:protected/*protected and package*/ modality:FINAL [fake_override,var]
overridden:
protected/*protected and package*/ final x: @[FlexibleNullability] kotlin.String? [fake_override,var]
@@ -0,0 +1,23 @@
// SKIP_KLIB_TEST
// Related to KT-49507
// FILE: A.java
public class A {
protected String x = "1";
protected String y = "2";
public static class B extends A {
protected String y = "3";
}
}
// FILE: test.kt
package test
fun <T> eval(f: () -> T) = f()
class C : A.B() {
// Both x & y here should in fact be taken from B class: this.(super<B>.x), this.(super<B>.y)
fun f() = eval { x }
fun g() = eval { y }
}
@@ -0,0 +1,28 @@
package test
fun <T : Any?> eval(f: Function0<T>): T {
return f.invoke()
}
class C : B {
constructor() /* primary */ {
super/*B*/()
/* <init>() */
}
fun f(): @FlexibleNullability String? {
return eval<@FlexibleNullability String?>(f = local fun <anonymous>(): @FlexibleNullability String? {
return <this>super.#x
}
)
}
fun g(): @FlexibleNullability String? {
return eval<@FlexibleNullability String?>(f = local fun <anonymous>(): @FlexibleNullability String? {
return <this>super.#y
}
)
}
}
@@ -55,7 +55,7 @@ fun test(b: Boolean) {
else -> d2
}
k.#f = 42
k.#f /*~> Unit */
ksuper.#f /*~> Unit */
val md1: DerivedThroughMid1 = DerivedThroughMid1()
val md2: DerivedThroughMid2 = DerivedThroughMid2()
val mk: Mid = when {
@@ -63,5 +63,5 @@ fun test(b: Boolean) {
else -> md2
}
mk.#f = 44
mk.#f /*~> Unit */
mksuper.#f /*~> Unit */
}
@@ -10,7 +10,7 @@ class Derived : Base {
}
fun getValue(): Int {
return <this>.#value
return <this>super.#value
}
fun setValue(value: Int) {
+1 -1
View File
@@ -13,7 +13,7 @@ class Owner<out T : JCTree> {
get(): String {
var tree: JCTree = <this>.<get-tree>()
when {
tree is JCTypeApply -> return tree /*as JCTypeApply */.#clazz /*!! String */
tree is JCTypeApply -> return tree /*as JCTypeApply */super.#clazz /*!! String */
}
return ""
}
@@ -1,6 +1,6 @@
fun foo(movedPaths: MutableList<Couple<FilePath>>) {
movedPaths.forEach<Couple<FilePath>>(action = local fun <anonymous>(it: Couple<FilePath>) {
it.#second.getName() /*~> Unit */
itsuper.#second.getName() /*~> Unit */
}
)
}
@@ -6,6 +6,6 @@ fun testSetField(a: Any, b: Any) {
fun testGetField(a: Any): String {
a as JCell<String> /*~> Unit */
return a /*as JCell<String> */.#value /*!! String */
return a /*as JCell<String> */super.#value /*!! String */
}
@@ -17347,6 +17347,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/fieldRename/genericPropertyWithItself.kt");
}
@Test
@TestMetadata("javaFieldAndKotlinProperty.kt")
public void testJavaFieldAndKotlinProperty() throws Exception {
runTest("compiler/testData/codegen/box/fieldRename/javaFieldAndKotlinProperty.kt");
}
@Test
@TestMetadata("jvmFieldNoClash1.kt")
public void testJvmFieldNoClash1() throws Exception {
@@ -1118,6 +1118,12 @@ public class IrTextTestGenerated extends AbstractIrTextTest {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/ir/irText/expressions"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
}
@Test
@TestMetadata("ambiguousFieldAccess.kt")
public void testAmbiguousFieldAccess() throws Exception {
runTest("compiler/testData/ir/irText/expressions/ambiguousFieldAccess.kt");
}
@Test
@TestMetadata("argumentMappedWithError.kt")
public void testArgumentMappedWithError() throws Exception {
@@ -862,6 +862,11 @@ public class KlibTextTestCaseGenerated extends AbstractKlibTextTestCase {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/ir/irText/expressions"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
}
@TestMetadata("ambiguousFieldAccess.kt")
public void testAmbiguousFieldAccess() throws Exception {
runTest("compiler/testData/ir/irText/expressions/ambiguousFieldAccess.kt");
}
@TestMetadata("argumentMappedWithError.kt")
public void testArgumentMappedWithError() throws Exception {
runTest("compiler/testData/ir/irText/expressions/argumentMappedWithError.kt");