diff --git a/compiler/testData/binaryCompatibility/klibEvolution/addAbstractMemberBody.kt b/compiler/testData/binaryCompatibility/klibEvolution/addAbstractMemberBody.kt new file mode 100644 index 00000000000..b1306bf3f34 --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/addAbstractMemberBody.kt @@ -0,0 +1,43 @@ +// MODULE: lib +// FILE: A.kt +// VERSION: 1 + +abstract class X { + abstract fun foo(): String + abstract val bar: String + + fun qux() = "nothing" +} + +// FILE: B.kt +// VERSION: 2 + +abstract class X { + open fun foo(): String = "now with a body" + open val bar: String get() = "now with a body" + fun qux() = foo() + bar +} + +// MODULE: mainLib(lib) +// FILE: mainLib.kt + +class Y: X() { + override fun foo() = "derived body" + override val bar get() = "derived body" +} + +fun lib(): String { + val y = Y() + return when { + y.foo() != "derived body" -> "fail 1" + y.bar != "derived body" -> "fail 2" + y.qux() != "derived bodyderived body" -> "fail 3" + + else -> "OK" + } +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/addCompanionObject.kt b/compiler/testData/binaryCompatibility/klibEvolution/addCompanionObject.kt new file mode 100644 index 00000000000..cbd7e09183f --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/addCompanionObject.kt @@ -0,0 +1,31 @@ +// MODULE: lib +// FILE: A.kt +// VERSION: 1 + +class X { + fun foo() = "without companion" +} + +// FILE: B.kt +// VERSION: 2 + +class X { + fun foo() = "with companion" + + companion object { + val bar = "this is a companion" + } +} + +// MODULE: mainLib(lib) +// FILE: mainLib.kt + +fun lib(): String = when { + X().foo() != "with companion" -> "fail 1" + else -> "OK" +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/addDefaultImplementations.kt b/compiler/testData/binaryCompatibility/klibEvolution/addDefaultImplementations.kt new file mode 100644 index 00000000000..edc41a93540 --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/addDefaultImplementations.kt @@ -0,0 +1,52 @@ +// MODULE: lib +// FILE: A.kt +// VERSION: 1 + +interface X { + fun foo(): String + val bar: String + fun qux(): String +} + +interface Z { + fun qux(): String = "initially default method" +} + +// FILE: B.kt +// VERSION: 2 + +interface X { + fun foo(): String = "default method" + val bar: String get() = "default property" + fun qux(): String = "ubdated default method" +} + +interface Z { + fun qux(): String = "alternative default method" +} + +// MODULE: mainLib(lib) +// FILE: mainLib.kt + +class Y: X, Z { + override fun foo(): String = "overridden method" + override val bar: String get() = "overridden property" + override fun qux(): String = "overridden multiple versions" +} + +val y = Y() +val t = object : Z {} + +fun lib(): String = when { + y.foo() != "overridden method" -> "fail 1" + y.bar != "overridden property" -> "fail 2" + y.qux() != "overridden multiple versions" -> "fail 3" + t.qux() != "alternative default method" -> "fail 4" + + else -> "OK" +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/addEnumClassMember.kt b/compiler/testData/binaryCompatibility/klibEvolution/addEnumClassMember.kt new file mode 100644 index 00000000000..6af8f2a5c66 --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/addEnumClassMember.kt @@ -0,0 +1,32 @@ +// MODULE: lib +// FILE: A.kt +// VERSION: 1 + +enum class X { + Y, + Z +} + +// FILE: B.kt +// VERSION: 2 + +enum class X { + Y, + Z, + W +} + +// MODULE: mainLib(lib) +// FILE: mainLib.kt + +fun lib(): String = when { + X.values().map { it.name }.joinToString(", ") != "Y, Z, W" -> "fail 1" + X.valueOf("W").name != "W" -> "fail 2" + + else -> "OK" +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/addLateinitToVar.kt b/compiler/testData/binaryCompatibility/klibEvolution/addLateinitToVar.kt new file mode 100644 index 00000000000..a2b4760e5fe --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/addLateinitToVar.kt @@ -0,0 +1,55 @@ +// MODULE: lib +// FILE: A.kt +// VERSION: 1 + +var qux: String = "no lateinit" + +class X { + var bar: String = "no lateinit" +} + +// FILE: B.kt +// VERSION: 2 + +lateinit var qux: String + +class X { + lateinit var bar: String +} + +// MODULE: mainLib(lib) +// FILE: mainLib.kt + +val x = X() + +fun lib(): String { + + val a = try { + qux + } catch (e: UninitializedPropertyAccessException) { + "uninitiaized" + } + + val b = try { + x.bar + } catch(e: UninitializedPropertyAccessException) { + "uninitiaized" + } + + qux = "new global value" + x.bar = "new member value" + + return when { + a != "uninitiaized" -> "fail 1" + b != "uninitiaized" -> "fail 2" + qux != "new global value" -> "fail 3" + x.bar != "new member value" -> "fail 4" + + else -> "OK" + } +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/addOpenToClass.kt b/compiler/testData/binaryCompatibility/klibEvolution/addOpenToClass.kt new file mode 100644 index 00000000000..c7242e785ed --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/addOpenToClass.kt @@ -0,0 +1,39 @@ +// MODULE: lib +// FILE: A.kt +// VERSION: 1 + +class X { + fun foo(): String = "in final class" + val bar: String = "in final class" +} + +fun qux(): X = X() + +// FILE: B.kt +// VERSION: 2 + +open class X { + fun foo(): String = "in open class" + val bar: String = "in open class" +} + +class Y: X() + +fun qux(): X = Y() + +// MODULE: mainLib(lib) +// FILE: mainLib.kt + +fun lib(): String = when { + X().foo() != "in open class" -> "fail 1" + X().bar != "in open class" -> "fail 2" + qux().foo() != "in open class" -> "fail 3" + qux().bar != "in open class" -> "fail 4" + + else -> "OK" +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/addOpenToMember.kt b/compiler/testData/binaryCompatibility/klibEvolution/addOpenToMember.kt new file mode 100644 index 00000000000..36574ff317d --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/addOpenToMember.kt @@ -0,0 +1,44 @@ +// MODULE: lib +// FILE: A.kt +// VERSION: 1 + +open class X { + fun foo(): String = "final method" + val bar: String = "final property" +} + +class Y: X() + +// FILE: B.kt +// VERSION: 2 + +open class X { + open fun foo(): String = "open method" + open val bar: String = "open property" +} + +class Y: X() { + override fun foo(): String = "derived method" + override val bar: String = "derived property" +} + +// MODULE: mainLib(lib) +// FILE: mainLib.kt + +class Z: X() + +fun lib(): String = when { + X().foo() != "open method" -> "fail 1" + X().bar != "open property" -> "fail 2" + Y().foo() != "derived method" -> "fail 3" + Y().bar != "derived property" -> "fail 4" + Z().foo() != "open method" -> "fail 5" + Z().bar != "open property" -> "fail 6" + + else -> "OK" +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/addOrRemoveConst.kt b/compiler/testData/binaryCompatibility/klibEvolution/addOrRemoveConst.kt new file mode 100644 index 00000000000..e1100bc4708 --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/addOrRemoveConst.kt @@ -0,0 +1,49 @@ +// MODULE: lib +// FILE: A.kt +// VERSION: 1 + +val bar: String + get() = "a val with a getter" + +const val qux: String = "a const val" + +object X { + val zem: String + get() = "a member val with a getter" + + const val spi: String = "a member const val" +} + +// FILE: B.kt +// VERSION: 2 + +const val bar: String = "a val turned into a const" + +val qux: String + get() = "a const turned into a val with a getter" + +object X { + val zem: String + get() = "a member val turned into a const" + + const val spi: String = "a member const turned into a val with a getter" +} + +// MODULE: mainLib(lib) +// FILE: mainLib.kt + +fun lib(): String { + return when { + bar != "a val turned into a const" -> "fail 1" + qux != "a const turned into a val with a getter" -> "fail 2" + X.zem != "a member val turned into a const" -> "fail 1" + X.spi != "a member const turned into a val with a getter" -> "fail 2" + + else -> "OK" + } +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/addOrRemoveInitBlock.kt b/compiler/testData/binaryCompatibility/klibEvolution/addOrRemoveInitBlock.kt new file mode 100644 index 00000000000..12f75f0ac7c --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/addOrRemoveInitBlock.kt @@ -0,0 +1,49 @@ +// MODULE: lib +// FILE: A.kt +// VERSION: 1 + +class X { + var x = 17 + init { + x = 19 + } + init { + x = 23 + } + init { + x = 29 + } + var y = 31 +} + +// FILE: B.kt +// VERSION: 2 + +class X { + init { + // Empty + } + var x = 17 + var y = 31 + init { + x = 37 + y = 41 + } +} + +// MODULE: mainLib(lib) +// FILE: mainLib.kt + +fun lib(): String { + val x = X() + return when { + x.x != 37 -> "fail 1" + x.y != 41 -> "fail 2" + else -> "OK" + } +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/addOverloads.kt b/compiler/testData/binaryCompatibility/klibEvolution/addOverloads.kt new file mode 100644 index 00000000000..629d0e858ed --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/addOverloads.kt @@ -0,0 +1,62 @@ +// MODULE: lib +// FILE: A.kt +// VERSION: 1 + +class X { + fun foo(s: String): String = "initial overload $s" + fun bar(s: String?): String = "initial nullable overload $s" + fun qux(s: Any): String = "initial any overload $s" +} + +fun foo(s: String): String = "initial overload $s" +fun bar(s: String?): String = "initial nullable overload $s" +fun qux(s: Any): String = "initial any overload $s" + +// FILE: B.kt +// VERSION: 2 + +class X { + fun foo(): String = "no arg overload" + fun foo(s: String): String = "initial overload $s" + fun foo(s: String?): String = "nullable overload $s" + fun foo(s: String, p: String): String = "more args overload $s" + + fun bar(s: String?): String = "initial overload $s" + fun bar(s: String): String = "non-nullable overload $s" + + fun qux(s: Any): String = "initial any overload $s" + fun qux(s: String): String = "initial narrower overload $s" +} + +fun foo(): String = "no arg overload" +fun foo(s: String): String = "initial overload $s" +fun foo(s: String?): String = "nullable overload $s" +fun foo(s: String, p: String): String = "more args overload $s" + +fun bar(s: String?): String = "initial overload $s" +fun bar(s: String): String = "non-nullable overload $s" + +fun qux(s: Any): String = "initial any overload $s" +fun qux(s: String): String = "initial narrower overload $s" + +// MODULE: mainLib(lib) +// FILE: mainLib.kt + +val x = X() + +fun lib(): String = when { + x.foo("first") != "initial overload first" -> "fail 1" + x.bar("second") != "initial overload second" -> "fail 2" + x.qux("third") != "initial any overload third" -> "fail 3" + + foo("first") != "initial overload first" -> "fail 4" + bar("second") != "initial overload second" -> "fail 5" + qux("third") != "initial any overload third" -> "fail 6" + + else -> "OK" +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/addParameterDefaulValue.kt b/compiler/testData/binaryCompatibility/klibEvolution/addParameterDefaulValue.kt new file mode 100644 index 00000000000..ae23ff41196 --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/addParameterDefaulValue.kt @@ -0,0 +1,32 @@ +// MODULE: lib +// FILE: A.kt +// VERSION: 1 + +fun foo(param: String) = "foo before change $param" + +class X(val constructorParam: String) { + fun bar(param: String) = "bar before change $param and $constructorParam" +} + +// FILE: A.kt +// VERSION: 2 + +fun foo(param: String = "none") = "foo after change $param" + +class X(val constructorParam: String = "none") { + fun bar(param: String = "none") = "bar after change $param and $constructorParam" +} + + +// MODULE: mainLib(lib) +// FILE: mainLib.kt +fun lib(): String = when { + foo("global") != "foo after change global" -> "fail 1" + X("constructor").bar("member") != "bar after change member and constructor" -> "fail 2" + else -> "OK" +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/addProeprtyAccessor.kt b/compiler/testData/binaryCompatibility/klibEvolution/addProeprtyAccessor.kt new file mode 100644 index 00000000000..48a9f413379 --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/addProeprtyAccessor.kt @@ -0,0 +1,67 @@ +// MODULE: lib +// FILE: A.kt +// VERSION: 1 + +val bar = "original global value" +var muc = "original global value" +var toc = "original global value" + +class X() { + val qux = "original member value" + var nis = "original member value" + var roo = "original member value" +} + +// FILE: B.kt +// VERSION: 2 + +val bar + get() = "changed global value of val" +var muc = "initialized global value of var with field" + get() = field + set(value) { + field = "changed global value of var with field" + } +var toc + get() = "changed global value of var without field" + set(value) { } + + +class X() { + val qux + get() = "changed member value of val" + var nis = "initialized member value of var with field" + get() = field + set(value) { + field = "changed member value of var with field" + } + var roo = "initialized member value of var without field" + get() = "changed member value of var without field" +} + +// MODULE: mainLib(lib) +// FILE: mainLib.kt +fun lib(): String { + val x = X() + muc = "first" + toc = "second" + x.nis = "third" + x.roo = "fourth" + + return when { + bar != "changed global value of val" -> "fail 1" + muc != "changed global value of var with field" -> "fail 2" + toc != "changed global value of var without field" -> "fail 3" + + x.qux != "changed member value of val" -> "fail 4" + x.nis != "changed member value of var with field" -> "fail 5" + x.roo != "changed member value of var without field" -> "fail 5" + + else -> "OK" + } +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/addingSealedClassMember.kt b/compiler/testData/binaryCompatibility/klibEvolution/addingSealedClassMember.kt new file mode 100644 index 00000000000..cb8d3487389 --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/addingSealedClassMember.kt @@ -0,0 +1,47 @@ +// MODULE: lib +// FILE: A.kt +// VERSION: 1 + +sealed class X(val name: String ="X") + +class Y: X("Y") + +class Z: X("Z") + +fun last(): X = Z() + +// FILE: B.kt +// VERSION: 2 + +sealed class X(val name: String ="X") + +class Y: X("Y") + +class Z: X("Z") + +class W: X("W") + +fun last(): X = W() + +// MODULE: mainLib(lib) +// FILE: mainLib.kt + +fun lib(): String { + val x = last() + return when(x) { + is Y -> "fail 1" + is Z -> "fail 2" + + else -> { + if (x.name == "W") + "OK" + else + "fail 3" + } + } +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/changeBaseClassOrder.kt b/compiler/testData/binaryCompatibility/klibEvolution/changeBaseClassOrder.kt new file mode 100644 index 00000000000..5ad4e53e2e1 --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/changeBaseClassOrder.kt @@ -0,0 +1,63 @@ +// MODULE: base +// FILE: base.kt + +open class X { + open val bar: String + get() = "base class open" + val zon: String + get() = "base class" +} + +interface Y { + val qux: String + get() = "base interface Y" +} + +interface Z { + val sep: String + get() = "base interface Z" +} + +// MODULE: lib(base) +// FILE: A.kt +// VERSION: 1 + +class W : Y, Z, X() { + override val bar: String + get() = "from base class" + override val qux: String + get() = "from interface Y" + override val sep: String + get() = "from interface Z" +} + +// FILE: B.kt +// VERSION: 2 + +class W : X(), Z, Y { + override val bar: String + get() = "from base class" + override val qux: String + get() = "from interface Y" + override val sep: String + get() = "from interface Z" +} + +// MODULE: mainLib(lib) +// FILE: mainLib.kt + +fun lib(): String { + val w = W() + return when { + w.bar != "from base class" -> "fail 1" + w.zon != "base class" -> "fail 2" + w.qux != "from interface Y" -> "fail 3" + w.sep != "from interface Z" -> "fail 4" + else -> "OK" + } +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/changeCompanionToNestedObject.kt b/compiler/testData/binaryCompatibility/klibEvolution/changeCompanionToNestedObject.kt new file mode 100644 index 00000000000..d7016fe2536 --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/changeCompanionToNestedObject.kt @@ -0,0 +1,47 @@ +// MODULE: lib +// FILE: A.kt +// VERSION: 1 + +open class N { + fun bar() = "something in N" +} + +class X { + fun foo() = "with companion" + + companion object : N() { + val qux = "this is in companion object" + } +} + +// FILE: B.kt +// VERSION: 2 + +open class N { + fun bar() = "something in N" +} + +class X { + fun foo() = "without companion" + + object Companion : N() { + val qux = "this is in object" + } + +} + +// MODULE: mainLib(lib) +// FILE: mainLib.kt + +fun lib(): String = when { + X.qux != "this is in object" -> "fail 1" + X.bar() != "something in N" -> "fail 2" + X().foo() != "without companion" -> "fail 3" + + else -> "OK" +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/changeConstInitialization.kt b/compiler/testData/binaryCompatibility/klibEvolution/changeConstInitialization.kt new file mode 100644 index 00000000000..6db0e1a5f3b --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/changeConstInitialization.kt @@ -0,0 +1,55 @@ +// MODULE: lib +// FILE: A.kt +// VERSION: 1 + +const val bar = 17 +const val muc = "first" + +object X { + const val tis = "second" + const val roo = 19 +} + +class Y { + companion object { + const val zeb = 23 + const val loo = "third" + } +} + +// FILE: B.kt +// VERSION: 2 + +const val bar = 31 +const val muc = "fourth" + +object X { + const val tis = "fifth" + const val roo = 37 +} + +class Y { + companion object { + const val zeb = 41 + const val loo = "sixth" + } +} + + +// MODULE: mainLib(lib) +// FILE: mainLib.kt +fun lib(): String = when { + bar != 31 -> "fail 1" + muc != "fourth" -> "fail 2" + X.tis != "fifth" -> "fail 3" + X.roo != 37 -> "fail 4" + Y.zeb != 41 -> "fail 5" + Y.loo != "sixth" -> "fail 6" + + else -> "OK" +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/changeNamesOfTypeParameters.kt b/compiler/testData/binaryCompatibility/klibEvolution/changeNamesOfTypeParameters.kt new file mode 100644 index 00000000000..03d84ae0b67 --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/changeNamesOfTypeParameters.kt @@ -0,0 +1,59 @@ +// MODULE: lib +// FILE: A.kt +// VERSION: 1 + +interface B { + var few: T +} + +class A(z: Z, w: W): B { + var bar: Z = z + override var few: W = w + fun foo(x: X): Y { + return x as Y + } +} + +fun qux(u: U): V { + return u as V +} + +// FILE: B.kt +// VERSION: 2 + +interface B { + var few: T1 +} + +class A(z: Z1, w: W1): B { + var bar: Z1 = z + override var few: W1 = w + fun foo(x: X1): Y1 { + return x as Y1 + } +} + +fun qux(u: U1): V1 { + return u as V1 +} + +// MODULE: mainLib(lib) +// FILE: mainLib.kt + +fun lib(): String { + val a = A(19, 17) + + return when { + a.foo("first") != "first" -> "fail 1" + a.bar != 19 -> "fail 2" + a.few != 17 -> "fail 3" + qux("second") != "second" -> "fail 4" + + else -> "OK" + } +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/changeObjectToCompanion.kt b/compiler/testData/binaryCompatibility/klibEvolution/changeObjectToCompanion.kt new file mode 100644 index 00000000000..33194b6507d --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/changeObjectToCompanion.kt @@ -0,0 +1,47 @@ +// MODULE: lib +// FILE: A.kt +// VERSION: 1 + +open class N { + fun bar() = "something in N" +} + +class X { + fun foo() = "without companion" + + object W : N() { + val qux = "this is in object" + } + +} + +// FILE: B.kt +// VERSION: 2 + +open class N { + fun bar() = "something in N" +} + +class X { + fun foo() = "with companion" + + companion object W : N() { + val qux = "this is in companion object" + } +} + +// MODULE: mainLib(lib) +// FILE: mainLib.kt + +fun lib(): String = when { + X.W.qux != "this is in companion object" -> "fail 1" + X.W.bar() != "something in N" -> "fail 2" + X().foo() != "with companion" -> "fail 3" + + else -> "OK" +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/changeParameterDefaultValue.kt b/compiler/testData/binaryCompatibility/klibEvolution/changeParameterDefaultValue.kt new file mode 100644 index 00000000000..c5d412f1964 --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/changeParameterDefaultValue.kt @@ -0,0 +1,33 @@ +// MODULE: lib +// FILE: A.kt +// VERSION: 1 + +fun foo(param: String = "global") = "foo before change $param" + +class X(val constructorParam: String = "constructor") { + fun bar(param: String = "member") = "bar before change $param and $constructorParam" +} + +// FILE: B.kt +// VERSION: 2 + +fun foo(param: String = "in file") = "foo after change $param" + +class X(val constructorParam: String = "in constructor") { + fun bar(param: String = "in class") = "bar after change $param and $constructorParam" +} + +// MODULE: mainLib(lib) +// FILE: mainLib.kt +fun lib(): String = when { + foo("in global") != "foo after change in global" -> "fail 1" + X("in constructor").bar("in member") != "bar after change in member and in constructor" -> "fail 2" + foo() != "foo after change in file" -> "fail 3" + X().bar() != "bar after change in class and in constructor" -> "fail 4" + else -> "OK" +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/changePropertyFromValToVar.kt b/compiler/testData/binaryCompatibility/klibEvolution/changePropertyFromValToVar.kt new file mode 100644 index 00000000000..d579329e207 --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/changePropertyFromValToVar.kt @@ -0,0 +1,48 @@ +// MODULE: lib +// FILE: A.kt +// VERSION: 1 + +val bar = "global val initialization value" + +class X { + val qux = "member val initialization value" +} + +fun foo(x: X) { + // DO NOTHING +} + +// FILE: B.kt +// VERSION: 2 + +var bar = "global var initialization value" + +class X { + var qux = "member var initialization value" +} + +fun foo(x: X) { + bar = "changed global value" + x.qux = "changed member value" + +} + + +// MODULE: mainLib(lib) +// FILE: mainLib.kt +fun lib(): String { + val x = X() + foo(x) + + return when { + bar != "changed global value" -> "fail 1" + x.qux != "changed member value" -> "fail 2" + + else -> "OK" + } +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/changePropertyInitialization.kt b/compiler/testData/binaryCompatibility/klibEvolution/changePropertyInitialization.kt new file mode 100644 index 00000000000..97cbc35fea3 --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/changePropertyInitialization.kt @@ -0,0 +1,56 @@ +// MODULE: lib +// FILE: A.kt +// VERSION: 1 + +val bar = 17 +var muc = "first" +var toc = "second" + get() = field + + +class X() { + val bar = "third" + var muc = 19 + var toc = "fourth" + get() = field +} + +// FILE: B.kt +// VERSION: 2 + +val bar = 23 +var muc = "fifth" +var toc = "sixth" + get() = field + + +class X() { + val bar = "seventh" + var muc = 29 + var toc = "eighth" + get() = field +} + + +// MODULE: mainLib(lib) +// FILE: mainLib.kt +fun lib(): String { + val x = X() + + return when { + bar != 23 -> "fail 1" + muc != "fifth" -> "fail 2" + toc != "sixth" -> "fail 3" + + x.bar != "seventh" -> "fail 4" + x.muc != 29 -> "fail 5" + x.toc != "eighth" -> "fail 6" + + else -> "OK" + } +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/constructorParameterMarkValVar.kt b/compiler/testData/binaryCompatibility/klibEvolution/constructorParameterMarkValVar.kt new file mode 100644 index 00000000000..49f502d69db --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/constructorParameterMarkValVar.kt @@ -0,0 +1,46 @@ +// MODULE: lib +// FILE: A.kt +// VERSION: 1 + +open class X(x: String, y: String, open val z: String) { + val w = x+y +} + +// FILE: B.kt +// VERSION: 2 + +open class X(val x: String, var y: String, open var z: String) { + val w = x+y +} + +// MODULE: mainLib(lib) +// FILE: mainLib.kt + +val x = X("first", "second", "third") + +class Y(a: String, b: String, c: String): X(a, b, c) { + val x: String = "fourth" + val y: String = "fifth" + override val z: String = "sixth" + val superz: String = super.z +} + +val y = Y("seventh", "eighth", "ninth") + +fun lib(): String { + return when { + x.w != "firstsecond" -> "fail 1" + x.z != "third" -> "fail 2" + y.x != "fourth" -> "fail 3" + y.y != "fifth" -> "fail 4" + y.z != "sixth" -> "fail 5" + y.superz != "ninth" -> "fail 6" + + else -> "OK" + } +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/deleteOverrideMember.kt b/compiler/testData/binaryCompatibility/klibEvolution/deleteOverrideMember.kt new file mode 100644 index 00000000000..40083d096c8 --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/deleteOverrideMember.kt @@ -0,0 +1,48 @@ +// MODULE: base +// FILE: base.kt + +open class X { + open fun foo() = "base function" + open val bar = "base property" +} + +// MODULE: lib(base) +// FILE: A.kt +// VERSION: 1 + +open class Y: X() { + override fun foo() = "overridden function" + override val bar = "overridden property" +} + +// FILE: B.kt +// VERSION: 2 + +open class Y: X() + +// MODULE: mainLib(lib) +// FILE: mainLib.kt + +class Z: Y() { + override fun foo() = "primordial overridden function" + override val bar = "primordial overridden property" +} + +fun lib(): String { + val y = Y() + val z = Z() + return when { + y.foo() != "base function" -> "fail 1" + y.bar != "base property" -> "fail 2" + + z.foo() != "primordial overridden function" -> "fail 5" + z.bar != "primordial overridden property" -> "fail 6" + + else -> "OK" + } +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/deletePrivateMembers.kt b/compiler/testData/binaryCompatibility/klibEvolution/deletePrivateMembers.kt new file mode 100644 index 00000000000..e6c0ff31135 --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/deletePrivateMembers.kt @@ -0,0 +1,37 @@ +// MODULE: lib +// FILE: A.kt +// VERSION: 1 + +open class X { + private fun foo() = "private fun in superclass" + private val bar = "private val in superclass" + private class Z { + fun qux() = "fun in a provate inner class in superclass" + } + + fun bar() = "${foo()} $bar ${Z()}" +} + +// FILE: B.kt +// VERSION: 2 + +open class X { + fun bar() = "no private references after change" +} + +// MODULE: mainLib(lib) +// FILE: mainLib.kt + +class Y: X() + +fun lib(): String = when { + X().bar() != "no private references after change" -> "fail 1" + Y().bar() != "no private references after change" -> "fail 2" + + else -> "OK" +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/inlineBodyChange.kt b/compiler/testData/binaryCompatibility/klibEvolution/inlineBodyChange.kt new file mode 100644 index 00000000000..b914605ab9b --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/inlineBodyChange.kt @@ -0,0 +1,32 @@ +// MODULE: lib +// FILE: A.kt +// VERSION: 1 + +inline fun foo() = "foo before change" + +class X { + inline fun bar() = "bar before change" +} + +// FILE: A.kt +// VERSION: 2 + +inline fun foo() = "foo after change" + +class X { + inline fun bar() = "bar after change" +} + + +// MODULE: mainLib(lib) +// FILE: mainLib.kt +fun lib(): String = when { + foo() != "foo after change" -> "fail 1" + X().bar() != "bar after change" -> "fail 2" + else -> "OK" +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/inlineFunction.kt b/compiler/testData/binaryCompatibility/klibEvolution/inlineFunction.kt new file mode 100644 index 00000000000..de2540efe33 --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/inlineFunction.kt @@ -0,0 +1,31 @@ +// MODULE: lib +// FILE: A.kt +// VERSION: 1 + +fun foo() = "global" + +class X { + fun foo() = "member" +} + +// FILE: A.kt +// VERSION: 2 + +inline fun foo() = "inline global" + +class X { + inline fun foo() = "inline member" +} + +// MODULE: mainLib(lib) +// FILE: mainLib.kt +fun lib(): String = when { + foo() != "inline global" -> "fail 1" + X().foo() != "inline member" -> "fail 2" + else -> "OK" +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/makeFunctionInfixOrTailrec.kt b/compiler/testData/binaryCompatibility/klibEvolution/makeFunctionInfixOrTailrec.kt new file mode 100644 index 00000000000..f9630cb0517 --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/makeFunctionInfixOrTailrec.kt @@ -0,0 +1,38 @@ +// MODULE: lib +// FILE: A.kt +// VERSION: 1 + +fun X.foo(param: String) = "foo before change $param" +fun bar(param: String) = "bar before change $param" + +class X() { + fun qux(param: String) = "qux before change $param" + fun muc(param: String) = "muc before change $param" +} + +// FILE: B.kt +// VERSION: 2 + +infix fun X.foo(param: String) = "foo after change to infix $param" +tailrec fun bar(param: String) = "bar after change to tailrec $param" + +class X() { + infix fun qux(param: String) = "qux after change to infix $param" + tailrec fun muc(param: String) = "muc after change to tailrec $param" +} + + +// MODULE: mainLib(lib) +// FILE: mainLib.kt +fun lib(): String = when { + X().foo("yes") != "foo after change to infix yes" -> "fail 1" + bar("indeed") != "bar after change to tailrec indeed" -> "fail 2" + X().qux("naturally") != "qux after change to infix naturally" -> "fail 3" + X().muc("of course") != "muc after change to tailrec of course" -> "fail 4" + else -> "OK" +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/moreSpecificBaseClass.kt b/compiler/testData/binaryCompatibility/klibEvolution/moreSpecificBaseClass.kt new file mode 100644 index 00000000000..e98b2f78581 --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/moreSpecificBaseClass.kt @@ -0,0 +1,36 @@ +// MODULE: base +// FILE: base.kt + +open class X { + open val bar: String = "base class" +} + +open class Y: X() { + override val bar: String = "child class" +} + +// MODULE: lib(base) +// FILE: A.kt +// VERSION: 1 + +class Z : X() + +// FILE: B.kt +// VERSION: 2 + +class Z : Y() + +// MODULE: mainLib(lib) +// FILE: mainLib.kt + +fun lib(): String { + return when { + Z().bar != "child class" -> "fail 1" + else -> "OK" + } +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/moveMemberUpInHierarchy.kt b/compiler/testData/binaryCompatibility/klibEvolution/moveMemberUpInHierarchy.kt new file mode 100644 index 00000000000..67ca831fae7 --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/moveMemberUpInHierarchy.kt @@ -0,0 +1,80 @@ +// MODULE: base +// FILE: base1.kt +// VERSION: 1 + +open class X { +} + +// FILE: base2.kt +// VERSION: 2 + +open class X { + fun foo() = "non-open member function moved higher" + val bar = "non-open member property moved higher" + fun nux() = "non-open member function moved higher to cause conflict" + val zip = "non-open member property moved higher to cause conflict" + open fun ril() = "open member function moved higher" + open val det = "open member property moved higher" +} + + +// MODULE: lib(base) +// FILE: A.kt +// VERSION: 1 + +open class Y: X() { + fun foo() = "non-open member function" + val bar = "non-open member property" + fun nux() = "non-open member function" + val zip = "non-open member property" + open fun ril() = "open member function" + open val det = "open member property" +} + +// FILE: B.kt +// VERSION: 2 + +open class Y: X() { +} + +// MODULE: mainLib(lib) +// FILE: mainLib.kt + +// Note that frontend woulnb'y allow us to have Any->String->Int chain of overrides. + +class Z: X() { + fun nux() = "non-open member function sudden conflict" + val zip = "non-open member property sudden conflict" +} + +class W: Y() { + override fun ril() = "overridden open member function" + override val det = "overridden open member property" +} + +fun lib(): String { + val y = Y() + val z = Z() + val w = W() + return when { + y.foo() != "non-open member function moved higher" -> "fail 1" + y.bar != "non-open member property moved higher" -> "fail 2" + y.nux() != "non-open member function moved higher to cause conflict" -> "fail 3" + y.zip != "non-open member property moved higher to cause conflict" -> "fail 4" + y.ril() != "open member function moved higher" -> "fail 5" + y.det != "open member property moved higher" -> "fail 6" + + z.nux() != "non-open member function sudden conflict" -> "fail 7" + z.zip != "non-open member property sudden conflict" -> "fail 8" + + w.ril() != "overridden open member function"-> "fail 9" + w.det != "overridden open member property" -> "fail 10" + + else -> "OK" + } +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/newFakeOverride.kt.disabled b/compiler/testData/binaryCompatibility/klibEvolution/newFakeOverride.kt.disabled new file mode 100644 index 00000000000..ef0dc94f9aa --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/newFakeOverride.kt.disabled @@ -0,0 +1,54 @@ +// MODULE: base +// FILE: A.kt +// VERSION: 1 + +open class X { + val hasFoo = false +} + +// FILE: B.kt +// VERSION: 2 + +open class X { + val hasFoo = false + open fun foo(): String = "new member" +} + +// MODULE: child(base) +// FILE: C.kt + +class Y: X() + +// MODULE: lib(child) +// FILE: D.kt +// VERSION: 1 + +fun qux(): String = "no foo() exists in ${Y()}" + +// FILE: E.kt +// VERSION: 2 + +fun qux(): String = Y().foo() + +// MODULE: mainLib(lib) +// FILE: mainLib.kt + +fun qux(): String { + val y = Y() + if (y.hasFoo()) { + foo() + } else { + "no foo" + } +} + +fun lib(): String = when { + qux() != "new member" -> "fail 1" + + else -> "OK" +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/newOverrideMember.kt b/compiler/testData/binaryCompatibility/klibEvolution/newOverrideMember.kt new file mode 100644 index 00000000000..299e48ed25d --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/newOverrideMember.kt @@ -0,0 +1,48 @@ +// MODULE: base +// FILE: base.kt + +open class X { + open fun foo() = "base function" + open val bar = "base property" +} + +// MODULE: lib(base) +// FILE: A.kt +// VERSION: 1 + +open class Y: X() + +// FILE: B.kt +// VERSION: 2 + +open class Y: X() { + override fun foo() = "overridden function" + override val bar = "overridden property" +} + +// MODULE: mainLib(lib) +// FILE: mainLib.kt + +class Z: Y() { + override fun foo() = "primordial overridden function" + override val bar = "primordial overridden property" +} + +fun lib(): String { + val y = Y() + val z = Z() + return when { + y.foo() != "overridden function" -> "fail 1" + y.bar != "overridden property" -> "fail 2" + + z.foo() != "primordial overridden function" -> "fail 5" + z.bar != "primordial overridden property" -> "fail 6" + + else -> "OK" + } +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/removeAbstractFromClass.kt b/compiler/testData/binaryCompatibility/klibEvolution/removeAbstractFromClass.kt new file mode 100644 index 00000000000..fc3b6083a1f --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/removeAbstractFromClass.kt @@ -0,0 +1,33 @@ +// MODULE: lib +// FILE: A.kt +// VERSION: 1 + +abstract class X { + fun foo(): String = "in abstract class" + val bar: String = "in abstract class" +} + +// FILE: B.kt +// VERSION: 2 + +open class X { + fun foo(): String = "in non-abstract class" + val bar: String = "in non-abstract class" +} + +// MODULE: mainLib(lib) +// FILE: mainLib.kt + +class Y: X() + +fun lib(): String = when { + Y().foo() != "in non-abstract class" -> "fail 1" + Y().bar != "in non-abstract class" -> "fail 2" + + else -> "OK" +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/removeInfixOrTailrecFromFunction.kt b/compiler/testData/binaryCompatibility/klibEvolution/removeInfixOrTailrecFromFunction.kt new file mode 100644 index 00000000000..aede701f5d4 --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/removeInfixOrTailrecFromFunction.kt @@ -0,0 +1,38 @@ +// MODULE: lib +// FILE: B.kt +// VERSION: 1 + +infix fun X.foo(param: String) = "foo before change $param" +tailrec fun bar(param: String) = "bar before change $param" + +class X() { + infix fun qux(param: String) = "qux before change $param" + tailrec fun muc(param: String) = "muc before change $param" +} + +// FILE: A.kt +// VERSION: 2 + +fun X.foo(param: String) = "foo after removal of infix $param" +fun bar(param: String) = "bar after removal of tailrec $param" + +class X() { + fun qux(param: String) = "qux after removal of infix $param" + fun muc(param: String) = "muc after removal of tailrec $param" +} + + +// MODULE: mainLib(lib) +// FILE: mainLib.kt +fun lib(): String = when { + X() foo "yes" != "foo after removal of infix yes" -> "fail 1" + bar("indeed") != "bar after removal of tailrec indeed" -> "fail 2" + X() qux "naturally" != "qux after removal of infix naturally" -> "fail 3" + X().muc("of course") != "muc after removal of tailrec of course" -> "fail 4" + else -> "OK" +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/removeLateinitFromVar.kt b/compiler/testData/binaryCompatibility/klibEvolution/removeLateinitFromVar.kt new file mode 100644 index 00000000000..071fea6ba62 --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/removeLateinitFromVar.kt @@ -0,0 +1,45 @@ +// MODULE: lib +// FILE: A.kt +// VERSION: 1 + +lateinit var qux: String + +class X { + lateinit var bar: String +} + +// FILE: B.kt +// VERSION: 2 + +var qux: String = "initialized global" + +class X { + var bar: String = "initialized member" +} + +// MODULE: mainLib(lib) +// FILE: mainLib.kt + +val x = X() + +fun lib(): String { + + val a = qux + val b = x.bar + qux = "new global value" + x.bar = "new member value" + + return when { + a != "initialized global" -> "fail 1" + b != "initialized member" -> "fail 2" + qux != "new global value" -> "fail 3" + x.bar != "new member value" -> "fail 4" + + else -> "OK" + } +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/removePropertyAccessor.kt b/compiler/testData/binaryCompatibility/klibEvolution/removePropertyAccessor.kt new file mode 100644 index 00000000000..44f5e7fdd89 --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/removePropertyAccessor.kt @@ -0,0 +1,67 @@ +// MODULE: lib +// FILE: A.kt +// VERSION: 1 + +val bar + get() = "original global value of val" +var muc = "initialized global value of var with field" + get() = field + set(value) { + field = "original global value of var with field" + } +var toc + get() = "original global value of var without field" + set(value) { } + + +class X() { + val qux + get() = "original member value of val" + var nis = "initialized member value of var with field" + get() = field + set(value) { + field = "original member value of var with field" + } + var roo = "initialized member value of var without field" + get() = "original member value of var without field" +} + +// FILE: B.kt +// VERSION: 2 + +val bar = "changed global value" +var muc = "changed global value" +var toc = "changed global value" + +class X() { + val qux = "changed member value" + var nis = "changed member value" + var roo = "changed member value" +} + +// MODULE: mainLib(lib) +// FILE: mainLib.kt +fun lib(): String { + val x = X() + muc = "first" + toc = "second" + x.nis = "third" + x.roo = "fourth" + + return when { + bar != "changed global value" -> "fail 1" + muc != "first" -> "fail 2" + toc != "second" -> "fail 3" + + x.qux != "changed member value" -> "fail 4" + x.nis != "third" -> "fail 5" + x.roo != "fourth" -> "fail 6" + + else -> "OK" + } +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/renameArguments.kt b/compiler/testData/binaryCompatibility/klibEvolution/renameArguments.kt new file mode 100644 index 00000000000..5d14e19f70f --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/renameArguments.kt @@ -0,0 +1,129 @@ +// MODULE: lib +// FILE: A.kt +// VERSION: 1 + +fun foo_a(a: String) = a +fun foo_b(b: String = "foo_b default") = b +fun foo_c(vararg c: String) = c.joinToString(", ") + +fun foo_d(a: String, b: String) = a + b +fun foo_e(a: String = "foo_e default a", b: String = "foo_e default b") = a + b +fun foo_f(vararg a: String, b: String) = a.joinToString(", ") + b + +class X() { + fun bar_a(a: String) = a + fun bar_b(b: String = "foo_b default") = b + fun bar_c(vararg c: String) = c.joinToString(", ") + + fun bar_d(a: String, b: String) = a + b + fun bar_e(a: String = "foo_e default a", b: String = "foo_e default b") = a + b + fun bar_f(vararg a: String, b: String) = a.joinToString(", ") + b +} + +class qux_a(a: String) { + val x = a +} +class qux_b(b: String = "foo_b default") { + val x = b +} +class qux_c(vararg c: String) { + val x = c.joinToString(", ") +} + +// swap order +class qux_d(a: String, b: String) { + val x = a + b +} + +class qux_e(a: String = "foo_e default a", b: String = "foo_e default b") { + val x = a + b +} +class qux_f(vararg a: String, b: String) { + val x= a.joinToString(", ") + b +} + + +// FILE: B.kt +// VERSION: 2 + +fun foo_a(a1: String) = a1 +fun foo_b(b1: String = "foo_b default") = b1 +fun foo_c(vararg c1: String) = c1.joinToString(", ") + +// swap order +fun foo_d(b: String, a: String) = b + a +fun foo_e(b: String = "foo_e default a", a: String = "foo_e default b") = b + a +fun foo_f(vararg b: String, a: String) = b.joinToString(", ") + a + +class X() { + fun bar_a(a1: String) = a1 + fun bar_b(b1: String = "foo_b default") = b1 + fun bar_c(vararg c1: String) = c1.joinToString(", ") + + fun bar_d(b: String, a: String) = b + a + fun bar_e(b: String = "foo_e default a", a: String = "foo_e default b") = b + a + fun bar_f(vararg b: String, a: String) = b.joinToString(", ") + a +} + +class qux_a(a1: String) { + val x = a1 +} +class qux_b(b1: String = "foo_b default") { + val x = b1 +} +class qux_c(vararg c1: String) { + val x = c1.joinToString(", ") +} + +// swap order +class qux_d(b: String, a: String) { + val x = b + a +} + +class qux_e(b: String = "foo_e default a", a: String = "foo_e default b") { + val x = b + a +} +class qux_f(vararg b: String, a: String) { + val x= b.joinToString(", ") + a +} + +// MODULE: mainLib(lib) +// FILE: mainLib.kt +fun lib(): String { + val x = X() + return when { + foo_a("first") != "first" -> "fail 1" + foo_b() != "foo_b default" -> "fail 2" + foo_c("first", "second") != "first, second" -> "fail 3" + foo_d("first", "second") != "firstsecond" -> "fail 4" + foo_d(a = "first", b = "second") != "firstsecond" -> "fail 5" + foo_e() != "foo_e default afoo_e default b" -> "fail 6" + foo_e(a = "first", b = "second") != "firstsecond" -> "fail 7" + foo_f("second", "third", b = "first") != "second, thirdfirst" -> "fail 8" + + x.bar_a("first") != "first" -> "fail 11" + x.bar_b() != "foo_b default" -> "fail 12" + x.bar_c("first", "second") != "first, second" -> "fail 13" + x.bar_d("first", "second") != "firstsecond" -> "fail 14" + x.bar_d(a = "first", b = "second") != "firstsecond" -> "fail 15" + x.bar_e() != "foo_e default afoo_e default b" -> "fail 16" + x.bar_e(a = "first", b = "second") != "firstsecond" -> "fail 17" + x.bar_f("second", "third", b = "first") != "second, thirdfirst" -> "fail 18" + + qux_a("first").x != "first" -> "fail 21" + qux_b().x != "foo_b default" -> "fail 22" + qux_c("first", "second").x != "first, second" -> "fail 23" + qux_d("first", "second").x != "firstsecond" -> "fail 24" + qux_d(a = "first", b = "second").x != "firstsecond" -> "fail 25" + qux_e().x != "foo_e default afoo_e default b" -> "fail 26" + qux_e(a = "first", b = "second").x != "firstsecond" -> "fail 27" + qux_f("second", "third", b = "first").x != "second, thirdfirst" -> "fail 28" + + else -> "OK" + } +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/reorderClassConstructors.kt b/compiler/testData/binaryCompatibility/klibEvolution/reorderClassConstructors.kt new file mode 100644 index 00000000000..600c3fb5671 --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/reorderClassConstructors.kt @@ -0,0 +1,42 @@ +// MODULE: lib +// FILE: A.kt +// VERSION: 1 + +open class X(open val y: String) { + constructor(x: String, y: String): this(x+y) + constructor(x: String, y: String, z: String): this(x, y+z) +} + +// FILE: B.kt +// VERSION: 2 + +open class X(x: String, _y: String, z: String) { + constructor(x: String): this("fifth", x, "sixth") + constructor(y: String, z: String): this(y+z, "tenth", "eleventh") + val y = _y +} + +// MODULE: mainLib(lib) +// FILE: mainLib.kt + +open class Y: X("nineth") +open class Z: X("seventh", "eighth") +open class W: X("first", "second", "third") + +fun lib(): String { + val y = Y() + val z = Z() + val w = W() + return when { + y.y != "nineth" -> "fail 1" + z.y != "tenth" -> "fail 2" + w.y != "second" -> "fail 3" + + else -> "OK" + } +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/turnClassIntoDataClass.kt b/compiler/testData/binaryCompatibility/klibEvolution/turnClassIntoDataClass.kt new file mode 100644 index 00000000000..14aeee3e70d --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/turnClassIntoDataClass.kt @@ -0,0 +1,46 @@ +// MODULE: lib +// FILE: A.kt +// VERSION: 1 + +interface A { + fun foo(): String + val bar: String +} + +class X(val a: String, var b: String) { + fun foo(): String = "original class' method" + val bar: String = "original class' property" +} + +// FILE: B.kt +// VERSION: 2 + +interface A { + fun foo(): String + val bar: String +} + +data class X(val a: String, var b: String) { + fun foo(): String = a + b + val bar: String = b + a +} + +// MODULE: mainLib(lib) +// FILE: mainLib.kt + +fun lib(): String { + val x = X("first", "second") + return when { + x.a != "first" -> "fail 1" + x.b != "second" -> "fail 2" + x.foo() != "firstsecond" -> "fail 3" + x.bar != "secondfirst" -> "fail 4" + x.toString() != "X(a=first, b=second)" -> "fail 5" + else -> "OK" + } +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() + diff --git a/compiler/testData/binaryCompatibility/klibEvolution/widenSuperMemberVisibility.kt b/compiler/testData/binaryCompatibility/klibEvolution/widenSuperMemberVisibility.kt new file mode 100644 index 00000000000..547a2488deb --- /dev/null +++ b/compiler/testData/binaryCompatibility/klibEvolution/widenSuperMemberVisibility.kt @@ -0,0 +1,50 @@ +// MODULE: lib +// FILE: A.kt +// VERSION: 1 + +open class X { + private fun foo() = "private in super" + fun bar() = foo() + + private val zeg = "private in super" + fun lim() = zeg +} + +// FILE: B.kt +// VERSION: 2 + +open class X { + public fun foo() = "public in super" + fun bar() = foo() + + private val zeg = "public in super" + fun lim() = zeg +} + +// MODULE: mainLib(lib) +// FILE: mainLib.kt + +class Y: X() { + private fun foo() = "private in derived" + fun qux() = foo() + + private val zeg = "private in derived" + fun tes() = zeg +} + +fun lib(): String = when { + X().bar() != "public in super" -> "fail 1" + Y().bar() != "public in super" -> "fail 2" + Y().qux() != "private in derived" -> "fail 3" + + X().lim() != "public in super" -> "fail 4" + Y().lim() != "public in super" -> "fail 5" + Y().tes() != "private in derived" -> "fail 6" + + else -> "OK" +} + +// MODULE: main(mainLib) +// FILE: main.kt +fun box(): String = lib() +