Change some names in source code from useExperimental to optIn

This commit is contained in:
Mikhail Glukhikh
2022-01-25 11:45:35 +03:00
committed by Space
parent 3e00f41a99
commit c255da815f
4 changed files with 37 additions and 23 deletions
@@ -58,9 +58,9 @@ object FirOptInAnnotationCallChecker : FirAnnotationCallChecker() {
reporter: DiagnosticReporter reporter: DiagnosticReporter
) { ) {
val languageVersionSettings = context.session.languageVersionSettings val languageVersionSettings = context.session.languageVersionSettings
val useExperimentalFqNames = languageVersionSettings.getFlag(AnalysisFlags.optIn) val optInFqNames = languageVersionSettings.getFlag(AnalysisFlags.optIn)
if (!languageVersionSettings.supportsFeature(LanguageFeature.OptInRelease) && if (!languageVersionSettings.supportsFeature(LanguageFeature.OptInRelease) &&
OptInNames.REQUIRES_OPT_IN_FQ_NAME.asString() !in useExperimentalFqNames OptInNames.REQUIRES_OPT_IN_FQ_NAME.asString() !in optInFqNames
) { ) {
reporter.reportOn(element, FirErrors.OPT_IN_IS_NOT_ENABLED, context) reporter.reportOn(element, FirErrors.OPT_IN_IS_NOT_ENABLED, context)
} }
@@ -47,18 +47,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 OptInNames.USE_EXPERIMENTAL_FQ_NAMES -> { in OptInNames.OPT_IN_FQ_NAMES -> {
val annotationClasses = val annotationClasses =
annotation.allValueArguments[OptInNames.USE_EXPERIMENTAL_ANNOTATION_CLASS] annotation.allValueArguments[OptInNames.USE_EXPERIMENTAL_ANNOTATION_CLASS]
.safeAs<ArrayValue>()?.value.orEmpty() .safeAs<ArrayValue>()?.value.orEmpty()
checkUseExperimentalUsage(annotationClasses, trace, entry) checkOptInUsage(annotationClasses, trace, entry)
} }
in OptInNames.EXPERIMENTAL_FQ_NAMES -> { in OptInNames.REQUIRES_OPT_IN_FQ_NAMES -> {
isAnnotatedWithExperimental = true isAnnotatedWithExperimental = true
} }
} }
val annotationClass = annotation.annotationClass ?: continue val annotationClass = annotation.annotationClass ?: continue
if (annotationClass.annotations.any { it.fqName in OptInNames.EXPERIMENTAL_FQ_NAMES }) { if (annotationClass.annotations.any { it.fqName in OptInNames.REQUIRES_OPT_IN_FQ_NAMES }) {
val applicableTargets = AnnotationChecker.applicableTargetSet(annotationClass) val applicableTargets = AnnotationChecker.applicableTargetSet(annotationClass)
val possibleTargets = applicableTargets.intersect(actualTargets) val possibleTargets = applicableTargets.intersect(actualTargets)
val annotationUseSiteTarget = entry.useSiteTarget?.getAnnotationUseSiteTarget() val annotationUseSiteTarget = entry.useSiteTarget?.getAnnotationUseSiteTarget()
@@ -131,7 +131,7 @@ class ExperimentalMarkerDeclarationAnnotationChecker(private val module: ModuleD
return false return false
} }
private fun checkUseExperimentalUsage(annotationClasses: List<ConstantValue<*>>, trace: BindingTrace, entry: KtAnnotationEntry) { private fun checkOptInUsage(annotationClasses: List<ConstantValue<*>>, trace: BindingTrace, entry: KtAnnotationEntry) {
if (annotationClasses.isEmpty()) { if (annotationClasses.isEmpty()) {
trace.report(Errors.OPT_IN_WITHOUT_ARGUMENTS.on(entry)) trace.report(Errors.OPT_IN_WITHOUT_ARGUMENTS.on(entry))
return return
@@ -35,13 +35,13 @@ 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.REQUIRES_OPT_IN_FQ_NAMES
import org.jetbrains.kotlin.resolve.checkers.OptInNames.OLD_EXPERIMENTAL_FQ_NAME 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.OLD_USE_EXPERIMENTAL_FQ_NAME
import org.jetbrains.kotlin.resolve.checkers.OptInNames.OPT_IN_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.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_ANNOTATION_CLASS
import org.jetbrains.kotlin.resolve.checkers.OptInNames.USE_EXPERIMENTAL_FQ_NAMES import org.jetbrains.kotlin.resolve.checkers.OptInNames.OPT_IN_FQ_NAMES
import org.jetbrains.kotlin.resolve.checkers.OptInNames.WAS_EXPERIMENTAL_FQ_NAME 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
@@ -303,7 +303,7 @@ class ExperimentalUsageChecker(project: Project) : CallChecker {
annotationFqName.asString() in languageVersionSettings.getFlag(AnalysisFlags.optIn) || annotationFqName.asString() in languageVersionSettings.getFlag(AnalysisFlags.optIn) ||
anyParentMatches { element -> anyParentMatches { element ->
element.isDeclarationAnnotatedWith(annotationFqName, bindingContext) || element.isDeclarationAnnotatedWith(annotationFqName, bindingContext) ||
element.isElementAnnotatedWithUseExperimentalOf(annotationFqName, bindingContext) element.isElementAnnotatedWithOptIn(annotationFqName, bindingContext)
} }
private fun PsiElement.isDeclarationAnnotatedWith(annotationFqName: FqName, bindingContext: BindingContext): Boolean { private fun PsiElement.isDeclarationAnnotatedWith(annotationFqName: FqName, bindingContext: BindingContext): Boolean {
@@ -313,10 +313,10 @@ class ExperimentalUsageChecker(project: Project) : CallChecker {
return descriptor != null && descriptor.annotations.hasAnnotation(annotationFqName) return descriptor != null && descriptor.annotations.hasAnnotation(annotationFqName)
} }
private fun PsiElement.isElementAnnotatedWithUseExperimentalOf(annotationFqName: FqName, bindingContext: BindingContext): Boolean { private fun PsiElement.isElementAnnotatedWithOptIn(annotationFqName: FqName, bindingContext: BindingContext): Boolean {
return this is KtAnnotated && annotationEntries.any { entry -> return this is KtAnnotated && annotationEntries.any { entry ->
val descriptor = bindingContext.get(BindingContext.ANNOTATION, entry) val descriptor = bindingContext.get(BindingContext.ANNOTATION, entry)
if (descriptor != null && descriptor.fqName in USE_EXPERIMENTAL_FQ_NAMES) { if (descriptor != null && descriptor.fqName in OPT_IN_FQ_NAMES) {
val annotationClasses = descriptor.allValueArguments[USE_EXPERIMENTAL_ANNOTATION_CLASS] val annotationClasses = descriptor.allValueArguments[USE_EXPERIMENTAL_ANNOTATION_CLASS]
annotationClasses is ArrayValue && annotationClasses.value.any { annotationClass -> annotationClasses is ArrayValue && annotationClasses.value.any { annotationClass ->
annotationClass is KClassValue && annotationClass.value.let { value -> annotationClass is KClassValue && annotationClass.value.let { value ->
@@ -391,8 +391,8 @@ class ExperimentalUsageChecker(project: Project) : CallChecker {
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 REQUIRES_OPT_IN_FQ_NAMES || fqName in OPT_IN_FQ_NAMES) {
checkUsageOfKotlinExperimentalOrUseExperimental(element, context) checkUsageOfKotlinExperimentalOrOptIn(element, context)
return return
} }
} }
@@ -404,7 +404,7 @@ class ExperimentalUsageChecker(project: Project) : CallChecker {
} }
if (targetClass != null && targetClass.loadExperimentalityForMarkerAnnotation() != null) { if (targetClass != null && targetClass.loadExperimentalityForMarkerAnnotation() != null) {
if (!element.isUsageAsAnnotationOrImport() && if (!element.isUsageAsAnnotationOrImport() &&
!element.isUsageAsUseExperimentalArgument(context.trace.bindingContext) !element.isUsageAsOptInArgument(context.trace.bindingContext)
) { ) {
context.trace.report( context.trace.report(
Errors.OPT_IN_MARKER_CAN_ONLY_BE_USED_AS_ANNOTATION_OR_ARGUMENT_IN_OPT_IN.on(element) Errors.OPT_IN_MARKER_CAN_ONLY_BE_USED_AS_ANNOTATION_OR_ARGUMENT_IN_OPT_IN.on(element)
@@ -426,11 +426,11 @@ class ExperimentalUsageChecker(project: Project) : CallChecker {
} }
} }
private fun checkUsageOfKotlinExperimentalOrUseExperimental(element: PsiElement, context: CheckerContext) { private fun checkUsageOfKotlinExperimentalOrOptIn(element: PsiElement, context: CheckerContext) {
val useExperimentalFqNames = context.languageVersionSettings.getFlag(AnalysisFlags.optIn) val optInFqNames = context.languageVersionSettings.getFlag(AnalysisFlags.optIn)
if (!context.languageVersionSettings.supportsFeature(LanguageFeature.OptInRelease) && if (!context.languageVersionSettings.supportsFeature(LanguageFeature.OptInRelease) &&
REQUIRES_OPT_IN_FQ_NAME.asString() !in useExperimentalFqNames && REQUIRES_OPT_IN_FQ_NAME.asString() !in optInFqNames &&
OLD_EXPERIMENTAL_FQ_NAME.asString() !in useExperimentalFqNames OLD_EXPERIMENTAL_FQ_NAME.asString() !in optInFqNames
) { ) {
context.trace.report(Errors.OPT_IN_IS_NOT_ENABLED.on(element)) context.trace.report(Errors.OPT_IN_IS_NOT_ENABLED.on(element))
} }
@@ -451,7 +451,7 @@ class ExperimentalUsageChecker(project: Project) : CallChecker {
return false return false
} }
private fun PsiElement.isUsageAsUseExperimentalArgument(bindingContext: BindingContext): Boolean { private fun PsiElement.isUsageAsOptInArgument(bindingContext: BindingContext): Boolean {
val qualifier = (this as? KtSimpleNameExpression)?.getTopmostParentQualifiedExpressionForSelector() ?: this val qualifier = (this as? KtSimpleNameExpression)?.getTopmostParentQualifiedExpressionForSelector() ?: this
val parent = qualifier.parent val parent = qualifier.parent
@@ -460,7 +460,7 @@ class ExperimentalUsageChecker(project: Project) : CallChecker {
parent.parent.parent is KtValueArgumentList && parent.parent.parent is KtValueArgumentList &&
parent.parent.parent.parent.let { entry -> parent.parent.parent.parent.let { entry ->
entry is KtAnnotationEntry && bindingContext.get(BindingContext.ANNOTATION, entry)?.let { annotation -> entry is KtAnnotationEntry && bindingContext.get(BindingContext.ANNOTATION, entry)?.let { annotation ->
annotation.fqName in USE_EXPERIMENTAL_FQ_NAMES || annotation.fqName == WAS_EXPERIMENTAL_FQ_NAME annotation.fqName in OPT_IN_FQ_NAMES || annotation.fqName == WAS_EXPERIMENTAL_FQ_NAME
} == true } == true
} }
} }
@@ -22,6 +22,20 @@ object OptInNames {
val USE_EXPERIMENTAL_ANNOTATION_CLASS = Name.identifier("markerClass") val USE_EXPERIMENTAL_ANNOTATION_CLASS = Name.identifier("markerClass")
val WAS_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 REQUIRES_OPT_IN_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) val OPT_IN_FQ_NAMES = setOf(OLD_USE_EXPERIMENTAL_FQ_NAME, OPT_IN_FQ_NAME)
@Deprecated(
message = "EXPERIMENTAL_FQ_NAMES is deprecated, please use REQUIRES_OPT_IN_FQ_NAMES instead",
ReplaceWith("REQUIRES_OPT_IN_FQ_NAMES", imports = ["org.jetbrains.kotlin.resolve.checkers.OptInNames.REQUIRES_OPT_IN_FQ_NAMES"])
)
@Suppress("unused")
val EXPERIMENTAL_FQ_NAMES = REQUIRES_OPT_IN_FQ_NAMES
@Deprecated(
message = "USE_EXPERIMENTAL_FQ_NAMES is deprecated, please use OPT_IN_FQ_NAMES instead",
ReplaceWith("OPT_IN_FQ_NAMES", imports = ["org.jetbrains.kotlin.resolve.checkers.OptInNames.OPT_IN_FQ_NAMES"])
)
@Suppress("unused")
val USE_EXPERIMENTAL_FQ_NAMES = OPT_IN_FQ_NAMES
} }