Correct processing of "is" check

This commit is contained in:
Valentin Kipyatkov
2016-08-25 20:11:42 +03:00
parent 25ab66053b
commit 3910f31de9
3 changed files with 31 additions and 8 deletions
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
import org.jetbrains.kotlin.idea.references.KtDestructuringDeclarationReference
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinRequestResultProcessor
import org.jetbrains.kotlin.idea.search.restrictToKotlinSources
import org.jetbrains.kotlin.idea.search.unionSafe
import org.jetbrains.kotlin.idea.util.FuzzyType
import org.jetbrains.kotlin.idea.util.fuzzyExtensionReceiverType
import org.jetbrains.kotlin.idea.util.toFuzzyType
@@ -70,10 +71,7 @@ fun findDestructuringDeclarationUsages(
) {
// for local scope it's faster to use plain search
if (scope is LocalSearchScope) {
val unwrappedElement = ktDeclaration.namedUnwrappedElement ?: return
val resultProcessor = KotlinRequestResultProcessor(unwrappedElement,
filter = { ref -> ref is KtDestructuringDeclarationReference })
optimizer.searchWord("(", scope.restrictToKotlinSources(), UsageSearchContext.IN_CODE, true, unwrappedElement, resultProcessor)
doPlainSearch(ktDeclaration, scope, optimizer)
return
}
@@ -89,18 +87,32 @@ fun findDestructuringDeclarationUsages(
classDescriptor.defaultType.toFuzzyType(classDescriptor.typeConstructor.parameters)
}
Processor(dataType, ktDeclaration, scope, consumer).run()
Processor(dataType,
ktDeclaration,
scope,
consumer,
plainSearchHandler = { searchScope -> doPlainSearch(ktDeclaration, searchScope, optimizer) }
).run()
}
private fun doPlainSearch(ktDeclaration: KtDeclaration, scope: SearchScope, optimizer: SearchRequestCollector) {
val unwrappedElement = ktDeclaration.namedUnwrappedElement ?: return
val resultProcessor = KotlinRequestResultProcessor(unwrappedElement,
filter = { ref -> ref is KtDestructuringDeclarationReference })
optimizer.searchWord("(", scope.restrictToKotlinSources(), UsageSearchContext.IN_CODE, true, unwrappedElement, resultProcessor)
}
private class Processor(
private val dataType: FuzzyType,
private val target: KtDeclaration,
private val searchScope: SearchScope,
private val consumer: Processor<PsiReference>
private val consumer: Processor<PsiReference>,
private val plainSearchHandler: (SearchScope) -> Unit
) {
private val project = target.project
private val declarationsToSearch = ArrayList<PsiElement>()
private val declarationsToSearchSet = HashSet<PsiElement>()
private var scopeToUsePlainSearch: SearchScope = LocalSearchScope.EMPTY
fun run() {
val dataClassDescriptor = dataType.type.constructor.declarationDescriptor ?: return
@@ -135,6 +147,8 @@ private class Processor(
val declaration = declarationsToSearch[index++]
processDeclarationOfTypeWithDataClass(declaration)
}
plainSearchHandler(scopeToUsePlainSearch)
}
//TODO: check if it's operator (too expensive)
@@ -200,7 +214,9 @@ private class Processor(
}
is KtIsExpression -> {
return true //TODO!
val scopeOfPossibleSmartCast = typeRefParent.getParentOfType<KtDeclarationWithBody>(true)
scopeOfPossibleSmartCast?.let { usePlainSearch(it) }
return true
}
is KtBinaryExpressionWithTypeRHS -> {
@@ -321,6 +337,11 @@ private class Processor(
}
}
private fun usePlainSearch(scopeElement: KtElement) {
scopeToUsePlainSearch = LocalSearchScope(scopeElement)
.intersectWith(searchScope)
.unionSafe(scopeToUsePlainSearch)
}
private fun PsiModifierListOwner.isPrivateOrLocal(): Boolean {
return hasModifierProperty(PsiModifier.PRIVATE) || parents.any { it is PsiCodeBlock }
@@ -24,6 +24,7 @@ fun listOfA() = listOf<A>(A(1, "", ""))
fun x(o: Any) {
if (o is A) {
val (x, y) = o
val (x1, y1) = A(1, "", "")
}
}
@@ -6,7 +6,8 @@
[dataClass.2.kt] Value read 13 val (x4, y4, z4) = listOfA()[0]
[dataClass.2.kt] Value read 15 val (x5, y5, z5) = javaClass.getA()[0]
[dataClass.2.kt] Value read 26 val (x, y) = o
[dataClass.2.kt] Value read 32 val (x, y) = list[0]
[dataClass.2.kt] Value read 27 val (x1, y1) = A(1, "", "")
[dataClass.2.kt] Value read 33 val (x, y) = list[0]
[dataClass.2.kt] Value read 5 a.n
[dataClass.2.kt] Value read 8 val (x, y, z) = a
[dataClass.2.kt] Value read 9 val (x1, y1, z1) = f()