From eaa36d4d275259f513550453f839ed84b0589e8b Mon Sep 17 00:00:00 2001 From: Igor Yakovlev Date: Tue, 28 May 2019 20:45:23 +0300 Subject: [PATCH] Fix kotlin.Deprecated annotation for UL-classes --- .../KtLightClassForSourceDeclaration.kt | 44 ++------------ .../kotlin/asJava/classes/ultraLightClass.kt | 4 ++ .../asJava/classes/ultraLightMethods.kt | 4 ++ .../kotlin/asJava/classes/ultraLightUtils.kt | 59 +++++++++++++++---- 4 files changed, 60 insertions(+), 51 deletions(-) diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLightClassForSourceDeclaration.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLightClassForSourceDeclaration.kt index 0455e287cad..1c2e98458ee 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLightClassForSourceDeclaration.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLightClassForSourceDeclaration.kt @@ -5,7 +5,6 @@ package org.jetbrains.kotlin.asJava.classes -import com.google.common.collect.Lists import com.intellij.openapi.components.ServiceManager import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.project.Project @@ -28,7 +27,6 @@ import com.intellij.psi.util.CachedValuesManager import com.intellij.psi.util.PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT import com.intellij.psi.util.PsiUtilCore import com.intellij.util.IncorrectOperationException -import com.intellij.util.containers.ContainerUtil import org.jetbrains.annotations.NonNls import org.jetbrains.kotlin.asJava.ImpreciseResolveResult import org.jetbrains.kotlin.asJava.ImpreciseResolveResult.UNSURE @@ -38,14 +36,15 @@ import org.jetbrains.kotlin.asJava.builder.InvalidLightClassDataHolder import org.jetbrains.kotlin.asJava.builder.LightClassData import org.jetbrains.kotlin.asJava.builder.LightClassDataHolder import org.jetbrains.kotlin.asJava.builder.LightClassDataProviderForClassOrObject -import org.jetbrains.kotlin.asJava.elements.* +import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass +import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier +import org.jetbrains.kotlin.asJava.elements.KtLightModifierList +import org.jetbrains.kotlin.asJava.elements.KtLightPsiReferenceList import org.jetbrains.kotlin.asJava.hasInterfaceDefaultImpls -import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.lexer.KtTokens.* import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind -import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqNameUnsafe import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.debugText.getDebugText @@ -76,6 +75,7 @@ abstract class KtLightClassForSourceDeclaration( private val _extendsList by lazyPub { createExtendsList() } private val _implementsList by lazyPub { createImplementsList() } + private val _deprecated by lazyPub { classOrObject.isDeprecated() } protected open fun createExtendsList(): PsiReferenceList? = super.getExtendsList()?.let { KtLightPsiReferenceList(it, this) } protected open fun createImplementsList(): PsiReferenceList? = super.getImplementsList()?.let { KtLightPsiReferenceList(it, this) } @@ -227,39 +227,7 @@ abstract class KtLightClassForSourceDeclaration( override fun hasModifierProperty(@NonNls name: String): Boolean = modifierList?.hasModifierProperty(name) ?: false - override fun isDeprecated(): Boolean { - val jetModifierList = classOrObject.modifierList ?: return false - - val deprecatedFqName = KotlinBuiltIns.FQ_NAMES.deprecated - val deprecatedName = deprecatedFqName.shortName().asString() - - for (annotationEntry in jetModifierList.annotationEntries) { - val typeReference = annotationEntry.typeReference ?: continue - - val typeElement = typeReference.typeElement - if (typeElement !is KtUserType) continue // If it's not a user type, it's definitely not a ref to deprecated - - val fqName = toQualifiedName(typeElement) ?: continue - - if (deprecatedFqName == fqName) return true - if (deprecatedName == fqName.asString()) return true - } - return false - } - - private fun toQualifiedName(userType: KtUserType): FqName? { - val reversedNames = Lists.newArrayList() - - var current: KtUserType? = userType - while (current != null) { - val name = current.referencedName ?: return null - - reversedNames.add(name) - current = current.qualifier - } - - return FqName.fromSegments(ContainerUtil.reverse(reversedNames)) - } + override fun isDeprecated(): Boolean = _deprecated override fun isInterface(): Boolean { if (classOrObject !is KtClass) return false diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightClass.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightClass.kt index 19f2f7c0830..bec56e167ca 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightClass.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightClass.kt @@ -371,5 +371,9 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor return super.isInheritorDeep(baseClass, classToByPass) } + private val _deprecated by lazyPub { classOrObject.isDeprecated(support) } + + override fun isDeprecated(): Boolean = _deprecated + override fun copy(): KtLightClassImpl = KtUltraLightClass(classOrObject.copy() as KtClassOrObject, support) } \ No newline at end of file diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightMethods.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightMethods.kt index 834c4e4915f..f8a040ba0c1 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightMethods.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightMethods.kt @@ -71,6 +71,8 @@ internal abstract class KtUltraLightMethod( list } + private val _deprecated: Boolean by lazyPub { kotlinOrigin?.isDeprecated(support) ?: false } + override fun getHierarchicalMethodSignature() = PsiSuperMethodImplUtil.getHierarchicalMethodSignature(this) override fun findSuperMethodSignaturesIncludingStatic(checkAccess: Boolean): List = @@ -95,6 +97,8 @@ internal abstract class KtUltraLightMethod( override fun equals(other: Any?): Boolean = this === other override fun hashCode(): Int = name.hashCode() + + override fun isDeprecated(): Boolean = _deprecated } internal class KtUltraLightMethodForSourceDeclaration( diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightUtils.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightUtils.kt index 24e29af4114..7e601485379 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightUtils.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightUtils.kt @@ -5,15 +5,18 @@ package org.jetbrains.kotlin.asJava.classes -import com.intellij.openapi.util.registry.Registry +import com.google.common.collect.Lists import com.intellij.psi.* import com.intellij.psi.impl.cache.ModifierFlags import com.intellij.psi.impl.cache.TypeInfo import com.intellij.psi.impl.compiled.ClsTypeElementImpl import com.intellij.psi.impl.compiled.SignatureParsing import com.intellij.psi.impl.compiled.StubBuildingVisitor -import com.intellij.psi.impl.light.* +import com.intellij.psi.impl.light.LightMethodBuilder +import com.intellij.psi.impl.light.LightModifierList +import com.intellij.psi.impl.light.LightParameterListBuilder import com.intellij.util.BitUtil.isSet +import com.intellij.util.containers.ContainerUtil import org.jetbrains.kotlin.asJava.LightClassGenerationSupport import org.jetbrains.kotlin.asJava.elements.KotlinLightTypeParameterListBuilder import org.jetbrains.kotlin.asJava.elements.KtLightMethod @@ -25,24 +28,15 @@ import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.descriptors.annotations.Annotated import org.jetbrains.kotlin.lexer.KtTokens -import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.load.kotlin.TypeMappingMode import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_FQ_NAME import org.jetbrains.kotlin.resolve.annotations.argumentValue import org.jetbrains.kotlin.resolve.constants.EnumValue -import org.jetbrains.kotlin.resolve.descriptorUtil.isPublishedApi -import org.jetbrains.kotlin.resolve.inline.isInlineOnly -import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_OVERLOADS_FQ_NAME -import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_SYNTHETIC_ANNOTATION_FQ_NAME -import org.jetbrains.kotlin.resolve.jvm.annotations.STRICTFP_ANNOTATION_FQ_NAME -import org.jetbrains.kotlin.resolve.jvm.annotations.SYNCHRONIZED_ANNOTATION_FQ_NAME import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeProjectionImpl import org.jetbrains.kotlin.types.replace @@ -302,8 +296,11 @@ private fun packMethodFlags(access: Int, isInterface: Boolean): Int { return flags } -internal fun KtDeclaration.isHiddenByDeprecation(support: KtUltraLightSupport): Boolean { - val deprecated = support.findAnnotation(this, FqName("kotlin.Deprecated"))?.second +internal fun KtModifierListOwner.isHiddenByDeprecation(support: KtUltraLightSupport): Boolean { + val jetModifierList = this.modifierList ?: return false + if (jetModifierList.annotationEntries.isEmpty()) return false + + val deprecated = support.findAnnotation(this, KotlinBuiltIns.FQ_NAMES.deprecated)?.second return (deprecated?.argumentValue("level") as? EnumValue)?.enumEntryName?.asString() == "HIDDEN" } @@ -314,3 +311,39 @@ internal fun KtDeclaration.simpleVisibility(): String = when { hasModifier(KtTokens.PROTECTED_KEYWORD) -> PsiModifier.PROTECTED else -> PsiModifier.PUBLIC } + +internal fun KtModifierListOwner.isDeprecated(support: KtUltraLightSupport? = null): Boolean { + val jetModifierList = this.modifierList ?: return false + if (jetModifierList.annotationEntries.isEmpty()) return false + + val deprecatedFqName = KotlinBuiltIns.FQ_NAMES.deprecated + val deprecatedName = deprecatedFqName.shortName().asString() + + for (annotationEntry in jetModifierList.annotationEntries) { + val typeReference = annotationEntry.typeReference ?: continue + + val typeElement = typeReference.typeElement as? KtUserType ?: continue + // If it's not a user type, it's definitely not a ref to deprecated + + val fqName = toQualifiedName(typeElement) ?: continue + + if (deprecatedFqName == fqName) return true + if (deprecatedName == fqName.asString()) return true + } + + return support?.findAnnotation(this, KotlinBuiltIns.FQ_NAMES.deprecated) !== null +} + +private fun toQualifiedName(userType: KtUserType): FqName? { + val reversedNames = Lists.newArrayList() + + var current: KtUserType? = userType + while (current != null) { + val name = current.referencedName ?: return null + + reversedNames.add(name) + current = current.qualifier + } + + return FqName.fromSegments(ContainerUtil.reverse(reversedNames)) +}