| /* |
| * Copyright 2000-2013 JetBrains s.r.o. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.jetbrains.plugins.groovy.lang.findUsages |
| |
| import com.intellij.codeInsight.TargetElementUtilBase |
| import com.intellij.find.FindManager |
| import com.intellij.find.findUsages.FindUsagesHandler |
| import com.intellij.find.findUsages.FindUsagesManager |
| import com.intellij.find.findUsages.FindUsagesOptions |
| import com.intellij.find.impl.FindManagerImpl |
| import com.intellij.psi.* |
| import com.intellij.psi.search.GlobalSearchScope |
| import com.intellij.psi.search.searches.DirectClassInheritorsSearch |
| import com.intellij.psi.search.searches.MethodReferencesSearch |
| import com.intellij.psi.search.searches.ReferencesSearch |
| import com.intellij.psi.search.searches.SuperMethodsSearch |
| import com.intellij.psi.util.MethodSignatureBackedByPsiMethod |
| import com.intellij.psi.util.PsiTreeUtil |
| import com.intellij.usageView.UsageInfo |
| import com.intellij.util.CommonProcessors |
| import com.intellij.util.Query |
| import org.jetbrains.plugins.groovy.LightGroovyTestCase |
| import org.jetbrains.plugins.groovy.lang.psi.GroovyFile |
| import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition |
| import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod |
| import org.jetbrains.plugins.groovy.util.TestUtils |
| |
| /** |
| * @author ven |
| */ |
| public class FindUsagesTest extends LightGroovyTestCase { |
| @Override |
| protected String getBasePath() { |
| return "${TestUtils.testDataPath}findUsages/${getTestName(true)}/"; |
| } |
| |
| private void doConstructorTest(String filePath, int expectedCount) throws Throwable { |
| myFixture.configureByFile(filePath); |
| final PsiElement elementAt = myFixture.file.findElementAt(myFixture.editor.caretModel.offset); |
| final PsiMethod method = PsiTreeUtil.getParentOfType(elementAt, PsiMethod.class); |
| assertNotNull(method); |
| assertTrue(method.constructor); |
| final Query<PsiReference> query = ReferencesSearch.search(method); |
| |
| assertEquals(expectedCount, query.findAll().size()); |
| } |
| |
| public void testDerivedClass() throws Throwable { |
| myFixture.configureByFiles("p/B.java", "A.groovy"); |
| final PsiElement elementAt = myFixture.file.findElementAt(myFixture.editor.caretModel.offset); |
| final PsiClass clazz = PsiTreeUtil.getParentOfType(elementAt, PsiClass.class); |
| assertNotNull(clazz); |
| |
| final GlobalSearchScope projectScope = GlobalSearchScope.projectScope(myFixture.project); |
| final Query<PsiClass> query = DirectClassInheritorsSearch.search(clazz, projectScope); |
| |
| assertEquals(1, query.findAll().size()); |
| } |
| |
| public void testConstructor1() throws Throwable { |
| doConstructorTest("A.groovy", 2); |
| } |
| |
| public void testConstructorUsageInNewExpression() throws Throwable { |
| myFixture.configureByFile("ConstructorUsageInNewExpression.groovy"); |
| final PsiElement resolved = TargetElementUtilBase.findTargetElement(myFixture.editor, TargetElementUtilBase.instance.referenceSearchFlags); |
| assertNotNull("Could not resolve reference", resolved); |
| final GlobalSearchScope projectScope = GlobalSearchScope.projectScope(myFixture.project); |
| assertEquals(2, MethodReferencesSearch.search((PsiMethod)resolved, projectScope, true).findAll().size()); |
| assertEquals(4, MethodReferencesSearch.search((PsiMethod)resolved, projectScope, false).findAll().size()); |
| } |
| |
| public void testGotoConstructor() throws Throwable { |
| myFixture.configureByFile("GotoConstructor.groovy"); |
| final PsiElement target = TargetElementUtilBase.findTargetElement(myFixture.editor, TargetElementUtilBase.instance.referenceSearchFlags); |
| assertNotNull(target); |
| assertInstanceOf(target, PsiMethod.class); |
| assertTrue(((PsiMethod)target).constructor); |
| assertTrue(((PsiMethod)target).parameterList.parametersCount == 0); |
| } |
| |
| public void testSetter1() throws Throwable { |
| doTestImpl("A.groovy", 2); |
| } |
| |
| public void testGetter1() throws Throwable { |
| doTestImpl("A.groovy", 1); |
| } |
| |
| public void testProperty1() throws Throwable { |
| doTestImpl("A.groovy", 2); |
| } |
| |
| public void testProperty2() throws Throwable { |
| doTestImpl("A.groovy", 1); |
| } |
| |
| public void testEscapedReference() throws Throwable { |
| doTestImpl("A.groovy", 1); |
| } |
| |
| public void testKeywordPropertyName() throws Throwable { |
| doTestImpl("A.groovy", 1); |
| } |
| |
| public void testTypeAlias() throws Throwable { |
| doTestImpl("A.groovy", 2); |
| } |
| |
| public void testMethodAlias() throws Throwable { |
| doTestImpl("A.groovy", 2); |
| } |
| |
| public void testAliasImportedProperty() throws Throwable { |
| myFixture.addFileToProject("Abc.groovy", "class Abc {static def foo}"); |
| doTestImpl("A.groovy", 5); |
| } |
| |
| public void testGetterWhenAliasedImportedProperty() throws Throwable { |
| myFixture.addFileToProject("Abc.groovy", "class Abc {static def foo}"); |
| doTestImpl("A.groovy", 5); |
| } |
| |
| public void testForInParameter() throws Throwable { |
| doTestImpl("A.groovy", 1); |
| } |
| |
| public void testSyntheticParameter() throws Throwable { |
| doTestImpl("A.groovy", 1); |
| } |
| |
| public void testOverridingMethodUsage() throws Throwable { |
| doTestImpl("OverridingMethodUsage.groovy", 2); |
| } |
| |
| public void testDynamicUsages() { |
| doTestImpl("DynamicUsages.groovy", 2); |
| } |
| |
| public void testAnnotatedMemberSearch() throws Throwable { |
| |
| final PsiReference ref = myFixture.getReferenceAtCaretPosition("A.groovy"); |
| assertNotNull("Did not find reference", ref); |
| final PsiElement resolved = ref.resolve(); |
| assertNotNull("Could not resolve reference", resolved); |
| |
| final Query<PsiReference> query; |
| final GlobalSearchScope projectScope = GlobalSearchScope.projectScope(myFixture.getProject()); |
| if (resolved instanceof PsiMethod) { |
| query = MethodReferencesSearch.search((PsiMethod)resolved, projectScope, true); |
| } |
| else { |
| query = ReferencesSearch.search(resolved, projectScope); |
| } |
| |
| assertEquals(1, query.findAll().size()); |
| } |
| |
| private void doTestImpl(String filePath, int expectedUsagesCount) { |
| myFixture.configureByFile(filePath); |
| assertUsageCount(expectedUsagesCount); |
| } |
| |
| private void assertUsageCount(int expectedUsagesCount) { |
| final PsiElement resolved = TargetElementUtilBase.findTargetElement(myFixture.getEditor(), |
| TargetElementUtilBase.getInstance().getReferenceSearchFlags()); |
| assertNotNull("Could not resolve reference", resolved); |
| doFind(expectedUsagesCount, resolved); |
| } |
| |
| private void doFind(int expectedUsagesCount, PsiElement resolved) { |
| FindUsagesManager findUsagesManager = ((FindManagerImpl)FindManager.getInstance(getProject())).getFindUsagesManager(); |
| FindUsagesHandler handler = findUsagesManager.getFindUsagesHandler(resolved, false); |
| assertNotNull(handler); |
| final FindUsagesOptions options = handler.getFindUsagesOptions(); |
| final CommonProcessors.CollectProcessor<UsageInfo> processor = new CommonProcessors.CollectProcessor<UsageInfo>(); |
| for (PsiElement element : handler.getPrimaryElements()) { |
| handler.processElementUsages(element, processor, options); |
| } |
| for (PsiElement element : handler.getSecondaryElements()) { |
| handler.processElementUsages(element, processor, options); |
| } |
| assertEquals(expectedUsagesCount, processor.getResults().size()); |
| } |
| |
| public void testGdkMethod() throws Exception { |
| myFixture.configureByText("a.groovy", "[''].ea<caret>ch {}"); |
| assertUsageCount(1); |
| } |
| |
| public void testGDKSuperMethodSearch() throws Exception { |
| doSuperMethodTest("T"); |
| } |
| |
| public void testGDKSuperMethodForMapSearch() throws Exception { |
| doSuperMethodTest("Map"); |
| } |
| |
| public void testLabels() throws Exception { |
| myFixture.configureByFile(getTestName(false) + ".groovy"); |
| final GroovyFile file = (GroovyFile)myFixture.getFile(); |
| assertEquals(2, ReferencesSearch.search(file.getTopStatements()[0]).findAll().size()); |
| } |
| |
| public void testConstructorUsageInAnonymousClass() { |
| doTestImpl("A.groovy", 1); |
| } |
| |
| void testCapitalizedProperty1() { |
| doTest(1, '''\ |
| class A { |
| def Pro<caret>p |
| } |
| |
| new A().Prop''') |
| } |
| |
| void testCapitalizedProperty2() { |
| doTest(1, '''\ |
| class A { |
| def Pro<caret>p |
| } |
| |
| new A().prop''') |
| } |
| |
| void testCapitalizedProperty3() { |
| doTest(0, '''\ |
| class A { |
| def pro<caret>p |
| } |
| |
| new A().Prop''') |
| } |
| |
| void testCapitalizedProperty4() { |
| doTest(1, '''\ |
| class A { |
| def p<caret>rop |
| } |
| |
| new A().prop''') |
| } |
| |
| void testCategoryProperty() { |
| doTest(1, '''\ |
| class Cat { |
| static def ge<caret>tFoo(Number s) {'num'} |
| } |
| |
| use(Cat) { |
| 2.foo |
| } |
| ''') |
| } |
| |
| void "test do not report dynamic usages when argument count differs"() { |
| doTest(0, '''\ |
| class A { |
| static void start<caret>sWith(String s, String s1, boolean b) {} |
| def c = { it.startsWith("aaa") } |
| } |
| ''') |
| } |
| |
| void 'test literal names'() { |
| doTest(1, '''\ |
| def 'f<caret>oo'() {} |
| |
| 'foo'() |
| ''') |
| } |
| |
| void 'test literal name with escaping'() { |
| doTest(1, '''\ |
| def 'f<caret>oo \\''() {} |
| |
| 'foo \\''() |
| ''') |
| } |
| |
| void 'test literal name with escaping and other quotes'() { |
| doTest(1, '''\ |
| def 'f<caret>oo \\''() {} |
| |
| "foo '"() |
| ''') |
| } |
| |
| //todo |
| void '_test literal name with escaping and other quotes 2'() { |
| doTest(1, '''\ |
| def '<caret>\\''() {} |
| |
| "'"() |
| ''') |
| } |
| |
| |
| void testResolveBinding1() { |
| doTest(2, '''\ |
| abc = 4 |
| |
| print ab<caret>c |
| ''') |
| } |
| |
| void testResolveBinding2() { |
| doTest(2, '''\ |
| print ab<caret>c |
| |
| abc = 4 |
| ''', ) |
| } |
| |
| void testResolveBinding3() { |
| doTest(2, '''\ |
| a<caret>bc = 4 |
| |
| print abc |
| ''', ) |
| } |
| |
| void testResolveBinding4() { |
| doTest(2, '''\ |
| print abc |
| |
| a<caret>bc = 4 |
| ''', ) |
| } |
| |
| |
| void testResolveBinding5() { |
| doTest(2, '''\ |
| def foo() { |
| abc = 4 |
| } |
| |
| def bar() { |
| print ab<caret>c |
| } |
| ''', ) |
| } |
| |
| void testResolveBinding6() { |
| doTest(2, '''\ |
| def foo() { |
| print ab<caret>c |
| } |
| |
| def bar() { |
| abc = 4 |
| } |
| ''', ) |
| } |
| |
| void testResolveBinding7() { |
| doTest(2, '''\ |
| def foo() { |
| a<caret>bc = 4 |
| } |
| |
| def bar() { |
| print abc |
| } |
| ''', ) |
| } |
| |
| void testResolveBinding8() { |
| doTest(2, '''\ |
| def foo() { |
| print abc |
| } |
| |
| def bar() { |
| a<caret>bc = 4 |
| } |
| ''', ) |
| } |
| |
| void testBinding9() { |
| doTest(4, '''\ |
| a<caret>a = 5 |
| print aa |
| aa = 6 |
| print aa |
| ''', ) |
| } |
| |
| void testBinding10() { |
| doTest(4, '''\ |
| aa = 5 |
| print a<caret>a |
| aa = 6 |
| print aa |
| ''', ) |
| } |
| |
| void testBinding11() { |
| doTest(4, '''\ |
| aa = 5 |
| print aa |
| a<caret>a = 6 |
| print aa |
| ''', ) |
| } |
| |
| void testBinding12() { |
| doTest(4, '''\ |
| aa = 5 |
| print aa |
| aa = 6 |
| print a<caret>a |
| ''', ) |
| } |
| |
| void testTraitField() { |
| doTest(4, ''' |
| trait T { |
| public int fi<caret>eld = 4 |
| |
| def bar() { |
| print field |
| print T__field |
| } |
| } |
| |
| class C implements T { |
| def abc() { |
| print field //unresolved |
| print T__field |
| } |
| } |
| |
| |
| new C().T__field |
| new C().field //unresolved |
| |
| ''') |
| } |
| |
| private void doSuperMethodTest(String... firstParameterTypes) { |
| myFixture.configureByFile(getTestName(false) + ".groovy"); |
| final GroovyFile file = (GroovyFile)myFixture.getFile(); |
| final GrTypeDefinition psiClass = (GrTypeDefinition)file.getClasses()[0]; |
| final GrMethod method = (GrMethod)psiClass.getMethods()[0]; |
| final Collection<MethodSignatureBackedByPsiMethod> superMethods = SuperMethodsSearch.search(method, null, true, true).findAll(); |
| assertEquals(firstParameterTypes.length, superMethods.size()); |
| |
| final Iterator<MethodSignatureBackedByPsiMethod> iterator = superMethods.iterator(); |
| for (String firstParameterType : firstParameterTypes) { |
| final MethodSignatureBackedByPsiMethod methodSignature = iterator.next(); |
| final PsiMethod superMethod = methodSignature.getMethod(); |
| final String className = superMethod.getContainingClass().getName(); |
| assertEquals("DefaultGroovyMethods", className); |
| final String actualParameterType = ((PsiClassType)methodSignature.getParameterTypes()[0]).resolve().getName(); |
| assertEquals(firstParameterType, actualParameterType); |
| } |
| } |
| |
| private void doTest(int usageCount, String text) { |
| myFixture.configureByText('_.groovy', text) |
| assertUsageCount(usageCount); |
| } |
| |
| } |