mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-04-04 08:31:30 +00:00
test for handling smart casts in "show expression type"
#KT-10588 Fixed
This commit is contained in:
@@ -25,7 +25,6 @@ import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getType
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
class KotlinExpressionTypeProvider : ExpressionTypeProvider<KtExpression>() {
|
||||
override fun getExpressionsAt(elementAt: PsiElement): List<KtExpression> =
|
||||
@@ -39,27 +38,27 @@ class KotlinExpressionTypeProvider : ExpressionTypeProvider<KtExpression>() {
|
||||
}
|
||||
|
||||
override fun getInformationHint(element: KtExpression): String {
|
||||
val type = typeByExpression(element) ?: return "Type is unknown"
|
||||
return renderTypeHint(type)
|
||||
val bindingContext = element.analyze()
|
||||
|
||||
return "<html>${renderExpressionType(element, bindingContext)}</html>"
|
||||
}
|
||||
|
||||
private fun renderExpressionType(element: KtExpression, bindingContext: BindingContext): String {
|
||||
if (element is KtCallableDeclaration) {
|
||||
val descriptor = bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, element] as? CallableDescriptor
|
||||
if (descriptor != null) {
|
||||
return descriptor.returnType?.let { DescriptorRenderer.HTML.renderType(it) } ?: "Type is unknown"
|
||||
}
|
||||
}
|
||||
|
||||
val expressionType = element.getType(bindingContext) ?: return "Type is unknown"
|
||||
val result = DescriptorRenderer.HTML.renderType(expressionType)
|
||||
val smartCast = bindingContext[BindingContext.SMARTCAST, element]
|
||||
if (smartCast != null) {
|
||||
return result + " (smart cast)"
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
override fun getErrorHint(): String = "No expression found"
|
||||
|
||||
companion object {
|
||||
fun renderTypeHint(type: KotlinType) = "<html>" + DescriptorRenderer.HTML.renderType(type) + "</html>"
|
||||
|
||||
fun typeByExpression(expression: KtExpression): KotlinType? {
|
||||
val bindingContext = expression.analyze()
|
||||
|
||||
if (expression is KtCallableDeclaration) {
|
||||
val descriptor = bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, expression] as? CallableDescriptor
|
||||
if (descriptor != null) {
|
||||
return descriptor.returnType
|
||||
}
|
||||
}
|
||||
|
||||
return expression.getType(bindingContext)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
9
idea/testData/codeInsight/expressionType/SmartCast.kt
vendored
Normal file
9
idea/testData/codeInsight/expressionType/SmartCast.kt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
fun foo(x: Any) {
|
||||
if (x is String) {
|
||||
<caret>x.length
|
||||
}
|
||||
}
|
||||
|
||||
// TYPE: if (x is String) { x.length } -> <html>kotlin.Unit</html>
|
||||
// TYPE: x -> <html>kotlin.String (smart cast)</html>
|
||||
// TYPE: x.length -> <html>kotlin.Int</html>
|
||||
@@ -29,7 +29,8 @@ abstract class AbstractExpressionTypeTest : KotlinLightCodeInsightFixtureTestCas
|
||||
protected fun doTest(path: String) {
|
||||
myFixture.configureByFile(path)
|
||||
val expressionTypeProvider = KotlinExpressionTypeProvider()
|
||||
val expressions = expressionTypeProvider.getExpressionsAt(myFixture.elementAtCaret)
|
||||
val elementAtCaret = myFixture.file.findElementAt(myFixture.editor.caretModel.offset)!!
|
||||
val expressions = expressionTypeProvider.getExpressionsAt(elementAtCaret)
|
||||
val types = expressions.map { "${it.text.replace('\n', ' ')} -> ${expressionTypeProvider.getInformationHint(it)}" }
|
||||
val expectedTypes = InTextDirectivesUtils.findLinesWithPrefixesRemoved(myFixture.file.text, "// TYPE: ")
|
||||
UsefulTestCase.assertOrderedEquals(types, expectedTypes)
|
||||
|
||||
Reference in New Issue
Block a user