Relax requirements on function modifiers in multiplatform projects
Allow to implement header functions with external/tailrec/inline/infix/operator functions
This commit is contained in:
+9
-4
@@ -178,7 +178,8 @@ class HeaderImplDeclarationChecker(val moduleToCheck: ModuleDescriptor? = null)
|
|||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
|
|
||||||
object FunctionModifiers : Incompatible("modifiers are different (external, infix, inline, operator, suspend, tailrec)")
|
object FunctionModifiersDifferent : Incompatible("modifiers are different (suspend)")
|
||||||
|
object FunctionModifiersNotSubset : Incompatible("some modifiers on header declaration are missing on the implementation (external, infix, inline, operator, tailrec)")
|
||||||
|
|
||||||
// Properties
|
// Properties
|
||||||
|
|
||||||
@@ -273,9 +274,13 @@ class HeaderImplDeclarationChecker(val moduleToCheck: ModuleDescriptor? = null)
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun areCompatibleFunctions(a: FunctionDescriptor, b: FunctionDescriptor): Compatibility {
|
private fun areCompatibleFunctions(a: FunctionDescriptor, b: FunctionDescriptor): Compatibility {
|
||||||
if (!equalBy(a, b) { f ->
|
if (!equalBy(a, b) { f -> f.isSuspend }) return Incompatible.FunctionModifiersDifferent
|
||||||
listOf(f.isExternal, f.isInfix, f.isInline, f.isOperator, f.isSuspend, f.isTailrec)
|
|
||||||
}) return Incompatible.FunctionModifiers
|
if (a.isExternal && !b.isExternal ||
|
||||||
|
a.isInfix && !b.isInfix ||
|
||||||
|
a.isInline && !b.isInline ||
|
||||||
|
a.isOperator && !b.isOperator ||
|
||||||
|
a.isTailrec && !b.isTailrec) return Incompatible.FunctionModifiersNotSubset
|
||||||
|
|
||||||
return Compatible
|
return Compatible
|
||||||
}
|
}
|
||||||
|
|||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
// !LANGUAGE: +MultiPlatformProjects
|
||||||
|
// !DIAGNOSTICS: -NOTHING_TO_INLINE
|
||||||
|
// MODULE: m1-common
|
||||||
|
// FILE: common.kt
|
||||||
|
|
||||||
|
header fun external()
|
||||||
|
header fun tailrec()
|
||||||
|
header fun inline()
|
||||||
|
header fun String.unaryMinus(): String
|
||||||
|
header fun String.and(other: String): String
|
||||||
|
|
||||||
|
// MODULE: m2-jvm(m1-common)
|
||||||
|
// FILE: jvm.kt
|
||||||
|
|
||||||
|
impl external fun external()
|
||||||
|
impl tailrec fun tailrec(): Unit = if (true) Unit else tailrec()
|
||||||
|
impl inline fun inline() {}
|
||||||
|
impl operator fun String.unaryMinus(): String = this
|
||||||
|
impl infix fun String.and(other: String): String = this + other
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
// -- Module: <m1-common> --
|
||||||
|
package
|
||||||
|
|
||||||
|
public header fun external(): kotlin.Unit
|
||||||
|
public header fun inline(): kotlin.Unit
|
||||||
|
public header fun tailrec(): kotlin.Unit
|
||||||
|
public header fun kotlin.String.and(/*0*/ other: kotlin.String): kotlin.String
|
||||||
|
public header fun kotlin.String.unaryMinus(): kotlin.String
|
||||||
|
|
||||||
|
|
||||||
|
// -- Module: <m2-jvm> --
|
||||||
|
package
|
||||||
|
|
||||||
|
public external impl fun external(): kotlin.Unit
|
||||||
|
public inline impl fun inline(): kotlin.Unit
|
||||||
|
public tailrec impl fun tailrec(): kotlin.Unit
|
||||||
|
public infix impl fun kotlin.String.and(/*0*/ other: kotlin.String): kotlin.String
|
||||||
|
public operator impl fun kotlin.String.unaryMinus(): kotlin.String
|
||||||
@@ -15,4 +15,4 @@ impl fun nonInlineFun() { }
|
|||||||
// FILE: js.kt
|
// FILE: js.kt
|
||||||
|
|
||||||
impl <!NOTHING_TO_INLINE!>inline<!> fun inlineFun() { }
|
impl <!NOTHING_TO_INLINE!>inline<!> fun inlineFun() { }
|
||||||
<!IMPLEMENTATION_WITHOUT_HEADER!>impl<!> <!NOTHING_TO_INLINE!>inline<!> fun nonInlineFun() { }
|
impl <!NOTHING_TO_INLINE!>inline<!> fun nonInlineFun() { }
|
||||||
|
|||||||
@@ -1,14 +1,9 @@
|
|||||||
header infix fun Int.plus(s: CharSequence): Int
|
header infix fun Int.plus(s: CharSequence): Int
|
||||||
header fun Int.minus(s: String): Int
|
|
||||||
|
|
||||||
header operator fun Double.times(x: CharArray)
|
header operator fun Double.times(x: CharArray)
|
||||||
header fun Double.divide(x: ByteArray)
|
|
||||||
|
|
||||||
header external fun f1()
|
header external fun f1()
|
||||||
header fun g1()
|
|
||||||
|
|
||||||
header inline fun f2()
|
header inline fun f2()
|
||||||
header fun g2()
|
|
||||||
|
|
||||||
header tailrec fun f3()
|
header tailrec fun f3()
|
||||||
header fun g3()
|
|
||||||
|
|||||||
@@ -1,14 +1,9 @@
|
|||||||
impl fun Int.plus(s: CharSequence): Int = 0
|
impl fun Int.plus(s: CharSequence): Int = 0
|
||||||
impl infix fun Int.minus(s: String): Int = 1
|
|
||||||
|
|
||||||
impl fun Double.times(x: CharArray) {}
|
impl fun Double.times(x: CharArray) {}
|
||||||
impl operator fun Double.divide(x: ByteArray) {}
|
|
||||||
|
|
||||||
impl fun f1() {}
|
impl fun f1() {}
|
||||||
impl external fun g1()
|
|
||||||
|
|
||||||
impl fun f2() {}
|
impl fun f2() {}
|
||||||
impl inline fun g2() {}
|
|
||||||
|
|
||||||
impl fun f3() {}
|
impl fun f3() {}
|
||||||
impl tailrec fun g3() {}
|
|
||||||
|
|||||||
@@ -6,96 +6,48 @@ Output:
|
|||||||
Exit code: COMPILATION_ERROR
|
Exit code: COMPILATION_ERROR
|
||||||
Output:
|
Output:
|
||||||
compiler/testData/multiplatform/incompatibleFunctions/common.kt:1:1: error: header declaration 'plus' has no implementation in module
|
compiler/testData/multiplatform/incompatibleFunctions/common.kt:1:1: error: header declaration 'plus' has no implementation in module
|
||||||
The following declaration is incompatible because modifiers are different (external, infix, inline, operator, suspend, tailrec):
|
The following declaration is incompatible because some modifiers on header declaration are missing on the implementation (external, infix, inline, operator, tailrec):
|
||||||
public impl fun Int.plus(s: CharSequence): Int
|
public impl fun Int.plus(s: CharSequence): Int
|
||||||
|
|
||||||
header infix fun Int.plus(s: CharSequence): Int
|
header infix fun Int.plus(s: CharSequence): Int
|
||||||
^
|
^
|
||||||
compiler/testData/multiplatform/incompatibleFunctions/common.kt:2:1: error: header declaration 'minus' has no implementation in module
|
compiler/testData/multiplatform/incompatibleFunctions/common.kt:3:1: error: header declaration 'times' has no implementation in module
|
||||||
The following declaration is incompatible because modifiers are different (external, infix, inline, operator, suspend, tailrec):
|
The following declaration is incompatible because some modifiers on header declaration are missing on the implementation (external, infix, inline, operator, tailrec):
|
||||||
public infix impl fun Int.minus(s: String): Int
|
|
||||||
|
|
||||||
header fun Int.minus(s: String): Int
|
|
||||||
^
|
|
||||||
compiler/testData/multiplatform/incompatibleFunctions/common.kt:4:1: error: header declaration 'times' has no implementation in module
|
|
||||||
The following declaration is incompatible because modifiers are different (external, infix, inline, operator, suspend, tailrec):
|
|
||||||
public impl fun Double.times(x: CharArray): Unit
|
public impl fun Double.times(x: CharArray): Unit
|
||||||
|
|
||||||
header operator fun Double.times(x: CharArray)
|
header operator fun Double.times(x: CharArray)
|
||||||
^
|
^
|
||||||
compiler/testData/multiplatform/incompatibleFunctions/common.kt:5:1: error: header declaration 'divide' has no implementation in module
|
compiler/testData/multiplatform/incompatibleFunctions/common.kt:5:1: error: header declaration 'f1' has no implementation in module
|
||||||
The following declaration is incompatible because modifiers are different (external, infix, inline, operator, suspend, tailrec):
|
The following declaration is incompatible because some modifiers on header declaration are missing on the implementation (external, infix, inline, operator, tailrec):
|
||||||
public operator impl fun Double.divide(x: ByteArray): Unit
|
|
||||||
|
|
||||||
header fun Double.divide(x: ByteArray)
|
|
||||||
^
|
|
||||||
compiler/testData/multiplatform/incompatibleFunctions/common.kt:7:1: error: header declaration 'f1' has no implementation in module
|
|
||||||
The following declaration is incompatible because modifiers are different (external, infix, inline, operator, suspend, tailrec):
|
|
||||||
public impl fun f1(): Unit
|
public impl fun f1(): Unit
|
||||||
|
|
||||||
header external fun f1()
|
header external fun f1()
|
||||||
^
|
^
|
||||||
compiler/testData/multiplatform/incompatibleFunctions/common.kt:8:1: error: header declaration 'g1' has no implementation in module
|
compiler/testData/multiplatform/incompatibleFunctions/common.kt:7:1: error: header declaration 'f2' has no implementation in module
|
||||||
The following declaration is incompatible because modifiers are different (external, infix, inline, operator, suspend, tailrec):
|
The following declaration is incompatible because some modifiers on header declaration are missing on the implementation (external, infix, inline, operator, tailrec):
|
||||||
public external impl fun g1(): Unit
|
|
||||||
|
|
||||||
header fun g1()
|
|
||||||
^
|
|
||||||
compiler/testData/multiplatform/incompatibleFunctions/common.kt:10:1: error: header declaration 'f2' has no implementation in module
|
|
||||||
The following declaration is incompatible because modifiers are different (external, infix, inline, operator, suspend, tailrec):
|
|
||||||
public impl fun f2(): Unit
|
public impl fun f2(): Unit
|
||||||
|
|
||||||
header inline fun f2()
|
header inline fun f2()
|
||||||
^
|
^
|
||||||
compiler/testData/multiplatform/incompatibleFunctions/common.kt:11:1: error: header declaration 'g2' has no implementation in module
|
compiler/testData/multiplatform/incompatibleFunctions/common.kt:9:1: error: header declaration 'f3' has no implementation in module
|
||||||
The following declaration is incompatible because modifiers are different (external, infix, inline, operator, suspend, tailrec):
|
The following declaration is incompatible because some modifiers on header declaration are missing on the implementation (external, infix, inline, operator, tailrec):
|
||||||
public inline impl fun g2(): Unit
|
|
||||||
|
|
||||||
header fun g2()
|
|
||||||
^
|
|
||||||
compiler/testData/multiplatform/incompatibleFunctions/common.kt:13:1: error: header declaration 'f3' has no implementation in module
|
|
||||||
The following declaration is incompatible because modifiers are different (external, infix, inline, operator, suspend, tailrec):
|
|
||||||
public impl fun f3(): Unit
|
public impl fun f3(): Unit
|
||||||
|
|
||||||
header tailrec fun f3()
|
header tailrec fun f3()
|
||||||
^
|
^
|
||||||
compiler/testData/multiplatform/incompatibleFunctions/common.kt:14:1: error: header declaration 'g3' has no implementation in module
|
|
||||||
The following declaration is incompatible because modifiers are different (external, infix, inline, operator, suspend, tailrec):
|
|
||||||
public tailrec impl fun g3(): Unit
|
|
||||||
|
|
||||||
header fun g3()
|
|
||||||
^
|
|
||||||
compiler/testData/multiplatform/incompatibleFunctions/jvm.kt:1:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code
|
compiler/testData/multiplatform/incompatibleFunctions/jvm.kt:1:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code
|
||||||
impl fun Int.plus(s: CharSequence): Int = 0
|
impl fun Int.plus(s: CharSequence): Int = 0
|
||||||
^
|
^
|
||||||
compiler/testData/multiplatform/incompatibleFunctions/jvm.kt:2:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code
|
compiler/testData/multiplatform/incompatibleFunctions/jvm.kt:3:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code
|
||||||
impl infix fun Int.minus(s: String): Int = 1
|
|
||||||
^
|
|
||||||
compiler/testData/multiplatform/incompatibleFunctions/jvm.kt:4:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code
|
|
||||||
impl fun Double.times(x: CharArray) {}
|
impl fun Double.times(x: CharArray) {}
|
||||||
^
|
^
|
||||||
compiler/testData/multiplatform/incompatibleFunctions/jvm.kt:5:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code
|
compiler/testData/multiplatform/incompatibleFunctions/jvm.kt:5:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code
|
||||||
impl operator fun Double.divide(x: ByteArray) {}
|
|
||||||
^
|
|
||||||
compiler/testData/multiplatform/incompatibleFunctions/jvm.kt:5:6: error: 'operator' modifier is inapplicable on this function: illegal function name
|
|
||||||
impl operator fun Double.divide(x: ByteArray) {}
|
|
||||||
^
|
|
||||||
compiler/testData/multiplatform/incompatibleFunctions/jvm.kt:7:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code
|
|
||||||
impl fun f1() {}
|
impl fun f1() {}
|
||||||
^
|
^
|
||||||
compiler/testData/multiplatform/incompatibleFunctions/jvm.kt:8:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code
|
compiler/testData/multiplatform/incompatibleFunctions/jvm.kt:7:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code
|
||||||
impl external fun g1()
|
|
||||||
^
|
|
||||||
compiler/testData/multiplatform/incompatibleFunctions/jvm.kt:10:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code
|
|
||||||
impl fun f2() {}
|
impl fun f2() {}
|
||||||
^
|
^
|
||||||
compiler/testData/multiplatform/incompatibleFunctions/jvm.kt:11:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code
|
compiler/testData/multiplatform/incompatibleFunctions/jvm.kt:9:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code
|
||||||
impl inline fun g2() {}
|
|
||||||
^
|
|
||||||
compiler/testData/multiplatform/incompatibleFunctions/jvm.kt:13:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code
|
|
||||||
impl fun f3() {}
|
impl fun f3() {}
|
||||||
^
|
^
|
||||||
compiler/testData/multiplatform/incompatibleFunctions/jvm.kt:14:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code
|
|
||||||
impl tailrec fun g3() {}
|
|
||||||
^
|
|
||||||
|
|
||||||
|
|||||||
@@ -13149,6 +13149,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("functionModifiers.kt")
|
||||||
|
public void testFunctionModifiers() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/topLevelFun/functionModifiers.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("headerAndImplInDIfferentPackages.kt")
|
@TestMetadata("headerAndImplInDIfferentPackages.kt")
|
||||||
public void testHeaderAndImplInDIfferentPackages() throws Exception {
|
public void testHeaderAndImplInDIfferentPackages() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/topLevelFun/headerAndImplInDIfferentPackages.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/topLevelFun/headerAndImplInDIfferentPackages.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user