SLC: keep annotations on type when converting to PsiType

^KT-55815 Fixed
This commit is contained in:
Jinseong Jeon
2023-01-12 17:15:21 -08:00
committed by Ilya Kirillov
parent 120ca08740
commit 88b07f5287
13 changed files with 170 additions and 107 deletions
@@ -5,8 +5,7 @@
package org.jetbrains.kotlin.light.classes.symbol.annotations
import com.intellij.psi.PsiClassType
import com.intellij.psi.PsiElement
import com.intellij.psi.*
import com.intellij.psi.impl.light.LightReferenceListBuilder
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.annotations.*
@@ -14,7 +13,10 @@ import org.jetbrains.kotlin.analysis.api.annotations.KtKClassAnnotationValue.KtN
import org.jetbrains.kotlin.analysis.api.components.buildClassType
import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionSymbol
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtAnnotatedSymbol
import org.jetbrains.kotlin.analysis.api.types.KtNonErrorClassType
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.analysis.api.types.KtTypeMappingMode
import org.jetbrains.kotlin.asJava.classes.annotateByTypeAnnotationProvider
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassBase
@@ -126,3 +128,30 @@ internal fun KtAnnotatedSymbol.computeThrowsList(
annoApp.arguments.forEach { handleAnnotationValue(it.expression) }
}
context(KtAnalysisSession)
internal fun annotateByKtType(
psiType: PsiType,
ktType: KtType,
psiContext: PsiTypeElement,
): PsiType {
fun KtType.getAnnotationsSequence(): Sequence<List<PsiAnnotation>> =
sequence {
yield(annotations.map { annoApp ->
SymbolLightSimpleAnnotation(
annoApp.classId?.asFqNameString(),
psiContext,
annoApp.arguments,
annoApp.psi
)
})
(this@getAnnotationsSequence as? KtNonErrorClassType)?.ownTypeArguments?.forEach { typeProjection ->
typeProjection.type?.let {
yieldAll(it.getAnnotationsSequence())
}
}
}
return psiType.annotateByTypeAnnotationProvider(ktType.getAnnotationsSequence())
}
@@ -93,7 +93,9 @@ internal class SymbolLightFieldForEnumEntry(
private val _type: PsiType by lazyPub {
withEnumEntrySymbol { enumEntrySymbol ->
enumEntrySymbol.returnType.asPsiType(this@SymbolLightFieldForEnumEntry, allowErrorTypes = true) ?: nonExistentType()
enumEntrySymbol.returnType
.asPsiType(this@SymbolLightFieldForEnumEntry, allowErrorTypes = true)
?: nonExistentType()
}
}
@@ -66,23 +66,16 @@ internal class SymbolLightFieldForProperty private constructor(
private val _returnedType: PsiType by lazyPub {
withPropertySymbol { propertySymbol ->
val isDelegated = (propertySymbol as? KtKotlinPropertySymbol)?.isDelegatedProperty == true
when {
isDelegated ->
(kotlinOrigin as? KtProperty)?.delegateExpression?.let {
it.getKtType()?.asPsiType(
this@SymbolLightFieldForProperty,
allowErrorTypes = true,
KtTypeMappingMode.RETURN_TYPE
)
}
else -> propertySymbol.returnType.asPsiType(
this@SymbolLightFieldForProperty,
allowErrorTypes = true,
KtTypeMappingMode.RETURN_TYPE
)
} ?: nonExistentType()
}
val ktType = if (isDelegated)
(kotlinOrigin as? KtProperty)?.delegateExpression?.getKtType()
else
propertySymbol.returnType
ktType?.asPsiType(
this@SymbolLightFieldForProperty,
allowErrorTypes = true,
KtTypeMappingMode.RETURN_TYPE
)
} ?: nonExistentType()
}
private val _isDeprecated: Boolean by lazyPub {
@@ -187,12 +187,14 @@ internal class SymbolLightSimpleMethod(
functionSymbol.returnType.takeUnless { it.isVoidType } ?: return@withFunctionSymbol PsiType.VOID
}
ktType.asPsiType(
ktType.asPsiTypeElement(
this@SymbolLightSimpleMethod,
allowErrorTypes = true,
KtTypeMappingMode.RETURN_TYPE,
this@SymbolLightSimpleMethod.containingClass.isAnnotationType,
)
)?.let {
annotateByKtType(it.type, ktType, it)
}
} ?: nonExistentType()
}
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.analysis.api.types.KtTypeMappingMode
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier
import org.jetbrains.kotlin.light.classes.symbol.*
import org.jetbrains.kotlin.light.classes.symbol.annotations.annotateByKtType
import org.jetbrains.kotlin.light.classes.symbol.methods.SymbolLightMethodBase
import org.jetbrains.kotlin.psi.KtParameter
@@ -77,7 +78,13 @@ internal abstract class SymbolLightParameterCommon(
else -> KtTypeMappingMode.VALUE_PARAMETER
}
ktType.asPsiType(this@SymbolLightParameterCommon, allowErrorTypes = true, typeMappingMode)
ktType.asPsiTypeElement(
this@SymbolLightParameterCommon,
allowErrorTypes = true,
typeMappingMode
)?.let {
annotateByKtType(it.type, ktType, it)
}
} ?: nonExistentType()
if (parameterSymbol.isVararg) {
@@ -17,10 +17,7 @@ import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.light.classes.symbol.*
import org.jetbrains.kotlin.light.classes.symbol.annotations.GranularAnnotationsBox
import org.jetbrains.kotlin.light.classes.symbol.annotations.NullabilityAnnotationsProvider
import org.jetbrains.kotlin.light.classes.symbol.annotations.SymbolAnnotationsProvider
import org.jetbrains.kotlin.light.classes.symbol.annotations.toOptionalFilter
import org.jetbrains.kotlin.light.classes.symbol.annotations.*
import org.jetbrains.kotlin.light.classes.symbol.methods.SymbolLightMethodBase
import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightClassModifierList
import org.jetbrains.kotlin.psi.KtParameter
@@ -85,7 +82,10 @@ internal class SymbolLightParameterForReceiver private constructor(
private val _type: PsiType by lazyPub {
withReceiverSymbol { receiver ->
receiver.type.asPsiType(this, allowErrorTypes = true)
val ktType = receiver.type
ktType.asPsiTypeElement(this, allowErrorTypes = true)?.let {
annotateByKtType(it.type, ktType, it)
}
} ?: nonExistentType()
}
@@ -41,12 +41,14 @@ internal fun KtAnalysisSession.mapType(
psiContext: PsiElement,
mode: KtTypeMappingMode
): PsiClassType? {
val psiType = type.asPsiType(
val psiTypeElement = type.asPsiTypeElement(
psiContext,
allowErrorTypes = true,
mode,
)
return psiType as? PsiClassType
return (psiTypeElement?.type as? PsiClassType)?.let {
annotateByKtType(it, type, psiTypeElement) as? PsiClassType
}
}