Do not report warning if -XXLanguage turns on bugfix
KT-25554 Fixed
This commit is contained in:
committed by
Dmitry Savvinov
parent
e42017a468
commit
6dacd1011f
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.compilerRunner;
|
package org.jetbrains.kotlin.compilerRunner;
|
||||||
|
|
||||||
import com.intellij.util.containers.ContainerUtil;
|
import com.intellij.util.containers.ContainerUtil;
|
||||||
|
import kotlin.collections.CollectionsKt;
|
||||||
import kotlin.jvm.JvmClassMappingKt;
|
import kotlin.jvm.JvmClassMappingKt;
|
||||||
import kotlin.reflect.KClass;
|
import kotlin.reflect.KClass;
|
||||||
import kotlin.reflect.KProperty1;
|
import kotlin.reflect.KProperty1;
|
||||||
@@ -26,6 +27,7 @@ import kotlin.reflect.jvm.ReflectJvmMapping;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.Argument;
|
import org.jetbrains.kotlin.cli.common.arguments.Argument;
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments;
|
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.cli.common.arguments.ParseCommandLineArgumentsKt;
|
||||||
import org.jetbrains.kotlin.utils.StringsKt;
|
import org.jetbrains.kotlin.utils.StringsKt;
|
||||||
|
|
||||||
@@ -46,7 +48,7 @@ public class ArgumentUtils {
|
|||||||
Class<? extends CommonToolArguments> argumentsClass = arguments.getClass();
|
Class<? extends CommonToolArguments> argumentsClass = arguments.getClass();
|
||||||
convertArgumentsToStringList(arguments, argumentsClass.newInstance(), JvmClassMappingKt.getKotlinClass(argumentsClass), result);
|
convertArgumentsToStringList(arguments, argumentsClass.newInstance(), JvmClassMappingKt.getKotlinClass(argumentsClass), result);
|
||||||
result.addAll(arguments.getFreeArgs());
|
result.addAll(arguments.getFreeArgs());
|
||||||
result.addAll(arguments.getInternalArguments());
|
result.addAll(CollectionsKt.map(arguments.getInternalArguments(), InternalArgument::getStringRepresentation));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-3
@@ -245,11 +245,9 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun HashMap<LanguageFeature, LanguageFeature.State>.configureLanguageFeaturesFromInternalArgs(collector: MessageCollector) {
|
private fun HashMap<LanguageFeature, LanguageFeature.State>.configureLanguageFeaturesFromInternalArgs(collector: MessageCollector) {
|
||||||
val languageSettingsParser = LanguageSettingsParser()
|
|
||||||
val featuresThatForcePreReleaseBinaries = mutableListOf<LanguageFeature>()
|
val featuresThatForcePreReleaseBinaries = mutableListOf<LanguageFeature>()
|
||||||
|
|
||||||
for (argument in internalArguments) {
|
for ((feature, state) in internalArguments.filterIsInstance<ManualLanguageFeatureSetting>()) {
|
||||||
val (feature, state) = languageSettingsParser.parseInternalArgument(argument, collector) ?: continue
|
|
||||||
put(feature, state)
|
put(feature, state)
|
||||||
if (state == LanguageFeature.State.ENABLED && feature.forcesPreReleaseBinariesIfEnabled()) {
|
if (state == LanguageFeature.State.ENABLED && feature.forcesPreReleaseBinariesIfEnabled()) {
|
||||||
featuresThatForcePreReleaseBinaries += feature
|
featuresThatForcePreReleaseBinaries += feature
|
||||||
|
|||||||
+1
-1
@@ -50,5 +50,5 @@ abstract class CommonToolArguments : Freezable(), Serializable {
|
|||||||
@Argument(value = "-Werror", description = "Report an error if there are any warnings")
|
@Argument(value = "-Werror", description = "Report an error if there are any warnings")
|
||||||
var allWarningsAsErrors: Boolean by FreezableVar(false)
|
var allWarningsAsErrors: Boolean by FreezableVar(false)
|
||||||
|
|
||||||
var internalArguments: List<String> by FreezableVar(emptyList())
|
var internalArguments: List<InternalArgument> by FreezableVar(emptyList())
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-12
@@ -6,8 +6,6 @@
|
|||||||
package org.jetbrains.kotlin.cli.common.arguments
|
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.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
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -25,7 +23,7 @@ interface InternalArgumentParser<A : InternalArgument> {
|
|||||||
// Should be fast
|
// Should be fast
|
||||||
fun canParse(arg: String): Boolean
|
fun canParse(arg: String): Boolean
|
||||||
|
|
||||||
fun parseInternalArgument(arg: String, messageCollector: MessageCollector): A?
|
fun parseInternalArgument(arg: String, errors: ArgumentParseErrors): A?
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
internal const val INTERNAL_ARGUMENT_PREFIX = "-XX"
|
internal const val INTERNAL_ARGUMENT_PREFIX = "-XX"
|
||||||
@@ -41,13 +39,13 @@ abstract class AbstractInternalArgumentParser<A : InternalArgument>(familyName:
|
|||||||
|
|
||||||
override fun canParse(arg: String): Boolean = arg.startsWith(wholePrefix)
|
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
|
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<A : InternalArgument>(familyName:
|
|||||||
class LanguageSettingsParser : AbstractInternalArgumentParser<ManualLanguageFeatureSetting>("Language") {
|
class LanguageSettingsParser : AbstractInternalArgumentParser<ManualLanguageFeatureSetting>("Language") {
|
||||||
|
|
||||||
// Expected tail form: ':(+|-)<language feature name>'
|
// Expected tail form: ':(+|-)<language feature name>'
|
||||||
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? {
|
fun reportAndReturnNull(message: String): Nothing? {
|
||||||
messageCollector.report(CompilerMessageSeverity.STRONG_WARNING, message)
|
errors.internalArgumentsParsingProblems += message
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,12 +74,18 @@ class LanguageSettingsParser : AbstractInternalArgumentParser<ManualLanguageFeat
|
|||||||
if (languageFeatureName.isEmpty()) return reportAndReturnNull("Empty language feature name for internal argument '$wholeArgument'")
|
if (languageFeatureName.isEmpty()) return reportAndReturnNull("Empty language feature name for internal argument '$wholeArgument'")
|
||||||
|
|
||||||
val languageFeature = LanguageFeature.fromString(languageFeatureName)
|
val languageFeature = LanguageFeature.fromString(languageFeatureName)
|
||||||
?: return reportAndReturnNull("Unknown language feature '$languageFeatureName' in passed internal argument '$wholeArgument'")
|
?: return reportAndReturnNull("Unknown language feature '$languageFeatureName' in passed internal argument '$wholeArgument'")
|
||||||
|
|
||||||
return ManualLanguageFeatureSetting(languageFeature, languageFeatureState)
|
return ManualLanguageFeatureSetting(languageFeature, languageFeatureState, wholeArgument)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface InternalArgument
|
interface InternalArgument {
|
||||||
|
val stringRepresentation: String
|
||||||
|
}
|
||||||
|
|
||||||
data class ManualLanguageFeatureSetting(val languageFeature: LanguageFeature, val state: LanguageFeature.State) : InternalArgument
|
data class ManualLanguageFeatureSetting(
|
||||||
|
val languageFeature: LanguageFeature,
|
||||||
|
val state: LanguageFeature.State,
|
||||||
|
override val stringRepresentation: String
|
||||||
|
) : InternalArgument
|
||||||
+6
-3
@@ -54,7 +54,10 @@ data class ArgumentParseErrors(
|
|||||||
|
|
||||||
var argumentWithoutValue: String? = null,
|
var argumentWithoutValue: String? = null,
|
||||||
|
|
||||||
val argfileErrors: MutableList<String> = SmartList()
|
val argfileErrors: MutableList<String> = SmartList(),
|
||||||
|
|
||||||
|
// Reports from internal arguments parsers
|
||||||
|
val internalArgumentsParsingProblems: MutableList<String> = SmartList()
|
||||||
)
|
)
|
||||||
|
|
||||||
// Parses arguments into the passed [result] object. Errors related to the parsing will be collected into [CommonToolArguments.errors].
|
// Parses arguments into the passed [result] object. Errors related to the parsing will be collected into [CommonToolArguments.errors].
|
||||||
@@ -108,7 +111,7 @@ private fun <A : CommonToolArguments> parsePreprocessedCommandLineArguments(args
|
|||||||
}
|
}
|
||||||
|
|
||||||
val freeArgs = ArrayList<String>()
|
val freeArgs = ArrayList<String>()
|
||||||
val internalArguments = ArrayList<String>()
|
val internalArguments = ArrayList<InternalArgument>()
|
||||||
|
|
||||||
var i = 0
|
var i = 0
|
||||||
loop@ while (i < args.size) {
|
loop@ while (i < args.size) {
|
||||||
@@ -132,7 +135,7 @@ private fun <A : CommonToolArguments> parsePreprocessedCommandLineArguments(args
|
|||||||
if (parser == null) {
|
if (parser == null) {
|
||||||
errors.unknownExtraFlags += arg
|
errors.unknownExtraFlags += arg
|
||||||
} else {
|
} else {
|
||||||
internalArguments.add(arg)
|
internalArguments.add(parser.parseInternalArgument(arg, errors) ?: continue)
|
||||||
}
|
}
|
||||||
|
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -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.common.messages.CompilerMessageSeverity.STRONG_WARNING
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.CompileEnvironmentException
|
import org.jetbrains.kotlin.cli.jvm.compiler.CompileEnvironmentException
|
||||||
import org.jetbrains.kotlin.config.KotlinCompilerVersion
|
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 org.jetbrains.kotlin.config.Services
|
||||||
import java.io.PrintStream
|
import java.io.PrintStream
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
@@ -129,20 +132,38 @@ abstract class CLITool<A : CommonToolArguments> {
|
|||||||
for ((deprecatedName, newName) in errors.deprecatedArguments) {
|
for ((deprecatedName, newName) in errors.deprecatedArguments) {
|
||||||
collector.report(STRONG_WARNING, "Argument $deprecatedName is deprecated. Please use $newName instead")
|
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(
|
collector.report(
|
||||||
STRONG_WARNING,
|
STRONG_WARNING,
|
||||||
"ATTENTION!\n" +
|
"ATTENTION!\n" +
|
||||||
"This build uses internal compiler arguments:\n" +
|
"This build uses unsafe internal compiler arguments:\n" +
|
||||||
arguments.internalArguments.joinToString(prefix = "\n", postfix = "\n\n", separator = "\n") +
|
unsafeArgumentsString +
|
||||||
"This mode is not recommended for production use,\n" +
|
"This mode is not recommended for production use,\n" +
|
||||||
"as no stability/compatibility guarantees are given on\n" +
|
"as no stability/compatibility guarantees are given on\n" +
|
||||||
"compiler or generated code. Use it at your own risk!\n"
|
"compiler or generated code. Use it at your own risk!\n"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
for (argfileError in errors.argfileErrors) {
|
|
||||||
collector.report(STRONG_WARNING, argfileError)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <A : CommonToolArguments> printVersionIfNeeded(messageCollector: MessageCollector, arguments: A) {
|
private fun <A : CommonToolArguments> printVersionIfNeeded(messageCollector: MessageCollector, arguments: A) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
warning: ATTENTION!
|
warning: ATTENTION!
|
||||||
This build uses internal compiler arguments:
|
This build uses unsafe internal compiler arguments:
|
||||||
|
|
||||||
-XXLanguage:-SoundSmartCastsAfterTry
|
-XXLanguage:-SoundSmartCastsAfterTry
|
||||||
|
|
||||||
|
|||||||
@@ -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:+'
|
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?
|
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
|
some.length
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
warning: ATTENTION!
|
warning: ATTENTION!
|
||||||
This build uses internal compiler arguments:
|
This build uses unsafe internal compiler arguments:
|
||||||
|
|
||||||
-XXLanguage:+SoundSmartCastsAfterTry
|
-XXLanguage:+SoundSmartCastsAfterTry
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
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?
|
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
|
some.length
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
$TESTDATA_DIR$/simple.kt
|
||||||
|
-d
|
||||||
|
$TEMP_DIR$
|
||||||
|
-language-version
|
||||||
|
1.2
|
||||||
|
-XXLanguage:+ProhibitDataClassesOverridingCopy
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
OK
|
||||||
@@ -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'
|
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?
|
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
|
some.length
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
warning: ATTENTION!
|
warning: ATTENTION!
|
||||||
This build uses internal compiler arguments:
|
This build uses unsafe internal compiler arguments:
|
||||||
|
|
||||||
-XXLanguage:+SoundSmartCastsAfterTry
|
-XXLanguage:+SoundSmartCastsAfterTry
|
||||||
|
|
||||||
|
|||||||
@@ -261,6 +261,11 @@ public class CliTestGenerated extends AbstractCliTest {
|
|||||||
runTest("compiler/testData/cli/jvm/internalArgMissingModificator.args");
|
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")
|
@TestMetadata("internalArgUnrecognizedFeature.args")
|
||||||
public void testInternalArgUnrecognizedFeature() throws Exception {
|
public void testInternalArgUnrecognizedFeature() throws Exception {
|
||||||
runTest("compiler/testData/cli/jvm/internalArgUnrecognizedFeature.args");
|
runTest("compiler/testData/cli/jvm/internalArgUnrecognizedFeature.args");
|
||||||
|
|||||||
Reference in New Issue
Block a user