K1: Implement a checker that disallows to have different member scopes for expect open and its actual

^KT-22841 Fixed
Review: https://jetbrains.team/p/kt/reviews/11603/timeline

The commit also introduces `@AllowDifferentMembersInActual` annotation in
stdlib which allows to suppress the diagnostic
This commit is contained in:
Nikita Bobko
2023-07-11 18:00:53 +02:00
committed by Space Team
parent 797ca34a34
commit 25c082f02b
155 changed files with 3875 additions and 40 deletions
@@ -0,0 +1,19 @@
// MODULE: m1-common
// FILE: common.kt
expect open class Foo {
fun existingMethod()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual typealias Foo = FooImpl
open class FooImpl {
fun existingMethod() {}
val existingParam: Int = 904
fun injectedMethod() {} // accidential override can happen with this injected fun. That's why it's prohibited
}
@@ -0,0 +1,19 @@
// MODULE: m1-common
// FILE: common.kt
expect open class Foo {
fun existingMethod()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual typealias <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_MEMBERS_AS_NON_FINAL_EXPECT_CLASSIFIER!>Foo<!> = FooImpl
open class FooImpl {
fun existingMethod() {}
val existingParam: Int = 904
fun injectedMethod() {} // accidential override can happen with this injected fun. That's why it's prohibited
}
@@ -0,0 +1,24 @@
// FIR_IDENTICAL
// MODULE: m1-common
// FILE: common.kt
open class Base() {
open val foo: Int = 1
}
expect open class Foo : Base {
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual typealias Foo = FooImpl
// FILE: Foo.java
public class FooImpl extends Base {
@Override
public int getFoo() {
return 1;
}
}
@@ -0,0 +1,18 @@
// FIR_IDENTICAL
// MODULE: m1-common
// FILE: common.kt
expect open class Foo() {
fun existingFun()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo {
actual fun existingFun() {}
actual val existingParam: Int = 904
actual constructor() {}
}
@@ -0,0 +1,18 @@
// FIR_IDENTICAL
// MODULE: m1-common
// FILE: common.kt
expect open class Foo {
fun existingFun()
val existingParam: Int
constructor()
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo actual constructor() {
actual fun existingFun() {}
actual val existingParam: Int = 904
}
@@ -0,0 +1,21 @@
// FIR_IDENTICAL
// WITH_STDLIB
// MODULE: m1-common
// FILE: common.kt
expect open class Foo {
fun existingMethod()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
@OptIn(kotlin.ExperimentalMultiplatform::class)
@kotlin.AllowDifferentMembersInActual
actual open class Foo {
actual fun existingMethod() {}
actual val existingParam: Int = 904
fun injectedMethod() {} // accidential override can happen with this injected fun. That's why it's prohibited
}
@@ -0,0 +1,23 @@
// FIR_IDENTICAL
// WITH_STDLIB
// MODULE: m1-common
// FILE: common.kt
expect open class Foo {
fun existingMethod()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
@OptIn(kotlin.ExperimentalMultiplatform::class)
@kotlin.AllowDifferentMembersInActual
actual typealias Foo = FooImpl
open class FooImpl {
fun existingMethod() {}
val existingParam: Int = 904
fun injectedMethod() {} // accidential override can happen with this injected fun. That's why it's prohibited
}
@@ -0,0 +1,25 @@
// FIR_IDENTICAL
// LANGUAGE: +ContextReceivers
// MODULE: m1-common
// FILE: common.kt
open class Base<T> {
open fun returnType(): T = null!!
open fun parameterType(t: T) {}
context(T)
open fun contextReceiverType() {}
open fun T.extensionReceiverType() {}
}
expect open class Foo<E> : Base<E>
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo<R> : Base<R>() {
override fun returnType(): R = null!!
override fun parameterType(t: R) {}
context(R)
override fun contextReceiverType() {}
override fun R.extensionReceiverType() {}
}
@@ -0,0 +1,15 @@
// MODULE: m1-common
// FILE: common.kt
open class Base {
<!INCOMPATIBLE_MATCHING{JVM}!>open fun <T> foo(t: T) {}<!>
}
<!INCOMPATIBLE_MATCHING{JVM}!>expect open class Foo : Base<!>
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo : Base() {
override fun <R> foo(t: R) {}
}
@@ -0,0 +1,15 @@
// MODULE: m1-common
// FILE: common.kt
open class Base {
open fun <T> foo(t: T) {}
}
expect open class Foo : Base
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_MEMBERS_AS_NON_FINAL_EXPECT_CLASSIFIER!>class Foo<!> : Base() {
override fun <!TYPE_PARAMETER_NAMES_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION!><R><!> foo(t: R) {}
}
@@ -0,0 +1,20 @@
// MODULE: m1-common
// FILE: common.kt
open class Base {
<!INCOMPATIBLE_MATCHING{JVM}!>open var red1: String = ""<!>
<!INCOMPATIBLE_MATCHING{JVM}!>open lateinit var red2: String<!>
open lateinit var green: String
}
<!INCOMPATIBLE_MATCHING{JVM}!>expect open class Foo : Base {
}<!>
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo : Base() {
override lateinit var red1: String
override var red2: String = ""
override lateinit var green: String
}
@@ -0,0 +1,20 @@
// MODULE: m1-common
// FILE: common.kt
open class Base {
open var red1: String = ""
open lateinit var red2: String
open lateinit var green: String
}
expect open class Foo : Base {
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_MEMBERS_AS_NON_FINAL_EXPECT_CLASSIFIER!>class Foo<!> : Base() {
override <!LATEINIT_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION!>lateinit<!> var red1: String
override var <!LATEINIT_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION!>red2<!>: String = ""
override lateinit var green: String
}
@@ -0,0 +1,15 @@
// MODULE: m1-common
// FILE: common.kt
open class Base {
<!INCOMPATIBLE_MATCHING{JVM}!>open fun foo() {}<!>
}
<!INCOMPATIBLE_MATCHING{JVM}!>expect open class Foo : Base<!>
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo : Base() {
final override fun foo() {}
}
@@ -0,0 +1,15 @@
// MODULE: m1-common
// FILE: common.kt
open class Base {
open fun foo() {}
}
expect open class Foo : Base
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_MEMBERS_AS_NON_FINAL_EXPECT_CLASSIFIER!>class Foo<!> : Base() {
<!MODALITY_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION!>final<!> override fun foo() {}
}
@@ -0,0 +1,15 @@
// MODULE: m1-common
// FILE: common.kt
open class Base<T> {
<!INCOMPATIBLE_MATCHING{JVM}!>open fun foo(t: T) {}<!>
}
<!INCOMPATIBLE_MATCHING{JVM}!>expect open class Foo : Base<String><!>
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo : Base<String>() {
final override fun foo(t: String) {}
}
@@ -0,0 +1,15 @@
// MODULE: m1-common
// FILE: common.kt
open class Base<T> {
open fun foo(t: T) {}
}
expect open class Foo : Base<String>
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_MEMBERS_AS_NON_FINAL_EXPECT_CLASSIFIER!>class Foo<!> : Base<String>() {
<!MODALITY_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION!>final<!> override fun foo(t: String) {}
}
@@ -0,0 +1,11 @@
// MODULE: m1-common
// FILE: common.kt
<!INCOMPATIBLE_MATCHING{JVM}!>expect open class Foo<!>
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo {
final override fun toString() = "Foo"
}
@@ -0,0 +1,11 @@
// MODULE: m1-common
// FILE: common.kt
expect open class Foo
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_MEMBERS_AS_NON_FINAL_EXPECT_CLASSIFIER!>class Foo<!> {
<!MODALITY_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION!>final<!> override fun toString() = "Foo"
}
@@ -0,0 +1,34 @@
// MODULE: m1-common
// FILE: common.kt
open class Base {
<!INCOMPATIBLE_MATCHING{JVM}!>open fun foo(param: Int) {}<!>
}
<!INCOMPATIBLE_MATCHING{JVM}!>expect open class Foo1 : Base<!>
expect open class Foo2 : Base
expect open class Foo3 {
open fun foo(param: Int)
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo1 : Base() {
override fun foo(paramNameChanged: Int) {}
}
actual typealias Foo2 = Foo2Java
actual typealias Foo3 = Foo3Java
// FILE: Foo2Java.java
public class Foo2Java extends Base {
@Override
public void foo(int paramNameChanged) {}
}
// FILE: Foo3Java.java
public class Foo3Java {
public void foo(int paramNameChanged) {}
}
@@ -0,0 +1,34 @@
// MODULE: m1-common
// FILE: common.kt
open class Base {
open fun foo(param: Int) {}
}
expect open class Foo1 : Base
expect open class Foo2 : Base
expect open class Foo3 {
open fun foo(param: Int)
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_MEMBERS_AS_NON_FINAL_EXPECT_CLASSIFIER!>class Foo1<!> : Base() {
override fun <!PARAMETER_NAME_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION!>foo<!>(<!PARAMETER_NAME_CHANGED_ON_OVERRIDE!>paramNameChanged<!>: Int) {}
}
actual typealias Foo2 = Foo2Java
actual typealias Foo3 = Foo3Java
// FILE: Foo2Java.java
public class Foo2Java extends Base {
@Override
public void foo(int paramNameChanged) {}
}
// FILE: Foo3Java.java
public class Foo3Java {
public void foo(int paramNameChanged) {}
}
@@ -0,0 +1,17 @@
// MODULE: m1-common
// FILE: common.kt
open class Base {
<!INCOMPATIBLE_MATCHING{JVM}!>open var foo: String = ""
protected set<!>
}
<!INCOMPATIBLE_MATCHING{JVM}!>expect open class Foo : Base<!>
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo : Base() {
override var foo: String = ""
public set
}
@@ -0,0 +1,17 @@
// MODULE: m1-common
// FILE: common.kt
open class Base {
open var foo: String = ""
protected set
}
expect open class Foo : Base
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_MEMBERS_AS_NON_FINAL_EXPECT_CLASSIFIER!>class Foo<!> : Base() {
override var foo: String = ""
<!SETTER_VISIBILITY_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION!>public<!> set
}
@@ -0,0 +1,15 @@
// MODULE: m1-common
// FILE: common.kt
open class Base {
<!INCOMPATIBLE_MATCHING{JVM}!>protected open fun foo() {}<!>
}
<!INCOMPATIBLE_MATCHING{JVM}!>expect open class Foo : Base<!>
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo : Base() {
public override fun foo() {}
}
@@ -0,0 +1,15 @@
// MODULE: m1-common
// FILE: common.kt
open class Base {
protected open fun foo() {}
}
expect open class Foo : Base
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_MEMBERS_AS_NON_FINAL_EXPECT_CLASSIFIER!>class Foo<!> : Base() {
<!VISIBILITY_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION!>public<!> override fun foo() {}
}
@@ -0,0 +1,17 @@
// MODULE: m1-common
// FILE: common.kt
open class Base {
open val foo: String = ""
<!INCOMPATIBLE_MATCHING{JVM}, INCOMPATIBLE_MATCHING{JVM}!>open fun foo(): Any = ""<!>
}
<!INCOMPATIBLE_MATCHING{JVM}!>expect open class Foo : Base {
}<!>
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo : Base() {
override fun foo(): String = ""
}
@@ -0,0 +1,17 @@
// MODULE: m1-common
// FILE: common.kt
open class Base {
open val foo: String = ""
open fun foo(): Any = ""
}
expect open class Foo : Base {
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_MEMBERS_AS_NON_FINAL_EXPECT_CLASSIFIER!>class Foo<!> : Base() {
override fun foo(): <!RETURN_TYPE_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION!>String<!> = ""
}
@@ -0,0 +1,18 @@
// MODULE: m1-common
// FILE: common.kt
interface I
open class Base {
<!INCOMPATIBLE_MATCHING{JVM}!>open fun foo(): I = null!!<!>
}
<!INCOMPATIBLE_MATCHING{JVM}!>expect open class Foo<T : I> : Base {
}<!>
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo<T : I> : Base() {
override fun foo(): T = null!!
}
@@ -0,0 +1,18 @@
// MODULE: m1-common
// FILE: common.kt
interface I
open class Base {
open fun foo(): I = null!!
}
expect open class Foo<T : I> : Base {
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_MEMBERS_AS_NON_FINAL_EXPECT_CLASSIFIER!>class Foo<!><T : I> : Base() {
override fun foo(): <!RETURN_TYPE_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION!>T<!> = null!!
}
@@ -0,0 +1,16 @@
// MODULE: m1-common
// FILE: common.kt
open class Base<R> {
<!INCOMPATIBLE_MATCHING{JVM}!>open fun foo(): R = null!!<!>
}
<!INCOMPATIBLE_MATCHING{JVM}!>expect open class Foo<R, T : R> : Base<R> {
}<!>
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo<E, F : E> : Base<E>() {
override fun foo(): F = null!!
}
@@ -0,0 +1,16 @@
// MODULE: m1-common
// FILE: common.kt
open class Base<R> {
open fun foo(): R = null!!
}
expect open class Foo<R, T : R> : Base<R> {
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_MEMBERS_AS_NON_FINAL_EXPECT_CLASSIFIER!>class Foo<!><E, F : E> : Base<E>() {
override fun foo(): <!RETURN_TYPE_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION!>F<!> = null!!
}
@@ -0,0 +1,16 @@
// MODULE: m1-common
// FILE: common.kt
open class Base {
<!INCOMPATIBLE_MATCHING{JVM}, INCOMPATIBLE_MATCHING{JVM}!>open val foo: Any = ""<!>
open fun foo(): String = ""
}
<!INCOMPATIBLE_MATCHING{JVM}!>expect open class Foo : Base<!>
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo : Base() {
override val foo: String = ""
}
@@ -0,0 +1,16 @@
// MODULE: m1-common
// FILE: common.kt
open class Base {
open val foo: Any = ""
open fun foo(): String = ""
}
expect open class Foo : Base
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_MEMBERS_AS_NON_FINAL_EXPECT_CLASSIFIER!>class Foo<!> : Base() {
override val foo: <!RETURN_TYPE_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION!>String<!> = ""
}
@@ -0,0 +1,16 @@
// FIR_IDENTICAL
// MODULE: m1-common
// FILE: common.kt
open class Base {
open fun foo() {}
}
expect open class Foo : Base
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo : Base() {
override fun foo() {}
}
@@ -0,0 +1,12 @@
// FIR_IDENTICAL
// MODULE: m1-common
// FILE: common.kt
expect class Foo
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo {
fun injectedMethod() {}
}
@@ -0,0 +1,16 @@
// MODULE: m1-common
// FILE: common.kt
expect open class Foo {
fun foo()
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo {
// Hypothetically, it's more restricting than necessary. I can't see how actualizing final -> open can breaking anything.
// But technically, actual and expect scopes don't match
actual open fun foo() {
}
}
@@ -0,0 +1,16 @@
// MODULE: m1-common
// FILE: common.kt
expect open class Foo {
fun foo()
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_MEMBERS_AS_NON_FINAL_EXPECT_CLASSIFIER!>class Foo<!> {
// Hypothetically, it's more restricting than necessary. I can't see how actualizing final -> open can breaking anything.
// But technically, actual and expect scopes don't match
actual <!MODALITY_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION!>open<!> fun foo() {
}
}
@@ -0,0 +1,33 @@
// MODULE: m1-common
// FILE: common.kt
expect open class Base {
<!INCOMPATIBLE_MATCHING{JVM}!>open fun foo(): MutableList<String><!>
}
<!INCOMPATIBLE_MATCHING{JVM}!>expect open class Foo : Base {
}<!>
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual typealias Base = BaseJava
actual open class Foo : Base() {
// K1 doesn't report a diagnostic here because when it compares scopes it sees flexible type
// K2 will likely report a diagnostic here
// I don't think we can fix this 'K1 green -> K2 red'. It must be a rare case anyway.
override fun foo(): List<String> {
return super.foo()
}
}
// FILE: BaseJava.java
import java.util.List;
public class BaseJava {
public List<String> foo() {
return null;
}
}
@@ -0,0 +1,33 @@
// MODULE: m1-common
// FILE: common.kt
expect open class Base {
open fun foo(): MutableList<String>
}
expect open class Foo : Base {
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual typealias Base = BaseJava
actual open class Foo : Base() {
// K1 doesn't report a diagnostic here because when it compares scopes it sees flexible type
// K2 will likely report a diagnostic here
// I don't think we can fix this 'K1 green -> K2 red'. It must be a rare case anyway.
override fun foo(): List<String> {
return super.foo()
}
}
// FILE: BaseJava.java
import java.util.List;
public class BaseJava {
public List<String> foo() {
return null;
}
}
@@ -0,0 +1,24 @@
// FIR_IDENTICAL
// MODULE: m1-common
// FILE: common.kt
expect open class Foo {
fun existingFun()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo {
actual fun existingFun() {}
actual val existingParam: Int = 904
class InjectedClass
// Injected classes can be considered as members (because they caputer `this`) => scopes are different
// => the diagnostic should be reported.
//
// But since `override inner class` isn't possible in Kotlin, red code here is unnecessary
inner class InjectedInnerClass
}
@@ -0,0 +1,17 @@
// LANGUAGE: +ContextReceivers
// MODULE: m1-common
// FILE: common.kt
expect open class Foo {
fun foo()
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo {
actual fun foo() {}
context(Int)
fun foo() {} // accidential override can happen with this injected fun. That's why it's prohibited
}
@@ -0,0 +1,17 @@
// LANGUAGE: +ContextReceivers
// MODULE: m1-common
// FILE: common.kt
expect open class Foo {
fun <!AMBIGUOUS_ACTUALS{JVM}!>foo<!>()
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_MEMBERS_AS_NON_FINAL_EXPECT_CLASSIFIER!>class Foo<!> {
actual fun foo() {}
context(Int)
fun <!ACTUAL_MISSING, NON_ACTUAL_MEMBER_DECLARED_IN_EXPECT_NON_FINAL_CLASSIFIER_ACTUALIZATION!>foo<!>() {} // accidential override can happen with this injected fun. That's why it's prohibited
}
@@ -0,0 +1,17 @@
// MODULE: m1-common
// FILE: common.kt
expect open class Foo {
fun existingMethod()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
open class InjectedEmptySuperClass()
actual open class Foo : InjectedEmptySuperClass() {
actual fun existingMethod() {}
actual val existingParam: Int = 904
}
@@ -0,0 +1,17 @@
// MODULE: m1-common
// FILE: common.kt
expect open class Foo {
fun existingMethod()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
open class InjectedEmptySuperClass()
actual open <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_SUPERTYPES_AS_NON_FINAL_EXPECT_CLASSIFIER!>class Foo<!> : InjectedEmptySuperClass() {
actual fun existingMethod() {}
actual val existingParam: Int = 904
}
@@ -0,0 +1,15 @@
// MODULE: m1-common
// FILE: common.kt
expect open class Foo {
fun foo()
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo {
actual fun foo() {}
fun Int.foo() {} // accidential override can happen with this injected fun. That's why it's prohibited
}
@@ -0,0 +1,15 @@
// MODULE: m1-common
// FILE: common.kt
expect open class Foo {
fun foo()
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_MEMBERS_AS_NON_FINAL_EXPECT_CLASSIFIER!>class Foo<!> {
actual fun foo() {}
fun Int.<!NON_ACTUAL_MEMBER_DECLARED_IN_EXPECT_NON_FINAL_CLASSIFIER_ACTUALIZATION!>foo<!>() {} // accidential override can happen with this injected fun. That's why it's prohibited
}
@@ -0,0 +1,15 @@
// MODULE: m1-common
// FILE: common.kt
open class Base {
fun <T> foo(t: T) {}
}
expect open class Foo : Base
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo : Base() {
fun <T : Comparable<T>> foo(t: T) {}
}
@@ -0,0 +1,15 @@
// MODULE: m1-common
// FILE: common.kt
open class Base {
fun <T> foo(t: T) {}
}
expect open class Foo : Base
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_MEMBERS_AS_NON_FINAL_EXPECT_CLASSIFIER!>class Foo<!> : Base() {
fun <T : Comparable<T>> <!NON_ACTUAL_MEMBER_DECLARED_IN_EXPECT_NON_FINAL_CLASSIFIER_ACTUALIZATION!>foo<!>(t: T) {}
}
@@ -0,0 +1,17 @@
// MODULE: m1-common
// FILE: common.kt
expect open class Foo {
fun existingMethod()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo {
actual fun existingMethod() {}
actual val existingParam: Int = 904
internal fun injectedMethod() {} // accidential override can happen with this injected fun. That's why it's prohibited
}
@@ -0,0 +1,17 @@
// MODULE: m1-common
// FILE: common.kt
expect open class Foo {
fun existingMethod()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_MEMBERS_AS_NON_FINAL_EXPECT_CLASSIFIER!>class Foo<!> {
actual fun existingMethod() {}
actual val existingParam: Int = 904
internal fun <!NON_ACTUAL_MEMBER_DECLARED_IN_EXPECT_NON_FINAL_CLASSIFIER_ACTUALIZATION!>injectedMethod<!>() {} // accidential override can happen with this injected fun. That's why it's prohibited
}
@@ -0,0 +1,18 @@
// FIR_IDENTICAL
// MODULE: m1-common
// FILE: common.kt
expect open class Foo {
fun existingMethod()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo {
actual fun existingMethod() {}
actual val existingParam: Int = 904
private fun injected() {}
}
@@ -0,0 +1,17 @@
// MODULE: m1-common
// FILE: common.kt
expect open class Foo {
fun existingMethod()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo {
actual fun existingMethod() {}
actual val existingParam: Int = 904
protected fun injectedMethod() {} // accidential override can happen with this injected fun. That's why it's prohibited
}
@@ -0,0 +1,17 @@
// MODULE: m1-common
// FILE: common.kt
expect open class Foo {
fun existingMethod()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_MEMBERS_AS_NON_FINAL_EXPECT_CLASSIFIER!>class Foo<!> {
actual fun existingMethod() {}
actual val existingParam: Int = 904
protected fun <!NON_ACTUAL_MEMBER_DECLARED_IN_EXPECT_NON_FINAL_CLASSIFIER_ACTUALIZATION!>injectedMethod<!>() {} // accidential override can happen with this injected fun. That's why it's prohibited
}
@@ -0,0 +1,17 @@
// MODULE: m1-common
// FILE: common.kt
expect open class Foo {
fun existingMethod()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo {
actual fun existingMethod() {}
actual val existingParam: Int = 904
fun injectedMethod() {} // accidential override can happen with this injected fun. That's why it's prohibited
}
@@ -0,0 +1,17 @@
// MODULE: m1-common
// FILE: common.kt
expect open class Foo {
fun existingMethod()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_MEMBERS_AS_NON_FINAL_EXPECT_CLASSIFIER!>class Foo<!> {
actual fun existingMethod() {}
actual val existingParam: Int = 904
fun <!NON_ACTUAL_MEMBER_DECLARED_IN_EXPECT_NON_FINAL_CLASSIFIER_ACTUALIZATION!>injectedMethod<!>() {} // accidential override can happen with this injected fun. That's why it's prohibited
}
@@ -0,0 +1,19 @@
// MODULE: m1-common
// FILE: common.kt
expect open class Foo {
fun existingMethod()
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual typealias Foo = FooImpl
// FILE: Foo.java
public class FooImpl {
public void existingMethod() {}
public void injectedMethod() {}
}
@@ -0,0 +1,19 @@
// MODULE: m1-common
// FILE: common.kt
expect open class Foo {
fun existingMethod()
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual typealias <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_MEMBERS_AS_NON_FINAL_EXPECT_CLASSIFIER!>Foo<!> = FooImpl
// FILE: Foo.java
public class FooImpl {
public void existingMethod() {}
public void injectedMethod() {}
}
@@ -0,0 +1,15 @@
// MODULE: m1-common
// FILE: common.kt
expect open class Foo {
fun foo()
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo {
actual fun foo() {}
fun foo(overloaded: Int) {} // accidential override can happen with this injected fun. That's why it's prohibited
}
@@ -0,0 +1,15 @@
// MODULE: m1-common
// FILE: common.kt
expect open class Foo {
fun foo()
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_MEMBERS_AS_NON_FINAL_EXPECT_CLASSIFIER!>class Foo<!> {
actual fun foo() {}
fun <!NON_ACTUAL_MEMBER_DECLARED_IN_EXPECT_NON_FINAL_CLASSIFIER_ACTUALIZATION!>foo<!>(overloaded: Int) {} // accidential override can happen with this injected fun. That's why it's prohibited
}
@@ -0,0 +1,15 @@
// MODULE: m1-common
// FILE: common.kt
open class Base<T> {
open fun foo(t: T) {}
}
expect open class Foo<R> : Base<R>
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo<R>() : Base<R>() {
fun <T> foo(t: T) {}
}
@@ -0,0 +1,15 @@
// MODULE: m1-common
// FILE: common.kt
open class Base<T> {
open fun foo(t: T) {}
}
expect open class Foo<R> : Base<R>
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_MEMBERS_AS_NON_FINAL_EXPECT_CLASSIFIER!>class Foo<!><R>() : Base<R>() {
fun <T> <!NON_ACTUAL_MEMBER_DECLARED_IN_EXPECT_NON_FINAL_CLASSIFIER_ACTUALIZATION!>foo<!>(t: T) {}
}
@@ -0,0 +1,16 @@
// FIR_IDENTICAL
// MODULE: m1-common
// FILE: common.kt
expect open class Foo {
fun existingFun()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo(injectedConstructor: Int) {
actual fun existingFun() {}
actual val existingParam: Int = 904
}
@@ -0,0 +1,18 @@
// FIR_IDENTICAL
// MODULE: m1-common
// FILE: common.kt
expect open class Foo {
fun existingFun()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo {
actual fun existingFun() {}
actual val existingParam: Int = 904
private val injectedProperty = 1
}
@@ -0,0 +1,17 @@
// MODULE: m1-common
// FILE: common.kt
expect open class Foo {
fun existingFun()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo {
actual fun existingFun() {}
actual val existingParam: Int = 904
val injectedProperty = 1
}
@@ -0,0 +1,17 @@
// MODULE: m1-common
// FILE: common.kt
expect open class Foo {
fun existingFun()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_MEMBERS_AS_NON_FINAL_EXPECT_CLASSIFIER!>class Foo<!> {
actual fun existingFun() {}
actual val existingParam: Int = 904
val <!NON_ACTUAL_MEMBER_DECLARED_IN_EXPECT_NON_FINAL_CLASSIFIER_ACTUALIZATION!>injectedProperty<!> = 1
}
@@ -0,0 +1,15 @@
// MODULE: m1-common
// FILE: common.kt
expect open class Foo {
fun foo(): Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo {
actual fun foo(): Int = 904
val foo: Int = 42
}
@@ -0,0 +1,15 @@
// MODULE: m1-common
// FILE: common.kt
expect open class Foo {
fun foo(): Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_MEMBERS_AS_NON_FINAL_EXPECT_CLASSIFIER!>class Foo<!> {
actual fun foo(): Int = 904
val <!NON_ACTUAL_MEMBER_DECLARED_IN_EXPECT_NON_FINAL_CLASSIFIER_ACTUALIZATION!>foo<!>: Int = 42
}
@@ -0,0 +1,19 @@
// MODULE: m1-common
// FILE: common.kt
expect open class Foo {
fun existingMethod()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
open class Injector {
fun injectedMethod() {}
}
actual open class Foo : Injector() {
actual fun existingMethod() {}
actual val existingParam: Int = 904
}
@@ -0,0 +1,19 @@
// MODULE: m1-common
// FILE: common.kt
expect open class Foo {
fun existingMethod()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
open class Injector {
fun injectedMethod() {}
}
actual open <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_SUPERTYPES_AS_NON_FINAL_EXPECT_CLASSIFIER!>class Foo<!> : Injector() {
actual fun existingMethod() {}
actual val existingParam: Int = 904
}
@@ -0,0 +1,18 @@
// FIR_IDENTICAL
// MODULE: m1-common
// FILE: common.kt
expect open class Foo {
fun existingFun()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo {
actual fun existingFun() {}
actual val existingParam: Int = 904
constructor(injectedConstructor: Int) {}
}
@@ -0,0 +1,24 @@
// WITH_STDLIB
// MODULE: m1-common
// FILE: common.kt
expect open class Base {
fun injected()
}
expect open class Foo {
fun existingMethod()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Base {
actual fun injected() {}
}
actual open class Foo : Base() {
actual fun existingMethod() {}
actual val existingParam: Int = 904
}
@@ -0,0 +1,24 @@
// WITH_STDLIB
// MODULE: m1-common
// FILE: common.kt
expect open class Base {
fun injected()
}
expect open class Foo {
fun existingMethod()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Base {
actual fun injected() {}
}
actual open <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_SUPERTYPES_AS_NON_FINAL_EXPECT_CLASSIFIER!>class Foo<!> : Base() {
actual fun existingMethod() {}
actual val existingParam: Int = 904
}
@@ -0,0 +1,26 @@
// WITH_STDLIB
// MODULE: m1-common
// FILE: common.kt
expect open class Base {
fun injected()
}
expect open class Foo {
fun existingMethod()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Base {
actual fun injected() {}
}
open class Transitive : Base()
actual open class Foo : Transitive() {
actual fun existingMethod() {}
actual val existingParam: Int = 904
}
@@ -0,0 +1,26 @@
// WITH_STDLIB
// MODULE: m1-common
// FILE: common.kt
expect open class Base {
fun injected()
}
expect open class Foo {
fun existingMethod()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Base {
actual fun injected() {}
}
open class Transitive : Base()
actual open <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_SUPERTYPES_AS_NON_FINAL_EXPECT_CLASSIFIER!>class Foo<!> : Transitive() {
actual fun existingMethod() {}
actual val existingParam: Int = 904
}
@@ -0,0 +1,15 @@
// MODULE: m1-common
// FILE: common.kt
open class Base {
open fun foo(t: String) {}
}
expect open class Foo : Base
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo : Base() {
open fun foo(vararg t: String) {} // injected
}
@@ -0,0 +1,15 @@
// MODULE: m1-common
// FILE: common.kt
open class Base {
open fun foo(t: String) {}
}
expect open class Foo : Base
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_MEMBERS_AS_NON_FINAL_EXPECT_CLASSIFIER!>class Foo<!> : Base() {
open fun <!NON_ACTUAL_MEMBER_DECLARED_IN_EXPECT_NON_FINAL_CLASSIFIER_ACTUALIZATION!>foo<!>(vararg t: String) {} // injected
}
@@ -0,0 +1,22 @@
// MODULE: m1-common
// FILE: common.kt
// Rules for expect actual matching are ad-hoc for nested classes. That's why this test exist
expect class Outer {
open class Foo {
fun existingMethod()
val existingParam: Int
}
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual class Outer {
actual open class Foo {
actual fun existingMethod() {}
actual val existingParam: Int = 904
fun injectedMethod() {} // accidential override can happen with this injected fun. That's why it's prohibited
}
}
@@ -0,0 +1,22 @@
// MODULE: m1-common
// FILE: common.kt
// Rules for expect actual matching are ad-hoc for nested classes. That's why this test exist
expect class Outer {
open class Foo {
fun existingMethod()
val existingParam: Int
}
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual class Outer {
actual open <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_MEMBERS_AS_NON_FINAL_EXPECT_CLASSIFIER!>class Foo<!> {
actual fun existingMethod() {}
actual val existingParam: Int = 904
fun <!NON_ACTUAL_MEMBER_DECLARED_IN_EXPECT_NON_FINAL_CLASSIFIER_ACTUALIZATION!>injectedMethod<!>() {} // accidential override can happen with this injected fun. That's why it's prohibited
}
}
@@ -0,0 +1,15 @@
// MODULE: m1-common
// FILE: common.kt
open class Base {
<!INCOMPATIBLE_MATCHING{JVM}!>open val foo: Int = 1<!>
}
<!INCOMPATIBLE_MATCHING{JVM}!>expect open class Foo : Base<!>
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo : Base() {
override var foo: Int = 1
}
@@ -0,0 +1,15 @@
// MODULE: m1-common
// FILE: common.kt
open class Base {
open val foo: Int = 1
}
expect open class Foo : Base
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_MEMBERS_AS_NON_FINAL_EXPECT_CLASSIFIER!>class Foo<!> : Base() {
override <!PROPERTY_KIND_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION!>var<!> foo: Int = 1
}
@@ -0,0 +1,29 @@
// MODULE: m1-common
// FILE: common.kt
open class Base() {
<!INCOMPATIBLE_MATCHING{JVM}!>open fun overrideReturnType(): Any = ""<!>
<!INCOMPATIBLE_MATCHING{JVM}!>open fun overrideModality1(): Any = ""<!>
<!INCOMPATIBLE_MATCHING{JVM}!>open fun overrideModality2(): Any = ""<!>
<!INCOMPATIBLE_MATCHING{JVM}!>protected open fun overrideVisibility(): Any = ""<!>
}
<!INCOMPATIBLE_MATCHING{JVM}!>expect open class Foo : Base {
fun existingMethod()
val existingParam: Int
}<!>
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo : Base() {
actual fun existingMethod() {}
actual val existingParam: Int = 904
fun injectedMethod() {}
val injectedProperty: Int = 42
override fun overrideReturnType(): String = ""
final override fun overrideModality1(): Any = ""
final override fun overrideModality2(): Any = ""
public override fun overrideVisibility(): Any = ""
}
@@ -0,0 +1,29 @@
// MODULE: m1-common
// FILE: common.kt
open class Base() {
open fun overrideReturnType(): Any = ""
open fun overrideModality1(): Any = ""
open fun overrideModality2(): Any = ""
protected open fun overrideVisibility(): Any = ""
}
expect open class Foo : Base {
fun existingMethod()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_MEMBERS_AS_NON_FINAL_EXPECT_CLASSIFIER!>class Foo<!> : Base() {
actual fun existingMethod() {}
actual val existingParam: Int = 904
fun <!NON_ACTUAL_MEMBER_DECLARED_IN_EXPECT_NON_FINAL_CLASSIFIER_ACTUALIZATION!>injectedMethod<!>() {}
val <!NON_ACTUAL_MEMBER_DECLARED_IN_EXPECT_NON_FINAL_CLASSIFIER_ACTUALIZATION!>injectedProperty<!>: Int = 42
override fun overrideReturnType(): <!RETURN_TYPE_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION!>String<!> = ""
<!MODALITY_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION!>final<!> override fun overrideModality1(): Any = ""
<!MODALITY_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION!>final<!> override fun overrideModality2(): Any = ""
<!VISIBILITY_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION!>public<!> override fun overrideVisibility(): Any = ""
}
@@ -0,0 +1,16 @@
// FIR_IDENTICAL
// MODULE: m1-common
// FILE: common.kt
open class Base<T> {
open fun foo(t: T) {}
}
expect open class Foo : Base<String>
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo : Base<String>() {
override fun foo(t: String) {}
}
@@ -0,0 +1,22 @@
// FIR_IDENTICAL
// MODULE: m1-common
// FILE: common.kt
expect open class Supertype()
expect open class Foo : Supertype {
fun existingMethod()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual typealias Supertype = SupertypeImpl
open class SupertypeImpl()
actual open class Foo : SupertypeImpl() {
actual fun existingMethod() {}
actual val existingParam: Int = 904
}
@@ -0,0 +1,19 @@
// FIR_IDENTICAL
// MODULE: m1-common
// FILE: common.kt
open class Supertype()
typealias SupertypeAlias = Supertype
expect open class Foo : Supertype {
fun existingMethod()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo : SupertypeAlias() {
actual fun existingMethod() {}
actual val existingParam: Int = 904
}
@@ -0,0 +1,19 @@
// FIR_IDENTICAL
// MODULE: m1-common
// FILE: common.kt
open class Supertype()
typealias SupertypeAlias = Supertype
expect open class Foo : SupertypeAlias {
fun existingMethod()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Foo : Supertype() {
actual fun existingMethod() {}
actual val existingParam: Int = 904
}
@@ -0,0 +1,29 @@
// WITH_STDLIB
// MODULE: m1-common
// FILE: common.kt
expect open class Base {
fun existingMethodInBase()
}
expect open class Foo : Base {
fun existingMethod()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
@OptIn(ExperimentalMultiplatform::class)
@AllowDifferentMembersInActual
actual open class Base {
actual fun existingMethodInBase() {}
open fun injected(): Any = ""
}
actual open class Foo : Base() {
actual fun existingMethod() {}
actual val existingParam: Int = 904
override fun injected(): String = "" // covariant override
}
@@ -0,0 +1,29 @@
// WITH_STDLIB
// MODULE: m1-common
// FILE: common.kt
expect open class Base {
fun existingMethodInBase()
}
expect open class Foo : Base {
fun existingMethod()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
@OptIn(ExperimentalMultiplatform::class)
@AllowDifferentMembersInActual
actual open class Base {
actual fun existingMethodInBase() {}
open fun injected(): Any = ""
}
actual open <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_MEMBERS_AS_NON_FINAL_EXPECT_CLASSIFIER!>class Foo<!> : Base() {
actual fun existingMethod() {}
actual val existingParam: Int = 904
override fun injected(): <!RETURN_TYPE_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION!>String<!> = "" // covariant override
}
@@ -0,0 +1,31 @@
// WITH_STDLIB
// MODULE: m1-common
// FILE: common.kt
expect open class Base<T>() {
fun existingMethodInBase(param: T)
}
open class Transitive : Base<String>()
expect open class Foo : Transitive {
fun existingMethod()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
@OptIn(ExperimentalMultiplatform::class)
@AllowDifferentMembersInActual
actual open class Base<T> {
actual fun existingMethodInBase(param: T) {}
open fun injected(param: T): Any = ""
}
actual open class Foo : Transitive() {
actual fun existingMethod() {}
actual val existingParam: Int = 904
override fun injected(param: String): String = "" // covariant override
}
@@ -0,0 +1,31 @@
// WITH_STDLIB
// MODULE: m1-common
// FILE: common.kt
expect open class Base<T>() {
fun existingMethodInBase(param: T)
}
open class Transitive : Base<String>()
expect open class Foo : Transitive {
fun existingMethod()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
@OptIn(ExperimentalMultiplatform::class)
@AllowDifferentMembersInActual
actual open class Base<T> {
actual fun existingMethodInBase(param: T) {}
open fun injected(param: T): Any = ""
}
actual open <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_MEMBERS_AS_NON_FINAL_EXPECT_CLASSIFIER!>class Foo<!> : Transitive() {
actual fun existingMethod() {}
actual val existingParam: Int = 904
override fun injected(param: String): <!RETURN_TYPE_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION!>String<!> = "" // covariant override
}
@@ -0,0 +1,28 @@
// FIR_IDENTICAL
// WITH_STDLIB
// MODULE: m1-common
// FILE: common.kt
expect open class Base {
fun existingMethodInBase()
}
expect open class Foo : Base {
fun existingMethod()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
@OptIn(ExperimentalMultiplatform::class)
@AllowDifferentMembersInActual
actual open class Base {
actual fun existingMethodInBase() {}
fun injected() {}
}
actual open class Foo : Base() {
actual fun existingMethod() {}
actual val existingParam: Int = 904
}
@@ -0,0 +1,30 @@
// FIR_IDENTICAL
// WITH_STDLIB
// MODULE: m1-common
// FILE: common.kt
expect open class Base<T>() {
fun existingMethodInBase(param: T)
}
open class Transitive : Base<String>()
expect open class Foo : Transitive {
fun existingMethod()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
@OptIn(ExperimentalMultiplatform::class)
@AllowDifferentMembersInActual
actual open class Base<T> {
actual fun existingMethodInBase(param: T) {}
fun injected() {}
}
actual open class Foo : Transitive() {
actual fun existingMethod() {}
actual val existingParam: Int = 904
}
@@ -0,0 +1,24 @@
// WITH_STDLIB
// MODULE: m1-common
// FILE: common.kt
expect open class Base {
fun injected()
}
expect open class Foo {
fun existingMethod()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Base {
actual fun injected() {}
}
actual open class Foo : Base() {
actual fun existingMethod() {}
actual val existingParam: Int = 904
}
@@ -0,0 +1,24 @@
// WITH_STDLIB
// MODULE: m1-common
// FILE: common.kt
expect open class Base {
fun injected()
}
expect open class Foo {
fun existingMethod()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Base {
actual fun injected() {}
}
actual open <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_SUPERTYPES_AS_NON_FINAL_EXPECT_CLASSIFIER!>class Foo<!> : Base() {
actual fun existingMethod() {}
actual val existingParam: Int = 904
}
@@ -0,0 +1,26 @@
// WITH_STDLIB
// MODULE: m1-common
// FILE: common.kt
expect open class Base<T> {
fun injected(param: T)
}
expect open class Foo {
fun existingMethod()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Base<T> {
actual fun injected(param: T) {}
}
open class Transitive : Base<String>()
actual open class Foo : Transitive() {
actual fun existingMethod() {}
actual val existingParam: Int = 904
}
@@ -0,0 +1,26 @@
// WITH_STDLIB
// MODULE: m1-common
// FILE: common.kt
expect open class Base<T> {
fun injected(param: T)
}
expect open class Foo {
fun existingMethod()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Base<T> {
actual fun injected(param: T) {}
}
open class Transitive : Base<String>()
actual open <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_SUPERTYPES_AS_NON_FINAL_EXPECT_CLASSIFIER!>class Foo<!> : Transitive() {
actual fun existingMethod() {}
actual val existingParam: Int = 904
}
@@ -0,0 +1,27 @@
// FIR_IDENTICAL
// WITH_STDLIB
// MODULE: m1-common
// FILE: common.kt
expect open class Base() {
open fun existingMethodInBase()
}
expect open class Foo : Base {
fun existingMethod()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Base {
actual open fun existingMethodInBase() {}
}
actual open class Foo : Base() {
actual fun existingMethod() {}
actual val existingParam: Int = 904
override fun existingMethodInBase() {} // override from super
}
@@ -0,0 +1,29 @@
// FIR_IDENTICAL
// WITH_STDLIB
// MODULE: m1-common
// FILE: common.kt
expect open class Base<T>() {
open fun existingMethodInBase(param: T)
}
open class Transitive : Base<String>()
expect open class Foo : Transitive {
fun existingMethod()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual open class Base<T> {
actual open fun existingMethodInBase(param: T) {}
}
actual open class Foo : Transitive() {
actual fun existingMethod() {}
actual val existingParam: Int = 904
override fun existingMethodInBase(param: String) {} // override from super
}
@@ -0,0 +1,30 @@
// FIR_IDENTICAL
// WITH_STDLIB
// MODULE: m1-common
// FILE: common.kt
expect open class Base() {
fun existingMethodInBase()
}
expect open class Foo : Base {
fun existingMethod()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
@OptIn(ExperimentalMultiplatform::class)
@AllowDifferentMembersInActual
actual typealias Base = BaseImpl
open class BaseImpl {
fun existingMethodInBase() {}
fun injected() {}
}
actual open class Foo : Base() {
actual fun existingMethod() {}
actual val existingParam: Int = 904
}
@@ -0,0 +1,32 @@
// FIR_IDENTICAL
// WITH_STDLIB
// MODULE: m1-common
// FILE: common.kt
expect open class Base<T>() {
fun existingMethodInBase(param: T)
}
open class Transitive : Base<String>()
expect open class Foo : Transitive {
fun existingMethod()
val existingParam: Int
}
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
@OptIn(ExperimentalMultiplatform::class)
@AllowDifferentMembersInActual
actual typealias Base<T> = BaseImpl<T>
open class BaseImpl<T> {
fun existingMethodInBase(param: T) {}
fun injected() {}
}
actual open class Foo : Transitive() {
actual fun existingMethod() {}
actual val existingParam: Int = 904
}
@@ -40,4 +40,4 @@ actual typealias <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>MyDeprecatedNotMatch<!>
actual typealias MyDeprecatedMatch = kotlin.Deprecated
actual typealias MyAbstractIterator<T> = AbstractIterator<T>
actual typealias <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_MEMBERS_AS_NON_FINAL_EXPECT_CLASSIFIER, ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_SUPERTYPES_AS_NON_FINAL_EXPECT_CLASSIFIER!>MyAbstractIterator<!><T> = AbstractIterator<T>

Some files were not shown because too many files have changed in this diff Show More