Experimental fixes: introduce "add -Xuse-experimental" (KT-22760)
This commit is contained in:
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.idea.core.toDescriptor
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||
import org.jetbrains.kotlin.idea.util.projectStructure.module
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypesAndPredicate
|
||||
import org.jetbrains.kotlin.resolve.AnnotationChecker
|
||||
import org.jetbrains.kotlin.resolve.checkers.ExperimentalUsageChecker
|
||||
@@ -87,6 +88,13 @@ object ExperimentalFixesFactory : KotlinIntentionActionsFactory() {
|
||||
}
|
||||
}
|
||||
}
|
||||
val containingFile = containingDeclaration.containingKtFile
|
||||
val module = containingFile.module
|
||||
if (module != null) {
|
||||
result.add(
|
||||
MakeModuleExperimentalFix(containingFile, module, annotationFqName)
|
||||
)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.quickfix
|
||||
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProviderImpl
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.config.CompilerSettings
|
||||
import org.jetbrains.kotlin.idea.facet.getOrCreateFacet
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
|
||||
class MakeModuleExperimentalFix(
|
||||
file: KtFile,
|
||||
private val module: Module,
|
||||
private val annotationFqName: FqName
|
||||
) : KotlinQuickFixAction<KtFile>(file) {
|
||||
override fun getText(): String = "Add '-Xuse-experimental=$annotationFqName' to module ${module.name} compiler arguments"
|
||||
|
||||
override fun getFamilyName(): String = "Make module experimental"
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val modelsProvider = IdeModifiableModelsProviderImpl(project)
|
||||
val facet = module.getOrCreateFacet(modelsProvider, useProjectSettings = false, commitModel = true)
|
||||
val facetSettings = facet.configuration.settings
|
||||
val compilerSettings = facetSettings.compilerSettings ?: CompilerSettings().also {
|
||||
facetSettings.compilerSettings = it
|
||||
}
|
||||
|
||||
compilerSettings.additionalArguments += " -Xuse-experimental=$annotationFqName"
|
||||
facetSettings.updateMergedArguments()
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
// WITH_RUNTIME
|
||||
// ACTION: Add '@MyExperimentalAPI' annotation to containing class 'Bar'
|
||||
// ACTION: Add '@UseExperimental(MyExperimentalAPI::class)' annotation to 'bar'
|
||||
// ACTION: Add '-Xuse-experimental=MyExperimentalAPI' to module light_idea_test_case compiler arguments
|
||||
// ERROR: This declaration is experimental and its usage must be marked with '@MyExperimentalAPI' or '@UseExperimental(MyExperimentalAPI::class)'
|
||||
// ERROR: This declaration is experimental and its usage must be marked with '@MyExperimentalAPI' or '@UseExperimental(MyExperimentalAPI::class)'
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
// "Add '-Xuse-experimental=test.MyExperimentalAPI' to module light_idea_test_case compiler arguments" "true"
|
||||
// COMPILER_ARGUMENTS: -Xuse-experimental=kotlin.Experimental
|
||||
// COMPILER_ARGUMENTS_AFTER: -Xuse-experimental=kotlin.Experimental -Xuse-experimental=test.MyExperimentalAPI
|
||||
// DISABLE-ERRORS
|
||||
// WITH_RUNTIME
|
||||
|
||||
package test
|
||||
|
||||
@Experimental
|
||||
annotation class MyExperimentalAPI
|
||||
|
||||
@MyExperimentalAPI
|
||||
class Some {
|
||||
fun foo() {}
|
||||
}
|
||||
|
||||
class Bar {
|
||||
fun bar() {
|
||||
Some().foo<caret>()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// "Add '-Xuse-experimental=test.MyExperimentalAPI' to module light_idea_test_case compiler arguments" "true"
|
||||
// COMPILER_ARGUMENTS: -Xuse-experimental=kotlin.Experimental
|
||||
// COMPILER_ARGUMENTS_AFTER: -Xuse-experimental=kotlin.Experimental -Xuse-experimental=test.MyExperimentalAPI
|
||||
// DISABLE-ERRORS
|
||||
// WITH_RUNTIME
|
||||
|
||||
package test
|
||||
|
||||
@Experimental
|
||||
annotation class MyExperimentalAPI
|
||||
|
||||
@MyExperimentalAPI
|
||||
class Some {
|
||||
fun foo() {}
|
||||
}
|
||||
|
||||
class Bar {
|
||||
fun bar() {
|
||||
Some().foo()
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
// ACTION: Add '@MyExperimentalAPI' annotation to 'bar'
|
||||
// ACTION: Add '@MyExperimentalAPI' annotation to containing class 'Inner'
|
||||
// ACTION: Add '@UseExperimental(MyExperimentalAPI::class)' annotation to 'bar'
|
||||
// ACTION: Add '-Xuse-experimental=MyExperimentalAPI' to module light_idea_test_case compiler arguments
|
||||
// ERROR: This declaration is experimental and its usage must be marked with '@MyExperimentalAPI' or '@UseExperimental(MyExperimentalAPI::class)'
|
||||
|
||||
@Experimental
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
// ACTION: Add '@MyExperimentalAPI' annotation to 'foo'
|
||||
// ACTION: Add '@UseExperimental(MyExperimentalAPI::class)' annotation to 'foo'
|
||||
// ACTION: Add '@UseExperimental(MyExperimentalAPI::class)' annotation to containing class 'Derived'
|
||||
// ACTION: Add '-Xuse-experimental=MyExperimentalAPI' to module light_idea_test_case compiler arguments
|
||||
// ERROR: This declaration overrides experimental member of supertype 'Base' and must be annotated with '@MyExperimentalAPI'
|
||||
|
||||
@Experimental
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.intellij.rt.execution.junit.FileComparisonFailure
|
||||
import com.intellij.testFramework.*
|
||||
import com.intellij.util.ui.UIUtil
|
||||
import junit.framework.TestCase
|
||||
import org.jetbrains.kotlin.idea.facet.KotlinFacet
|
||||
import org.jetbrains.kotlin.idea.quickfix.utils.findInspectionFile
|
||||
import org.jetbrains.kotlin.idea.test.*
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
@@ -114,6 +115,13 @@ abstract class AbstractQuickFixTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||
|
||||
applyAction(contents, fileName)
|
||||
|
||||
val compilerArgumentsAfter = InTextDirectivesUtils.findStringWithPrefixes(fileText, "COMPILER_ARGUMENTS_AFTER: ")
|
||||
if (compilerArgumentsAfter != null) {
|
||||
val facetSettings = KotlinFacet.get(module)!!.configuration.settings
|
||||
val compilerSettings = facetSettings.compilerSettings
|
||||
TestCase.assertEquals(compilerArgumentsAfter, compilerSettings?.additionalArguments)
|
||||
}
|
||||
|
||||
UsefulTestCase.assertEmpty(expectedErrorMessage)
|
||||
}
|
||||
catch (e: FileComparisonFailure) {
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.intellij.rt.execution.junit.FileComparisonFailure
|
||||
import com.intellij.testFramework.*
|
||||
import com.intellij.util.ui.UIUtil
|
||||
import junit.framework.TestCase
|
||||
import org.jetbrains.kotlin.idea.facet.KotlinFacet
|
||||
import org.jetbrains.kotlin.idea.quickfix.utils.findInspectionFile
|
||||
import org.jetbrains.kotlin.idea.test.*
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
@@ -98,6 +99,13 @@ abstract class AbstractQuickFixTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||
|
||||
applyAction(contents, testFile.canonicalPath)
|
||||
|
||||
val compilerArgumentsAfter = InTextDirectivesUtils.findStringWithPrefixes(fileText, "COMPILER_ARGUMENTS_AFTER: ")
|
||||
if (compilerArgumentsAfter != null) {
|
||||
val facetSettings = KotlinFacet.get(module)!!.configuration.settings
|
||||
val compilerSettings = facetSettings.compilerSettings
|
||||
TestCase.assertEquals(compilerArgumentsAfter, compilerSettings?.additionalArguments)
|
||||
}
|
||||
|
||||
UsefulTestCase.assertEmpty(expectedErrorMessage)
|
||||
}
|
||||
catch (e: FileComparisonFailure) {
|
||||
|
||||
@@ -6047,6 +6047,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
runTest("idea/testData/quickfix/experimental/basicFunctionNotApplicable.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("basicModule.kt")
|
||||
public void testBasicModule() throws Exception {
|
||||
runTest("idea/testData/quickfix/experimental/basicModule.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("basicUseExperimental.kt")
|
||||
public void testBasicUseExperimental() throws Exception {
|
||||
runTest("idea/testData/quickfix/experimental/basicUseExperimental.kt");
|
||||
|
||||
Reference in New Issue
Block a user