diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationUtil.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationUtil.kt index f2bb40c799a..103e33a8190 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationUtil.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationUtil.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.resolve.constants.ConstantValue import org.jetbrains.kotlin.resolve.constants.ErrorValue val JVM_STATIC_ANNOTATION_FQ_NAME = FqName("kotlin.jvm.JvmStatic") @@ -43,6 +44,6 @@ private val STRICTFP_ANNOTATION_FQ_NAME = FqName("kotlin.jvm.Strictfp") fun DeclarationDescriptor.findStrictfpAnnotation() = DescriptorUtils.getAnnotationByFqName(annotations, STRICTFP_ANNOTATION_FQ_NAME) -fun AnnotationDescriptor.argumentValue(parameterName: String): Any? { - return allValueArguments[Name.identifier(parameterName)].takeUnless { it is ErrorValue }?.value +fun AnnotationDescriptor.argumentValue(parameterName: String): ConstantValue<*>? { + return allValueArguments[Name.identifier(parameterName)].takeUnless { it is ErrorValue } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/deprecationUtil.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/deprecationUtil.kt index eb15f5411b0..abd8d055222 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/deprecationUtil.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/deprecationUtil.kt @@ -33,6 +33,9 @@ import org.jetbrains.kotlin.resolve.DeprecationLevelValue.* import org.jetbrains.kotlin.resolve.annotations.argumentValue import org.jetbrains.kotlin.resolve.calls.checkers.isOperatorMod import org.jetbrains.kotlin.resolve.calls.checkers.shouldWarnAboutDeprecatedModFromBuiltIns +import org.jetbrains.kotlin.resolve.constants.AnnotationValue +import org.jetbrains.kotlin.resolve.constants.EnumValue +import org.jetbrains.kotlin.resolve.constants.StringValue import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor @@ -42,6 +45,7 @@ import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.utils.SmartList +import org.jetbrains.kotlin.utils.addToStdlib.safeAs private val JAVA_DEPRECATED = FqName("java.lang.Deprecated") @@ -55,27 +59,22 @@ fun Deprecation.deprecatedByOverriddenMessage(): String? = (this as? DeprecatedB fun Deprecation.deprecatedByAnnotationReplaceWithExpression(): String? { val annotation = (this as? DeprecatedByAnnotation)?.annotation ?: return null - val replaceWithAnnotation = annotation.argumentValue(kotlin.Deprecated::replaceWith.name) - as? AnnotationDescriptor ?: return null - - return replaceWithAnnotation.argumentValue(kotlin.ReplaceWith::expression.name) as String + val replaceWithAnnotation = + annotation.argumentValue(kotlin.Deprecated::replaceWith.name)?.safeAs()?.value ?: return null + return replaceWithAnnotation.argumentValue(kotlin.ReplaceWith::expression.name)?.safeAs()?.value } private data class DeprecatedByAnnotation(val annotation: AnnotationDescriptor, override val target: DeclarationDescriptor) : Deprecation { override val deprecationLevel: DeprecationLevelValue - get() { - val level = annotation.argumentValue("level") as? ClassDescriptor - - return when (level?.name?.asString()) { - "WARNING" -> WARNING - "ERROR" -> ERROR - "HIDDEN" -> HIDDEN - else -> WARNING - } + get() = when (annotation.argumentValue("level")?.safeAs()?.enumEntryName?.asString()) { + "WARNING" -> WARNING + "ERROR" -> ERROR + "HIDDEN" -> HIDDEN + else -> WARNING } override val message: String? - get() = annotation.argumentValue("message") as? String + get() = annotation.argumentValue("message")?.safeAs()?.value } private data class DeprecatedByOverridden(private val deprecations: Collection) : Deprecation { diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/AnnotationTypeQualifierResolver.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/AnnotationTypeQualifierResolver.kt index 04d32d21dc3..30c6ce18554 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/AnnotationTypeQualifierResolver.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/AnnotationTypeQualifierResolver.kt @@ -27,7 +27,7 @@ import org.jetbrains.kotlin.resolve.constants.ArrayValue import org.jetbrains.kotlin.resolve.constants.ConstantValue import org.jetbrains.kotlin.resolve.constants.EnumValue import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass -import org.jetbrains.kotlin.resolve.descriptorUtil.firstArgumentValue +import org.jetbrains.kotlin.resolve.descriptorUtil.firstArgument import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.utils.Jsr305State @@ -148,7 +148,7 @@ class AnnotationTypeQualifierResolver(storageManager: StorageManager, private va } private fun ClassDescriptor.migrationAnnotationStatus(): ReportLevel? { - val stateDescriptor = annotations.findAnnotation(MIGRATION_ANNOTATION_FQNAME)?.firstArgumentValue()?.safeAs() + val stateDescriptor = annotations.findAnnotation(MIGRATION_ANNOTATION_FQNAME)?.firstArgument()?.safeAs()?.value ?: return null jsr305State.migration?.let { return jsr305State.migration } diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/descriptors/util.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/descriptors/util.kt index 8b3907a84a8..a8b0cb2992e 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/descriptors/util.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/descriptors/util.kt @@ -24,7 +24,8 @@ import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl import org.jetbrains.kotlin.load.java.JvmAnnotationNames import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaStaticClassScope import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource -import org.jetbrains.kotlin.resolve.descriptorUtil.firstArgumentValue +import org.jetbrains.kotlin.resolve.constants.StringValue +import org.jetbrains.kotlin.resolve.descriptorUtil.firstArgument import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.jvm.JvmClassName @@ -78,7 +79,7 @@ fun DeserializedMemberDescriptor.isFromJvmPackagePart(): Boolean = fun ValueParameterDescriptor.getParameterNameAnnotation(): AnnotationDescriptor? { val annotation = annotations.findAnnotation(JvmAnnotationNames.PARAMETER_NAME_FQ_NAME) ?: return null - if (annotation.firstArgumentValue()?.safeAs()?.isEmpty() != false) { + if (annotation.firstArgument()?.safeAs()?.value?.isEmpty() != false) { return null } @@ -91,8 +92,8 @@ object NullDefaultValue : AnnotationDefaultValue() fun ValueParameterDescriptor.getDefaultValueFromAnnotation(): AnnotationDefaultValue? { annotations.findAnnotation(JvmAnnotationNames.DEFAULT_VALUE_FQ_NAME) - ?.firstArgumentValue() - ?.safeAs() + ?.firstArgument() + ?.safeAs()?.value ?.let { return StringDefaultValue(it) } if (annotations.hasAnnotation(JvmAnnotationNames.DEFAULT_NULL_FQ_NAME)) { diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaScope.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaScope.kt index d683e87b631..7b94d638c88 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaScope.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaScope.kt @@ -36,7 +36,8 @@ import org.jetbrains.kotlin.load.java.structure.JavaMethod import org.jetbrains.kotlin.load.java.structure.JavaValueParameter import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.DescriptorUtils -import org.jetbrains.kotlin.resolve.descriptorUtil.firstArgumentValue +import org.jetbrains.kotlin.resolve.constants.StringValue +import org.jetbrains.kotlin.resolve.descriptorUtil.firstArgument import org.jetbrains.kotlin.resolve.retainMostSpecificInEachOverridableGroup import org.jetbrains.kotlin.resolve.scopes.DescriptorKindExclude.NonExtensions import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter @@ -174,8 +175,8 @@ abstract class LazyJavaScope(protected val c: LazyJavaResolverContext) : MemberS val typeUsage = TypeUsage.COMMON.toAttributes() val parameterName = annotations .findAnnotation(JvmAnnotationNames.PARAMETER_NAME_FQ_NAME) - ?.firstArgumentValue() - ?.safeAs() + ?.firstArgument() + ?.safeAs()?.value val (outType, varargElementType) = if (javaParameter.isVararg) { diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/typeEnhancement/signatureEnhancement.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/typeEnhancement/signatureEnhancement.kt index 98aa35220f3..d5bcc376032 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/typeEnhancement/signatureEnhancement.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/typeEnhancement/signatureEnhancement.kt @@ -30,7 +30,8 @@ import org.jetbrains.kotlin.load.kotlin.SignatureBuildingComponents import org.jetbrains.kotlin.load.kotlin.computeJvmDescriptor import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.platform.JavaToKotlinClassMap -import org.jetbrains.kotlin.resolve.descriptorUtil.firstArgumentValue +import org.jetbrains.kotlin.resolve.constants.EnumValue +import org.jetbrains.kotlin.resolve.descriptorUtil.firstArgument import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.checker.KotlinTypeChecker import org.jetbrains.kotlin.types.typeUtil.isTypeParameter @@ -49,12 +50,10 @@ class SignatureEnhancement( ) { private fun AnnotationDescriptor.extractNullabilityTypeFromArgument(): NullabilityQualifierWithMigrationStatus? { - val enumEntryDescriptor = firstArgumentValue() + val enumEntryDescriptor = firstArgument().safeAs()?.value // if no argument is specified, use default value: NOT_NULL ?: return NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL) - if (enumEntryDescriptor !is ClassDescriptor) return null - return when (enumEntryDescriptor.name.asString()) { "ALWAYS" -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL) "MAYBE", "NEVER" -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NULLABLE) diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.kt index f5366fb3e92..412710122b5 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.kt @@ -30,6 +30,7 @@ import org.jetbrains.kotlin.name.FqNameUnsafe import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils.getContainingClass +import org.jetbrains.kotlin.resolve.constants.ConstantValue import org.jetbrains.kotlin.resolve.constants.EnumValue import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.MemberScope @@ -416,7 +417,7 @@ fun ClassDescriptor.isSubclassOf(superclass: ClassDescriptor): Boolean = Descrip val AnnotationDescriptor.annotationClass: ClassDescriptor? get() = type.constructor.declarationDescriptor as? ClassDescriptor -fun AnnotationDescriptor.firstArgumentValue() = allValueArguments.values.firstOrNull()?.value +fun AnnotationDescriptor.firstArgument(): ConstantValue<*>? = allValueArguments.values.firstOrNull() fun MemberDescriptor.isEffectivelyExternal(): Boolean { if (isExternal) return true diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/injection/KotlinLanguageInjector.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/injection/KotlinLanguageInjector.kt index d7c430e51d8..ad5793a51a4 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/injection/KotlinLanguageInjector.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/injection/KotlinLanguageInjector.kt @@ -54,10 +54,12 @@ import org.jetbrains.kotlin.idea.util.ProjectRootsUtil import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.annotations.argumentValue +import org.jetbrains.kotlin.resolve.constants.StringValue import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.util.aliasImportMap import org.jetbrains.kotlin.utils.SmartList import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull +import org.jetbrains.kotlin.utils.addToStdlib.safeAs class KotlinLanguageInjector( private val configuration: Configuration, @@ -334,7 +336,7 @@ class KotlinLanguageInjector( val parameterDescriptor = functionDescriptor.valueParameters.getOrNull(argumentIndex) ?: return null val injectAnnotation = parameterDescriptor.annotations.findAnnotation(FqName(AnnotationUtil.LANGUAGE)) ?: return null - val languageId = injectAnnotation.argumentValue("value") as? String ?: return null + val languageId = injectAnnotation.argumentValue("value")?.safeAs()?.value ?: return null return InjectionInfo(languageId, null, null) } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/DeprecatedSymbolUsageFixBase.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/DeprecatedSymbolUsageFixBase.kt index d312b484554..60508a68448 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/DeprecatedSymbolUsageFixBase.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/DeprecatedSymbolUsageFixBase.kt @@ -24,7 +24,6 @@ import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.searches.ReferencesSearch import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.DiagnosticFactory @@ -45,10 +44,13 @@ import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.resolve.annotations.argumentValue import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess +import org.jetbrains.kotlin.resolve.constants.AnnotationValue +import org.jetbrains.kotlin.resolve.constants.ArrayValue import org.jetbrains.kotlin.resolve.constants.StringValue import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.util.constructors +import org.jetbrains.kotlin.utils.addToStdlib.safeAs //TODO: different replacements for property accessors @@ -77,10 +79,11 @@ abstract class DeprecatedSymbolUsageFixBase( companion object { fun fetchReplaceWithPattern(descriptor: DeclarationDescriptor, project: Project): ReplaceWith? { val annotation = descriptor.annotations.findAnnotation(KotlinBuiltIns.FQ_NAMES.deprecated) ?: return null - val replaceWithValue = annotation.argumentValue(kotlin.Deprecated::replaceWith.name) as? AnnotationDescriptor ?: return null - val pattern = replaceWithValue.argumentValue(kotlin.ReplaceWith::expression.name) as? String ?: return null + val replaceWithValue = + annotation.argumentValue(kotlin.Deprecated::replaceWith.name)?.safeAs()?.value ?: return null + val pattern = replaceWithValue.argumentValue(kotlin.ReplaceWith::expression.name)?.safeAs()?.value ?: return null if (pattern.isEmpty()) return null - val importValues = replaceWithValue.argumentValue(kotlin.ReplaceWith::imports.name) as? List<*> ?: return null + val importValues = replaceWithValue.argumentValue(kotlin.ReplaceWith::imports.name)?.safeAs()?.value ?: return null if (importValues.any { it !is StringValue }) return null val imports = importValues.map { (it as StringValue).value }