show detailed smart cast info in "Show expression type" (KT-8803)
This commit is contained in:
@@ -20,12 +20,14 @@ import com.intellij.lang.ExpressionTypeProvider
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||
import org.jetbrains.kotlin.renderer.RenderingFormat
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getType
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
||||
|
||||
class KotlinExpressionTypeProvider : ExpressionTypeProvider<KtExpression>() {
|
||||
private val typeRenderer = DescriptorRenderer.COMPACT_WITH_SHORT_TYPES.withOptions {
|
||||
@@ -59,11 +61,22 @@ class KotlinExpressionTypeProvider : ExpressionTypeProvider<KtExpression>() {
|
||||
}
|
||||
}
|
||||
|
||||
val expressionType = element.getType(bindingContext) ?: return "Type is unknown"
|
||||
val result = typeRenderer.renderType(expressionType)
|
||||
val expressionTypeInfo = bindingContext[BindingContext.EXPRESSION_TYPE_INFO, element] ?: return "Type is unknown"
|
||||
val expressionType = element.getType(bindingContext)
|
||||
val result = expressionType?.let { typeRenderer.renderType(it) } ?: return "Type is unknown"
|
||||
|
||||
val dataFlowValue = DataFlowValueFactory.createDataFlowValue(element, expressionType, bindingContext, element.findModuleDescriptor())
|
||||
val types = expressionTypeInfo.dataFlowInfo.getStableTypes(dataFlowValue)
|
||||
if (!types.isEmpty()) {
|
||||
return types.joinToString(separator = " & ") { typeRenderer.renderType(it) } + " (smart cast from " + result + ")"
|
||||
}
|
||||
|
||||
val smartCast = bindingContext[BindingContext.SMARTCAST, element]
|
||||
if (smartCast != null) {
|
||||
return result + " (smart cast)"
|
||||
if (smartCast != null && element is KtReferenceExpression) {
|
||||
val declaredType = (bindingContext[BindingContext.REFERENCE_TARGET, element] as? CallableDescriptor)?.returnType
|
||||
if (declaredType != null) {
|
||||
return result + " (smart cast from " + typeRenderer.renderType(declaredType) + ")"
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
+1
-1
@@ -4,5 +4,5 @@ fun foo(x: Any) {
|
||||
}
|
||||
}
|
||||
|
||||
// TYPE: x -> <html>String (smart cast)</html>
|
||||
// TYPE: x -> <html>String (smart cast from Any)</html>
|
||||
// TYPE: x.length -> <html>Int</html>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
interface A
|
||||
interface B : A
|
||||
|
||||
fun fn(value: Any) {
|
||||
if (value is B) {
|
||||
if (<caret>value is A) { // here
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TYPE: value -> <html>B (smart cast from Any)</html>
|
||||
// TYPE: value is A -> <html>Boolean</html>
|
||||
@@ -0,0 +1,14 @@
|
||||
interface A
|
||||
interface B
|
||||
|
||||
fun fn(value: Any) {
|
||||
if (value is B) {
|
||||
if (value is A) {
|
||||
println(valu<caret>e)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TYPE: value -> <html>A & B (smart cast from Any)</html>
|
||||
// TYPE: println(value) -> <html>Unit</html>
|
||||
@@ -89,6 +89,12 @@ public class ExpressionTypeTestGenerated extends AbstractExpressionTypeTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("SoftSmartCastMultipleTypes.kt")
|
||||
public void testSoftSmartCastMultipleTypes() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/expressionType/SoftSmartCastMultipleTypes.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("VariableDeclaration.kt")
|
||||
public void testVariableDeclaration() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/expressionType/VariableDeclaration.kt");
|
||||
|
||||
Reference in New Issue
Block a user