diff --git a/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleConfiguratorTest.kt b/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleConfiguratorTest.kt index d7832413f2d..a7262942e65 100644 --- a/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleConfiguratorTest.kt +++ b/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleConfiguratorTest.kt @@ -1,17 +1,6 @@ /* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.idea.codeInsight.gradle @@ -202,7 +191,10 @@ class GradleConfiguratorTest : GradleImportingTestCase() { runReadAction { val configurator = findGradleModuleConfigurator() - val moduleNames = getCanBeConfiguredModulesWithKotlinFiles(myProject).map { it.name } + val (modules, ableToRunConfigurators) = getConfigurationPossibilities(myProject) + assertTrue(ableToRunConfigurators.any { it is KotlinGradleModuleConfigurator }) + assertTrue(ableToRunConfigurators.any { it is KotlinJsGradleModuleConfigurator }) + val moduleNames = modules.map { it.name } assertSameElements(moduleNames, "app") val moduleNamesFromConfigurator = getCanBeConfiguredModules(myProject, configurator).map { it.name } @@ -240,7 +232,7 @@ class GradleConfiguratorTest : GradleImportingTestCase() { importProject() runReadAction { - assertEmpty(getCanBeConfiguredModulesWithKotlinFiles(myProject)) + assertEmpty(getConfigurationPossibilities(myProject).first) } } @@ -271,7 +263,7 @@ class GradleConfiguratorTest : GradleImportingTestCase() { importProject() runReadAction { - assertEmpty(getCanBeConfiguredModulesWithKotlinFiles(myProject)) + assertEmpty(getConfigurationPossibilities(myProject).first) } } diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinInProjectUtils.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinInProjectUtils.kt index 2a54e89312c..008d24238a5 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinInProjectUtils.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinInProjectUtils.kt @@ -182,12 +182,31 @@ fun getCanBeConfiguredModulesWithKotlinFiles(project: Project, configurator: Kot return modules.filter { configurator.getStatus(it) == ConfigureKotlinStatus.CAN_BE_CONFIGURED }.map { it.baseModule } } -fun getCanBeConfiguredModulesWithKotlinFiles(project: Project, excludeModules: Collection = emptyList()): Collection { +fun getConfigurationPossibilities( + project: Project, + excludeModules: Collection = emptyList() +): Pair, Collection> { val modulesWithKotlinFiles = getConfigurableModulesWithKotlinFiles(project).exclude(excludeModules) val configurators = allConfigurators() - return modulesWithKotlinFiles.filter { moduleSourceRootGroup -> - configurators.any { it.getStatus(moduleSourceRootGroup) == ConfigureKotlinStatus.CAN_BE_CONFIGURED } - }.map { it.baseModule } + + val runnableConfigurators = mutableSetOf() + val configurableModules = mutableListOf() + + // We need to return all modules for which at least one configurator is applicable, as well as all configurators which + // are applicable for at least one module. At the same time we want to call getStatus() only once for each module/configurator pair. + for (moduleSourceRootGroup in modulesWithKotlinFiles) { + var moduleCanBeConfigured = false + for (configurator in configurators) { + if (moduleCanBeConfigured && configurator in runnableConfigurators) continue + if (configurator.getStatus(moduleSourceRootGroup) == ConfigureKotlinStatus.CAN_BE_CONFIGURED) { + moduleCanBeConfigured = true + runnableConfigurators.add(configurator) + } + } + if (moduleCanBeConfigured) configurableModules.add(moduleSourceRootGroup.baseModule) + } + + return configurableModules to runnableConfigurators } fun findApplicableConfigurator(module: Module): KotlinProjectConfigurator { diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/ui/notifications/ConfigureKotlinNotification.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/ui/notifications/ConfigureKotlinNotification.kt index d8ba799e941..2646c6e083c 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/ui/notifications/ConfigureKotlinNotification.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/ui/notifications/ConfigureKotlinNotification.kt @@ -1,17 +1,6 @@ /* - * Copyright 2010-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.idea.configuration.ui.notifications @@ -22,26 +11,27 @@ import com.intellij.notification.NotificationType import com.intellij.openapi.module.Module import com.intellij.openapi.project.Project import org.jetbrains.kotlin.idea.configuration.KotlinProjectConfigurator -import org.jetbrains.kotlin.idea.configuration.getAbleToRunConfigurators +import org.jetbrains.kotlin.idea.configuration.getConfigurationPossibilities import org.jetbrains.kotlin.idea.configuration.getConfiguratorByName -import org.jetbrains.kotlin.idea.configuration.getCanBeConfiguredModulesWithKotlinFiles import org.jetbrains.kotlin.idea.configuration.ui.KotlinConfigurationCheckerComponent import javax.swing.event.HyperlinkEvent class ConfigureKotlinNotification( - project: Project, - excludeModules: List, - notificationString: String) : Notification(KotlinConfigurationCheckerComponent.CONFIGURE_NOTIFICATION_GROUP_ID, "Configure Kotlin", - notificationString, - NotificationType.WARNING, NotificationListener { notification, event -> - if (event.eventType == HyperlinkEvent.EventType.ACTIVATED) { - val configurator = getConfiguratorByName(event.description) ?: throw AssertionError("Missed action: " + event.description) - notification.expire() + project: Project, + excludeModules: List, + notificationString: String +) : Notification( + KotlinConfigurationCheckerComponent.CONFIGURE_NOTIFICATION_GROUP_ID, "Configure Kotlin", + notificationString, + NotificationType.WARNING, NotificationListener { notification, event -> + if (event.eventType == HyperlinkEvent.EventType.ACTIVATED) { + val configurator = getConfiguratorByName(event.description) ?: throw AssertionError("Missed action: " + event.description) + notification.expire() - configurator.configure(project, excludeModules) + configurator.configure(project, excludeModules) + } } -}) { - +) { override fun equals(o: Any?): Boolean { if (this === o) return true if (o !is ConfigureKotlinNotification) return false @@ -57,15 +47,14 @@ class ConfigureKotlinNotification( companion object { fun getNotificationString(project: Project, excludeModules: Collection): String? { - val modules = getCanBeConfiguredModulesWithKotlinFiles(project, excludeModules) - - val isOnlyOneModule = modules.size == 1 - - val modulesString = if (isOnlyOneModule) "'${modules.first().name}' module" else "modules" - val ableToRunConfigurators = getAbleToRunConfigurators(project) + val (configurableModules, ableToRunConfigurators) = getConfigurationPossibilities(project, excludeModules) if (ableToRunConfigurators.isEmpty()) return null - val links = ableToRunConfigurators.joinToString(separator = "
") { - configurator -> getLink(configurator, isOnlyOneModule) + + val isOnlyOneModule = configurableModules.size == 1 + + val modulesString = if (isOnlyOneModule) "'${configurableModules.first().name}' module" else "modules" + val links = ableToRunConfigurators.joinToString(separator = "
") { configurator -> + getLink(configurator, isOnlyOneModule) } return "Configure $modulesString in '${project.name}' project
$links"