Fixed FindUsages case on look up implementation getter/setters via property names

#KT-40788 Fixed
#KT-24616 Fixed

back-port from kotlin-ide commit aa5580bb5a7e96b209cdaa1c82f4e485ee001ae8
This commit is contained in:
Vladimir Dolzhenko
2020-08-10 22:02:44 +02:00
parent e49cdf0ca2
commit 8540f47c15
86 changed files with 157 additions and 61 deletions
@@ -71,7 +71,7 @@ class ExpressionsOfTypeProcessor(
var mode = if (ApplicationManager.getApplication().isUnitTestMode) Mode.ALWAYS_SMART else Mode.PLAIN_WHEN_NEEDED
@get:TestOnly
var testLog: MutableList<String>? = null
var testLog: MutableCollection<String>? = null
inline fun testLog(s: () -> String) {
testLog?.add(s())
@@ -238,7 +238,7 @@ abstract class KotlinFindMemberUsagesHandler<T : KtNamedDeclaration> protected c
if (element is KtElement && !isOnlyKotlinSearch(options.searchScope)) {
// TODO: very bad code!! ReferencesSearch does not work correctly for constructors and annotation parameters
val psiMethodScopeSearch = when {
element is KtNamedFunction || element is KtParameter && element.dataClassComponentFunction() != null ->
element is KtParameter && element.dataClassComponentFunction() != null ->
options.searchScope.excludeKotlinSources()
else -> options.searchScope
}
@@ -2,10 +2,8 @@ Resolved c()
Resolved fieldWithType()
Resolved methodWithType()
Resolved o()
Resolved o()
Resolved o.methodNoType()()
Resolved o.methodWithType()()
Resolved o.methodWithType()()
Searched references to GroovyClass
Searched references to GroovyClass.fieldWithType in non-Java files
Searched references to GroovyClass.methodWithType() in non-Java files
@@ -1,8 +1,4 @@
Resolved INSTANCE()
Resolved INSTANCE()
Resolved INSTANCE()
Resolved INSTANCE()
Resolved OJC()
Resolved OJC()
Resolved c()
Resolved o()
@@ -1,5 +1,4 @@
Resolved INSTANCE()
Resolved INSTANCE()
Searched imported static member PsiField:INSTANCE in [KtFile: javaInvokeWithStaticImport.0.kt]
Searched imported static member PsiField:INSTANCE in [KtFile: javaInvokeWithStaticImport.1.kt]
Searched references to JavaClassWI
@@ -23,4 +23,6 @@ class A() {
interface Foo
fun Foo.ext() {
}
}
// DISABLE-ERRORS
@@ -11,4 +11,6 @@ data class B(val x: Int, val y: Int)
fun foo() {
val (x, y) = A.b()
}
}
// DISABLE-ERRORS
@@ -2,24 +2,15 @@ Checked type of a
Checked type of g()
Checked type of h()
Checked type of listOfA()
Checked type of listOfA()
Checked type of x
Checked type of x1
Checked type of x1
Checked type of x2
Checked type of x2
Checked type of x3
Checked type of x3
Checked type of x3
Checked type of x4
Checked type of x5
Checked type of y
Checked type of y1
Checked type of y1
Checked type of y2
Checked type of y2
Checked type of y3
Checked type of y3
Checked type of y3
Checked type of y4
Checked type of y5
@@ -35,7 +26,6 @@ Resolved (x1, y1, z1)
Resolved (x2, y2)
Resolved (x2, y2, z2)
Resolved (x3, y3)
Resolved (x3, y3)
Resolved (x3, y3, z3)
Resolved (x4, y4, z4)
Resolved (x5, y5, z5)
@@ -1,7 +1,5 @@
Checked type of parameter a of FOR
Checked type of x
Checked type of x
Checked type of y
Checked type of y
Checked type of z
Resolved (x, y)
@@ -14,3 +14,4 @@ fun y(o: Any) {
val list = o as List<A>
val (x, y) = list[0]
}
// DISABLE-ERRORS
@@ -1,8 +1,4 @@
Checked type of x
Checked type of x
Checked type of x
Checked type of y
Checked type of y
Checked type of y
Resolved (x, y)
Resolved b1 + b2
@@ -1,15 +1,12 @@
Checked type of a1
Checked type of a2
Checked type of a2
Checked type of n1
Checked type of n2
Checked type of n2
ExpressionOfTypeProcessor is already started for A. Exit for operator parameter a of A(val a: A?, val n: Int).
Resolved (a1, n1)
Resolved (a2, n2)
Resolved (a2, n2)
Searched references to A
Searched references to parameter a of A(val a: A?, val n: Int) in non-Java files
Searched references to parameter a of f(a: A) in non-Java files
Used plain search of parameter a of A(val a: A?, val n: Int) in LocalSearchScope:
CLASS:A
CLASS:A
+1 -3
View File
@@ -1,7 +1,5 @@
Resolved !in
Resolved !in
Resolved in
Resolved in
Searched references to A
Used plain search of A.contains(k: Int) in LocalSearchScope:
CLASS:A
CLASS:A
@@ -1,7 +1,6 @@
Checked type of parameter a of FOR
Checked type of parameter a of FOR
Resolved for (a in A<Int>()) {}
Resolved for (a in A<String>()) {}
Searched references to A
Used plain search of A.iterator() in LocalSearchScope:
CLASS:A
CLASS:A
+2
View File
@@ -12,3 +12,5 @@ fun test() {
val b = B(2)
b[3] = "a"
}
// DISABLE-ERRORS
+2
View File
@@ -20,3 +20,5 @@ fun test(array: Array<A>) {
val (a1, a2) = array
a1 + 1
}
// DISABLE-ERRORS
-1
View File
@@ -5,7 +5,6 @@ ExpressionOfTypeProcessor is already started for A. Exit for operator A.plus(a:
ExpressionOfTypeProcessor is already started for A. Exit for operator A.plus(m: Int).
Resolved A(0) + A(1)
Resolved A(0) + A(1) + 2
Resolved A(0) + A(1) + 2
Resolved a += 1
Resolved a += A(1)
Resolved a1 + 1
+2
View File
@@ -13,3 +13,5 @@ fun test() {
a[2]++
a[3]
}
// DISABLE-ERRORS
@@ -1,24 +1,15 @@
Checked type of a
Checked type of a
Checked type of b
Checked type of b
Checked type of c
Checked type of c
Checked type of d
Checked type of d
Checked type of dInT2
Checked type of dInT3
Checked type of div(other: A)
Checked type of indirectDiction()
Checked type of indirectDiction()
Checked type of indirectDiction()
Checked type of indirectPlusDiction()
Checked type of indirectPlusDiction()
Checked type of t
Checked type of t
Checked type of times(other: Diction)
Checked type of tt
Checked type of tt
ExpressionOfTypeProcessor is already started for Diction. Exit for operator Diction.minus(other: Diction).
ExpressionOfTypeProcessor is already started for Diction. Exit for operator Diction.plus(other: Diction).
ExpressionOfTypeProcessor is already started for Diction. Exit for operator times(other: Diction).
@@ -15,3 +15,5 @@ open class C: Y {
interface Z: A {
}
// DISABLE-ERRORS
@@ -15,3 +15,5 @@ open class C: Y {
interface Z: A {
}
// DISABLE-ERRORS
@@ -15,3 +15,4 @@ open class C: Y {
interface Z: A {
}
// DISABLE-ERRORS
@@ -15,3 +15,4 @@ open class C: Y {
interface Z: A {
}
// DISABLE-ERRORS
@@ -3,3 +3,4 @@
package server
data class <caret>Data
// DISABLE-ERRORS
@@ -15,3 +15,5 @@ open class <caret>Server {
println("Server")
}
}
// DISABLE-ERRORS
@@ -54,4 +54,6 @@ fun Any.asServer(): Server? {
is Server -> println("Server!")
}
return if (this is Server) this as Server else this as? Server
}
}
// DISABLE-ERRORS
@@ -14,3 +14,4 @@ fun foo() {
}
}
// DISABLE-ERRORS
@@ -14,3 +14,4 @@ fun foo() {
}
}
// DISABLE-ERRORS
@@ -14,3 +14,4 @@ fun foo() {
}
}
// DISABLE-ERRORS
@@ -10,3 +10,4 @@ fun foo() {
}
}
// DISABLE-ERRORS
@@ -7,3 +7,5 @@ fun foo(): Any {
}
val x = Bar()
// DISABLE-ERRORS
@@ -11,3 +11,5 @@ fun foo(): Any {
}
val x = Bar()
// DISABLE-ERRORS
@@ -14,3 +14,4 @@ public class ServerEx(): Server() {
override fun processRequest() = Server.Foo()
}
// DISABLE-ERRORS
@@ -23,3 +23,5 @@ enum class E {
open fun <caret>foo(n: Int): Int = n
}
// DISABLE-ERRORS
@@ -16,3 +16,5 @@ fun test(i: I) {
A().foo()
B().foo()
}
// DISABLE-ERRORS
@@ -13,3 +13,5 @@ fun foo() {
}
bar()
// DISABLE-ERRORS
@@ -15,3 +15,4 @@ fun foo(n: Int) {
}
val foo: Int
// DISABLE-ERRORS
@@ -43,3 +43,5 @@ fun B.foo(s: String, n: Number) {
fun bar(b: B) {
b.foo("", 0)
}
// DISABLE-ERRORS
@@ -21,3 +21,4 @@ fun A.foo(s: String) {
fun X.foo(n: Int) {
}
// DISABLE-ERRORS
@@ -11,4 +11,5 @@ public open class Server() {
public class ServerEx(): Server() {
override fun processRequest() = "foo" + doProcessRequest()
}
// DISABLE-ERRORS
@@ -0,0 +1,9 @@
// PSI_ELEMENT: org.jetbrains.kotlin.psi.KtNamedFunction
// CHECK_SUPER_METHODS_YES_NO_DIALOG: no
// OPTIONS: usages
class SomeXImpl: SomeX {
override fun <caret>getSmth(): String = TODO()
}
fun foo(x: SomeXImpl) = x.smth
@@ -0,0 +1,4 @@
public interface SomeX {
String getSmth();
}
@@ -0,0 +1 @@
Value read 9 fun foo(x: SomeXImpl) = x.smth
@@ -11,3 +11,5 @@ fun main(a: A) {
a.copy(1)
B(0).copy(1)
}
// DISABLE-ERRORS
@@ -24,4 +24,6 @@ fun test() {
val t = B().p
B().p = 1
}
}
// DISABLE-ERRORS
@@ -25,4 +25,6 @@ fun test() {
val t = B().p
B().p = 1
}
}
// DISABLE-ERRORS
@@ -25,4 +25,6 @@ fun test() {
val t = B().p
B().p = 1
}
}
// DISABLE-ERRORS
@@ -7,3 +7,5 @@ fun foo(): Any {
}
val x = Bar
// DISABLE-ERRORS
@@ -11,3 +11,4 @@ fun foo(): Any {
}
val x = Bar
// DISABLE-ERRORS
@@ -14,3 +14,4 @@ public class ServerEx(): Server() {
override fun processRequest() = Server.Foo
}
// DISABLE-ERRORS
@@ -14,4 +14,6 @@ open class A<T>(<caret>foo: T) {
fun usage() {
A(foo = ":)")
}
}
// DISABLE-ERRORS
@@ -7,3 +7,5 @@ fun foo(): String {
}
val x = bar
// DISABLE-ERRORS
@@ -11,3 +11,4 @@ fun foo(): String {
}
val x = bar
// DISABLE-ERRORS
@@ -9,3 +9,4 @@ fun foo() {
val <caret>foo: Int = 1
val Int.foo: Int = 2
// DISABLE-ERRORS
@@ -11,4 +11,5 @@ public open class Server() {
public class ServerEx(): Server() {
override fun processRequest() = "foo" + foo
}
// DISABLE-ERRORS
@@ -10,4 +10,5 @@ public class ServerEx(): Server(foo = "!") {
override fun processRequest() = "foo" + foo // this reference is found as a side effect of big use scope of constructor parameter:
// if it was simple property, it wouldn't be found
}
// DISABLE-ERRORS
@@ -17,3 +17,4 @@ open class B: A<String>() {
super<A>.foo = value
}
}
// DISABLE-ERRORS
@@ -15,3 +15,5 @@ open class B: A<String>() {
super<A>.foo = value
}
}
// DISABLE-ERRORS
@@ -17,3 +17,5 @@ open class B: A<String>() {
super<A>.foo = value
}
}
// DISABLE-ERRORS
@@ -15,3 +15,5 @@ open class B: A<String>() {
super<A>.foo = value
}
}
// DISABLE-ERRORS
@@ -17,3 +17,4 @@ open class B: A<String>() {
super<A>.foo = value
}
}
// DISABLE-ERRORS
@@ -15,3 +15,5 @@ open class B: A<String>() {
super<A>.foo = value
}
}
// DISABLE-ERRORS
@@ -8,4 +8,5 @@ fun main(args: Array<String>) {
val a = A(10)
println(a.field)
}
}
// DISABLE-ERRORS
@@ -1,2 +1,4 @@
// PSI_ELEMENT: org.jetbrains.kotlin.psi.KtTypeParameter
val <T<caret>> foo: T
val <T<caret>> foo: T
// DISABLE-ERRORS
@@ -18,3 +18,5 @@ open class B: A<String>() {
super<A>.foo = value
}
}
// DISABLE-ERRORS
@@ -23,3 +23,5 @@ enum class E {
internal open fun <caret>foo(n: Int): Int = n
}
// DISABLE-ERRORS
@@ -15,3 +15,5 @@ fun foo(n: Int) {
}
val foo: Int
// ERROR: Property must be initialized
@@ -8,4 +8,6 @@ interface TraitWithImpl {
public class TraitWithDelegatedWithImpl(f: TraitWithImpl): TraitWithImpl by f
fun test(twdwi: TraitWithDelegatedWithImpl) = twdwi.foo()
fun test(twdwi: TraitWithDelegatedWithImpl) = twdwi.foo()
// ERROR: Modifier 'internal' is not applicable inside 'interface'
@@ -14,3 +14,4 @@ fun main(a: A) {
}
// for KT-3769 Find usages gives no result for overrides
// ERROR: Modifier 'internal' is not applicable inside 'interface'
@@ -9,3 +9,5 @@ fun foo() {
internal val <caret>foo: Int = 1
val Int.foo: Int = 2
// ERROR: Extension property cannot be initialized because it has no backing field
@@ -17,3 +17,5 @@ open class B: A<String>() {
super<A>.foo = value
}
}
// DISABLE-ERRORS
@@ -2,4 +2,6 @@
// OPTIONS: usages
<caret>object: Any() {
}
}
// ERROR: No script runtime was found in the classpath: class 'kotlin.script.templates.standard.ScriptTemplateWithArgs' not found. Please add kotlin-script-runtime.jar to the module dependencies.
@@ -2,4 +2,6 @@
// OPTIONS: usages
val x = <caret>object: Any() {
}
}
// ERROR: No script runtime was found in the classpath: class 'kotlin.script.templates.standard.ScriptTemplateWithArgs' not found. Please add kotlin-script-runtime.jar to the module dependencies.
@@ -3,3 +3,5 @@
fun foo() {
val x = <caret>object : Any() {}
}
// ERROR: No script runtime was found in the classpath: class 'kotlin.script.templates.standard.ScriptTemplateWithArgs' not found. Please add kotlin-script-runtime.jar to the module dependencies.
+2
View File
@@ -2,3 +2,5 @@
// OPTIONS: usages
val <caret>foo = "foo"
val bar = foo
// ERROR: No script runtime was found in the classpath: class 'kotlin.script.templates.standard.ScriptTemplateWithArgs' not found. Please add kotlin-script-runtime.jar to the module dependencies.
@@ -5,3 +5,5 @@ fun foo() {
val x = Local()
}
// ERROR: No script runtime was found in the classpath: class 'kotlin.script.templates.standard.ScriptTemplateWithArgs' not found. Please add kotlin-script-runtime.jar to the module dependencies.
@@ -8,3 +8,6 @@ fun foo() {
val <caret>c = C()
c += 10
}
// ERROR: 'operator' modifier is inapplicable on this function: must return Unit
// ERROR: Function 'plusAssign' should return Unit to be used by corresponding operator '+='
@@ -11,3 +11,5 @@ fun foo() {
v += 1
(v) -= 1
}
// ERROR: Unresolved reference: X
@@ -11,3 +11,5 @@ fun foo() {
v += 1
(v) -= 1
}
// ERROR: This annotation is not applicable to target 'expression'
// ERROR: Unresolved reference: X
@@ -6,5 +6,5 @@ package usages
import library.Foo
fun test() {
Foo().<caret>x = 1
Foo(1).<caret>x = 1
}
@@ -1 +1 @@
Value write 9 Foo().x = 1
Value write 9 Foo(1).x = 1
@@ -6,5 +6,5 @@ package usages
import library.Foo
fun test() {
Foo().<caret>bar(1)
Foo(1).<caret>bar(1)
}
@@ -1 +1 @@
Function call 9 Foo().bar(1)
Function call 9 Foo(1).bar(1)
@@ -38,12 +38,14 @@ import com.intellij.usages.impl.rules.UsageTypeProvider
import com.intellij.usages.rules.UsageFilteringRule
import com.intellij.usages.rules.UsageGroupingRule
import com.intellij.util.CommonProcessors
import org.jetbrains.kotlin.idea.caches.resolve.analyzeWithAllCompilerChecks
import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationManager
import org.jetbrains.kotlin.idea.core.util.clearDialogsResults
import org.jetbrains.kotlin.idea.core.util.setDialogsResult
import org.jetbrains.kotlin.idea.findUsages.handlers.KotlinFindMemberUsagesHandler
import org.jetbrains.kotlin.idea.refactoring.CHECK_SUPER_METHODS_YES_NO_DIALOG
import org.jetbrains.kotlin.idea.search.usagesSearch.ExpressionsOfTypeProcessor
import org.jetbrains.kotlin.idea.test.DirectiveBasedActionUtils
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
import org.jetbrains.kotlin.idea.test.TestFixtureExtension
@@ -51,10 +53,12 @@ import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
import org.jetbrains.kotlin.idea.util.runReadActionInSmartMode
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
import org.jetbrains.kotlin.test.InTextDirectivesUtils
import org.jetbrains.kotlin.test.KotlinTestUtils
import java.io.File
import java.util.*
import kotlin.collections.LinkedHashSet
abstract class AbstractFindUsagesWithDisableComponentSearchTest : AbstractFindUsagesTest() {
@@ -135,6 +139,12 @@ abstract class AbstractFindUsagesTest : KotlinLightCodeInsightFixtureTestCase()
ScriptConfigurationManager.updateScriptDependenciesSynchronously(myFixture.file)
}
(myFixture.file as? KtFile)?.let { ktFile ->
val diagnosticsProvider: (KtFile) -> Diagnostics = { it.analyzeWithAllCompilerChecks().bindingContext.diagnostics }
DirectiveBasedActionUtils.checkForUnexpectedWarnings(ktFile, diagnosticsProvider)
DirectiveBasedActionUtils.checkForUnexpectedErrors(ktFile, diagnosticsProvider)
}
val caretElement = when {
InTextDirectivesUtils.isDirectiveDefined(mainFileText, "// FIND_BY_REF") -> TargetElementUtil.findTargetElement(
myFixture.editor,
@@ -226,7 +236,7 @@ internal fun <T : PsiElement> findUsagesAndCheckResults(
val highlightingMode = InTextDirectivesUtils.isDirectiveDefined(mainFileText, "// HIGHLIGHTING")
var log: String? = null
val logList = ArrayList<String>()
val logList = LinkedHashSet<String>()
val usageInfos = try {
if (ExpressionsOfTypeProcessor.mode !== ExpressionsOfTypeProcessor.Mode.ALWAYS_PLAIN) {
ExpressionsOfTypeProcessor.testLog = logList
@@ -724,6 +724,11 @@ public class FindUsagesTestGenerated extends AbstractFindUsagesTest {
runTest("idea/testData/findUsages/kotlin/findFunctionUsages/localClassMember.0.kt");
}
@TestMetadata("nonBaseDeclarationFunctionAsPropName.0.kt")
public void testNonBaseDeclarationFunctionAsPropName() throws Exception {
runTest("idea/testData/findUsages/kotlin/findFunctionUsages/nonBaseDeclarationFunctionAsPropName.0.kt");
}
@TestMetadata("objectExpressionDeepMember.0.kt")
public void testObjectExpressionDeepMember() throws Exception {
runTest("idea/testData/findUsages/kotlin/findFunctionUsages/objectExpressionDeepMember.0.kt");