Fix kotlin.Deprecated annotation for UL-classes

This commit is contained in:
Igor Yakovlev
2019-05-28 20:45:23 +03:00
parent 2a729082a0
commit eaa36d4d27
4 changed files with 60 additions and 51 deletions
@@ -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<String>()
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
@@ -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)
}
@@ -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<MethodSignatureBackedByPsiMethod> =
@@ -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(
@@ -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<String>()
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))
}