From b2d1f8d323467b6484e776b5f762ca139a7042ef Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Tue, 13 Aug 2013 16:10:48 +0400 Subject: [PATCH] Add separate search of constructor usages --- .../dialogs/KotlinFindClassUsagesDialog.java | 28 ++++++- .../KotlinFindClassUsagesHandler.java | 84 ++++++++++++++++++- .../options/KotlinClassFindUsagesOptions.java | 16 ++++ .../findClassUsages/javaClassAllUsages.0.kt | 6 ++ .../findClassUsages/javaClassAllUsages.1.java | 13 +++ .../javaClassAllUsages.results.txt | 4 + .../javaClassConstructorUsages.0.kt | 6 ++ .../javaClassConstructorUsages.1.java | 13 +++ .../javaClassConstructorUsages.results.txt | 1 + ....kt => javaClassNonConstructorUsages.0.kt} | 1 + .../javaClassNonConstructorUsages.1.java | 13 +++ .../javaClassNonConstructorUsages.results.txt | 3 + .../findClassUsages/javaClassUsages.1.java | 5 -- .../javaClassUsages.results.txt | 1 - .../findClassUsages/kotlinClassAllUsages.0.kt | 13 +++ ...sUsages.1.kt => kotlinClassAllUsages.1.kt} | 8 +- .../kotlinClassAllUsages.results.txt | 13 +++ ...sages2.0.kt => kotlinClassAllUsages2.0.kt} | 1 + ...sages2.1.kt => kotlinClassAllUsages2.1.kt} | 0 ....txt => kotlinClassAllUsages2.results.txt} | 0 ...sages3.0.kt => kotlinClassAllUsages3.0.kt} | 1 + ...sages3.1.kt => kotlinClassAllUsages3.1.kt} | 0 ....txt => kotlinClassAllUsages3.results.txt} | 0 .../kotlinClassConstructorUsages.0.kt | 13 +++ .../kotlinClassConstructorUsages.1.kt | 38 +++++++++ .../kotlinClassConstructorUsages.results.txt | 2 + ...t => kotlinClassNonConstructorUsages.0.kt} | 1 + .../kotlinClassNonConstructorUsages.1.kt | 38 +++++++++ ...tlinClassNonConstructorUsages.results.txt} | 11 ++- .../findWithFilteringImports.0.kt | 1 + .../unresolvedAnnotation.0.kt | 1 + .../findUsages/AbstractJetFindUsagesTest.java | 32 ++++++- .../jet/findUsages/JetFindUsagesTest.java | 44 +++++++--- 33 files changed, 377 insertions(+), 34 deletions(-) create mode 100644 idea/testData/findUsages/findClassUsages/javaClassAllUsages.0.kt create mode 100644 idea/testData/findUsages/findClassUsages/javaClassAllUsages.1.java create mode 100644 idea/testData/findUsages/findClassUsages/javaClassAllUsages.results.txt create mode 100644 idea/testData/findUsages/findClassUsages/javaClassConstructorUsages.0.kt create mode 100644 idea/testData/findUsages/findClassUsages/javaClassConstructorUsages.1.java create mode 100644 idea/testData/findUsages/findClassUsages/javaClassConstructorUsages.results.txt rename idea/testData/findUsages/findClassUsages/{javaClassUsages.0.kt => javaClassNonConstructorUsages.0.kt} (83%) create mode 100644 idea/testData/findUsages/findClassUsages/javaClassNonConstructorUsages.1.java create mode 100644 idea/testData/findUsages/findClassUsages/javaClassNonConstructorUsages.results.txt delete mode 100644 idea/testData/findUsages/findClassUsages/javaClassUsages.1.java delete mode 100644 idea/testData/findUsages/findClassUsages/javaClassUsages.results.txt create mode 100644 idea/testData/findUsages/findClassUsages/kotlinClassAllUsages.0.kt rename idea/testData/findUsages/findClassUsages/{kotlinClassUsages.1.kt => kotlinClassAllUsages.1.kt} (83%) create mode 100644 idea/testData/findUsages/findClassUsages/kotlinClassAllUsages.results.txt rename idea/testData/findUsages/findClassUsages/{kotlinClassUsages2.0.kt => kotlinClassAllUsages2.0.kt} (73%) rename idea/testData/findUsages/findClassUsages/{kotlinClassUsages2.1.kt => kotlinClassAllUsages2.1.kt} (100%) rename idea/testData/findUsages/findClassUsages/{kotlinClassUsages2.results.txt => kotlinClassAllUsages2.results.txt} (100%) rename idea/testData/findUsages/findClassUsages/{kotlinClassUsages3.0.kt => kotlinClassAllUsages3.0.kt} (70%) rename idea/testData/findUsages/findClassUsages/{kotlinClassUsages3.1.kt => kotlinClassAllUsages3.1.kt} (100%) rename idea/testData/findUsages/findClassUsages/{kotlinClassUsages3.results.txt => kotlinClassAllUsages3.results.txt} (100%) create mode 100644 idea/testData/findUsages/findClassUsages/kotlinClassConstructorUsages.0.kt create mode 100644 idea/testData/findUsages/findClassUsages/kotlinClassConstructorUsages.1.kt create mode 100644 idea/testData/findUsages/findClassUsages/kotlinClassConstructorUsages.results.txt rename idea/testData/findUsages/findClassUsages/{kotlinClassUsages.0.kt => kotlinClassNonConstructorUsages.0.kt} (91%) create mode 100644 idea/testData/findUsages/findClassUsages/kotlinClassNonConstructorUsages.1.kt rename idea/testData/findUsages/findClassUsages/{kotlinClassUsages.results.txt => kotlinClassNonConstructorUsages.results.txt} (50%) diff --git a/idea/src/org/jetbrains/jet/plugin/findUsages/dialogs/KotlinFindClassUsagesDialog.java b/idea/src/org/jetbrains/jet/plugin/findUsages/dialogs/KotlinFindClassUsagesDialog.java index b9eb48a012d..09494b4e442 100644 --- a/idea/src/org/jetbrains/jet/plugin/findUsages/dialogs/KotlinFindClassUsagesDialog.java +++ b/idea/src/org/jetbrains/jet/plugin/findUsages/dialogs/KotlinFindClassUsagesDialog.java @@ -4,12 +4,13 @@ import com.intellij.find.FindBundle; import com.intellij.find.findUsages.FindClassUsagesDialog; import com.intellij.find.findUsages.FindUsagesHandler; import com.intellij.find.findUsages.FindUsagesOptions; +import com.intellij.find.findUsages.JavaClassFindUsagesOptions; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiClass; import com.intellij.ui.SimpleColoredComponent; +import com.intellij.ui.StateRestoringCheckBox; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.asJava.KotlinLightClassForExplicitDeclaration; -import org.jetbrains.jet.lang.psi.JetClass; import org.jetbrains.jet.plugin.JetBundle; import org.jetbrains.jet.plugin.findUsages.options.KotlinClassFindUsagesOptions; import org.jetbrains.jet.plugin.refactoring.JetRefactoringUtil; @@ -17,6 +18,8 @@ import org.jetbrains.jet.plugin.refactoring.JetRefactoringUtil; import javax.swing.*; public class KotlinFindClassUsagesDialog extends FindClassUsagesDialog { + private StateRestoringCheckBox constructorUsages; + public KotlinFindClassUsagesDialog( PsiClass klass, Project project, @@ -60,6 +63,13 @@ public class KotlinFindClassUsagesDialog extends FindClassUsagesDialog { JetBundle.message("find.what.derived.classes.checkbox") ); + constructorUsages = addCheckboxToPanel( + JetBundle.message("find.what.constructor.usages.checkbox"), + getFindUsagesOptions().searchConstructorUsages, + findWhatPanel, + true + ); + return findWhatPanel; } @@ -75,4 +85,20 @@ public class KotlinFindClassUsagesDialog extends FindClassUsagesDialog { coloredComponent.append(JetRefactoringUtil.formatClass(((KotlinLightClassForExplicitDeclaration) klass).getJetClassOrObject())); } } + + @Override + protected void update() { + super.update(); + if (!isOKActionEnabled() && constructorUsages.isSelected()) { + setOKActionEnabled(true); + } + } + + @Override + public void calcFindUsagesOptions(JavaClassFindUsagesOptions options) { + assert options instanceof KotlinClassFindUsagesOptions; + + super.calcFindUsagesOptions(options); + ((KotlinClassFindUsagesOptions) options).searchConstructorUsages = constructorUsages.isSelected(); + } } diff --git a/idea/src/org/jetbrains/jet/plugin/findUsages/handlers/KotlinFindClassUsagesHandler.java b/idea/src/org/jetbrains/jet/plugin/findUsages/handlers/KotlinFindClassUsagesHandler.java index 9e53ed9290b..cd30eb152ab 100644 --- a/idea/src/org/jetbrains/jet/plugin/findUsages/handlers/KotlinFindClassUsagesHandler.java +++ b/idea/src/org/jetbrains/jet/plugin/findUsages/handlers/KotlinFindClassUsagesHandler.java @@ -19,14 +19,26 @@ package org.jetbrains.jet.plugin.findUsages.handlers; import com.intellij.find.findUsages.AbstractFindUsagesDialog; import com.intellij.find.findUsages.FindUsagesOptions; import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiElement; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.search.searches.ReferencesSearch; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.usageView.UsageInfo; +import com.intellij.util.Processor; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.asJava.LightClassUtil; -import org.jetbrains.jet.lang.psi.JetClass; +import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.plugin.findUsages.KotlinFindUsagesHandlerFactory; import org.jetbrains.jet.plugin.findUsages.dialogs.KotlinFindClassUsagesDialog; +import org.jetbrains.jet.plugin.findUsages.options.KotlinClassFindUsagesOptions; +import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; + +import java.util.Collection; public class KotlinFindClassUsagesHandler extends KotlinFindUsagesHandler { public KotlinFindClassUsagesHandler(@NotNull JetClass jetClass, @NotNull KotlinFindUsagesHandlerFactory factory) { @@ -45,6 +57,72 @@ public class KotlinFindClassUsagesHandler extends KotlinFindUsagesHandler processor, @NotNull FindUsagesOptions options + ) { + KotlinClassFindUsagesOptions kotlinOptions = (KotlinClassFindUsagesOptions)options; + JetClass jetClass = (JetClass) element; + + if (kotlinOptions.isUsages || kotlinOptions.searchConstructorUsages) { + Collection references = ReferencesSearch.search( + new ReferencesSearch.SearchParameters(jetClass, kotlinOptions.searchScope, false) + ).findAll(); + for (PsiReference ref : references) { + boolean constructorUsage = isConstructorUsage(ref.getElement(), jetClass); + if ((constructorUsage && !kotlinOptions.searchConstructorUsages) + || (!constructorUsage && !kotlinOptions.isUsages)) continue; + + TextRange rangeInElement = ref.getRangeInElement(); + processor.process( + new UsageInfo(ref.getElement(), rangeInElement.getStartOffset(), rangeInElement.getEndOffset(), false) + ); + } + } + return true; + } + + private static DeclarationDescriptor getCallDescriptor(PsiElement element, BindingContext bindingContext) { + JetConstructorCalleeExpression constructorCalleeExpression = + PsiTreeUtil.getParentOfType(element, JetConstructorCalleeExpression.class); + if (constructorCalleeExpression != null) { + JetReferenceExpression classReference = constructorCalleeExpression.getConstructorReferenceExpression(); + return bindingContext.get(BindingContext.REFERENCE_TARGET, classReference); + } + + JetCallExpression callExpression = PsiTreeUtil.getParentOfType(element, JetCallExpression.class); + if (callExpression != null) { + JetExpression callee = callExpression.getCalleeExpression(); + if (callee instanceof JetReferenceExpression) { + return bindingContext.get(BindingContext.REFERENCE_TARGET, (JetReferenceExpression) callee); + } + } + + return null; + } + + private static boolean isConstructorUsage(PsiElement element, JetClass jetClass) { + PsiConstructorCall constructorCall = PsiTreeUtil.getParentOfType(element, PsiConstructorCall.class); + if (constructorCall != null && constructorCall == element.getParent()) { + PsiMethod constructor = constructorCall.resolveConstructor(); + if (constructor == null) return false; + + PsiClass constructorClass = constructor.getContainingClass(); + return constructorClass != null && constructorClass.getNavigationElement() == jetClass; + } + if (!(element instanceof JetElement)) return false; + + BindingContext bindingContext = + AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) element.getContainingFile()).getBindingContext(); + + DeclarationDescriptor descriptor = getCallDescriptor(element, bindingContext); + if (!(descriptor instanceof ConstructorDescriptor)) return false; + + DeclarationDescriptor containingDescriptor = descriptor.getContainingDeclaration(); + return containingDescriptor != null + && BindingContextUtils.descriptorToDeclaration(bindingContext, containingDescriptor) == jetClass; + } + @Override protected boolean isSearchForTextOccurencesAvailable(@NotNull PsiElement psiElement, boolean isSingleFile) { if (isSingleFile) return false; diff --git a/idea/src/org/jetbrains/jet/plugin/findUsages/options/KotlinClassFindUsagesOptions.java b/idea/src/org/jetbrains/jet/plugin/findUsages/options/KotlinClassFindUsagesOptions.java index ca47a170b5d..f6ededde079 100644 --- a/idea/src/org/jetbrains/jet/plugin/findUsages/options/KotlinClassFindUsagesOptions.java +++ b/idea/src/org/jetbrains/jet/plugin/findUsages/options/KotlinClassFindUsagesOptions.java @@ -5,7 +5,23 @@ import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; public class KotlinClassFindUsagesOptions extends JavaClassFindUsagesOptions { + public boolean searchConstructorUsages = true; + public KotlinClassFindUsagesOptions(@NotNull Project project) { super(project); } + + @Override + public boolean equals(Object o) { + return super.equals(o) + && o instanceof KotlinClassFindUsagesOptions + && ((KotlinClassFindUsagesOptions) o).searchConstructorUsages == searchConstructorUsages; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + (searchConstructorUsages ? 1 : 0); + return result; + } } diff --git a/idea/testData/findUsages/findClassUsages/javaClassAllUsages.0.kt b/idea/testData/findUsages/findClassUsages/javaClassAllUsages.0.kt new file mode 100644 index 00000000000..9c48ddc6e2a --- /dev/null +++ b/idea/testData/findUsages/findClassUsages/javaClassAllUsages.0.kt @@ -0,0 +1,6 @@ +// PSI_ELEMENT: org.jetbrains.jet.lang.psi.JetClass +// OPTIONS: usages, constructorUsages +package testing + +class Server() { +} diff --git a/idea/testData/findUsages/findClassUsages/javaClassAllUsages.1.java b/idea/testData/findUsages/findClassUsages/javaClassAllUsages.1.java new file mode 100644 index 00000000000..d455ac08377 --- /dev/null +++ b/idea/testData/findUsages/findClassUsages/javaClassAllUsages.1.java @@ -0,0 +1,13 @@ +import testing.*; + +class Client { + private Server myServer = new Server(); + + public void setServer(Server server) { + myServer = server; + } + + public Server getMyServer() { + return myServer; + } +} diff --git a/idea/testData/findUsages/findClassUsages/javaClassAllUsages.results.txt b/idea/testData/findUsages/findClassUsages/javaClassAllUsages.results.txt new file mode 100644 index 00000000000..aa27029830b --- /dev/null +++ b/idea/testData/findUsages/findClassUsages/javaClassAllUsages.results.txt @@ -0,0 +1,4 @@ +Field declaration (4: 13) private Server myServer = new Server(); +Method parameter declaration (6: 27) public void setServer(Server server) { +Method return type (10: 12) public Server getMyServer() { +New instance creation (4: 35) private Server myServer = new Server(); \ No newline at end of file diff --git a/idea/testData/findUsages/findClassUsages/javaClassConstructorUsages.0.kt b/idea/testData/findUsages/findClassUsages/javaClassConstructorUsages.0.kt new file mode 100644 index 00000000000..df5e70a9b05 --- /dev/null +++ b/idea/testData/findUsages/findClassUsages/javaClassConstructorUsages.0.kt @@ -0,0 +1,6 @@ +// PSI_ELEMENT: org.jetbrains.jet.lang.psi.JetClass +// OPTIONS: constructorUsages +package testing + +class Server() { +} diff --git a/idea/testData/findUsages/findClassUsages/javaClassConstructorUsages.1.java b/idea/testData/findUsages/findClassUsages/javaClassConstructorUsages.1.java new file mode 100644 index 00000000000..d455ac08377 --- /dev/null +++ b/idea/testData/findUsages/findClassUsages/javaClassConstructorUsages.1.java @@ -0,0 +1,13 @@ +import testing.*; + +class Client { + private Server myServer = new Server(); + + public void setServer(Server server) { + myServer = server; + } + + public Server getMyServer() { + return myServer; + } +} diff --git a/idea/testData/findUsages/findClassUsages/javaClassConstructorUsages.results.txt b/idea/testData/findUsages/findClassUsages/javaClassConstructorUsages.results.txt new file mode 100644 index 00000000000..61fd77b2bf8 --- /dev/null +++ b/idea/testData/findUsages/findClassUsages/javaClassConstructorUsages.results.txt @@ -0,0 +1 @@ +New instance creation (4: 35) private Server myServer = new Server(); \ No newline at end of file diff --git a/idea/testData/findUsages/findClassUsages/javaClassUsages.0.kt b/idea/testData/findUsages/findClassUsages/javaClassNonConstructorUsages.0.kt similarity index 83% rename from idea/testData/findUsages/findClassUsages/javaClassUsages.0.kt rename to idea/testData/findUsages/findClassUsages/javaClassNonConstructorUsages.0.kt index 4ab083d87c1..ca050edca44 100644 --- a/idea/testData/findUsages/findClassUsages/javaClassUsages.0.kt +++ b/idea/testData/findUsages/findClassUsages/javaClassNonConstructorUsages.0.kt @@ -1,4 +1,5 @@ // PSI_ELEMENT: org.jetbrains.jet.lang.psi.JetClass +// OPTIONS: usages package testing class Server() { diff --git a/idea/testData/findUsages/findClassUsages/javaClassNonConstructorUsages.1.java b/idea/testData/findUsages/findClassUsages/javaClassNonConstructorUsages.1.java new file mode 100644 index 00000000000..d455ac08377 --- /dev/null +++ b/idea/testData/findUsages/findClassUsages/javaClassNonConstructorUsages.1.java @@ -0,0 +1,13 @@ +import testing.*; + +class Client { + private Server myServer = new Server(); + + public void setServer(Server server) { + myServer = server; + } + + public Server getMyServer() { + return myServer; + } +} diff --git a/idea/testData/findUsages/findClassUsages/javaClassNonConstructorUsages.results.txt b/idea/testData/findUsages/findClassUsages/javaClassNonConstructorUsages.results.txt new file mode 100644 index 00000000000..b9ae0e614b1 --- /dev/null +++ b/idea/testData/findUsages/findClassUsages/javaClassNonConstructorUsages.results.txt @@ -0,0 +1,3 @@ +Field declaration (4: 13) private Server myServer = new Server(); +Method parameter declaration (6: 27) public void setServer(Server server) { +Method return type (10: 12) public Server getMyServer() { \ No newline at end of file diff --git a/idea/testData/findUsages/findClassUsages/javaClassUsages.1.java b/idea/testData/findUsages/findClassUsages/javaClassUsages.1.java deleted file mode 100644 index 30a18142b2a..00000000000 --- a/idea/testData/findUsages/findClassUsages/javaClassUsages.1.java +++ /dev/null @@ -1,5 +0,0 @@ -import testing.*; - -class Client { - private Server myServer; -} diff --git a/idea/testData/findUsages/findClassUsages/javaClassUsages.results.txt b/idea/testData/findUsages/findClassUsages/javaClassUsages.results.txt deleted file mode 100644 index a6a1b5a7518..00000000000 --- a/idea/testData/findUsages/findClassUsages/javaClassUsages.results.txt +++ /dev/null @@ -1 +0,0 @@ -Field declaration (4: 13) private Server myServer; \ No newline at end of file diff --git a/idea/testData/findUsages/findClassUsages/kotlinClassAllUsages.0.kt b/idea/testData/findUsages/findClassUsages/kotlinClassAllUsages.0.kt new file mode 100644 index 00000000000..b7e19ba83fe --- /dev/null +++ b/idea/testData/findUsages/findClassUsages/kotlinClassAllUsages.0.kt @@ -0,0 +1,13 @@ +// PSI_ELEMENT: org.jetbrains.jet.lang.psi.JetClass +// OPTIONS: usages, constructorUsages +package server + +open class Server { + class object { + val NAME = "Server" + } + + open fun work() { + println("Server") + } +} \ No newline at end of file diff --git a/idea/testData/findUsages/findClassUsages/kotlinClassUsages.1.kt b/idea/testData/findUsages/findClassUsages/kotlinClassAllUsages.1.kt similarity index 83% rename from idea/testData/findUsages/findClassUsages/kotlinClassUsages.1.kt rename to idea/testData/findUsages/findClassUsages/kotlinClassAllUsages.1.kt index b24ac3812cf..7195e473204 100644 --- a/idea/testData/findUsages/findClassUsages/kotlinClassUsages.1.kt +++ b/idea/testData/findUsages/findClassUsages/kotlinClassAllUsages.1.kt @@ -2,8 +2,8 @@ package client import server.Server -class Client: Server { - var nextServer: Server? = null +class Client: Server() { + var nextServer: Server? = new Server() val name = Server.NAME fun foo(s: Server) { @@ -21,6 +21,10 @@ class Client: Server { } } +object ClientObject: Server() { + +} + fun Client.bar(s: Server) { foo(s) } diff --git a/idea/testData/findUsages/findClassUsages/kotlinClassAllUsages.results.txt b/idea/testData/findUsages/findClassUsages/kotlinClassAllUsages.results.txt new file mode 100644 index 00000000000..43de735ee5f --- /dev/null +++ b/idea/testData/findUsages/findClassUsages/kotlinClassAllUsages.results.txt @@ -0,0 +1,13 @@ +Class/object property type (6: 21) var nextServer: Server? = new Server() +Function return types (14: 26) fun getNextServer(): Server? { +Function return types (36: 21) fun Any.asServer(): Server? { +Import directive (3: 15) import server.Server +Local variable type (10: 21) val server: Server = s +Nested class/object (7: 16) val name = Server.NAME +Parameter type (28: 19) fun Client.bar(s: Server) { +Parameter type (9: 16) fun foo(s: Server) { +Super type qualifier (19: 15) super.work() +Target type of 'as' operation (37: 40) return if (this is Server) this as Server else null +Target type of 'is' operation (37: 24) return if (this is Server) this as Server else null +Unclassified usage (24: 22) object ClientObject: Server() { +Unclassified usage (5: 15) class Client: Server() { \ No newline at end of file diff --git a/idea/testData/findUsages/findClassUsages/kotlinClassUsages2.0.kt b/idea/testData/findUsages/findClassUsages/kotlinClassAllUsages2.0.kt similarity index 73% rename from idea/testData/findUsages/findClassUsages/kotlinClassUsages2.0.kt rename to idea/testData/findUsages/findClassUsages/kotlinClassAllUsages2.0.kt index c24f7c8c6f3..dd1d217bc89 100644 --- a/idea/testData/findUsages/findClassUsages/kotlinClassUsages2.0.kt +++ b/idea/testData/findUsages/findClassUsages/kotlinClassAllUsages2.0.kt @@ -1,4 +1,5 @@ // PSI_ELEMENT: org.jetbrains.jet.lang.psi.JetClass +// OPTIONS: usages, constructorUsages package server annotation class X(val x: String) \ No newline at end of file diff --git a/idea/testData/findUsages/findClassUsages/kotlinClassUsages2.1.kt b/idea/testData/findUsages/findClassUsages/kotlinClassAllUsages2.1.kt similarity index 100% rename from idea/testData/findUsages/findClassUsages/kotlinClassUsages2.1.kt rename to idea/testData/findUsages/findClassUsages/kotlinClassAllUsages2.1.kt diff --git a/idea/testData/findUsages/findClassUsages/kotlinClassUsages2.results.txt b/idea/testData/findUsages/findClassUsages/kotlinClassAllUsages2.results.txt similarity index 100% rename from idea/testData/findUsages/findClassUsages/kotlinClassUsages2.results.txt rename to idea/testData/findUsages/findClassUsages/kotlinClassAllUsages2.results.txt diff --git a/idea/testData/findUsages/findClassUsages/kotlinClassUsages3.0.kt b/idea/testData/findUsages/findClassUsages/kotlinClassAllUsages3.0.kt similarity index 70% rename from idea/testData/findUsages/findClassUsages/kotlinClassUsages3.0.kt rename to idea/testData/findUsages/findClassUsages/kotlinClassAllUsages3.0.kt index 6a09805eae1..033f44a9ecb 100644 --- a/idea/testData/findUsages/findClassUsages/kotlinClassUsages3.0.kt +++ b/idea/testData/findUsages/findClassUsages/kotlinClassAllUsages3.0.kt @@ -1,4 +1,5 @@ // PSI_ELEMENT: org.jetbrains.jet.lang.psi.JetClass +// OPTIONS: usages, constructorUsages package server data class Data \ No newline at end of file diff --git a/idea/testData/findUsages/findClassUsages/kotlinClassUsages3.1.kt b/idea/testData/findUsages/findClassUsages/kotlinClassAllUsages3.1.kt similarity index 100% rename from idea/testData/findUsages/findClassUsages/kotlinClassUsages3.1.kt rename to idea/testData/findUsages/findClassUsages/kotlinClassAllUsages3.1.kt diff --git a/idea/testData/findUsages/findClassUsages/kotlinClassUsages3.results.txt b/idea/testData/findUsages/findClassUsages/kotlinClassAllUsages3.results.txt similarity index 100% rename from idea/testData/findUsages/findClassUsages/kotlinClassUsages3.results.txt rename to idea/testData/findUsages/findClassUsages/kotlinClassAllUsages3.results.txt diff --git a/idea/testData/findUsages/findClassUsages/kotlinClassConstructorUsages.0.kt b/idea/testData/findUsages/findClassUsages/kotlinClassConstructorUsages.0.kt new file mode 100644 index 00000000000..00816ad2af6 --- /dev/null +++ b/idea/testData/findUsages/findClassUsages/kotlinClassConstructorUsages.0.kt @@ -0,0 +1,13 @@ +// PSI_ELEMENT: org.jetbrains.jet.lang.psi.JetClass +// OPTIONS: constructorUsages +package server + +open class Server { + class object { + val NAME = "Server" + } + + open fun work() { + println("Server") + } +} \ No newline at end of file diff --git a/idea/testData/findUsages/findClassUsages/kotlinClassConstructorUsages.1.kt b/idea/testData/findUsages/findClassUsages/kotlinClassConstructorUsages.1.kt new file mode 100644 index 00000000000..7195e473204 --- /dev/null +++ b/idea/testData/findUsages/findClassUsages/kotlinClassConstructorUsages.1.kt @@ -0,0 +1,38 @@ +package client + +import server.Server + +class Client: Server() { + var nextServer: Server? = new Server() + val name = Server.NAME + + fun foo(s: Server) { + val server: Server = s + println("Server: $server") + } + + fun getNextServer(): Server? { + return nextServer + } + + override fun work() { + super.work() + println("Client") + } +} + +object ClientObject: Server() { + +} + +fun Client.bar(s: Server) { + foo(s) +} + +fun Client.hasNextServer(): Boolean { + return getNextServer() != null +} + +fun Any.asServer(): Server? { + return if (this is Server) this as Server else null +} \ No newline at end of file diff --git a/idea/testData/findUsages/findClassUsages/kotlinClassConstructorUsages.results.txt b/idea/testData/findUsages/findClassUsages/kotlinClassConstructorUsages.results.txt new file mode 100644 index 00000000000..ef5256be8ee --- /dev/null +++ b/idea/testData/findUsages/findClassUsages/kotlinClassConstructorUsages.results.txt @@ -0,0 +1,2 @@ +Unclassified usage (24: 22) object ClientObject: Server() { +Unclassified usage (5: 15) class Client: Server() { \ No newline at end of file diff --git a/idea/testData/findUsages/findClassUsages/kotlinClassUsages.0.kt b/idea/testData/findUsages/findClassUsages/kotlinClassNonConstructorUsages.0.kt similarity index 91% rename from idea/testData/findUsages/findClassUsages/kotlinClassUsages.0.kt rename to idea/testData/findUsages/findClassUsages/kotlinClassNonConstructorUsages.0.kt index 1ebe7bd4f2d..a94b7cd2728 100644 --- a/idea/testData/findUsages/findClassUsages/kotlinClassUsages.0.kt +++ b/idea/testData/findUsages/findClassUsages/kotlinClassNonConstructorUsages.0.kt @@ -1,4 +1,5 @@ // PSI_ELEMENT: org.jetbrains.jet.lang.psi.JetClass +// OPTIONS: usages package server open class Server { diff --git a/idea/testData/findUsages/findClassUsages/kotlinClassNonConstructorUsages.1.kt b/idea/testData/findUsages/findClassUsages/kotlinClassNonConstructorUsages.1.kt new file mode 100644 index 00000000000..7195e473204 --- /dev/null +++ b/idea/testData/findUsages/findClassUsages/kotlinClassNonConstructorUsages.1.kt @@ -0,0 +1,38 @@ +package client + +import server.Server + +class Client: Server() { + var nextServer: Server? = new Server() + val name = Server.NAME + + fun foo(s: Server) { + val server: Server = s + println("Server: $server") + } + + fun getNextServer(): Server? { + return nextServer + } + + override fun work() { + super.work() + println("Client") + } +} + +object ClientObject: Server() { + +} + +fun Client.bar(s: Server) { + foo(s) +} + +fun Client.hasNextServer(): Boolean { + return getNextServer() != null +} + +fun Any.asServer(): Server? { + return if (this is Server) this as Server else null +} \ No newline at end of file diff --git a/idea/testData/findUsages/findClassUsages/kotlinClassUsages.results.txt b/idea/testData/findUsages/findClassUsages/kotlinClassNonConstructorUsages.results.txt similarity index 50% rename from idea/testData/findUsages/findClassUsages/kotlinClassUsages.results.txt rename to idea/testData/findUsages/findClassUsages/kotlinClassNonConstructorUsages.results.txt index ce29933b911..5b7dc62aeed 100644 --- a/idea/testData/findUsages/findClassUsages/kotlinClassUsages.results.txt +++ b/idea/testData/findUsages/findClassUsages/kotlinClassNonConstructorUsages.results.txt @@ -1,12 +1,11 @@ -Class/object property type (6: 21) var nextServer: Server? = null +Class/object property type (6: 21) var nextServer: Server? = new Server() Function return types (14: 26) fun getNextServer(): Server? { -Function return types (32: 21) fun Any.asServer(): Server? { +Function return types (36: 21) fun Any.asServer(): Server? { Import directive (3: 15) import server.Server Local variable type (10: 21) val server: Server = s Nested class/object (7: 16) val name = Server.NAME -Parameter type (24: 19) fun Client.bar(s: Server) { +Parameter type (28: 19) fun Client.bar(s: Server) { Parameter type (9: 16) fun foo(s: Server) { Super type qualifier (19: 15) super.work() -Supertype (5: 15) class Client: Server { -Target type of 'as' operation (33: 40) return if (this is Server) this as Server else null -Target type of 'is' operation (33: 24) return if (this is Server) this as Server else null \ No newline at end of file +Target type of 'as' operation (37: 40) return if (this is Server) this as Server else null +Target type of 'is' operation (37: 24) return if (this is Server) this as Server else null \ No newline at end of file diff --git a/idea/testData/findUsages/findWithFilteringImports/findWithFilteringImports.0.kt b/idea/testData/findUsages/findWithFilteringImports/findWithFilteringImports.0.kt index c429d44b7e3..cc54430de25 100644 --- a/idea/testData/findUsages/findWithFilteringImports/findWithFilteringImports.0.kt +++ b/idea/testData/findUsages/findWithFilteringImports/findWithFilteringImports.0.kt @@ -1,5 +1,6 @@ // PSI_ELEMENT: org.jetbrains.jet.lang.psi.JetClass // FILTERING_RULES: org.jetbrains.jet.plugin.findUsages.JetImportFilteringRule +// OPTIONS: usages, constructorUsages package testing diff --git a/idea/testData/findUsages/unresolvedAnnotation/unresolvedAnnotation.0.kt b/idea/testData/findUsages/unresolvedAnnotation/unresolvedAnnotation.0.kt index 95c1ce43581..b88ad322d8e 100644 --- a/idea/testData/findUsages/unresolvedAnnotation/unresolvedAnnotation.0.kt +++ b/idea/testData/findUsages/unresolvedAnnotation/unresolvedAnnotation.0.kt @@ -1,4 +1,5 @@ // PSI_ELEMENT: org.jetbrains.jet.lang.psi.JetClass +// OPTIONS: usages, constructorUsages open class Foo { vv open val foo = 1 } \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/findUsages/AbstractJetFindUsagesTest.java b/idea/tests/org/jetbrains/jet/findUsages/AbstractJetFindUsagesTest.java index 3565b87f174..e85c90edefb 100644 --- a/idea/tests/org/jetbrains/jet/findUsages/AbstractJetFindUsagesTest.java +++ b/idea/tests/org/jetbrains/jet/findUsages/AbstractJetFindUsagesTest.java @@ -44,9 +44,11 @@ import com.intellij.util.CommonProcessors; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.InTextDirectivesUtils; +import org.jetbrains.jet.lang.psi.JetClass; import org.jetbrains.jet.lang.psi.JetNamedFunction; import org.jetbrains.jet.plugin.JetLightProjectDescriptor; import org.jetbrains.jet.plugin.PluginTestCaseBase; +import org.jetbrains.jet.plugin.findUsages.options.KotlinClassFindUsagesOptions; import org.jetbrains.jet.plugin.findUsages.options.KotlinMethodFindUsagesOptions; import java.io.File; @@ -58,6 +60,26 @@ import java.util.List; public abstract class AbstractJetFindUsagesTest extends LightCodeInsightFixtureTestCase { protected static enum OptionsParser { + CLASS { + @NotNull + @Override + public FindUsagesOptions parse(@NotNull String text, @NotNull Project project) { + KotlinClassFindUsagesOptions options = new KotlinClassFindUsagesOptions(project); + options.isUsages = false; + options.searchConstructorUsages = false; + for (String s : InTextDirectivesUtils.findListWithPrefixes(text, "// OPTIONS: ")) { + if (s.equals("usages")) { + options.isUsages = true; + } + else if (s.equals("constructorUsages")) { + options.searchConstructorUsages = true; + } + else fail("Invalid option: " + s); + } + + return options; + } + }, METHOD { @NotNull @Override @@ -68,16 +90,15 @@ public abstract class AbstractJetFindUsagesTest extends LightCodeInsightFixtureT if (s.equals("usages")) { options.isUsages = true; } - - if (s.equals("overrides")) { + else if (s.equals("overrides")) { options.isOverridingMethods = true; options.isImplementingMethods = true; } - - if (s.equals("overloadUsages")) { + else if (s.equals("overloadUsages")) { options.isIncludeOverloadUsages = true; options.isUsages = true; } + else fail("Invalid option: " + s); } return options; @@ -92,6 +113,9 @@ public abstract class AbstractJetFindUsagesTest extends LightCodeInsightFixtureT if (klass == JetNamedFunction.class) { return METHOD; } + if (klass == JetClass.class) { + return CLASS; + } return null; } diff --git a/idea/tests/org/jetbrains/jet/findUsages/JetFindUsagesTest.java b/idea/tests/org/jetbrains/jet/findUsages/JetFindUsagesTest.java index 9581ecedb12..a96e0acf2e4 100644 --- a/idea/tests/org/jetbrains/jet/findUsages/JetFindUsagesTest.java +++ b/idea/tests/org/jetbrains/jet/findUsages/JetFindUsagesTest.java @@ -43,24 +43,44 @@ public class JetFindUsagesTest extends AbstractJetFindUsagesTest { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/findUsages/findClassUsages"), Pattern.compile("^(.+).0.kt$"), true); } - @TestMetadata("javaClassUsages.0.kt") - public void testJavaClassUsages() throws Exception { - doTest("idea/testData/findUsages/findClassUsages/javaClassUsages.0.kt"); + @TestMetadata("javaClassAllUsages.0.kt") + public void testJavaClassAllUsages() throws Exception { + doTest("idea/testData/findUsages/findClassUsages/javaClassAllUsages.0.kt"); } - @TestMetadata("kotlinClassUsages.0.kt") - public void testKotlinClassUsages() throws Exception { - doTest("idea/testData/findUsages/findClassUsages/kotlinClassUsages.0.kt"); + @TestMetadata("javaClassConstructorUsages.0.kt") + public void testJavaClassConstructorUsages() throws Exception { + doTest("idea/testData/findUsages/findClassUsages/javaClassConstructorUsages.0.kt"); } - @TestMetadata("kotlinClassUsages2.0.kt") - public void testKotlinClassUsages2() throws Exception { - doTest("idea/testData/findUsages/findClassUsages/kotlinClassUsages2.0.kt"); + @TestMetadata("javaClassNonConstructorUsages.0.kt") + public void testJavaClassNonConstructorUsages() throws Exception { + doTest("idea/testData/findUsages/findClassUsages/javaClassNonConstructorUsages.0.kt"); } - @TestMetadata("kotlinClassUsages3.0.kt") - public void testKotlinClassUsages3() throws Exception { - doTest("idea/testData/findUsages/findClassUsages/kotlinClassUsages3.0.kt"); + @TestMetadata("kotlinClassAllUsages.0.kt") + public void testKotlinClassAllUsages() throws Exception { + doTest("idea/testData/findUsages/findClassUsages/kotlinClassAllUsages.0.kt"); + } + + @TestMetadata("kotlinClassAllUsages2.0.kt") + public void testKotlinClassAllUsages2() throws Exception { + doTest("idea/testData/findUsages/findClassUsages/kotlinClassAllUsages2.0.kt"); + } + + @TestMetadata("kotlinClassAllUsages3.0.kt") + public void testKotlinClassAllUsages3() throws Exception { + doTest("idea/testData/findUsages/findClassUsages/kotlinClassAllUsages3.0.kt"); + } + + @TestMetadata("kotlinClassConstructorUsages.0.kt") + public void testKotlinClassConstructorUsages() throws Exception { + doTest("idea/testData/findUsages/findClassUsages/kotlinClassConstructorUsages.0.kt"); + } + + @TestMetadata("kotlinClassNonConstructorUsages.0.kt") + public void testKotlinClassNonConstructorUsages() throws Exception { + doTest("idea/testData/findUsages/findClassUsages/kotlinClassNonConstructorUsages.0.kt"); } }