[psi] get type text based on provided stubs
This commit is contained in:
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.psi
|
||||
import com.intellij.lang.ASTNode
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElementOrCallableRef
|
||||
import org.jetbrains.kotlin.psi.stubs.KotlinPlaceHolderStub
|
||||
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
|
||||
import org.jetbrains.kotlin.psi.stubs.elements.KtTokenSets
|
||||
@@ -57,4 +58,55 @@ class KtTypeReference : KtModifierListOwnerStub<KotlinPlaceHolderStub<KtTypeRefe
|
||||
}
|
||||
|
||||
fun nameForReceiverLabel() = (typeElement as? KtUserType)?.referencedName
|
||||
|
||||
/**
|
||||
* Returns presentable text for the underlying type based on stubs when provided.
|
||||
* No decompilation happens if [KtTypeReference] represents compiled code.
|
||||
*/
|
||||
fun getTypeText(): String {
|
||||
return stub?.let { getTypeText(typeElement) } ?: text
|
||||
}
|
||||
|
||||
private fun getQualifiedName(userType: KtUserType): String? {
|
||||
val qualifier = userType.qualifier ?: return userType.referencedName
|
||||
return getQualifiedName(qualifier) + "." + userType.referencedName
|
||||
}
|
||||
|
||||
private fun getTypeText(typeElement: KtTypeElement?): String? {
|
||||
return when (typeElement) {
|
||||
is KtUserType -> buildString {
|
||||
append(getQualifiedName(typeElement))
|
||||
val args = typeElement.typeArguments
|
||||
if (args.isNotEmpty()) {
|
||||
append(args.joinToString(", ", "<", ">") {
|
||||
val projection = when (it.projectionKind) {
|
||||
KtProjectionKind.IN -> "in "
|
||||
KtProjectionKind.OUT -> "out "
|
||||
KtProjectionKind.STAR -> "*"
|
||||
KtProjectionKind.NONE -> ""
|
||||
}
|
||||
projection + (getTypeText(it.typeReference?.typeElement) ?: "")
|
||||
})
|
||||
}
|
||||
}
|
||||
is KtFunctionType -> buildString {
|
||||
val contextReceivers = typeElement.contextReceiversTypeReferences
|
||||
if (contextReceivers.isNotEmpty()) {
|
||||
append(contextReceivers.joinToString(", ", "context(", ")") {getTypeText(it.typeElement) ?: ""})
|
||||
}
|
||||
typeElement.receiverTypeReference?.let { append(getTypeText(it.typeElement)) }
|
||||
append(typeElement.parameters.joinToString(", ", "(", ")") { param ->
|
||||
param.name + ": " + param.typeReference?.getTypeText()
|
||||
})
|
||||
typeElement.returnTypeReference?.let { returnType ->
|
||||
append(" -> ")
|
||||
append(getTypeText(returnType.typeElement))
|
||||
}
|
||||
}
|
||||
is KtIntersectionType -> getTypeText(typeElement.getLeftTypeRef()?.typeElement) + " & " + getTypeText(typeElement.getRightTypeRef()?.typeElement)
|
||||
is KtNullableType -> getTypeText(typeElement.innerType) + "?"
|
||||
null -> null
|
||||
else -> error("Unsupported type $typeElement")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user