From 169599abcca2f7ac2db09306e7fa1d3bdf0f9f05 Mon Sep 17 00:00:00 2001 From: Mikhail Zarechenskiy Date: Mon, 10 Sep 2018 09:25:10 +0300 Subject: [PATCH] Add flag to allow using `kotlin.Result` as a return type #KT-26659 Fixed --- .../cli/common/arguments/CommonCompilerArguments.kt | 7 +++++++ .../resolve/checkers/ResultClassInReturnTypeChecker.kt | 3 +++ compiler/testData/cli/js/jsExtraHelp.out | 1 + compiler/testData/cli/jvm/extraHelp.out | 1 + .../cli/jvm/flagAllowingResultAsReturnType.args | 4 ++++ .../testData/cli/jvm/flagAllowingResultAsReturnType.kt | 1 + .../cli/jvm/flagAllowingResultAsReturnType.out | 1 + .../coroutines/allowResultInReturnTypeWithFlag.kt | 8 ++++++++ .../coroutines/allowResultInReturnTypeWithFlag.txt | 5 +++++ .../checkers/CompilerTestLanguageVersionSettings.kt | 10 ++++++++-- .../checkers/DiagnosticsTestWithStdLibGenerated.java | 5 +++++ .../DiagnosticsTestWithStdLibUsingJavacGenerated.java | 5 +++++ .../org/jetbrains/kotlin/cli/CliTestGenerated.java | 5 +++++ .../src/org/jetbrains/kotlin/config/AnalysisFlag.kt | 3 +++ 14 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 compiler/testData/cli/jvm/flagAllowingResultAsReturnType.args create mode 100644 compiler/testData/cli/jvm/flagAllowingResultAsReturnType.kt create mode 100644 compiler/testData/cli/jvm/flagAllowingResultAsReturnType.out create mode 100644 compiler/testData/diagnostics/testsWithStdLib/coroutines/allowResultInReturnTypeWithFlag.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/coroutines/allowResultInReturnTypeWithFlag.txt diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.kt index 85b73a5a1ea..acbb3b47078 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.kt @@ -190,6 +190,12 @@ abstract class CommonCompilerArguments : CommonToolArguments() { ) var commonSources: Array? by FreezableVar(null) + @Argument( + value = "-Xallow-result-return-type", + description = "Allow compiling code when `kotlin.Result` is used as a return type" + ) + var allowResultReturnType: Boolean by FreezableVar(false) + open fun configureAnalysisFlags(collector: MessageCollector): MutableMap, Any> { return HashMap, Any>().apply { put(AnalysisFlag.skipMetadataVersionCheck, skipMetadataVersionCheck) @@ -198,6 +204,7 @@ abstract class CommonCompilerArguments : CommonToolArguments() { put(AnalysisFlag.experimental, experimental?.toList().orEmpty()) put(AnalysisFlag.useExperimental, useExperimental?.toList().orEmpty()) put(AnalysisFlag.explicitApiVersion, apiVersion != null) + put(AnalysisFlag.allowResultReturnType, allowResultReturnType) } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ResultClassInReturnTypeChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ResultClassInReturnTypeChecker.kt index 9c909b43bd6..5d9aec6c7cf 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ResultClassInReturnTypeChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ResultClassInReturnTypeChecker.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.resolve.checkers import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.config.AnalysisFlag import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.diagnostics.reportDiagnosticOnce @@ -19,6 +20,8 @@ class ResultClassInReturnTypeChecker : DeclarationChecker { } override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) { + if (context.languageVersionSettings.getFlag(AnalysisFlag.allowResultReturnType)) return + if (declaration !is KtCallableDeclaration || descriptor !is CallableMemberDescriptor) return val returnType = descriptor.returnType ?: return diff --git a/compiler/testData/cli/js/jsExtraHelp.out b/compiler/testData/cli/js/jsExtraHelp.out index 2f61b5ed2c2..138cbf6d4be 100644 --- a/compiler/testData/cli/js/jsExtraHelp.out +++ b/compiler/testData/cli/js/jsExtraHelp.out @@ -4,6 +4,7 @@ where advanced options include: -Xfriend-modules-disabled Disable internal declaration export -Xtyped-arrays Translate primitive arrays to JS typed arrays -Xallow-kotlin-package Allow compiling code in package 'kotlin' and allow not requiring kotlin.stdlib in module-info + -Xallow-result-return-type Allow compiling code when `kotlin.Result` is used as a return type -Xcommon-sources= Sources of the common module that need to be compiled together with this module in the multi-platform mode. Should be a subset of sources passed as free arguments -Xcoroutines={enable|warn|error} diff --git a/compiler/testData/cli/jvm/extraHelp.out b/compiler/testData/cli/jvm/extraHelp.out index 564e3d335ef..280ddd9f508 100644 --- a/compiler/testData/cli/jvm/extraHelp.out +++ b/compiler/testData/cli/jvm/extraHelp.out @@ -62,6 +62,7 @@ where advanced options include: -Xuse-old-class-files-reading Use old class files reading implementation (may slow down the build and should be used in case of problems with the new implementation) -Xuse-type-table Use type table in metadata serialization -Xallow-kotlin-package Allow compiling code in package 'kotlin' and allow not requiring kotlin.stdlib in module-info + -Xallow-result-return-type Allow compiling code when `kotlin.Result` is used as a return type -Xcommon-sources= Sources of the common module that need to be compiled together with this module in the multi-platform mode. Should be a subset of sources passed as free arguments -Xcoroutines={enable|warn|error} diff --git a/compiler/testData/cli/jvm/flagAllowingResultAsReturnType.args b/compiler/testData/cli/jvm/flagAllowingResultAsReturnType.args new file mode 100644 index 00000000000..a79300a6a43 --- /dev/null +++ b/compiler/testData/cli/jvm/flagAllowingResultAsReturnType.args @@ -0,0 +1,4 @@ +$TESTDATA_DIR$/flagAllowingResultAsReturnType.kt +-Xallow-result-return-type +-d +$TEMP_DIR$ diff --git a/compiler/testData/cli/jvm/flagAllowingResultAsReturnType.kt b/compiler/testData/cli/jvm/flagAllowingResultAsReturnType.kt new file mode 100644 index 00000000000..7d0238befc6 --- /dev/null +++ b/compiler/testData/cli/jvm/flagAllowingResultAsReturnType.kt @@ -0,0 +1 @@ +fun foo(): Result = TODO() \ No newline at end of file diff --git a/compiler/testData/cli/jvm/flagAllowingResultAsReturnType.out b/compiler/testData/cli/jvm/flagAllowingResultAsReturnType.out new file mode 100644 index 00000000000..a0aba9318ad --- /dev/null +++ b/compiler/testData/cli/jvm/flagAllowingResultAsReturnType.out @@ -0,0 +1 @@ +OK \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/allowResultInReturnTypeWithFlag.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/allowResultInReturnTypeWithFlag.kt new file mode 100644 index 00000000000..3fd5a6d9f8e --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/allowResultInReturnTypeWithFlag.kt @@ -0,0 +1,8 @@ +// !ALLOW_RESULT_RETURN_TYPE + +fun result(): Result = TODO() +val resultP: Result = result() + +fun f(r1: Result?) { + r1 ?: 0 +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/allowResultInReturnTypeWithFlag.txt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/allowResultInReturnTypeWithFlag.txt new file mode 100644 index 00000000000..934177306bd --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/allowResultInReturnTypeWithFlag.txt @@ -0,0 +1,5 @@ +package + +public val resultP: kotlin.Result +public fun f(/*0*/ r1: kotlin.Result?): kotlin.Unit +public fun result(): kotlin.Result diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/CompilerTestLanguageVersionSettings.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/CompilerTestLanguageVersionSettings.kt index 5f8b5b40fb5..4a72ff7b85c 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/CompilerTestLanguageVersionSettings.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/CompilerTestLanguageVersionSettings.kt @@ -21,6 +21,7 @@ const val USE_EXPERIMENTAL_DIRECTIVE = "USE_EXPERIMENTAL" const val IGNORE_DATA_FLOW_IN_ASSERT_DIRECTIVE = "IGNORE_DATA_FLOW_IN_ASSERT" const val JVM_DEFAULT_MODE = "JVM_DEFAULT_MODE" const val SKIP_METADATA_VERSION_CHECK = "SKIP_METADATA_VERSION_CHECK" +const val ALLOW_RESULT_RETURN_TYPE = "ALLOW_RESULT_RETURN_TYPE" data class CompilerTestLanguageVersionSettings( private val initialLanguageFeatures: Map, @@ -58,8 +59,13 @@ fun parseLanguageVersionSettings(directiveMap: Map): CompilerTes val ignoreDataFlowInAssert = AnalysisFlag.ignoreDataFlowInAssert to directiveMap.containsKey(IGNORE_DATA_FLOW_IN_ASSERT_DIRECTIVE) val enableJvmDefault = directiveMap[JVM_DEFAULT_MODE]?.let { AnalysisFlag.jvmDefaultMode to JvmDefaultMode.fromStringOrNull(it)!! } val skipMetadataVersionCheck = AnalysisFlag.skipMetadataVersionCheck to directiveMap.containsKey(SKIP_METADATA_VERSION_CHECK) + val allowResultReturnType = AnalysisFlag.allowResultReturnType to directiveMap.containsKey(ALLOW_RESULT_RETURN_TYPE) - if (apiVersionString == null && languageFeaturesString == null && experimental == null && useExperimental == null && !ignoreDataFlowInAssert.second) return null + if (apiVersionString == null && languageFeaturesString == null && experimental == null && + useExperimental == null && !ignoreDataFlowInAssert.second && !allowResultReturnType.second + ) { + return null + } val apiVersion = (if (apiVersionString != null) ApiVersion.parse(apiVersionString) else ApiVersion.LATEST_STABLE) ?: error("Unknown API version: $apiVersionString") @@ -72,7 +78,7 @@ fun parseLanguageVersionSettings(directiveMap: Map): CompilerTes languageFeatures, apiVersion, languageVersion, mapOf( *listOfNotNull( - experimental, useExperimental, enableJvmDefault, ignoreDataFlowInAssert, skipMetadataVersionCheck + experimental, useExperimental, enableJvmDefault, ignoreDataFlowInAssert, skipMetadataVersionCheck, allowResultReturnType ).toTypedArray() ) ) diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java index 819a12bb378..5d0f338a62d 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java @@ -1433,6 +1433,11 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/coroutines"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); } + @TestMetadata("allowResultInReturnTypeWithFlag.kt") + public void testAllowResultInReturnTypeWithFlag() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/allowResultInReturnTypeWithFlag.kt"); + } + @TestMetadata("callableReferences.kt") public void testCallableReferences() throws Exception { runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/callableReferences.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java index 337c3cc98ce..4795eec998f 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java @@ -1433,6 +1433,11 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/coroutines"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); } + @TestMetadata("allowResultInReturnTypeWithFlag.kt") + public void testAllowResultInReturnTypeWithFlag() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/allowResultInReturnTypeWithFlag.kt"); + } + @TestMetadata("callableReferences.kt") public void testCallableReferences() throws Exception { runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/callableReferences.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/cli/CliTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/cli/CliTestGenerated.java index f131c1b6d5e..52e9ddb1f1d 100644 --- a/compiler/tests/org/jetbrains/kotlin/cli/CliTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/cli/CliTestGenerated.java @@ -251,6 +251,11 @@ public class CliTestGenerated extends AbstractCliTest { runTest("compiler/testData/cli/jvm/fileClassClashMultipleFiles.args"); } + @TestMetadata("flagAllowingResultAsReturnType.args") + public void testFlagAllowingResultAsReturnType() throws Exception { + runTest("compiler/testData/cli/jvm/flagAllowingResultAsReturnType.args"); + } + @TestMetadata("help.args") public void testHelp() throws Exception { runTest("compiler/testData/cli/jvm/help.args"); diff --git a/compiler/util/src/org/jetbrains/kotlin/config/AnalysisFlag.kt b/compiler/util/src/org/jetbrains/kotlin/config/AnalysisFlag.kt index 9f460799ce3..9ea861a8c23 100644 --- a/compiler/util/src/org/jetbrains/kotlin/config/AnalysisFlag.kt +++ b/compiler/util/src/org/jetbrains/kotlin/config/AnalysisFlag.kt @@ -71,5 +71,8 @@ class AnalysisFlag internal constructor( @JvmStatic val jvmDefaultMode by Flag.JvmDefaultModeDisabledByDefaul + + @JvmStatic + val allowResultReturnType by Flag.Boolean } }