diff --git a/idea/idea-test-framework/src/org/jetbrains/kotlin/idea/test/KotlinProjectDescriptorWithFacet.kt b/idea/idea-test-framework/src/org/jetbrains/kotlin/idea/test/KotlinProjectDescriptorWithFacet.kt index 51e3e15ac62..70de5ca8a4a 100644 --- a/idea/idea-test-framework/src/org/jetbrains/kotlin/idea/test/KotlinProjectDescriptorWithFacet.kt +++ b/idea/idea-test-framework/src/org/jetbrains/kotlin/idea/test/KotlinProjectDescriptorWithFacet.kt @@ -21,6 +21,7 @@ import com.intellij.openapi.module.Module import com.intellij.openapi.roots.ContentEntry import com.intellij.openapi.roots.ModifiableRootModel import org.jetbrains.kotlin.config.LanguageVersion +import org.jetbrains.kotlin.idea.facet.KotlinFacet import org.jetbrains.kotlin.idea.facet.KotlinFacetConfiguration import org.jetbrains.kotlin.idea.facet.KotlinFacetType import org.jetbrains.kotlin.test.testFramework.runInEdtAndWait @@ -28,15 +29,8 @@ import org.jetbrains.kotlin.test.testFramework.runWriteAction class KotlinProjectDescriptorWithFacet(val languageVersion: LanguageVersion) : KotlinLightProjectDescriptor() { override fun configureModule(module: Module, model: ModifiableRootModel, contentEntry: ContentEntry) { - val facetManager = FacetManager.getInstance(module) - val facetModel = facetManager.createModifiableModel() - val configuration = KotlinFacetConfiguration() - configuration.settings.useProjectSettings = false - configuration.settings.versionInfo.languageLevel = languageVersion - val facet = facetManager.createFacet(KotlinFacetType.INSTANCE, "Kotlin", configuration, null) - facetModel.addFacet(facet) - runInEdtAndWait { - runWriteAction { facetModel.commit() } + configureKotlinFacet(module) { -> + settings.versionInfo.languageLevel = languageVersion } } @@ -44,3 +38,18 @@ class KotlinProjectDescriptorWithFacet(val languageVersion: LanguageVersion) : K val KOTLIN_10 = KotlinProjectDescriptorWithFacet(LanguageVersion.KOTLIN_1_0) } } + +fun configureKotlinFacet(module: Module, configureCallback: KotlinFacetConfiguration.() -> Unit = {}): KotlinFacet { + val facetManager = FacetManager.getInstance(module) + val facetModel = facetManager.createModifiableModel() + val configuration = KotlinFacetConfiguration() + configuration.settings.useProjectSettings = false + configuration.configureCallback() + val facet = facetManager.createFacet(KotlinFacetType.INSTANCE, "Kotlin", configuration, null) + facetModel.addFacet(facet) + runInEdtAndWait { + runWriteAction { facetModel.commit() } + } + return facet +} + diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/EnableUnsupportedFeatureFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/EnableUnsupportedFeatureFix.kt index ab6e5557bcb..e5ead1b87f6 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/EnableUnsupportedFeatureFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/EnableUnsupportedFeatureFix.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.idea.quickfix +import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.editor.Editor import com.intellij.openapi.fileEditor.OpenFileDescriptor import com.intellij.openapi.module.Module @@ -157,23 +158,27 @@ sealed class EnableUnsupportedFeatureFix( fun checkUpdateRuntime(project: Project, requiredVersion: ApiVersion): Boolean { val modulesWithOutdatedRuntime = project.allModules().filter { module -> - val parsedModuleRuntimeVersion = getRuntimeLibraryVersion(module)?.let { ApiVersion.parse(it) } + val parsedModuleRuntimeVersion = getRuntimeLibraryVersion(module)?.let { version -> + ApiVersion.parse(version.substringBefore("-")) + } parsedModuleRuntimeVersion != null && parsedModuleRuntimeVersion < requiredVersion } if (modulesWithOutdatedRuntime.isNotEmpty()) { - if (askUpdateRuntime(project, requiredVersion, - modulesWithOutdatedRuntime.mapNotNull(::findKotlinRuntimeLibrary))) return false + if (!askUpdateRuntime(project, requiredVersion, + modulesWithOutdatedRuntime.mapNotNull(::findKotlinRuntimeLibrary))) return false } return true } fun askUpdateRuntime(project: Project, requiredVersion: ApiVersion, librariesToUpdate: List): Boolean { - val rc = Messages.showOkCancelDialog(project, - "This language feature requires version $requiredVersion or later of the Kotlin runtime library. " + - "Would you like to update the runtime library in your project?", - "Update Runtime Library", - Messages.getQuestionIcon()) - if (rc != Messages.OK) return false + if (!ApplicationManager.getApplication().isUnitTestMode) { + val rc = Messages.showOkCancelDialog(project, + "This language feature requires version $requiredVersion or later of the Kotlin runtime library. " + + "Would you like to update the runtime library in your project?", + "Update Runtime Library", + Messages.getQuestionIcon()) + if (rc != Messages.OK) return false + } updateLibraries(project, librariesToUpdate) return true diff --git a/idea/src/org/jetbrains/kotlin/idea/versions/KotlinRuntimeLibraryUtil.kt b/idea/src/org/jetbrains/kotlin/idea/versions/KotlinRuntimeLibraryUtil.kt index 6ba4307c835..a429671afba 100644 --- a/idea/src/org/jetbrains/kotlin/idea/versions/KotlinRuntimeLibraryUtil.kt +++ b/idea/src/org/jetbrains/kotlin/idea/versions/KotlinRuntimeLibraryUtil.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.idea.versions +import com.google.common.collect.Sets import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.module.Module import com.intellij.openapi.module.ModuleManager @@ -84,42 +85,40 @@ fun updateLibraries(project: Project, libraries: Collection) { return } - ApplicationManager.getApplication().invokeLater { - val kJvmConfigurator = getConfiguratorByName(KotlinJavaModuleConfigurator.NAME) as KotlinJavaModuleConfigurator? ?: - error("Configurator with given name doesn't exists: " + KotlinJavaModuleConfigurator.NAME) + val kJvmConfigurator = getConfiguratorByName(KotlinJavaModuleConfigurator.NAME) as KotlinJavaModuleConfigurator? ?: + error("Configurator with given name doesn't exists: " + KotlinJavaModuleConfigurator.NAME) - val kJsConfigurator = getConfiguratorByName(KotlinJsModuleConfigurator.NAME) as KotlinJsModuleConfigurator? ?: - error("Configurator with given name doesn't exists: " + KotlinJsModuleConfigurator.NAME) + val kJsConfigurator = getConfiguratorByName(KotlinJsModuleConfigurator.NAME) as KotlinJsModuleConfigurator? ?: + error("Configurator with given name doesn't exists: " + KotlinJsModuleConfigurator.NAME) - val collector = createConfigureKotlinNotificationCollector(project) + val collector = createConfigureKotlinNotificationCollector(project) - for (library in libraries) { - if (isDetected(JavaRuntimePresentationProvider.getInstance(), library)) { - updateJar(project, getRuntimeJar(library), LibraryJarDescriptor.RUNTIME_JAR) - updateJar(project, getReflectJar(library), LibraryJarDescriptor.REFLECT_JAR) - updateJar(project, getTestJar(library), LibraryJarDescriptor.TEST_JAR) + for (library in libraries) { + if (isDetected(JavaRuntimePresentationProvider.getInstance(), library)) { + updateJar(project, getRuntimeJar(library), LibraryJarDescriptor.RUNTIME_JAR) + updateJar(project, getReflectJar(library), LibraryJarDescriptor.REFLECT_JAR) + updateJar(project, getTestJar(library), LibraryJarDescriptor.TEST_JAR) - if (kJvmConfigurator.changeOldSourcesPathIfNeeded(library, collector)) { - kJvmConfigurator.copySourcesToPathFromLibrary(library, collector) - } - else { - updateJar(project, getRuntimeSrcJar(library), LibraryJarDescriptor.RUNTIME_SRC_JAR) - } + if (kJvmConfigurator.changeOldSourcesPathIfNeeded(library, collector)) { + kJvmConfigurator.copySourcesToPathFromLibrary(library, collector) } - else if (isDetected(JSLibraryStdPresentationProvider.getInstance(), library)) { - updateJar(project, getJsStdLibJar(library), LibraryJarDescriptor.JS_STDLIB_JAR) - - if (kJsConfigurator.changeOldSourcesPathIfNeeded(library, collector)) { - kJsConfigurator.copySourcesToPathFromLibrary(library, collector) - } - else { - updateJar(project, getJsStdLibSrcJar(library), LibraryJarDescriptor.JS_STDLIB_SRC_JAR) - } + else { + updateJar(project, getRuntimeSrcJar(library), LibraryJarDescriptor.RUNTIME_SRC_JAR) } } + else if (isDetected(JSLibraryStdPresentationProvider.getInstance(), library)) { + updateJar(project, getJsStdLibJar(library), LibraryJarDescriptor.JS_STDLIB_JAR) - collector.showNotification() + if (kJsConfigurator.changeOldSourcesPathIfNeeded(library, collector)) { + kJsConfigurator.copySourcesToPathFromLibrary(library, collector) + } + else { + updateJar(project, getJsStdLibSrcJar(library), LibraryJarDescriptor.JS_STDLIB_SRC_JAR) + } + } } + + collector.showNotification() } private fun updateJar( diff --git a/idea/src/org/jetbrains/kotlin/idea/versions/OutdatedKotlinRuntimeChecker.kt b/idea/src/org/jetbrains/kotlin/idea/versions/OutdatedKotlinRuntimeChecker.kt index 0d3a0baf10a..8dda6123e71 100644 --- a/idea/src/org/jetbrains/kotlin/idea/versions/OutdatedKotlinRuntimeChecker.kt +++ b/idea/src/org/jetbrains/kotlin/idea/versions/OutdatedKotlinRuntimeChecker.kt @@ -108,7 +108,9 @@ fun notifyOutdatedKotlinRuntime(project: Project, outdatedLibraries: Collection< if (event.eventType == HyperlinkEvent.EventType.ACTIVATED) { if ("update" == event.description) { val outdatedLibraries = findOutdatedKotlinLibraries(project).map { it.library } - updateLibraries(project, outdatedLibraries) + ApplicationManager.getApplication().invokeLater { + updateLibraries(project, outdatedLibraries) + } suggestDeleteKotlinJsIfNeeded(project, outdatedLibraries) } else if ("ignore" == event.description) { diff --git a/idea/src/org/jetbrains/kotlin/idea/versions/UnsupportedAbiVersionNotificationPanelProvider.kt b/idea/src/org/jetbrains/kotlin/idea/versions/UnsupportedAbiVersionNotificationPanelProvider.kt index 08d270a5860..d9a13ed27d8 100644 --- a/idea/src/org/jetbrains/kotlin/idea/versions/UnsupportedAbiVersionNotificationPanelProvider.kt +++ b/idea/src/org/jetbrains/kotlin/idea/versions/UnsupportedAbiVersionNotificationPanelProvider.kt @@ -122,7 +122,11 @@ class UnsupportedAbiVersionNotificationPanelProvider(private val project: Projec } val actionLabelText = MessageFormat.format("$updateAction {0,choice,0#|1#|1\"s\"::length") + + myFixture.launchAction(myFixture.findSingleIntention("Set project language version to 1.1")) + + assertEquals("1.1", KotlinCommonCompilerArgumentsHolder.getInstance(project).settings.languageVersion) + assertEquals("1.1", KotlinCommonCompilerArgumentsHolder.getInstance(project).settings.apiVersion) + } + + fun testIncreaseLangAndApiLevel_10() { + val runtime = configureRuntime("mockRuntime106") + resetProjectSettings(LanguageVersion.KOTLIN_1_0) + myFixture.configureByText("foo.kt", "val x = \"s\"::length") + + myFixture.launchAction(myFixture.findSingleIntention("Set project language version to 1.1")) + + assertEquals("1.1", KotlinCommonCompilerArgumentsHolder.getInstance(project).settings.languageVersion) + assertEquals("1.1", KotlinCommonCompilerArgumentsHolder.getInstance(project).settings.apiVersion) + + assertEquals(bundledRuntimeVersion(), JavaRuntimeDetectionUtil.getJavaRuntimeVersion(listOf(runtime))) + } + + fun testIncreaseLangLevelFacet_10() { + val runtime = configureRuntime("mockRuntime106") + resetProjectSettings(LanguageVersion.KOTLIN_1_0) + configureKotlinFacet(myModule) { + settings.versionInfo.languageLevel = LanguageVersion.KOTLIN_1_0 + settings.versionInfo.apiLevel = LanguageVersion.KOTLIN_1_0 + } + myFixture.configureByText("foo.kt", "val x = \"s\"::length") + + assertEquals(LanguageVersion.KOTLIN_1_0, myModule.languageVersionSettings.languageVersion) + myFixture.launchAction(myFixture.findSingleIntention("Set module language version to 1.1")) + assertEquals(LanguageVersion.KOTLIN_1_1, myModule.languageVersionSettings.languageVersion) + + assertEquals(bundledRuntimeVersion(), JavaRuntimeDetectionUtil.getJavaRuntimeVersion(listOf(runtime))) + } + + private fun configureRuntime(path: String): VirtualFile { + val tempFile = FileUtil.createTempFile("kotlin-runtime", ".jar") + FileUtil.copy(File("idea/testData/configuration/$path/kotlin-runtime.jar"), tempFile) + val tempVFile = LocalFileSystem.getInstance().findFileByIoFile(tempFile)!! + + updateModel(myFixture.module) { model -> + val editor = NewLibraryEditor() + editor.name = "KotlinJavaRuntime" + + editor.addRoot(JarFileSystem.getInstance().getJarRootForLocalFile(tempVFile), OrderRootType.CLASSES) + + ConfigLibraryUtil.addLibrary(editor, model) + } + return tempVFile + } + + private fun resetProjectSettings(version: LanguageVersion) { + with(KotlinCommonCompilerArgumentsHolder.getInstance(project).settings) { + languageVersion = version.versionString + apiVersion = version.versionString + coroutinesEnable = false + coroutinesWarn = true + coroutinesError = false + } + } + + override fun tearDown() { + FacetManager.getInstance(myModule).getFacetByType(KotlinFacetType.TYPE_ID)?.let { + FacetUtil.deleteFacet(it) + } + ConfigLibraryUtil.removeLibrary(myModule, "KotlinJavaRuntime") + super.tearDown() + } +}