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:
Dmitry Jemerov
2017-07-20 18:44:34 +02:00
parent 0971af803c
commit f370d74609
11 changed files with 283 additions and 93 deletions
@@ -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?) {
@@ -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)
}
}
}
@@ -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)
}
}
}
}