Allow Result return type and nullability operators on Result type
by default
This commit is contained in:
+1
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.types.expressions.ControlStructureTypingUtils
|
||||
class ResultTypeWithNullableOperatorsChecker : CallChecker {
|
||||
override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) {
|
||||
if (context.languageVersionSettings.supportsFeature(LanguageFeature.AllowNullOperatorsForResult)) return
|
||||
if (context.languageVersionSettings.supportsFeature(LanguageFeature.AllowNullOperatorsForResultAndResultReturnTypeByDefault)) return
|
||||
|
||||
val name = resolvedCall.resultingDescriptor.name
|
||||
val operationNode = resolvedCall.call.callOperationNode
|
||||
|
||||
+6
-3
@@ -19,13 +19,16 @@ import org.jetbrains.kotlin.types.KotlinType
|
||||
class ResultClassInReturnTypeChecker : DeclarationChecker {
|
||||
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||
val languageVersionSettings = context.languageVersionSettings
|
||||
if (
|
||||
languageVersionSettings.getFlag(AnalysisFlags.allowResultReturnType) ||
|
||||
(languageVersionSettings.getFeatureSupport(LanguageFeature.InlineClasses) == LanguageFeature.State.ENABLED ||
|
||||
|
||||
if (languageVersionSettings.getFlag(AnalysisFlags.allowResultReturnType)) return
|
||||
|
||||
if ((languageVersionSettings.getFeatureSupport(LanguageFeature.InlineClasses) == LanguageFeature.State.ENABLED ||
|
||||
languageVersionSettings.supportsFeature(LanguageFeature.JvmInlineValueClasses)) &&
|
||||
languageVersionSettings.supportsFeature(LanguageFeature.AllowResultInReturnType)
|
||||
) return
|
||||
|
||||
if (languageVersionSettings.supportsFeature(LanguageFeature.AllowNullOperatorsForResultAndResultReturnTypeByDefault)) return
|
||||
|
||||
if (declaration !is KtCallableDeclaration || descriptor !is CallableMemberDescriptor) return
|
||||
|
||||
val returnType = descriptor.returnType ?: return
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
$TESTDATA_DIR$/resultInReturnType.kt
|
||||
-d
|
||||
$TEMP_DIR$
|
||||
-language-version
|
||||
1.5
|
||||
@@ -0,0 +1 @@
|
||||
OK
|
||||
@@ -1,4 +1,6 @@
|
||||
$TESTDATA_DIR$/resultInReturnType.kt
|
||||
-d
|
||||
$TEMP_DIR$
|
||||
-Xinline-classes
|
||||
-Xinline-classes
|
||||
-language-version
|
||||
1.4
|
||||
|
||||
+3
-1
@@ -1,4 +1,6 @@
|
||||
$TESTDATA_DIR$/resultInReturnType.kt
|
||||
-d
|
||||
$TEMP_DIR$
|
||||
-XXLanguage\:+InlineClasses
|
||||
-XXLanguage\:+InlineClasses
|
||||
-language-version
|
||||
1.4
|
||||
|
||||
+2
-2
@@ -16,14 +16,14 @@ fun baz(r: Result<Int>) {}
|
||||
fun returnsInlineClass() = Foo(1)
|
||||
|
||||
@JvmName("test")
|
||||
fun returnsKotlinResult(a: Result<Int>): <!RESULT_CLASS_IN_RETURN_TYPE!>Result<Int><!> = a
|
||||
fun returnsKotlinResult(a: Result<Int>): Result<Int> = a
|
||||
|
||||
class C {
|
||||
@JvmName("test")
|
||||
fun returnsInlineClass() = Foo(1)
|
||||
|
||||
@JvmName("test")
|
||||
fun returnsKotlinResult(a: Result<Int>): <!RESULT_CLASS_IN_RETURN_TYPE!>Result<Int><!> = a
|
||||
fun returnsKotlinResult(a: Result<Int>): Result<Int> = a
|
||||
}
|
||||
|
||||
@JvmName("extensionFun")
|
||||
|
||||
Vendored
+2
-2
@@ -2,6 +2,6 @@
|
||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION
|
||||
|
||||
fun test(r: Result<Int>?) {
|
||||
r <!RESULT_CLASS_WITH_NULLABLE_OPERATOR!>?:<!> 0
|
||||
r<!RESULT_CLASS_WITH_NULLABLE_OPERATOR!>?.<!>isFailure
|
||||
r ?: 0
|
||||
r?.isFailure
|
||||
}
|
||||
Vendored
+1
-1
@@ -5,5 +5,5 @@ fun result(): Result<Int> = TODO()
|
||||
val resultP: Result<Int> = result()
|
||||
|
||||
fun f(r1: Result<Int>?) {
|
||||
r1 <!RESULT_CLASS_WITH_NULLABLE_OPERATOR!>?:<!> <!UNUSED_EXPRESSION!>0<!>
|
||||
r1 ?: <!UNUSED_EXPRESSION!>0<!>
|
||||
}
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
// !LANGUAGE: +InlineClasses -AllowResultInReturnType
|
||||
|
||||
fun result(): <!RESULT_CLASS_IN_RETURN_TYPE!>Result<Int><!> = TODO()
|
||||
val resultP: <!RESULT_CLASS_IN_RETURN_TYPE!>Result<Int><!> = result()
|
||||
fun result(): Result<Int> = TODO()
|
||||
val resultP: Result<Int> = result()
|
||||
|
||||
+42
-42
@@ -16,105 +16,105 @@ fun params(
|
||||
|
||||
class CtorParams(r1: Result<Int>)
|
||||
|
||||
fun returnTypePublic(): <!RESULT_CLASS_IN_RETURN_TYPE!>Result<Int><!> = TODO()
|
||||
internal fun returnTypeInternal(): <!RESULT_CLASS_IN_RETURN_TYPE!>Result<Int><!> = TODO()
|
||||
private fun returnTypePrivate(): <!RESULT_CLASS_IN_RETURN_TYPE!>Result<Int><!> = TODO()
|
||||
fun returnTypeNullable(): <!RESULT_CLASS_IN_RETURN_TYPE!>Result<Int>?<!> = TODO()
|
||||
fun returnTypeAlias(): <!RESULT_CLASS_IN_RETURN_TYPE!>ResultAlias<Int><!> = TODO()
|
||||
fun <!RESULT_CLASS_IN_RETURN_TYPE!>returnInferred<!>(r1: Result<Int>, r2: ResultAlias<Int>, b: Boolean) = if (b) r1 else r2
|
||||
fun returnTypePublic(): Result<Int> = TODO()
|
||||
internal fun returnTypeInternal(): Result<Int> = TODO()
|
||||
private fun returnTypePrivate(): Result<Int> = TODO()
|
||||
fun returnTypeNullable(): Result<Int>? = TODO()
|
||||
fun returnTypeAlias(): ResultAlias<Int> = TODO()
|
||||
fun returnInferred(r1: Result<Int>, r2: ResultAlias<Int>, b: Boolean) = if (b) r1 else r2
|
||||
|
||||
fun returnTypeInline(): InlineResult<Int> = TODO()
|
||||
fun returnContainer(): List<Result<Int>> = TODO()
|
||||
|
||||
val topLevelP: <!RESULT_CLASS_IN_RETURN_TYPE!>Result<Int><!> = TODO()
|
||||
val <!RESULT_CLASS_IN_RETURN_TYPE!>topLevelPInferred<!> = topLevelP
|
||||
internal val topLevelPInternal: <!RESULT_CLASS_IN_RETURN_TYPE!>Result<Int><!> = TODO()
|
||||
val topLevelP: Result<Int> = TODO()
|
||||
val topLevelPInferred = topLevelP
|
||||
internal val topLevelPInternal: Result<Int> = TODO()
|
||||
|
||||
private val topLevelPPrivate: Result<Int> = TODO()
|
||||
private val topLevelPPrivateInferred = topLevelP
|
||||
|
||||
private val topLevelPPrivateCustomGetter: <!RESULT_CLASS_IN_RETURN_TYPE!>Result<Int><!>
|
||||
private val topLevelPPrivateCustomGetter: Result<Int>
|
||||
get() = TODO()
|
||||
|
||||
val asFunctional: () -> Result<Int> = TODO()
|
||||
|
||||
open class PublicCls(
|
||||
val r1: <!RESULT_CLASS_IN_RETURN_TYPE!>Result<String><!>,
|
||||
val r2: <!RESULT_CLASS_IN_RETURN_TYPE!>Result<Int>?<!>,
|
||||
val r3: <!RESULT_CLASS_IN_RETURN_TYPE!>ResultAlias<Int><!>,
|
||||
val r4: <!RESULT_CLASS_IN_RETURN_TYPE!>ResultAlias<Int>?<!>,
|
||||
val r1: Result<String>,
|
||||
val r2: Result<Int>?,
|
||||
val r3: ResultAlias<Int>,
|
||||
val r4: ResultAlias<Int>?,
|
||||
|
||||
val r5: InlineResult<Int>,
|
||||
|
||||
internal val r6: <!RESULT_CLASS_IN_RETURN_TYPE!>Result<Int><!>,
|
||||
internal val r6: Result<Int>,
|
||||
|
||||
private val r7: Result<Int>,
|
||||
val r8: List<Result<Int>>
|
||||
) {
|
||||
val p1: <!RESULT_CLASS_IN_RETURN_TYPE!>Result<Int><!> = TODO()
|
||||
var p2: <!RESULT_CLASS_IN_RETURN_TYPE!>Result<Int><!> = TODO()
|
||||
val p3: <!RESULT_CLASS_IN_RETURN_TYPE!>ResultAlias<Int>?<!> = TODO()
|
||||
val p1: Result<Int> = TODO()
|
||||
var p2: Result<Int> = TODO()
|
||||
val p3: ResultAlias<Int>? = TODO()
|
||||
|
||||
val <!RESULT_CLASS_IN_RETURN_TYPE!>p4<!> = p1
|
||||
val p4 = p1
|
||||
|
||||
internal val p5: <!RESULT_CLASS_IN_RETURN_TYPE!>Result<Int><!> = TODO()
|
||||
internal val p5: Result<Int> = TODO()
|
||||
|
||||
private var p6: Result<Int> = TODO()
|
||||
|
||||
internal val <!RESULT_CLASS_IN_RETURN_TYPE!>p7<!> = p1
|
||||
protected val <!RESULT_CLASS_IN_RETURN_TYPE!>p8<!> = p1
|
||||
internal val p7 = p1
|
||||
protected val p8 = p1
|
||||
|
||||
fun returnInCls(): <!RESULT_CLASS_IN_RETURN_TYPE!>Result<Int><!> = TODO()
|
||||
protected fun returnInClsProtected(): <!RESULT_CLASS_IN_RETURN_TYPE!>Result<Int><!> = TODO()
|
||||
private fun returnInClsPrivate(): <!RESULT_CLASS_IN_RETURN_TYPE!>Result<Int><!> = TODO()
|
||||
fun returnInCls(): Result<Int> = TODO()
|
||||
protected fun returnInClsProtected(): Result<Int> = TODO()
|
||||
private fun returnInClsPrivate(): Result<Int> = TODO()
|
||||
}
|
||||
|
||||
internal open class InternalCls(
|
||||
val r1: <!RESULT_CLASS_IN_RETURN_TYPE!>Result<Int><!>,
|
||||
val r2: <!RESULT_CLASS_IN_RETURN_TYPE!>ResultAlias<Int>?<!>,
|
||||
val r1: Result<Int>,
|
||||
val r2: ResultAlias<Int>?,
|
||||
|
||||
val r3: List<Result<Int>>
|
||||
) {
|
||||
companion object {
|
||||
val cr1: <!RESULT_CLASS_IN_RETURN_TYPE!>Result<Int><!> = TODO()
|
||||
val cr1: Result<Int> = TODO()
|
||||
|
||||
private val cr2: Result<Int> = TODO()
|
||||
}
|
||||
|
||||
val <!RESULT_CLASS_IN_RETURN_TYPE!>p1<!> = r1
|
||||
val p2: <!RESULT_CLASS_IN_RETURN_TYPE!>Result<String><!> = TODO()
|
||||
val p1 = r1
|
||||
val p2: Result<String> = TODO()
|
||||
|
||||
protected val <!RESULT_CLASS_IN_RETURN_TYPE!>p3<!> = p1
|
||||
protected val p3 = p1
|
||||
|
||||
fun returnInInternal(): <!RESULT_CLASS_IN_RETURN_TYPE!>Result<Int><!> = TODO()
|
||||
protected fun returnInClsProtected(): <!RESULT_CLASS_IN_RETURN_TYPE!>Result<Int><!> = TODO()
|
||||
fun returnInInternal(): Result<Int> = TODO()
|
||||
protected fun returnInClsProtected(): Result<Int> = TODO()
|
||||
}
|
||||
|
||||
private class PrivateCls(
|
||||
val r1: <!RESULT_CLASS_IN_RETURN_TYPE!>Result<Int><!>,
|
||||
val r2: <!RESULT_CLASS_IN_RETURN_TYPE!>ResultAlias<Int>?<!>,
|
||||
val r1: Result<Int>,
|
||||
val r2: ResultAlias<Int>?,
|
||||
val r3: List<Result<Int>>
|
||||
) {
|
||||
companion object {
|
||||
val cr1: <!RESULT_CLASS_IN_RETURN_TYPE!>Result<Int><!> = TODO()
|
||||
val cr1: Result<Int> = TODO()
|
||||
private val cr2: Result<Int> = TODO()
|
||||
}
|
||||
|
||||
val <!RESULT_CLASS_IN_RETURN_TYPE!>p1<!> = r1
|
||||
val p2: <!RESULT_CLASS_IN_RETURN_TYPE!>Result<String><!> = TODO()
|
||||
val p1 = r1
|
||||
val p2: Result<String> = TODO()
|
||||
|
||||
fun returnInPrivate(): <!RESULT_CLASS_IN_RETURN_TYPE!>Result<Int><!> = TODO()
|
||||
fun returnInPrivate(): Result<Int> = TODO()
|
||||
}
|
||||
|
||||
fun local(r: Result<Int>) {
|
||||
val l1: Result<Int>? = null
|
||||
val l2 = r
|
||||
|
||||
fun localFun(): <!RESULT_CLASS_IN_RETURN_TYPE!>Result<Int><!> = TODO()
|
||||
fun localFun(): Result<Int> = TODO()
|
||||
|
||||
class F {
|
||||
val p1: <!RESULT_CLASS_IN_RETURN_TYPE!>Result<Int><!> = r
|
||||
val <!RESULT_CLASS_IN_RETURN_TYPE!>p2<!> = r
|
||||
val p1: Result<Int> = r
|
||||
val p2 = r
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Vendored
+15
-15
@@ -4,7 +4,7 @@
|
||||
fun <T> id(x: T): T = x
|
||||
|
||||
private val asFun: () -> Result<Int>? = TODO()
|
||||
private val Int.intResult: <!RESULT_CLASS_IN_RETURN_TYPE!>Result<Int>?<!>
|
||||
private val Int.intResult: Result<Int>?
|
||||
get() = null
|
||||
|
||||
fun returnInt(): Int? = 0
|
||||
@@ -12,29 +12,29 @@ fun returnInt(): Int? = 0
|
||||
|
||||
fun nullableOperators(r1: Result<Int>?, b: Boolean) {
|
||||
if (b) {
|
||||
r1<!RESULT_CLASS_WITH_NULLABLE_OPERATOR!>!!<!>
|
||||
asFun()<!RESULT_CLASS_WITH_NULLABLE_OPERATOR!>!!<!>
|
||||
returnInt()?.intResult<!RESULT_CLASS_WITH_NULLABLE_OPERATOR!>!!<!>.toString()
|
||||
r1!!
|
||||
asFun()!!
|
||||
returnInt()?.intResult!!.toString()
|
||||
}
|
||||
|
||||
if (b) {
|
||||
id(r1)<!RESULT_CLASS_WITH_NULLABLE_OPERATOR!>!!<!>
|
||||
id(r1)!!
|
||||
}
|
||||
|
||||
if (b) {
|
||||
r1<!RESULT_CLASS_WITH_NULLABLE_OPERATOR!>?.<!>toString()
|
||||
r1<!RESULT_CLASS_WITH_NULLABLE_OPERATOR!>?.<!>let { }
|
||||
returnInt()?.intResult<!RESULT_CLASS_WITH_NULLABLE_OPERATOR!>?.<!>toString()
|
||||
asFun()<!RESULT_CLASS_WITH_NULLABLE_OPERATOR!>?.<!>toString()
|
||||
id(r1)<!RESULT_CLASS_WITH_NULLABLE_OPERATOR!>?.<!>toString()
|
||||
r1?.toString()
|
||||
r1?.let { }
|
||||
returnInt()?.intResult?.toString()
|
||||
asFun()?.toString()
|
||||
id(r1)?.toString()
|
||||
}
|
||||
|
||||
if (b) {
|
||||
r1 <!RESULT_CLASS_WITH_NULLABLE_OPERATOR!>?:<!> 0
|
||||
r1 <!RESULT_CLASS_WITH_NULLABLE_OPERATOR!>?:<!> r1
|
||||
asFun() <!RESULT_CLASS_WITH_NULLABLE_OPERATOR!>?:<!> r1 <!RESULT_CLASS_WITH_NULLABLE_OPERATOR!>?:<!> 0
|
||||
id(asFun()) <!RESULT_CLASS_WITH_NULLABLE_OPERATOR!>?:<!> 0
|
||||
r1 ?: 0
|
||||
r1 ?: r1
|
||||
asFun() ?: r1 ?: 0
|
||||
id(asFun()) ?: 0
|
||||
|
||||
returnInt() ?: returnInt() ?: asFun() <!RESULT_CLASS_WITH_NULLABLE_OPERATOR!>?:<!> 0
|
||||
returnInt() ?: returnInt() ?: asFun() ?: 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -706,6 +706,11 @@ public class CliTestGenerated extends AbstractCliTest {
|
||||
runTest("compiler/testData/cli/jvm/progressiveModeOn.args");
|
||||
}
|
||||
|
||||
@TestMetadata("resultInReturnTypeSupportedByDefault15.args")
|
||||
public void testResultInReturnTypeSupportedByDefault15() throws Exception {
|
||||
runTest("compiler/testData/cli/jvm/resultInReturnTypeSupportedByDefault15.args");
|
||||
}
|
||||
|
||||
@TestMetadata("resultInReturnTypeUnsupportedByDefault14.args")
|
||||
public void testResultInReturnTypeUnsupportedByDefault14() throws Exception {
|
||||
runTest("compiler/testData/cli/jvm/resultInReturnTypeUnsupportedByDefault14.args");
|
||||
|
||||
@@ -239,15 +239,6 @@ class LauncherScriptTest : TestCaseWithTmpdir() {
|
||||
}
|
||||
|
||||
fun testScriptWithXArguments() {
|
||||
runProcess(
|
||||
"kotlin", "$testDataDirectory/funWithResultReturn.kts",
|
||||
expectedExitCode = 1,
|
||||
expectedStderr = """error: 'kotlin.Result' cannot be used as a return type (funWithResultReturn.kts:2:11)
|
||||
compiler/testData/launcher/funWithResultReturn.kts:2:11: error: 'kotlin.Result' cannot be used as a return type
|
||||
fun f() : Result<Int> = Result.success(42)
|
||||
^
|
||||
"""
|
||||
)
|
||||
runProcess("kotlin", "-Xallow-result-return-type", "$testDataDirectory/funWithResultReturn.kts", expectedStdout = "42\n")
|
||||
}
|
||||
|
||||
@@ -308,18 +299,6 @@ println(42)
|
||||
"kotlin", "-howtorun", "script", "$testDataDirectory/funWithResultReturn.myscript",
|
||||
expectedExitCode = 1, expectedStderr = "error: unrecognized script type: funWithResultReturn.myscript; Specify path to the script file as the first argument\n"
|
||||
)
|
||||
runProcess(
|
||||
"kotlin", "-howtorun", ".kts", "$testDataDirectory/funWithResultReturn.myscript",
|
||||
expectedExitCode = 1, expectedStderr = """error: unresolved reference: CompilerOptions (funWithResultReturn.myscript:1:7)
|
||||
error: 'kotlin.Result' cannot be used as a return type (funWithResultReturn.myscript:3:11)
|
||||
compiler/testData/launcher/funWithResultReturn.myscript:1:7: error: unresolved reference: CompilerOptions
|
||||
@file:CompilerOptions("-Xallow-result-return-type")
|
||||
^
|
||||
compiler/testData/launcher/funWithResultReturn.myscript:3:11: error: 'kotlin.Result' cannot be used as a return type
|
||||
fun f() : Result<Int> = Result.success(42)
|
||||
^
|
||||
"""
|
||||
)
|
||||
runProcess(
|
||||
"kotlin", "-howtorun", ".main.kts", "$testDataDirectory/funWithResultReturn.myscript",
|
||||
expectedStdout = "42\n"
|
||||
|
||||
@@ -116,6 +116,7 @@ enum class LanguageFeature(
|
||||
AllowAssigningArrayElementsToVarargsInNamedFormForFunctions(KOTLIN_1_4),
|
||||
AllowNullOperatorsForResult(KOTLIN_1_4),
|
||||
AllowResultInReturnType(KOTLIN_1_4, defaultState = State.DISABLED),
|
||||
AllowNullOperatorsForResultAndResultReturnTypeByDefault(KOTLIN_1_5, defaultState = State.ENABLED),
|
||||
PreferJavaFieldOverload(KOTLIN_1_4),
|
||||
AllowContractsForNonOverridableMembers(KOTLIN_1_4),
|
||||
AllowReifiedGenericsInContracts(KOTLIN_1_4),
|
||||
|
||||
Reference in New Issue
Block a user