Correctly detect stdlib in Gradle projects; move detection out of EDT
To detect whether a module has an stdlib in its dependencies, look at source root modules and not at base module.
This commit is contained in:
@@ -55,6 +55,8 @@ inline fun <K, V> MutableMap<K, V>.getOrPutNullable(key: K, defaultValue: () ->
|
||||
|
||||
inline fun <T, C: Collection<T>> C.ifEmpty(body: () -> C): C = if (isEmpty()) body() else this
|
||||
|
||||
inline fun <K, V, M: Map<K, V>> M.ifEmpty(body: () -> M): M = if (isEmpty()) body() else this
|
||||
|
||||
inline fun <T> Array<out T>.ifEmpty(body: () -> Array<out T>): Array<out T> = if (isEmpty()) body() else this
|
||||
|
||||
fun <T: Any> MutableCollection<T>.addIfNotNull(t: T?) {
|
||||
|
||||
+2
-1
@@ -48,7 +48,8 @@ abstract class KotlinMavenConfigurator
|
||||
override val name: String,
|
||||
override val presentableText: String) : KotlinProjectConfigurator {
|
||||
|
||||
override fun getStatus(module: Module): ConfigureKotlinStatus {
|
||||
override fun getStatus(moduleSourceRootGroup: ModuleSourceRootGroup): ConfigureKotlinStatus {
|
||||
val module = moduleSourceRootGroup.baseModule
|
||||
if (!KotlinPluginUtil.isMavenModule(module))
|
||||
return ConfigureKotlinStatus.NON_APPLICABLE
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@ import org.jetbrains.kotlin.idea.configuration.*
|
||||
import org.jetbrains.kotlin.idea.util.projectStructure.allModules
|
||||
import org.jetbrains.kotlin.js.resolve.JsPlatform
|
||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
|
||||
import org.jetbrains.kotlin.utils.ifEmpty
|
||||
|
||||
abstract class ConfigureKotlinInProjectAction : AnAction() {
|
||||
|
||||
@@ -35,7 +34,7 @@ abstract class ConfigureKotlinInProjectAction : AnAction() {
|
||||
override fun actionPerformed(e: AnActionEvent) {
|
||||
val project = e.project ?: return
|
||||
|
||||
val modules = getConfigurableModulesWithKotlinFiles(project).ifEmpty { project.allModules() }
|
||||
val modules = getConfigurableModules(project)
|
||||
if (modules.all(::isModuleConfigured)) {
|
||||
Messages.showInfoMessage("All modules with Kotlin files are configured", e.presentation.text!!)
|
||||
return
|
||||
|
||||
@@ -18,9 +18,7 @@ package org.jetbrains.kotlin.idea.configuration
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.extensions.Extensions
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.module.ModuleManager
|
||||
import com.intellij.openapi.project.DumbService
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.roots.DependencyScope
|
||||
@@ -30,6 +28,7 @@ import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||
import org.jetbrains.kotlin.idea.configuration.ui.notifications.ConfigureKotlinNotification
|
||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||
import org.jetbrains.kotlin.idea.util.projectStructure.allModules
|
||||
import org.jetbrains.kotlin.idea.versions.getKotlinJvmRuntimeMarkerClass
|
||||
import org.jetbrains.kotlin.idea.versions.hasKotlinJsKjsmFile
|
||||
@@ -96,9 +95,9 @@ fun getRepositoryForVersion(version: String): RepositoryDescription? = when {
|
||||
else -> null
|
||||
}
|
||||
|
||||
fun isModuleConfigured(module: Module): Boolean {
|
||||
fun isModuleConfigured(moduleSourceRootGroup: ModuleSourceRootGroup): Boolean {
|
||||
return allConfigurators().any {
|
||||
it.getStatus(module) == ConfigureKotlinStatus.CONFIGURED
|
||||
it.getStatus(moduleSourceRootGroup) == ConfigureKotlinStatus.CONFIGURED
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,57 +106,67 @@ fun getModulesWithKotlinFiles(project: Project): Collection<Module> {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
if (!FileTypeIndex.containsFileOfType(KotlinFileType.INSTANCE, GlobalSearchScope.projectScope(project))) {
|
||||
if (!runReadAction { FileTypeIndex.containsFileOfType (KotlinFileType.INSTANCE, GlobalSearchScope.projectScope(project)) }) {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
return project.allModules()
|
||||
.filter { module ->
|
||||
FileTypeIndex.containsFileOfType(KotlinFileType.INSTANCE, module.getModuleScope(true))
|
||||
runReadAction {
|
||||
FileTypeIndex.containsFileOfType(KotlinFileType.INSTANCE, module.getModuleScope(true))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getConfigurableModulesWithKotlinFiles(project: Project): Collection<Module> {
|
||||
fun getConfigurableModulesWithKotlinFiles(project: Project): List<ModuleSourceRootGroup> {
|
||||
val modules = getModulesWithKotlinFiles(project)
|
||||
if (modules.isEmpty()) return modules
|
||||
if (modules.isEmpty()) return emptyList()
|
||||
|
||||
val pathMap = ModuleManager.getInstance(project).modules.asList().buildExternalPathMap()
|
||||
return modules.mapTo(HashSet()) { module ->
|
||||
val externalPath = module.externalProjectPath
|
||||
if (externalPath == null) module else (pathMap[externalPath] ?: module)
|
||||
}
|
||||
return ModuleSourceRootMap(project).groupByBaseModules(modules)
|
||||
}
|
||||
|
||||
fun showConfigureKotlinNotificationIfNeeded(module: Module) {
|
||||
if (isModuleConfigured(module)) return
|
||||
val moduleGroup = ModuleSourceRootMap(module.project).toModuleGroup(module)
|
||||
if (isModuleConfigured(moduleGroup)) return
|
||||
|
||||
ConfigureKotlinNotificationManager.notify(module.project)
|
||||
}
|
||||
|
||||
fun showConfigureKotlinNotificationIfNeeded(project: Project, excludeModules: List<Module> = emptyList()) {
|
||||
ApplicationManager.getApplication().executeOnPooledThread {
|
||||
val notificationString = DumbService.getInstance(project).runReadActionInSmartMode(Computable {
|
||||
val modules = getConfigurableModulesWithKotlinFiles(project) - excludeModules
|
||||
if (modules.all(::isModuleConfigured)) null else ConfigureKotlinNotification.getNotificationString(project, excludeModules)
|
||||
})
|
||||
if (notificationString != null) {
|
||||
ApplicationManager.getApplication().invokeLater {
|
||||
ConfigureKotlinNotificationManager.notify(project, ConfigureKotlinNotification(project, excludeModules, notificationString))
|
||||
}
|
||||
val notificationString = DumbService.getInstance(project).runReadActionInSmartMode(Computable {
|
||||
val modules = getConfigurableModulesWithKotlinFiles(project).exclude(excludeModules)
|
||||
if (modules.all(::isModuleConfigured))
|
||||
null
|
||||
else
|
||||
ConfigureKotlinNotification.getNotificationString(project, excludeModules)
|
||||
})
|
||||
|
||||
if (notificationString != null) {
|
||||
ApplicationManager.getApplication().invokeLater {
|
||||
ConfigureKotlinNotificationManager.notify(project, ConfigureKotlinNotification(project, excludeModules, notificationString))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getAbleToRunConfigurators(project: Project): Collection<KotlinProjectConfigurator> {
|
||||
val modules = getConfigurableModulesWithKotlinFiles(project).ifEmpty { project.allModules() }
|
||||
val modules = getConfigurableModules(project)
|
||||
|
||||
return allConfigurators().filter { configurator ->
|
||||
modules.any { module -> configurator.getStatus(module) == ConfigureKotlinStatus.CAN_BE_CONFIGURED }
|
||||
modules.any { configurator.getStatus(it) == ConfigureKotlinStatus.CAN_BE_CONFIGURED }
|
||||
}
|
||||
}
|
||||
|
||||
fun getConfigurableModules(project: Project): List<ModuleSourceRootGroup> {
|
||||
return getConfigurableModulesWithKotlinFiles(project).ifEmpty {
|
||||
ModuleSourceRootMap(project).groupByBaseModules(project.allModules())
|
||||
}
|
||||
}
|
||||
|
||||
fun getAbleToRunConfigurators(module: Module): Collection<KotlinProjectConfigurator> {
|
||||
return allConfigurators().filter { it.getStatus(module) == ConfigureKotlinStatus.CAN_BE_CONFIGURED }
|
||||
val moduleGroup = ModuleSourceRootMap(module.project).toModuleGroup(module)
|
||||
return allConfigurators().filter {
|
||||
it.getStatus(moduleGroup) == ConfigureKotlinStatus.CAN_BE_CONFIGURED
|
||||
}
|
||||
}
|
||||
|
||||
fun getConfiguratorByName(name: String): KotlinProjectConfigurator? {
|
||||
@@ -167,56 +176,26 @@ fun getConfiguratorByName(name: String): KotlinProjectConfigurator? {
|
||||
fun allConfigurators() = Extensions.getExtensions(KotlinProjectConfigurator.EP_NAME)
|
||||
|
||||
fun getCanBeConfiguredModules(project: Project, configurator: KotlinProjectConfigurator): List<Module> {
|
||||
return project.allModules()
|
||||
.filter { module -> configurator.canConfigure(module) }
|
||||
.excludeSourceRootModules()
|
||||
return ModuleSourceRootMap(project).groupByBaseModules(project.allModules())
|
||||
.filter { configurator.canConfigure(it) }
|
||||
.map { it.baseModule }
|
||||
}
|
||||
|
||||
private fun KotlinProjectConfigurator.canConfigure(module: Module) =
|
||||
getStatus(module) == ConfigureKotlinStatus.CAN_BE_CONFIGURED &&
|
||||
(allConfigurators().toList() - this).none { it.getStatus(module) == ConfigureKotlinStatus.CONFIGURED }
|
||||
|
||||
fun Collection<Module>.excludeSourceRootModules(): List<Module> {
|
||||
val pathMap = buildExternalPathMap()
|
||||
return filter { it.externalProjectId == null || it.externalProjectPath == null } + pathMap.values
|
||||
}
|
||||
|
||||
fun Collection<Module>.buildExternalPathMap(): Map<String, Module> {
|
||||
val pathMap = mutableMapOf<String, Module>()
|
||||
for (module in this) {
|
||||
val externalId = module.externalProjectId
|
||||
val externalPath = module.externalProjectPath
|
||||
if (externalId != null && externalPath != null) {
|
||||
val previousModule = pathMap[externalPath]
|
||||
// the module without the source root suffix will have the shortest name
|
||||
if (previousModule == null || isSourceRootPrefix(externalId, previousModule.externalProjectId!!)) {
|
||||
pathMap[externalPath] = module
|
||||
}
|
||||
}
|
||||
}
|
||||
return pathMap
|
||||
}
|
||||
|
||||
private fun isSourceRootPrefix(externalId: String, previousModuleExternalId: String)
|
||||
= externalId.length < previousModuleExternalId.length && previousModuleExternalId.startsWith(externalId)
|
||||
|
||||
val Module.externalProjectId: String?
|
||||
get() = ExternalSystemApiUtil.getExternalProjectId(this)
|
||||
|
||||
val Module.externalProjectPath: String?
|
||||
get() = ExternalSystemApiUtil.getExternalProjectPath(this)
|
||||
private fun KotlinProjectConfigurator.canConfigure(moduleSourceRootGroup: ModuleSourceRootGroup) =
|
||||
getStatus(moduleSourceRootGroup) == ConfigureKotlinStatus.CAN_BE_CONFIGURED &&
|
||||
(allConfigurators().toList() - this).none { it.getStatus(moduleSourceRootGroup) == ConfigureKotlinStatus.CONFIGURED }
|
||||
|
||||
fun getCanBeConfiguredModulesWithKotlinFiles(project: Project, configurator: KotlinProjectConfigurator): List<Module> {
|
||||
val modules = getConfigurableModulesWithKotlinFiles(project)
|
||||
return modules.filter { module -> configurator.getStatus(module) == ConfigureKotlinStatus.CAN_BE_CONFIGURED }
|
||||
return modules.filter { configurator.getStatus(it) == ConfigureKotlinStatus.CAN_BE_CONFIGURED }.map { it.baseModule }
|
||||
}
|
||||
|
||||
fun getCanBeConfiguredModulesWithKotlinFiles(project: Project, excludeModules: Collection<Module> = emptyList()): Collection<Module> {
|
||||
val modulesWithKotlinFiles = getConfigurableModulesWithKotlinFiles(project) - excludeModules
|
||||
val modulesWithKotlinFiles = getConfigurableModulesWithKotlinFiles(project).exclude(excludeModules)
|
||||
val configurators = allConfigurators()
|
||||
return modulesWithKotlinFiles.filter { module ->
|
||||
configurators.any { it.getStatus(module) == ConfigureKotlinStatus.CAN_BE_CONFIGURED }
|
||||
}
|
||||
return modulesWithKotlinFiles.filter { moduleSourceRootGroup ->
|
||||
configurators.any { it.getStatus(moduleSourceRootGroup) == ConfigureKotlinStatus.CAN_BE_CONFIGURED }
|
||||
}.map { it.baseModule }
|
||||
}
|
||||
|
||||
fun hasAnyKotlinRuntimeInScope(module: Module): Boolean {
|
||||
|
||||
@@ -37,7 +37,7 @@ enum class ConfigureKotlinStatus {
|
||||
|
||||
interface KotlinProjectConfigurator {
|
||||
|
||||
fun getStatus(module: Module): ConfigureKotlinStatus
|
||||
fun getStatus(moduleSourceRootGroup: ModuleSourceRootGroup): ConfigureKotlinStatus
|
||||
|
||||
@JvmSuppressWildcards fun configure(project: Project, excludeModules: Collection<Module>)
|
||||
|
||||
|
||||
@@ -46,12 +46,13 @@ import java.util.*
|
||||
|
||||
abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator {
|
||||
|
||||
override fun getStatus(module: Module): ConfigureKotlinStatus {
|
||||
override fun getStatus(moduleSourceRootGroup: ModuleSourceRootGroup): ConfigureKotlinStatus {
|
||||
val module = moduleSourceRootGroup.baseModule
|
||||
if (!isApplicable(module)) {
|
||||
return ConfigureKotlinStatus.NON_APPLICABLE
|
||||
}
|
||||
|
||||
if (hasAnyKotlinRuntimeInScope(module)) {
|
||||
if (moduleSourceRootGroup.sourceRootModules.all(::hasAnyKotlinRuntimeInScope)) {
|
||||
return ConfigureKotlinStatus.CONFIGURED
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,8 @@ abstract class KotlinWithLibraryConfigurator internal constructor() : KotlinProj
|
||||
|
||||
protected val libraryKind: PersistentLibraryKind<*>? = libraryType?.kind
|
||||
|
||||
override fun getStatus(module: Module): ConfigureKotlinStatus {
|
||||
override fun getStatus(moduleSourceRootGroup: ModuleSourceRootGroup): ConfigureKotlinStatus {
|
||||
val module = moduleSourceRootGroup.baseModule
|
||||
if (!isApplicable(module)) {
|
||||
return ConfigureKotlinStatus.NON_APPLICABLE
|
||||
}
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.configuration
|
||||
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.idea.util.projectStructure.allModules
|
||||
|
||||
class ModuleSourceRootGroup(val baseModule: Module,
|
||||
val sourceRootModules: List<Module>)
|
||||
|
||||
class ModuleSourceRootMap(val modules: Collection<Module>) {
|
||||
private val baseModuleByExternalPath: Map<String, Module>
|
||||
private val allModulesByExternalPath: Map<String, List<Module>>
|
||||
|
||||
constructor(project: Project): this(project.allModules())
|
||||
|
||||
init {
|
||||
allModulesByExternalPath = modules
|
||||
.filter { it.externalProjectPath != null && it.externalProjectId != null }
|
||||
.groupBy { it.externalProjectPath!! }
|
||||
|
||||
baseModuleByExternalPath = allModulesByExternalPath
|
||||
.mapValues { (path, modules) ->
|
||||
modules.reduce { m1, m2 ->
|
||||
if (isSourceRootPrefix(m2.externalProjectId!!, m1.externalProjectId!!)) m2 else m1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun groupByBaseModules(modules: Collection<Module>): List<ModuleSourceRootGroup> {
|
||||
return modules
|
||||
.groupBy { module ->
|
||||
val externalPath = module.externalProjectPath
|
||||
if (externalPath == null) module else (baseModuleByExternalPath[externalPath] ?: module)
|
||||
}
|
||||
.map { (module, sourceRootModules) ->
|
||||
ModuleSourceRootGroup(module,
|
||||
if (sourceRootModules.size > 1) sourceRootModules - module else sourceRootModules)
|
||||
}
|
||||
}
|
||||
|
||||
fun toModuleGroup(module: Module): ModuleSourceRootGroup = groupByBaseModules(listOf(module)).single()
|
||||
}
|
||||
|
||||
private fun isSourceRootPrefix(externalId: String, previousModuleExternalId: String)
|
||||
= externalId.length < previousModuleExternalId.length && previousModuleExternalId.startsWith(externalId)
|
||||
|
||||
val Module.externalProjectId: String?
|
||||
get() = ExternalSystemApiUtil.getExternalProjectId(this)
|
||||
|
||||
val Module.externalProjectPath: String?
|
||||
get() = ExternalSystemApiUtil.getExternalProjectPath(this)
|
||||
|
||||
fun List<ModuleSourceRootGroup>.exclude(excludeModules: Collection<Module>): List<ModuleSourceRootGroup> {
|
||||
return mapNotNull {
|
||||
if (it.baseModule in excludeModules)
|
||||
null
|
||||
else {
|
||||
val remainingSourceRootModules = it.sourceRootModules - excludeModules
|
||||
if (remainingSourceRootModules.isEmpty())
|
||||
null
|
||||
else
|
||||
ModuleSourceRootGroup(it.baseModule, remainingSourceRootModules)
|
||||
}
|
||||
}
|
||||
}
|
||||
+15
-13
@@ -23,13 +23,10 @@ import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.components.AbstractProjectComponent
|
||||
import com.intellij.openapi.project.DumbService
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.roots.ModuleRootAdapter
|
||||
import com.intellij.openapi.roots.ModuleRootEvent
|
||||
import com.intellij.openapi.roots.ModuleRootListener
|
||||
import com.intellij.openapi.startup.StartupManager
|
||||
import org.jetbrains.kotlin.idea.configuration.ConfigureKotlinNotificationManager
|
||||
import org.jetbrains.kotlin.idea.configuration.getModulesWithKotlinFiles
|
||||
import org.jetbrains.kotlin.idea.configuration.isModuleConfigured
|
||||
import org.jetbrains.kotlin.idea.configuration.showConfigureKotlinNotificationIfNeeded
|
||||
import org.jetbrains.kotlin.idea.configuration.*
|
||||
import org.jetbrains.kotlin.idea.project.getAndCacheLanguageLevelByDependencies
|
||||
import org.jetbrains.kotlin.idea.versions.collectModulesWithOutdatedRuntime
|
||||
import org.jetbrains.kotlin.idea.versions.findOutdatedKotlinLibraries
|
||||
@@ -44,10 +41,11 @@ class KotlinConfigurationCheckerComponent(project: Project) : AbstractProjectCom
|
||||
NotificationsConfiguration.getNotificationsConfiguration().register(CONFIGURE_NOTIFICATION_GROUP_ID, NotificationDisplayType.STICKY_BALLOON, true)
|
||||
|
||||
val connection = project.messageBus.connect()
|
||||
connection.subscribe(ProjectTopics.PROJECT_ROOTS, object : ModuleRootAdapter() {
|
||||
connection.subscribe(ProjectTopics.PROJECT_ROOTS, object : ModuleRootListener {
|
||||
override fun rootsChanged(event: ModuleRootEvent?) {
|
||||
if (notificationPostponed && !isSyncing) {
|
||||
DumbService.getInstance(myProject).smartInvokeLater {
|
||||
ApplicationManager.getApplication().executeOnPooledThread {
|
||||
DumbService.getInstance(myProject).waitForSmartMode()
|
||||
if (!isSyncing) {
|
||||
notificationPostponed = false
|
||||
showConfigureKotlinNotificationIfNeeded(myProject,
|
||||
@@ -59,7 +57,7 @@ class KotlinConfigurationCheckerComponent(project: Project) : AbstractProjectCom
|
||||
if (ConfigureKotlinNotificationManager.getVisibleNotifications(project).isNotEmpty()) {
|
||||
ApplicationManager.getApplication().executeOnPooledThread {
|
||||
DumbService.getInstance(myProject).waitForSmartMode()
|
||||
if (getModulesWithKotlinFiles(project).all(::isModuleConfigured)) {
|
||||
if (getConfigurableModulesWithKotlinFiles(project).all(::isModuleConfigured)) {
|
||||
ApplicationManager.getApplication().invokeLater {
|
||||
ConfigureKotlinNotificationManager.expireOldNotifications(project)
|
||||
}
|
||||
@@ -74,18 +72,22 @@ class KotlinConfigurationCheckerComponent(project: Project) : AbstractProjectCom
|
||||
super.projectOpened()
|
||||
|
||||
StartupManager.getInstance(myProject).registerPostStartupActivity {
|
||||
DumbService.getInstance(myProject).smartInvokeLater {
|
||||
ApplicationManager.getApplication().executeOnPooledThread {
|
||||
DumbService.getInstance(myProject).waitForSmartMode()
|
||||
|
||||
for (module in getModulesWithKotlinFiles(myProject)) {
|
||||
module.getAndCacheLanguageLevelByDependencies()
|
||||
}
|
||||
|
||||
val libraries = findOutdatedKotlinLibraries(myProject)
|
||||
if (!libraries.isEmpty()) {
|
||||
notifyOutdatedKotlinRuntime(myProject, libraries)
|
||||
ApplicationManager.getApplication().invokeLater {
|
||||
notifyOutdatedKotlinRuntime(myProject, libraries)
|
||||
}
|
||||
}
|
||||
if (syncDepth.get() == 0) {
|
||||
showConfigureKotlinNotificationIfNeeded(myProject,
|
||||
collectModulesWithOutdatedRuntime(libraries))
|
||||
if (!isSyncing) {
|
||||
val excludeModules = collectModulesWithOutdatedRuntime(libraries)
|
||||
showConfigureKotlinNotificationIfNeeded(myProject, excludeModules)
|
||||
}
|
||||
else {
|
||||
notificationPostponed = true
|
||||
|
||||
@@ -60,11 +60,12 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
|
||||
myProject.baseDir.createChildData(null, "build.gradle")
|
||||
|
||||
val module = ModuleManager.getInstance(myProject).findModuleByName("app")!!
|
||||
val moduleGroup = ModuleSourceRootMap(myProject).toModuleGroup(module)
|
||||
// We have a Kotlin runtime in build.gradle but not in the classpath, so it doesn't make sense
|
||||
// to suggest configuring it
|
||||
assertEquals(ConfigureKotlinStatus.BROKEN, findGradleModuleConfigurator().getStatus(module))
|
||||
assertEquals(ConfigureKotlinStatus.BROKEN, findGradleModuleConfigurator().getStatus(moduleGroup))
|
||||
// Don't offer the JS configurator if the JVM configuration exists but is broken
|
||||
assertEquals(ConfigureKotlinStatus.BROKEN, findJsGradleModuleConfigurator().getStatus(module))
|
||||
assertEquals(ConfigureKotlinStatus.BROKEN, findJsGradleModuleConfigurator().getStatus(moduleGroup))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -212,6 +213,68 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testListNonConfiguredModules_Configured() {
|
||||
createProjectSubFile("settings.gradle", "include ':app'")
|
||||
createProjectSubFile("app/build.gradle", """
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'java'
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile "org.jetbrains.kotlin:kotlin-stdlib:1.1.3"
|
||||
}
|
||||
""".trimIndent())
|
||||
createProjectSubFile("app/src/main/java/foo.kt", "")
|
||||
|
||||
importProject()
|
||||
|
||||
runReadAction {
|
||||
assertEmpty(getCanBeConfiguredModulesWithKotlinFiles(myProject))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testListNonConfiguredModules_ConfiguredOnlyTest() {
|
||||
createProjectSubFile("settings.gradle", "include ':app'")
|
||||
createProjectSubFile("app/build.gradle", """
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'java'
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testCompile "org.jetbrains.kotlin:kotlin-stdlib:1.1.3"
|
||||
}
|
||||
""".trimIndent())
|
||||
createProjectSubFile("app/src/test/java/foo.kt", "")
|
||||
|
||||
importProject()
|
||||
|
||||
runReadAction {
|
||||
assertEmpty(getCanBeConfiguredModulesWithKotlinFiles(myProject))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAddNonKotlinLibraryGSK() {
|
||||
val buildScript = createProjectSubFile("build.gradle.kts",
|
||||
@@ -751,5 +814,4 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
|
||||
}
|
||||
""".trimIndent(), LoadTextUtil.loadText(buildScript).toString())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.idea.codeInsight.gradle
|
||||
|
||||
import com.intellij.openapi.application.Result
|
||||
import com.intellij.openapi.application.WriteAction
|
||||
import com.intellij.openapi.application.runReadAction
|
||||
import com.intellij.openapi.projectRoots.JavaSdk
|
||||
import com.intellij.openapi.projectRoots.ProjectJdkTable
|
||||
import com.intellij.openapi.roots.LibraryOrderEntry
|
||||
@@ -27,9 +28,13 @@ import com.intellij.openapi.util.text.StringUtil
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
||||
import org.jetbrains.kotlin.config.*
|
||||
import org.jetbrains.kotlin.idea.configuration.ConfigureKotlinStatus
|
||||
import org.jetbrains.kotlin.idea.configuration.ModuleSourceRootMap
|
||||
import org.jetbrains.kotlin.idea.configuration.allConfigurators
|
||||
import org.jetbrains.kotlin.idea.facet.KotlinFacet
|
||||
import org.jetbrains.kotlin.idea.framework.CommonLibraryKind
|
||||
import org.jetbrains.kotlin.idea.framework.JSLibraryKind
|
||||
import org.jetbrains.kotlin.idea.util.projectStructure.allModules
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
import java.io.File
|
||||
@@ -46,9 +51,6 @@ class GradleFacetImportTest : GradleImportingTestCase() {
|
||||
@Test
|
||||
fun testJvmImport() {
|
||||
createProjectSubFile("build.gradle", """
|
||||
group 'Again'
|
||||
version '1.0-SNAPSHOT'
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
@@ -97,6 +99,48 @@ class GradleFacetImportTest : GradleImportingTestCase() {
|
||||
Assert.assertEquals("-Xdump-declarations-to=tmpTest",
|
||||
compilerSettings!!.additionalArguments)
|
||||
}
|
||||
|
||||
assertAllModulesConfigured()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testJvmImportWithPlugin() {
|
||||
createProjectSubFile("build.gradle", """
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
id "org.jetbrains.kotlin.jvm" version "1.1.3"
|
||||
}
|
||||
|
||||
version '1.0-SNAPSHOT'
|
||||
|
||||
apply plugin: 'java'
|
||||
|
||||
sourceCompatibility = 1.8
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:1.1.3"
|
||||
testCompile group: 'junit', name: 'junit', version: '4.12'
|
||||
}
|
||||
|
||||
compileKotlin {
|
||||
kotlinOptions.jvmTarget = "1.8"
|
||||
}
|
||||
compileTestKotlin {
|
||||
kotlinOptions.jvmTarget = "1.8"
|
||||
}
|
||||
""")
|
||||
importProject()
|
||||
|
||||
assertAllModulesConfigured()
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -227,6 +271,8 @@ class GradleFacetImportTest : GradleImportingTestCase() {
|
||||
Assert.assertEquals("-Xdump-declarations-to=tmpTest",
|
||||
compilerSettings!!.additionalArguments)
|
||||
}
|
||||
|
||||
assertAllModulesConfigured()
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -436,6 +482,8 @@ class GradleFacetImportTest : GradleImportingTestCase() {
|
||||
val rootManager = ModuleRootManager.getInstance(getModule("project_main"))
|
||||
val stdlib = rootManager.orderEntries.filterIsInstance<LibraryOrderEntry>().single().library
|
||||
assertEquals(JSLibraryKind, (stdlib as LibraryEx).kind)
|
||||
|
||||
assertAllModulesConfigured()
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -511,6 +559,8 @@ class GradleFacetImportTest : GradleImportingTestCase() {
|
||||
Assert.assertEquals("-main callTest",
|
||||
compilerSettings!!.additionalArguments)
|
||||
}
|
||||
|
||||
assertAllModulesConfigured()
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1160,4 +1210,15 @@ class GradleFacetImportTest : GradleImportingTestCase() {
|
||||
}.execute()
|
||||
}
|
||||
}
|
||||
|
||||
private fun assertAllModulesConfigured() {
|
||||
runReadAction {
|
||||
for (moduleGroup in ModuleSourceRootMap(myProject).groupByBaseModules(myProject.allModules())) {
|
||||
val configurator = allConfigurators().find {
|
||||
it.getStatus(moduleGroup) == ConfigureKotlinStatus.CAN_BE_CONFIGURED
|
||||
}
|
||||
Assert.assertNull("Configurator $configurator tells that ${moduleGroup.baseModule} can be configured", configurator)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user