Implement search of class members usages

This commit is contained in:
Alexey Sedunov
2013-08-14 15:41:06 +04:00
parent b2d1f8d323
commit a7e46a4ba7
27 changed files with 497 additions and 1 deletions
@@ -18,7 +18,11 @@ package org.jetbrains.jet.plugin.findUsages.handlers;
import com.intellij.find.findUsages.AbstractFindUsagesDialog;
import com.intellij.find.findUsages.FindUsagesOptions;
import com.intellij.find.findUsages.JavaClassFindUsagesOptions;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ReadActionProcessor;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.search.searches.ReferencesSearch;
@@ -64,6 +68,14 @@ public class KotlinFindClassUsagesHandler extends KotlinFindUsagesHandler<JetCla
KotlinClassFindUsagesOptions kotlinOptions = (KotlinClassFindUsagesOptions)options;
JetClass jetClass = (JetClass) element;
PsiClass lightClass = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass>() {
@Override
public PsiClass compute() {
return LightClassUtil.getPsiClass(getElement());
}
});
if (lightClass == null) return true;
if (kotlinOptions.isUsages || kotlinOptions.searchConstructorUsages) {
Collection<PsiReference> references = ReferencesSearch.search(
new ReferencesSearch.SearchParameters(jetClass, kotlinOptions.searchScope, false)
@@ -79,7 +91,8 @@ public class KotlinFindClassUsagesHandler extends KotlinFindUsagesHandler<JetCla
);
}
}
return true;
return processDeclarationsUsages(jetClass, processor, kotlinOptions);
}
private static DeclarationDescriptor getCallDescriptor(PsiElement element, BindingContext bindingContext) {
@@ -101,6 +114,27 @@ public class KotlinFindClassUsagesHandler extends KotlinFindUsagesHandler<JetCla
return null;
}
private static boolean processDeclarationsUsages(
@NotNull JetClass klass,
@NotNull final Processor<UsageInfo> processor,
@NotNull final JavaClassFindUsagesOptions options
) {
for (JetDeclaration declaration : klass.getDeclarations()) {
if (declaration instanceof JetNamedFunction && options.isMethodsUsages
|| declaration instanceof JetProperty && options.isFieldsUsages) {
if (!ReferencesSearch.search(new ReferencesSearch.SearchParameters(declaration, options.searchScope, false)).forEach(
new ReadActionProcessor<PsiReference>() {
@Override
public boolean processInReadAction(PsiReference ref) {
return processUsage(processor, ref, options);
}
}
)) return false;
}
}
return true;
}
private static boolean isConstructorUsage(PsiElement element, JetClass jetClass) {
PsiConstructorCall constructorCall = PsiTreeUtil.getParentOfType(element, PsiConstructorCall.class);
if (constructorCall != null && constructorCall == element.getParent()) {
@@ -0,0 +1,37 @@
// PSI_ELEMENT: org.jetbrains.jet.lang.psi.JetClass
// OPTIONS: functionUsages
trait <caret>X {
val a: String
get() {
return ""
}
var b: Int
get () {
return 0
}
set (value: Int) {
}
fun foo(s: String) {
println(s)
}
}
open class A: X {
override val a: String
get() {
return "?"
}
override var b: Int
get () {
return 1
}
set (value: Int) {
println(value)
}
override fun foo(s: String) {
println("!$s!")
}
}
@@ -0,0 +1,13 @@
class Usages {
void foo(A a) {
a.foo("");
System.out.println(a.getA() + " " + a.getB());
a.setB(12);
}
void foo(X x) {
x.foo("");
System.out.println(x.getA() + " " + x.getB());
x.setB(12);
}
}
@@ -0,0 +1 @@
Unclassified usage (9: 11) x.foo("");
@@ -0,0 +1,37 @@
// PSI_ELEMENT: org.jetbrains.jet.lang.psi.JetClass
// OPTIONS: functionUsages
trait X {
val a: String
get() {
return ""
}
var b: Int
get () {
return 0
}
set (value: Int) {
}
fun foo(s: String) {
println(s)
}
}
open class <caret>A: X {
override val a: String
get() {
return "?"
}
override var b: Int
get () {
return 1
}
set (value: Int) {
println(value)
}
override fun foo(s: String) {
println("!$s!")
}
}
@@ -0,0 +1,13 @@
class Usages {
void foo(A a) {
a.foo("");
System.out.println(a.getA() + " " + a.getB());
a.setB(12);
}
void foo(X x) {
x.foo("");
System.out.println(x.getA() + " " + x.getB());
x.setB(12);
}
}
@@ -0,0 +1 @@
Unclassified usage (3: 11) a.foo("");
@@ -0,0 +1,37 @@
// PSI_ELEMENT: org.jetbrains.jet.lang.psi.JetClass
// OPTIONS: propertyUsages
trait <caret>X {
val a: String
get() {
return ""
}
var b: Int
get () {
return 0
}
set (value: Int) {
}
fun foo(s: String) {
println(s)
}
}
open class A: X {
override val a: String
get() {
return "?"
}
override var b: Int
get () {
return 1
}
set (value: Int) {
println(value)
}
override fun foo(s: String) {
println("!$s!")
}
}
@@ -0,0 +1,13 @@
class Usages {
void foo(A a) {
a.foo("");
System.out.println(a.getA() + " " + a.getB());
a.setB(12);
}
void foo(X x) {
x.foo("");
System.out.println(x.getA() + " " + x.getB());
x.setB(12);
}
}
@@ -0,0 +1,3 @@
Unclassified usage (10: 30) System.out.println(x.getA() + " " + x.getB());
Unclassified usage (10: 47) System.out.println(x.getA() + " " + x.getB());
Unclassified usage (11: 11) x.setB(12);
@@ -0,0 +1,37 @@
// PSI_ELEMENT: org.jetbrains.jet.lang.psi.JetClass
// OPTIONS: propertyUsages
trait X {
val a: String
get() {
return ""
}
var b: Int
get () {
return 0
}
set (value: Int) {
}
fun foo(s: String) {
println(s)
}
}
open class <caret>A: X {
override val a: String
get() {
return "?"
}
override var b: Int
get () {
return 1
}
set (value: Int) {
println(value)
}
override fun foo(s: String) {
println("!$s!")
}
}
@@ -0,0 +1,13 @@
class Usages {
void foo(A a) {
a.foo("");
System.out.println(a.getA() + " " + a.getB());
a.setB(12);
}
void foo(X x) {
x.foo("");
System.out.println(x.getA() + " " + x.getB());
x.setB(12);
}
}
@@ -0,0 +1,3 @@
Unclassified usage (4: 30) System.out.println(a.getA() + " " + a.getB());
Unclassified usage (4: 47) System.out.println(a.getA() + " " + a.getB());
Unclassified usage (5: 11) a.setB(12);
@@ -0,0 +1,37 @@
// PSI_ELEMENT: org.jetbrains.jet.lang.psi.JetClass
// OPTIONS: functionUsages
trait <caret>X {
val a: String
get() {
return ""
}
var b: Int
get () {
return 0
}
set (value: Int) {
}
fun foo(s: String) {
println(s)
}
}
open class A: X {
override val a: String
get() {
return "?"
}
override var b: Int
get () {
return 1
}
set (value: Int) {
println(value)
}
override fun foo(s: String) {
println("!$s!")
}
}
@@ -0,0 +1,13 @@
class Usages {
fun foo(a: A) {
a.foo("")
println("${a.a} ${a.b}")
a.b = 12
}
fun foo(x: X) {
x.foo("")
println("${x.a} ${x.b}")
x.b = 12
}
}
@@ -0,0 +1 @@
Function call (9: 11) x.foo("")
@@ -0,0 +1,37 @@
// PSI_ELEMENT: org.jetbrains.jet.lang.psi.JetClass
// OPTIONS: functionUsages
trait X {
val a: String
get() {
return ""
}
var b: Int
get () {
return 0
}
set (value: Int) {
}
fun foo(s: String) {
println(s)
}
}
open class <caret>A: X {
override val a: String
get() {
return "?"
}
override var b: Int
get () {
return 1
}
set (value: Int) {
println(value)
}
override fun foo(s: String) {
println("!$s!")
}
}
@@ -0,0 +1,13 @@
class Usages {
fun foo(a: A) {
a.foo("")
println("${a.a} ${a.b}")
a.b = 12
}
fun foo(x: X) {
x.foo("")
println("${x.a} ${x.b}")
x.b = 12
}
}
@@ -0,0 +1 @@
Function call (3: 11) a.foo("")
@@ -0,0 +1,37 @@
// PSI_ELEMENT: org.jetbrains.jet.lang.psi.JetClass
// OPTIONS: propertyUsages
trait <caret>X {
val a: String
get() {
return ""
}
var b: Int
get () {
return 0
}
set (value: Int) {
}
fun foo(s: String) {
println(s)
}
}
open class A: X {
override val a: String
get() {
return "?"
}
override var b: Int
get () {
return 1
}
set (value: Int) {
println(value)
}
override fun foo(s: String) {
println("!$s!")
}
}
@@ -0,0 +1,13 @@
class Usages {
fun foo(a: A) {
a.foo("")
println("${a.a} ${a.b}")
a.b = 12
}
fun foo(x: X) {
x.foo("")
println("${x.a} ${x.b}")
x.b = 12
}
}
@@ -0,0 +1,3 @@
Selector (10: 22) println("${x.a} ${x.b}")
Selector (10: 29) println("${x.a} ${x.b}")
Selector (11: 11) x.b = 12
@@ -0,0 +1,37 @@
// PSI_ELEMENT: org.jetbrains.jet.lang.psi.JetClass
// OPTIONS: propertyUsages
trait X {
val a: String
get() {
return ""
}
var b: Int
get () {
return 0
}
set (value: Int) {
}
fun foo(s: String) {
println(s)
}
}
open class <caret>A: X {
override val a: String
get() {
return "?"
}
override var b: Int
get () {
return 1
}
set (value: Int) {
println(value)
}
override fun foo(s: String) {
println("!$s!")
}
}
@@ -0,0 +1,13 @@
class Usages {
fun foo(a: A) {
a.foo("")
println("${a.a} ${a.b}")
a.b = 12
}
fun foo(x: X) {
x.foo("")
println("${x.a} ${x.b}")
x.b = 12
}
}
@@ -0,0 +1,3 @@
Selector (4: 22) println("${a.a} ${a.b}")
Selector (4: 29) println("${a.a} ${a.b}")
Selector (5: 11) a.b = 12
@@ -74,6 +74,12 @@ public abstract class AbstractJetFindUsagesTest extends LightCodeInsightFixtureT
else if (s.equals("constructorUsages")) {
options.searchConstructorUsages = true;
}
else if (s.equals("functionUsages")) {
options.isMethodsUsages = true;
}
else if (s.equals("propertyUsages")) {
options.isFieldsUsages = true;
}
else fail("Invalid option: " + s);
}
@@ -53,11 +53,31 @@ public class JetFindUsagesTest extends AbstractJetFindUsagesTest {
doTest("idea/testData/findUsages/findClassUsages/javaClassConstructorUsages.0.kt");
}
@TestMetadata("javaClassFunctionUsages1.0.kt")
public void testJavaClassFunctionUsages1() throws Exception {
doTest("idea/testData/findUsages/findClassUsages/javaClassFunctionUsages1.0.kt");
}
@TestMetadata("javaClassFunctionUsages2.0.kt")
public void testJavaClassFunctionUsages2() throws Exception {
doTest("idea/testData/findUsages/findClassUsages/javaClassFunctionUsages2.0.kt");
}
@TestMetadata("javaClassNonConstructorUsages.0.kt")
public void testJavaClassNonConstructorUsages() throws Exception {
doTest("idea/testData/findUsages/findClassUsages/javaClassNonConstructorUsages.0.kt");
}
@TestMetadata("javaClassPropertyUsages1.0.kt")
public void testJavaClassPropertyUsages1() throws Exception {
doTest("idea/testData/findUsages/findClassUsages/javaClassPropertyUsages1.0.kt");
}
@TestMetadata("javaClassPropertyUsages2.0.kt")
public void testJavaClassPropertyUsages2() throws Exception {
doTest("idea/testData/findUsages/findClassUsages/javaClassPropertyUsages2.0.kt");
}
@TestMetadata("kotlinClassAllUsages.0.kt")
public void testKotlinClassAllUsages() throws Exception {
doTest("idea/testData/findUsages/findClassUsages/kotlinClassAllUsages.0.kt");
@@ -78,11 +98,31 @@ public class JetFindUsagesTest extends AbstractJetFindUsagesTest {
doTest("idea/testData/findUsages/findClassUsages/kotlinClassConstructorUsages.0.kt");
}
@TestMetadata("kotlinClassFunctionUsages1.0.kt")
public void testKotlinClassFunctionUsages1() throws Exception {
doTest("idea/testData/findUsages/findClassUsages/kotlinClassFunctionUsages1.0.kt");
}
@TestMetadata("kotlinClassFunctionUsages2.0.kt")
public void testKotlinClassFunctionUsages2() throws Exception {
doTest("idea/testData/findUsages/findClassUsages/kotlinClassFunctionUsages2.0.kt");
}
@TestMetadata("kotlinClassNonConstructorUsages.0.kt")
public void testKotlinClassNonConstructorUsages() throws Exception {
doTest("idea/testData/findUsages/findClassUsages/kotlinClassNonConstructorUsages.0.kt");
}
@TestMetadata("kotlinClassPropertyUsages1.0.kt")
public void testKotlinClassPropertyUsages1() throws Exception {
doTest("idea/testData/findUsages/findClassUsages/kotlinClassPropertyUsages1.0.kt");
}
@TestMetadata("kotlinClassPropertyUsages2.0.kt")
public void testKotlinClassPropertyUsages2() throws Exception {
doTest("idea/testData/findUsages/findClassUsages/kotlinClassPropertyUsages2.0.kt");
}
}
@TestMetadata("idea/testData/findUsages/findMethodUsages")