Implement diagnostics for ignored compiler arguments on script compilation

This commit is contained in:
Ilya Chernikov
2019-01-23 16:33:30 +01:00
parent 7ee9801c5f
commit 95d782b6ca
4 changed files with 127 additions and 24 deletions
@@ -13,6 +13,7 @@ import com.intellij.psi.impl.PsiFileFactoryImpl
import com.intellij.testFramework.LightVirtualFile
import org.jetbrains.kotlin.analyzer.AnalysisResult
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.arguments.Argument
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.parseCommandLineArguments
import org.jetbrains.kotlin.cli.common.environment.setIdeaIoUseFallback
@@ -41,7 +42,9 @@ import org.jetbrains.kotlin.script.KotlinScriptDefinition
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
import java.util.*
import kotlin.reflect.KClass
import kotlin.reflect.KMutableProperty1
import kotlin.reflect.KType
import kotlin.reflect.full.findAnnotation
import kotlin.reflect.full.starProjectedType
import kotlin.script.dependencies.ScriptContents
import kotlin.script.experimental.api.*
@@ -66,6 +69,7 @@ class KJvmCompilerImpl(val hostConfiguration: ScriptingHostConfiguration) : KJvm
scriptCompilationConfiguration: ScriptCompilationConfiguration
): ResultWithDiagnostics<CompiledScript<*>> {
val messageCollector = ScriptDiagnosticsMessageCollector()
val reportingState = ReportingState()
fun failure(vararg diagnostics: ScriptDiagnostic): ResultWithDiagnostics.Failure =
ResultWithDiagnostics.Failure(*messageCollector.diagnostics.toTypedArray(), *diagnostics)
@@ -80,7 +84,8 @@ class KJvmCompilerImpl(val hostConfiguration: ScriptingHostConfiguration) : KJvm
// TODO: refactor/cleanup when the internal resolving API will allow easier info passing between resolver and compiler
val kotlinCompilerConfiguration = createInitialCompilerConfiguration(scriptCompilationConfiguration, messageCollector)
val kotlinCompilerConfiguration =
createInitialCompilerConfiguration(scriptCompilationConfiguration, messageCollector, reportingState)
val initialScriptCompilationConfiguration =
scriptCompilationConfiguration.withUpdatesFromCompilerConfiguration(kotlinCompilerConfiguration)
@@ -113,7 +118,7 @@ class KJvmCompilerImpl(val hostConfiguration: ScriptingHostConfiguration) : KJvm
// collectScriptsCompilationDependencies calls resolver for every file, so at this point all updated configurations are collected
environment.configuration.updateWithRefinedConfigurations(
initialScriptCompilationConfiguration, sourcesWithRefinementsState.refinedConfigurations
initialScriptCompilationConfiguration, sourcesWithRefinementsState.refinedConfigurations, messageCollector, reportingState
)
val analysisResult = analyze(sourceFiles, environment)
@@ -142,6 +147,10 @@ class KJvmCompilerImpl(val hostConfiguration: ScriptingHostConfiguration) : KJvm
val refinedConfigurations = hashMapOf<SourceCode, ScriptCompilationConfiguration>()
}
private class ReportingState {
var currentArguments = K2JVMCompilerArguments()
}
private fun makeScriptDefinition(
scriptCompilationConfiguration: ScriptCompilationConfiguration,
mainScript: SourceCode,
@@ -174,7 +183,8 @@ class KJvmCompilerImpl(val hostConfiguration: ScriptingHostConfiguration) : KJvm
private fun createInitialCompilerConfiguration(
scriptCompilationConfiguration: ScriptCompilationConfiguration,
messageCollector: MessageCollector
messageCollector: MessageCollector,
reportingState: ReportingState
): CompilerConfiguration {
val baseArguments = K2JVMCompilerArguments()
@@ -183,6 +193,9 @@ class KJvmCompilerImpl(val hostConfiguration: ScriptingHostConfiguration) : KJvm
baseArguments
)
reportArgumentsIgnoredGenerally(baseArguments, messageCollector, reportingState)
reportingState.currentArguments = baseArguments
return org.jetbrains.kotlin.config.CompilerConfiguration().apply {
// default value differs from the argument'ss default (see #KT-29405 and #KT-29319)
@@ -260,7 +273,9 @@ class KJvmCompilerImpl(val hostConfiguration: ScriptingHostConfiguration) : KJvm
private fun CompilerConfiguration.updateWithRefinedConfigurations(
initialScriptCompilationConfiguration: ScriptCompilationConfiguration,
refinedScriptCompilationConfigurations: HashMap<SourceCode, ScriptCompilationConfiguration>
refinedScriptCompilationConfigurations: HashMap<SourceCode, ScriptCompilationConfiguration>,
messageCollector: ScriptDiagnosticsMessageCollector,
reportingState: ReportingState
) {
val updatedCompilerOptions = refinedScriptCompilationConfigurations.flatMap {
it.value[ScriptCompilationConfiguration.compilerOptions] ?: emptyList()
@@ -272,13 +287,14 @@ class KJvmCompilerImpl(val hostConfiguration: ScriptingHostConfiguration) : KJvm
val updatedArguments = K2JVMCompilerArguments()
parseCommandLineArguments(updatedCompilerOptions, updatedArguments)
reportArgumentsIgnoredGenerally(updatedArguments, messageCollector, reportingState)
reportArgumentsIgnoredFromRefinement(updatedArguments, messageCollector, reportingState)
setupCommonArguments(updatedArguments)
setupJvmSpecificArguments(updatedArguments)
configureAdvancedJvmOptions(updatedArguments)
// TODO: report warnings for all ignored options
}
}
@@ -357,6 +373,70 @@ class KJvmCompilerImpl(val hostConfiguration: ScriptingHostConfiguration) : KJvm
KJvmCompiledModule(generationState)
)
}
private fun reportArgumentsIgnoredGenerally(
arguments: K2JVMCompilerArguments,
messageCollector: MessageCollector,
reportingState: ReportingState
) {
reportIgnoredArguments(
arguments,
"The following compiler arguments are ignored on script compilation: ",
messageCollector,
reportingState,
K2JVMCompilerArguments::version,
K2JVMCompilerArguments::destination,
K2JVMCompilerArguments::buildFile,
K2JVMCompilerArguments::commonSources,
K2JVMCompilerArguments::allWarningsAsErrors,
K2JVMCompilerArguments::script,
K2JVMCompilerArguments::scriptTemplates,
K2JVMCompilerArguments::scriptResolverEnvironment,
K2JVMCompilerArguments::disableStandardScript,
K2JVMCompilerArguments::disableDefaultScriptingPlugin,
K2JVMCompilerArguments::pluginClasspaths,
K2JVMCompilerArguments::pluginOptions,
K2JVMCompilerArguments::useJavac,
K2JVMCompilerArguments::compileJava,
K2JVMCompilerArguments::reportPerf,
K2JVMCompilerArguments::dumpPerf
)
}
private fun reportArgumentsIgnoredFromRefinement(
arguments: K2JVMCompilerArguments, messageCollector: MessageCollector, reportingState: ReportingState
) {
reportIgnoredArguments(
arguments,
"The following compiler arguments are ignored when configured from refinement callbacks: ",
messageCollector,
reportingState,
K2JVMCompilerArguments::noJdk,
K2JVMCompilerArguments::jdkHome,
K2JVMCompilerArguments::javaModulePath,
K2JVMCompilerArguments::classpath,
K2JVMCompilerArguments::noStdlib,
K2JVMCompilerArguments::noReflect
)
}
private fun reportIgnoredArguments(
arguments: K2JVMCompilerArguments, message: String,
messageCollector: MessageCollector, reportingState: ReportingState,
vararg toIgnore: KMutableProperty1<K2JVMCompilerArguments, *>
) {
val ignoredArgKeys = toIgnore.mapNotNull { argProperty ->
if (argProperty.get(arguments) != argProperty.get(reportingState.currentArguments)) {
argProperty.findAnnotation<Argument>()?.value
?: throw IllegalStateException("unknown compiler argument property: $argProperty: no Argument annotation found")
} else null
}
if (ignoredArgKeys.isNotEmpty()) {
messageCollector.report(CompilerMessageSeverity.STRONG_WARNING, "$message${ignoredArgKeys.joinToString(", ")}")
}
}
}
}