From 7c7e41592ae0edd693a6be3963b6a1a51f106458 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Tue, 21 Mar 2017 19:37:53 +0300 Subject: [PATCH] Kotlin Facet: KT-16980 Avoid reinitialization of module-level settings on each run of the analyzer in the absence of Kotlin facet #KT-16980 Fixed --- .../idea/facet/KotlinVersionInfoProvider.kt | 2 +- .../jetbrains/kotlin/idea/project/Platform.kt | 14 +++---- .../idea/project/ProjectStructureUtil.java | 2 +- .../kotlin/config/KotlinFacetSettings.kt | 3 +- .../facet/KotlinFacetSettingsProviderImpl.kt | 37 ++++++++++++++++--- .../quickfix/ChangeCoroutineSupportFix.kt | 2 +- .../quickfix/EnableUnsupportedFeatureFix.kt | 2 +- .../ConfigureKotlinInTempDirTest.kt | 4 +- .../configuration/ConfigureKotlinTest.java | 8 ++-- .../idea/stubs/AbstractMultiModuleTest.kt | 2 +- 10 files changed, 51 insertions(+), 25 deletions(-) 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 a971b24a39c..b3cda46a5b2 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 @@ -75,7 +75,7 @@ fun getDefaultLanguageLevel( } fun getRuntimeLibraryVersion(module: Module): String? { - val targetPlatform = KotlinFacetSettingsProvider.getInstance(module.project).getSettings(module).targetPlatformKind + val targetPlatform = KotlinFacetSettingsProvider.getInstance(module.project).getInitializedSettings(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 08063c1263e..1b8c3ddc077 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 @@ -44,14 +44,10 @@ private val multiPlatformProjectsArg: String by lazy { } fun Module.getAndCacheLanguageLevelByDependencies(): LanguageVersion { - val languageLevel = getLibraryLanguageLevel( - this, - null, - KotlinFacetSettingsProvider.getInstance(project).getSettings(this).targetPlatformKind - ) + val facetSettings = KotlinFacetSettingsProvider.getInstance(project).getInitializedSettings(this) + val languageLevel = getLibraryLanguageLevel(this, null, facetSettings.targetPlatformKind) // Preserve inferred version in facet/project settings - val facetSettings = KotlinFacetSettingsProvider.getInstance(project).getSettings(this) if (facetSettings.useProjectSettings) { KotlinCommonCompilerArgumentsHolder.getInstance(project).update { if (languageVersion == null) { @@ -97,7 +93,9 @@ fun Project.getLanguageVersionSettings(contextModule: Module? = null): LanguageV val Module.languageVersionSettings: LanguageVersionSettings get() { - val facetSettings = KotlinFacetSettingsProvider.getInstance(project).getSettings(this) + val facetSettingsProvider = KotlinFacetSettingsProvider.getInstance(project) + if (facetSettingsProvider.getSettings(this) == null) return project.getLanguageVersionSettings(this) + val facetSettings = facetSettingsProvider.getInitializedSettings(this) if (facetSettings.useProjectSettings) return project.getLanguageVersionSettings(this) val languageVersion = facetSettings.languageLevel ?: getAndCacheLanguageLevelByDependencies() val apiVersion = facetSettings.apiLevel ?: languageVersion @@ -115,7 +113,7 @@ val Module.languageVersionSettings: LanguageVersionSettings } val Module.targetPlatform: TargetPlatformKind<*>? - get() = KotlinFacetSettingsProvider.getInstance(project).getSettings(this).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 cd75d931d44..3cbda09fd3f 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 @@ -67,7 +67,7 @@ public class ProjectStructureUtil { @Nullable private static TargetPlatform getPlatformConfiguredInFacet(@NotNull Module module) { - KotlinFacetSettings settings = KotlinFacetSettingsProvider.Companion.getInstance(module.getProject()).getSettings(module); + KotlinFacetSettings settings = KotlinFacetSettingsProvider.Companion.getInstance(module.getProject()).getInitializedSettings(module); 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 4336cb0cf33..41552aaae02 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 @@ -143,7 +143,8 @@ fun TargetPlatformKind<*>.createCompilerArguments(): CommonCompilerArguments { } interface KotlinFacetSettingsProvider { - fun getSettings(module: Module): KotlinFacetSettings + fun getSettings(module: Module): KotlinFacetSettings? + fun getInitializedSettings(module: Module): KotlinFacetSettings companion object { fun getInstance(project: Project) = ServiceManager.getService(project, KotlinFacetSettingsProvider::class.java)!! diff --git a/idea/src/org/jetbrains/kotlin/idea/facet/KotlinFacetSettingsProviderImpl.kt b/idea/src/org/jetbrains/kotlin/idea/facet/KotlinFacetSettingsProviderImpl.kt index b85903fb070..2a753b3eedc 100644 --- a/idea/src/org/jetbrains/kotlin/idea/facet/KotlinFacetSettingsProviderImpl.kt +++ b/idea/src/org/jetbrains/kotlin/idea/facet/KotlinFacetSettingsProviderImpl.kt @@ -16,14 +16,41 @@ package org.jetbrains.kotlin.idea.facet +import com.intellij.ProjectTopics import com.intellij.openapi.module.Module +import com.intellij.openapi.module.ModuleManager +import com.intellij.openapi.project.Project +import com.intellij.openapi.roots.ModuleRootEvent +import com.intellij.openapi.roots.ModuleRootListener +import com.intellij.openapi.util.Key import org.jetbrains.kotlin.config.KotlinFacetSettings import org.jetbrains.kotlin.config.KotlinFacetSettingsProvider +import org.jetbrains.kotlin.psi.UserDataProperty -class KotlinFacetSettingsProviderImpl : KotlinFacetSettingsProvider { - override fun getSettings(module: Module): KotlinFacetSettings { - val settings = KotlinFacet.get(module)?.configuration?.settings ?: KotlinFacetSettings() - settings.initializeIfNeeded(module, null) - return settings +class KotlinFacetSettingsProviderImpl(private val project: Project) : KotlinFacetSettingsProvider { + companion object { + private var Module.facetSettingsCache : KotlinFacetSettings? by UserDataProperty(Key.create("FACET_SETTINGS_CACHE")) + } + + init { + project.messageBus.connect(project).subscribe( + ProjectTopics.PROJECT_ROOTS, + object : ModuleRootListener { + override fun rootsChanged(event: ModuleRootEvent?) { + ModuleManager.getInstance(project).modules.forEach { it.facetSettingsCache = null } + } + } + ) + } + + override fun getSettings(module: Module) = KotlinFacet.get(module)?.configuration?.settings + + override fun getInitializedSettings(module: Module): KotlinFacetSettings { + getSettings(module)?.let { return it } + + return KotlinFacetSettings().apply { + initializeIfNeeded(module, null) + module.facetSettingsCache = this + } } } \ 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 c23807ed646..bba09d0e43b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeCoroutineSupportFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeCoroutineSupportFix.kt @@ -76,7 +76,7 @@ sealed class ChangeCoroutineSupportFix( return } - val facetSettings = KotlinFacetSettingsProvider.getInstance(project).getSettings(module) + val facetSettings = KotlinFacetSettingsProvider.getInstance(project).getInitializedSettings(module) ModuleRootModificationUtil.updateModel(module) { facetSettings.coroutineSupport = coroutineSupport facetSettings.apiLevel = 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 299f04eac73..9141fe35e6b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/EnableUnsupportedFeatureFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/EnableUnsupportedFeatureFix.kt @@ -65,7 +65,7 @@ sealed class EnableUnsupportedFeatureFix( runtimeVersion < feature.sinceApiVersion } ?: false - val facetSettings = KotlinFacetSettingsProvider.getInstance(project).getSettings(module) + val facetSettings = KotlinFacetSettingsProvider.getInstance(project).getInitializedSettings(module) val targetApiLevel = facetSettings.apiLevel?.let { apiLevel -> if (ApiVersion.createByLanguageVersion(apiLevel) < feature.sinceApiVersion) feature.sinceApiVersion.versionString diff --git a/idea/tests/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinInTempDirTest.kt b/idea/tests/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinInTempDirTest.kt index 9d971119079..f87d8fdf836 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinInTempDirTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinInTempDirTest.kt @@ -66,14 +66,14 @@ class ConfigureKotlinInTempDirTest : AbstractConfigureKotlinTest() { } fun testProject106InconsistentVersionInConfig() { - val settings = KotlinFacetSettingsProvider.getInstance(myProject).getSettings(module) + val settings = KotlinFacetSettingsProvider.getInstance(myProject).getInitializedSettings(module) Assert.assertEquals(false, settings.useProjectSettings) Assert.assertEquals("1.0", settings.languageLevel!!.description) Assert.assertEquals("1.0", settings.apiLevel!!.description) } fun testProject107InconsistentVersionInConfig() { - val settings = KotlinFacetSettingsProvider.getInstance(myProject).getSettings(module) + val settings = KotlinFacetSettingsProvider.getInstance(myProject).getInitializedSettings(module) Assert.assertEquals(false, settings.useProjectSettings) Assert.assertEquals("1.0", settings.languageLevel!!.description) Assert.assertEquals("1.0", settings.apiLevel!!.description) diff --git a/idea/tests/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinTest.java b/idea/tests/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinTest.java index 3c3608ccf9b..c16d37c75cd 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinTest.java +++ b/idea/tests/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinTest.java @@ -174,7 +174,7 @@ public class ConfigureKotlinTest extends AbstractConfigureKotlinTest { @SuppressWarnings("ConstantConditions") public void testJvmProjectWithV1FacetConfig() { - KotlinFacetSettings settings = KotlinFacetSettingsProvider.Companion.getInstance(myProject).getSettings(getModule()); + KotlinFacetSettings settings = KotlinFacetSettingsProvider.Companion.getInstance(myProject).getInitializedSettings(getModule()); K2JVMCompilerArguments arguments = (K2JVMCompilerArguments) settings.getCompilerArguments(); assertEquals(false, settings.getUseProjectSettings()); assertEquals("1.1", settings.getLanguageLevel().getDescription()); @@ -189,7 +189,7 @@ public class ConfigureKotlinTest extends AbstractConfigureKotlinTest { @SuppressWarnings("ConstantConditions") public void testJsProjectWithV1FacetConfig() { - KotlinFacetSettings settings = KotlinFacetSettingsProvider.Companion.getInstance(myProject).getSettings(getModule()); + KotlinFacetSettings settings = KotlinFacetSettingsProvider.Companion.getInstance(myProject).getInitializedSettings(getModule()); K2JSCompilerArguments arguments = (K2JSCompilerArguments) settings.getCompilerArguments(); assertEquals(false, settings.getUseProjectSettings()); assertEquals("1.1", settings.getLanguageLevel().getDescription()); @@ -204,7 +204,7 @@ public class ConfigureKotlinTest extends AbstractConfigureKotlinTest { @SuppressWarnings("ConstantConditions") public void testJvmProjectWithV2FacetConfig() { - KotlinFacetSettings settings = KotlinFacetSettingsProvider.Companion.getInstance(myProject).getSettings(getModule()); + KotlinFacetSettings settings = KotlinFacetSettingsProvider.Companion.getInstance(myProject).getInitializedSettings(getModule()); K2JVMCompilerArguments arguments = (K2JVMCompilerArguments) settings.getCompilerArguments(); assertEquals(false, settings.getUseProjectSettings()); assertEquals("1.1", settings.getLanguageLevel().getDescription()); @@ -219,7 +219,7 @@ public class ConfigureKotlinTest extends AbstractConfigureKotlinTest { @SuppressWarnings("ConstantConditions") public void testJsProjectWithV2FacetConfig() { - KotlinFacetSettings settings = KotlinFacetSettingsProvider.Companion.getInstance(myProject).getSettings(getModule()); + KotlinFacetSettings settings = KotlinFacetSettingsProvider.Companion.getInstance(myProject).getInitializedSettings(getModule()); K2JSCompilerArguments arguments = (K2JSCompilerArguments) settings.getCompilerArguments(); assertEquals(false, settings.getUseProjectSettings()); assertEquals("1.1", settings.getLanguageLevel().getDescription()); diff --git a/idea/tests/org/jetbrains/kotlin/idea/stubs/AbstractMultiModuleTest.kt b/idea/tests/org/jetbrains/kotlin/idea/stubs/AbstractMultiModuleTest.kt index 0627121727d..57a823e9157 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/stubs/AbstractMultiModuleTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/stubs/AbstractMultiModuleTest.kt @@ -93,7 +93,7 @@ abstract class AbstractMultiModuleTest : DaemonAnalyzerTestCase() { protected fun Module.enableMultiPlatform() { createFacet() - val facetSettings = KotlinFacetSettingsProvider.getInstance(project).getSettings(this) + val facetSettings = KotlinFacetSettingsProvider.getInstance(project).getInitializedSettings(this) val compilerSettings = CompilerSettings() compilerSettings.additionalArguments += " -$multiPlatformArg" facetSettings.compilerSettings = compilerSettings