diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/framework/JsLibraryStdDetectionUtil.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/framework/JsLibraryStdDetectionUtil.kt index 64f8649bee0..b167c351b1e 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/framework/JsLibraryStdDetectionUtil.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/framework/JsLibraryStdDetectionUtil.kt @@ -33,9 +33,9 @@ import java.util.jar.Attributes object JsLibraryStdDetectionUtil { private val IS_JS_LIBRARY_STD_LIB = Key.create("IS_JS_LIBRARY_STD_LIB") - fun hasJsStdlibJar(library: Library): Boolean { + fun hasJsStdlibJar(library: Library, ignoreKind: Boolean = false): Boolean { if (library !is LibraryEx || library.isDisposed) return false - if (library.kind !is JSLibraryKind) return false + if (!ignoreKind && library.kind !is JSLibraryKind) return false val classes = Arrays.asList(*library.getFiles(OrderRootType.CLASSES)) return getJsStdLibJar(classes) != null diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/ProjectStructureUtil.java b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/ProjectStructureUtil.java index 3cbda09fd3f..f777e90c25d 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/ProjectStructureUtil.java +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/ProjectStructureUtil.java @@ -90,7 +90,7 @@ public class ProjectStructureUtil { ModuleRootManager.getInstance(module).orderEntries().librariesOnly().forEachLibrary(new Processor() { @Override public boolean process(Library library) { - if (JsLibraryStdDetectionUtil.INSTANCE.hasJsStdlibJar(library)) { + if (JsLibraryStdDetectionUtil.INSTANCE.hasJsStdlibJar(library, false)) { jsLibrary.set(library); return false; } diff --git a/idea/src/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinInProjectUtils.kt b/idea/src/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinInProjectUtils.kt index 31477146248..a99176c4f14 100644 --- a/idea/src/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinInProjectUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinInProjectUtils.kt @@ -22,12 +22,19 @@ import com.intellij.openapi.module.Module import com.intellij.openapi.project.DumbService import com.intellij.openapi.project.Project import com.intellij.openapi.roots.DependencyScope +import com.intellij.openapi.roots.LibraryOrderEntry +import com.intellij.openapi.roots.ModuleRootManager +import com.intellij.openapi.roots.impl.libraries.LibraryEx +import com.intellij.openapi.roots.libraries.PersistentLibraryKind import com.intellij.openapi.util.Computable +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.psi.search.DelegatingGlobalSearchScope import com.intellij.psi.search.FileTypeIndex 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.framework.JSLibraryKind import org.jetbrains.kotlin.idea.util.application.runReadAction import org.jetbrains.kotlin.idea.util.projectStructure.allModules import org.jetbrains.kotlin.idea.versions.getKotlinJvmRuntimeMarkerClass @@ -202,7 +209,7 @@ fun hasAnyKotlinRuntimeInScope(module: Module): Boolean { val scope = module.getModuleWithDependenciesAndLibrariesScope(hasKotlinFilesOnlyInTests(module)) return runReadAction { getKotlinJvmRuntimeMarkerClass(module.project, scope) != null || - hasKotlinJsKjsmFile(module.project, scope) || + hasKotlinJsKjsmFile(module.project, LibraryKindSearchScope(module, scope, JSLibraryKind) ) || hasKotlinCommonRuntimeInScope(scope) } } @@ -217,7 +224,7 @@ fun hasKotlinJvmRuntimeInScope(module: Module): Boolean { fun hasKotlinJsRuntimeInScope(module: Module): Boolean { return runReadAction { val scope = module.getModuleWithDependenciesAndLibrariesScope(hasKotlinFilesOnlyInTests(module)) - hasKotlinJsKjsmFile(module.project, scope) + hasKotlinJsKjsmFile(module.project, LibraryKindSearchScope(module, scope, JSLibraryKind)) } } @@ -244,4 +251,18 @@ fun isEap(version: String): Boolean { fun useEapRepository(minorKotlinVersion: Int, version: String): Boolean { return Regex("1\\.$minorKotlinVersion(\\.\\d)?-[A-Za-z][A-Za-z0-9-]*").matches(version) && !version.startsWith("1.$minorKotlinVersion.0-dev") -} \ No newline at end of file +} + +private class LibraryKindSearchScope(val module: Module, + val baseScope: GlobalSearchScope, + val libraryKind: PersistentLibraryKind<*> +) : DelegatingGlobalSearchScope(baseScope) { + override fun contains(file: VirtualFile): Boolean { + if (!super.contains(file)) return false + val orderEntry = ModuleRootManager.getInstance(module).fileIndex.getOrderEntryForFile(file) + if (orderEntry is LibraryOrderEntry) { + return (orderEntry.library as LibraryEx).kind == libraryKind + } + return true + } +} diff --git a/idea/src/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinNotificationManager.kt b/idea/src/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinNotificationManager.kt index d67c9cf29b4..7dbc33c404a 100644 --- a/idea/src/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinNotificationManager.kt +++ b/idea/src/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinNotificationManager.kt @@ -18,7 +18,9 @@ package org.jetbrains.kotlin.idea.configuration import com.intellij.notification.Notification import com.intellij.notification.NotificationsManager +import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.module.Module +import com.intellij.openapi.project.DumbService import com.intellij.openapi.project.Project import org.jetbrains.kotlin.idea.configuration.ui.notifications.ConfigureKotlinNotification import kotlin.reflect.KClass @@ -64,3 +66,16 @@ interface KotlinSingleNotificationManager { } } + +fun checkHideNonConfiguredNotifications(project: Project) { + if (ConfigureKotlinNotificationManager.getVisibleNotifications(project).isNotEmpty()) { + ApplicationManager.getApplication().executeOnPooledThread { + DumbService.getInstance(project).waitForSmartMode() + if (getConfigurableModulesWithKotlinFiles(project).all(::isModuleConfigured)) { + ApplicationManager.getApplication().invokeLater { + ConfigureKotlinNotificationManager.expireOldNotifications(project) + } + } + } + } +} diff --git a/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinJavaModuleConfigurator.kt b/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinJavaModuleConfigurator.kt index e1affc0e8b5..9a2a31791aa 100644 --- a/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinJavaModuleConfigurator.kt +++ b/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinJavaModuleConfigurator.kt @@ -22,6 +22,9 @@ import com.intellij.openapi.module.Module import com.intellij.openapi.projectRoots.JavaSdk import com.intellij.openapi.projectRoots.JavaSdkVersion import com.intellij.openapi.projectRoots.Sdk +import com.intellij.openapi.roots.LibraryOrderEntry +import com.intellij.openapi.roots.ModuleRootManager +import com.intellij.openapi.roots.impl.libraries.LibraryEx import com.intellij.openapi.roots.libraries.Library import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments import org.jetbrains.kotlin.config.JvmTarget @@ -30,6 +33,7 @@ import org.jetbrains.kotlin.idea.compiler.configuration.Kotlin2JvmCompilerArgume import org.jetbrains.kotlin.idea.facet.getOrCreateFacet import org.jetbrains.kotlin.idea.facet.initializeIfNeeded import org.jetbrains.kotlin.idea.framework.JavaRuntimeLibraryDescription +import org.jetbrains.kotlin.idea.framework.JsLibraryStdDetectionUtil import org.jetbrains.kotlin.idea.util.projectStructure.allModules import org.jetbrains.kotlin.idea.util.projectStructure.sdk import org.jetbrains.kotlin.idea.versions.LibraryJarDescriptor @@ -38,6 +42,9 @@ import org.jetbrains.kotlin.resolve.TargetPlatform import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform open class KotlinJavaModuleConfigurator internal constructor() : KotlinWithLibraryConfigurator() { + override fun isApplicable(module: Module): Boolean { + return super.isApplicable(module) && !hasBrokenJsRuntime(module) + } override fun isConfigured(module: Module): Boolean { return hasKotlinJvmRuntimeInScope(module) @@ -113,4 +120,12 @@ open class KotlinJavaModuleConfigurator internal constructor() : KotlinWithLibra val instance: KotlinJavaModuleConfigurator get() = Extensions.findExtension(KotlinProjectConfigurator.EP_NAME, KotlinJavaModuleConfigurator::class.java) } + + private fun hasBrokenJsRuntime(module: Module): Boolean { + for (orderEntry in ModuleRootManager.getInstance(module).orderEntries) { + val library = (orderEntry as? LibraryOrderEntry)?.library as? LibraryEx ?: continue + if (JsLibraryStdDetectionUtil.hasJsStdlibJar(library, ignoreKind = true)) return true + } + return false + } } diff --git a/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinJsModuleConfigurator.kt b/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinJsModuleConfigurator.kt index 5ac358412cd..d4c2a03be30 100644 --- a/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinJsModuleConfigurator.kt +++ b/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinJsModuleConfigurator.kt @@ -18,11 +18,17 @@ package org.jetbrains.kotlin.idea.configuration import com.intellij.openapi.module.Module import com.intellij.openapi.projectRoots.Sdk +import com.intellij.openapi.roots.LibraryOrderEntry +import com.intellij.openapi.roots.ModuleRootManager +import com.intellij.openapi.roots.impl.libraries.LibraryEx import com.intellij.openapi.roots.libraries.DummyLibraryProperties import com.intellij.openapi.roots.libraries.Library import com.intellij.openapi.roots.libraries.LibraryType +import org.jetbrains.kotlin.idea.framework.JSLibraryKind import org.jetbrains.kotlin.idea.framework.JSLibraryStdDescription import org.jetbrains.kotlin.idea.framework.JSLibraryType +import org.jetbrains.kotlin.idea.framework.JsLibraryStdDetectionUtil +import org.jetbrains.kotlin.idea.util.application.runWriteAction import org.jetbrains.kotlin.idea.versions.LibraryJarDescriptor import org.jetbrains.kotlin.idea.versions.isKotlinJsRuntime import org.jetbrains.kotlin.js.JavaScript @@ -65,4 +71,32 @@ open class KotlinJsModuleConfigurator : KotlinWithLibraryConfigurator() { companion object { const val NAME = JavaScript.LOWER_NAME } + + /** + * Migrate pre-1.1.3 projects which didn't have explicitly specified kind for JS libraries. + */ + override fun findAndFixBrokenKotlinLibrary(module: Module, collector: NotificationMessageCollector): Library? { + val allLibraries = mutableListOf() + var brokenStdlib: Library? = null + for (orderEntry in ModuleRootManager.getInstance(module).orderEntries) { + val library = (orderEntry as? LibraryOrderEntry)?.library as? LibraryEx ?: continue + allLibraries.add(library) + if (JsLibraryStdDetectionUtil.hasJsStdlibJar(library, ignoreKind = true) && library.kind == null) { + brokenStdlib = library + } + } + + if (brokenStdlib != null) { + runWriteAction { + for (library in allLibraries.filter { it.kind == null }) { + library.modifiableModel.apply { + kind = JSLibraryKind + commit() + } + } + } + collector.addMessage("Updated JavaScript libraries in module ${module.name}") + } + return brokenStdlib + } } diff --git a/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinSetupEnvironmentNotificationProvider.kt b/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinSetupEnvironmentNotificationProvider.kt index bcd2090620e..339707a0bca 100644 --- a/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinSetupEnvironmentNotificationProvider.kt +++ b/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinSetupEnvironmentNotificationProvider.kt @@ -114,7 +114,7 @@ class KotlinSetupEnvironmentNotificationProvider( createComponentActionLabel("Configure") { label -> val singleConfigurator = configurators.singleOrNull() if (singleConfigurator != null) { - singleConfigurator.configure(module.project, emptyList()) + singleConfigurator.apply(module.project) } else { val configuratorsPopup = createConfiguratorsPopup(module.project, configurators) @@ -125,15 +125,19 @@ class KotlinSetupEnvironmentNotificationProvider( } } + private fun KotlinProjectConfigurator.apply(project: Project) { + configure(project, emptyList()) + EditorNotifications.getInstance(project).updateAllNotifications() + checkHideNonConfiguredNotifications(project) + } + fun createConfiguratorsPopup(project: Project, configurators: List): ListPopup { val step = object : BaseListPopupStep("Choose Configurator", configurators) { - override fun getTextFor(value: KotlinProjectConfigurator?): String { - return value?.presentableText ?: "" - } + override fun getTextFor(value: KotlinProjectConfigurator?) = value?.presentableText ?: "" override fun onChosen(selectedValue: KotlinProjectConfigurator?, finalChoice: Boolean): PopupStep<*>? { return doFinalStep { - selectedValue?.configure(project, emptyList()) + selectedValue?.apply(project) } } } diff --git a/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.kt b/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.kt index be5205872d2..08e767e31d6 100644 --- a/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.kt +++ b/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.kt @@ -137,7 +137,8 @@ abstract class KotlinWithLibraryConfigurator internal constructor() : KotlinProj ) { val project = module.project - val library = getKotlinLibrary(module) + val library = findAndFixBrokenKotlinLibrary(module, collector) + ?: getKotlinLibrary(module) ?: getKotlinLibrary(project) ?: createNewLibrary(project, collector) @@ -316,15 +317,17 @@ abstract class KotlinWithLibraryConfigurator internal constructor() : KotlinProj protected open fun configureKotlinSettings(modules: List) { } + protected open fun findAndFixBrokenKotlinLibrary(module: Module, collector: NotificationMessageCollector): Library? = null + + protected open fun isApplicable(module: Module): Boolean { + return !KotlinPluginUtil.isAndroidGradleModule(module) && + !KotlinPluginUtil.isMavenModule(module) && + !KotlinPluginUtil.isGradleModule(module) + } + companion object { val DEFAULT_LIBRARY_DIR = "lib" - protected fun isApplicable(module: Module): Boolean { - return !KotlinPluginUtil.isAndroidGradleModule(module) && - !KotlinPluginUtil.isMavenModule(module) && - !KotlinPluginUtil.isGradleModule(module) - } - fun getPathFromLibrary(library: Library?, type: OrderRootType): String? { if (library == null) return null diff --git a/idea/src/org/jetbrains/kotlin/idea/configuration/ui/KotlinConfigurationCheckerComponent.kt b/idea/src/org/jetbrains/kotlin/idea/configuration/ui/KotlinConfigurationCheckerComponent.kt index e29ef894b09..45187f23c5d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/configuration/ui/KotlinConfigurationCheckerComponent.kt +++ b/idea/src/org/jetbrains/kotlin/idea/configuration/ui/KotlinConfigurationCheckerComponent.kt @@ -26,7 +26,9 @@ import com.intellij.openapi.project.Project import com.intellij.openapi.roots.ModuleRootEvent import com.intellij.openapi.roots.ModuleRootListener import com.intellij.openapi.startup.StartupManager -import org.jetbrains.kotlin.idea.configuration.* +import org.jetbrains.kotlin.idea.configuration.checkHideNonConfiguredNotifications +import org.jetbrains.kotlin.idea.configuration.getModulesWithKotlinFiles +import org.jetbrains.kotlin.idea.configuration.showConfigureKotlinNotificationIfNeeded import org.jetbrains.kotlin.idea.project.getAndCacheLanguageLevelByDependencies import org.jetbrains.kotlin.idea.versions.collectModulesWithOutdatedRuntime import org.jetbrains.kotlin.idea.versions.findOutdatedKotlinLibraries @@ -54,16 +56,7 @@ class KotlinConfigurationCheckerComponent(project: Project) : AbstractProjectCom } } - if (ConfigureKotlinNotificationManager.getVisibleNotifications(project).isNotEmpty()) { - ApplicationManager.getApplication().executeOnPooledThread { - DumbService.getInstance(myProject).waitForSmartMode() - if (getConfigurableModulesWithKotlinFiles(project).all(::isModuleConfigured)) { - ApplicationManager.getApplication().invokeLater { - ConfigureKotlinNotificationManager.expireOldNotifications(project) - } - } - } - } + checkHideNonConfiguredNotifications(project) } }) } diff --git a/idea/testData/configuration/jsLibraryWithoutPaths/projectFile.ipr b/idea/testData/configuration/jsLibraryWithoutPaths/projectFile.ipr index bcccccf0007..c1fe6a3e398 100644 --- a/idea/testData/configuration/jsLibraryWithoutPaths/projectFile.ipr +++ b/idea/testData/configuration/jsLibraryWithoutPaths/projectFile.ipr @@ -7,7 +7,7 @@ - + diff --git a/idea/testData/configuration/jsLibraryWrongKind/module.iml b/idea/testData/configuration/jsLibraryWrongKind/module.iml new file mode 100644 index 00000000000..4a3ded12725 --- /dev/null +++ b/idea/testData/configuration/jsLibraryWrongKind/module.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/idea/testData/configuration/jsLibraryWrongKind/projectFile.ipr b/idea/testData/configuration/jsLibraryWrongKind/projectFile.ipr new file mode 100644 index 00000000000..6446db85e1d --- /dev/null +++ b/idea/testData/configuration/jsLibraryWrongKind/projectFile.ipr @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/idea/testData/configuration/jsLibraryWrongKind/src/foo.kt b/idea/testData/configuration/jsLibraryWrongKind/src/foo.kt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/idea/testData/configuration/twoModulesWithJSNonDefaultPath/projectFile.ipr b/idea/testData/configuration/twoModulesWithJSNonDefaultPath/projectFile.ipr index b88b2c75921..5985892cc93 100644 --- a/idea/testData/configuration/twoModulesWithJSNonDefaultPath/projectFile.ipr +++ b/idea/testData/configuration/twoModulesWithJSNonDefaultPath/projectFile.ipr @@ -8,7 +8,7 @@ - + diff --git a/idea/tests/org/jetbrains/kotlin/idea/configuration/AbstractConfigureKotlinTest.kt b/idea/tests/org/jetbrains/kotlin/idea/configuration/AbstractConfigureKotlinTest.kt index d77cb6c15f6..a7267881f9c 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/configuration/AbstractConfigureKotlinTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/configuration/AbstractConfigureKotlinTest.kt @@ -176,24 +176,24 @@ abstract class AbstractConfigureKotlinTest : PlatformTestCase() { } private val pathToNonexistentRuntimeJar: String - get() { - val pathToTempKotlinRuntimeJar = FileUtil.getTempDirectory() + "/" + PathUtil.KOTLIN_JAVA_RUNTIME_JAR - PlatformTestCase.myFilesToDelete.add(File(pathToTempKotlinRuntimeJar)) - return pathToTempKotlinRuntimeJar - } + get() { + val pathToTempKotlinRuntimeJar = FileUtil.getTempDirectory() + "/" + PathUtil.KOTLIN_JAVA_RUNTIME_JAR + PlatformTestCase.myFilesToDelete.add(File(pathToTempKotlinRuntimeJar)) + return pathToTempKotlinRuntimeJar + } private val pathToNonexistentJsJar: String - get() { - val pathToTempKotlinRuntimeJar = FileUtil.getTempDirectory() + "/" + PathUtil.JS_LIB_JAR_NAME - PlatformTestCase.myFilesToDelete.add(File(pathToTempKotlinRuntimeJar)) - return pathToTempKotlinRuntimeJar - } + get() { + val pathToTempKotlinRuntimeJar = FileUtil.getTempDirectory() + "/" + PathUtil.JS_LIB_JAR_NAME + PlatformTestCase.myFilesToDelete.add(File(pathToTempKotlinRuntimeJar)) + return pathToTempKotlinRuntimeJar + } private val pathToExistentRuntimeJar: String - get() = PathUtil.getKotlinPathsForDistDirectory().stdlibPath.parent + get() = PathUtil.getKotlinPathsForDistDirectory().stdlibPath.parent private val pathToExistentJsJar: String - get() = PathUtil.getKotlinPathsForDistDirectory().jsStdLibJarPath.parent + get() = PathUtil.getKotlinPathsForDistDirectory().jsStdLibJarPath.parent protected fun assertNotConfigured(module: Module, configurator: KotlinWithLibraryConfigurator) { TestCase.assertFalse( diff --git a/idea/tests/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinTest.java b/idea/tests/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinTest.java index 3d9d6b2d3d3..83b03be158b 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinTest.java +++ b/idea/tests/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinTest.java @@ -18,6 +18,9 @@ package org.jetbrains.kotlin.idea.configuration; import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProviderImpl; import com.intellij.openapi.module.Module; +import com.intellij.openapi.roots.LibraryOrderEntry; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.RootPolicy; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.util.io.FileUtil; import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments; @@ -121,6 +124,11 @@ public class ConfigureKotlinTest extends AbstractConfigureKotlinTest { doTestOneJsModule(KotlinWithLibraryConfigurator.FileState.DO_NOT_COPY); } + public void testJsLibraryWrongKind() { + doTestOneJsModule(KotlinWithLibraryConfigurator.FileState.EXISTS); + assertEquals(1, ModuleRootManager.getInstance(getModule()).orderEntries().process(new LibraryCountingRootPolicy(), 0).intValue()); + } + public void testProjectWithoutFacetWithRuntime106WithoutLanguageLevel() { assertEquals(LanguageVersion.KOTLIN_1_0, PlatformKt.getLanguageVersionSettings(myProject, null).getLanguageVersion()); assertEquals(LanguageVersion.KOTLIN_1_0, PlatformKt.getLanguageVersionSettings(getModule()).getLanguageVersion()); @@ -261,4 +269,11 @@ public class ConfigureKotlinTest extends AbstractConfigureKotlinTest { public void testProjectWithoutFacetWithJvmTarget18() { assertEquals(TargetPlatformKind.Jvm.Companion.get(JvmTarget.JVM_1_8), PlatformKt.getTargetPlatform(getModule())); } + + private static class LibraryCountingRootPolicy extends RootPolicy { + @Override + public Integer visitLibraryOrderEntry(LibraryOrderEntry libraryOrderEntry, Integer value) { + return value + 1; + } + } }