Extract common parts from ExperimentalUsageChecker
This commit is contained in:
+4
-4
@@ -52,18 +52,18 @@ class ExperimentalMarkerDeclarationAnnotationChecker(private val module: ModuleD
|
|||||||
for (entry in entries) {
|
for (entry in entries) {
|
||||||
val annotation = trace.bindingContext.get(BindingContext.ANNOTATION, entry) ?: continue
|
val annotation = trace.bindingContext.get(BindingContext.ANNOTATION, entry) ?: continue
|
||||||
when (annotation.fqName) {
|
when (annotation.fqName) {
|
||||||
in ExperimentalUsageChecker.USE_EXPERIMENTAL_FQ_NAMES -> {
|
in OptInNames.USE_EXPERIMENTAL_FQ_NAMES -> {
|
||||||
val annotationClasses =
|
val annotationClasses =
|
||||||
annotation.allValueArguments[ExperimentalUsageChecker.USE_EXPERIMENTAL_ANNOTATION_CLASS]
|
annotation.allValueArguments[OptInNames.USE_EXPERIMENTAL_ANNOTATION_CLASS]
|
||||||
.safeAs<ArrayValue>()?.value.orEmpty()
|
.safeAs<ArrayValue>()?.value.orEmpty()
|
||||||
checkUseExperimentalUsage(annotationClasses, trace, entry)
|
checkUseExperimentalUsage(annotationClasses, trace, entry)
|
||||||
}
|
}
|
||||||
in ExperimentalUsageChecker.EXPERIMENTAL_FQ_NAMES -> {
|
in OptInNames.EXPERIMENTAL_FQ_NAMES -> {
|
||||||
isAnnotatedWithExperimental = true
|
isAnnotatedWithExperimental = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val annotationClass = annotation.annotationClass ?: continue
|
val annotationClass = annotation.annotationClass ?: continue
|
||||||
if (annotationClass.annotations.any { it.fqName in ExperimentalUsageChecker.EXPERIMENTAL_FQ_NAMES }) {
|
if (annotationClass.annotations.any { it.fqName in OptInNames.EXPERIMENTAL_FQ_NAMES }) {
|
||||||
val annotationUseSiteTarget = entry.useSiteTarget?.getAnnotationUseSiteTarget()
|
val annotationUseSiteTarget = entry.useSiteTarget?.getAnnotationUseSiteTarget()
|
||||||
if (KotlinTarget.PROPERTY_GETTER in actualTargets ||
|
if (KotlinTarget.PROPERTY_GETTER in actualTargets ||
|
||||||
annotationUseSiteTarget == AnnotationUseSiteTarget.PROPERTY_GETTER
|
annotationUseSiteTarget == AnnotationUseSiteTarget.PROPERTY_GETTER
|
||||||
|
|||||||
+18
-24
@@ -34,6 +34,14 @@ import org.jetbrains.kotlin.resolve.*
|
|||||||
import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker
|
import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker
|
||||||
import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext
|
import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
|
import org.jetbrains.kotlin.resolve.checkers.OptInNames.EXPERIMENTAL_FQ_NAMES
|
||||||
|
import org.jetbrains.kotlin.resolve.checkers.OptInNames.OLD_EXPERIMENTAL_FQ_NAME
|
||||||
|
import org.jetbrains.kotlin.resolve.checkers.OptInNames.OLD_USE_EXPERIMENTAL_FQ_NAME
|
||||||
|
import org.jetbrains.kotlin.resolve.checkers.OptInNames.OPT_IN_FQ_NAME
|
||||||
|
import org.jetbrains.kotlin.resolve.checkers.OptInNames.REQUIRES_OPT_IN_FQ_NAME
|
||||||
|
import org.jetbrains.kotlin.resolve.checkers.OptInNames.USE_EXPERIMENTAL_ANNOTATION_CLASS
|
||||||
|
import org.jetbrains.kotlin.resolve.checkers.OptInNames.USE_EXPERIMENTAL_FQ_NAMES
|
||||||
|
import org.jetbrains.kotlin.resolve.checkers.OptInNames.WAS_EXPERIMENTAL_FQ_NAME
|
||||||
import org.jetbrains.kotlin.resolve.constants.ArrayValue
|
import org.jetbrains.kotlin.resolve.constants.ArrayValue
|
||||||
import org.jetbrains.kotlin.resolve.constants.EnumValue
|
import org.jetbrains.kotlin.resolve.constants.EnumValue
|
||||||
import org.jetbrains.kotlin.resolve.constants.KClassValue
|
import org.jetbrains.kotlin.resolve.constants.KClassValue
|
||||||
@@ -55,14 +63,6 @@ import org.jetbrains.kotlin.utils.addIfNotNull
|
|||||||
class ExperimentalUsageChecker(project: Project) : CallChecker {
|
class ExperimentalUsageChecker(project: Project) : CallChecker {
|
||||||
private val moduleAnnotationsResolver = ModuleAnnotationsResolver.getInstance(project)
|
private val moduleAnnotationsResolver = ModuleAnnotationsResolver.getInstance(project)
|
||||||
|
|
||||||
data class Experimentality(val annotationFqName: FqName, val severity: Severity, val message: String?) {
|
|
||||||
enum class Severity { WARNING, ERROR }
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
val DEFAULT_SEVERITY = Severity.ERROR
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ExperimentalityDiagnostic {
|
interface ExperimentalityDiagnostic {
|
||||||
fun report(trace: BindingTrace, element: PsiElement, fqName: FqName, message: String?)
|
fun report(trace: BindingTrace, element: PsiElement, fqName: FqName, message: String?)
|
||||||
}
|
}
|
||||||
@@ -113,18 +113,6 @@ class ExperimentalUsageChecker(project: Project) : CallChecker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val OLD_EXPERIMENTAL_FQ_NAME = FqName("kotlin.Experimental")
|
|
||||||
val OLD_USE_EXPERIMENTAL_FQ_NAME = FqName("kotlin.UseExperimental")
|
|
||||||
val REQUIRES_OPT_IN_FQ_NAME = FqName("kotlin.RequiresOptIn")
|
|
||||||
val OPT_IN_FQ_NAME = FqName("kotlin.OptIn")
|
|
||||||
|
|
||||||
val EXPERIMENTAL_FQ_NAMES = setOf(OLD_EXPERIMENTAL_FQ_NAME, REQUIRES_OPT_IN_FQ_NAME)
|
|
||||||
val USE_EXPERIMENTAL_FQ_NAMES = setOf(OLD_USE_EXPERIMENTAL_FQ_NAME, OPT_IN_FQ_NAME)
|
|
||||||
|
|
||||||
internal val WAS_EXPERIMENTAL_FQ_NAME = FqName("kotlin.WasExperimental")
|
|
||||||
internal val USE_EXPERIMENTAL_ANNOTATION_CLASS = Name.identifier("markerClass")
|
|
||||||
internal val WAS_EXPERIMENTAL_ANNOTATION_CLASS = Name.identifier("markerClass")
|
|
||||||
|
|
||||||
private val LEVEL = Name.identifier("level")
|
private val LEVEL = Name.identifier("level")
|
||||||
private val MESSAGE = Name.identifier("message")
|
private val MESSAGE = Name.identifier("message")
|
||||||
private val WARNING_LEVEL = Name.identifier("WARNING")
|
private val WARNING_LEVEL = Name.identifier("WARNING")
|
||||||
@@ -329,8 +317,12 @@ class ExperimentalUsageChecker(project: Project) : CallChecker {
|
|||||||
// Ideally, we should run full resolution (with all classifier usage checkers) on classifiers used in "-Xexperimental" and
|
// Ideally, we should run full resolution (with all classifier usage checkers) on classifiers used in "-Xexperimental" and
|
||||||
// "-Xuse-experimental" arguments. However, it's not easy to do this. This should be solved in the future with the support of
|
// "-Xuse-experimental" arguments. However, it's not easy to do this. This should be solved in the future with the support of
|
||||||
// module annotations. For now, we only check deprecations because this is needed to correctly retire unneeded compiler arguments.
|
// module annotations. For now, we only check deprecations because this is needed to correctly retire unneeded compiler arguments.
|
||||||
val deprecationResolver =
|
val deprecationResolver = DeprecationResolver(
|
||||||
DeprecationResolver(LockBasedStorageManager("ExperimentalUsageChecker"), languageVersionSettings, CoroutineCompatibilitySupport.ENABLED, DeprecationSettings.Default)
|
LockBasedStorageManager("ExperimentalUsageChecker"),
|
||||||
|
languageVersionSettings,
|
||||||
|
CoroutineCompatibilitySupport.ENABLED,
|
||||||
|
DeprecationSettings.Default
|
||||||
|
)
|
||||||
|
|
||||||
// Returns true if fqName resolves to a valid opt-in requirement marker.
|
// Returns true if fqName resolves to a valid opt-in requirement marker.
|
||||||
fun checkAnnotation(fqName: String): Boolean {
|
fun checkAnnotation(fqName: String): Boolean {
|
||||||
@@ -372,7 +364,8 @@ class ExperimentalUsageChecker(project: Project) : CallChecker {
|
|||||||
override fun check(targetDescriptor: ClassifierDescriptor, element: PsiElement, context: ClassifierUsageCheckerContext) {
|
override fun check(targetDescriptor: ClassifierDescriptor, element: PsiElement, context: ClassifierUsageCheckerContext) {
|
||||||
val name = targetDescriptor.name
|
val name = targetDescriptor.name
|
||||||
if (name == OLD_EXPERIMENTAL_FQ_NAME.shortName() || name == REQUIRES_OPT_IN_FQ_NAME.shortName() ||
|
if (name == OLD_EXPERIMENTAL_FQ_NAME.shortName() || name == REQUIRES_OPT_IN_FQ_NAME.shortName() ||
|
||||||
name == OLD_USE_EXPERIMENTAL_FQ_NAME.shortName() || name == OPT_IN_FQ_NAME.shortName()) {
|
name == OLD_USE_EXPERIMENTAL_FQ_NAME.shortName() || name == OPT_IN_FQ_NAME.shortName()
|
||||||
|
) {
|
||||||
val fqName = targetDescriptor.fqNameSafe
|
val fqName = targetDescriptor.fqNameSafe
|
||||||
if (fqName in EXPERIMENTAL_FQ_NAMES || fqName in USE_EXPERIMENTAL_FQ_NAMES) {
|
if (fqName in EXPERIMENTAL_FQ_NAMES || fqName in USE_EXPERIMENTAL_FQ_NAMES) {
|
||||||
checkUsageOfKotlinExperimentalOrUseExperimental(element, context)
|
checkUsageOfKotlinExperimentalOrUseExperimental(element, context)
|
||||||
@@ -412,7 +405,8 @@ class ExperimentalUsageChecker(project: Project) : CallChecker {
|
|||||||
private fun checkUsageOfKotlinExperimentalOrUseExperimental(element: PsiElement, context: CheckerContext) {
|
private fun checkUsageOfKotlinExperimentalOrUseExperimental(element: PsiElement, context: CheckerContext) {
|
||||||
val useExperimentalFqNames = context.languageVersionSettings.getFlag(AnalysisFlags.useExperimental)
|
val useExperimentalFqNames = context.languageVersionSettings.getFlag(AnalysisFlags.useExperimental)
|
||||||
if (REQUIRES_OPT_IN_FQ_NAME.asString() !in useExperimentalFqNames &&
|
if (REQUIRES_OPT_IN_FQ_NAME.asString() !in useExperimentalFqNames &&
|
||||||
OLD_EXPERIMENTAL_FQ_NAME.asString() !in useExperimentalFqNames) {
|
OLD_EXPERIMENTAL_FQ_NAME.asString() !in useExperimentalFqNames
|
||||||
|
) {
|
||||||
context.trace.report(Errors.EXPERIMENTAL_IS_NOT_ENABLED.on(element))
|
context.trace.report(Errors.EXPERIMENTAL_IS_NOT_ENABLED.on(element))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
|
|||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
|
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
|
||||||
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForTypeAliasObject
|
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForTypeAliasObject
|
||||||
import org.jetbrains.kotlin.resolve.checkers.ExperimentalUsageChecker
|
import org.jetbrains.kotlin.resolve.checkers.OptInNames
|
||||||
import org.jetbrains.kotlin.resolve.constants.ArrayValue
|
import org.jetbrains.kotlin.resolve.constants.ArrayValue
|
||||||
import org.jetbrains.kotlin.resolve.constants.KClassValue
|
import org.jetbrains.kotlin.resolve.constants.KClassValue
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||||
@@ -88,8 +88,8 @@ private fun DeclarationDescriptor.getOwnSinceKotlinVersion(): SinceKotlinValue?
|
|||||||
(this as? PropertyAccessorDescriptor)?.correspondingProperty?.consider()
|
(this as? PropertyAccessorDescriptor)?.correspondingProperty?.consider()
|
||||||
|
|
||||||
val typeAlias = this as? TypeAliasDescriptor
|
val typeAlias = this as? TypeAliasDescriptor
|
||||||
?: (this as? TypeAliasConstructorDescriptor)?.typeAliasDescriptor
|
?: (this as? TypeAliasConstructorDescriptor)?.typeAliasDescriptor
|
||||||
?: (this as? FakeCallableDescriptorForTypeAliasObject)?.typeAliasDescriptor
|
?: (this as? FakeCallableDescriptorForTypeAliasObject)?.typeAliasDescriptor
|
||||||
|
|
||||||
typeAlias?.consider()
|
typeAlias?.consider()
|
||||||
|
|
||||||
@@ -103,9 +103,9 @@ private fun DeclarationDescriptor.getOwnSinceKotlinVersion(): SinceKotlinValue?
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun DeclarationDescriptor.loadWasExperimentalMarkerClasses(): List<ClassDescriptor> {
|
private fun DeclarationDescriptor.loadWasExperimentalMarkerClasses(): List<ClassDescriptor> {
|
||||||
val wasExperimental = annotations.findAnnotation(ExperimentalUsageChecker.WAS_EXPERIMENTAL_FQ_NAME)
|
val wasExperimental = annotations.findAnnotation(OptInNames.WAS_EXPERIMENTAL_FQ_NAME)
|
||||||
if (wasExperimental != null) {
|
if (wasExperimental != null) {
|
||||||
val annotationClasses = wasExperimental.allValueArguments[ExperimentalUsageChecker.WAS_EXPERIMENTAL_ANNOTATION_CLASS]
|
val annotationClasses = wasExperimental.allValueArguments[OptInNames.WAS_EXPERIMENTAL_ANNOTATION_CLASS]
|
||||||
if (annotationClasses is ArrayValue) {
|
if (annotationClasses is ArrayValue) {
|
||||||
return annotationClasses.value.mapNotNull { annotationClass ->
|
return annotationClasses.value.mapNotNull { annotationClass ->
|
||||||
(annotationClass as? KClassValue)?.getArgumentType(module)?.constructor?.declarationDescriptor as? ClassDescriptor
|
(annotationClass as? KClassValue)?.getArgumentType(module)?.constructor?.declarationDescriptor as? ClassDescriptor
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* 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.resolve.checkers
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
|
||||||
|
data class Experimentality(val annotationFqName: FqName, val severity: Severity, val message: String?) {
|
||||||
|
enum class Severity { WARNING, ERROR }
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val DEFAULT_SEVERITY = Severity.ERROR
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* 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.resolve.checkers
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
|
object OptInNames {
|
||||||
|
val OLD_EXPERIMENTAL_FQ_NAME = FqName("kotlin.Experimental")
|
||||||
|
val OLD_USE_EXPERIMENTAL_FQ_NAME = FqName("kotlin.UseExperimental")
|
||||||
|
val REQUIRES_OPT_IN_FQ_NAME = FqName("kotlin.RequiresOptIn")
|
||||||
|
val OPT_IN_FQ_NAME = FqName("kotlin.OptIn")
|
||||||
|
|
||||||
|
val WAS_EXPERIMENTAL_FQ_NAME = FqName("kotlin.WasExperimental")
|
||||||
|
val USE_EXPERIMENTAL_ANNOTATION_CLASS = Name.identifier("markerClass")
|
||||||
|
val WAS_EXPERIMENTAL_ANNOTATION_CLASS = Name.identifier("markerClass")
|
||||||
|
|
||||||
|
val EXPERIMENTAL_FQ_NAMES = setOf(OLD_EXPERIMENTAL_FQ_NAME, REQUIRES_OPT_IN_FQ_NAME)
|
||||||
|
val USE_EXPERIMENTAL_FQ_NAMES = setOf(OLD_USE_EXPERIMENTAL_FQ_NAME, OPT_IN_FQ_NAME)
|
||||||
|
}
|
||||||
+3
-3
@@ -40,8 +40,8 @@ import org.jetbrains.kotlin.renderer.DescriptorRenderer.Companion.withOptions
|
|||||||
import org.jetbrains.kotlin.renderer.DescriptorRendererModifier.*
|
import org.jetbrains.kotlin.renderer.DescriptorRendererModifier.*
|
||||||
import org.jetbrains.kotlin.renderer.OverrideRenderingPolicy
|
import org.jetbrains.kotlin.renderer.OverrideRenderingPolicy
|
||||||
import org.jetbrains.kotlin.renderer.render
|
import org.jetbrains.kotlin.renderer.render
|
||||||
import org.jetbrains.kotlin.resolve.checkers.ExperimentalUsageChecker
|
|
||||||
import org.jetbrains.kotlin.resolve.checkers.ExplicitApiDeclarationChecker
|
import org.jetbrains.kotlin.resolve.checkers.ExplicitApiDeclarationChecker
|
||||||
|
import org.jetbrains.kotlin.resolve.checkers.OptInNames
|
||||||
import org.jetbrains.kotlin.resolve.checkers.explicitApiEnabled
|
import org.jetbrains.kotlin.resolve.checkers.explicitApiEnabled
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.setSingleOverridden
|
import org.jetbrains.kotlin.resolve.descriptorUtil.setSingleOverridden
|
||||||
import org.jetbrains.kotlin.util.findCallableMemberBySignature
|
import org.jetbrains.kotlin.util.findCallableMemberBySignature
|
||||||
@@ -209,8 +209,8 @@ private val OVERRIDE_RENDERER = withOptions {
|
|||||||
renderUnabbreviatedType = false
|
renderUnabbreviatedType = false
|
||||||
annotationFilter = {
|
annotationFilter = {
|
||||||
val annotations = it.type.constructor.declarationDescriptor?.annotations
|
val annotations = it.type.constructor.declarationDescriptor?.annotations
|
||||||
annotations != null && (annotations.hasAnnotation(ExperimentalUsageChecker.REQUIRES_OPT_IN_FQ_NAME) ||
|
annotations != null && (annotations.hasAnnotation(OptInNames.REQUIRES_OPT_IN_FQ_NAME) ||
|
||||||
annotations.hasAnnotation(ExperimentalUsageChecker.OLD_EXPERIMENTAL_FQ_NAME))
|
annotations.hasAnnotation(OptInNames.OLD_EXPERIMENTAL_FQ_NAME))
|
||||||
}
|
}
|
||||||
presentableUnresolvedTypes = true
|
presentableUnresolvedTypes = true
|
||||||
informativeErrorType = false
|
informativeErrorType = false
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ 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
|
||||||
import org.jetbrains.kotlin.resolve.AnnotationChecker
|
import org.jetbrains.kotlin.resolve.AnnotationChecker
|
||||||
import org.jetbrains.kotlin.resolve.checkers.ExperimentalUsageChecker
|
import org.jetbrains.kotlin.resolve.checkers.OptInNames
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||||
|
|
||||||
object ExperimentalFixesFactory : KotlinIntentionActionsFactory() {
|
object ExperimentalFixesFactory : KotlinIntentionActionsFactory() {
|
||||||
@@ -103,8 +103,8 @@ object ExperimentalFixesFactory : KotlinIntentionActionsFactory() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val ModuleDescriptor.OPT_IN_FQ_NAME: FqName
|
private val ModuleDescriptor.OPT_IN_FQ_NAME: FqName
|
||||||
get() = ExperimentalUsageChecker.OPT_IN_FQ_NAME.takeIf { fqNameIsExisting(it) }
|
get() = OptInNames.OPT_IN_FQ_NAME.takeIf { fqNameIsExisting(it) }
|
||||||
?: ExperimentalUsageChecker.OLD_USE_EXPERIMENTAL_FQ_NAME
|
?: OptInNames.OLD_USE_EXPERIMENTAL_FQ_NAME
|
||||||
|
|
||||||
|
|
||||||
fun ModuleDescriptor.fqNameIsExisting(fqName: FqName): Boolean = resolveClassByFqName(fqName, NoLookupLocation.FROM_IDE) != null
|
fun ModuleDescriptor.fqNameIsExisting(fqName: FqName): Boolean = resolveClassByFqName(fqName, NoLookupLocation.FROM_IDE) != null
|
||||||
|
|||||||
@@ -24,14 +24,14 @@ 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
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.resolve.checkers.ExperimentalUsageChecker
|
import org.jetbrains.kotlin.resolve.checkers.OptInNames
|
||||||
|
|
||||||
class MakeModuleExperimentalFix(
|
class MakeModuleExperimentalFix(
|
||||||
file: KtFile,
|
file: KtFile,
|
||||||
private val module: Module,
|
private val module: Module,
|
||||||
private val annotationFqName: FqName
|
private val annotationFqName: FqName
|
||||||
) : KotlinQuickFixAction<KtFile>(file) {
|
) : KotlinQuickFixAction<KtFile>(file) {
|
||||||
private val experimentalPrefix = if (module.toDescriptor()?.fqNameIsExisting(ExperimentalUsageChecker.REQUIRES_OPT_IN_FQ_NAME) == true)
|
private val experimentalPrefix = if (module.toDescriptor()?.fqNameIsExisting(OptInNames.REQUIRES_OPT_IN_FQ_NAME) == true)
|
||||||
"opt-in"
|
"opt-in"
|
||||||
else
|
else
|
||||||
"use-experimental"
|
"use-experimental"
|
||||||
@@ -64,7 +64,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 && annotationFqName != ExperimentalUsageChecker.OLD_EXPERIMENTAL_FQ_NAME) {
|
return if (annotationFqName != OptInNames.REQUIRES_OPT_IN_FQ_NAME && annotationFqName != OptInNames.OLD_EXPERIMENTAL_FQ_NAME) {
|
||||||
compilerArgument !in compilerSettings.additionalArgumentsAsList
|
compilerArgument !in compilerSettings.additionalArgumentsAsList
|
||||||
} else {
|
} else {
|
||||||
compilerSettings.additionalArgumentsAsList.none {
|
compilerSettings.additionalArgumentsAsList.none {
|
||||||
@@ -80,9 +80,9 @@ class MakeModuleExperimentalFix(
|
|||||||
return MakeModuleExperimentalFix(
|
return MakeModuleExperimentalFix(
|
||||||
containingKtFile,
|
containingKtFile,
|
||||||
module,
|
module,
|
||||||
ExperimentalUsageChecker.REQUIRES_OPT_IN_FQ_NAME.takeIf {
|
OptInNames.REQUIRES_OPT_IN_FQ_NAME.takeIf {
|
||||||
module.toDescriptor()?.fqNameIsExisting(it) == true
|
module.toDescriptor()?.fqNameIsExisting(it) == true
|
||||||
} ?: ExperimentalUsageChecker.OLD_EXPERIMENTAL_FQ_NAME
|
} ?: OptInNames.OLD_EXPERIMENTAL_FQ_NAME
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ 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.hasActualModifier
|
import org.jetbrains.kotlin.psi.psiUtil.hasActualModifier
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.checkers.ExperimentalUsageChecker
|
import org.jetbrains.kotlin.resolve.checkers.OptInNames
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.OptionalAnnotationUtil
|
import org.jetbrains.kotlin.resolve.multiplatform.OptionalAnnotationUtil
|
||||||
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
|
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
|
||||||
@@ -262,8 +262,8 @@ private fun KtPsiFactory.repairSuperTypeList(
|
|||||||
private val forbiddenAnnotationFqNames = setOf(
|
private val forbiddenAnnotationFqNames = setOf(
|
||||||
OptionalAnnotationUtil.OPTIONAL_EXPECTATION_FQ_NAME,
|
OptionalAnnotationUtil.OPTIONAL_EXPECTATION_FQ_NAME,
|
||||||
FqName("kotlin.ExperimentalMultiplatform"),
|
FqName("kotlin.ExperimentalMultiplatform"),
|
||||||
ExperimentalUsageChecker.OPT_IN_FQ_NAME,
|
OptInNames.OPT_IN_FQ_NAME,
|
||||||
ExperimentalUsageChecker.OLD_USE_EXPERIMENTAL_FQ_NAME
|
OptInNames.OLD_USE_EXPERIMENTAL_FQ_NAME
|
||||||
)
|
)
|
||||||
|
|
||||||
internal fun generateCallable(
|
internal fun generateCallable(
|
||||||
|
|||||||
Reference in New Issue
Block a user