Skip to content

Commit

Permalink
ExperimentalFixesFactory: OptIn shouldn't be added for old version
Browse files Browse the repository at this point in the history
#KT-36478

(cherry picked from commit ecb7478)
  • Loading branch information
dimonchik0036 committed Mar 3, 2020
1 parent 9922e74 commit facddfc
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.idea.quickfix

import com.intellij.codeInsight.intention.IntentionAction
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
import org.jetbrains.kotlin.descriptors.resolveClassByFqName
import org.jetbrains.kotlin.diagnostics.Diagnostic
Expand All @@ -16,6 +17,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
import org.jetbrains.kotlin.idea.core.toDescriptor
import org.jetbrains.kotlin.idea.util.projectStructure.module
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypesAndPredicate
Expand All @@ -36,8 +38,7 @@ object ExperimentalFixesFactory : KotlinIntentionActionsFactory() {
!KtPsiUtil.isLocal(it)
} ?: return emptyList()

val factory = diagnostic.factory
val annotationFqName = when (factory) {
val annotationFqName = when (diagnostic.factory) {
EXPERIMENTAL_API_USAGE -> EXPERIMENTAL_API_USAGE.cast(diagnostic).a
EXPERIMENTAL_API_USAGE_ERROR -> EXPERIMENTAL_API_USAGE_ERROR.cast(diagnostic).a
EXPERIMENTAL_OVERRIDE -> EXPERIMENTAL_OVERRIDE.cast(diagnostic).a
Expand Down Expand Up @@ -71,7 +72,7 @@ object ExperimentalFixesFactory : KotlinIntentionActionsFactory() {
}
result.add(
AddAnnotationFix(
containingDeclaration, ExperimentalUsageChecker.OPT_IN_FQ_NAME, suffix, annotationFqName
containingDeclaration, moduleDescriptor.OPT_IN_FQ_NAME, suffix, annotationFqName
)
)
}
Expand All @@ -84,7 +85,7 @@ object ExperimentalFixesFactory : KotlinIntentionActionsFactory() {
} else {
result.add(
AddAnnotationFix(
containingClassOrObject, ExperimentalUsageChecker.OPT_IN_FQ_NAME, suffix, annotationFqName
containingClassOrObject, moduleDescriptor.OPT_IN_FQ_NAME, suffix, annotationFqName
)
)
}
Expand All @@ -100,4 +101,11 @@ object ExperimentalFixesFactory : KotlinIntentionActionsFactory() {

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
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.config.CompilerSettings
import org.jetbrains.kotlin.config.additionalArgumentsAsList
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.getBuildSystemType
import org.jetbrains.kotlin.idea.facet.KotlinFacet
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.util.projectStructure.module
import org.jetbrains.kotlin.name.FqName
Expand All @@ -28,11 +30,16 @@ class MakeModuleExperimentalFix(
private val module: Module,
private val annotationFqName: FqName
) : 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"

private val compilerArgument = "-Xopt-in=$annotationFqName"
private val compilerArgument = "-X$experimentalPrefix=$annotationFqName"

override fun invoke(project: Project, editor: Editor?, file: KtFile) {
val modelsProvider = IdeModifiableModelsProviderImpl(project)
Expand All @@ -56,7 +63,7 @@ class MakeModuleExperimentalFix(
val facet = KotlinFacet.get(module) ?: return true
val facetSettings = facet.configuration.settings
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
} else {
compilerSettings.additionalArgumentsAsList.none {
Expand All @@ -69,7 +76,13 @@ class MakeModuleExperimentalFix(
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
val containingKtFile = diagnostic.psiElement.containingFile as? KtFile ?: 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
)
}
}
}

0 comments on commit facddfc

Please sign in to comment.