From 6636c4376beeaa5358682408eb82205ac9b45549 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Mon, 11 Sep 2017 15:30:37 +0300 Subject: [PATCH] as31: Kotlin Facet: Configure facet based on Android build variant (in AS) #KT-19958 Fixed --- .../KotlinAndroidModuleSetupStep.kt.as31 | 40 +++ ...droidModuleModelProjectDataService.kt.as31 | 3 +- .../KotlinGradleSourceSetDataService.kt.as31 | 49 ++- idea/src/META-INF/android.xml.as31 | 4 + .../kotlin/idea/facet/facetUtils.kt.as31 | 281 ++++++++++++++++++ 5 files changed, 363 insertions(+), 14 deletions(-) create mode 100644 idea/idea-android/src/org/jetbrains/kotlin/android/configure/KotlinAndroidModuleSetupStep.kt.as31 create mode 100644 idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt.as31 diff --git a/idea/idea-android/src/org/jetbrains/kotlin/android/configure/KotlinAndroidModuleSetupStep.kt.as31 b/idea/idea-android/src/org/jetbrains/kotlin/android/configure/KotlinAndroidModuleSetupStep.kt.as31 new file mode 100644 index 00000000000..b7b2f5caf11 --- /dev/null +++ b/idea/idea-android/src/org/jetbrains/kotlin/android/configure/KotlinAndroidModuleSetupStep.kt.as31 @@ -0,0 +1,40 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.android.configure + +import com.android.tools.idea.gradle.project.model.AndroidModuleModel +import com.android.tools.idea.gradle.project.sync.setup.post.ModuleSetupStep +import com.intellij.openapi.module.Module +import com.intellij.openapi.progress.ProgressIndicator +import org.jetbrains.android.facet.AndroidFacet +import org.jetbrains.kotlin.idea.configuration.compilerArgumentsBySourceSet +import org.jetbrains.kotlin.idea.configuration.configureFacetByCompilerArguments +import org.jetbrains.kotlin.idea.configuration.sourceSetName +import org.jetbrains.kotlin.idea.facet.KotlinFacet + +class KotlinAndroidModuleSetupStep : ModuleSetupStep() { + override fun setUpModule(module: Module, progressIndicator: ProgressIndicator?) { + val facet = AndroidFacet.getInstance(module) ?: return + val androidModel = AndroidModuleModel.get(facet) ?: return + val sourceSetName = androidModel.selectedVariant.name + if (module.sourceSetName == sourceSetName) return + val argsInfo = module.compilerArgumentsBySourceSet?.get(sourceSetName) ?: return + val kotlinFacet = KotlinFacet.get(module) ?: return + module.sourceSetName = sourceSetName + configureFacetByCompilerArguments(kotlinFacet, argsInfo, null) + } +} \ No newline at end of file diff --git a/idea/idea-android/src/org/jetbrains/kotlin/android/configure/KotlinGradleAndroidModuleModelProjectDataService.kt.as31 b/idea/idea-android/src/org/jetbrains/kotlin/android/configure/KotlinGradleAndroidModuleModelProjectDataService.kt.as31 index 6807f56fcb5..b060507a2eb 100644 --- a/idea/idea-android/src/org/jetbrains/kotlin/android/configure/KotlinGradleAndroidModuleModelProjectDataService.kt.as31 +++ b/idea/idea-android/src/org/jetbrains/kotlin/android/configure/KotlinGradleAndroidModuleModelProjectDataService.kt.as31 @@ -46,7 +46,8 @@ class KotlinGradleAndroidModuleModelProjectDataService : AbstractProjectDataServ val moduleNode = ExternalSystemApiUtil.findParent(moduleModelNode, ProjectKeys.MODULE) ?: continue val moduleData = moduleNode.data val ideModule = modelsProvider.findIdeModule(moduleData) ?: continue - val kotlinFacet = configureFacetByGradleModule(moduleNode, null, ideModule, modelsProvider) ?: continue + val sourceSetName = moduleModelNode.data.selectedVariant.name + val kotlinFacet = configureFacetByGradleModule(moduleNode, sourceSetName, ideModule, modelsProvider) ?: continue GradleProjectImportHandler.getInstances(project).forEach { it.importByModule(kotlinFacet, moduleNode) } } } diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleSourceSetDataService.kt.as31 b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleSourceSetDataService.kt.as31 index 2b4903540b1..1d4ad130467 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleSourceSetDataService.kt.as31 +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleSourceSetDataService.kt.as31 @@ -26,11 +26,13 @@ import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsPr import com.intellij.openapi.externalSystem.service.project.manage.AbstractProjectDataService import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil import com.intellij.openapi.module.Module +import com.intellij.openapi.module.isQualifiedModuleNamesEnabled import com.intellij.openapi.project.Project import com.intellij.openapi.roots.OrderRootType import com.intellij.openapi.roots.impl.libraries.LibraryEx import com.intellij.openapi.roots.impl.libraries.LibraryImpl import com.intellij.openapi.roots.libraries.PersistentLibraryKind +import com.intellij.openapi.util.Key import com.intellij.util.PathUtil import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments @@ -40,6 +42,8 @@ import org.jetbrains.kotlin.config.JvmTarget import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.TargetPlatformKind import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor +import org.jetbrains.kotlin.gradle.ArgsInfo +import org.jetbrains.kotlin.gradle.CompilerArgumentsBySourceSet import org.jetbrains.kotlin.idea.facet.* import org.jetbrains.kotlin.idea.framework.CommonLibraryKind import org.jetbrains.kotlin.idea.framework.JSLibraryKind @@ -47,11 +51,18 @@ import org.jetbrains.kotlin.idea.framework.detectLibraryKind import org.jetbrains.kotlin.idea.inspections.gradle.findAll import org.jetbrains.kotlin.idea.inspections.gradle.findKotlinPluginVersion import org.jetbrains.kotlin.idea.inspections.gradle.getResolvedKotlinStdlibVersionByModuleData +import org.jetbrains.kotlin.psi.UserDataProperty import org.jetbrains.plugins.gradle.model.data.BuildScriptClasspathData import org.jetbrains.plugins.gradle.model.data.GradleSourceSetData import java.io.File import java.util.* +var Module.compilerArgumentsBySourceSet + by UserDataProperty(Key.create("CURRENT_COMPILER_ARGUMENTS")) + +var Module.sourceSetName + by UserDataProperty(Key.create("SOURCE_SET_NAME")) + interface GradleProjectImportHandler { companion object : ProjectExtensionDescriptor( "org.jetbrains.kotlin.gradleProjectImportHandler", @@ -76,7 +87,8 @@ class KotlinGradleSourceSetDataService : AbstractProjectDataService): TargetPla fun configureFacetByGradleModule( moduleNode: DataNode, - sourceSetNode: DataNode?, + sourceSetName: String?, ideModule: Module, modelsProvider: IdeModifiableModelsProvider ): KotlinFacet? { @@ -200,23 +212,17 @@ fun configureFacetByGradleModule( val kotlinFacet = ideModule.getOrCreateFacet(modelsProvider, false) kotlinFacet.configureFacet(compilerVersion, coroutinesProperty, platformKind, modelsProvider) - val sourceSetName = sourceSetNode?.data?.id?.let { it.substring(it.lastIndexOf(':') + 1) } + ideModule.compilerArgumentsBySourceSet = moduleNode.compilerArgumentsBySourceSet + ideModule.sourceSetName = sourceSetName val argsInfo = moduleNode.compilerArgumentsBySourceSet?.get(sourceSetName ?: "main") if (argsInfo != null) { - val currentCompilerArguments = argsInfo.currentArguments - val defaultCompilerArguments = argsInfo.defaultArguments - val dependencyClasspath = argsInfo.dependencyClasspath.map { PathUtil.toSystemIndependentName(it) } - if (currentCompilerArguments.isNotEmpty()) { - parseCompilerArgumentsToFacet(currentCompilerArguments, defaultCompilerArguments, kotlinFacet, modelsProvider) - } - adjustClasspath(kotlinFacet, dependencyClasspath) + configureFacetByCompilerArguments(kotlinFacet, argsInfo, modelsProvider) } with(kotlinFacet.configuration.settings) { - implementedModuleNames = (sourceSetNode ?: moduleNode).implementedModuleNames - productionOutputPath = getExplicitOutputPath(moduleNode, platformKind, "main") - testOutputPath = getExplicitOutputPath(moduleNode, platformKind, "test") + implementedModuleNames = getImplementedModuleNames(moduleNode, sourceSetName, ideModule.project) + testOutputPath = getExplicitTestOutputPath(moduleNode, platformKind) } kotlinFacet.noVersionAutoAdvance() @@ -224,6 +230,23 @@ fun configureFacetByGradleModule( return kotlinFacet } +fun configureFacetByCompilerArguments(kotlinFacet: KotlinFacet, argsInfo: ArgsInfo, modelsProvider: IdeModifiableModelsProvider?) { + val currentCompilerArguments = argsInfo.currentArguments + val defaultCompilerArguments = argsInfo.defaultArguments + val dependencyClasspath = argsInfo.dependencyClasspath.map { PathUtil.toSystemIndependentName(it) } + if (currentCompilerArguments.isNotEmpty()) { + parseCompilerArgumentsToFacet(currentCompilerArguments, defaultCompilerArguments, kotlinFacet, modelsProvider) + } + adjustClasspath(kotlinFacet, dependencyClasspath) +} + +private fun getImplementedModuleNames(moduleNode: DataNode, sourceSetName: String?, project: Project): List { + val baseModuleNames = moduleNode.implementedModuleNames + if (baseModuleNames.isEmpty() || sourceSetName == null) return baseModuleNames + val delimiter = if(isQualifiedModuleNamesEnabled(project)) "." else "_" + return baseModuleNames.map { "$it$delimiter$sourceSetName" } +} + private fun getExplicitOutputPath(moduleNode: DataNode, platformKind: TargetPlatformKind<*>?, sourceSet: String): String? { if (platformKind !== TargetPlatformKind.JavaScript) return null val k2jsArgumentList = moduleNode.compilerArgumentsBySourceSet?.get(sourceSet)?.currentArguments ?: return null diff --git a/idea/src/META-INF/android.xml.as31 b/idea/src/META-INF/android.xml.as31 index 60f5a26d546..babdbcbcc4b 100644 --- a/idea/src/META-INF/android.xml.as31 +++ b/idea/src/META-INF/android.xml.as31 @@ -110,6 +110,10 @@ + + + + diff --git a/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt.as31 b/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt.as31 new file mode 100644 index 00000000000..81075c04e9b --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt.as31 @@ -0,0 +1,281 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.idea.facet + +import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider +import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProviderImpl +import com.intellij.openapi.module.Module +import com.intellij.openapi.project.Project +import com.intellij.openapi.projectRoots.JavaSdk +import com.intellij.openapi.projectRoots.JavaSdkVersion +import com.intellij.openapi.projectRoots.ProjectJdkTable +import com.intellij.openapi.roots.ModuleRootManager +import com.intellij.openapi.roots.ModuleRootModel +import com.intellij.openapi.roots.ProjectRootModificationTracker +import com.intellij.openapi.util.io.FileUtil +import com.intellij.openapi.util.text.StringUtil +import com.intellij.psi.util.CachedValueProvider +import org.jetbrains.kotlin.analyzer.ModuleInfo +import org.jetbrains.kotlin.caches.resolve.KotlinCacheService +import org.jetbrains.kotlin.cli.common.arguments.* +import org.jetbrains.kotlin.compilerRunner.ArgumentUtils +import org.jetbrains.kotlin.config.* +import org.jetbrains.kotlin.descriptors.ModuleDescriptor +import org.jetbrains.kotlin.idea.caches.project.* +import org.jetbrains.kotlin.idea.compiler.configuration.Kotlin2JsCompilerArgumentsHolder +import org.jetbrains.kotlin.idea.compiler.configuration.Kotlin2JvmCompilerArgumentsHolder +import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCommonCompilerArgumentsHolder +import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCompilerSettings +import org.jetbrains.kotlin.idea.framework.KotlinSdkType +import org.jetbrains.kotlin.idea.util.application.runWriteAction +import org.jetbrains.kotlin.idea.versions.* +import kotlin.reflect.KProperty1 + +private fun getDefaultTargetPlatform(module: Module, rootModel: ModuleRootModel?): TargetPlatformKind<*> { + for (platform in TargetPlatformKind.ALL_PLATFORMS) { + if (getRuntimeLibraryVersions(module, rootModel, platform).isNotEmpty()) { + return platform + } + } + + val sdk = ((rootModel ?: ModuleRootManager.getInstance(module))).sdk + val sdkVersion = (sdk?.sdkType as? JavaSdk)?.getVersion(sdk!!) + return when { + sdkVersion == null || sdkVersion >= JavaSdkVersion.JDK_1_8 -> TargetPlatformKind.Jvm[JvmTarget.JVM_1_8] + else -> TargetPlatformKind.Jvm[JvmTarget.JVM_1_6] + } +} + +fun KotlinFacetSettings.initializeIfNeeded( + module: Module, + rootModel: ModuleRootModel?, + platformKind: TargetPlatformKind<*>? = null, // if null, detect by module dependencies + languageVersion: String? = null +) { + val project = module.project + + val shouldInferLanguageLevel = languageLevel == null + val shouldInferAPILevel = apiLevel == null + + if (compilerSettings == null) { + compilerSettings = KotlinCompilerSettings.getInstance(project).settings + } + + val commonArguments = KotlinCommonCompilerArgumentsHolder.getInstance(module.project).settings + + if (compilerArguments == null) { + val targetPlatformKind = platformKind ?: getDefaultTargetPlatform(module, rootModel) + compilerArguments = targetPlatformKind.createCompilerArguments { + targetPlatformKind.getPlatformCompilerArgumentsByProject(module.project)?.let { mergeBeans(it, this) } + mergeBeans(commonArguments, this) + } + } + + if (shouldInferLanguageLevel) { + languageLevel = (if (useProjectSettings) LanguageVersion.fromVersionString(commonArguments.languageVersion) else null) + ?: getDefaultLanguageLevel(module, languageVersion) + } + + if (shouldInferAPILevel) { + apiLevel = if (useProjectSettings) { + LanguageVersion.fromVersionString(commonArguments.apiVersion) ?: languageLevel + } + else { + languageLevel!!.coerceAtMost(getLibraryLanguageLevel(module, rootModel, targetPlatformKind)) + } + } +} + +fun TargetPlatformKind<*>.getPlatformCompilerArgumentsByProject(project: Project): CommonCompilerArguments? { + return when (this) { + is TargetPlatformKind.Jvm -> Kotlin2JvmCompilerArgumentsHolder.getInstance(project).settings + is TargetPlatformKind.JavaScript -> Kotlin2JsCompilerArgumentsHolder.getInstance(project).settings + else -> null + } +} + +val TargetPlatformKind<*>.mavenLibraryIds: List + get() = when (this) { + is TargetPlatformKind.Jvm -> listOf(MAVEN_STDLIB_ID, MAVEN_STDLIB_ID_JRE7, MAVEN_STDLIB_ID_JDK7, MAVEN_STDLIB_ID_JRE8, MAVEN_STDLIB_ID_JDK8) + is TargetPlatformKind.JavaScript -> listOf(MAVEN_JS_STDLIB_ID, MAVEN_OLD_JS_STDLIB_ID) + is TargetPlatformKind.Common -> listOf(MAVEN_COMMON_STDLIB_ID) + } + +val mavenLibraryIdToPlatform: Map> by lazy { + TargetPlatformKind.ALL_PLATFORMS + .flatMap { platform -> platform.mavenLibraryIds.map { it to platform } } + .sortedByDescending { it.first.length } + .toMap() +} + +fun Module.getOrCreateFacet(modelsProvider: IdeModifiableModelsProvider, + useProjectSettings: Boolean, + commitModel: Boolean = false): KotlinFacet { + val facetModel = modelsProvider.getModifiableFacetModel(this) + + val facet = facetModel.findFacet(KotlinFacetType.TYPE_ID, KotlinFacetType.INSTANCE.defaultFacetName) + ?: with(KotlinFacetType.INSTANCE) { createFacet(this@getOrCreateFacet, defaultFacetName, createDefaultConfiguration(), null) } + .apply { facetModel.addFacet(this) } + facet.configuration.settings.useProjectSettings = useProjectSettings + if (commitModel) { + runWriteAction { + facetModel.commit() + } + } + return facet +} + +fun KotlinFacet.configureFacet( + compilerVersion: String, + coroutineSupport: LanguageFeature.State, + platformKind: TargetPlatformKind<*>?, // if null, detect by module dependencies + modelsProvider: IdeModifiableModelsProvider +) { + val module = module + with(configuration.settings) { + compilerArguments = null + compilerSettings = null + initializeIfNeeded( + module, + modelsProvider.getModifiableRootModel(module), + platformKind, + compilerVersion + ) + val apiLevel = apiLevel + val languageLevel = languageLevel + if (languageLevel != null && apiLevel != null && apiLevel > languageLevel) { + this.apiLevel = languageLevel + } + this.coroutineSupport = coroutineSupport + } +} + +fun KotlinFacet.noVersionAutoAdvance() { + configuration.settings.compilerArguments?.let { + it.autoAdvanceLanguageVersion = false + it.autoAdvanceApiVersion = false + } +} + +// "Primary" fields are written to argument beans directly and thus not presented in the "additional arguments" string +// Update these lists when facet/project settings UI changes +val commonUIExposedFields = listOf(CommonCompilerArguments::languageVersion.name, + CommonCompilerArguments::apiVersion.name, + CommonCompilerArguments::suppressWarnings.name, + CommonCompilerArguments::coroutinesState.name) +private val commonUIHiddenFields = listOf(CommonCompilerArguments::pluginClasspaths.name, + CommonCompilerArguments::pluginOptions.name) +private val commonPrimaryFields = commonUIExposedFields + commonUIHiddenFields + +private val jvmSpecificUIExposedFields = listOf(K2JVMCompilerArguments::jvmTarget.name, + K2JVMCompilerArguments::destination.name, + K2JVMCompilerArguments::classpath.name) +val jvmUIExposedFields = commonUIExposedFields + jvmSpecificUIExposedFields +private val jvmPrimaryFields = commonPrimaryFields + jvmSpecificUIExposedFields + +private val jsSpecificUIExposedFields = listOf(K2JSCompilerArguments::sourceMap.name, + K2JSCompilerArguments::sourceMapPrefix.name, + K2JSCompilerArguments::sourceMapEmbedSources.name, + K2JSCompilerArguments::outputPrefix.name, + K2JSCompilerArguments::outputPostfix.name, + K2JSCompilerArguments::moduleKind.name) +val jsUIExposedFields = commonUIExposedFields + jsSpecificUIExposedFields +private val jsPrimaryFields = commonPrimaryFields + jsSpecificUIExposedFields + +private val metadataSpecificUIExposedFields = listOf(K2MetadataCompilerArguments::destination.name, + K2MetadataCompilerArguments::classpath.name) +val metadataUIExposedFields = commonUIExposedFields + metadataSpecificUIExposedFields +private val metadataPrimaryFields = commonPrimaryFields + metadataSpecificUIExposedFields + +private val CommonCompilerArguments.primaryFields: List + get() = when (this) { + is K2JVMCompilerArguments -> jvmPrimaryFields + is K2JSCompilerArguments -> jsPrimaryFields + is K2MetadataCompilerArguments -> metadataPrimaryFields + else -> commonPrimaryFields + } + +private val CommonCompilerArguments.ignoredFields: List + get() = when (this) { + is K2JVMCompilerArguments -> listOf(K2JVMCompilerArguments::noJdk.name, K2JVMCompilerArguments::jdkHome.name) + else -> emptyList() + } + +private fun Module.configureSdkIfPossible(compilerArguments: CommonCompilerArguments, modelsProvider: IdeModifiableModelsProvider) { + val allSdks = ProjectJdkTable.getInstance().allJdks + val sdk = if (compilerArguments is K2JVMCompilerArguments) { + val jdkHome = compilerArguments.jdkHome ?: return + allSdks.firstOrNull { it.sdkType is JavaSdk && FileUtil.comparePaths(it.homePath, jdkHome) == 0 } ?: return + } else { + allSdks.firstOrNull { it.sdkType is KotlinSdkType } ?: KotlinSdkType.INSTANCE.createSdkWithUniqueName(allSdks.toList()) + } + + modelsProvider.getModifiableRootModel(this).sdk = sdk +} + +fun parseCompilerArgumentsToFacet( + arguments: List, + defaultArguments: List, + kotlinFacet: KotlinFacet, + modelsProvider: IdeModifiableModelsProvider? +) { + with(kotlinFacet.configuration.settings) { + val compilerArguments = this.compilerArguments ?: return + + val defaultCompilerArguments = compilerArguments::class.java.newInstance() + parseCommandLineArguments(defaultArguments, defaultCompilerArguments) + defaultCompilerArguments.convertPathsToSystemIndependent() + + parseCommandLineArguments(arguments, compilerArguments) + + compilerArguments.convertPathsToSystemIndependent() + + // Retain only fields exposed (and not explicitly ignored) in facet configuration editor. + // The rest is combined into string and stored in CompilerSettings.additionalArguments + + kotlinFacet.module.configureSdkIfPossible(compilerArguments, modelsProvider) + + val primaryFields = compilerArguments.primaryFields + val ignoredFields = compilerArguments.ignoredFields + + fun exposeAsAdditionalArgument(property: KProperty1) = + property.name !in primaryFields && property.get(compilerArguments) != property.get(defaultCompilerArguments) + + val additionalArgumentsString = with(compilerArguments::class.java.newInstance()) { + copyFieldsSatisfying(compilerArguments, this) { exposeAsAdditionalArgument(it) && it.name !in ignoredFields } + ArgumentUtils.convertArgumentsToStringList(this).joinToString(separator = " ") { + if (StringUtil.containsWhitespaces(it) || it.startsWith('"')) { + StringUtil.wrapWithDoubleQuote(StringUtil.escapeQuotes(it)) + } else it + } + } + compilerSettings?.additionalArguments = + if (additionalArgumentsString.isNotEmpty()) additionalArgumentsString else CompilerSettings.DEFAULT_ADDITIONAL_ARGUMENTS + + with(compilerArguments::class.java.newInstance()) { + copyFieldsSatisfying(this, compilerArguments) { exposeAsAdditionalArgument(it) || it.name in ignoredFields } + } + + val languageLevel = languageLevel + val apiLevel = apiLevel + if (languageLevel != null && apiLevel != null && apiLevel > languageLevel) { + this.apiLevel = languageLevel + } + + updateMergedArguments() + } +}