Support -Xexperimental and -Xuse-experimental, validate their values

#KT-22759 In Progress
This commit is contained in:
Alexander Udalov
2018-01-02 16:46:07 +01:00
parent 153c86c069
commit 77625831f7
29 changed files with 204 additions and 10 deletions
@@ -123,7 +123,7 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
value = "-Xlegacy-smart-cast-after-try",
description = "Allow var smart casts despite assignment in try block"
)
var legacySmartCastAfterTry by FreezableVar(false)
var legacySmartCastAfterTry: Boolean by FreezableVar(false)
@Argument(
value = "-Xeffect-system",
@@ -137,11 +137,27 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
)
var readDeserializedContracts: Boolean by FreezableVar(false)
@Argument(
value = "-Xexperimental",
valueDescription = "<fq.name>",
description = "Enable and propagate usages of experimental API for marker annotation with the given fully qualified name"
)
var experimental: Array<String>? by FreezableVar(null)
@Argument(
value = "-Xuse-experimental",
valueDescription = "<fq.name>",
description = "Enable usages of COMPILATION-affecting experimental API for marker annotation with the given fully qualified name"
)
var useExperimental: Array<String>? by FreezableVar(null)
open fun configureAnalysisFlags(collector: MessageCollector): MutableMap<AnalysisFlag<*>, Any> {
return HashMap<AnalysisFlag<*>, Any>().apply {
put(AnalysisFlag.skipMetadataVersionCheck, skipMetadataVersionCheck)
put(AnalysisFlag.multiPlatformDoNotCheckActual, noCheckActual)
put(AnalysisFlag.allowKotlinPackage, allowKotlinPackage)
put(AnalysisFlag.experimental, experimental?.toList().orEmpty())
put(AnalysisFlag.useExperimental, useExperimental?.toList().orEmpty())
}
}
@@ -22,6 +22,7 @@ import kotlin.reflect.KMutableProperty1
import kotlin.reflect.full.findAnnotation
import kotlin.reflect.full.memberProperties
@Target(AnnotationTarget.PROPERTY)
annotation class Argument(
val value: String,
val shortName: String = "",
@@ -23,6 +23,7 @@ import com.intellij.psi.util.PsiFormatUtil
import org.jetbrains.kotlin.analyzer.AnalysisResult
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.*
import org.jetbrains.kotlin.codegen.state.IncompatibleClassTrackerImpl
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.diagnostics.*
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils.sortedDiagnostics
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
@@ -33,12 +34,16 @@ import org.jetbrains.kotlin.resolve.AnalyzingUtils
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.checkers.ExperimentalUsageChecker
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
import org.jetbrains.kotlin.resolve.jvm.JvmBindingContextSlices
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData
class AnalyzerWithCompilerReport(private val messageCollector: MessageCollector) {
class AnalyzerWithCompilerReport(
private val messageCollector: MessageCollector,
private val languageVersionSettings: LanguageVersionSettings
) {
lateinit var analysisResult: AnalysisResult
private fun reportIncompleteHierarchies() {
@@ -94,6 +99,9 @@ class AnalyzerWithCompilerReport(private val messageCollector: MessageCollector)
fun analyzeAndReport(files: Collection<KtFile>, analyze: () -> AnalysisResult) {
analysisResult = analyze()
ExperimentalUsageChecker.checkCompilerArguments(analysisResult.moduleDescriptor, languageVersionSettings) { message ->
messageCollector.report(ERROR, message)
}
reportSyntaxErrors(files)
reportDiagnostics(analysisResult.bindingContext.diagnostics, messageCollector)
reportIncompleteHierarchies()
@@ -222,7 +222,9 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
return COMPILATION_ERROR;
}
AnalyzerWithCompilerReport analyzerWithCompilerReport = new AnalyzerWithCompilerReport(messageCollector);
AnalyzerWithCompilerReport analyzerWithCompilerReport = new AnalyzerWithCompilerReport(
messageCollector, CommonConfigurationKeysKt.getLanguageVersionSettings(configuration)
);
analyzerWithCompilerReport.analyzeAndReport(sourcesFiles, () -> TopDownAnalyzerFacadeForJS.analyzeFiles(sourcesFiles, config));
if (analyzerWithCompilerReport.hasErrors()) {
return COMPILATION_ERROR;
@@ -43,10 +43,7 @@ import org.jetbrains.kotlin.cli.jvm.config.*
import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.codegen.state.GenerationStateEventCallback
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.config.addKotlinSourceRoots
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
import org.jetbrains.kotlin.idea.MainFunctionDetector
import org.jetbrains.kotlin.javac.JavacWrapper
@@ -364,7 +361,7 @@ object KotlinToJVMBytecodeCompiler {
val collector = environment.messageCollector
val analysisStart = PerformanceCounter.currentTime()
val analyzerWithCompilerReport = AnalyzerWithCompilerReport(collector)
val analyzerWithCompilerReport = AnalyzerWithCompilerReport(collector, environment.configuration.languageVersionSettings)
analyzerWithCompilerReport.analyzeAndReport(sourceFiles) {
val project = environment.project
val moduleOutputs = environment.configuration.get(JVMConfigurationKeys.MODULES)?.mapNotNullTo(hashSetOf()) { module ->
@@ -62,7 +62,7 @@ open class MetadataSerializer(private val dependOnOldBuiltIns: Boolean) {
return
}
val analyzer = AnalyzerWithCompilerReport(messageCollector)
val analyzer = AnalyzerWithCompilerReport(messageCollector, configuration.languageVersionSettings)
analyzer.analyzeAndReport(files) {
CommonAnalyzerFacade.analyzeFiles(files, moduleName, dependOnOldBuiltIns, configuration.languageVersionSettings) { _, content ->
environment.createPackagePartProvider(content.moduleContentScope)