DataFlowValue & DataFlowValueFactory major refactoring, get rid of DataFlowValue.id : Any?
Instead, DataFlowValue now requires IdentifierInfo implementation to be created DataFlowValue is compared using IdentifierInfo
This commit is contained in:
committed by
Mikhail Glukhikh
parent
7f9b9ddb45
commit
9001b9bcc0
+11
-8
@@ -21,20 +21,23 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.IdentifierInfo
|
||||
|
||||
fun renderDataFlowValue(value: DataFlowValue): String? {
|
||||
// If it is not a stable identifier, there's no point in rendering it
|
||||
if (!value.isPredictable) return null
|
||||
|
||||
fun renderId(id: Any?): String? {
|
||||
return when (id) {
|
||||
is KtExpression -> id.text
|
||||
is ImplicitReceiver -> "this@${id.declarationDescriptor.name}"
|
||||
is VariableDescriptor -> id.name.asString()
|
||||
is PackageViewDescriptor -> id.fqName.asString()
|
||||
is com.intellij.openapi.util.Pair<*, *> -> renderId(id.first) + "." + renderId(id.second)
|
||||
fun renderId(identifierInfo: IdentifierInfo): String? = with (identifierInfo) {
|
||||
when (this) {
|
||||
is DataFlowValueFactory.ExpressionIdentifierInfo -> expression.text
|
||||
is IdentifierInfo.Receiver -> (this.value as? ImplicitReceiver)?.declarationDescriptor?.name?.let { "this@$it" }
|
||||
is IdentifierInfo.Variable -> variable.name.asString()
|
||||
is IdentifierInfo.PackageOrClass -> (descriptor as? PackageViewDescriptor)?.let { it.fqName.asString() }
|
||||
is IdentifierInfo.Qualified -> renderId(receiverInfo) + "." + renderId(selectorInfo)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
return renderId(value.id)
|
||||
|
||||
return renderId(value.identifierInfo)
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.core
|
||||
|
||||
import com.intellij.openapi.util.Pair
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
@@ -28,10 +27,7 @@ import org.jetbrains.kotlin.idea.util.getResolutionScope
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfo
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.Nullability
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.*
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
@@ -85,24 +81,31 @@ class SmartCastCalculator(
|
||||
val dataFlowValueToEntity: (DataFlowValue) -> Any?
|
||||
if (receiver != null) {
|
||||
val receiverType = bindingContext.getType(receiver) ?: return emptyMap()
|
||||
val receiverId = DataFlowValueFactory.createDataFlowValue(receiver, receiverType, bindingContext, containingDeclarationOrModule).id
|
||||
val receiverIdentifierInfo = DataFlowValueFactory.createDataFlowValue(
|
||||
receiver, receiverType, bindingContext, containingDeclarationOrModule
|
||||
).identifierInfo
|
||||
dataFlowValueToEntity = { value ->
|
||||
val id = value.id
|
||||
if (id is Pair<*, *> && id.first == receiverId) id.second as? VariableDescriptor else null
|
||||
val identifierInfo = value.identifierInfo
|
||||
if (identifierInfo is IdentifierInfo.Qualified && identifierInfo.receiverInfo == receiverIdentifierInfo) {
|
||||
(identifierInfo.selectorInfo as? IdentifierInfo.Variable)?.variable
|
||||
}
|
||||
else null
|
||||
}
|
||||
}
|
||||
else {
|
||||
dataFlowValueToEntity = fun (value: DataFlowValue): Any? {
|
||||
val id = value.id
|
||||
when(id) {
|
||||
is VariableDescriptor, is ImplicitReceiver -> return id
|
||||
val identifierInfo = value.identifierInfo
|
||||
when(identifierInfo) {
|
||||
is IdentifierInfo.Variable -> return identifierInfo.variable
|
||||
is IdentifierInfo.Receiver -> return identifierInfo.value as? ImplicitReceiver
|
||||
|
||||
is Pair<*, *> -> {
|
||||
val first = id.first
|
||||
val second = id.second
|
||||
if (first !is ImplicitReceiver || second !is VariableDescriptor) return null
|
||||
if (resolutionScope?.findNearestReceiverForVariable(second)?.value != first) return null
|
||||
return second
|
||||
is IdentifierInfo.Qualified -> {
|
||||
val receiverInfo = identifierInfo.receiverInfo
|
||||
val selectorInfo = identifierInfo.selectorInfo
|
||||
if (receiverInfo !is IdentifierInfo.Receiver || selectorInfo !is IdentifierInfo.Variable) return null
|
||||
val receiverValue = receiverInfo.value as? ImplicitReceiver ?: return null
|
||||
if (resolutionScope?.findNearestReceiverForVariable(selectorInfo.variable)?.value != receiverValue) return null
|
||||
return selectorInfo.variable
|
||||
}
|
||||
|
||||
else -> return null
|
||||
|
||||
Reference in New Issue
Block a user