Avoid duplicate scan of modules with Kotlin files (KT-23183)

This commit is contained in:
Dmitry Jemerov
2018-03-08 17:25:54 +01:00
parent 1be33b91fa
commit fa39cec94b
3 changed files with 54 additions and 54 deletions
@@ -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)
}
}
@@ -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<Module> = emptyList()): Collection<Module> {
fun getConfigurationPossibilities(
project: Project,
excludeModules: Collection<Module> = emptyList()
): Pair<Collection<Module>, Collection<KotlinProjectConfigurator>> {
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<KotlinProjectConfigurator>()
val configurableModules = mutableListOf<Module>()
// 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 {
@@ -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<Module>,
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<Module>,
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<Module>): 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 = "<br/>") {
configurator -> getLink(configurator, isOnlyOneModule)
val isOnlyOneModule = configurableModules.size == 1
val modulesString = if (isOnlyOneModule) "'${configurableModules.first().name}' module" else "modules"
val links = ableToRunConfigurators.joinToString(separator = "<br/>") { configurator ->
getLink(configurator, isOnlyOneModule)
}
return "Configure $modulesString in '${project.name}' project<br/> $links"