diff --git a/build-common/src/org/jetbrains/kotlin/compilerRunner/ArgumentUtils.java b/build-common/src/org/jetbrains/kotlin/compilerRunner/ArgumentUtils.java index 8ce73120707..1558094d24b 100644 --- a/build-common/src/org/jetbrains/kotlin/compilerRunner/ArgumentUtils.java +++ b/build-common/src/org/jetbrains/kotlin/compilerRunner/ArgumentUtils.java @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.compilerRunner; import com.intellij.util.containers.ContainerUtil; +import kotlin.collections.CollectionsKt; import kotlin.jvm.JvmClassMappingKt; import kotlin.reflect.KClass; import kotlin.reflect.KProperty1; @@ -26,6 +27,7 @@ import kotlin.reflect.jvm.ReflectJvmMapping; import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.cli.common.arguments.Argument; import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments; +import org.jetbrains.kotlin.cli.common.arguments.InternalArgument; import org.jetbrains.kotlin.cli.common.arguments.ParseCommandLineArgumentsKt; import org.jetbrains.kotlin.utils.StringsKt; @@ -46,7 +48,7 @@ public class ArgumentUtils { Class argumentsClass = arguments.getClass(); convertArgumentsToStringList(arguments, argumentsClass.newInstance(), JvmClassMappingKt.getKotlinClass(argumentsClass), result); result.addAll(arguments.getFreeArgs()); - result.addAll(arguments.getInternalArguments()); + result.addAll(CollectionsKt.map(arguments.getInternalArguments(), InternalArgument::getStringRepresentation)); return result; } 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 f6e48bf4031..f2b8790eba4 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 @@ -245,11 +245,9 @@ abstract class CommonCompilerArguments : CommonToolArguments() { } private fun HashMap.configureLanguageFeaturesFromInternalArgs(collector: MessageCollector) { - val languageSettingsParser = LanguageSettingsParser() val featuresThatForcePreReleaseBinaries = mutableListOf() - for (argument in internalArguments) { - val (feature, state) = languageSettingsParser.parseInternalArgument(argument, collector) ?: continue + for ((feature, state) in internalArguments.filterIsInstance()) { put(feature, state) if (state == LanguageFeature.State.ENABLED && feature.forcesPreReleaseBinariesIfEnabled()) { featuresThatForcePreReleaseBinaries += feature diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonToolArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonToolArguments.kt index 9a89f90e248..ddf21dde214 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonToolArguments.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonToolArguments.kt @@ -50,5 +50,5 @@ abstract class CommonToolArguments : Freezable(), Serializable { @Argument(value = "-Werror", description = "Report an error if there are any warnings") var allWarningsAsErrors: Boolean by FreezableVar(false) - var internalArguments: List by FreezableVar(emptyList()) + var internalArguments: List by FreezableVar(emptyList()) } diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/InternalCompilerArgument.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/InternalCompilerArgument.kt index 7030898ae82..1f4e520d3f3 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/InternalCompilerArgument.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/InternalCompilerArgument.kt @@ -6,8 +6,6 @@ package org.jetbrains.kotlin.cli.common.arguments import org.jetbrains.kotlin.cli.common.arguments.InternalArgumentParser.Companion.INTERNAL_ARGUMENT_PREFIX -import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity -import org.jetbrains.kotlin.cli.common.messages.MessageCollector import org.jetbrains.kotlin.config.LanguageFeature /** @@ -25,7 +23,7 @@ interface InternalArgumentParser { // Should be fast fun canParse(arg: String): Boolean - fun parseInternalArgument(arg: String, messageCollector: MessageCollector): A? + fun parseInternalArgument(arg: String, errors: ArgumentParseErrors): A? companion object { internal const val INTERNAL_ARGUMENT_PREFIX = "-XX" @@ -41,13 +39,13 @@ abstract class AbstractInternalArgumentParser(familyName: override fun canParse(arg: String): Boolean = arg.startsWith(wholePrefix) - override fun parseInternalArgument(arg: String, messageCollector: MessageCollector): A? { + override fun parseInternalArgument(arg: String, errors: ArgumentParseErrors): A? { if (!arg.startsWith(wholePrefix)) return null - return parseTail(arg.removePrefix(wholePrefix), arg, messageCollector) + return parseTail(arg.removePrefix(wholePrefix), arg, errors) } - abstract fun parseTail(tail: String, wholeArgument: String, messageCollector: MessageCollector): A? + abstract fun parseTail(tail: String, wholeArgument: String, errors: ArgumentParseErrors): A? } @@ -55,9 +53,9 @@ abstract class AbstractInternalArgumentParser(familyName: class LanguageSettingsParser : AbstractInternalArgumentParser("Language") { // Expected tail form: ':(+|-)' - override fun parseTail(tail: String, wholeArgument: String, messageCollector: MessageCollector): ManualLanguageFeatureSetting? { + override fun parseTail(tail: String, wholeArgument: String, errors: ArgumentParseErrors): ManualLanguageFeatureSetting? { fun reportAndReturnNull(message: String): Nothing? { - messageCollector.report(CompilerMessageSeverity.STRONG_WARNING, message) + errors.internalArgumentsParsingProblems += message return null } @@ -76,12 +74,18 @@ class LanguageSettingsParser : AbstractInternalArgumentParser = SmartList() + val argfileErrors: MutableList = SmartList(), + + // Reports from internal arguments parsers + val internalArgumentsParsingProblems: MutableList = SmartList() ) // Parses arguments into the passed [result] object. Errors related to the parsing will be collected into [CommonToolArguments.errors]. @@ -108,7 +111,7 @@ private fun parsePreprocessedCommandLineArguments(args } val freeArgs = ArrayList() - val internalArguments = ArrayList() + val internalArguments = ArrayList() var i = 0 loop@ while (i < args.size) { @@ -132,7 +135,7 @@ private fun parsePreprocessedCommandLineArguments(args if (parser == null) { errors.unknownExtraFlags += arg } else { - internalArguments.add(arg) + internalArguments.add(parser.parseInternalArgument(arg, errors) ?: continue) } continue diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/common/CLITool.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/common/CLITool.kt index 81e973d67d9..5705592b9e7 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/common/CLITool.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/common/CLITool.kt @@ -23,6 +23,9 @@ import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.INFO import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.STRONG_WARNING import org.jetbrains.kotlin.cli.jvm.compiler.CompileEnvironmentException import org.jetbrains.kotlin.config.KotlinCompilerVersion +import org.jetbrains.kotlin.config.LanguageFeature +import org.jetbrains.kotlin.config.LanguageFeature.Kind.* +import org.jetbrains.kotlin.config.LanguageFeature.State.* import org.jetbrains.kotlin.config.Services import java.io.PrintStream import java.net.URL @@ -129,20 +132,38 @@ abstract class CLITool { for ((deprecatedName, newName) in errors.deprecatedArguments) { collector.report(STRONG_WARNING, "Argument $deprecatedName is deprecated. Please use $newName instead") } - if (arguments.internalArguments.isNotEmpty()) { + + for (argfileError in errors.argfileErrors) { + collector.report(STRONG_WARNING, argfileError) + } + + reportUnsafeInternalArgumentsIfAny(arguments, collector) + for (internalArgumentsError in errors.internalArgumentsParsingProblems) { + collector.report(STRONG_WARNING, internalArgumentsError) + } + } + + private fun reportUnsafeInternalArgumentsIfAny(arguments: A, collector: MessageCollector) { + val unsafeArguments = arguments.internalArguments.filterNot { + // -XXLanguage which turns on BUG_FIX considered safe + it is ManualLanguageFeatureSetting && it.languageFeature.kind == BUG_FIX && it.state == ENABLED + } + + if (unsafeArguments.isNotEmpty()) { + val unsafeArgumentsString = unsafeArguments.joinToString(prefix = "\n", postfix = "\n\n", separator = "\n") { + it.stringRepresentation + } + collector.report( STRONG_WARNING, "ATTENTION!\n" + - "This build uses internal compiler arguments:\n" + - arguments.internalArguments.joinToString(prefix = "\n", postfix = "\n\n", separator = "\n") + + "This build uses unsafe internal compiler arguments:\n" + + unsafeArgumentsString + "This mode is not recommended for production use,\n" + "as no stability/compatibility guarantees are given on\n" + "compiler or generated code. Use it at your own risk!\n" ) } - for (argfileError in errors.argfileErrors) { - collector.report(STRONG_WARNING, argfileError) - } } private fun printVersionIfNeeded(messageCollector: MessageCollector, arguments: A) { diff --git a/compiler/testData/cli/jvm/internalArgDisableLanguageFeature.out b/compiler/testData/cli/jvm/internalArgDisableLanguageFeature.out index b9a4d8b59c6..91e4fcf215b 100644 --- a/compiler/testData/cli/jvm/internalArgDisableLanguageFeature.out +++ b/compiler/testData/cli/jvm/internalArgDisableLanguageFeature.out @@ -1,5 +1,5 @@ warning: ATTENTION! -This build uses internal compiler arguments: +This build uses unsafe internal compiler arguments: -XXLanguage:-SoundSmartCastsAfterTry diff --git a/compiler/testData/cli/jvm/internalArgEmptyFeatureName.out b/compiler/testData/cli/jvm/internalArgEmptyFeatureName.out index d757024b328..1436a5b3b5d 100644 --- a/compiler/testData/cli/jvm/internalArgEmptyFeatureName.out +++ b/compiler/testData/cli/jvm/internalArgEmptyFeatureName.out @@ -1,12 +1,3 @@ -warning: ATTENTION! -This build uses internal compiler arguments: - --XXLanguage:+ - -This mode is not recommended for production use, -as no stability/compatibility guarantees are given on -compiler or generated code. Use it at your own risk! - warning: empty language feature name for internal argument '-XXLanguage:+' compiler/testData/cli/jvm/legacySmartCastsAfterTry.kt:8:9: error: only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String? some.length diff --git a/compiler/testData/cli/jvm/internalArgEnableLanguageFeature.out b/compiler/testData/cli/jvm/internalArgEnableLanguageFeature.out index 59a6e106708..7eeb0db523f 100644 --- a/compiler/testData/cli/jvm/internalArgEnableLanguageFeature.out +++ b/compiler/testData/cli/jvm/internalArgEnableLanguageFeature.out @@ -1,5 +1,5 @@ warning: ATTENTION! -This build uses internal compiler arguments: +This build uses unsafe internal compiler arguments: -XXLanguage:+SoundSmartCastsAfterTry diff --git a/compiler/testData/cli/jvm/internalArgMissingModificator.out b/compiler/testData/cli/jvm/internalArgMissingModificator.out index 238fafd19eb..3aa7bfac819 100644 --- a/compiler/testData/cli/jvm/internalArgMissingModificator.out +++ b/compiler/testData/cli/jvm/internalArgMissingModificator.out @@ -1,12 +1,3 @@ -warning: ATTENTION! -This build uses internal compiler arguments: - --XXLanguage:SoundSmartCastAfterTry - -This mode is not recommended for production use, -as no stability/compatibility guarantees are given on -compiler or generated code. Use it at your own risk! - warning: incorrect internal argument syntax, missing modificator: -XXLanguage:SoundSmartCastAfterTry compiler/testData/cli/jvm/legacySmartCastsAfterTry.kt:8:9: error: only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String? some.length diff --git a/compiler/testData/cli/jvm/internalArgNoWarningForEnablingBugfix.args b/compiler/testData/cli/jvm/internalArgNoWarningForEnablingBugfix.args new file mode 100644 index 00000000000..4e4f50d5f50 --- /dev/null +++ b/compiler/testData/cli/jvm/internalArgNoWarningForEnablingBugfix.args @@ -0,0 +1,6 @@ +$TESTDATA_DIR$/simple.kt +-d +$TEMP_DIR$ +-language-version +1.2 +-XXLanguage:+ProhibitDataClassesOverridingCopy \ No newline at end of file diff --git a/compiler/testData/cli/jvm/internalArgNoWarningForEnablingBugfix.out b/compiler/testData/cli/jvm/internalArgNoWarningForEnablingBugfix.out new file mode 100644 index 00000000000..d86bac9de59 --- /dev/null +++ b/compiler/testData/cli/jvm/internalArgNoWarningForEnablingBugfix.out @@ -0,0 +1 @@ +OK diff --git a/compiler/testData/cli/jvm/internalArgUnrecognizedFeature.out b/compiler/testData/cli/jvm/internalArgUnrecognizedFeature.out index 048ac12dc93..df9f2de7850 100644 --- a/compiler/testData/cli/jvm/internalArgUnrecognizedFeature.out +++ b/compiler/testData/cli/jvm/internalArgUnrecognizedFeature.out @@ -1,12 +1,3 @@ -warning: ATTENTION! -This build uses internal compiler arguments: - --XXLanguage:+UnknownFeature - -This mode is not recommended for production use, -as no stability/compatibility guarantees are given on -compiler or generated code. Use it at your own risk! - warning: unknown language feature 'UnknownFeature' in passed internal argument '-XXLanguage:+UnknownFeature' compiler/testData/cli/jvm/legacySmartCastsAfterTry.kt:8:9: error: only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String? some.length diff --git a/compiler/testData/cli/jvm/internalArgumentOverrideExtraArgument.out b/compiler/testData/cli/jvm/internalArgumentOverrideExtraArgument.out index 59a6e106708..7eeb0db523f 100644 --- a/compiler/testData/cli/jvm/internalArgumentOverrideExtraArgument.out +++ b/compiler/testData/cli/jvm/internalArgumentOverrideExtraArgument.out @@ -1,5 +1,5 @@ warning: ATTENTION! -This build uses internal compiler arguments: +This build uses unsafe internal compiler arguments: -XXLanguage:+SoundSmartCastsAfterTry diff --git a/compiler/tests/org/jetbrains/kotlin/cli/CliTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/cli/CliTestGenerated.java index 626b92a7470..480571a3f73 100644 --- a/compiler/tests/org/jetbrains/kotlin/cli/CliTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/cli/CliTestGenerated.java @@ -261,6 +261,11 @@ public class CliTestGenerated extends AbstractCliTest { runTest("compiler/testData/cli/jvm/internalArgMissingModificator.args"); } + @TestMetadata("internalArgNoWarningForEnablingBugfix.args") + public void testInternalArgNoWarningForEnablingBugfix() throws Exception { + runTest("compiler/testData/cli/jvm/internalArgNoWarningForEnablingBugfix.args"); + } + @TestMetadata("internalArgUnrecognizedFeature.args") public void testInternalArgUnrecognizedFeature() throws Exception { runTest("compiler/testData/cli/jvm/internalArgUnrecognizedFeature.args");