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
This commit is contained in:
Alexey Sedunov
2017-03-21 19:37:53 +03:00
parent 43f1c843ce
commit 7c7e41592a
10 changed files with 51 additions and 25 deletions
@@ -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()
}
@@ -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
@@ -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;
@@ -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)!!
@@ -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
}
}
}
@@ -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
@@ -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
@@ -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)
@@ -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());
@@ -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