mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-04-14 08:31:29 +00:00
Fixed bug with class using data class as type parameter in supers list
This commit is contained in:
@@ -21,7 +21,6 @@ import com.intellij.lang.java.JavaLanguage
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.search.*
|
||||
import com.intellij.psi.search.searches.ClassInheritorsSearch
|
||||
import com.intellij.psi.search.searches.ReferencesSearch
|
||||
import com.intellij.util.Processor
|
||||
import org.jetbrains.kotlin.KtNodeTypes
|
||||
@@ -187,29 +186,7 @@ private class Processor(
|
||||
return
|
||||
}
|
||||
|
||||
val parameters = ClassInheritorsSearch.SearchParameters(psiClass, GlobalSearchScope.allScope(project), true, true, false)
|
||||
val classesToSearch = listOf(psiClass) + ClassInheritorsSearch.search(parameters).findAll()
|
||||
testLog?.add("Searched inheritors of ${psiClass.logPresentation()}")
|
||||
|
||||
for (classToSearch in classesToSearch) {
|
||||
testLog?.add("Searched references to ${classToSearch.logPresentation()}")
|
||||
ReferencesSearch.search(classToSearch).forEach(Processor processor@ { reference -> //TODO: see KT-13607
|
||||
if (processDataClassUsage(reference)) return@processor true
|
||||
|
||||
if (destructuringDeclarationUsageSearchMode != ALWAYS_SMART) {
|
||||
plainSearchHandler(searchScope)
|
||||
return@processor false
|
||||
}
|
||||
|
||||
val element = reference.element
|
||||
val document = PsiDocumentManager.getInstance(project).getDocument(element.containingFile)
|
||||
val lineAndCol = DiagnosticUtils.offsetToLineAndColumn(document, element.startOffset)
|
||||
error("Unsupported reference: '${element.text}' in ${element.containingFile.name} line ${lineAndCol.line} column ${lineAndCol.column}")
|
||||
})
|
||||
|
||||
// we must use plain search inside our data class (and inheritors) because implicit 'this' can happen anywhere
|
||||
(classToSearch as? KtLightClass)?.kotlinOrigin?.let { usePlainSearch(it) }
|
||||
}
|
||||
addClassToProcess(psiClass)
|
||||
|
||||
processTasks()
|
||||
|
||||
@@ -230,6 +207,31 @@ private class Processor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun addClassToProcess(classToSearch: PsiClass) {
|
||||
data class ProcessClassUsagesTask(val classToSearch: PsiClass) : Task {
|
||||
override fun perform() {
|
||||
testLog?.add("Searched references to ${classToSearch.logPresentation()}")
|
||||
ReferencesSearch.search(classToSearch).forEach(Processor processor@ { reference -> //TODO: see KT-13607
|
||||
if (processDataClassUsage(reference)) return@processor true
|
||||
|
||||
if (destructuringDeclarationUsageSearchMode != ALWAYS_SMART) {
|
||||
plainSearchHandler(searchScope)
|
||||
return@processor false
|
||||
}
|
||||
|
||||
val element = reference.element
|
||||
val document = PsiDocumentManager.getInstance(project).getDocument(element.containingFile)
|
||||
val lineAndCol = DiagnosticUtils.offsetToLineAndColumn(document, element.startOffset)
|
||||
error("Unsupported reference: '${element.text}' in ${element.containingFile.name} line ${lineAndCol.line} column ${lineAndCol.column}")
|
||||
})
|
||||
|
||||
// we must use plain search inside our data class (and inheritors) because implicit 'this' can happen anywhere
|
||||
(classToSearch as? KtLightClass)?.kotlinOrigin?.let { usePlainSearch(it) }
|
||||
}
|
||||
}
|
||||
addTask(ProcessClassUsagesTask(classToSearch))
|
||||
}
|
||||
|
||||
private enum class CallableToProcessKind {
|
||||
HAS_DATA_CLASS_TYPE,
|
||||
PROCESS_LAMBDAS
|
||||
@@ -407,15 +409,20 @@ private class Processor(
|
||||
}
|
||||
|
||||
is KtConstructorCalleeExpression -> {
|
||||
if (typeRefParent.parent is KtSuperTypeCallEntry) {
|
||||
// usage in super type list - just ignore, inheritors are processed above
|
||||
val parent = typeRefParent.parent
|
||||
if (parent is KtSuperTypeCallEntry) {
|
||||
val classOrObject = (parent.parent as KtSuperTypeList).parent as KtClassOrObject
|
||||
val psiClass = classOrObject.toLightClass()
|
||||
psiClass?.let { addClassToProcess(it) }
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
is KtSuperTypeListEntry -> {
|
||||
if (typeRef == typeRefParent.typeReference) {
|
||||
// usage in super type list - just ignore, inheritors are processed above
|
||||
val classOrObject = (typeRefParent.parent as KtSuperTypeList).parent as KtClassOrObject
|
||||
val psiClass = classOrObject.toLightClass()
|
||||
psiClass?.let { addClassToProcess(it) }
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -492,6 +499,16 @@ private class Processor(
|
||||
}
|
||||
break@ParentsLoop
|
||||
}
|
||||
|
||||
is PsiReferenceList -> {
|
||||
if (parent.role == PsiReferenceList.Role.EXTENDS_LIST || parent.role == PsiReferenceList.Role.IMPLEMENTS_LIST) {
|
||||
val psiClass = parent.parent as PsiClass
|
||||
if (!psiClass.isPrivateOrLocal()) {
|
||||
addClassToProcess(psiClass)
|
||||
}
|
||||
}
|
||||
break@ParentsLoop
|
||||
}
|
||||
}
|
||||
|
||||
prev = parent
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
Resolved java class to descriptor: JavaSAM
|
||||
Searched inheritors of pack.A
|
||||
Searched references to JavaClass.takeSAM() in Kotlin files
|
||||
Searched references to JavaSAM in java files
|
||||
Searched references to pack.A
|
||||
|
||||
@@ -6,7 +6,6 @@ Checked type of X.f2()
|
||||
Checked type of constructor
|
||||
Checked type of fun2
|
||||
Checked type of fun3
|
||||
Searched inheritors of A
|
||||
Searched references to A
|
||||
Searched references to X.f2() in Kotlin files
|
||||
Searched references to constructor in Kotlin files
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
Searched inheritors of A
|
||||
Searched references to A
|
||||
Used plain search in LocalSearchScope:
|
||||
CLASS:A
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
Checked type of (x, y)
|
||||
Checked type of f()
|
||||
Searched inheritors of X
|
||||
Searched references to X
|
||||
Searched references to f() in Kotlin files
|
||||
Used plain search in LocalSearchScope:
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
Checked type of (x1, y1)
|
||||
Checked type of f()
|
||||
Checked type of g()
|
||||
Searched inheritors of X
|
||||
Searched references to X
|
||||
Searched references to f() in Kotlin files
|
||||
Used plain search in LocalSearchScope:
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// PSI_ELEMENT: org.jetbrains.kotlin.psi.KtParameter
|
||||
// OPTIONS: usages
|
||||
import pack.A;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
@@ -24,4 +24,4 @@ fun List<A>.ext1() {
|
||||
val (x, y) = get(0)
|
||||
}
|
||||
|
||||
fun <T> T.getThis(): T = this
|
||||
fun <T> T.getThis(): T = this
|
||||
|
||||
6
idea/testData/findUsages/kotlin/conventions/components/dataClass.1.java
vendored
Normal file
6
idea/testData/findUsages/kotlin/conventions/components/dataClass.1.java
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
import pack.A;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class JavaClass2 implements List<A> {
|
||||
}
|
||||
@@ -20,3 +20,8 @@ fun g() = A()
|
||||
fun h() = g()
|
||||
|
||||
fun listOfA() = listOf<A>(A(1, "", ""))
|
||||
|
||||
fun test2(p1: JavaClass2, p2: JavaClass3) {
|
||||
val (x1, y1) = p1[0]
|
||||
val (x2, y2) = p2[0]
|
||||
}
|
||||
6
idea/testData/findUsages/kotlin/conventions/components/dataClass.2.java
vendored
Normal file
6
idea/testData/findUsages/kotlin/conventions/components/dataClass.2.java
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
import pack.A;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class JavaClass3 extends ArrayList<A> {
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
Checked type of (x, y, z)
|
||||
Checked type of (x1, y1)
|
||||
Checked type of (x1, y1, z1)
|
||||
Checked type of (x2, y2)
|
||||
Checked type of (x2, y2, z2)
|
||||
Checked type of (x3, y3, z3)
|
||||
Checked type of (x4, y4, z4)
|
||||
@@ -9,15 +11,20 @@ Checked type of g()
|
||||
Checked type of h()
|
||||
Checked type of listOfA()
|
||||
Checked type of listOfA()
|
||||
Searched inheritors of pack.A
|
||||
Searched references to JavaClass.getA() in Kotlin files
|
||||
Searched references to JavaClass2
|
||||
Searched references to JavaClass3
|
||||
Searched references to a in Kotlin files
|
||||
Searched references to f() in Kotlin files
|
||||
Searched references to g() in Kotlin files
|
||||
Searched references to h() in Kotlin files
|
||||
Searched references to listOfA() in Kotlin files
|
||||
Searched references to pack.A
|
||||
Searched references to pack.X
|
||||
Searched references to parameter p1 in test2() in Kotlin files
|
||||
Searched references to parameter p2 in test2() in Kotlin files
|
||||
Used plain search in LocalSearchScope:
|
||||
CLASS:A
|
||||
CLASS:X
|
||||
FUN:ext1
|
||||
FUN:ext1
|
||||
@@ -5,6 +5,8 @@
|
||||
[dataClass.1.kt] Value read 11 val (x3, y3, z3) = h()
|
||||
[dataClass.1.kt] Value read 13 val (x4, y4, z4) = listOfA()[0]
|
||||
[dataClass.1.kt] Value read 15 val (x5, y5, z5) = javaClass.getA()[0]
|
||||
[dataClass.1.kt] Value read 25 val (x1, y1) = p1[0]
|
||||
[dataClass.1.kt] Value read 26 val (x2, y2) = p2[0]
|
||||
[dataClass.1.kt] Value read 5 a.n
|
||||
[dataClass.1.kt] Value read 8 val (x, y, z) = a
|
||||
[dataClass.1.kt] Value read 9 val (x1, y1, z1) = f()
|
||||
@@ -1,6 +1,5 @@
|
||||
Checked type of (x, y, z)
|
||||
Checked type of a
|
||||
Searched inheritors of A
|
||||
Searched references to A
|
||||
Searched references to a in Kotlin files
|
||||
Used plain search in LocalSearchScope:
|
||||
|
||||
@@ -2,9 +2,6 @@ Checked type of (a, n)
|
||||
Checked type of (a1, n1)
|
||||
Checked type of (x, y, z)
|
||||
Checked type of (x1, y1, z1)
|
||||
Searched inheritors of A
|
||||
Searched inheritors of B
|
||||
Searched inheritors of C
|
||||
Searched references to A
|
||||
Searched references to B
|
||||
Searched references to C
|
||||
|
||||
@@ -5,6 +5,13 @@ interface X
|
||||
|
||||
class Y : X
|
||||
|
||||
open class G<T> {
|
||||
fun get(): T = TODO()
|
||||
}
|
||||
|
||||
abstract class Z1 : List<X>
|
||||
abstract class Z2 : G<X>()
|
||||
|
||||
operator fun X.component1(): Int = 0
|
||||
operator fun X.<caret>component2(): Int = 1
|
||||
|
||||
@@ -17,3 +24,8 @@ fun test() {
|
||||
fun Y.ext() {
|
||||
val (a, b) = this
|
||||
}
|
||||
|
||||
fun g(z1: Z1, z2: Z2) {
|
||||
val (x1, y1) = z1[0]
|
||||
val (x2, y2) = z2.get()
|
||||
}
|
||||
|
||||
@@ -1,12 +1,19 @@
|
||||
Checked type of (x, y)
|
||||
Checked type of (x1, y1)
|
||||
Checked type of (x2, y2)
|
||||
Checked type of f()
|
||||
Searched inheritors of X
|
||||
Searched references to X
|
||||
Searched references to Y
|
||||
Searched references to Z1
|
||||
Searched references to Z2
|
||||
Searched references to f() in Kotlin files
|
||||
Searched references to parameter z1 in g() in Kotlin files
|
||||
Searched references to parameter z2 in g() in Kotlin files
|
||||
Used plain search in LocalSearchScope:
|
||||
CLASS:X
|
||||
CLASS:Y
|
||||
CLASS:Z1
|
||||
CLASS:Z2
|
||||
FUN:component1
|
||||
FUN:component2
|
||||
FUN:ext
|
||||
@@ -1,2 +1,4 @@
|
||||
Value read 14 val (x, y) = f()
|
||||
Value read 18 val (a, b) = this
|
||||
Value read 21 val (x, y) = f()
|
||||
Value read 25 val (a, b) = this
|
||||
Value read 29 val (x1, y1) = z1[0]
|
||||
Value read 30 val (x2, y2) = z2.get()
|
||||
@@ -1,7 +1,6 @@
|
||||
Checked type of (x, y)
|
||||
Checked type of (x, y, z)
|
||||
Checked type of parameter a in FOR
|
||||
Searched inheritors of A
|
||||
Searched references to A
|
||||
Searched references to parameter a in FOR in Kotlin files
|
||||
Used plain search in LocalSearchScope:
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
Checked type of (x, y)
|
||||
Checked type of (x1, y1)
|
||||
Checked type of list
|
||||
Searched inheritors of A
|
||||
Searched references to A
|
||||
Searched references to list in Kotlin files
|
||||
Used plain search in LocalSearchScope:
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
Searched inheritors of A
|
||||
Searched references to A
|
||||
Searched references to parameter p in foo() in Kotlin files
|
||||
Searched references to parameter p in takeExtFun() in Kotlin files
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
Checked type of (x1, y1)
|
||||
Checked type of y1()
|
||||
Searched inheritors of A
|
||||
Searched references to A
|
||||
Searched references to parameter a in condition() in Kotlin files
|
||||
Searched references to parameter a in x() in Kotlin files
|
||||
|
||||
@@ -4,7 +4,6 @@ Checked type of (x2, y2)
|
||||
Checked type of f()
|
||||
Checked type of g()
|
||||
Checked type of h()
|
||||
Searched inheritors of X
|
||||
Searched references to X
|
||||
Searched references to Y
|
||||
Searched references to Z
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
Searched inheritors of A
|
||||
Searched references to A
|
||||
Used plain search in LocalSearchScope:
|
||||
CLASS:A
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
Checked type of (a1, n1)
|
||||
Checked type of (a2, n2)
|
||||
Checked type of (a2, n2)
|
||||
Searched inheritors of A
|
||||
Searched references to A
|
||||
Searched references to parameter a in A() in Kotlin files
|
||||
Searched references to parameter a in f() in Kotlin files
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
Checked type of (a1, s)
|
||||
Checked type of (b, n)
|
||||
Searched inheritors of A
|
||||
Searched inheritors of B
|
||||
Searched references to A
|
||||
Searched references to B
|
||||
Searched references to a1 in Kotlin files
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
Searched inheritors of A
|
||||
Searched references to A
|
||||
Used plain search in LocalSearchScope:
|
||||
CLASS:A
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
Searched inheritors of test.KotlinDataClass
|
||||
Searched references to test.KotlinDataClass
|
||||
Used plain search in LocalSearchScope:
|
||||
CLASS:KotlinDataClass
|
||||
|
||||
Reference in New Issue
Block a user