Add test for enabling coroutines/bumping language level, fix several breakages
This commit is contained in:
+18
-9
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Library>): 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
|
||||
|
||||
@@ -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<Library>) {
|
||||
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(
|
||||
|
||||
@@ -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) {
|
||||
|
||||
+5
-1
@@ -122,7 +122,11 @@ class UnsupportedAbiVersionNotificationPanelProvider(private val project: Projec
|
||||
}
|
||||
|
||||
val actionLabelText = MessageFormat.format("$updateAction {0,choice,0#|1#|1<all }Kotlin runtime librar{0,choice,0#|1#y|1<ies} ", badRuntimeLibraries.size)
|
||||
answer.createActionLabel(actionLabelText) { updateLibraries(project, badRuntimeLibraries) }
|
||||
answer.createActionLabel(actionLabelText) {
|
||||
ApplicationManager.getApplication().invokeLater {
|
||||
updateLibraries(project, badRuntimeLibraries)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (badVersionedRoots.size == 1) {
|
||||
val badVersionedRoot = badVersionedRoots.first()
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* 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.quickfix
|
||||
|
||||
import com.intellij.facet.FacetManager
|
||||
import com.intellij.facet.impl.FacetUtil
|
||||
import com.intellij.openapi.roots.ModuleRootModificationUtil.updateModel
|
||||
import com.intellij.openapi.roots.OrderRootType
|
||||
import com.intellij.openapi.roots.ui.configuration.libraryEditor.NewLibraryEditor
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.openapi.vfs.JarFileSystem
|
||||
import com.intellij.openapi.vfs.LocalFileSystem
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase
|
||||
import org.jetbrains.kotlin.config.CoroutineSupport
|
||||
import org.jetbrains.kotlin.config.LanguageVersion
|
||||
import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCommonCompilerArgumentsHolder
|
||||
import org.jetbrains.kotlin.idea.facet.KotlinFacetType
|
||||
import org.jetbrains.kotlin.idea.framework.JavaRuntimeDetectionUtil
|
||||
import org.jetbrains.kotlin.idea.project.languageVersionSettings
|
||||
import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil
|
||||
import org.jetbrains.kotlin.idea.test.configureKotlinFacet
|
||||
import org.jetbrains.kotlin.idea.versions.bundledRuntimeVersion
|
||||
import java.io.File
|
||||
|
||||
class LanguageFeatureQuickFixTest : LightPlatformCodeInsightFixtureTestCase() {
|
||||
fun testEnableCoroutines() {
|
||||
configureRuntime("mockRuntime11")
|
||||
resetProjectSettings(LanguageVersion.KOTLIN_1_1)
|
||||
myFixture.configureByText("foo.kt", "suspend fun foo()")
|
||||
|
||||
assertFalse(KotlinCommonCompilerArgumentsHolder.getInstance(project).settings.coroutinesEnable)
|
||||
myFixture.launchAction(myFixture.findSingleIntention("Enable coroutine support in the project"))
|
||||
assertTrue(KotlinCommonCompilerArgumentsHolder.getInstance(project).settings.coroutinesEnable)
|
||||
}
|
||||
|
||||
fun testEnableCoroutinesFacet() {
|
||||
configureRuntime("mockRuntime11")
|
||||
val facet = configureKotlinFacet(myModule)
|
||||
resetProjectSettings(LanguageVersion.KOTLIN_1_1)
|
||||
myFixture.configureByText("foo.kt", "suspend fun foo()")
|
||||
|
||||
assertEquals(CoroutineSupport.ENABLED_WITH_WARNING, facet.configuration.settings.compilerInfo.coroutineSupport)
|
||||
myFixture.launchAction(myFixture.findSingleIntention("Enable coroutine support in the current module"))
|
||||
assertEquals(CoroutineSupport.ENABLED, facet.configuration.settings.compilerInfo.coroutineSupport)
|
||||
}
|
||||
|
||||
fun testIncreaseLangLevel() {
|
||||
configureRuntime("mockRuntime11")
|
||||
resetProjectSettings(LanguageVersion.KOTLIN_1_0)
|
||||
myFixture.configureByText("foo.kt", "val x get() = 1")
|
||||
|
||||
myFixture.launchAction(myFixture.findSingleIntention("Set project language version to 1.1"))
|
||||
|
||||
assertEquals("1.1", KotlinCommonCompilerArgumentsHolder.getInstance(project).settings.languageVersion)
|
||||
assertEquals("1.0", KotlinCommonCompilerArgumentsHolder.getInstance(project).settings.apiVersion)
|
||||
}
|
||||
|
||||
fun testIncreaseLangLevelFacet() {
|
||||
configureRuntime("mockRuntime11")
|
||||
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 get() = 1")
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
fun testIncreaseLangAndApiLevel() {
|
||||
configureRuntime("mockRuntime11")
|
||||
resetProjectSettings(LanguageVersion.KOTLIN_1_0)
|
||||
myFixture.configureByText("foo.kt", "val x = <caret>\"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 = <caret>\"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 = <caret>\"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()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user