Add quickfix to enable coroutines by editing build.gradle
#KT-15955 Fixed
This commit is contained in:
@@ -40,8 +40,10 @@ import org.jetbrains.kotlin.psi.psiUtil.getChildrenOfType
|
||||
import org.jetbrains.plugins.gradle.util.GradleConstants
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrApplicationStatement
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.util.GrStatementOwner
|
||||
import java.io.File
|
||||
@@ -255,6 +257,43 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator {
|
||||
}
|
||||
}
|
||||
|
||||
fun changeCoroutineConfiguration(module: Module, coroutineOption: String): PsiElement? {
|
||||
return changeBuildGradle(module) { gradleFile ->
|
||||
changeCoroutineConfiguration(gradleFile, coroutineOption)
|
||||
}
|
||||
}
|
||||
|
||||
fun changeCoroutineConfiguration(gradleFile: GroovyFile, coroutineOption: String): PsiElement? {
|
||||
val snippet = "coroutines \"$coroutineOption\""
|
||||
val kotlinBlock = getBlockOrCreate(gradleFile, "kotlin")
|
||||
val experimentalBlock = getBlockOrCreate(kotlinBlock, "experimental")
|
||||
addOrReplaceExpression(experimentalBlock, snippet) { stmt ->
|
||||
(stmt as? GrMethodCall)?.invokedExpression?.text == "coroutines"
|
||||
}
|
||||
return kotlinBlock.parent
|
||||
}
|
||||
|
||||
private fun changeBuildGradle(module: Module, body: (GroovyFile) -> PsiElement?): PsiElement? {
|
||||
val gradleFilePath = getModuleFilePath(module)
|
||||
val gradleFile = getBuildGradleFile(module.project, gradleFilePath)
|
||||
if (gradleFile != null && canConfigureFile(gradleFile)) {
|
||||
return gradleFile.project.executeWriteCommand("Change build.gradle configuration", null) {
|
||||
body(gradleFile)
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun addOrReplaceExpression(block: GrClosableBlock, snippet: String, predicate: (GrStatement) -> Boolean) {
|
||||
block.statements.firstOrNull(predicate)?.let { stmt ->
|
||||
val newStatement = GroovyPsiElementFactory.getInstance(block.project).createExpressionFromText(snippet)
|
||||
CodeStyleManager.getInstance(block.project).reformat(newStatement)
|
||||
stmt.replaceWithStatement(newStatement)
|
||||
return
|
||||
}
|
||||
addLastExpressionInBlockIfNeeded(snippet, block)
|
||||
}
|
||||
|
||||
fun getKotlinStdlibVersion(module: Module): String? {
|
||||
val gradleFilePath = getModuleFilePath(module)
|
||||
val gradleFile = getBuildGradleFile(module.project, gradleFilePath) ?: return null
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.idea.quickfix
|
||||
|
||||
import com.intellij.codeInsight.intention.IntentionAction
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.fileEditor.OpenFileDescriptor
|
||||
import com.intellij.openapi.module.ModuleUtilCore
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.roots.ModuleRootModificationUtil
|
||||
@@ -29,6 +30,7 @@ import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.idea.KotlinPluginUtil
|
||||
import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCommonCompilerArgumentsHolder
|
||||
import org.jetbrains.kotlin.idea.configuration.KotlinWithGradleConfigurator
|
||||
import org.jetbrains.kotlin.idea.facet.KotlinFacet
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
|
||||
@@ -41,6 +43,14 @@ sealed class ChangeCoroutineSupportFix(
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val module = ModuleUtilCore.findModuleForPsiElement(file) ?: return
|
||||
if (KotlinPluginUtil.isGradleModule(module)) {
|
||||
val element = KotlinWithGradleConfigurator.changeCoroutineConfiguration(module, coroutineSupport.compilerArgument)
|
||||
element?.let {
|
||||
OpenFileDescriptor(project, it.containingFile.virtualFile, it.textRange.startOffset).navigate(true)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
val facetSettings = KotlinFacet.get(module)?.configuration?.settings ?: return
|
||||
ModuleRootModificationUtil.updateModel(module) {
|
||||
facetSettings.compilerInfo.coroutineSupport = coroutineSupport
|
||||
@@ -85,10 +95,13 @@ sealed class ChangeCoroutineSupportFix(
|
||||
else -> return emptyList()
|
||||
}
|
||||
val module = ModuleUtilCore.findModuleForPsiElement(diagnostic.psiElement) ?: return emptyList()
|
||||
if (KotlinPluginUtil.isGradleModule(module) || KotlinPluginUtil.isMavenModule(module)) return emptyList()
|
||||
if (KotlinPluginUtil.isMavenModule(module)) return emptyList()
|
||||
val facetSettings = KotlinFacet.get(module)?.configuration?.settings
|
||||
|
||||
val configureInProject = (facetSettings == null || facetSettings.useProjectSettings) &&
|
||||
!KotlinPluginUtil.isGradleModule(module)
|
||||
val quickFixConstructor: (PsiElement, CoroutineSupport) -> ChangeCoroutineSupportFix =
|
||||
if (facetSettings == null || facetSettings.useProjectSettings) ::InProject else ::InModule
|
||||
if (configureInProject) ::InProject else ::InModule
|
||||
return newCoroutineSupports.map { quickFixConstructor(diagnostic.psiElement, it) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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.gradle
|
||||
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
|
||||
import org.jetbrains.kotlin.idea.configuration.KotlinWithGradleConfigurator
|
||||
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile
|
||||
|
||||
class KotlinWithGradleConfiguratorTest : LightCodeInsightFixtureTestCase() {
|
||||
fun testAddCoroutinesSupport() {
|
||||
val buildGradle = myFixture.configureByText("build.gradle", "apply plugin: 'kotlin'\n") as GroovyFile
|
||||
myFixture.project.executeWriteCommand("") {
|
||||
KotlinWithGradleConfigurator.changeCoroutineConfiguration(buildGradle, "enable")
|
||||
}
|
||||
myFixture.checkResult(
|
||||
"""apply plugin: 'kotlin'
|
||||
|kotlin {
|
||||
| experimental {
|
||||
| coroutines "enable"
|
||||
| }
|
||||
|}
|
||||
|""".trimMargin("|"))
|
||||
}
|
||||
|
||||
fun testChangeCoroutinesSupport() {
|
||||
val buildGradle = myFixture.configureByText("build.gradle",
|
||||
"""apply plugin: 'kotlin'
|
||||
|kotlin {
|
||||
| experimental {
|
||||
| coroutines "disable"
|
||||
| }
|
||||
|}
|
||||
|""".trimMargin("|")) as GroovyFile
|
||||
myFixture.project.executeWriteCommand("") {
|
||||
KotlinWithGradleConfigurator.changeCoroutineConfiguration(buildGradle, "enable")
|
||||
}
|
||||
myFixture.checkResult(
|
||||
"""apply plugin: 'kotlin'
|
||||
|kotlin {
|
||||
| experimental {
|
||||
| coroutines "enable"
|
||||
| }
|
||||
|}
|
||||
|""".trimMargin("|"))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user