diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/facet/KotlinVersionInfoProvider.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/facet/KotlinVersionInfoProvider.kt index 53313d27428..a971b24a39c 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/facet/KotlinVersionInfoProvider.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/facet/KotlinVersionInfoProvider.kt @@ -54,7 +54,7 @@ fun getLibraryLanguageLevel( rootModel: ModuleRootModel?, targetPlatform: TargetPlatformKind<*>? ): LanguageVersion { - val minVersion = getRuntimeLibraryVersions(module, rootModel, targetPlatform ?: TargetPlatformKind.Jvm[JvmTarget.JVM_1_8]) + val minVersion = getRuntimeLibraryVersions(module, rootModel, targetPlatform ?: TargetPlatformKind.DEFAULT_PLATFORM) .minWith(VersionComparatorUtil.COMPARATOR) return getDefaultLanguageLevel(module, minVersion) } @@ -75,7 +75,7 @@ fun getDefaultLanguageLevel( } fun getRuntimeLibraryVersion(module: Module): String? { - val targetPlatform = KotlinFacetSettingsProvider.getInstance(module.project).getSettings(module).versionInfo.targetPlatformKind - val versions = getRuntimeLibraryVersions(module, null, targetPlatform ?: TargetPlatformKind.Jvm[JvmTarget.JVM_1_8]) + val targetPlatform = KotlinFacetSettingsProvider.getInstance(module.project).getSettings(module).targetPlatformKind + val versions = getRuntimeLibraryVersions(module, null, targetPlatform ?: TargetPlatformKind.DEFAULT_PLATFORM) return versions.toSet().singleOrNull() } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/Platform.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/Platform.kt index c9782c7d347..641a7714403 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/Platform.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/Platform.kt @@ -47,7 +47,7 @@ fun Module.getAndCacheLanguageLevelByDependencies(): LanguageVersion { val languageLevel = getLibraryLanguageLevel( this, null, - KotlinFacetSettingsProvider.getInstance(project).getSettings(this).versionInfo.targetPlatformKind + KotlinFacetSettingsProvider.getInstance(project).getSettings(this).targetPlatformKind ) // Preserve inferred version in facet/project settings @@ -63,7 +63,7 @@ fun Module.getAndCacheLanguageLevelByDependencies(): LanguageVersion { } } else { - with(facetSettings.versionInfo) { + with(facetSettings) { if (this.languageLevel == null) { this.languageLevel = languageLevel } @@ -101,14 +101,13 @@ val Module.languageVersionSettings: LanguageVersionSettings get() { val facetSettings = KotlinFacetSettingsProvider.getInstance(project).getSettings(this) if (facetSettings.useProjectSettings) return project.getLanguageVersionSettings(this) - val versionInfo = facetSettings.versionInfo - val languageVersion = versionInfo.languageLevel ?: getAndCacheLanguageLevelByDependencies() - val apiVersion = versionInfo.apiLevel ?: languageVersion + val languageVersion = facetSettings.languageLevel ?: getAndCacheLanguageLevelByDependencies() + val apiVersion = facetSettings.apiLevel ?: languageVersion val extraLanguageFeatures = getExtraLanguageFeatures( - versionInfo.targetPlatformKind ?: TargetPlatformKind.Common, - facetSettings.compilerInfo.coroutineSupport, - facetSettings.compilerInfo.compilerSettings, + facetSettings.targetPlatformKind ?: TargetPlatformKind.Common, + facetSettings.coroutineSupport, + facetSettings.compilerSettings, this ) @@ -116,7 +115,7 @@ val Module.languageVersionSettings: LanguageVersionSettings } val Module.targetPlatform: TargetPlatformKind<*>? - get() = KotlinFacetSettingsProvider.getInstance(project).getSettings(this).versionInfo.targetPlatformKind + get() = KotlinFacetSettingsProvider.getInstance(project).getSettings(this).targetPlatformKind private val Module.implementsCommonModule: Boolean get() = targetPlatform != TargetPlatformKind.Common diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/ProjectStructureUtil.java b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/ProjectStructureUtil.java index 38648709a1c..6003110ebdb 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/ProjectStructureUtil.java +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/ProjectStructureUtil.java @@ -68,7 +68,7 @@ public class ProjectStructureUtil { @Nullable private static TargetPlatform getPlatformConfiguredInFacet(@NotNull Module module) { KotlinFacetSettings settings = KotlinFacetSettingsProvider.Companion.getInstance(module.getProject()).getSettings(module); - TargetPlatformKind kind = settings.getVersionInfo().getTargetPlatformKind(); + TargetPlatformKind kind = settings.getTargetPlatformKind(); if (kind instanceof TargetPlatformKind.Jvm) { return JvmPlatform.INSTANCE; } diff --git a/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinFacetSettings.kt b/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinFacetSettings.kt index 974af76d7c8..8dafa4c77e5 100644 --- a/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinFacetSettings.kt +++ b/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinFacetSettings.kt @@ -19,11 +19,10 @@ package org.jetbrains.kotlin.config import com.intellij.openapi.components.ServiceManager import com.intellij.openapi.module.Module import com.intellij.openapi.project.Project -import com.intellij.util.xmlb.annotations.Property -import com.intellij.util.xmlb.annotations.Transient import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments +import org.jetbrains.kotlin.cli.common.arguments.K2MetadataCompilerArguments import org.jetbrains.kotlin.utils.DescriptionAware sealed class TargetPlatformKind( @@ -45,24 +44,12 @@ sealed class TargetPlatformKind( object Common : TargetPlatformKind(DescriptionAware.NoVersion, "Common (experimental)") companion object { - val ALL_PLATFORMS: List> by lazy { Jvm.JVM_PLATFORMS + JavaScript + Common } + val DEFAULT_PLATFORM: TargetPlatformKind<*> + get() = Jvm[JvmTarget.DEFAULT] } } -data class KotlinVersionInfo( - var languageLevel: LanguageVersion? = null, - var apiLevel: LanguageVersion? = null, - @get:Transient var targetPlatformKind: TargetPlatformKind<*>? = null -) { - // To be serialized - var targetPlatformName: String - get() = targetPlatformKind?.description ?: "" - set(value) { - targetPlatformKind = TargetPlatformKind.ALL_PLATFORMS.firstOrNull { it.description == value } - } -} - enum class CoroutineSupport( override val description: String, val compilerArgument: String @@ -90,38 +77,62 @@ enum class CoroutineSupport( } } -class KotlinCompilerInfo { - // To be serialized - @Property private var _commonCompilerArguments: CommonCompilerArguments.DummyImpl? = null - @get:Transient var commonCompilerArguments: CommonCompilerArguments? - get() = _commonCompilerArguments - set(value) { - _commonCompilerArguments = value as? CommonCompilerArguments.DummyImpl - } - var k2jsCompilerArguments: K2JSCompilerArguments? = null - var k2jvmCompilerArguments: K2JVMCompilerArguments? = null - var compilerSettings: CompilerSettings? = null - - @get:Transient var coroutineSupport: CoroutineSupport - get() = CoroutineSupport.byCompilerArguments(commonCompilerArguments) - set(value) { - commonCompilerArguments?.coroutinesEnable = value == CoroutineSupport.ENABLED - commonCompilerArguments?.coroutinesWarn = value == CoroutineSupport.ENABLED_WITH_WARNING - commonCompilerArguments?.coroutinesError = value == CoroutineSupport.DISABLED - } -} - class KotlinFacetSettings { companion object { // Increment this when making serialization-incompatible changes to configuration data - val CURRENT_VERSION = 1 + val CURRENT_VERSION = 2 val DEFAULT_VERSION = 0 } var useProjectSettings: Boolean = true - var versionInfo = KotlinVersionInfo() - var compilerInfo = KotlinCompilerInfo() + var compilerArguments: CommonCompilerArguments? = null + var compilerSettings: CompilerSettings? = null + + var languageLevel: LanguageVersion? + get() = compilerArguments?.languageVersion?.let { LanguageVersion.fromFullVersionString(it) } + set(value) { + compilerArguments!!.languageVersion = value?.versionString + } + + var apiLevel: LanguageVersion? + get() = compilerArguments?.apiVersion?.let { LanguageVersion.fromFullVersionString(it) } + set(value) { + compilerArguments!!.apiVersion = value?.versionString + } + + val targetPlatformKind: TargetPlatformKind<*>? + get() = compilerArguments?.let { + when (it) { + is K2JVMCompilerArguments -> { + val jvmTarget = it.jvmTarget ?: JvmTarget.DEFAULT.description + TargetPlatformKind.Jvm.JVM_PLATFORMS.firstOrNull { it.version.description >= jvmTarget } + } + is K2JSCompilerArguments -> TargetPlatformKind.JavaScript + is K2MetadataCompilerArguments -> TargetPlatformKind.Common + else -> null + } + } + + var coroutineSupport: CoroutineSupport + get() = CoroutineSupport.byCompilerArguments(compilerArguments) + set(value) { + with(compilerArguments!!) { + coroutinesEnable = value == CoroutineSupport.ENABLED + coroutinesWarn = value == CoroutineSupport.ENABLED_WITH_WARNING + coroutinesError = value == CoroutineSupport.DISABLED + } + } +} + +fun TargetPlatformKind<*>.createCompilerArguments(): CommonCompilerArguments { + return when (this) { + is TargetPlatformKind.Jvm -> { + K2JVMCompilerArguments().apply { jvmTarget = this@createCompilerArguments.version.description } + } + is TargetPlatformKind.JavaScript -> K2JSCompilerArguments() + is TargetPlatformKind.Common -> K2MetadataCompilerArguments() + } } interface KotlinFacetSettingsProvider { diff --git a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/KotlinMavenImporter.kt b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/KotlinMavenImporter.kt index 915b26facc3..d3fde34a61f 100644 --- a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/KotlinMavenImporter.kt +++ b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/KotlinMavenImporter.kt @@ -150,7 +150,7 @@ class KotlinMavenImporter : MavenImporter(KOTLIN_PLUGIN_GROUP_ID, KOTLIN_PLUGIN_ val platform = detectPlatformByExecutions(mavenProject) ?: detectPlatformByLibraries(mavenProject) kotlinFacet.configureFacet(compilerVersion, CoroutineSupport.DEFAULT, platform, modifiableModelsProvider) - val configuredPlatform = kotlinFacet.configuration.settings.versionInfo.targetPlatformKind!! + val configuredPlatform = kotlinFacet.configuration.settings.targetPlatformKind!! val configuration = mavenPlugin.configurationElement val sharedArguments = configuration?.let { getCompilerArgumentsByConfigurationElement(it, configuredPlatform) } ?: emptyList() val executionArguments = mavenPlugin.executions?.filter { it.goals.any { it in compilationGoals } } diff --git a/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/KotlinMavenImporterTest.kt b/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/KotlinMavenImporterTest.kt index 383e3ecd3c5..482e4674aa6 100644 --- a/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/KotlinMavenImporterTest.kt +++ b/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/KotlinMavenImporterTest.kt @@ -16,6 +16,8 @@ package org.jetbrains.kotlin.idea.maven +import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments +import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments import org.jetbrains.kotlin.config.KotlinFacetSettings import org.jetbrains.kotlin.config.TargetPlatformKind import org.jetbrains.kotlin.idea.facet.KotlinFacet @@ -442,16 +444,16 @@ class KotlinMavenImporterTest : MavenImportingTestCase() { assertImporterStatePresent() with (facetSettings) { - Assert.assertEquals("1.1", versionInfo.languageLevel!!.versionString) - Assert.assertEquals("1.1", compilerInfo.commonCompilerArguments!!.languageVersion) - Assert.assertEquals("1.0", versionInfo.apiLevel!!.versionString) - Assert.assertEquals("1.0", compilerInfo.commonCompilerArguments!!.apiVersion) - Assert.assertEquals(true, compilerInfo.commonCompilerArguments!!.suppressWarnings) - Assert.assertEquals("enable", compilerInfo.coroutineSupport.compilerArgument) - Assert.assertEquals("JVM 1.8", versionInfo.targetPlatformKind!!.description) - Assert.assertEquals("1.8", compilerInfo.k2jvmCompilerArguments!!.jvmTarget) + Assert.assertEquals("1.1", languageLevel!!.versionString) + Assert.assertEquals("1.1", compilerArguments!!.languageVersion) + Assert.assertEquals("1.0", apiLevel!!.versionString) + Assert.assertEquals("1.0", compilerArguments!!.apiVersion) + Assert.assertEquals(true, compilerArguments!!.suppressWarnings) + Assert.assertEquals("enable", coroutineSupport.compilerArgument) + Assert.assertEquals("JVM 1.8", targetPlatformKind!!.description) + Assert.assertEquals("1.8", (compilerArguments as K2JVMCompilerArguments).jvmTarget) Assert.assertEquals("-cp foobar.jar -jdk-home JDK_HOME -Xmulti-platform", - compilerInfo.compilerSettings!!.additionalArguments) + compilerSettings!!.additionalArguments) } } @@ -510,17 +512,19 @@ class KotlinMavenImporterTest : MavenImportingTestCase() { assertImporterStatePresent() with (facetSettings) { - Assert.assertEquals("1.1", versionInfo.languageLevel!!.versionString) - Assert.assertEquals("1.1", compilerInfo.commonCompilerArguments!!.languageVersion) - Assert.assertEquals("1.0", versionInfo.apiLevel!!.versionString) - Assert.assertEquals("1.0", compilerInfo.commonCompilerArguments!!.apiVersion) - Assert.assertEquals(true, compilerInfo.commonCompilerArguments!!.suppressWarnings) - Assert.assertEquals("enable", compilerInfo.coroutineSupport.compilerArgument) - Assert.assertTrue(versionInfo.targetPlatformKind is TargetPlatformKind.JavaScript) - Assert.assertEquals(true, compilerInfo.k2jsCompilerArguments!!.sourceMap) - Assert.assertEquals("commonjs", compilerInfo.k2jsCompilerArguments!!.moduleKind) + Assert.assertEquals("1.1", languageLevel!!.versionString) + Assert.assertEquals("1.1", compilerArguments!!.languageVersion) + Assert.assertEquals("1.0", apiLevel!!.versionString) + Assert.assertEquals("1.0", compilerArguments!!.apiVersion) + Assert.assertEquals(true, compilerArguments!!.suppressWarnings) + Assert.assertEquals("enable", coroutineSupport.compilerArgument) + Assert.assertTrue(targetPlatformKind is TargetPlatformKind.JavaScript) + with(compilerArguments as K2JSCompilerArguments) { + Assert.assertEquals(true, sourceMap) + Assert.assertEquals("commonjs", moduleKind) + } Assert.assertEquals("-output test.js -meta-info -Xmulti-platform", - compilerInfo.compilerSettings!!.additionalArguments) + compilerSettings!!.additionalArguments) } } @@ -580,16 +584,16 @@ class KotlinMavenImporterTest : MavenImportingTestCase() { assertImporterStatePresent() with (facetSettings) { - Assert.assertEquals("1.1", versionInfo.languageLevel!!.versionString) - Assert.assertEquals("1.1", compilerInfo.commonCompilerArguments!!.languageVersion) - Assert.assertEquals("1.0", versionInfo.apiLevel!!.versionString) - Assert.assertEquals("1.0", compilerInfo.commonCompilerArguments!!.apiVersion) - Assert.assertEquals(true, compilerInfo.commonCompilerArguments!!.suppressWarnings) - Assert.assertEquals("enable", compilerInfo.coroutineSupport.compilerArgument) - Assert.assertEquals("JVM 1.8", versionInfo.targetPlatformKind!!.description) - Assert.assertEquals("1.8", compilerInfo.k2jvmCompilerArguments!!.jvmTarget) + Assert.assertEquals("1.1", languageLevel!!.versionString) + Assert.assertEquals("1.1", compilerArguments!!.languageVersion) + Assert.assertEquals("1.0", apiLevel!!.versionString) + Assert.assertEquals("1.0", compilerArguments!!.apiVersion) + Assert.assertEquals(true, compilerArguments!!.suppressWarnings) + Assert.assertEquals("enable", coroutineSupport.compilerArgument) + Assert.assertEquals("JVM 1.8", targetPlatformKind!!.description) + Assert.assertEquals("1.8", (compilerArguments as K2JVMCompilerArguments).jvmTarget) Assert.assertEquals("-cp foobar.jar -jdk-home JDK_HOME -Xmulti-platform", - compilerInfo.compilerSettings!!.additionalArguments) + compilerSettings!!.additionalArguments) } } @@ -642,9 +646,9 @@ class KotlinMavenImporterTest : MavenImportingTestCase() { assertImporterStatePresent() with (facetSettings) { - Assert.assertEquals("JVM 1.8", versionInfo.targetPlatformKind!!.description) - Assert.assertEquals("1.8", compilerInfo.k2jvmCompilerArguments!!.jvmTarget) - Assert.assertEquals("enable", compilerInfo.coroutineSupport.compilerArgument) + Assert.assertEquals("JVM 1.8", targetPlatformKind!!.description) + Assert.assertEquals("1.8", (compilerArguments as K2JVMCompilerArguments).jvmTarget) + Assert.assertEquals("enable", coroutineSupport.compilerArgument) } } diff --git a/idea/idea-test-framework/src/org/jetbrains/kotlin/idea/test/KotlinProjectDescriptorWithFacet.kt b/idea/idea-test-framework/src/org/jetbrains/kotlin/idea/test/KotlinProjectDescriptorWithFacet.kt index 70de5ca8a4a..55155cf5ac4 100644 --- a/idea/idea-test-framework/src/org/jetbrains/kotlin/idea/test/KotlinProjectDescriptorWithFacet.kt +++ b/idea/idea-test-framework/src/org/jetbrains/kotlin/idea/test/KotlinProjectDescriptorWithFacet.kt @@ -24,13 +24,14 @@ import org.jetbrains.kotlin.config.LanguageVersion import org.jetbrains.kotlin.idea.facet.KotlinFacet import org.jetbrains.kotlin.idea.facet.KotlinFacetConfiguration import org.jetbrains.kotlin.idea.facet.KotlinFacetType +import org.jetbrains.kotlin.idea.facet.initializeIfNeeded import org.jetbrains.kotlin.test.testFramework.runInEdtAndWait import org.jetbrains.kotlin.test.testFramework.runWriteAction class KotlinProjectDescriptorWithFacet(val languageVersion: LanguageVersion) : KotlinLightProjectDescriptor() { override fun configureModule(module: Module, model: ModifiableRootModel, contentEntry: ContentEntry) { configureKotlinFacet(module) { -> - settings.versionInfo.languageLevel = languageVersion + settings.languageLevel = languageVersion } } @@ -43,6 +44,7 @@ fun configureKotlinFacet(module: Module, configureCallback: KotlinFacetConfigura val facetManager = FacetManager.getInstance(module) val facetModel = facetManager.createModifiableModel() val configuration = KotlinFacetConfiguration() + configuration.settings.initializeIfNeeded(module, null) configuration.settings.useProjectSettings = false configuration.configureCallback() val facet = facetManager.createFacet(KotlinFacetType.INSTANCE, "Kotlin", configuration, null) diff --git a/idea/src/org/jetbrains/kotlin/idea/compiler/configuration/KotlinCompilerConfigurableTab.java b/idea/src/org/jetbrains/kotlin/idea/compiler/configuration/KotlinCompilerConfigurableTab.java index 878d6652ab9..b508b8488d5 100644 --- a/idea/src/org/jetbrains/kotlin/idea/compiler/configuration/KotlinCompilerConfigurableTab.java +++ b/idea/src/org/jetbrains/kotlin/idea/compiler/configuration/KotlinCompilerConfigurableTab.java @@ -110,11 +110,10 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable, Co public KotlinCompilerConfigurableTab( Project project, - CommonCompilerArguments commonCompilerArguments, - K2JSCompilerArguments k2jsCompilerArguments, - CompilerSettings compilerSettings, + @NotNull CommonCompilerArguments commonCompilerArguments, + @NotNull K2JSCompilerArguments k2jsCompilerArguments, + @NotNull K2JVMCompilerArguments k2jvmCompilerArguments, CompilerSettings compilerSettings, @Nullable KotlinCompilerWorkspaceSettings compilerWorkspaceSettings, - @Nullable K2JVMCompilerArguments k2jvmCompilerArguments, boolean isProjectSettings, boolean isMultiEditor ) { @@ -174,9 +173,9 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable, Co this(project, KotlinCommonCompilerArgumentsHolder.getInstance(project).getSettings(), Kotlin2JsCompilerArgumentsHolder.getInstance(project).getSettings(), + Kotlin2JvmCompilerArgumentsHolder.getInstance(project).getSettings(), KotlinCompilerSettings.getInstance(project).getSettings(), ServiceManager.getService(project, KotlinCompilerWorkspaceSettings.class), - Kotlin2JvmCompilerArgumentsHolder.getInstance(project).getSettings(), true, false); } @@ -323,7 +322,8 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable, Co isModified(outputPrefixFile, k2jsCompilerArguments.outputPrefix) || isModified(outputPostfixFile, k2jsCompilerArguments.outputPostfix) || !getSelectedModuleKind().equals(getModuleKindOrDefault(k2jsCompilerArguments.moduleKind)) || - (k2jvmCompilerArguments != null && !getSelectedJvmVersion().equals(getJvmVersionOrDefault(k2jvmCompilerArguments.jvmTarget))); + + !getSelectedJvmVersion().equals(getJvmVersionOrDefault(k2jvmCompilerArguments.jvmTarget)); } @NotNull @@ -395,9 +395,7 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable, Co k2jsCompilerArguments.outputPostfix = StringUtil.nullize(outputPostfixFile.getText(), true); k2jsCompilerArguments.moduleKind = getSelectedModuleKind(); - if (k2jvmCompilerArguments != null) { - k2jvmCompilerArguments.jvmTarget = getSelectedJvmVersion(); - } + k2jvmCompilerArguments.jvmTarget = getSelectedJvmVersion(); BuildManager.getInstance().clearState(project); } @@ -426,9 +424,7 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable, Co moduleKindComboBox.setSelectedItem(getModuleKindOrDefault(k2jsCompilerArguments.moduleKind)); - if (k2jvmCompilerArguments != null) { - jvmVersionComboBox.setSelectedItem(getJvmVersionOrDefault(k2jvmCompilerArguments.jvmTarget)); - } + jvmVersionComboBox.setSelectedItem(getJvmVersionOrDefault(k2jvmCompilerArguments.jvmTarget)); } @Override @@ -511,4 +507,12 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable, Co isEnabled = value; UIUtil.setEnabled(getContentPane(), value, true); } + + public K2JSCompilerArguments getK2jsCompilerArguments() { + return k2jsCompilerArguments; + } + + public K2JVMCompilerArguments getK2jvmCompilerArguments() { + return k2jvmCompilerArguments; + } } diff --git a/idea/src/org/jetbrains/kotlin/idea/facet/KotlinFacetConfiguration.kt b/idea/src/org/jetbrains/kotlin/idea/facet/KotlinFacetConfiguration.kt index 20f95d604de..7840e15c076 100644 --- a/idea/src/org/jetbrains/kotlin/idea/facet/KotlinFacetConfiguration.kt +++ b/idea/src/org/jetbrains/kotlin/idea/facet/KotlinFacetConfiguration.kt @@ -24,12 +24,77 @@ import com.intellij.util.xmlb.SkipDefaultsSerializationFilter import com.intellij.util.xmlb.XmlSerializer import org.jdom.DataConversionException import org.jdom.Element -import org.jetbrains.kotlin.config.KotlinFacetSettings +import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments +import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments +import org.jetbrains.kotlin.config.* class KotlinFacetConfiguration : FacetConfiguration { var settings = KotlinFacetSettings() private set + private fun Element.getOption(name: String) = getChildren("option").firstOrNull { it.getAttribute("name").value == name } + + private fun Element.getOptionValue(name: String) = getOption(name)?.getAttribute("value")?.value + + private fun Element.getOptionBody(name: String) = getOption(name)?.children?.firstOrNull() + + private fun readV1Config(element: Element) { + val useProjectSettings = element.getOptionValue("useProjectSettings")?.toBoolean() + + val targetPlatformName = element.getOptionBody("versionInfo")?.getOptionValue("targetPlatformName") + val targetPlatform = TargetPlatformKind.ALL_PLATFORMS.firstOrNull { it.description == targetPlatformName } + ?: TargetPlatformKind.Jvm.get(JvmTarget.DEFAULT) + + val compilerInfoElement = element.getOptionBody("compilerInfo") + + val compilerSettings = CompilerSettings().apply { + compilerInfoElement?.getOptionBody("compilerSettings")?.let { compilerSettingsElement -> + XmlSerializer.deserializeInto(this, compilerSettingsElement) + } + } + + val commonArgumentsElement = compilerInfoElement?.getOptionBody("_commonCompilerArguments") + val jvmArgumentsElement = compilerInfoElement?.getOptionBody("k2jvmCompilerArguments") + val jsArgumentsElement = compilerInfoElement?.getOptionBody("k2jsCompilerArguments") + + val compilerArguments = targetPlatform.createCompilerArguments() + + commonArgumentsElement?.let { XmlSerializer.deserializeInto(compilerArguments, it) } + when (compilerArguments) { + is K2JVMCompilerArguments -> jvmArgumentsElement?.let { XmlSerializer.deserializeInto(compilerArguments, it) } + is K2JSCompilerArguments -> jsArgumentsElement?.let { XmlSerializer.deserializeInto(compilerArguments, it) } + } + + if (useProjectSettings != null) { + settings.useProjectSettings = useProjectSettings + } + else { + // Migration problem workaround for pre-1.1-beta releases (mainly 1.0.6) -> 1.1-rc+ + // Problematic cases: 1.1-beta/1.1-beta2 -> 1.1-rc+ (useProjectSettings gets reset to false) + // This heuristic detects old enough configurations: + if (jvmArgumentsElement == null) { + settings.useProjectSettings = false + } + } + + settings.compilerSettings = compilerSettings + settings.compilerArguments = compilerArguments + } + + private fun readV2Config(element: Element) { + element.getAttributeValue("useProjectSettings")?.let { settings.useProjectSettings = it.toBoolean() } + val platformName = element.getAttributeValue("platform") + val platformKind = TargetPlatformKind.ALL_PLATFORMS.firstOrNull { it.description == platformName } ?: TargetPlatformKind.DEFAULT_PLATFORM + element.getChild("compilerSettings")?.let { + settings.compilerSettings = CompilerSettings() + XmlSerializer.deserializeInto(settings.compilerSettings!!, it) + } + element.getChild("compilerArguments")?.let { + settings.compilerArguments = platformKind.createCompilerArguments() + XmlSerializer.deserializeInto(settings.compilerArguments!!, it) + } + } + @Suppress("OverridingDeprecatedMember") override fun readExternal(element: Element) { val version = @@ -39,27 +104,36 @@ class KotlinFacetConfiguration : FacetConfiguration { catch(e: DataConversionException) { null } ?: KotlinFacetSettings.DEFAULT_VERSION - // Reset facet configuration if versions don't match - if (version == KotlinFacetSettings.CURRENT_VERSION) { - XmlSerializer.deserializeInto(settings, element) - } - else { - settings = KotlinFacetSettings() - } - - // Migration problem workaround for pre-1.1-beta releases (mainly 1.0.6) -> 1.1-rc+ - // Problematic cases: 1.1-beta/1.1-beta2 -> 1.1-rc+ (useProjectSettings gets reset to false) - // This heuristic detects old enough configurations: - if (element.children.none { it.getAttribute("name").value == "useProjectSettings" } - && settings.compilerInfo.k2jvmCompilerArguments == null) { - settings.useProjectSettings = false + when (version) { + 1 -> readV1Config(element) + 2 -> readV2Config(element) + else -> settings = KotlinFacetSettings() // Reset facet configuration if versions don't match } } @Suppress("OverridingDeprecatedMember") override fun writeExternal(element: Element) { + val filter = SkipDefaultsSerializationFilter() + element.setAttribute("version", KotlinFacetSettings.CURRENT_VERSION.toString()) - XmlSerializer.serializeInto(settings, element, SkipDefaultsSerializationFilter()) + settings.targetPlatformKind?.let { + element.setAttribute("platform", it.description) + } + if (!settings.useProjectSettings) { + element.setAttribute("useProjectSettings", settings.useProjectSettings.toString()) + } + settings.compilerSettings?.let { + Element("compilerSettings").apply { + XmlSerializer.serializeInto(it, this, filter) + element.addContent(this) + } + } + settings.compilerArguments?.let { + Element("compilerArguments").apply { + XmlSerializer.serializeInto(it, this, filter) + element.addContent(this) + } + } } override fun createEditorTabs( diff --git a/idea/src/org/jetbrains/kotlin/idea/facet/KotlinFacetEditorGeneralTab.kt b/idea/src/org/jetbrains/kotlin/idea/facet/KotlinFacetEditorGeneralTab.kt index 3a479a60373..d3cbc5f6595 100644 --- a/idea/src/org/jetbrains/kotlin/idea/facet/KotlinFacetEditorGeneralTab.kt +++ b/idea/src/org/jetbrains/kotlin/idea/facet/KotlinFacetEditorGeneralTab.kt @@ -23,11 +23,10 @@ import com.intellij.openapi.project.Project import com.intellij.ui.DocumentAdapter import com.intellij.util.ui.FormBuilder import com.intellij.util.ui.ThreeStateCheckBox -import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments -import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments -import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments -import org.jetbrains.kotlin.cli.common.arguments.parseArguments +import org.jetbrains.kotlin.cli.common.arguments.* import org.jetbrains.kotlin.config.* +import org.jetbrains.kotlin.idea.compiler.configuration.Kotlin2JsCompilerArgumentsHolder +import org.jetbrains.kotlin.idea.compiler.configuration.Kotlin2JvmCompilerArgumentsHolder import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCompilerConfigurableTab import java.awt.BorderLayout import javax.swing.JComboBox @@ -46,25 +45,36 @@ class KotlinFacetEditorGeneralTab( ) : JPanel(BorderLayout()) { private val isMultiEditor = configuration == null - private val compilerInfo = configuration?.settings?.compilerInfo - ?: KotlinCompilerInfo() - .apply { - commonCompilerArguments = object : CommonCompilerArguments() {} - k2jsCompilerArguments = K2JSCompilerArguments() - k2jvmCompilerArguments = K2JVMCompilerArguments() - compilerSettings = CompilerSettings() - } - val compilerConfigurable = with(compilerInfo) { - KotlinCompilerConfigurableTab( - project, - commonCompilerArguments, - k2jsCompilerArguments, - compilerSettings, - null, - k2jvmCompilerArguments, - false, - isMultiEditor - ) + val compilerConfigurable = with(configuration?.settings) { + if (isMultiEditor) { + KotlinCompilerConfigurableTab( + project, + object : CommonCompilerArguments() {}, + K2JSCompilerArguments(), + K2JVMCompilerArguments(), + CompilerSettings(), + null, + false, + true + ) + } + else { + val compilerArguments = configuration!!.settings.compilerArguments!! + val k2jvmCompilerArguments = compilerArguments as? K2JVMCompilerArguments + ?: copyBean(Kotlin2JvmCompilerArgumentsHolder.getInstance(project).settings) + val k2jsCompilerArguments = compilerArguments as? K2JSCompilerArguments + ?: copyBean(Kotlin2JsCompilerArgumentsHolder.getInstance(project).settings) + KotlinCompilerConfigurableTab( + project, + compilerArguments, + k2jsCompilerArguments, + k2jvmCompilerArguments, + configuration.settings.compilerSettings!!, + null, + false, + false + ) + } } val useProjectSettingsCheckBox = ThreeStateCheckBox("Use project settings").apply { isThirdStateEnabled = isMultiEditor } @@ -90,14 +100,6 @@ class KotlinFacetEditorGeneralTab( targetPlatformComboBox.addActionListener { updateCompilerConfigurable() } - - val commonCompilerArguments = compilerInfo.commonCompilerArguments - if (configuration != null && commonCompilerArguments != null) { - with(configuration.settings.versionInfo) { - commonCompilerArguments.languageVersion = languageLevel?.versionString - commonCompilerArguments.apiVersion = apiLevel?.versionString - } - } } internal fun updateCompilerConfigurable() { @@ -128,7 +130,7 @@ class KotlinFacetEditorGeneralTab( override fun check(): ValidationResult { val selectedOption = editor.compilerConfigurable.coroutineSupportComboBox.selectedItem as? CoroutineSupport ?: return ValidationResult.OK - val parsedArguments = configuration.settings.compilerInfo.commonCompilerArguments?.javaClass?.newInstance() + val parsedArguments = configuration.settings.compilerArguments?.javaClass?.newInstance() ?: return ValidationResult.OK parseArguments( editor.compilerConfigurable.additionalArgsOptionsField.text.split(Regex("\\s")).toTypedArray(), @@ -195,13 +197,13 @@ class KotlinFacetEditorGeneralTab( override fun isModified(): Boolean { if (editor.useProjectSettingsCheckBox.isSelected != configuration.settings.useProjectSettings) return true - if (editor.targetPlatformComboBox.selectedItem != configuration.settings.versionInfo.targetPlatformKind) return true + if (editor.targetPlatformComboBox.selectedItem != configuration.settings.targetPlatformKind) return true return !editor.useProjectSettingsCheckBox.isSelected && editor.compilerConfigurable.isModified } override fun reset() { editor.useProjectSettingsCheckBox.isSelected = configuration.settings.useProjectSettings - editor.targetPlatformComboBox.selectedItem = configuration.settings.versionInfo.targetPlatformKind + editor.targetPlatformComboBox.selectedItem = configuration.settings.targetPlatformKind editor.compilerConfigurable.reset() editor.updateCompilerConfigurable() } @@ -210,9 +212,21 @@ class KotlinFacetEditorGeneralTab( editor.compilerConfigurable.apply() with(configuration.settings) { useProjectSettings = editor.useProjectSettingsCheckBox.isSelected - versionInfo.targetPlatformKind = editor.targetPlatformComboBox.selectedItem as TargetPlatformKind<*>? - versionInfo.languageLevel = LanguageVersion.fromVersionString(compilerInfo.commonCompilerArguments?.languageVersion) - versionInfo.apiLevel = LanguageVersion.fromVersionString(compilerInfo.commonCompilerArguments?.apiVersion) + (editor.targetPlatformComboBox.selectedItem as TargetPlatformKind<*>?)?.let { + if (it != targetPlatformKind) { + val newCompilerArguments = it.createCompilerArguments() + val platformArguments = when (it) { + is TargetPlatformKind.Jvm -> editor.compilerConfigurable.k2jvmCompilerArguments + is TargetPlatformKind.JavaScript -> editor.compilerConfigurable.k2jsCompilerArguments + else -> null + } + if (platformArguments != null) { + mergeBeans(platformArguments, newCompilerArguments) + } + copyInheritedFields(compilerArguments!!, newCompilerArguments) + compilerArguments = newCompilerArguments + } + } } } diff --git a/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt b/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt index 6c62c7a10b7..9d4ac220413 100644 --- a/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt @@ -18,11 +18,11 @@ package org.jetbrains.kotlin.idea.facet import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider 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.roots.ModuleRootManager import com.intellij.openapi.roots.ModuleRootModel -import com.intellij.util.text.VersionComparatorUtil import org.jetbrains.kotlin.cli.common.arguments.* import org.jetbrains.kotlin.compilerRunner.ArgumentUtils import org.jetbrains.kotlin.config.* @@ -49,47 +49,47 @@ private fun getDefaultTargetPlatform(module: Module, rootModel: ModuleRootModel? } } -fun KotlinFacetSettings.initializeIfNeeded(module: Module, rootModel: ModuleRootModel?) { +fun KotlinFacetSettings.initializeIfNeeded( + module: Module, + rootModel: ModuleRootModel?, + platformKind: TargetPlatformKind<*>? = null // if null, detect by module dependencies +) { val project = module.project + if (compilerSettings == null) { + compilerSettings = copyBean(KotlinCompilerSettings.getInstance(project).settings) + } + val commonArguments = KotlinCommonCompilerArgumentsHolder.getInstance(module.project).settings - with(versionInfo) { - if (targetPlatformKind == null) { - targetPlatformKind = getDefaultTargetPlatform(module, rootModel) - } - - if (languageLevel == null) { - languageLevel = (if (useProjectSettings) LanguageVersion.fromVersionString(commonArguments.languageVersion) else null) - ?: getDefaultLanguageLevel(module) - } - - if (apiLevel == null) { - apiLevel = if (useProjectSettings) { - LanguageVersion.fromVersionString(commonArguments.apiVersion) ?: languageLevel - } - else { - languageLevel!!.coerceAtMost(getLibraryLanguageLevel(module, rootModel, targetPlatformKind!!)) - } + if (compilerArguments == null) { + val targetPlatformKind = platformKind ?: getDefaultTargetPlatform(module, rootModel) + compilerArguments = targetPlatformKind.createCompilerArguments().apply { + mergeBeans(commonArguments, this) + targetPlatformKind.getPlatformCompilerArgumentsByProject(module.project)?.let { mergeBeans(it, this) } } } - with(compilerInfo) { - if (commonCompilerArguments == null) { - commonCompilerArguments = copyBean(commonArguments) - } + if (languageLevel == null) { + languageLevel = (if (useProjectSettings) LanguageVersion.fromVersionString(commonArguments.languageVersion) else null) + ?: getDefaultLanguageLevel(module) + } - if (compilerSettings == null) { - compilerSettings = copyBean(KotlinCompilerSettings.getInstance(project).settings) + if (apiLevel == null) { + apiLevel = if (useProjectSettings) { + LanguageVersion.fromVersionString(commonArguments.apiVersion) ?: languageLevel } + else { + languageLevel!!.coerceAtMost(getLibraryLanguageLevel(module, rootModel, targetPlatformKind!!)) + } + } +} - if (k2jsCompilerArguments == null) { - k2jsCompilerArguments = copyBean(Kotlin2JsCompilerArgumentsHolder.getInstance(project).settings) - } - - if (k2jvmCompilerArguments == null) { - k2jvmCompilerArguments = copyBean(Kotlin2JvmCompilerArgumentsHolder.getInstance(project).settings) - } +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 } } @@ -118,19 +118,15 @@ fun KotlinFacet.configureFacet( ) { val module = module with(configuration.settings) { - versionInfo.targetPlatformKind = platformKind - versionInfo.apiLevel = null - initializeIfNeeded(module, modelsProvider.getModifiableRootModel(module)) - with(versionInfo) { - languageLevel = LanguageVersion.fromFullVersionString(compilerVersion) ?: LanguageVersion.LATEST - // Both apiLevel and languageLevel should be initialized in the lines above - if (apiLevel!! > languageLevel!!) { - apiLevel = languageLevel - } + compilerArguments = null + compilerSettings = null + initializeIfNeeded(module, modelsProvider.getModifiableRootModel(module), platformKind) + languageLevel = LanguageVersion.fromFullVersionString(compilerVersion) ?: LanguageVersion.LATEST + // Both apiLevel and languageLevel should be initialized in the lines above + if (apiLevel!! > languageLevel!!) { + apiLevel = languageLevel } - compilerInfo.coroutineSupport = coroutineSupport - compilerInfo.commonCompilerArguments?.languageVersion = versionInfo.languageLevel!!.versionString - compilerInfo.commonCompilerArguments?.apiVersion = versionInfo.apiLevel!!.versionString + this.coroutineSupport = coroutineSupport } } @@ -160,46 +156,21 @@ fun parseCompilerArgumentsToFacet(arguments: List, defaultArguments: Lis val argumentArray = arguments.toTypedArray() with(kotlinFacet.configuration.settings) { - // todo: merge common arguments with platform-specific ones in facet settings - - val commonCompilerArguments = compilerInfo.commonCompilerArguments!! - val compilerArguments = when (versionInfo.targetPlatformKind) { - is TargetPlatformKind.Jvm -> compilerInfo.k2jvmCompilerArguments - is TargetPlatformKind.JavaScript -> compilerInfo.k2jsCompilerArguments - else -> commonCompilerArguments - }!! + val compilerArguments = this.compilerArguments ?: return val defaultCompilerArguments = compilerArguments.javaClass.newInstance() parseArguments(defaultArguments.toTypedArray(), defaultCompilerArguments, true) - val oldCoroutineSupport = CoroutineSupport.byCompilerArguments(commonCompilerArguments) - commonCompilerArguments.coroutinesEnable = false - commonCompilerArguments.coroutinesWarn = false - commonCompilerArguments.coroutinesError = false - - if (compilerArguments != commonCompilerArguments) { - compilerArguments.coroutinesEnable = false - compilerArguments.coroutinesWarn = false - compilerArguments.coroutinesError = false - } + val oldCoroutineSupport = CoroutineSupport.byCompilerArguments(compilerArguments) + compilerArguments.coroutinesEnable = false + compilerArguments.coroutinesWarn = false + compilerArguments.coroutinesError = false parseArguments(argumentArray, compilerArguments, true) val restoreCoroutineSupport = !compilerArguments.coroutinesEnable && !compilerArguments.coroutinesWarn && !compilerArguments.coroutinesError - compilerArguments.apiVersion?.let { versionInfo.apiLevel = LanguageVersion.fromVersionString(it) } - compilerArguments.languageVersion?.let { versionInfo.languageLevel = LanguageVersion.fromVersionString(it) } - - if (versionInfo.targetPlatformKind is TargetPlatformKind.Jvm) { - val jvmTarget = compilerInfo.k2jvmCompilerArguments!!.jvmTarget - if (jvmTarget != null) { - versionInfo.targetPlatformKind = TargetPlatformKind.Jvm.JVM_PLATFORMS.firstOrNull { - VersionComparatorUtil.compare(it.version.description, jvmTarget) >= 0 - } ?: TargetPlatformKind.Jvm.JVM_PLATFORMS.last() - } - } - // Retain only fields exposed in facet configuration editor. // The rest is combined into string and stored in CompilerSettings.additionalArguments @@ -211,17 +182,15 @@ fun parseCompilerArgumentsToFacet(arguments: List, defaultArguments: Lis copyFieldsSatisfying(compilerArguments, this, ::exposeAsAdditionalArgument) ArgumentUtils.convertArgumentsToStringList(this).joinToString(separator = " ") } - compilerInfo.compilerSettings!!.additionalArguments = + compilerSettings?.additionalArguments = if (additionalArgumentsString.isNotEmpty()) additionalArgumentsString else CompilerSettings.DEFAULT_ADDITIONAL_ARGUMENTS with(compilerArguments.javaClass.newInstance()) { copyFieldsSatisfying(this, compilerArguments, ::exposeAsAdditionalArgument) } - copyInheritedFields(compilerArguments, commonCompilerArguments) - if (restoreCoroutineSupport) { - compilerInfo.coroutineSupport = oldCoroutineSupport + coroutineSupport = oldCoroutineSupport } } } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeCoroutineSupportFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeCoroutineSupportFix.kt index ccbed2c978c..efd1c761337 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeCoroutineSupportFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeCoroutineSupportFix.kt @@ -26,6 +26,7 @@ import com.intellij.openapi.roots.ex.ProjectRootManagerEx import com.intellij.openapi.ui.Messages import com.intellij.psi.PsiElement import org.jetbrains.kotlin.config.CoroutineSupport +import org.jetbrains.kotlin.config.KotlinFacetSettingsProvider import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageVersion import org.jetbrains.kotlin.diagnostics.Diagnostic @@ -70,11 +71,11 @@ sealed class ChangeCoroutineSupportFix( return } - val facetSettings = KotlinFacet.get(module)?.configuration?.settings ?: return + val facetSettings = KotlinFacetSettingsProvider.getInstance(project).getSettings(module) ModuleRootModificationUtil.updateModel(module) { - facetSettings.compilerInfo.coroutineSupport = coroutineSupport - facetSettings.versionInfo.apiLevel = LanguageVersion.KOTLIN_1_1 - facetSettings.versionInfo.languageLevel = LanguageVersion.KOTLIN_1_1 + facetSettings.coroutineSupport = coroutineSupport + facetSettings.apiLevel = LanguageVersion.KOTLIN_1_1 + facetSettings.languageLevel = LanguageVersion.KOTLIN_1_1 } } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/EnableUnsupportedFeatureFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/EnableUnsupportedFeatureFix.kt index e5ead1b87f6..b9a22d21d26 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/EnableUnsupportedFeatureFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/EnableUnsupportedFeatureFix.kt @@ -29,6 +29,7 @@ import com.intellij.openapi.roots.libraries.Library import com.intellij.openapi.ui.Messages import com.intellij.psi.PsiElement import org.jetbrains.kotlin.config.ApiVersion +import org.jetbrains.kotlin.config.KotlinFacetSettingsProvider import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageVersion import org.jetbrains.kotlin.diagnostics.Diagnostic @@ -64,8 +65,8 @@ sealed class EnableUnsupportedFeatureFix( runtimeVersion < feature.sinceApiVersion } ?: false - val facetSettings = KotlinFacet.get(module)?.configuration?.settings ?: return - val targetApiLevel = facetSettings.versionInfo.apiLevel?.let { apiLevel -> + val facetSettings = KotlinFacetSettingsProvider.getInstance(project).getSettings(module) + val targetApiLevel = facetSettings.apiLevel?.let { apiLevel -> if (ApiVersion.createByLanguageVersion(apiLevel) < feature.sinceApiVersion) feature.sinceApiVersion.versionString else @@ -97,7 +98,7 @@ sealed class EnableUnsupportedFeatureFix( } ModuleRootModificationUtil.updateModel(module) { - with(facetSettings.versionInfo) { + with(facetSettings) { if (!apiVersionOnly) { languageLevel = targetVersion } diff --git a/idea/testData/configuration/jsProjectWithV1FacetConfig/module.iml b/idea/testData/configuration/jsProjectWithV1FacetConfig/module.iml new file mode 100644 index 00000000000..ed9f94cf380 --- /dev/null +++ b/idea/testData/configuration/jsProjectWithV1FacetConfig/module.iml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/idea/testData/configuration/jsProjectWithV1FacetConfig/projectFile.ipr b/idea/testData/configuration/jsProjectWithV1FacetConfig/projectFile.ipr new file mode 100644 index 00000000000..a1407e2c8cd --- /dev/null +++ b/idea/testData/configuration/jsProjectWithV1FacetConfig/projectFile.ipr @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/idea/testData/configuration/jsProjectWithV1FacetConfig/src/foo.kt b/idea/testData/configuration/jsProjectWithV1FacetConfig/src/foo.kt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/idea/testData/configuration/jsProjectWithV2FacetConfig/module.iml b/idea/testData/configuration/jsProjectWithV2FacetConfig/module.iml new file mode 100644 index 00000000000..de9ef25ac5c --- /dev/null +++ b/idea/testData/configuration/jsProjectWithV2FacetConfig/module.iml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/idea/testData/configuration/jsProjectWithV2FacetConfig/projectFile.ipr b/idea/testData/configuration/jsProjectWithV2FacetConfig/projectFile.ipr new file mode 100644 index 00000000000..a1407e2c8cd --- /dev/null +++ b/idea/testData/configuration/jsProjectWithV2FacetConfig/projectFile.ipr @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/idea/testData/configuration/jsProjectWithV2FacetConfig/src/foo.kt b/idea/testData/configuration/jsProjectWithV2FacetConfig/src/foo.kt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/idea/testData/configuration/jvmProjectWithV1FacetConfig/module.iml b/idea/testData/configuration/jvmProjectWithV1FacetConfig/module.iml new file mode 100644 index 00000000000..d44d6254a8d --- /dev/null +++ b/idea/testData/configuration/jvmProjectWithV1FacetConfig/module.iml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/idea/testData/configuration/jvmProjectWithV1FacetConfig/projectFile.ipr b/idea/testData/configuration/jvmProjectWithV1FacetConfig/projectFile.ipr new file mode 100644 index 00000000000..a1407e2c8cd --- /dev/null +++ b/idea/testData/configuration/jvmProjectWithV1FacetConfig/projectFile.ipr @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/idea/testData/configuration/jvmProjectWithV1FacetConfig/src/foo.kt b/idea/testData/configuration/jvmProjectWithV1FacetConfig/src/foo.kt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/idea/testData/configuration/jvmProjectWithV2FacetConfig/module.iml b/idea/testData/configuration/jvmProjectWithV2FacetConfig/module.iml new file mode 100644 index 00000000000..b2e7004d53e --- /dev/null +++ b/idea/testData/configuration/jvmProjectWithV2FacetConfig/module.iml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/idea/testData/configuration/jvmProjectWithV2FacetConfig/projectFile.ipr b/idea/testData/configuration/jvmProjectWithV2FacetConfig/projectFile.ipr new file mode 100644 index 00000000000..a1407e2c8cd --- /dev/null +++ b/idea/testData/configuration/jvmProjectWithV2FacetConfig/projectFile.ipr @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/idea/testData/configuration/jvmProjectWithV2FacetConfig/src/foo.kt b/idea/testData/configuration/jvmProjectWithV2FacetConfig/src/foo.kt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/idea/tests/org/jetbrains/kotlin/idea/caches/resolve/MultiModuleHighlightingTest.kt b/idea/tests/org/jetbrains/kotlin/idea/caches/resolve/MultiModuleHighlightingTest.kt index 4e00dc6cf7b..6e193529b9b 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/caches/resolve/MultiModuleHighlightingTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/caches/resolve/MultiModuleHighlightingTest.kt @@ -63,10 +63,10 @@ class MultiModuleHighlightingTest : AbstractMultiModuleHighlightingTest() { fun testPlatformBasic() { val header = module("header") - header.setPlatformKind(TargetPlatformKind.Common) + header.createFacet(TargetPlatformKind.Common) val jvm = module("jvm") - jvm.setPlatformKind(TargetPlatformKind.Jvm[JvmTarget.JVM_1_6]) + jvm.createFacet(TargetPlatformKind.Jvm[JvmTarget.JVM_1_6]) jvm.enableMultiPlatform() jvm.addDependency(header) @@ -75,10 +75,10 @@ class MultiModuleHighlightingTest : AbstractMultiModuleHighlightingTest() { fun testPlatformClass() { val header = module("header") - header.setPlatformKind(TargetPlatformKind.Common) + header.createFacet(TargetPlatformKind.Common) val jvm = module("jvm") - jvm.setPlatformKind(TargetPlatformKind.Jvm[JvmTarget.JVM_1_6]) + jvm.createFacet(TargetPlatformKind.Jvm[JvmTarget.JVM_1_6]) jvm.enableMultiPlatform() jvm.addDependency(header) @@ -87,15 +87,15 @@ class MultiModuleHighlightingTest : AbstractMultiModuleHighlightingTest() { fun testPlatformNotImplementedForBoth() { val header = module("header") - header.setPlatformKind(TargetPlatformKind.Common) + header.createFacet(TargetPlatformKind.Common) val jvm = module("jvm") - jvm.setPlatformKind(TargetPlatformKind.Jvm[JvmTarget.JVM_1_6]) + jvm.createFacet(TargetPlatformKind.Jvm[JvmTarget.JVM_1_6]) jvm.enableMultiPlatform() jvm.addDependency(header) val js = module("js") - js.setPlatformKind(TargetPlatformKind.JavaScript) + js.createFacet(TargetPlatformKind.JavaScript) js.enableMultiPlatform() js.addDependency(header) @@ -104,10 +104,10 @@ class MultiModuleHighlightingTest : AbstractMultiModuleHighlightingTest() { fun testPlatformPartiallyImplemented() { val header = module("header") - header.setPlatformKind(TargetPlatformKind.Common) + header.createFacet(TargetPlatformKind.Common) val jvm = module("jvm") - jvm.setPlatformKind(TargetPlatformKind.Jvm[JvmTarget.JVM_1_6]) + jvm.createFacet(TargetPlatformKind.Jvm[JvmTarget.JVM_1_6]) jvm.enableMultiPlatform() jvm.addDependency(header) @@ -116,10 +116,10 @@ class MultiModuleHighlightingTest : AbstractMultiModuleHighlightingTest() { fun testPlatformFunctionProperty() { val header = module("header") - header.setPlatformKind(TargetPlatformKind.Common) + header.createFacet(TargetPlatformKind.Common) val jvm = module("jvm") - jvm.setPlatformKind(TargetPlatformKind.Jvm[JvmTarget.JVM_1_6]) + jvm.createFacet(TargetPlatformKind.Jvm[JvmTarget.JVM_1_6]) jvm.enableMultiPlatform() jvm.addDependency(header) @@ -128,10 +128,10 @@ class MultiModuleHighlightingTest : AbstractMultiModuleHighlightingTest() { fun testPlatformSuppress() { val header = module("header") - header.setPlatformKind(TargetPlatformKind.Common) + header.createFacet(TargetPlatformKind.Common) val jvm = module("jvm") - jvm.setPlatformKind(TargetPlatformKind.Jvm[JvmTarget.JVM_1_6]) + jvm.createFacet(TargetPlatformKind.Jvm[JvmTarget.JVM_1_6]) jvm.enableMultiPlatform() jvm.addDependency(header) diff --git a/idea/tests/org/jetbrains/kotlin/idea/caches/resolve/MultiModuleLineMarkerTest.kt b/idea/tests/org/jetbrains/kotlin/idea/caches/resolve/MultiModuleLineMarkerTest.kt index 32cf99475d4..d33555108b1 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/caches/resolve/MultiModuleLineMarkerTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/caches/resolve/MultiModuleLineMarkerTest.kt @@ -22,10 +22,10 @@ import org.jetbrains.kotlin.config.TargetPlatformKind class MultiModuleLineMarkerTest : AbstractMultiModuleLineMarkerTest() { fun testFromCommonToJvmHeader() { val header = module("header") - header.setPlatformKind(TargetPlatformKind.Common) + header.createFacet(TargetPlatformKind.Common) val jvm = module("jvm") - jvm.setPlatformKind(TargetPlatformKind.Jvm[JvmTarget.JVM_1_6]) + jvm.createFacet(TargetPlatformKind.Jvm[JvmTarget.JVM_1_6]) jvm.enableMultiPlatform() jvm.addDependency(header) @@ -34,10 +34,10 @@ class MultiModuleLineMarkerTest : AbstractMultiModuleLineMarkerTest() { fun testFromCommonToJvmImpl() { val header = module("header") - header.setPlatformKind(TargetPlatformKind.Common) + header.createFacet(TargetPlatformKind.Common) val jvm = module("jvm") - jvm.setPlatformKind(TargetPlatformKind.Jvm[JvmTarget.JVM_1_6]) + jvm.createFacet(TargetPlatformKind.Jvm[JvmTarget.JVM_1_6]) jvm.enableMultiPlatform() jvm.addDependency(header) @@ -46,10 +46,10 @@ class MultiModuleLineMarkerTest : AbstractMultiModuleLineMarkerTest() { fun testFromClassToAlias() { val header = module("header") - header.setPlatformKind(TargetPlatformKind.Common) + header.createFacet(TargetPlatformKind.Common) val jvm = module("jvm") - jvm.setPlatformKind(TargetPlatformKind.Jvm[JvmTarget.JVM_1_6]) + jvm.createFacet(TargetPlatformKind.Jvm[JvmTarget.JVM_1_6]) jvm.enableMultiPlatform() jvm.addDependency(header) diff --git a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleFacetImportTest.kt b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleFacetImportTest.kt index 10d50c1d161..a3cd1dcb4c5 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleFacetImportTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleFacetImportTest.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.idea.codeInsight.gradle +import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments import org.jetbrains.kotlin.config.CoroutineSupport import org.jetbrains.kotlin.config.JvmTarget import org.jetbrains.kotlin.config.KotlinFacetSettings @@ -62,12 +63,12 @@ class GradleFacetImportTest : GradleImportingTestCase() { importProject() with (facetSettings) { - Assert.assertEquals("1.1", versionInfo.languageLevel!!.versionString) - Assert.assertEquals("1.1", versionInfo.apiLevel!!.versionString) - Assert.assertEquals(TargetPlatformKind.Jvm[JvmTarget.JVM_1_8], versionInfo.targetPlatformKind) - Assert.assertEquals("1.7", compilerInfo.k2jvmCompilerArguments!!.jvmTarget) + Assert.assertEquals("1.1", languageLevel!!.versionString) + Assert.assertEquals("1.1", apiLevel!!.versionString) + Assert.assertEquals(TargetPlatformKind.Jvm[JvmTarget.JVM_1_8], targetPlatformKind) + Assert.assertEquals("1.7", (compilerArguments as K2JVMCompilerArguments).jvmTarget) Assert.assertEquals("-no-stdlib -no-reflect -module-name project_main -Xdump-declarations-to tmp -Xsingle-module -Xadd-compiler-builtins", - compilerInfo.compilerSettings!!.additionalArguments) + compilerSettings!!.additionalArguments) } } @@ -105,7 +106,7 @@ class GradleFacetImportTest : GradleImportingTestCase() { importProject() with (facetSettings) { - Assert.assertEquals(CoroutineSupport.ENABLED, compilerInfo.coroutineSupport) + Assert.assertEquals(CoroutineSupport.ENABLED, coroutineSupport) } } @@ -144,16 +145,16 @@ class GradleFacetImportTest : GradleImportingTestCase() { importProject() with (facetSettings) { - compilerInfo.k2jvmCompilerArguments!!.coroutinesEnable = true - compilerInfo.k2jvmCompilerArguments!!.coroutinesWarn = true - compilerInfo.k2jvmCompilerArguments!!.coroutinesError = true + compilerArguments!!.coroutinesEnable = true + compilerArguments!!.coroutinesWarn = true + compilerArguments!!.coroutinesError = true importProject() - Assert.assertEquals(CoroutineSupport.ENABLED, compilerInfo.coroutineSupport) - Assert.assertEquals(true, compilerInfo.k2jvmCompilerArguments!!.coroutinesEnable) - Assert.assertEquals(false, compilerInfo.k2jvmCompilerArguments!!.coroutinesWarn) - Assert.assertEquals(false, compilerInfo.k2jvmCompilerArguments!!.coroutinesError) + Assert.assertEquals(CoroutineSupport.ENABLED, coroutineSupport) + Assert.assertEquals(true, compilerArguments!!.coroutinesEnable) + Assert.assertEquals(false, compilerArguments!!.coroutinesWarn) + Assert.assertEquals(false, compilerArguments!!.coroutinesError) } } @@ -186,7 +187,7 @@ class GradleFacetImportTest : GradleImportingTestCase() { importProject() with (facetSettings) { - Assert.assertEquals(CoroutineSupport.ENABLED, compilerInfo.coroutineSupport) + Assert.assertEquals(CoroutineSupport.ENABLED, coroutineSupport) } } @@ -261,7 +262,7 @@ class GradleFacetImportTest : GradleImportingTestCase() { importProject() with (facetSettings) { - Assert.assertEquals(TargetPlatformKind.JavaScript, versionInfo.targetPlatformKind) + Assert.assertEquals(TargetPlatformKind.JavaScript, targetPlatformKind) } } @@ -293,9 +294,9 @@ class GradleFacetImportTest : GradleImportingTestCase() { importProject() with (facetSettings) { - Assert.assertEquals("1.1", versionInfo.languageLevel!!.versionString) - Assert.assertEquals("1.1", versionInfo.apiLevel!!.versionString) - Assert.assertEquals(TargetPlatformKind.Common, versionInfo.targetPlatformKind) + Assert.assertEquals("1.1", languageLevel!!.versionString) + Assert.assertEquals("1.1", apiLevel!!.versionString) + Assert.assertEquals(TargetPlatformKind.Common, targetPlatformKind) } } } diff --git a/idea/tests/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinTest.java b/idea/tests/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinTest.java index 4beb5504129..7223744409f 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinTest.java +++ b/idea/tests/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinTest.java @@ -24,7 +24,9 @@ import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.io.FileUtilRt; import com.intellij.testFramework.PlatformTestCase; import org.jetbrains.annotations.NotNull; -import org.jetbrains.kotlin.config.LanguageVersion; +import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments; +import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments; +import org.jetbrains.kotlin.config.*; import org.jetbrains.kotlin.idea.project.PlatformKt; import org.jetbrains.kotlin.utils.PathUtil; @@ -38,16 +40,13 @@ import static org.jetbrains.kotlin.idea.configuration.KotlinWithLibraryConfigura public class ConfigureKotlinTest extends PlatformTestCase { private static final String BASE_PATH = "idea/testData/configuration/"; - + private static final String TEMP_DIR_MACRO_KEY = "TEMP_TEST_DIR"; private static final KotlinJavaModuleConfigurator JAVA_CONFIGURATOR = new KotlinJavaModuleConfigurator() { @Override protected String getDefaultPathToJarFile(@NotNull Project project) { return getPathRelativeToTemp("default_jvm_lib"); } }; - - private static final String TEMP_DIR_MACRO_KEY = "TEMP_TEST_DIR"; - private static final KotlinJsModuleConfigurator JS_CONFIGURATOR = new KotlinJsModuleConfigurator() { @Override protected String getDefaultPathToJarFile(@NotNull Project project) { @@ -55,6 +54,98 @@ public class ConfigureKotlinTest extends PlatformTestCase { } }; + private static void configure( + @NotNull List modules, + @NotNull FileState runtimeState, + @NotNull LibraryState libraryState, + @NotNull KotlinWithLibraryConfigurator configurator, + @NotNull String jarFromDist, + @NotNull String jarFromTemp + ) { + Project project = modules.iterator().next().getProject(); + NotificationMessageCollector collector = NotificationMessageCollectorKt.createConfigureKotlinNotificationCollector(project); + for (Module module : modules) { + String pathToJar = getPathToJar(runtimeState, jarFromDist, jarFromTemp); + configurator.configureModuleWithLibraryClasses(module, libraryState, runtimeState, pathToJar, collector); + } + collector.showNotification(); + } + + @NotNull + private static String getPathToJar(@NotNull FileState runtimeState, @NotNull String jarFromDist, @NotNull String jarFromTemp) { + switch (runtimeState) { + case EXISTS: + return jarFromDist; + case COPY: + return jarFromTemp; + case DO_NOT_COPY: + return jarFromDist; + } + return jarFromDist; + } + + private static void configure(@NotNull Module module, @NotNull FileState jarState, @NotNull LibraryState libraryState, @NotNull KotlinProjectConfigurator configurator) { + if (configurator instanceof KotlinJavaModuleConfigurator) { + configure(Collections.singletonList(module), jarState, libraryState, + (KotlinWithLibraryConfigurator) configurator, + getPathToExistentRuntimeJar(), getPathToNonexistentRuntimeJar()); + } + if (configurator instanceof KotlinJsModuleConfigurator) { + configure(Collections.singletonList(module), jarState, libraryState, + (KotlinWithLibraryConfigurator) configurator, + getPathToExistentJsJar(), getPathToNonexistentJsJar()); + } + } + + private static String getPathToNonexistentRuntimeJar() { + String pathToTempKotlinRuntimeJar = FileUtil.getTempDirectory() + "/" + PathUtil.KOTLIN_JAVA_RUNTIME_JAR; + myFilesToDelete.add(new File(pathToTempKotlinRuntimeJar)); + return pathToTempKotlinRuntimeJar; + } + + private static String getPathToNonexistentJsJar() { + String pathToTempKotlinRuntimeJar = FileUtil.getTempDirectory() + "/" + PathUtil.JS_LIB_JAR_NAME; + myFilesToDelete.add(new File(pathToTempKotlinRuntimeJar)); + return pathToTempKotlinRuntimeJar; + } + + private static String getPathToExistentRuntimeJar() { + return PathUtil.getKotlinPathsForDistDirectory().getRuntimePath().getParent(); + } + + private static String getPathToExistentJsJar() { + return PathUtil.getKotlinPathsForDistDirectory().getJsStdLibJarPath().getParent(); + } + + private static void assertNotConfigured(Module module, KotlinWithLibraryConfigurator configurator) { + assertFalse( + String.format("Module %s should not be configured as %s Module", module.getName(), configurator.getPresentableText()), + configurator.isConfigured(module)); + } + + private static void assertConfigured(Module module, KotlinWithLibraryConfigurator configurator) { + assertTrue(String.format("Module %s should be configured with configurator '%s'", module.getName(), + configurator.getPresentableText()), + configurator.isConfigured(module)); + } + + private static void assertProperlyConfigured(Module module, KotlinWithLibraryConfigurator configurator) { + assertConfigured(module, configurator); + assertNotConfigured(module, getOppositeConfigurator(configurator)); + } + + private static KotlinWithLibraryConfigurator getOppositeConfigurator(KotlinWithLibraryConfigurator configurator) { + if (configurator == JAVA_CONFIGURATOR) return JS_CONFIGURATOR; + if (configurator == JS_CONFIGURATOR) return JAVA_CONFIGURATOR; + + throw new IllegalArgumentException("Only JS_CONFIGURATOR and JAVA_CONFIGURATOR are supported"); + } + + private static String getPathRelativeToTemp(String relativePath) { + String tempPath = PathMacros.getInstance().getValue(TEMP_DIR_MACRO_KEY); + return tempPath + '/' + relativePath; + } + @Override protected void tearDown() throws Exception { PathMacros.getInstance().removeMacro(TEMP_DIR_MACRO_KEY); @@ -195,6 +286,66 @@ public class ConfigureKotlinTest extends PlatformTestCase { assertEquals(LanguageVersion.KOTLIN_1_0, PlatformKt.getLanguageVersionSettings(getModule()).getLanguageVersion()); } + @SuppressWarnings("ConstantConditions") + public void testJvmProjectWithV1FacetConfig() { + KotlinFacetSettings settings = KotlinFacetSettingsProvider.Companion.getInstance(myProject).getSettings(getModule()); + K2JVMCompilerArguments arguments = (K2JVMCompilerArguments) settings.getCompilerArguments(); + assertEquals(false, settings.getUseProjectSettings()); + assertEquals("1.1", settings.getLanguageLevel().getDescription()); + assertEquals("1.0", settings.getApiLevel().getDescription()); + assertEquals(TargetPlatformKind.Jvm.Companion.get(JvmTarget.JVM_1_8), settings.getTargetPlatformKind()); + assertEquals("1.1", arguments.languageVersion); + assertEquals("1.0", arguments.apiVersion); + assertEquals("warn", CoroutineSupport.byCompilerArguments(arguments).getCompilerArgument()); + assertEquals("1.7", arguments.jvmTarget); + assertEquals("-version -Xallow-kotlin-package -Xskip-metadata-version-check", settings.getCompilerSettings().additionalArguments); + } + + @SuppressWarnings("ConstantConditions") + public void testJsProjectWithV1FacetConfig() { + KotlinFacetSettings settings = KotlinFacetSettingsProvider.Companion.getInstance(myProject).getSettings(getModule()); + K2JSCompilerArguments arguments = (K2JSCompilerArguments) settings.getCompilerArguments(); + assertEquals(false, settings.getUseProjectSettings()); + assertEquals("1.1", settings.getLanguageLevel().getDescription()); + assertEquals("1.0", settings.getApiLevel().getDescription()); + assertEquals(TargetPlatformKind.JavaScript.INSTANCE, settings.getTargetPlatformKind()); + assertEquals("1.1", arguments.languageVersion); + assertEquals("1.0", arguments.apiVersion); + assertEquals("warn", CoroutineSupport.byCompilerArguments(arguments).getCompilerArgument()); + assertEquals("amd", arguments.moduleKind); + assertEquals("-version -meta-info", settings.getCompilerSettings().additionalArguments); + } + + @SuppressWarnings("ConstantConditions") + public void testJvmProjectWithV2FacetConfig() { + KotlinFacetSettings settings = KotlinFacetSettingsProvider.Companion.getInstance(myProject).getSettings(getModule()); + K2JVMCompilerArguments arguments = (K2JVMCompilerArguments) settings.getCompilerArguments(); + assertEquals(false, settings.getUseProjectSettings()); + assertEquals("1.1", settings.getLanguageLevel().getDescription()); + assertEquals("1.0", settings.getApiLevel().getDescription()); + assertEquals(TargetPlatformKind.Jvm.Companion.get(JvmTarget.JVM_1_8), settings.getTargetPlatformKind()); + assertEquals("1.1", arguments.languageVersion); + assertEquals("1.0", arguments.apiVersion); + assertEquals("warn", CoroutineSupport.byCompilerArguments(arguments).getCompilerArgument()); + assertEquals("1.7", arguments.jvmTarget); + assertEquals("-version -Xallow-kotlin-package -Xskip-metadata-version-check", settings.getCompilerSettings().additionalArguments); + } + + @SuppressWarnings("ConstantConditions") + public void testJsProjectWithV2FacetConfig() { + KotlinFacetSettings settings = KotlinFacetSettingsProvider.Companion.getInstance(myProject).getSettings(getModule()); + K2JSCompilerArguments arguments = (K2JSCompilerArguments) settings.getCompilerArguments(); + assertEquals(false, settings.getUseProjectSettings()); + assertEquals("1.1", settings.getLanguageLevel().getDescription()); + assertEquals("1.0", settings.getApiLevel().getDescription()); + assertEquals(TargetPlatformKind.JavaScript.INSTANCE, settings.getTargetPlatformKind()); + assertEquals("1.1", arguments.languageVersion); + assertEquals("1.0", arguments.apiVersion); + assertEquals("warn", CoroutineSupport.byCompilerArguments(arguments).getCompilerArgument()); + assertEquals("amd", arguments.moduleKind); + assertEquals("-version -meta-info", settings.getCompilerSettings().additionalArguments); + } + private void doTestConfigureModulesWithNonDefaultSetup(KotlinWithLibraryConfigurator configurator) { assertNoFilesInDefaultPaths(); @@ -229,69 +380,6 @@ public class ConfigureKotlinTest extends PlatformTestCase { assertProperlyConfigured(module, configurator); } - private static void configure( - @NotNull List modules, - @NotNull FileState runtimeState, - @NotNull LibraryState libraryState, - @NotNull KotlinWithLibraryConfigurator configurator, - @NotNull String jarFromDist, - @NotNull String jarFromTemp - ) { - Project project = modules.iterator().next().getProject(); - NotificationMessageCollector collector = NotificationMessageCollectorKt.createConfigureKotlinNotificationCollector(project); - for (Module module : modules) { - String pathToJar = getPathToJar(runtimeState, jarFromDist, jarFromTemp); - configurator.configureModuleWithLibraryClasses(module, libraryState, runtimeState, pathToJar, collector); - } - collector.showNotification(); - } - - @NotNull - private static String getPathToJar(@NotNull FileState runtimeState, @NotNull String jarFromDist, @NotNull String jarFromTemp) { - switch (runtimeState) { - case EXISTS: - return jarFromDist; - case COPY: - return jarFromTemp; - case DO_NOT_COPY: - return jarFromDist; - } - return jarFromDist; - } - - private static void configure(@NotNull Module module, @NotNull FileState jarState, @NotNull LibraryState libraryState, @NotNull KotlinProjectConfigurator configurator) { - if (configurator instanceof KotlinJavaModuleConfigurator) { - configure(Collections.singletonList(module), jarState, libraryState, - (KotlinWithLibraryConfigurator) configurator, - getPathToExistentRuntimeJar(), getPathToNonexistentRuntimeJar()); - } - if (configurator instanceof KotlinJsModuleConfigurator) { - configure(Collections.singletonList(module), jarState, libraryState, - (KotlinWithLibraryConfigurator) configurator, - getPathToExistentJsJar(), getPathToNonexistentJsJar()); - } - } - - private static String getPathToNonexistentRuntimeJar() { - String pathToTempKotlinRuntimeJar = FileUtil.getTempDirectory() + "/" + PathUtil.KOTLIN_JAVA_RUNTIME_JAR; - myFilesToDelete.add(new File(pathToTempKotlinRuntimeJar)); - return pathToTempKotlinRuntimeJar; - } - - private static String getPathToNonexistentJsJar() { - String pathToTempKotlinRuntimeJar = FileUtil.getTempDirectory() + "/" + PathUtil.JS_LIB_JAR_NAME; - myFilesToDelete.add(new File(pathToTempKotlinRuntimeJar)); - return pathToTempKotlinRuntimeJar; - } - - private static String getPathToExistentRuntimeJar() { - return PathUtil.getKotlinPathsForDistDirectory().getRuntimePath().getParent(); - } - - private static String getPathToExistentJsJar() { - return PathUtil.getKotlinPathsForDistDirectory().getJsStdLibJarPath().getParent(); - } - @Override public Module getModule() { Module[] modules = ModuleManager.getInstance(myProject).getModules(); @@ -333,33 +421,4 @@ public class ConfigureKotlinTest extends PlatformTestCase { assertDoesntExist(new File(JAVA_CONFIGURATOR.getDefaultPathToJarFile(getProject()))); assertDoesntExist(new File(JS_CONFIGURATOR.getDefaultPathToJarFile(getProject()))); } - - private static void assertNotConfigured(Module module, KotlinWithLibraryConfigurator configurator) { - assertFalse( - String.format("Module %s should not be configured as %s Module", module.getName(), configurator.getPresentableText()), - configurator.isConfigured(module)); - } - - private static void assertConfigured(Module module, KotlinWithLibraryConfigurator configurator) { - assertTrue(String.format("Module %s should be configured with configurator '%s'", module.getName(), - configurator.getPresentableText()), - configurator.isConfigured(module)); - } - - private static void assertProperlyConfigured(Module module, KotlinWithLibraryConfigurator configurator) { - assertConfigured(module, configurator); - assertNotConfigured(module, getOppositeConfigurator(configurator)); - } - - private static KotlinWithLibraryConfigurator getOppositeConfigurator(KotlinWithLibraryConfigurator configurator) { - if (configurator == JAVA_CONFIGURATOR) return JS_CONFIGURATOR; - if (configurator == JS_CONFIGURATOR) return JAVA_CONFIGURATOR; - - throw new IllegalArgumentException("Only JS_CONFIGURATOR and JAVA_CONFIGURATOR are supported"); - } - - private static String getPathRelativeToTemp(String relativePath) { - String tempPath = PathMacros.getInstance().getValue(TEMP_DIR_MACRO_KEY); - return tempPath + '/' + relativePath; - } } diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/LanguageFeatureQuickFixTest.kt b/idea/tests/org/jetbrains/kotlin/idea/quickfix/LanguageFeatureQuickFixTest.kt index 157a4f7f448..39ae9edcaab 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/LanguageFeatureQuickFixTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/LanguageFeatureQuickFixTest.kt @@ -68,9 +68,9 @@ class LanguageFeatureQuickFixTest : LightPlatformCodeInsightFixtureTestCase() { resetProjectSettings(LanguageVersion.KOTLIN_1_1) myFixture.configureByText("foo.kt", "suspend fun foo()") - assertEquals(CoroutineSupport.ENABLED_WITH_WARNING, facet.configuration.settings.compilerInfo.coroutineSupport) + assertEquals(CoroutineSupport.ENABLED_WITH_WARNING, facet.configuration.settings.coroutineSupport) myFixture.launchAction(myFixture.findSingleIntention("Enable coroutine support in the current module")) - assertEquals(CoroutineSupport.ENABLED, facet.configuration.settings.compilerInfo.coroutineSupport) + assertEquals(CoroutineSupport.ENABLED, facet.configuration.settings.coroutineSupport) } fun testEnableCoroutines_UpdateRuntime() { @@ -99,8 +99,8 @@ class LanguageFeatureQuickFixTest : LightPlatformCodeInsightFixtureTestCase() { configureRuntime("mockRuntime11") resetProjectSettings(LanguageVersion.KOTLIN_1_0) configureKotlinFacet(myModule) { - settings.versionInfo.languageLevel = LanguageVersion.KOTLIN_1_0 - settings.versionInfo.apiLevel = LanguageVersion.KOTLIN_1_0 + settings.languageLevel = LanguageVersion.KOTLIN_1_0 + settings.apiLevel = LanguageVersion.KOTLIN_1_0 } myFixture.configureByText("foo.kt", "val x get() = 1") @@ -137,8 +137,8 @@ class LanguageFeatureQuickFixTest : LightPlatformCodeInsightFixtureTestCase() { val runtime = configureRuntime("mockRuntime106") resetProjectSettings(LanguageVersion.KOTLIN_1_0) configureKotlinFacet(myModule) { - settings.versionInfo.languageLevel = LanguageVersion.KOTLIN_1_0 - settings.versionInfo.apiLevel = LanguageVersion.KOTLIN_1_0 + settings.languageLevel = LanguageVersion.KOTLIN_1_0 + settings.apiLevel = LanguageVersion.KOTLIN_1_0 } myFixture.configureByText("foo.kt", "val x = \"s\"::length") diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiModuleTest.kt b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiModuleTest.kt index 1f5e159f498..233dd98725f 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiModuleTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiModuleTest.kt @@ -26,10 +26,10 @@ class QuickFixMultiModuleTest : AbstractQuickFixMultiModuleTest() { implName: String = "jvm", implKind: TargetPlatformKind<*> = TargetPlatformKind.Jvm[JvmTarget.JVM_1_6]) { val header = module(headerName) - header.setPlatformKind(TargetPlatformKind.Common) + header.createFacet(TargetPlatformKind.Common) val jvm = module(implName) - jvm.setPlatformKind(implKind) + jvm.createFacet(implKind) jvm.enableMultiPlatform() jvm.addDependency(header) diff --git a/idea/tests/org/jetbrains/kotlin/idea/stubs/AbstractMultiModuleTest.kt b/idea/tests/org/jetbrains/kotlin/idea/stubs/AbstractMultiModuleTest.kt index b425cc1b4ed..74a9d4f679c 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/stubs/AbstractMultiModuleTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/stubs/AbstractMultiModuleTest.kt @@ -33,6 +33,7 @@ import org.jetbrains.kotlin.config.CompilerSettings import org.jetbrains.kotlin.config.KotlinFacetSettingsProvider import org.jetbrains.kotlin.config.TargetPlatformKind import org.jetbrains.kotlin.idea.facet.getOrCreateFacet +import org.jetbrains.kotlin.idea.facet.initializeIfNeeded import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil import org.jetbrains.kotlin.idea.test.PluginTestCaseBase import java.io.File @@ -74,11 +75,15 @@ abstract class AbstractMultiModuleTest : DaemonAnalyzerTestCase() { exported: Boolean = false ) = ModuleRootModificationUtil.addDependency(this, other, dependencyScope, exported) - private fun Module.createFacet() { + protected fun Module.createFacet(platformKind: TargetPlatformKind<*>? = null) { val accessToken = WriteAction.start() try { val modelsProvider = IdeModifiableModelsProviderImpl(project) - getOrCreateFacet(modelsProvider, true) + getOrCreateFacet(modelsProvider, true).configuration.settings.initializeIfNeeded( + this, + modelsProvider.getModifiableRootModel(this), + platformKind + ) modelsProvider.commit() } finally { @@ -86,20 +91,12 @@ abstract class AbstractMultiModuleTest : DaemonAnalyzerTestCase() { } } - protected fun Module.setPlatformKind(platformKind: TargetPlatformKind<*>) { - createFacet() - val facetSettings = KotlinFacetSettingsProvider.getInstance(project).getSettings(this) - val versionInfo = facetSettings.versionInfo - versionInfo.targetPlatformKind = platformKind - } - protected fun Module.enableMultiPlatform() { createFacet() val facetSettings = KotlinFacetSettingsProvider.getInstance(project).getSettings(this) - val compilerInfo = facetSettings.compilerInfo val compilerSettings = CompilerSettings() compilerSettings.additionalArguments += " -$multiPlatformArg" - compilerInfo.compilerSettings = compilerSettings + facetSettings.compilerSettings = compilerSettings } companion object { diff --git a/jps-plugin/src/org/jetbrains/kotlin/jps/JpsKotlinCompilerSettings.kt b/jps-plugin/src/org/jetbrains/kotlin/jps/JpsKotlinCompilerSettings.kt index b7632daa9a8..ad41e628273 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/jps/JpsKotlinCompilerSettings.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/jps/JpsKotlinCompilerSettings.kt @@ -66,11 +66,8 @@ class JpsKotlinCompilerSettings : JpsElementBase() { val defaultArguments = getSettings(module.project).commonCompilerArguments val facetSettings = module.kotlinFacetExtension?.settings ?: return defaultArguments if (facetSettings.useProjectSettings) return defaultArguments - val (languageLevel, apiLevel) = facetSettings.versionInfo - val facetArguments = facetSettings.compilerInfo.commonCompilerArguments ?: return defaultArguments + val facetArguments = facetSettings.compilerArguments ?: return defaultArguments return copyBean(facetArguments).apply { - languageVersion = languageLevel?.description - apiVersion = apiLevel?.description multiPlatform = module .dependenciesList .dependencies @@ -86,11 +83,7 @@ class JpsKotlinCompilerSettings : JpsElementBase() { val defaultArguments = getSettings(module.project).k2JvmCompilerArguments val facetSettings = module.kotlinFacetExtension?.settings ?: return defaultArguments if (facetSettings.useProjectSettings) return defaultArguments - val targetPlatform = facetSettings.versionInfo.targetPlatformKind as? TargetPlatformKind.Jvm ?: return defaultArguments - val arguments = facetSettings.compilerInfo.k2jvmCompilerArguments ?: defaultArguments - return copyBean(arguments).apply { - jvmTarget = targetPlatform.version.description - } + return facetSettings.compilerArguments as? K2JVMCompilerArguments ?: defaultArguments } fun setK2JvmCompilerArguments(project: JpsProject, k2JvmCompilerArguments: K2JVMCompilerArguments) { @@ -101,7 +94,7 @@ class JpsKotlinCompilerSettings : JpsElementBase() { val defaultArguments = getSettings(module.project).k2JsCompilerArguments val facetSettings = module.kotlinFacetExtension?.settings ?: return defaultArguments if (facetSettings.useProjectSettings) return defaultArguments - return facetSettings.compilerInfo.k2jsCompilerArguments ?: defaultArguments + return facetSettings.compilerArguments as? K2JSCompilerArguments ?: defaultArguments } fun setK2JsCompilerArguments(project: JpsProject, k2JsCompilerArguments: K2JSCompilerArguments) { @@ -112,7 +105,7 @@ class JpsKotlinCompilerSettings : JpsElementBase() { val defaultSettings = getSettings(module.project).compilerSettings val facetSettings = module.kotlinFacetExtension?.settings ?: return defaultSettings if (facetSettings.useProjectSettings) return defaultSettings - return facetSettings.compilerInfo.compilerSettings ?: defaultSettings + return facetSettings.compilerSettings ?: defaultSettings } fun setCompilerSettings(project: JpsProject, compilerSettings: CompilerSettings) { @@ -122,4 +115,4 @@ class JpsKotlinCompilerSettings : JpsElementBase() { } val JpsModule.targetPlatform: TargetPlatformKind<*>? - get() = kotlinFacetExtension?.settings?.versionInfo?.targetPlatformKind \ No newline at end of file + get() = kotlinFacetExtension?.settings?.targetPlatformKind \ No newline at end of file diff --git a/plugins/allopen/allopen-ide/src/IdeAllOpenDeclarationAttributeAltererExtension.kt b/plugins/allopen/allopen-ide/src/IdeAllOpenDeclarationAttributeAltererExtension.kt index d0a4dcae2ed..0bb57cc587c 100644 --- a/plugins/allopen/allopen-ide/src/IdeAllOpenDeclarationAttributeAltererExtension.kt +++ b/plugins/allopen/allopen-ide/src/IdeAllOpenDeclarationAttributeAltererExtension.kt @@ -50,7 +50,7 @@ class IdeAllOpenDeclarationAttributeAltererExtension(val project: Project) : Abs return cache.value.getOrPut(module) { val kotlinFacet = KotlinFacet.get(module) ?: return@getOrPut emptyList() - val commonArgs = kotlinFacet.configuration.settings.compilerInfo.commonCompilerArguments ?: return@getOrPut emptyList() + val commonArgs = kotlinFacet.configuration.settings.compilerArguments ?: return@getOrPut emptyList() commonArgs.pluginOptions?.filter { it.startsWith(ANNOTATION_OPTION_PREFIX) } ?.map { it.substring(ANNOTATION_OPTION_PREFIX.length) } diff --git a/plugins/annotation-based-compiler-plugins-ide-support/src/idePluginUtils.kt b/plugins/annotation-based-compiler-plugins-ide-support/src/idePluginUtils.kt index 1e8127b1e84..e676b69000c 100644 --- a/plugins/annotation-based-compiler-plugins-ide-support/src/idePluginUtils.kt +++ b/plugins/annotation-based-compiler-plugins-ide-support/src/idePluginUtils.kt @@ -28,10 +28,10 @@ internal fun modifyCompilerArgumentsForPlugin( pluginName: String, annotationOptionName: String ) { - val compileInfo = facet.configuration.settings.compilerInfo + val facetSettings = facet.configuration.settings // investigate why copyBean() sometimes throws exceptions - val commonArguments = compileInfo.commonCompilerArguments ?: CommonCompilerArguments.DummyImpl() + val commonArguments = facetSettings.compilerArguments ?: CommonCompilerArguments.DummyImpl() /** See [CommonCompilerArguments.PLUGIN_OPTION_FORMAT] **/ val annotationOptions = setup?.annotationFqNames?.map { "plugin:$compilerPluginId:$annotationOptionName=$it" } ?: emptyList() @@ -48,5 +48,5 @@ internal fun modifyCompilerArgumentsForPlugin( commonArguments.pluginOptions = newPluginOptions.toTypedArray() commonArguments.pluginClasspaths = newPluginClasspaths.toTypedArray() - compileInfo.commonCompilerArguments = commonArguments + facetSettings.compilerArguments = commonArguments } \ No newline at end of file diff --git a/plugins/noarg/noarg-ide/src/IdeNoArgDeclarationChecker.kt b/plugins/noarg/noarg-ide/src/IdeNoArgDeclarationChecker.kt index eadc7dd4153..d9d47699c0a 100644 --- a/plugins/noarg/noarg-ide/src/IdeNoArgDeclarationChecker.kt +++ b/plugins/noarg/noarg-ide/src/IdeNoArgDeclarationChecker.kt @@ -24,9 +24,9 @@ import com.intellij.psi.util.CachedValue import com.intellij.psi.util.CachedValueProvider import com.intellij.psi.util.CachedValuesManager import org.jetbrains.kotlin.idea.facet.KotlinFacet -import org.jetbrains.kotlin.noarg.diagnostic.AbstractNoArgDeclarationChecker -import org.jetbrains.kotlin.noarg.NoArgCommandLineProcessor.Companion.PLUGIN_ID import org.jetbrains.kotlin.noarg.NoArgCommandLineProcessor.Companion.ANNOTATION_OPTION +import org.jetbrains.kotlin.noarg.NoArgCommandLineProcessor.Companion.PLUGIN_ID +import org.jetbrains.kotlin.noarg.diagnostic.AbstractNoArgDeclarationChecker import org.jetbrains.kotlin.psi.KtModifierListOwner import java.util.* @@ -45,7 +45,7 @@ class IdeNoArgDeclarationChecker(val project: Project) : AbstractNoArgDeclaratio return cache.value.getOrPut(module) { val kotlinFacet = KotlinFacet.get(module) ?: return@getOrPut emptyList() - val commonArgs = kotlinFacet.configuration.settings.compilerInfo.commonCompilerArguments ?: return@getOrPut emptyList() + val commonArgs = kotlinFacet.configuration.settings.compilerArguments ?: return@getOrPut emptyList() commonArgs.pluginOptions ?.filter { it.startsWith(ANNOTATION_OPTION_PREFIX) }