[SLC] symbolLightUtils: cleanup code

This commit is contained in:
Dmitrii Gridin
2023-03-14 20:24:44 +01:00
committed by Space Team
parent 4dbc6654b0
commit bccf1aaff0
3 changed files with 53 additions and 50 deletions
@@ -173,7 +173,7 @@ internal class SymbolLightFieldForProperty private constructor(
} }
private val _initializer by lazyPub { private val _initializer by lazyPub {
_initializerValue?.createPsiLiteral(this) _initializerValue?.createPsiExpression(this)
} }
override fun getInitializer(): PsiExpression? = _initializer override fun getInitializer(): PsiExpression? = _initializer
@@ -319,7 +319,7 @@ internal class SymbolLightAccessorMethod private constructor(
containingPropertySymbolPointer.withSymbol(ktModule) { propertySymbol -> containingPropertySymbolPointer.withSymbol(ktModule) { propertySymbol ->
when (val initializer = propertySymbol.initializer) { when (val initializer = propertySymbol.initializer) {
is KtConstantInitializerValue -> initializer.constant.createPsiLiteral(this@SymbolLightAccessorMethod) is KtConstantInitializerValue -> initializer.constant.createPsiExpression(this@SymbolLightAccessorMethod)
is KtConstantValueForAnnotation -> initializer.annotationValue.toAnnotationMemberValue(this@SymbolLightAccessorMethod) is KtConstantValueForAnnotation -> initializer.annotationValue.toAnnotationMemberValue(this@SymbolLightAccessorMethod)
is KtNonConstantInitializerValue -> null is KtNonConstantInitializerValue -> null
null -> null null -> null
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.light.classes.symbol package org.jetbrains.kotlin.light.classes.symbol
import com.intellij.openapi.project.Project
import com.intellij.psi.* import com.intellij.psi.*
import com.intellij.psi.util.CachedValueProvider import com.intellij.psi.util.CachedValueProvider
import com.intellij.psi.util.CachedValuesManager import com.intellij.psi.util.CachedValuesManager
@@ -164,44 +165,39 @@ private fun escapeString(str: String): String = buildString {
} }
} }
internal fun KtAnnotationValue.toAnnotationMemberValue(parent: PsiElement): PsiAnnotationMemberValue? { internal fun KtAnnotationValue.toAnnotationMemberValue(parent: PsiElement): PsiAnnotationMemberValue? = when (this) {
return when (this) { is KtArrayAnnotationValue ->
is KtArrayAnnotationValue -> SymbolPsiArrayInitializerMemberValue(sourcePsi, parent) { arrayLiteralParent ->
SymbolPsiArrayInitializerMemberValue(sourcePsi, parent) { arrayLiteralParent -> values.mapNotNull { element -> element.toAnnotationMemberValue(arrayLiteralParent) }
values.mapNotNull { element -> element.toAnnotationMemberValue(arrayLiteralParent) }
}
is KtAnnotationApplicationValue ->
SymbolLightSimpleAnnotation(
annotationValue.classId?.relativeClassName?.asString(),
parent,
annotationValue.arguments,
annotationValue.psi
)
is KtConstantAnnotationValue -> {
this.constantValue.createPsiLiteral(parent)?.let {
when (it) {
is PsiLiteral -> SymbolPsiLiteral(sourcePsi, parent, it)
else -> SymbolPsiExpression(sourcePsi, parent, it)
}
}
} }
is KtEnumEntryAnnotationValue -> asPsiReferenceExpression(parent) is KtAnnotationApplicationValue ->
KtUnsupportedAnnotationValue -> null SymbolLightSimpleAnnotation(
is KtKClassAnnotationValue -> toAnnotationMemberValue(parent) fqName = annotationValue.classId?.relativeClassName?.asString(),
parent = parent,
arguments = annotationValue.arguments,
kotlinOrigin = annotationValue.psi,
)
is KtConstantAnnotationValue -> {
this.constantValue.createPsiExpression(parent)?.let {
if (it is PsiLiteral)
SymbolPsiLiteral(sourcePsi, parent, it)
else
SymbolPsiExpression(sourcePsi, parent, it)
}
} }
is KtEnumEntryAnnotationValue -> asPsiReferenceExpression(parent)
is KtKClassAnnotationValue -> toAnnotationMemberValue(parent)
KtUnsupportedAnnotationValue -> null
} }
private fun KtEnumEntryAnnotationValue.asPsiReferenceExpression(parent: PsiElement): SymbolPsiReference? { private fun KtEnumEntryAnnotationValue.asPsiReferenceExpression(parent: PsiElement): SymbolPsiReference? {
val fqName = this.callableId?.asSingleFqName()?.asString() ?: return null val fqName = this.callableId?.asSingleFqName()?.asString() ?: return null
val elementFactory = PsiElementFactory.getInstance(parent.project) val psiReference = parent.project.withElementFactorySafe {
val psiReference = try { createReferenceFromText(fqName, parent)
elementFactory.createReferenceFromText(fqName, parent) } ?: return null
} catch (_: IncorrectOperationException) {
return null
}
return SymbolPsiReference(sourcePsi, parent, psiReference) return SymbolPsiReference(sourcePsi, parent, psiReference)
} }
@@ -212,36 +208,43 @@ private fun KtKClassAnnotationValue.toAnnotationMemberValue(parent: PsiElement):
is KtKClassAnnotationValue.KtLocalKClassAnnotationValue -> null is KtKClassAnnotationValue.KtLocalKClassAnnotationValue -> null
is KtKClassAnnotationValue.KtErrorClassAnnotationValue -> unresolvedQualifierName is KtKClassAnnotationValue.KtErrorClassAnnotationValue -> unresolvedQualifierName
} ?: return null } ?: return null
val canonicalText = psiType( val canonicalText = psiType(
typeString, parent, boxPrimitiveType = false, /* TODO value.arrayNestedness > 0*/ kotlinFqName = typeString,
context = parent,
boxPrimitiveType = false, /* TODO value.arrayNestedness > 0*/
).let(TypeConversionUtil::erasure).getCanonicalText(false) ).let(TypeConversionUtil::erasure).getCanonicalText(false)
return try {
PsiElementFactory.getInstance(parent.project).createExpressionFromText("$canonicalText.class", parent) return parent.project.withElementFactorySafe {
} catch (_: IncorrectOperationException) { createExpressionFromText("$canonicalText.class", parent)
null
} }
} }
private fun KtConstantValue.asStringForPsiLiteral(): String = private fun KtConstantValue.asStringForPsiLiteral(): String = when (val value = value) {
when (val value = value) { is Char -> "'$value'"
is Char -> "'$value'" is String -> "\"${escapeString(value)}\""
is String -> "\"${escapeString(value)}\"" is Long -> "${value}L"
is Long -> "${value}L" is Float -> "${value}f"
is Float -> "${value}f" null -> "null"
else -> value?.toString() ?: "null" else -> value.toString()
} }
internal fun KtConstantValue.createPsiExpression(parent: PsiElement): PsiExpression? {
internal fun KtConstantValue.createPsiLiteral(parent: PsiElement): PsiExpression? {
val asString = asStringForPsiLiteral() val asString = asStringForPsiLiteral()
return parent.project.withElementFactorySafe {
createExpressionFromText(asString, parent)
}
}
private inline fun <T> Project.withElementFactorySafe(crossinline action: PsiElementFactory.() -> T): T? {
val instance = PsiElementFactory.getInstance(this)
return try { return try {
PsiElementFactory.getInstance(parent.project).createExpressionFromText(asString, parent) instance.action()
} catch (_: IncorrectOperationException) { } catch (_: IncorrectOperationException) {
null null
} }
} }
internal fun BitSet.copy(): BitSet = clone() as BitSet internal fun BitSet.copy(): BitSet = clone() as BitSet
context(KtAnalysisSession) context(KtAnalysisSession)