Supported default objects in class usages.
This commit is contained in:
@@ -16,34 +16,23 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.references
|
package org.jetbrains.kotlin.idea.references
|
||||||
|
|
||||||
import com.intellij.psi.PsiReference
|
import com.intellij.psi.*
|
||||||
import com.intellij.psi.PsiElement
|
|
||||||
import org.jetbrains.kotlin.asJava.unwrapped
|
import org.jetbrains.kotlin.asJava.unwrapped
|
||||||
import com.intellij.psi.PsiMethod
|
|
||||||
import org.jetbrains.kotlin.psi.JetPropertyAccessor
|
|
||||||
import org.jetbrains.kotlin.psi.JetProperty
|
|
||||||
import java.util.HashSet
|
|
||||||
import org.jetbrains.kotlin.psi.JetExpression
|
|
||||||
import org.jetbrains.kotlin.idea.intentions.OperatorToFunctionIntention
|
import org.jetbrains.kotlin.idea.intentions.OperatorToFunctionIntention
|
||||||
import org.jetbrains.kotlin.psi.JetQualifiedExpression
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.JetCallExpression
|
|
||||||
import org.jetbrains.kotlin.psi.JetObjectDeclaration
|
|
||||||
import org.jetbrains.kotlin.psi.JetClass
|
|
||||||
import com.intellij.psi.PsiPolyVariantReference
|
|
||||||
import org.jetbrains.kotlin.utils.emptyOrSingletonList
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||||
|
import org.jetbrains.kotlin.utils.emptyOrSingletonList
|
||||||
|
import java.util.HashSet
|
||||||
|
|
||||||
// Navigation element of the resolved reference
|
// Navigation element of the resolved reference
|
||||||
// For property accessor return enclosing property
|
// For property accessor return enclosing property
|
||||||
// For default object return enclosing class
|
|
||||||
public val PsiReference.unwrappedTargets: Set<PsiElement>
|
public val PsiReference.unwrappedTargets: Set<PsiElement>
|
||||||
get() {
|
get() {
|
||||||
fun PsiElement.adjust(): PsiElement? {
|
fun PsiElement.adjust(): PsiElement? {
|
||||||
val target = unwrapped?.getOriginalElement()
|
val target = unwrapped?.getOriginalElement()
|
||||||
return when {
|
return when {
|
||||||
target is JetPropertyAccessor -> target.getNonStrictParentOfType<JetProperty>()
|
target is JetPropertyAccessor -> target.getNonStrictParentOfType<JetProperty>()
|
||||||
target is JetObjectDeclaration && target.isDefault() -> target.getNonStrictParentOfType<JetClass>()
|
|
||||||
else -> target
|
else -> target
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -62,6 +51,18 @@ public fun PsiReference.matchesTarget(candidateTarget: PsiElement): Boolean {
|
|||||||
if (this is JetReference) {
|
if (this is JetReference) {
|
||||||
return targets.any {
|
return targets.any {
|
||||||
it is PsiMethod && it.isConstructor() && it.getContainingClass() == unwrappedCandidate
|
it is PsiMethod && it.isConstructor() && it.getContainingClass() == unwrappedCandidate
|
||||||
|
|| it is JetObjectDeclaration && it.isDefault() && it.getNonStrictParentOfType<JetClass>() == unwrappedCandidate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this is PsiReferenceExpression && candidateTarget is JetObjectDeclaration && unwrappedTargets.size() == 1) {
|
||||||
|
val referredClass = unwrappedTargets.first()
|
||||||
|
if (referredClass is JetClass && candidateTarget in referredClass.getDefaultObjects()) {
|
||||||
|
val parentReference = getParent().getReference()
|
||||||
|
if (parentReference != null) {
|
||||||
|
return parentReference.unwrappedTargets.any {
|
||||||
|
(it is JetProperty || it is JetNamedFunction) && it.getParent()?.getParent() == candidateTarget
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
|||||||
+11
-8
@@ -17,18 +17,12 @@
|
|||||||
package org.jetbrains.kotlin.idea.search.usagesSearch
|
package org.jetbrains.kotlin.idea.search.usagesSearch
|
||||||
|
|
||||||
import com.intellij.psi.PsiReference
|
import com.intellij.psi.PsiReference
|
||||||
import org.jetbrains.kotlin.psi.JetClassOrObject
|
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.*
|
import org.jetbrains.kotlin.idea.search.usagesSearch.*
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.UsagesSearchFilter.*
|
import org.jetbrains.kotlin.idea.search.usagesSearch.UsagesSearchFilter.*
|
||||||
import org.jetbrains.kotlin.psi.JetProperty
|
|
||||||
import org.jetbrains.kotlin.psi.JetNamedFunction
|
|
||||||
import java.util.Collections
|
import java.util.Collections
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
import org.jetbrains.kotlin.psi.JetNamedDeclaration
|
|
||||||
import com.intellij.psi.PsiNamedElement
|
import com.intellij.psi.PsiNamedElement
|
||||||
import org.jetbrains.kotlin.asJava.LightClassUtil
|
import org.jetbrains.kotlin.asJava.LightClassUtil
|
||||||
import org.jetbrains.kotlin.psi.JetParameter
|
|
||||||
import org.jetbrains.kotlin.psi.JetPsiUtil
|
|
||||||
import org.jetbrains.kotlin.asJava.LightClassUtil.PropertyAccessorsPsiMethods
|
import org.jetbrains.kotlin.asJava.LightClassUtil.PropertyAccessorsPsiMethods
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -37,9 +31,10 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
|||||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||||
import org.jetbrains.kotlin.lexer.JetTokens
|
import org.jetbrains.kotlin.lexer.JetTokens
|
||||||
import org.jetbrains.kotlin.idea.references.*
|
import org.jetbrains.kotlin.idea.references.*
|
||||||
import org.jetbrains.kotlin.psi.JetDeclaration
|
|
||||||
import com.intellij.util.containers.ContainerUtil
|
import com.intellij.util.containers.ContainerUtil
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.singletonOrEmptyList
|
||||||
|
|
||||||
val isTargetUsage = (PsiReference::matchesTarget).searchFilter
|
val isTargetUsage = (PsiReference::matchesTarget).searchFilter
|
||||||
|
|
||||||
@@ -68,6 +63,14 @@ fun PsiNamedElement.getAccessorNames(readable: Boolean = true, writable: Boolean
|
|||||||
return Collections.emptyList()
|
return Collections.emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public fun PsiNamedElement.getClassNameForDefaultObject(): String? {
|
||||||
|
return if (this is JetObjectDeclaration) {
|
||||||
|
getNonStrictParentOfType<JetClass>()?.getName()
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public fun PsiNamedElement.getSpecialNamesToSearch(): List<String> {
|
public fun PsiNamedElement.getSpecialNamesToSearch(): List<String> {
|
||||||
val name = getName()
|
val name = getName()
|
||||||
return when {
|
return when {
|
||||||
@@ -102,7 +105,7 @@ public abstract class UsagesSearchHelper<T : PsiNamedElement> {
|
|||||||
|
|
||||||
protected open fun makeWordList(target: UsagesSearchTarget<T>): List<String> {
|
protected open fun makeWordList(target: UsagesSearchTarget<T>): List<String> {
|
||||||
return with(target.element) {
|
return with(target.element) {
|
||||||
ContainerUtil.createMaybeSingletonList(getName()) + getAccessorNames() + getSpecialNamesToSearch()
|
getName().singletonOrEmptyList() + getAccessorNames() + getClassNameForDefaultObject().singletonOrEmptyList() + getSpecialNamesToSearch()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
// PSI_ELEMENT: org.jetbrains.kotlin.psi.JetObjectDeclaration
|
||||||
|
// OPTIONS: usages
|
||||||
|
|
||||||
|
import kotlin.platform.platformStatic
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
default <caret>object {
|
||||||
|
fun f() {
|
||||||
|
}
|
||||||
|
|
||||||
|
platformStatic fun s() {
|
||||||
|
}
|
||||||
|
|
||||||
|
val CONST = 42
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
class JavaUsage {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
System.out.println(Foo.CONST);
|
||||||
|
Foo.s();
|
||||||
|
Foo.Default.f();
|
||||||
|
Foo foo = new Foo(); // not usage of default object
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
Class static member access (3: 28) System.out.println(Foo.CONST);
|
||||||
|
Class static member access (4: 9) Foo.s();
|
||||||
|
Unclassified usage (5: 13) Foo.Default.f();
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// PSI_ELEMENT: org.jetbrains.kotlin.psi.JetObjectDeclaration
|
||||||
|
// OPTIONS: usages
|
||||||
|
class Foo {
|
||||||
|
default object <caret>Bar {
|
||||||
|
fun f() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
fun main(args: Array<String>) {
|
||||||
|
val p: Foo = Foo() // simple class usage
|
||||||
|
|
||||||
|
// default object usages
|
||||||
|
Foo.f()
|
||||||
|
val x = Foo
|
||||||
|
|
||||||
|
Foo.Bar.f()
|
||||||
|
val xx = Foo.Bar
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Nested class/object (5: 5) Foo.f()
|
||||||
|
Nested class/object (8: 9) Foo.Bar.f()
|
||||||
|
Unclassified usage (6: 13) val x = Foo
|
||||||
|
Unclassified usage (9: 18) val xx = Foo.Bar
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// PSI_ELEMENT: org.jetbrains.kotlin.psi.JetObjectDeclaration
|
||||||
|
// OPTIONS: usages
|
||||||
|
class Foo {
|
||||||
|
default <caret>object {
|
||||||
|
fun f() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
fun main(args: Array<String>) {
|
||||||
|
val p: Foo = Foo() // simple class usage
|
||||||
|
|
||||||
|
// default object usages
|
||||||
|
Foo.f()
|
||||||
|
val x = Foo
|
||||||
|
|
||||||
|
Foo.Default.f()
|
||||||
|
val xx = Foo.Default
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Nested class/object (5: 5) Foo.f()
|
||||||
|
Nested class/object (8: 9) Foo.Default.f()
|
||||||
|
Unclassified usage (6: 13) val x = Foo
|
||||||
|
Unclassified usage (9: 18) val xx = Foo.Default
|
||||||
@@ -38,6 +38,7 @@ public class JetFindUsagesTestGenerated extends AbstractJetFindUsagesTest {
|
|||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@InnerTestClasses({
|
@InnerTestClasses({
|
||||||
Kotlin.Conventions.class,
|
Kotlin.Conventions.class,
|
||||||
|
Kotlin.DefaultObject.class,
|
||||||
Kotlin.FindClassUsages.class,
|
Kotlin.FindClassUsages.class,
|
||||||
Kotlin.FindFunctionUsages.class,
|
Kotlin.FindFunctionUsages.class,
|
||||||
Kotlin.FindObjectUsages.class,
|
Kotlin.FindObjectUsages.class,
|
||||||
@@ -167,6 +168,33 @@ public class JetFindUsagesTestGenerated extends AbstractJetFindUsagesTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("idea/testData/findUsages/kotlin/defaultObject")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class DefaultObject extends AbstractJetFindUsagesTest {
|
||||||
|
public void testAllFilesPresentInDefaultObject() throws Exception {
|
||||||
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/findUsages/kotlin/defaultObject"), Pattern.compile("^(.+)\\.0\\.kt$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("javaUsage.0.kt")
|
||||||
|
public void testJavaUsage() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/findUsages/kotlin/defaultObject/javaUsage.0.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("named.0.kt")
|
||||||
|
public void testNamed() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/findUsages/kotlin/defaultObject/named.0.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simple.0.kt")
|
||||||
|
public void testSimple() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/findUsages/kotlin/defaultObject/simple.0.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("idea/testData/findUsages/kotlin/findClassUsages")
|
@TestMetadata("idea/testData/findUsages/kotlin/findClassUsages")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
Reference in New Issue
Block a user