Support contracts in PartialBodyResolveFilter

Previously, PartialBodyResolveFilter didn't know about contracts and was
filtering out calls of such functions, leading to unstable completion in
cases like that:

fun test(x: Any?) {
    require(x is String)
    x.<caret>
}

However, PartialBodyResolveFilter works by pure PSI, while to determine
if function has a contract we have to resolve it.

To solve it, we do something very similar to what has been done with
Nothin-returning functions: introduce
KotlinProbablyContractedFunctionShortNameIndex, which collects all
function which *may* have a contract during indexing.

^KT-25275 Fixed
This commit is contained in:
Dmitry Savvinov
2018-07-20 19:35:45 +03:00
parent 5ab79a111d
commit f90b29c2e3
23 changed files with 293 additions and 2 deletions
@@ -0,0 +1,27 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.project
import com.intellij.openapi.project.Project
import com.intellij.psi.util.CachedValueProvider
import com.intellij.psi.util.CachedValuesManager
import com.intellij.psi.util.PsiModificationTracker
import org.jetbrains.kotlin.idea.stubindex.KotlinProbablyContractedFunctionShortNameIndex
import org.jetbrains.kotlin.resolve.lazy.ProbablyContractedCallableNames
class ProbablyContractedCallableNamesImpl(project: Project) : ProbablyContractedCallableNames {
private val functionNames = CachedValuesManager.getManager(project).createCachedValue(
{
CachedValueProvider.Result.create(
KotlinProbablyContractedFunctionShortNameIndex.getInstance().getAllKeys(project),
PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT
)
},
false
)
override fun isProbablyContractedCallableName(name: String): Boolean = name in functionNames.value
}
@@ -0,0 +1,30 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.stubindex
import com.intellij.openapi.project.Project
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.stubs.StringStubIndexExtension
import com.intellij.psi.stubs.StubIndex
import com.intellij.psi.stubs.StubIndexKey
import org.jetbrains.kotlin.psi.KtNamedFunction
class KotlinProbablyContractedFunctionShortNameIndex : StringStubIndexExtension<KtNamedFunction>() {
override fun getKey(): StubIndexKey<String, KtNamedFunction> = KEY
override fun get(name: String, project: Project, scope: GlobalSearchScope): MutableCollection<KtNamedFunction> =
StubIndex.getElements(KEY, name, project, scope, KtNamedFunction::class.java)
companion object {
private val KEY: StubIndexKey<String, KtNamedFunction> =
KotlinIndexUtil.createIndexKey(KotlinProbablyContractedFunctionShortNameIndex::class.java)
private val ourInstance = KotlinProbablyContractedFunctionShortNameIndex()
@JvmStatic
fun getInstance(): KotlinProbablyContractedFunctionShortNameIndex = ourInstance
}
}