ExperimentalFixesFactory: OptIn shouldn't be added for old version
#KT-36478
This commit is contained in:
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.idea.quickfix
|
|||||||
|
|
||||||
import com.intellij.codeInsight.intention.IntentionAction
|
import com.intellij.codeInsight.intention.IntentionAction
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
||||||
import org.jetbrains.kotlin.descriptors.resolveClassByFqName
|
import org.jetbrains.kotlin.descriptors.resolveClassByFqName
|
||||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||||
@@ -16,6 +17,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
|||||||
import org.jetbrains.kotlin.idea.core.toDescriptor
|
import org.jetbrains.kotlin.idea.core.toDescriptor
|
||||||
import org.jetbrains.kotlin.idea.util.projectStructure.module
|
import org.jetbrains.kotlin.idea.util.projectStructure.module
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypesAndPredicate
|
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypesAndPredicate
|
||||||
@@ -36,8 +38,7 @@ object ExperimentalFixesFactory : KotlinIntentionActionsFactory() {
|
|||||||
!KtPsiUtil.isLocal(it)
|
!KtPsiUtil.isLocal(it)
|
||||||
} ?: return emptyList()
|
} ?: return emptyList()
|
||||||
|
|
||||||
val factory = diagnostic.factory
|
val annotationFqName = when (diagnostic.factory) {
|
||||||
val annotationFqName = when (factory) {
|
|
||||||
EXPERIMENTAL_API_USAGE -> EXPERIMENTAL_API_USAGE.cast(diagnostic).a
|
EXPERIMENTAL_API_USAGE -> EXPERIMENTAL_API_USAGE.cast(diagnostic).a
|
||||||
EXPERIMENTAL_API_USAGE_ERROR -> EXPERIMENTAL_API_USAGE_ERROR.cast(diagnostic).a
|
EXPERIMENTAL_API_USAGE_ERROR -> EXPERIMENTAL_API_USAGE_ERROR.cast(diagnostic).a
|
||||||
EXPERIMENTAL_OVERRIDE -> EXPERIMENTAL_OVERRIDE.cast(diagnostic).a
|
EXPERIMENTAL_OVERRIDE -> EXPERIMENTAL_OVERRIDE.cast(diagnostic).a
|
||||||
@@ -71,7 +72,7 @@ object ExperimentalFixesFactory : KotlinIntentionActionsFactory() {
|
|||||||
}
|
}
|
||||||
result.add(
|
result.add(
|
||||||
AddAnnotationFix(
|
AddAnnotationFix(
|
||||||
containingDeclaration, ExperimentalUsageChecker.OPT_IN_FQ_NAME, suffix, annotationFqName
|
containingDeclaration, moduleDescriptor.OPT_IN_FQ_NAME, suffix, annotationFqName
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -84,7 +85,7 @@ object ExperimentalFixesFactory : KotlinIntentionActionsFactory() {
|
|||||||
} else {
|
} else {
|
||||||
result.add(
|
result.add(
|
||||||
AddAnnotationFix(
|
AddAnnotationFix(
|
||||||
containingClassOrObject, ExperimentalUsageChecker.OPT_IN_FQ_NAME, suffix, annotationFqName
|
containingClassOrObject, moduleDescriptor.OPT_IN_FQ_NAME, suffix, annotationFqName
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -100,4 +101,11 @@ object ExperimentalFixesFactory : KotlinIntentionActionsFactory() {
|
|||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val ModuleDescriptor.OPT_IN_FQ_NAME: FqName
|
||||||
|
get() = ExperimentalUsageChecker.OPT_IN_FQ_NAME.takeIf { fqNameIsExisting(it) }
|
||||||
|
?: ExperimentalUsageChecker.OLD_USE_EXPERIMENTAL_FQ_NAME
|
||||||
|
|
||||||
|
|
||||||
|
fun ModuleDescriptor.fqNameIsExisting(fqName: FqName): Boolean = resolveClassByFqName(fqName, NoLookupLocation.FROM_IDE) != null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,10 +13,12 @@ import com.intellij.openapi.project.Project
|
|||||||
import org.jetbrains.kotlin.config.CompilerSettings
|
import org.jetbrains.kotlin.config.CompilerSettings
|
||||||
import org.jetbrains.kotlin.config.additionalArgumentsAsList
|
import org.jetbrains.kotlin.config.additionalArgumentsAsList
|
||||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||||
|
import org.jetbrains.kotlin.idea.caches.project.toDescriptor
|
||||||
import org.jetbrains.kotlin.idea.configuration.BuildSystemType
|
import org.jetbrains.kotlin.idea.configuration.BuildSystemType
|
||||||
import org.jetbrains.kotlin.idea.configuration.getBuildSystemType
|
import org.jetbrains.kotlin.idea.configuration.getBuildSystemType
|
||||||
import org.jetbrains.kotlin.idea.facet.KotlinFacet
|
import org.jetbrains.kotlin.idea.facet.KotlinFacet
|
||||||
import org.jetbrains.kotlin.idea.facet.getOrCreateFacet
|
import org.jetbrains.kotlin.idea.facet.getOrCreateFacet
|
||||||
|
import org.jetbrains.kotlin.idea.quickfix.ExperimentalFixesFactory.fqNameIsExisting
|
||||||
import org.jetbrains.kotlin.idea.roots.invalidateProjectRoots
|
import org.jetbrains.kotlin.idea.roots.invalidateProjectRoots
|
||||||
import org.jetbrains.kotlin.idea.util.projectStructure.module
|
import org.jetbrains.kotlin.idea.util.projectStructure.module
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
@@ -28,11 +30,16 @@ class MakeModuleExperimentalFix(
|
|||||||
private val module: Module,
|
private val module: Module,
|
||||||
private val annotationFqName: FqName
|
private val annotationFqName: FqName
|
||||||
) : KotlinQuickFixAction<KtFile>(file) {
|
) : KotlinQuickFixAction<KtFile>(file) {
|
||||||
override fun getText(): String = "Add '-Xopt-in=$annotationFqName' to module ${module.name} compiler arguments"
|
private val experimentalPrefix = if (module.toDescriptor()?.fqNameIsExisting(ExperimentalUsageChecker.REQUIRES_OPT_IN_FQ_NAME) == true)
|
||||||
|
"opt-in"
|
||||||
|
else
|
||||||
|
"use-experimental"
|
||||||
|
|
||||||
|
override fun getText(): String = "Add '$compilerArgument' to module ${module.name} compiler arguments"
|
||||||
|
|
||||||
override fun getFamilyName(): String = "Add an opt-in requirement marker compiler argument"
|
override fun getFamilyName(): String = "Add an opt-in requirement marker compiler argument"
|
||||||
|
|
||||||
private val compilerArgument = "-Xopt-in=$annotationFqName"
|
private val compilerArgument = "-X$experimentalPrefix=$annotationFqName"
|
||||||
|
|
||||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||||
val modelsProvider = IdeModifiableModelsProviderImpl(project)
|
val modelsProvider = IdeModifiableModelsProviderImpl(project)
|
||||||
@@ -56,7 +63,7 @@ class MakeModuleExperimentalFix(
|
|||||||
val facet = KotlinFacet.get(module) ?: return true
|
val facet = KotlinFacet.get(module) ?: return true
|
||||||
val facetSettings = facet.configuration.settings
|
val facetSettings = facet.configuration.settings
|
||||||
val compilerSettings = facetSettings.compilerSettings ?: return true
|
val compilerSettings = facetSettings.compilerSettings ?: return true
|
||||||
return if (annotationFqName != ExperimentalUsageChecker.REQUIRES_OPT_IN_FQ_NAME) {
|
return if (annotationFqName != ExperimentalUsageChecker.REQUIRES_OPT_IN_FQ_NAME && annotationFqName != ExperimentalUsageChecker.OLD_EXPERIMENTAL_FQ_NAME) {
|
||||||
compilerArgument !in compilerSettings.additionalArgumentsAsList
|
compilerArgument !in compilerSettings.additionalArgumentsAsList
|
||||||
} else {
|
} else {
|
||||||
compilerSettings.additionalArgumentsAsList.none {
|
compilerSettings.additionalArgumentsAsList.none {
|
||||||
@@ -69,7 +76,13 @@ class MakeModuleExperimentalFix(
|
|||||||
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
|
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
|
||||||
val containingKtFile = diagnostic.psiElement.containingFile as? KtFile ?: return null
|
val containingKtFile = diagnostic.psiElement.containingFile as? KtFile ?: return null
|
||||||
val module = containingKtFile.module ?: return null
|
val module = containingKtFile.module ?: return null
|
||||||
return MakeModuleExperimentalFix(containingKtFile, module, ExperimentalUsageChecker.REQUIRES_OPT_IN_FQ_NAME)
|
return MakeModuleExperimentalFix(
|
||||||
|
containingKtFile,
|
||||||
|
module,
|
||||||
|
ExperimentalUsageChecker.REQUIRES_OPT_IN_FQ_NAME.takeIf {
|
||||||
|
module.toDescriptor()?.fqNameIsExisting(it) == true
|
||||||
|
} ?: ExperimentalUsageChecker.OLD_EXPERIMENTAL_FQ_NAME
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user