[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.lang.ASTNode
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
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.KotlinPlaceHolderStub
|
||||||
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
|
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
|
||||||
import org.jetbrains.kotlin.psi.stubs.elements.KtTokenSets
|
import org.jetbrains.kotlin.psi.stubs.elements.KtTokenSets
|
||||||
@@ -57,4 +58,55 @@ class KtTypeReference : KtModifierListOwnerStub<KotlinPlaceHolderStub<KtTypeRefe
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun nameForReceiverLabel() = (typeElement as? KtUserType)?.referencedName
|
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