Use AnnotationDescriptor.fqName instead of type
Also use the annotationClass extension property instead of TypeUtils.getClassDescriptor(annotation.type)
This commit is contained in:
+7
-6
@@ -21,28 +21,29 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
|||||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinRetention
|
import org.jetbrains.kotlin.descriptors.annotations.KotlinRetention
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
||||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
||||||
import org.jetbrains.kotlin.resolve.AdditionalAnnotationChecker
|
import org.jetbrains.kotlin.resolve.AdditionalAnnotationChecker
|
||||||
import org.jetbrains.kotlin.resolve.AnnotationChecker
|
import org.jetbrains.kotlin.resolve.AnnotationChecker
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getAnnotationRetention
|
import org.jetbrains.kotlin.resolve.descriptorUtil.getAnnotationRetention
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isRepeatableAnnotation
|
import org.jetbrains.kotlin.resolve.descriptorUtil.isRepeatableAnnotation
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
|
||||||
|
|
||||||
object RepeatableAnnotationChecker: AdditionalAnnotationChecker {
|
object RepeatableAnnotationChecker: AdditionalAnnotationChecker {
|
||||||
override fun checkEntries(entries: List<KtAnnotationEntry>, actualTargets: List<KotlinTarget>, trace: BindingTrace) {
|
override fun checkEntries(entries: List<KtAnnotationEntry>, actualTargets: List<KotlinTarget>, trace: BindingTrace) {
|
||||||
val entryTypesWithAnnotations = hashMapOf<KotlinType, MutableList<AnnotationUseSiteTarget?>>()
|
val entryTypesWithAnnotations = hashMapOf<FqName, MutableList<AnnotationUseSiteTarget?>>()
|
||||||
|
|
||||||
for (entry in entries) {
|
for (entry in entries) {
|
||||||
val descriptor = trace.get(BindingContext.ANNOTATION, entry) ?: continue
|
val descriptor = trace.get(BindingContext.ANNOTATION, entry) ?: continue
|
||||||
val classDescriptor = TypeUtils.getClassDescriptor(descriptor.type) ?: continue
|
val fqName = descriptor.fqName ?: continue
|
||||||
|
val classDescriptor = descriptor.annotationClass ?: continue
|
||||||
|
|
||||||
val useSiteTarget = entry.useSiteTarget?.getAnnotationUseSiteTarget()
|
val useSiteTarget = entry.useSiteTarget?.getAnnotationUseSiteTarget()
|
||||||
val existingTargetsForAnnotation = entryTypesWithAnnotations.getOrPut(descriptor.type) { arrayListOf() }
|
val existingTargetsForAnnotation = entryTypesWithAnnotations.getOrPut(fqName) { arrayListOf() }
|
||||||
val duplicateAnnotation = useSiteTarget in existingTargetsForAnnotation
|
val duplicateAnnotation = useSiteTarget in existingTargetsForAnnotation
|
||||||
|| (existingTargetsForAnnotation.any { (it == null) != (useSiteTarget == null) })
|
|| (existingTargetsForAnnotation.any { (it == null) != (useSiteTarget == null) })
|
||||||
|
|
||||||
@@ -66,7 +67,7 @@ object FileClassAnnotationsChecker: AdditionalAnnotationChecker {
|
|||||||
for (entry in entries) {
|
for (entry in entries) {
|
||||||
if (entry.useSiteTarget?.getAnnotationUseSiteTarget() != AnnotationUseSiteTarget.FILE) continue
|
if (entry.useSiteTarget?.getAnnotationUseSiteTarget() != AnnotationUseSiteTarget.FILE) continue
|
||||||
val descriptor = trace.get(BindingContext.ANNOTATION, entry) ?: continue
|
val descriptor = trace.get(BindingContext.ANNOTATION, entry) ?: continue
|
||||||
val classDescriptor = TypeUtils.getClassDescriptor(descriptor.type) ?: continue
|
val classDescriptor = descriptor.annotationClass ?: continue
|
||||||
// This check matters for the applicable annotations only.
|
// This check matters for the applicable annotations only.
|
||||||
val applicableTargets = AnnotationChecker.applicableTargetSet(classDescriptor)
|
val applicableTargets = AnnotationChecker.applicableTargetSet(classDescriptor)
|
||||||
if (applicableTargets == null || !applicableTargets.contains(KotlinTarget.FILE)) continue
|
if (applicableTargets == null || !applicableTargets.contains(KotlinTarget.FILE)) continue
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.getAnnotationRetention
|
|||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isRepeatableAnnotation
|
import org.jetbrains.kotlin.resolve.descriptorUtil.isRepeatableAnnotation
|
||||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
|
||||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
|
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
|
||||||
import org.jetbrains.kotlin.types.isError
|
import org.jetbrains.kotlin.types.isError
|
||||||
|
|
||||||
@@ -107,7 +106,7 @@ class AnnotationChecker(private val additionalCheckers: Iterable<AdditionalAnnot
|
|||||||
for (entry in entries) {
|
for (entry in entries) {
|
||||||
checkAnnotationEntry(entry, actualTargets, trace)
|
checkAnnotationEntry(entry, actualTargets, trace)
|
||||||
val descriptor = trace.get(BindingContext.ANNOTATION, entry) ?: continue
|
val descriptor = trace.get(BindingContext.ANNOTATION, entry) ?: continue
|
||||||
val classDescriptor = TypeUtils.getClassDescriptor(descriptor.type) ?: continue
|
val classDescriptor = descriptor.annotationClass ?: continue
|
||||||
|
|
||||||
val useSiteTarget = entry.useSiteTarget?.getAnnotationUseSiteTarget() ?: annotated.getDefaultUseSiteTarget(descriptor)
|
val useSiteTarget = entry.useSiteTarget?.getAnnotationUseSiteTarget() ?: annotated.getDefaultUseSiteTarget(descriptor)
|
||||||
val existingTargetsForAnnotation = entryTypesWithAnnotations.getOrPut(descriptor.type) { arrayListOf() }
|
val existingTargetsForAnnotation = entryTypesWithAnnotations.getOrPut(descriptor.type) { arrayListOf() }
|
||||||
@@ -169,8 +168,7 @@ class AnnotationChecker(private val additionalCheckers: Iterable<AdditionalAnnot
|
|||||||
val descriptor = trace.get(BindingContext.ANNOTATION, entry) ?: return KotlinTarget.DEFAULT_TARGET_SET
|
val descriptor = trace.get(BindingContext.ANNOTATION, entry) ?: return KotlinTarget.DEFAULT_TARGET_SET
|
||||||
// For descriptor with error type, all targets are considered as possible
|
// For descriptor with error type, all targets are considered as possible
|
||||||
if (descriptor.type.isError) return KotlinTarget.ALL_TARGET_SET
|
if (descriptor.type.isError) return KotlinTarget.ALL_TARGET_SET
|
||||||
val classDescriptor = TypeUtils.getClassDescriptor(descriptor.type) ?: return KotlinTarget.DEFAULT_TARGET_SET
|
return descriptor.annotationClass?.let(this::applicableTargetSet) ?: KotlinTarget.DEFAULT_TARGET_SET
|
||||||
return applicableTargetSet(classDescriptor) ?: KotlinTarget.DEFAULT_TARGET_SET
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic fun applicableTargetSet(descriptor: AnnotationDescriptor): Set<KotlinTarget> {
|
@JvmStatic fun applicableTargetSet(descriptor: AnnotationDescriptor): Set<KotlinTarget> {
|
||||||
|
|||||||
@@ -142,10 +142,10 @@ class TypeAliasExpander(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun checkRepeatedAnnotations(existingAnnotations: Annotations, newAnnotations: Annotations) {
|
private fun checkRepeatedAnnotations(existingAnnotations: Annotations, newAnnotations: Annotations) {
|
||||||
val existingAnnotationTypes = existingAnnotations.mapTo(hashSetOf()) { it.type }
|
val existingAnnotationFqNames = existingAnnotations.mapTo(hashSetOf()) { it.fqName }
|
||||||
|
|
||||||
for (annotation in newAnnotations) {
|
for (annotation in newAnnotations) {
|
||||||
if (annotation.type in existingAnnotationTypes) {
|
if (annotation.fqName in existingAnnotationFqNames) {
|
||||||
reportStrategy.repeatedAnnotation(annotation)
|
reportStrategy.repeatedAnnotation(annotation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-8
@@ -25,27 +25,22 @@ import org.jetbrains.kotlin.diagnostics.Errors
|
|||||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
|
||||||
|
|
||||||
object PublishedApiUsageChecker {
|
object PublishedApiUsageChecker {
|
||||||
|
|
||||||
fun check(
|
fun check(
|
||||||
declaration: KtDeclaration,
|
declaration: KtDeclaration,
|
||||||
descriptor: DeclarationDescriptor,
|
descriptor: DeclarationDescriptor,
|
||||||
trace: BindingTrace
|
trace: BindingTrace
|
||||||
) {
|
) {
|
||||||
if (descriptor !is DeclarationDescriptorWithVisibility || descriptor.visibility == Visibilities.INTERNAL) return
|
if (descriptor !is DeclarationDescriptorWithVisibility || descriptor.visibility == Visibilities.INTERNAL) return
|
||||||
/*Don't report diagnostic twise*/
|
// Don't report the diagnostic twice
|
||||||
if (descriptor is PropertyAccessorDescriptor) return
|
if (descriptor is PropertyAccessorDescriptor) return
|
||||||
|
|
||||||
for (entry in declaration.annotationEntries) {
|
for (entry in declaration.annotationEntries) {
|
||||||
val annotationDescriptor = trace.get(BindingContext.ANNOTATION, entry) ?: continue
|
val annotationDescriptor = trace.get(BindingContext.ANNOTATION, entry) ?: continue
|
||||||
val classDescriptor = TypeUtils.getClassDescriptor(annotationDescriptor.type) ?: continue
|
if (annotationDescriptor.fqName == KotlinBuiltIns.FQ_NAMES.publishedApi) {
|
||||||
if (classDescriptor.fqNameSafe == KotlinBuiltIns.FQ_NAMES.publishedApi) {
|
|
||||||
trace.report(Errors.NON_INTERNAL_PUBLISHED_API.on(entry))
|
trace.report(Errors.NON_INTERNAL_PUBLISHED_API.on(entry))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -171,7 +171,7 @@ abstract class KotlinSuppressCache {
|
|||||||
builder.addAll(suppressStringProvider[annotationDescriptor])
|
builder.addAll(suppressStringProvider[annotationDescriptor])
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!KotlinBuiltIns.isSuppressAnnotation(annotationDescriptor)) return
|
if (annotationDescriptor.fqName != KotlinBuiltIns.FQ_NAMES.suppress) return
|
||||||
|
|
||||||
// We only add strings and skip other values to facilitate recovery in presence of erroneous code
|
// We only add strings and skip other values to facilitate recovery in presence of erroneous code
|
||||||
for (arrayValue in annotationDescriptor.allValueArguments.values) {
|
for (arrayValue in annotationDescriptor.allValueArguments.values) {
|
||||||
|
|||||||
+5
-15
@@ -16,17 +16,12 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve.diagnostics
|
package org.jetbrains.kotlin.resolve.diagnostics
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors
|
import org.jetbrains.kotlin.diagnostics.*
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
|
||||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.psi.KtFunction
|
import org.jetbrains.kotlin.psi.KtFunction
|
||||||
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory1
|
|
||||||
import org.jetbrains.kotlin.psi.KtProperty
|
import org.jetbrains.kotlin.psi.KtProperty
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory0
|
|
||||||
|
|
||||||
val FUNCTION_NO_BODY_ERRORS: List<DiagnosticFactory1<KtFunction, SimpleFunctionDescriptor>> =
|
val FUNCTION_NO_BODY_ERRORS: List<DiagnosticFactory1<KtFunction, SimpleFunctionDescriptor>> =
|
||||||
listOf(Errors.NON_ABSTRACT_FUNCTION_WITH_NO_BODY, Errors.NON_MEMBER_FUNCTION_NO_BODY)
|
listOf(Errors.NON_ABSTRACT_FUNCTION_WITH_NO_BODY, Errors.NON_MEMBER_FUNCTION_NO_BODY)
|
||||||
@@ -36,18 +31,13 @@ val PROPERTY_NOT_INITIALIZED_ERRORS: List<DiagnosticFactory0<KtProperty>> =
|
|||||||
|
|
||||||
abstract class SuppressDiagnosticsByAnnotations(
|
abstract class SuppressDiagnosticsByAnnotations(
|
||||||
diagnosticsToSuppress: List<DiagnosticFactory<out Diagnostic>>,
|
diagnosticsToSuppress: List<DiagnosticFactory<out Diagnostic>>,
|
||||||
vararg annotationsFqName: FqName
|
vararg annotationFqNames: FqName
|
||||||
) : SuppressStringProvider {
|
) : SuppressStringProvider {
|
||||||
|
|
||||||
private val stringsToSuppress = diagnosticsToSuppress.map { it.name.toLowerCase() }
|
private val stringsToSuppress = diagnosticsToSuppress.map { it.name.toLowerCase() }
|
||||||
private val expectedFqNames = annotationsFqName.map(FqName::toString)
|
private val expectedFqNames = annotationFqNames.toSet()
|
||||||
|
|
||||||
override fun get(annotationDescriptor: AnnotationDescriptor): List<String> {
|
override fun get(annotationDescriptor: AnnotationDescriptor): List<String> {
|
||||||
val descriptor = DescriptorUtils.getClassDescriptorForType(annotationDescriptor.type)
|
return if (annotationDescriptor.fqName in expectedFqNames) stringsToSuppress else emptyList()
|
||||||
val actualFqName = DescriptorUtils.getFqName(descriptor).asString()
|
|
||||||
|
|
||||||
if (expectedFqNames.any { it == actualFqName }) return stringsToSuppress
|
|
||||||
|
|
||||||
return listOf()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-18
@@ -23,7 +23,10 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
|||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
||||||
import org.jetbrains.kotlin.resolve.*
|
import org.jetbrains.kotlin.resolve.AnnotationResolver
|
||||||
|
import org.jetbrains.kotlin.resolve.AnnotationResolverImpl
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
||||||
import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil
|
import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil
|
||||||
import org.jetbrains.kotlin.resolve.lazy.LazyEntity
|
import org.jetbrains.kotlin.resolve.lazy.LazyEntity
|
||||||
@@ -31,7 +34,6 @@ import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
|||||||
import org.jetbrains.kotlin.resolve.source.toSourceElement
|
import org.jetbrains.kotlin.resolve.source.toSourceElement
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
import org.jetbrains.kotlin.storage.getValue
|
import org.jetbrains.kotlin.storage.getValue
|
||||||
import org.jetbrains.kotlin.types.isError
|
|
||||||
|
|
||||||
abstract class LazyAnnotationsContext(
|
abstract class LazyAnnotationsContext(
|
||||||
val annotationResolver: AnnotationResolver,
|
val annotationResolver: AnnotationResolver,
|
||||||
@@ -62,22 +64,7 @@ class LazyAnnotations(
|
|||||||
AnnotationWithTarget(descriptor, target)
|
AnnotationWithTarget(descriptor, target)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun findAnnotation(fqName: FqName): AnnotationDescriptor? {
|
override fun findAnnotation(fqName: FqName): AnnotationDescriptor? = firstOrNull { it.fqName == fqName }
|
||||||
// We can not efficiently check short names here:
|
|
||||||
// an annotation class may be renamed on import
|
|
||||||
for (annotationDescriptor in iterator()) {
|
|
||||||
val annotationType = annotationDescriptor.type
|
|
||||||
if (annotationType.isError) continue
|
|
||||||
|
|
||||||
val descriptor = annotationType.constructor.declarationDescriptor ?: continue
|
|
||||||
|
|
||||||
if (DescriptorUtils.getFqNameSafe(descriptor) == fqName) {
|
|
||||||
return annotationDescriptor
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getUseSiteTargetedAnnotations(): List<AnnotationWithTarget> {
|
override fun getUseSiteTargetedAnnotations(): List<AnnotationWithTarget> {
|
||||||
return annotationEntries
|
return annotationEntries
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
|||||||
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageFragment
|
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageFragment
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
|
||||||
import org.jetbrains.kotlin.resolve.lazy.JvmResolveUtil
|
import org.jetbrains.kotlin.resolve.lazy.JvmResolveUtil
|
||||||
import org.jetbrains.kotlin.test.ConfigurationKind
|
import org.jetbrains.kotlin.test.ConfigurationKind
|
||||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||||
@@ -75,9 +74,7 @@ class LoadJavaPackageAnnotationsTest : KtUsefulTestCase() {
|
|||||||
val singleAnnotation = packageFragmentDescriptor.annotations.singleOrNull()
|
val singleAnnotation = packageFragmentDescriptor.annotations.singleOrNull()
|
||||||
assertNotNull(singleAnnotation)
|
assertNotNull(singleAnnotation)
|
||||||
|
|
||||||
val annotationFqName = singleAnnotation!!.type.constructor.declarationDescriptor?.fqNameSafe
|
assertEquals(FqName("test.Ann"), singleAnnotation!!.fqName)
|
||||||
|
|
||||||
assertEquals(FqName("test.Ann"), annotationFqName)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun testAnnotationFromSource() {
|
fun testAnnotationFromSource() {
|
||||||
|
|||||||
@@ -24,7 +24,10 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import org.jetbrains.kotlin.builtins.functions.BuiltInFictitiousFunctionClassFactory;
|
import org.jetbrains.kotlin.builtins.functions.BuiltInFictitiousFunctionClassFactory;
|
||||||
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor;
|
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor;
|
||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.*;
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget;
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.KotlinRetention;
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget;
|
||||||
import org.jetbrains.kotlin.descriptors.deserialization.AdditionalClassPartsProvider;
|
import org.jetbrains.kotlin.descriptors.deserialization.AdditionalClassPartsProvider;
|
||||||
import org.jetbrains.kotlin.descriptors.deserialization.ClassDescriptorFactory;
|
import org.jetbrains.kotlin.descriptors.deserialization.ClassDescriptorFactory;
|
||||||
import org.jetbrains.kotlin.descriptors.deserialization.PlatformDependentDeclarationFilter;
|
import org.jetbrains.kotlin.descriptors.deserialization.PlatformDependentDeclarationFilter;
|
||||||
@@ -254,7 +257,7 @@ public abstract class KotlinBuiltIns {
|
|||||||
public final FqNameUnsafe any = fqNameUnsafe("Any");
|
public final FqNameUnsafe any = fqNameUnsafe("Any");
|
||||||
public final FqNameUnsafe nothing = fqNameUnsafe("Nothing");
|
public final FqNameUnsafe nothing = fqNameUnsafe("Nothing");
|
||||||
public final FqNameUnsafe cloneable = fqNameUnsafe("Cloneable");
|
public final FqNameUnsafe cloneable = fqNameUnsafe("Cloneable");
|
||||||
public final FqNameUnsafe suppress = fqNameUnsafe("Suppress");
|
public final FqName suppress = fqName("Suppress");
|
||||||
public final FqNameUnsafe unit = fqNameUnsafe("Unit");
|
public final FqNameUnsafe unit = fqNameUnsafe("Unit");
|
||||||
public final FqNameUnsafe charSequence = fqNameUnsafe("CharSequence");
|
public final FqNameUnsafe charSequence = fqNameUnsafe("CharSequence");
|
||||||
public final FqNameUnsafe string = fqNameUnsafe("String");
|
public final FqNameUnsafe string = fqNameUnsafe("String");
|
||||||
@@ -1095,10 +1098,6 @@ public abstract class KotlinBuiltIns {
|
|||||||
return BUILT_INS_PACKAGE_FQ_NAME.child(primitiveType.getTypeName());
|
return BUILT_INS_PACKAGE_FQ_NAME.child(primitiveType.getTypeName());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isSuppressAnnotation(@NotNull AnnotationDescriptor annotationDescriptor) {
|
|
||||||
return isConstructedFromGivenClass(annotationDescriptor.getType(), FQ_NAMES.suppress);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean containsAnnotation(DeclarationDescriptor descriptor, FqName annotationClassFqName) {
|
private static boolean containsAnnotation(DeclarationDescriptor descriptor, FqName annotationClassFqName) {
|
||||||
DeclarationDescriptor original = descriptor.getOriginal();
|
DeclarationDescriptor original = descriptor.getOriginal();
|
||||||
Annotations annotations = original.getAnnotations();
|
Annotations annotations = original.getAnnotations();
|
||||||
|
|||||||
+4
-4
@@ -16,21 +16,21 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.descriptors.annotations
|
package org.jetbrains.kotlin.descriptors.annotations
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.SourceElement
|
import org.jetbrains.kotlin.descriptors.SourceElement
|
||||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
||||||
|
import org.jetbrains.kotlin.types.ErrorUtils
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
interface AnnotationDescriptor {
|
interface AnnotationDescriptor {
|
||||||
val type: KotlinType
|
val type: KotlinType
|
||||||
|
|
||||||
val fqName: FqName? get() =
|
val fqName: FqName?
|
||||||
(type.constructor.declarationDescriptor as? ClassDescriptor)?.fqNameUnsafe?.takeIf(FqNameUnsafe::isSafe)?.toSafe()
|
get() = annotationClass?.takeUnless(ErrorUtils::isError)?.fqNameUnsafe?.takeIf(FqNameUnsafe::isSafe)?.toSafe()
|
||||||
|
|
||||||
val allValueArguments: Map<Name, ConstantValue<*>>
|
val allValueArguments: Map<Name, ConstantValue<*>>
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.resolve.constants.AnnotationValue
|
|||||||
import org.jetbrains.kotlin.resolve.constants.ArrayValue
|
import org.jetbrains.kotlin.resolve.constants.ArrayValue
|
||||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
||||||
import org.jetbrains.kotlin.resolve.constants.KClassValue
|
import org.jetbrains.kotlin.resolve.constants.KClassValue
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue
|
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
import org.jetbrains.kotlin.types.ErrorUtils.UninferredParameterTypeConstructor
|
import org.jetbrains.kotlin.types.ErrorUtils.UninferredParameterTypeConstructor
|
||||||
@@ -428,7 +429,7 @@ internal class DescriptorRendererImpl(
|
|||||||
|
|
||||||
private fun renderAndSortAnnotationArguments(descriptor: AnnotationDescriptor): List<String> {
|
private fun renderAndSortAnnotationArguments(descriptor: AnnotationDescriptor): List<String> {
|
||||||
val allValueArguments = descriptor.allValueArguments
|
val allValueArguments = descriptor.allValueArguments
|
||||||
val classDescriptor = if (renderDefaultAnnotationArguments) TypeUtils.getClassDescriptor(descriptor.type) else null
|
val classDescriptor = if (renderDefaultAnnotationArguments) descriptor.annotationClass else null
|
||||||
val parameterDescriptorsWithDefaultValue = classDescriptor?.unsubstitutedPrimaryConstructor?.valueParameters
|
val parameterDescriptorsWithDefaultValue = classDescriptor?.unsubstitutedPrimaryConstructor?.valueParameters
|
||||||
?.filter { it.declaresDefaultValue() }
|
?.filter { it.declaresDefaultValue() }
|
||||||
?.map { it.name }
|
?.map { it.name }
|
||||||
|
|||||||
+3
-7
@@ -53,7 +53,7 @@ class KotlinSuppressIntentionAction private constructor(
|
|||||||
val id = "\"$suppressKey\""
|
val id = "\"$suppressKey\""
|
||||||
when (suppressAt) {
|
when (suppressAt) {
|
||||||
is KtModifierListOwner ->
|
is KtModifierListOwner ->
|
||||||
suppressAt.addAnnotation(KotlinBuiltIns.FQ_NAMES.suppress.toSafe(),
|
suppressAt.addAnnotation(KotlinBuiltIns.FQ_NAMES.suppress,
|
||||||
id,
|
id,
|
||||||
whiteSpaceText = if (kind.newLineNeeded) "\n" else " ",
|
whiteSpaceText = if (kind.newLineNeeded) "\n" else " ",
|
||||||
addToExistingAnnotation = { entry ->
|
addToExistingAnnotation = { entry ->
|
||||||
@@ -151,13 +151,9 @@ class KotlinSuppressIntentionAction private constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun findSuppressAnnotation(context: BindingContext, annotationEntries: List<KtAnnotationEntry>): KtAnnotationEntry? {
|
private fun findSuppressAnnotation(context: BindingContext, annotationEntries: List<KtAnnotationEntry>): KtAnnotationEntry? {
|
||||||
for (entry in annotationEntries) {
|
return annotationEntries.firstOrNull { entry ->
|
||||||
val annotationDescriptor = context.get(BindingContext.ANNOTATION, entry)
|
context.get(BindingContext.ANNOTATION, entry)?.fqName == KotlinBuiltIns.FQ_NAMES.suppress
|
||||||
if (annotationDescriptor != null && KotlinBuiltIns.isSuppressAnnotation(annotationDescriptor)) {
|
|
||||||
return entry
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,13 +18,11 @@ package org.jetbrains.kotlin.idea.util
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
import org.jetbrains.kotlin.idea.core.ShortenReferences
|
import org.jetbrains.kotlin.idea.core.ShortenReferences
|
||||||
import org.jetbrains.kotlin.js.descriptorUtils.getJetTypeFqName
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
|
|
||||||
|
|
||||||
fun KtModifierListOwner.addAnnotation(
|
fun KtModifierListOwner.addAnnotation(
|
||||||
annotationFqName: FqName,
|
annotationFqName: FqName,
|
||||||
annotationInnerText: String? = null,
|
annotationInnerText: String? = null,
|
||||||
@@ -75,16 +73,5 @@ fun KtAnnotated.findAnnotation(annotationFqName: FqName): KtAnnotationEntry? {
|
|||||||
|
|
||||||
val context = analyze(bodyResolveMode = BodyResolveMode.PARTIAL)
|
val context = analyze(bodyResolveMode = BodyResolveMode.PARTIAL)
|
||||||
|
|
||||||
for (entry in annotationEntries) {
|
return annotationEntries.firstOrNull { entry -> context.get(BindingContext.ANNOTATION, entry)?.fqName == annotationFqName }
|
||||||
val annotationDescriptor = context.get(BindingContext.ANNOTATION, entry)
|
|
||||||
if (annotationDescriptor != null) {
|
|
||||||
val fqName = annotationDescriptor.type.getJetTypeFqName(false)
|
|
||||||
if (fqName == annotationFqName.asString()) {
|
|
||||||
return entry
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -118,10 +118,9 @@ class KtParameterPattern : PsiElementPattern<KtParameter, KtParameterPattern>(Kt
|
|||||||
return withPatternCondition("KtParameterPattern-withAnnotation") { ktParameter, _ ->
|
return withPatternCondition("KtParameterPattern-withAnnotation") { ktParameter, _ ->
|
||||||
if (ktParameter.annotationEntries.isEmpty()) return@withPatternCondition false
|
if (ktParameter.annotationEntries.isEmpty()) return@withPatternCondition false
|
||||||
|
|
||||||
val parameterDescriptor = ktParameter.resolveToDescriptorIfAny() as? ValueParameterDescriptor ?: return@withPatternCondition false
|
val parameterDescriptor = ktParameter.resolveToDescriptorIfAny()
|
||||||
|
parameterDescriptor is ValueParameterDescriptor && parameterDescriptor.annotations.any { annotation ->
|
||||||
parameterDescriptor.annotations.any { annotation ->
|
annotation.fqName?.asString() == fqName
|
||||||
DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(annotation.type) == fqName
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -204,7 +204,7 @@ class MigrateExternalExtensionFix(declaration: KtNamedDeclaration)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (declaration is KtFunction) {
|
if (declaration is KtFunction) {
|
||||||
declaration.addAnnotation(KotlinBuiltIns.FQ_NAMES.suppress.toSafe(), "\"NOTHING_TO_INLINE\"")
|
declaration.addAnnotation(KotlinBuiltIns.FQ_NAMES.suppress, "\"NOTHING_TO_INLINE\"")
|
||||||
}
|
}
|
||||||
|
|
||||||
convertNativeAnnotationToJsName(declaration, annotations)
|
convertNativeAnnotationToJsName(declaration, annotations)
|
||||||
|
|||||||
+3
-5
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.psi.KtDeclaration
|
|||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.checkers.SimpleDeclarationChecker
|
import org.jetbrains.kotlin.resolve.checkers.SimpleDeclarationChecker
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
|
||||||
|
|
||||||
object JsExternalFileChecker : SimpleDeclarationChecker {
|
object JsExternalFileChecker : SimpleDeclarationChecker {
|
||||||
private val annotationFqNames = setOf(AnnotationsUtils.JS_MODULE_ANNOTATION, AnnotationsUtils.JS_QUALIFIER_ANNOTATION)
|
private val annotationFqNames = setOf(AnnotationsUtils.JS_MODULE_ANNOTATION, AnnotationsUtils.JS_QUALIFIER_ANNOTATION)
|
||||||
@@ -36,11 +35,10 @@ object JsExternalFileChecker : SimpleDeclarationChecker {
|
|||||||
) {
|
) {
|
||||||
if (!AnnotationsUtils.isNativeObject(descriptor) && DescriptorUtils.isTopLevelDeclaration(descriptor)) {
|
if (!AnnotationsUtils.isNativeObject(descriptor) && DescriptorUtils.isTopLevelDeclaration(descriptor)) {
|
||||||
AnnotationsUtils.getContainingFileAnnotations(bindingContext, descriptor).asSequence()
|
AnnotationsUtils.getContainingFileAnnotations(bindingContext, descriptor).asSequence()
|
||||||
.map { it.type }
|
.firstOrNull { it.fqName in annotationFqNames }
|
||||||
.firstOrNull { it.constructor.declarationDescriptor?.fqNameSafe in annotationFqNames }
|
|
||||||
?.let {
|
?.let {
|
||||||
diagnosticHolder.report(ErrorsJs.NON_EXTERNAL_DECLARATION_IN_INAPPROPRIATE_FILE.on(declaration, it))
|
diagnosticHolder.report(ErrorsJs.NON_EXTERNAL_DECLARATION_IN_INAPPROPRIATE_FILE.on(declaration, it.type))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user