Fix jvmTarget default divergence between KGP & IDE after change to 1.8

This commit is contained in:
Yaroslav Chernyshev
2021-03-01 11:02:20 +03:00
parent 43d9c6cc90
commit 634c8522a1
4 changed files with 84 additions and 11 deletions
@@ -29,21 +29,43 @@ 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.idea.ExplicitDefaultSubstitutor;
import org.jetbrains.kotlin.idea.ExplicitDefaultSubstitutorsKt;
import org.jetbrains.kotlin.utils.StringsKt;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.*;
public class ArgumentUtils {
private ArgumentUtils() {}
private ArgumentUtils() {
}
@NotNull
public static List<String> convertArgumentsToStringList(@NotNull CommonToolArguments arguments)
throws InstantiationException, IllegalAccessException, InvocationTargetException {
List<String> convertedArguments = convertArgumentsToStringListInternal(arguments);
Map<KClass<? extends CommonToolArguments>, Collection<ExplicitDefaultSubstitutor>> defaultSubstitutorsMap =
ExplicitDefaultSubstitutorsKt.getDefaultSubstitutors();
KClass<? extends CommonToolArguments> argumentsKClass = JvmClassMappingKt.getKotlinClass(arguments.getClass());
Collection<ExplicitDefaultSubstitutor> defaultSubstitutors = defaultSubstitutorsMap.get(argumentsKClass);
if (defaultSubstitutors != null) {
for (ExplicitDefaultSubstitutor substitutor : defaultSubstitutors) {
if (substitutor.isSubstitutable(convertedArguments)) convertedArguments.addAll(substitutor.getNewSubstitution());
}
}
return convertedArguments;
}
@NotNull
public static List<String> convertArgumentsToStringListNoDefaults(@NotNull CommonToolArguments arguments)
throws InstantiationException, IllegalAccessException, InvocationTargetException {
return convertArgumentsToStringListInternal(arguments);
}
private static List<String> convertArgumentsToStringListInternal(@NotNull CommonToolArguments arguments)
throws InstantiationException, IllegalAccessException, InvocationTargetException {
List<String> result = new ArrayList<>();
Class<? extends CommonToolArguments> argumentsClass = arguments.getClass();
convertArgumentsToStringList(arguments, argumentsClass.newInstance(), JvmClassMappingKt.getKotlinClass(argumentsClass), result);
@@ -0,0 +1,46 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea
import org.jetbrains.kotlin.cli.common.arguments.Argument
import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.config.JvmTarget
import kotlin.reflect.KClass
import kotlin.reflect.KProperty1
import kotlin.reflect.full.findAnnotation
val defaultSubstitutors: Map<KClass<out CommonToolArguments>, Collection<ExplicitDefaultSubstitutor>> =
mapOf(K2JVMCompilerArguments::class to listOf(JvmTargetDefaultSubstitutor))
sealed class ExplicitDefaultSubstitutor {
abstract val substitutedProperty: KProperty1<out CommonToolArguments, String?>
abstract val oldSubstitution: List<String>
abstract val newSubstitution: List<String>
abstract fun isSubstitutable(args: List<String>): Boolean
protected val argument: Argument by lazy {
substitutedProperty.findAnnotation() ?: error("Property \"${substitutedProperty.name}\" has no Argument annotation")
}
}
object JvmTargetDefaultSubstitutor : ExplicitDefaultSubstitutor() {
override val substitutedProperty
get() = K2JVMCompilerArguments::jvmTarget
private val oldDefault: String
get() = JvmTarget.JVM_1_6.description
private val newDefault: String
get() = JvmTarget.JVM_1_8.description
private fun prepareSubstitution(default: String): List<String> = listOf(argument.value, default)
override val oldSubstitution: List<String>
get() = prepareSubstitution(oldDefault)
override val newSubstitution: List<String>
get() = prepareSubstitution(newDefault)
override fun isSubstitutable(args: List<String>): Boolean = argument.value !in args
}
@@ -104,7 +104,7 @@ class GradleFacetImportTest : GradleImportingTestCase() {
Assert.assertFalse(compilerArguments!!.autoAdvanceLanguageVersion)
Assert.assertFalse(compilerArguments!!.autoAdvanceApiVersion)
Assert.assertEquals(JvmPlatforms.jvm16, targetPlatform)
Assert.assertEquals("1.8", (compilerArguments as K2JVMCompilerArguments).jvmTarget)
Assert.assertEquals("1.6", (compilerArguments as K2JVMCompilerArguments).jvmTarget)
Assert.assertEquals(
"-Xallow-no-source-files -Xdump-declarations-to=tmpTest",
compilerSettings!!.additionalArguments
@@ -158,7 +158,7 @@ class GradleFacetImportTest : GradleImportingTestCase() {
Assert.assertEquals("1.3", languageLevel!!.versionString)
Assert.assertEquals("1.0", apiLevel!!.versionString)
Assert.assertEquals(JvmPlatforms.jvm16, targetPlatform)
Assert.assertEquals("1.8", (compilerArguments as K2JVMCompilerArguments).jvmTarget)
Assert.assertEquals("1.6", (compilerArguments as K2JVMCompilerArguments).jvmTarget)
Assert.assertEquals(
"-Xallow-no-source-files -Xdump-declarations-to=tmpTest",
compilerSettings!!.additionalArguments
@@ -27,10 +27,10 @@ import org.jetbrains.kotlin.idea.configuration.externalCompilerVersion
import org.jetbrains.kotlin.idea.core.isAndroidModule
import org.jetbrains.kotlin.idea.framework.KotlinSdkType
import org.jetbrains.kotlin.idea.platform.tooling
import org.jetbrains.kotlin.idea.defaultSubstitutors
import org.jetbrains.kotlin.idea.util.application.runWriteAction
import org.jetbrains.kotlin.idea.util.getProjectJdkTableSafe
import org.jetbrains.kotlin.platform.*
import org.jetbrains.kotlin.platform.compat.toNewPlatform
import org.jetbrains.kotlin.platform.impl.JvmIdePlatformKind
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.psi.NotNullableUserDataProperty
@@ -298,6 +298,9 @@ private fun Module.configureSdkIfPossible(compilerArguments: CommonCompilerArgum
private fun Module.hasNonOverriddenExternalSdkConfiguration(compilerArguments: CommonCompilerArguments): Boolean =
hasExternalSdkConfiguration && (compilerArguments !is K2JVMCompilerArguments || compilerArguments.jdkHome == null)
private fun substituteDefaults(args: List<String>, compilerArguments: CommonCompilerArguments): List<String> =
args + defaultSubstitutors[compilerArguments::class]?.filter { it.isSubstitutable(args) }?.flatMap { it.oldSubstitution }.orEmpty()
fun parseCompilerArgumentsToFacet(
arguments: List<String>,
defaultArguments: List<String>,
@@ -307,8 +310,10 @@ fun parseCompilerArgumentsToFacet(
val compilerArgumentsClass = kotlinFacet.configuration.settings.compilerArguments?.javaClass ?: return
val currentArgumentsBean = compilerArgumentsClass.newInstance()
val defaultArgumentsBean = compilerArgumentsClass.newInstance()
parseCommandLineArguments(defaultArguments, defaultArgumentsBean)
parseCommandLineArguments(arguments, currentArgumentsBean)
val defaultArgumentWithDefaults = substituteDefaults(defaultArguments, defaultArgumentsBean)
val currentArgumentWithDefaults = substituteDefaults(arguments, currentArgumentsBean)
parseCommandLineArguments(defaultArgumentWithDefaults, defaultArgumentsBean)
parseCommandLineArguments(currentArgumentWithDefaults, currentArgumentsBean)
applyCompilerArgumentsToFacet(currentArgumentsBean, defaultArgumentsBean, kotlinFacet, modelsProvider)
}
@@ -352,7 +357,7 @@ fun applyCompilerArgumentsToFacet(
val additionalArgumentsString = with(compilerArguments::class.java.newInstance()) {
copyFieldsSatisfying(compilerArguments, this) { exposeAsAdditionalArgument(it) && it.name !in ignoredFields }
ArgumentUtils.convertArgumentsToStringList(this).joinToString(separator = " ") {
ArgumentUtils.convertArgumentsToStringListNoDefaults(this).joinToString(separator = " ") {
if (StringUtil.containsWhitespaces(it) || it.startsWith('"')) {
StringUtil.wrapWithDoubleQuote(StringUtil.escapeQuotes(it))
} else it