function expression searcher: find most likely files only among of files where occurr...
[idea/community.git] / java / java-tests / testSrc / com / intellij / codeInsight / daemon / lambda / FindFunctionalInterfaceTest.java
1 /*
2  * Copyright 2000-2014 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.codeInsight.daemon.lambda;
17
18 import com.intellij.JavaTestUtil;
19 import com.intellij.openapi.vfs.VirtualFile;
20 import com.intellij.psi.*;
21 import com.intellij.psi.impl.search.JavaFunctionalExpressionSearcher;
22 import com.intellij.psi.search.GlobalSearchScope;
23 import com.intellij.psi.search.searches.FunctionalExpressionSearch;
24 import com.intellij.psi.search.searches.ReferencesSearch;
25 import com.intellij.psi.util.PsiTreeUtil;
26 import com.intellij.testFramework.LightProjectDescriptor;
27 import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
28 import org.jetbrains.annotations.NotNull;
29
30 import java.util.Collection;
31 import java.util.function.Predicate;
32
33 public class FindFunctionalInterfaceTest extends LightCodeInsightFixtureTestCase {
34   public void testMethodArgument() throws Exception {
35     doTestOneExpression();
36   }
37
38   public void testMethodArgumentByTypeParameter() throws Exception {
39     doTestOneExpression();
40   }
41
42   public void testFieldDeclaredInFileWithoutFunctionalInterfaces() throws Exception {
43     myFixture.addClass("class B {" +
44                        "  void f(A a) {" +
45                        "    a.r = () -> {};" +
46                        "  }" +
47                        "}");
48     myFixture.addClass("public class A {" +
49                        "  public I r;" +
50                        "}");
51
52     doTestOneExpression();
53   }
54
55   public void testVarargPosition() throws Exception {
56     myFixture.addClass("\n" +
57                        "class A {  \n" +
58                        "  <T> void foo(T... r) {}\n" +
59                        "  void bar(J i){foo(i, i, () -> {});}\n" +
60                        "}");
61
62     doTestOneExpression();
63   }
64
65   private void doTestOneExpression() {
66     configure();
67     final PsiClass psiClass = findClassAtCaret();
68     final Collection<PsiFunctionalExpression> expressions = FunctionalExpressionSearch.search(psiClass).findAll();
69     int size = expressions.size();
70     assertEquals(1, size);
71     final PsiFunctionalExpression next = expressions.iterator().next();
72     assertNotNull(next);
73     assertEquals("() -> {}", next.getText());
74   }
75
76   @NotNull
77   private PsiClass findClassAtCaret() {
78     final PsiElement elementAtCaret = myFixture.getElementAtCaret();
79     assertNotNull(elementAtCaret);
80     final PsiClass psiClass = PsiTreeUtil.getParentOfType(elementAtCaret, PsiClass.class, false);
81     assertTrue(psiClass != null && psiClass.isInterface());
82     return psiClass;
83   }
84
85   public void testFieldFromAnonymousClassScope() throws Exception {
86     configure();
87     final PsiElement elementAtCaret = myFixture.getElementAtCaret();
88     assertNotNull(elementAtCaret);
89     final PsiField field = PsiTreeUtil.getParentOfType(elementAtCaret, PsiField.class, false);
90     assertNotNull(field);
91     final PsiClass aClass = field.getContainingClass();
92     assertTrue(aClass instanceof PsiAnonymousClass);
93     final Collection<PsiReference> references = ReferencesSearch.search(field).findAll();
94     assertFalse(references.isEmpty());
95     assertEquals(1, references.size());
96   }
97
98   public void testMethodWithClassTypeParameter() {
99     configure();
100     assertSize(1, FunctionalExpressionSearch.search(findClass("I")).findAll());
101   }
102
103   public void testFindSubInterfaceLambdas() {
104     configure();
105
106     assertSize(5, FunctionalExpressionSearch.search(findClass("DumbAwareRunnable")).findAll());
107     assertSize(3, FunctionalExpressionSearch.search(findClass("DumbAwareRunnable2")).findAll());
108     assertSize(6, FunctionalExpressionSearch.search(findClass("DumbAware")).findAll());
109
110     assertSize(1, FunctionalExpressionSearch.search(findClass("WithDefaultMethods")).findAll());
111     assertSize(1, FunctionalExpressionSearch.search(findClass("WithManyMethods")).findAll());
112     assertSize(1, FunctionalExpressionSearch.search(findClass("WithManyMethods2")).findAll());
113   }
114
115   public void testArraysStreamLikeApi() {
116     configure();
117     assertSize(1, FunctionalExpressionSearch.search(findClass("I")).findAll());
118   }
119
120   public void testStreamOfLikeApiWithLocalVar() {
121     configure();
122     assertSize(1, FunctionalExpressionSearch.search(findClass("I")).findAll());
123   }
124
125   public void testStreamOfLikeApiWithField() {
126     myFixture.addClass("class Base { StrType Stream = null; }");
127     configure();
128     assertSize(1, FunctionalExpressionSearch.search(findClass("I")).findAll());
129   }
130
131   public void testCallWithQualifiedName() {
132     myFixture.addClass("package pkg.p1.p2.p3; public interface I { void run() {} }");
133     myFixture.addClass("package pkg.p1.p2.p3; public class Util { public static void foo(I i) {} }");
134     configure();
135     assertSize(1, FunctionalExpressionSearch.search(findClass("pkg.p1.p2.p3.I")).findAll());
136   }
137
138   public void testCallOnGenericParameter() {
139     configure();
140     assertSize(1, FunctionalExpressionSearch.search(findClass("I")).findAll());
141   }
142
143   public void testChainStartingWithConstructor() {
144     configure();
145     assertSize(1, FunctionalExpressionSearch.search(findClass("IterHelper.MapIterCallback")).findAll());
146   }
147
148   public void testDontVisitInapplicableFiles() {
149     PsiClass sam = myFixture.addClass("interface I { void foo(); }");
150     myFixture.addClass("class Some { " +
151                        "{ I i = () -> {}; }" +
152                        "void doTest(int a) {} " +
153                        "void doTest(I i, I j) {} " +
154                        "Some intermediate() {} " +
155                        "Object intermediate(int a, int b) {} " +
156                        "}");
157     myFixture.addClass("class _WrongSignature {{ I i = a -> {}; I j = () -> true; }}");
158     myFixture.addClass("class _CallArgumentCountMismatch extends Some {{ " +
159                        "  doTest(() -> {}); " +
160                        "  intermediate(4).doTest(() -> {}, () -> {}); " +
161                        "}}");
162     myFixture.addClass("class _KnownTypeVariableAssignment {" +
163                        "static Runnable field;" +
164                        "{ Runnable r = () -> {}; field = () -> {}; } " +
165                        "}");
166     myFixture.addClass("class _SuperFieldAssignment extends _KnownTypeVariableAssignment {" +
167                        "{ field = () -> {}; } " +
168                        "}");
169     myFixture.addClass("import static _KnownTypeVariableAssignment.*; " +
170                        "class _StaticallyImportedFieldAssignment {" +
171                        "{ field = () -> {}; } " +
172                        "}");
173
174     assertSize(1, FunctionalExpressionSearch.search(sam).findAll());
175     for (VirtualFile file : JavaFunctionalExpressionSearcher.getFilesToSearchInPsi(sam, getProject())) {
176       assertFalse(file.getName(), file.getName().startsWith("_"));
177     }
178   }
179
180   private PsiClass findClass(String i) {
181     return JavaPsiFacade.getInstance(getProject()).findClass(i, GlobalSearchScope.allScope(getProject()));
182   }
183
184   private void configure() {
185     myFixture.configureByFile(getTestName(false) + ".java");
186   }
187
188   public void testClassFromJdk() {
189     doTestIndexSearch("(e) -> true");
190   }
191
192   public void testClassFromJdkMethodRef() {
193     doTestIndexSearch("this::bar");
194   }
195
196   public void doTestIndexSearch(String expected) {
197     configure();
198
199     PsiClass predicate = findClass(Predicate.class.getName());
200     assert predicate != null;
201     final PsiFunctionalExpression next = assertOneElement(FunctionalExpressionSearch.search(predicate).findAll());
202     assertEquals(expected, next.getText());
203   }
204
205   public void testConstructorReferences() {
206     configure();
207
208     myFixture.addClass("class Bar extends Foo {\n" +
209                        "  public Bar() { super(() -> 1); }\n" +
210                        "\n" +
211                        "  {\n" +
212                        "    new Foo(() -> 2) { };\n" +
213                        "    new Foo(() -> 3);\n" +
214                        "  }\n" +
215                        "}");
216
217     assertSize(5, FunctionalExpressionSearch.search(findClassAtCaret()).findAll());
218   }
219
220   @Override
221   protected String getBasePath() {
222     return JavaTestUtil.getRelativeJavaTestDataPath() + "/codeInsight/daemonCodeAnalyzer/lambda/findUsages/";
223   }
224
225   @NotNull
226   @Override
227   protected LightProjectDescriptor getProjectDescriptor() {
228     return JAVA_8;
229   }
230 }