From 44b7a5cc36a00f1cd24151cd4926134931c47c47 Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Fri, 27 Sep 2019 19:29:57 +0900 Subject: [PATCH] Make KotlinFacetSettingsProvider.getInstance() nullable A module may not have a KotlinFacet. It isn't correct to throw an exception in that case. --- .../compiler/IDELanguageSettingsProvider.kt | 2 +- .../idea/facet/KotlinVersionInfoProvider.kt | 3 +- .../jetbrains/kotlin/idea/project/Platform.kt | 35 ++++++++++----- .../kotlin/config/KotlinFacetSettings.kt | 4 +- .../KotlinWithLibraryConfigurator.kt | 44 +++++++++++-------- .../quickfix/EnableUnsupportedFeatureFix.kt | 4 +- .../jetbrains/kotlin/idea/facet/facetUtils.kt | 5 ++- .../ConfigureKotlinInTempDirTest.kt | 12 +++-- .../highlighter/Jsr305HighlightingTest.kt | 4 +- .../idea/stubs/AbstractMultiModuleTest.kt | 8 +++- 10 files changed, 77 insertions(+), 44 deletions(-) diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/compiler/IDELanguageSettingsProvider.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/compiler/IDELanguageSettingsProvider.kt index 32eea3bc3f9..a8da37e51a0 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/compiler/IDELanguageSettingsProvider.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/compiler/IDELanguageSettingsProvider.kt @@ -62,7 +62,7 @@ object IDELanguageSettingsProvider : LanguageSettingsProvider { private fun computeJsr305State(project: Project): Jsr305State? { var result: Jsr305State? = null for (module in ModuleManager.getInstance(project).modules) { - val settings = KotlinFacetSettingsProvider.getInstance(project).getSettings(module) ?: continue + val settings = KotlinFacetSettingsProvider.getInstance(project)?.getSettings(module) ?: continue val compilerArguments = settings.mergedCompilerArguments as? K2JVMCompilerArguments ?: continue result = Jsr305Parser(MessageCollector.NONE).parse( 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 f81d1748645..d5535b305ce 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 @@ -92,7 +92,8 @@ private fun Iterable.addReleaseVersionIfNecessary(shouldAdd: Boolean): I if (shouldAdd) this + VersionView.RELEASED_VERSION.versionString else this fun getRuntimeLibraryVersion(module: Module): String? { - val targetPlatform = KotlinFacetSettingsProvider.getInstance(module.project).getInitializedSettings(module).targetPlatform + val settingsProvider = KotlinFacetSettingsProvider.getInstance(module.project) ?: return null + val targetPlatform = settingsProvider.getInitializedSettings(module).targetPlatform val versions = getRuntimeLibraryVersions(module, null, targetPlatform.orDefault().idePlatformKind) 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 d054b243a31..c0c31fb1d14 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 @@ -58,11 +58,11 @@ val KtElement.builtIns: KotlinBuiltIns var KtFile.forcedTargetPlatform: TargetPlatform? by UserDataProperty(Key.create("FORCED_TARGET_PLATFORM")) fun Module.getAndCacheLanguageLevelByDependencies(): LanguageVersion { - val facetSettings = KotlinFacetSettingsProvider.getInstance(project).getInitializedSettings(this) - val languageLevel = getLibraryLanguageLevel(this, null, facetSettings.targetPlatform?.idePlatformKind) + val facetSettings = KotlinFacetSettingsProvider.getInstance(project)?.getInitializedSettings(this) + val languageLevel = getLibraryLanguageLevel(this, null, facetSettings?.targetPlatform?.idePlatformKind) // Preserve inferred version in facet/project settings - if (facetSettings.useProjectSettings) { + if (facetSettings == null || facetSettings.useProjectSettings) { KotlinCommonCompilerArgumentsHolder.getInstance(project).update { if (languageVersion == null) { languageVersion = languageLevel.versionString @@ -96,7 +96,8 @@ fun Module.getAndCacheLanguageLevelByDependencies(): LanguageVersion { fun Module.getStableName(): Name { // Here we check ideal situation: we have a facet, and it has 'moduleName' argument. // This should be the case for the most environments - val arguments = KotlinFacetSettingsProvider.getInstance(project).getInitializedSettings(this).mergedCompilerArguments + val settingsProvider = KotlinFacetSettingsProvider.getInstance(project) + val arguments = settingsProvider?.getInitializedSettings(this)?.mergedCompilerArguments val explicitNameFromArguments = when (arguments) { is K2JVMCompilerArguments -> arguments.moduleName is K2JSCompilerArguments -> arguments.outputFile?.let { FileUtil.getNameWithoutExtension(File(it)) } @@ -179,25 +180,35 @@ private fun Module.createCachedValueForLanguageVersionSettings(): CachedValue, Any>.initIDESpecificAnalysisSettings(pro } val Module.platform: TargetPlatform? - get() = KotlinFacetSettingsProvider.getInstance(project).getInitializedSettings(this).targetPlatform ?: project.platform + get() = KotlinFacetSettingsProvider.getInstance(project)?.getInitializedSettings(this)?.targetPlatform ?: project.platform val Module.isHMPPEnabled: Boolean - get() = KotlinFacetSettingsProvider.getInstance(project).getInitializedSettings(this).isHmppEnabled + get() = KotlinFacetSettingsProvider.getInstance(project)?.getInitializedSettings(this)?.isHmppEnabled ?: false // FIXME(dsavvinov): this logic is clearly wrong in MPP environment; review and fix val Project.platform: TargetPlatform? 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 328c4430c44..59f9465319d 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 @@ -290,6 +290,8 @@ interface KotlinFacetSettingsProvider { fun getInitializedSettings(module: Module): KotlinFacetSettings companion object { - fun getInstance(project: Project) = ServiceManager.getService(project, KotlinFacetSettingsProvider::class.java)!! + fun getInstance(project: Project): KotlinFacetSettingsProvider? { + return ServiceManager.getService(project, KotlinFacetSettingsProvider::class.java) + } } } diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.kt index f898dae827e..f6407b570bf 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.kt @@ -340,11 +340,13 @@ abstract class KotlinWithLibraryConfigurator protected constructor() : KotlinPro return } - val facetSettings = KotlinFacetSettingsProvider.getInstance(module.project).getInitializedSettings(module) - ModuleRootModificationUtil.updateModel(module) { - facetSettings.coroutineSupport = state - facetSettings.apiLevel = LanguageVersion.KOTLIN_1_1 - facetSettings.languageLevel = LanguageVersion.KOTLIN_1_1 + val facetSettings = KotlinFacetSettingsProvider.getInstance(module.project)?.getInitializedSettings(module) + if (facetSettings != null) { + ModuleRootModificationUtil.updateModel(module) { + facetSettings.coroutineSupport = state + facetSettings.apiLevel = LanguageVersion.KOTLIN_1_1 + facetSettings.languageLevel = LanguageVersion.KOTLIN_1_1 + } } } @@ -363,12 +365,14 @@ abstract class KotlinWithLibraryConfigurator protected constructor() : KotlinPro return } - val facetSettings = KotlinFacetSettingsProvider.getInstance(module.project).getInitializedSettings(module) - ModuleRootModificationUtil.updateModel(module) { - facetSettings.apiLevel = feature.sinceVersion - facetSettings.languageLevel = feature.sinceVersion - facetSettings.compilerSettings?.apply { - additionalArguments = additionalArguments.replaceLanguageFeature(feature, state, separator = " ", quoted = false) + val facetSettings = KotlinFacetSettingsProvider.getInstance(module.project)?.getInitializedSettings(module) + if (facetSettings != null) { + ModuleRootModificationUtil.updateModel(module) { + facetSettings.apiLevel = feature.sinceVersion + facetSettings.languageLevel = feature.sinceVersion + facetSettings.compilerSettings?.apply { + additionalArguments = additionalArguments.replaceLanguageFeature(feature, state, separator = " ", quoted = false) + } } } } @@ -382,14 +386,16 @@ abstract class KotlinWithLibraryConfigurator protected constructor() : KotlinPro return } - val facetSettings = KotlinFacetSettingsProvider.getInstance(module.project).getInitializedSettings(module) - ModuleRootModificationUtil.updateModel(module) { - with(facetSettings) { - if (languageVersion != null) { - languageLevel = LanguageVersion.fromVersionString(languageVersion) - } - if (apiVersion != null) { - apiLevel = LanguageVersion.fromVersionString(apiVersion) + val facetSettings = KotlinFacetSettingsProvider.getInstance(module.project)?.getInitializedSettings(module) + if (facetSettings != null) { + ModuleRootModificationUtil.updateModel(module) { + with(facetSettings) { + if (languageVersion != null) { + languageLevel = LanguageVersion.fromVersionString(languageVersion) + } + if (apiVersion != null) { + apiLevel = LanguageVersion.fromVersionString(apiVersion) + } } } } diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/quickfix/EnableUnsupportedFeatureFix.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/quickfix/EnableUnsupportedFeatureFix.kt index aa4c2487179..7199dfb8526 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/quickfix/EnableUnsupportedFeatureFix.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/quickfix/EnableUnsupportedFeatureFix.kt @@ -48,8 +48,8 @@ sealed class EnableUnsupportedFeatureFix( override fun invoke(project: Project, editor: Editor?, file: KtFile) { val module = ModuleUtilCore.findModuleForPsiElement(file) ?: return - val facetSettings = KotlinFacetSettingsProvider.getInstance(project).getInitializedSettings(module) - val targetApiLevel = facetSettings.apiLevel?.let { apiLevel -> + val facetSettings = KotlinFacetSettingsProvider.getInstance(project)?.getInitializedSettings(module) + val targetApiLevel = facetSettings?.apiLevel?.let { apiLevel -> if (ApiVersion.createByLanguageVersion(apiLevel) < feature.sinceApiVersion) feature.sinceApiVersion.versionString else diff --git a/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt b/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt index 22a28bb4540..acb4fd73b8d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt @@ -188,7 +188,10 @@ fun KotlinFacet.configureFacet( module.externalCompilerVersion = compilerVersion } -fun Module.externalSystemTestTasks() = KotlinFacetSettingsProvider.getInstance(project).getInitializedSettings(this).externalSystemTestTasks +fun Module.externalSystemTestTasks(): List { + val settingsProvider = KotlinFacetSettingsProvider.getInstance(project) ?: return emptyList() + return settingsProvider.getInitializedSettings(this).externalSystemTestTasks +} @Suppress("DEPRECATION_ERROR", "DeprecatedCallableAddReplaceWith") @Deprecated( diff --git a/idea/tests/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinInTempDirTest.kt b/idea/tests/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinInTempDirTest.kt index 3787297ae14..1fd374a4fe2 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinInTempDirTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinInTempDirTest.kt @@ -66,21 +66,27 @@ open class ConfigureKotlinInTempDirTest : AbstractConfigureKotlinInTempDirTest() } fun testProject106InconsistentVersionInConfig() { - val settings = KotlinFacetSettingsProvider.getInstance(myProject).getInitializedSettings(module) + val settings = KotlinFacetSettingsProvider.getInstance(myProject)?.getInitializedSettings(module) + ?: error("Facet settings are not found") + 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).getInitializedSettings(module) + val settings = KotlinFacetSettingsProvider.getInstance(myProject)?.getInitializedSettings(module) + ?: error("Facet settings are not found") + Assert.assertEquals(false, settings.useProjectSettings) Assert.assertEquals("1.0", settings.languageLevel!!.description) Assert.assertEquals("1.0", settings.apiLevel!!.description) } fun testFacetWithProjectSettings() { - val settings = KotlinFacetSettingsProvider.getInstance(myProject).getInitializedSettings(module) + val settings = KotlinFacetSettingsProvider.getInstance(myProject)?.getInitializedSettings(module) + ?: error("Facet settings are not found") + Assert.assertEquals(true, settings.useProjectSettings) Assert.assertEquals("1.1", settings.languageLevel!!.description) Assert.assertEquals("1.1", settings.apiLevel!!.description) diff --git a/idea/tests/org/jetbrains/kotlin/idea/highlighter/Jsr305HighlightingTest.kt b/idea/tests/org/jetbrains/kotlin/idea/highlighter/Jsr305HighlightingTest.kt index 2bbaba080d6..bbf24a63bab 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/highlighter/Jsr305HighlightingTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/highlighter/Jsr305HighlightingTest.kt @@ -35,9 +35,9 @@ class Jsr305HighlightingTest : KotlinLightCodeInsightFixtureTestCase() { override fun configureModule(module: Module, model: ModifiableRootModel) { super.configureModule(module, model) module.createFacet(JvmPlatforms.jvm18) - val facetSettings = KotlinFacetSettingsProvider.getInstance(module.project).getInitializedSettings(module) + val facetSettings = KotlinFacetSettingsProvider.getInstance(module.project)?.getInitializedSettings(module) - facetSettings.apply { + facetSettings?.apply { val jsrStateByTestName = ReportLevel.findByDescription(getTestName(true)) ?: return@apply diff --git a/idea/tests/org/jetbrains/kotlin/idea/stubs/AbstractMultiModuleTest.kt b/idea/tests/org/jetbrains/kotlin/idea/stubs/AbstractMultiModuleTest.kt index 86d1e152940..83e786e2ab9 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/stubs/AbstractMultiModuleTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/stubs/AbstractMultiModuleTest.kt @@ -109,7 +109,9 @@ abstract class AbstractMultiModuleTest : DaemonAnalyzerTestCase() { fun Module.enableMultiPlatform(additionalCompilerArguments: String = "") { createFacet() - val facetSettings = KotlinFacetSettingsProvider.getInstance(project).getInitializedSettings(this) + val facetSettings = KotlinFacetSettingsProvider.getInstance(project)?.getInitializedSettings(this) + ?: error("Facet settings are not found") + facetSettings.useProjectSettings = false facetSettings.compilerSettings = CompilerSettings().apply { additionalArguments += " -Xmulti-platform $additionalCompilerArguments" @@ -118,7 +120,9 @@ abstract class AbstractMultiModuleTest : DaemonAnalyzerTestCase() { fun Module.enableCoroutines() { createFacet() - val facetSettings = KotlinFacetSettingsProvider.getInstance(project).getInitializedSettings(this) + val facetSettings = KotlinFacetSettingsProvider.getInstance(project)?.getInitializedSettings(this) + ?: error("Facet settings are not found") + facetSettings.useProjectSettings = false facetSettings.coroutineSupport = LanguageFeature.State.ENABLED }