2 * Copyright 2000-2016 JetBrains s.r.o.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package com.intellij.structuralsearch;
18 import com.intellij.openapi.fileTypes.StdFileTypes;
19 import com.intellij.psi.*;
20 import com.intellij.structuralsearch.impl.matcher.MatcherImplUtil;
21 import com.intellij.testFramework.PlatformTestUtil;
22 import org.jetbrains.annotations.NotNull;
24 import java.io.IOException;
25 import java.util.ArrayList;
26 import java.util.List;
29 * @author Maxim.Mossienko
31 @SuppressWarnings({"HardCodedStringLiteral"})
32 public class StructuralSearchTest extends StructuralSearchTestCase {
33 private static final String s1 =
34 "debug(\"In action performed:\"+event);"+
35 "project = (Project)event.getDataContext().getData(DataConstants.PROJECT);" +
36 "CodeEditorManager.getInstance(project).commitAllToPsiFile();" +
37 "file = (PsiFile) event.getDataContext().getData(\"psi.File\"); " +
39 " (dialog = new SearchDialog()):" +
43 private static final String s2 = "((dialog==null)? (dialog = new SearchDialog()): dialog).show();";
44 private static final String s3 = "dialog = new SearchDialog()";
46 private static final String s4 =
48 " pattern = pattern.getNextSibling(); " +
50 " while (pattern!=null && filterLexicalNodes(pattern));";
52 private static final String s5 =
53 "{ System.out.println();" +
56 " pattern = pattern.getNextSibling(); " +
58 " while (pattern!=null && filterLexicalNodes(pattern)); " +
61 " pattern = pattern.getNextSibling(); " +
62 " } while (pattern!=null && filterLexicalNodes(pattern));" +
65 " pattern = pattern.getNextSibling(); " +
66 " } while (pattern!=null && filterLexicalNodes(pattern));" +
70 private static final String s6 =
72 " pattern.getNextSibling(); " +
74 " while (pattern!=null && filterLexicalNodes(pattern));";
76 private static final String s7 =
77 " if (true) throw new UnsupportedPatternException(statement.toString());" +
79 " throw new UnsupportedPatternException(statement.toString());" +
82 private static final String s8 =
84 " throw new UnsupportedPatternException(statement.toString());" +
87 private static final String s9 = " if (true) throw new UnsupportedPatternException(statement.toString());";
89 private static final String s10 = "listener.add(new Runnable() { public void run() {} });";
90 private static final String s11 = " new XXX()";
92 private static final String s12 =
94 " public void run() {" +
95 " matchContext.getSink().matchingFinished();" +
99 private static final String s13 = "new Runnable() {}";
100 private static final String s14_1 = "if (true) { aaa(var); }";
101 private static final String s14_2 = "if (true) { aaa(var); bbb(var2); }\n if(1==1) { system.out.println('o'); }";
102 private static final String s15 = "'T;";
103 private static final String s16 = "if('_T) { '_T2; }";
104 private static final String s17 =
105 "token.getText().equals(token2.getText());" +
106 "token.getText().equals(token2.getText2());" +
107 "token.a.equals(token2.b);" +
108 "token.a.equals(token2.a);";
109 private static final String s18_1 = "'_T1.'_T2.equals('_T3.'_T2);";
110 private static final String s18_2 = "'_T1.'_T2().equals('_T3.'_T2());";
111 private static final String s18_3 = "'_T1.'_T2";
112 private static final String s19 = "Aaa a = (Aaa)b; Aaa c = (Bbb)d;";
113 private static final String s20 = "'_T1 'T2 = ('_T1)'_T3;";
114 private static final String s20_2 = "'_T1 '_T2 = ('_T1)'_T3;";
115 private static final String s21_1 = "'_T1:Aa* 'T2 = ('_T1)'_T3;";
116 private static final String s21_2 = "'_T1:A* 'T2 = ( '_T1:A+ )'_T3;";
117 private static final String s21_3 = "'_T1:Aa* 'T2 = ( '_T1 )'_T3;";
119 private static final String s22 = "Aaa a = (Aaa)b; Bbb c = (Bbb)d;";
121 private static final String s23 = "a[i] = 1; b[a[i]] = f(); if (a[i]==1) return b[c[i]];";
122 private static final String s24_1 = "'T['_T2:.*i.* ] = '_T3;";
123 private static final String s24_2 = "'T['_T2:.*i.* ]";
124 private static final String s25 = "class MatcherImpl { void doMatch(int a) {} }\n" +
125 "class Matcher { abstract void doMatch(int a);}\n " +
126 "class Matcher2Impl { void doMatch(int a, int b) {} } ";
127 private static final String s26 = "class 'T:.*Impl { '_T2 '_T3('_T4 '_T5) {\n\n} } ";
128 private static final String s27 = "class A {} interface B {}";
129 private static final String s28 = "interface 'T {}";
131 private static final String s29 = "class A { void B(int C) {} } class D { void E(double e) {} }";
132 private static final String s30 = "class '_ { void '_('_:int '_); } ";
134 private static final String s31 = "class A extends B { } class D extends B { } class C extends C {}";
135 private static final String s32 = "class '_ extends B { } ";
137 private static final String s33 = "class A implements B,C { } class D implements B,D { } class C2 implements C,B {}";
138 private static final String s34 = "class '_ implements B,C { } ";
140 private static final String s35 = "class A { int b; double c; void d() {} int e() {} } " +
141 "class A2 { int b; void d() {} }";
142 private static final String s36 = "class '_ { double '_; int '_; int '_() {} void '_() {} } ";
144 private static final String s37 = "class A { void d() throws B,C,D {} } class A2 { void d() throws B,C {} }";
145 private static final String s38 = "class 'T { '_ '_() throws D,C {} } ";
147 private static final String s39 = "class A extends B { } class A2 { }";
148 private static final String s40 = "class 'T { } ";
150 private static final String s41 = "class A extends B { int a = 1; } class B { int[] c= new int[2]; } " +
151 "class D { double e; } class E { int d; } ";
152 private static final String s42_1 = "class '_ { '_T '_T2 = '_T3; } ";
153 private static final String s42_2 = "class '_ { '_T '_T2; } ";
155 private static final String s43 = "interface A extends B { int B = 1; } " +
156 "interface D { public final static double e = 1; } " +
157 "interface E { final static ind d = 2; } " +
159 private static final String s44 = "interface '_ { '_T 'T2 = '_T3; } ";
160 private static final String s45 = "class A extends B { private static final int B = 1; } " +
161 "class C extends D { int B = 1; }" +
164 private static final String s46 = "class '_ { final static private '_T 'T2 = '_T3; } ";
165 private static final String s46_2 = "class '_ { '_T 'T2 = '_T3; } ";
167 private static final String s47 = "class C { java.lang.String t; } class B { BufferedString t2;} class A { String p;} ";
168 private static final String s48 = "class '_ { String '_; }";
170 private static final String s49 = "class C { void a() throws java.lang.RuntimeException {} } class B { BufferedString t2;}";
171 private static final String s50 = "class '_ { '_ '_() throws RuntimeException; }";
173 private static final String s51 = "class C extends B { } class B extends A { } class E {}";
174 private static final String s52 = "class '_ extends '_ { }";
176 private static final String s53 = "class C { " +
177 " String a = System.getProperty(\"abcd\"); " +
178 " static { String s = System.getProperty(a); }" +
179 " static void b() { String s = System.getProperty(a); }" +
181 private static final String s54 = "System.getProperty('T)";
183 private static final String s55 = " a = b.class; ";
184 private static final String s56 = "'T.class";
186 private static final String s57 = "/** @author Maxim */ class C {" +
187 " private int value; " +
190 " /** @serializable */ private int value;" +
191 "private int value2; " +
192 " /** @since 1.4 */ void a() {} "+
195 " /** @since 1.4 */ void a() {} "+
196 " /** @serializable */ private int value2; " +
198 "class G { /** @param a*/ void a() {} }";
199 private static final String s57_2 = "/** @author Maxim */ class C { " +
202 "/** @serializable */ private int value; " +
203 "/** @since 1.4 */ void a() {} "+
206 "/** @since 1.4 */ void a() {} "+
207 "/** @serializable */ private int value2; " +
209 "class G { /** @param a*/ void a() {} }";
210 private static final String s58 = "/** @'T '_T2 */ class '_ { }";
211 private static final String s58_2 = "class '_ { /** @serializable '_* */ '_ '_; }";
212 private static final String s58_3 = "class '_ { /** @'T 1.4 */ '_ '_() {} }";
213 private static final String s58_4 = "/** @'T '_T2 */";
214 private static final String s58_5 = "/** @'T '_T2? */";
216 private static final String s59 = "interface A { void B(); }";
217 private static final String s60 = "interface '_ { void '_(); }";
219 private static final String s61 = "{ a=b; c=d; return; } { e=f; } {}";
220 private static final String s62_1 = "{ 'T*; }";
221 private static final String s62_2 = "{ 'T+; }";
222 private static final String s62_3 = "{ 'T?; }";
224 private static final String s62_4 = "{ '_*; }";
225 private static final String s62_5 = "{ '_+; }";
226 private static final String s62_6 = "{ '_?; }";
228 private static final String s63 = " class A { A() {} } class B { public void run() {} }";
229 private static final String s63_2 = " class A { A() {} " +
230 "class B { public void run() {} } " +
231 "class D { public void run() {} } " +
234 private static final String s64 = " class 'T { public void '_T2:run () {} }";
235 private static final String s64_2 = "class '_ { class 'T { public void '_T2:run () {} } }";
237 private static final String s65 = " if (A instanceof B) {} else if (B instanceof C) {}";
238 private static final String s66 = " '_T instanceof '_T2:B";
240 private static final String s67 = " buf.append((VirtualFile)a);";
241 private static final String s68 = " (VirtualFile)'T";
243 private static final String s69 = " System.getProperties(); System.out.println(); java.lang.System.out.println(); some.other.System.out.println();";
244 private static final String s70 = " System.out ";
245 private static final String s70_2 = " java.lang.System.out ";
247 private static final String s71 = " class A { " +
248 "class D { D() { c(); } }" +
249 "void a() { c(); new MouseListenener() { void b() { c(); } } }" +
251 private static final String s72 = " c(); ";
253 private static final String s73 = " class A { int A; static int B=5; public abstract void a(int c); void q() { ind d=7; } }";
254 private static final String s74 = " '_Type 'Var = '_Init?; ";
255 private static final String s75 = "/** @class aClass\n @author the author */ class A {}\n" +
256 "/** */ class B {}\n" +
257 "/** @class aClass */ class C {}";
258 private static final String s76 = " /** @'_tag+ '_value+ */";
259 private static final String s76_2 = " /** @'_tag* '_value* */";
260 private static final String s76_3 = " /** @'_tag? '_value? */ class 't {}";
262 private static final String s77 = " new ActionListener() {} ";
263 private static final String s78 = " class 'T:.*aaa {} ";
265 private static final String s79 = " class A { static { int c; } void a() { int b; b=1; }} ";
266 private static final String s80 = " { '_T 'T3 = '_T2?; '_*; } ";
268 private static final String s81 = "class Pair<First,Second> {" +
269 " <C,F> void a(B<C> b, D<F> e) throws C {" +
270 " P<Q> r = (S<T>)null;"+
272 " if (r instanceof S<T>) {}"+
274 "} class Q { void b() {} } ";
276 private static final String s81_2 = "class Double<T> {} class T {} class Single<First extends A & B> {}";
278 private static final String s82 = "class '_<'T+> {}";
279 private static final String s82_2 = "'_Expr instanceof '_Type<'_Parameter+>";
280 private static final String s82_3 = "( '_Type<'_Parameter+> ) '_Expr";
281 private static final String s82_4 = "'_Type<'_Parameter+> 'a = '_Init?;";
282 private static final String s82_5 = "class '_ { <'_+> '_Type 'Method('_* '_*); }";
283 private static final String s82_6 = "class '_<'_+ extends 'res+> {}";
284 private static final String s82_7 = "'Type";
286 private static final String s83 = "/**\n" +
287 " * @hibernate.class\n" +
288 " * table=\"CATS\"\n" +
290 "public class Cat {\n" +
291 " private Long id; // identifier\n" +
292 " private Date birthdate;\n" +
294 " * @hibernate.id\n" +
295 " * generator-class=\"native\"\n" +
296 " * column=\"CAT_ID\"\n" +
298 " public Long getId() {\n" +
301 " private void setId(Long id) {\n" +
306 " * @hibernate.property\n" +
307 " * column=\"BIRTH_DATE\"\n" +
309 " public Date getBirthdate() {\n" +
310 " return birthdate;\n" +
312 " void setBirthdate(Date date) {\n" +
313 " birthdate = date;\n" +
316 " * @hibernate.property\n" +
317 " * column=\"SEX\"\n" +
318 " * not-null=\"true\"\n" +
319 " * update=\"false\"\n" +
321 " public char getSex() {\n" +
324 " void setSex(char sex) {\n" +
329 private static final String s84 = " /**\n" +
330 " * @hibernate.property\n" +
334 private static final String s84_2 = " /**\n" +
335 " * @hibernate.property\n" +
336 " * update=\"fa.se\"\n" +
339 private static final String s85 = "{ int a; a=1; a=1; return a; }";
340 private static final String s86 = "'T; 'T;";
342 private static final String s87 = " getSomething(\"1\"); a.call(); ";
343 private static final String s88 = " '_Instance.'Call('_*); ";
344 private static final String s88_2 = " 'Call('_*); ";
345 private static final String s88_3 = " '_Instance?.'Call('_*); ";
346 private static final String s89 = "{ a = 1; b = 2; c=3; }";
347 private static final String s90 = "{ '_T*; '_T2*; }";
348 private static final String s90_2 = " { '_T*; '_T2*; '_T3+; } ";
349 private static final String s90_3 = " { '_T+; '_T2+; '_T3+; '_T4+; } ";
350 private static final String s90_4 = " { '_T{1,3}; '_T2{2}; } ";
351 private static final String s90_5 = " { '_T{1}?; '_T2*?; '_T3+?; } ";
352 private static final String s90_6 = " { '_T{1}?; '_T2{1,2}?; '_T3+?; '_T4+?; } ";
354 private static final String s91 = "class a {\n" +
363 private static final String s92 = "'T:a";
364 private static final String s92_2 = "'T:b";
365 private static final String s92_3 = "'T:c";
367 private static final String s93 = " class A {" +
368 "private int field;" +
369 "public void b() {}" +
371 private static final String s94 = " class '_ {" +
372 "private void b() {}" +
374 private static final String s94_2 = " class '_ {" +
375 "public void b() {}" +
377 private static final String s94_3 = " class '_ {" +
378 "protected int field;" +
380 private static final String s94_4 = " class '_ {" +
381 "private int field;" +
384 private static final String s95 = " class Clazz {" +
385 "private int field;" +
386 "private int field2;" +
387 "private int fiel-d2;" +
390 private static final String s96 = " class '_ {" +
391 "private int 'T+:field.* ;" +
394 public void testSearchExpressions() {
395 assertFalse("subexpr match",findMatchesCount(s2,s3)==0);
396 assertEquals("search for new ",findMatchesCount(s10,s11),0);
397 assertEquals("search for anonymous classes",findMatchesCount(s12,s13),1);
398 // expr in definition initializer
400 "expr in def initializer",
402 findMatchesCount(s53,s54)
405 // a.class expression search
408 findMatchesCount(s55,s56),
412 String complexCode = "interface I { void b(); } interface I2 extends I {} class I3 extends I {} " +
413 "class A implements I2 { void b() {} } class B implements I3 { void b() {}} " +
414 "I2 a; I3 b; a.b(); b.b(); b.b(); A c; B d; c.b(); d.b(); d.b(); ";
416 String exprTypePattern1 = "'t:[exprtype( I2 )].b();";
417 String exprTypePattern2 = "'t:[!exprtype( I2 )].b();";
419 String exprTypePattern3 = "'t:[exprtype( *I2 )].b();";
420 String exprTypePattern4 = "'t:[!exprtype( *I2 )].b();";
423 "expr type condition",
424 findMatchesCount(complexCode,exprTypePattern1),
429 "expr type condition 2",
431 findMatchesCount(complexCode,exprTypePattern2)
435 "expr type condition 3",
436 findMatchesCount(complexCode,exprTypePattern3),
441 "expr type condition 4",
442 findMatchesCount(complexCode,exprTypePattern4),
446 String complexCode2 = "enum X { XXX, YYY }\n class C { static void ordinal() {} void test() { C c; c.ordinal(); c.ordinal(); X.XXX.ordinal(); } }";
448 "expr type condition with enums",
449 findMatchesCount(complexCode2, "'t:[exprtype( *java\\.lang\\.Enum )].ordinal()"),
454 "no smart detection of search target",
455 findMatchesCount("processInheritors(1,2,3,4); processInheritors(1,2,3); processInheritors(1,2,3,4,5,6);","'instance?.processInheritors('_param1{1,6});"),
459 String arrays = "int[] a = new int[20];\n" +
460 "byte[] b = new byte[30]";
461 String arrayPattern = "new int['_a]";
463 "Improper array search",
465 findMatchesCount(arrays,arrayPattern)
468 String someCode = "a *= 2; a+=2;";
469 String otherCode = "a *= 2;";
472 "Improper *= 2 search",
474 findMatchesCount(someCode,otherCode)
477 String s1 = "Thread t = new Thread(\"my thread\",\"my another thread\") {\n" +
478 " public void run() {\n" +
482 String s2 = "new Thread('args*) { '_Other* }";
485 "Find inner class parameters",
487 findMatchesCount(s1,s2)
490 String s3 = "Thread t = new Thread(\"my thread\") {\n" +
491 " public void run() {\n" +
495 String s4 = "new Thread('_args)";
498 "Find inner class by new",
500 findMatchesCount(s3,s4)
503 String s5 = "class A {\n" +
504 "public static <T> T[] copy(T[] array, Class<T> aClass) {\n" +
505 " int i = (int)0;\n" +
506 " int b = (int)0;\n" +
507 " return (T[])array.clone();\n" +
510 String s6 = "('_T[])'_expr";
513 "Find cast to array",
515 findMatchesCount(s5,s6)
518 String s7 = "import java.math.BigDecimal;\n" +
520 "public class Prorator {\n" +
521 " public void prorate(BigDecimal[] array) {\n" +
524 " public void prorate2(java.math.BigDecimal[] array) {\n" +
527 " public void prorate(BigDecimal bd) {\n" +
531 " public static void main(String[] args) {\n" +
532 " BigDecimal[] something = new BigDecimal[2];\n" +
533 " java.math.BigDecimal[] something2 = new BigDecimal[2];\n" +
534 " something[0] = new BigDecimal(1.0);\n" +
535 " something[1] = new BigDecimal(1.0);\n" +
537 " Prorator prorator = new Prorator();\n" +
539 "// ---------------------------------------------------\n" +
540 "// the line below should've been found, in my opinion.\n" +
541 "// --------------------------------------------------\n" +
542 " prorator.prorate(something);\n" +
543 " prorator.prorate(something2);\n" +
545 " prorator.prorate(something[0]);\n" +
546 " prorator.prorate(something[1]);\n" +
547 " prorator.prorate(something[0]);\n" +
550 String s8 = "'_Instance.'_MethodCall:[regex( prorate )]('_Param:[exprtype( BigDecimal\\[\\] )]) ";
553 "Find method call with array for parameter expr type",
555 findMatchesCount(s7,s8,true)
558 String s13 = "try { } catch(Exception e) { e.printStackTrace(); }";
559 String s14 = "'_Instance.'_MethodCall('_Parameter*)";
562 "Find statement in catch",
564 findMatchesCount(s13,s14)
567 String s9 = "int a[] = new int[] { 1,2,3,4};\n" +
568 "int b[] = { 2,3,4,5 };\n" +
569 "Object[] c = new Object[] { \"\", null};\n" +
570 "Object[] d = {null, null};\n" +
571 "Object[] e = {};\n" +
572 "Object[] f = new Object[]{}\n" +
573 "String[] g = new String[]{}\n" +
574 "String[] h = new String[]{new String()}";
576 assertEquals("Find new array expressions, but no array initializer expressions", 5,
577 findMatchesCount(s9, "new '_ []{ '_* }"));
579 assertEquals("Find new int array expressions, including array initializer expressions", 2,
580 findMatchesCount(s9, "new int []{ '_* }"));
582 assertEquals("Find new int array expressions, including array initializer expressions using variable ", 2,
583 findMatchesCount(s9, "new 'a?:int [] { '_* }"));
585 assertEquals("Find all new array expressions, including array initializers", 8,
586 findMatchesCount(s9, "new '_? []{ '_* }"));
588 assertEquals("Find new Object array expressions, including array initializer expressions", 4,
589 findMatchesCount(s9, "new Object[] { '_* }"));
591 assertEquals("Find only array initializer expressions", 3,
592 findMatchesCount(s9, "new '_{0,0}[] { '_* }"));
594 assertEquals("Find only int array initializer expressions", 1,
595 findMatchesCount(s9, "new '_{0,0}:int [] { '_* }"));
597 assertEquals("Try to find String array initializer expressions", 0,
598 findMatchesCount(s9, "new '_{0,0}:String [] { '_* }"));
600 String s10 = "int time = 99;\n" +
601 "String str = time < 0 ? \"\" : \"\";" +
602 "String str2 = time < time ? \"\" : \"\";";
604 assertEquals("Find expressions mistaken for declarations by parser in block mode", 1,
605 findMatchesCount(s10, "time < time"));
607 assertEquals("Find expressions mistaken for declarations by parser in block mode 2", 1,
608 findMatchesCount(s10, "time < 0"));
610 assertEquals("Find expressions mistaken for declarations by parser in block mode 3", 1,
611 findMatchesCount(s10, "time < 0 ? '_a : '_b"));
613 assertEquals("Find expressions mistaken for declarations by parser in block mode 4", 2,
614 findMatchesCount(s10, "'_a < '_b"));
617 public void testLiteral() {
618 String s = "class A {\n" +
619 " static String a = 1;\n" +
620 " static String s = \"aaa\";\n" +
621 " static String s2;\n" +
623 String s2 = "static String '_FieldName = '_Init?:[!regex( \".*\" )];";
624 String s2_2 = "static String '_FieldName = '_Init:[!regex( \".*\" )];";
629 findMatchesCount(s,s2)
635 findMatchesCount(s,s2_2)
638 String pattern3 = "\"'String\"";
639 assertEquals("String literal", 1, findMatchesCount(s, pattern3));
641 String pattern4 = "\"test\"";
642 String source = "@SuppressWarnings(\"test\") class A {" +
643 " @SuppressWarnings({\"other\", \"test\"}) String field;" +
645 assertEquals("String literal in annotation", 2, findMatchesCount(source, pattern4));
648 public void testCovariantArraySearch() {
649 String s1 = "String[] argv;";
650 String s2 = "String argv;";
651 String s3 = "'T[] argv;";
652 String s3_2 = "'T:*Object [] argv;";
657 findMatchesCount(s1,s2)
661 "Find array types, 2",
663 findMatchesCount(s2,s1)
667 "Find array types, 3",
669 findMatchesCount(s2,s3)
673 "Find array types, 3",
675 findMatchesCount(s1,s3_2)
678 String s11 = "class A {\n" +
679 " void main(String[] argv);" +
680 " void main(String argv[]);" +
681 " void main(String argv);" +
683 String s12 = "'_t:[regex( *Object\\[\\] ) ] '_t2;";
684 String s12_2 = "'_t:[regex( *Object ) ] '_t2 [];";
685 String s12_3 = "'_t:[regex( *Object ) ] '_t2;";
688 "Find array covariant types",
690 findMatchesCount(s11,s12)
694 "Find array covariant types, 2",
696 findMatchesCount(s11,s12_2)
700 "Find array covariant types, 3",
702 findMatchesCount(s11,s12_3)
706 public void testFindArrayDeclarations() {
707 String source = "class A {" +
714 String target = "String[][] '_s;";
715 assertEquals("should find multi-dimensional c-style array declarations", 1, findMatchesCount(source, target));
717 String target2 = "class '_A { int[] 'f(); }";
718 assertEquals("should find c-style method return type declarations", 1, findMatchesCount(source, target2));
720 String target3 = "class '_A { int 'f(); }";
721 assertEquals("should not find methods with array return types",0, findMatchesCount(source, target3));
723 String source2 = "class A {" +
724 " void y(int... i) {}" +
725 " void y(String... ss) {}" +
726 " void y(boolean b) {}" +
728 assertEquals("find ellipsis type 1", 1, findMatchesCount(source2, "String[] '_a;"));
729 assertEquals("find ellipsis type 2", 1, findMatchesCount(source2, "int[] '_a;"));
730 assertEquals("find ellipsis type 3", 1, findMatchesCount(source2, "class '_X { void '_m(int... '_a); }"));
731 assertEquals("find ellipsis type 4", 2, findMatchesCount(source2, "'_T[] '_a;"));
733 String source3 = "class A {" +
734 " private int[] is;" +
736 assertEquals("find primitive array 1", 1, findMatchesCount(source3, "int[] '_a;"));
737 assertEquals("find primitive array 2", 1, findMatchesCount(source3, "'_T[] '_a;"));
738 assertEquals("find primitive array 3", 1, findMatchesCount(source3, "'_T:[regex( int )][] '_a;"));
739 assertEquals("find primitive array 4", 1, findMatchesCount(source3, "'_T:[regex( int\\[\\] )] '_a;"));
742 // @todo support back references (\1 in another reg exp or as fild member)
743 //private static final String s1002 = " setSSS( instance.getSSS() ); " +
744 // " setSSS( instance.SSS ); ";
745 //private static final String s1003 = " 't:set(.+) ( '_.get't_1() ); ";
746 //private static final String s1003_2 = " 't:set(.+) ( '_.'t_1 ); ";
748 public void testSearchStatements() {
749 assertEquals("statement search",findMatchesCount(s1,s2),1);
750 assertEquals("several constructions match",findMatchesCount(s5,s4),3);
751 assertFalse("several constructions 2",(findMatchesCount(s5,s6))!=0);
753 assertEquals("several constructions 3",findMatchesCount(s7,s8),2);
754 assertEquals("several constructions 4",findMatchesCount(s7,s9),2);
756 final String s1000 = "{ lastTest = \"search for parameterized pattern\";\n" +
757 " matches = testMatcher.findMatches(s14_1,s15, options);\n" +
758 " if (matches.size()!=2 ) return false;\n" +
759 "lastTest = \"search for parameterized pattern\";\n" +
760 " matches = testMatcher.findMatches(s14_1,s15, options);\n" +
761 " if (matches.size()!=2 ) return false; }";
762 final String s1001 = "lastTest = '_Descr; " +
763 " matches = testMatcher.findMatches('_In,'_Pattern, options);\n" +
764 " if (matches.size()!='_Number ) return false;";
766 assertEquals("several operators 5",findMatchesCount(s1000,s1001),2);
769 "two the same statements search",
770 findMatchesCount(s85,s86),
775 "search for simple call",
776 findMatchesCount(s87,s88),
781 "search for simple call 2",
782 findMatchesCount(s87,s88_2),
787 "search for simple call 3",
788 findMatchesCount(s87,s88_3),
792 String s10015 = "DocumentListener[] listeners = getCachedListeners();";
793 String s10016 = "'_Type 'Var = '_Call();";
796 "search for definition with init",
798 findMatchesCount(s10015,s10016)
801 String s10017 = "a = b; b = c; a=a; c=c;";
802 String s10018 = "'_a = '_a;";
805 "search silly assignments",
807 findMatchesCount(s10017,s10018)
810 String s10019 = "a.b(); a.b(null); a.b(null, 1);";
811 String s10020 = "a.b(null);";
816 findMatchesCount(s10019,s10020)
819 String s1008 = "int a, b, c, d; int a,b,c; int c,d; int e;";
820 String s1009 = "int '_a{3,4};";
823 "search many declarations",
825 findMatchesCount(s1008,s1009)
828 String s1 = "super(1,1); call(1,1); call(2,2);";
829 String s2 = "super('_t*);";
834 findMatchesCount(s1,s2)
837 String s10021 = "short a = 1;\n" +
840 String s10022 = "short '_a = '_b.b();";
843 "search def init bug",
845 findMatchesCount(s10021,s10022)
848 String s10023 = "abstract class A { public abstract short getType(); }\n" +
850 "switch(a.getType()) {\n" +
854 "switch(a.getType()) {\n" +
858 String s10024 = "switch('_a:[exprtype( short )]) { '_statement*; }";
862 findMatchesCount(s10023,s10024)
865 String s10025 = "A[] a;\n" +
868 String s10026 = "A[] 'a;";
869 String s10026_2 = "A 'a[];";
872 "array types in dcl",
874 findMatchesCount(s10025,s10026)
878 "array types in dcl 2",
880 findMatchesCount(s10025,s10026_2)
883 String s10027 = "try { a(); } catch(Exception ex) {}\n" +
884 "try { a(); } finally {}\n" +
885 "try { a(); } catch(Exception ex) {} finally {} \n";
886 String s10028 = "try { a(); } finally {}\n";
890 findMatchesCount(s10027,s10028)
893 String s10029 = "for(String a:b) { System.out.println(a); }";
894 String s10030 = "for(String a:b) { '_a; }";
898 findMatchesCount(s10029,s10030)
901 String s10031 = "try { a(); } catch(Exception ex) {} catch(Error error) { 1=1; }\n" +
902 "try { a(); } catch(Exception ex) {}";
903 String s10032 = "try { a(); } catch('_Type+ 'Arg+) { '_Statements*; }\n";
907 findMatchesCount(s10031,s10032)
910 String s10033 = "return x;\n" +
915 String s10034 = "return ('a);";
916 assertEquals("Find statement with parenthesized expr",2,findMatchesCount(s10033,s10034));
918 String in = "if (true) {" +
919 " System.out.println();" +
921 " System.out.println();" +
923 "if (true) System.out.println();";
924 String pattern1 = "if ('_exp) { '_statement*; }";
925 assertEquals("Find if statement with else", 2, findMatchesCount(in, pattern1));
927 String pattern2 = "if ('_exp) { '_statement*; } else { '_statement2{0,0}; }";
928 assertEquals("Find if statement without else", 1, findMatchesCount(in, pattern2));
931 public void testSearchClass() {
932 // no modifier list in interface vars
934 "no modifier for interface vars",
935 findMatchesCount(s43,s44),
939 // different order of access modifiers
941 "different order of access modifiers",
942 findMatchesCount(s45,s46),
946 // no access modifiers
948 "no access modifier",
949 findMatchesCount(s45,s46_2),
953 // type could differ with package
955 "type differs with package",
956 findMatchesCount(s47,s48),
960 // reference element could differ in package
962 "reference could differ in package",
963 findMatchesCount(s49,s50),
967 String s51 = "class C extends java.awt.List {} class A extends java.util.List {} class B extends java.awt.List {} ";
968 String s52 = "class 'B extends '_C:java\\.awt\\.List {}";
971 "reference could differ in package 2",
972 findMatchesCount(s51,s52),
977 "method access modifier",
978 findMatchesCount(s93,s94),
983 "method access modifier 2",
984 findMatchesCount(s93,s94_2),
989 "field access modifier",
990 findMatchesCount(s93,s94_3),
995 "field access modifier 2",
996 findMatchesCount(s93,s94_4),
1000 final String s127 = "class a { void b() { new c() {}; } }";
1001 final String s128 = "class 't {}";
1003 "class finds anonymous class",
1004 findMatchesCount(s127,s128),
1008 final String s129 = "class a { public void run() {} }\n" +
1009 "class a2 { public void run() { run(); } }\n" +
1010 "class a3 { public void run() { run(); } }\n" +
1011 "class a4 { public void run(); }";
1013 final String s130 = "class 'a { public void run() {} }";
1014 final String s130_2 = "class 'a { public void run() { '_statement; } }";
1015 final String s130_3 = "class 'a { public void run(); }";
1018 "empty method finds empty method only",
1019 findMatchesCount(s129,s130),
1024 "nonempty method finds nonempty method",
1025 findMatchesCount(s129,s130_2),
1030 "nonempty method finds nonempty method",
1031 findMatchesCount(s129,s130_3),
1035 final String s133 = "class S {\n" +
1037 " new Runnable() {\n" +
1038 " public void run() {\n" +
1041 " private void f() {\n" +
1042 " //To change body of created methods use File | Settings | File Templates.\n" +
1045 " new Runnable() {\n" +
1046 " public void run() {\n" +
1049 " private void g() {\n" +
1050 " //To change body of created methods use File | Settings | File Templates.\n" +
1053 " new Runnable() {\n" +
1054 " public void run() {\n" +
1059 " private void f() {\n" +
1060 " //To change body of created methods use File | Settings | File Templates.\n" +
1063 final String s134 = "new Runnable() {\n" +
1064 " public void run() {\n" +
1067 " private void '_f ();\n" +
1070 "complex expr matching",
1072 findMatchesCount(s133,s134)
1075 final String s135 = "abstract class My {\n" +
1076 " abstract void f();\n" +
1078 "abstract class My2 {\n" +
1079 " abstract void f();\n" +
1082 final String s136 = "class 'm {\n" +
1084 " '_type '_method{0,0} ('_paramtype* '_paramname* );\n" +
1087 "reject method with 0 max occurence",
1088 findMatchesCount(s135,s136),
1092 final String s137 = "abstract class My {\n" +
1095 "abstract class My2 {\n" +
1098 "abstract class My3 {\n" +
1100 " Project b = null;\n" +
1102 "abstract class My {\n" +
1105 final String s138 = "class 'm {\n" +
1106 " Project '_f{0,0} = '_t?;\n" +
1109 "reject field with 0 max occurence",
1110 findMatchesCount(s137,s138),
1114 final String s139 = "class My { boolean equals(Object o); int hashCode(); }";
1115 final String s139_2 = "class My { boolean equals(Object o); }";
1116 final String s140 = "class 'A { boolean equals(Object '_o ); int '_hashCode{0,0}:hashCode (); }";
1119 "reject method with constraint",
1120 findMatchesCount(s139,s140),
1125 "reject field with 0 max occurence",
1126 findMatchesCount(s139_2,s140),
1130 final String s141 = "class A { static { a = 10 } }\n" +
1131 "class B { { a = 10; } }\n" +
1132 "class C { { a = 10; } }";
1133 final String s142 = "class '_ { static { a = 10; } } ";
1135 "static block search",
1136 findMatchesCount(s141,s142),
1141 public void testParameterlessContructorSearch() {
1142 final String s143 = "class A { A() {} };\n" +
1143 "class B { B(int a) {} };\n" +
1144 "class C { C() {} C(int a) {} };\n" +
1147 final String s144 = "class '_a { '_d{0,0}:[ script( \"__context__.constructor\" ) ]('_b+ '_c+); }";
1149 "parameterless contructor search",
1151 findMatchesCount(s143,s144)
1155 public void testScriptSearch() {
1156 final String source = "package a;" +
1157 "class BX extends java.util.List {" +
1158 " private static final java.util.List VALUE = new BX();" +
1160 "class CX extends java.util.List {" +
1161 " private static final String S = \"\";" +
1163 // find static final fields whose type is a proper ancestor of the class declaring their fields
1164 assertEquals("all variables accessible from script", 1,
1165 findMatchesCount(source,
1167 "import com.intellij.psi.util.InheritanceUtil\n" +
1168 "import com.intellij.psi.util.PsiTreeUtil\n" +
1169 "import com.intellij.psi.PsiClass\n" +
1170 "init != null &&" + // redundant reference to '_init
1171 "InheritanceUtil.isInheritor(\n" +
1172 " PsiTreeUtil.getParentOfType(variable, PsiClass.class),\n" + // reference to 'variable
1174 " Type.type.canonicalText\n" + // reference to '_Type
1176 "static final '_Type 'variable = '_init;"));
1178 final String source2 = "class A {" +
1179 " String s = new String();" +
1180 " @SuppressWarnings(\"\") int m() {" +
1187 assertEquals("type of variables in script are as expected", 1,
1188 findMatchesCount(source2,
1190 "import com.intellij.psi.*\n" +
1191 "__context__ instanceof PsiElement &&" +
1192 "a instanceof PsiClass &&" +
1193 "b instanceof PsiTypeElement &&" +
1194 "c instanceof PsiField &&" +
1195 "d instanceof PsiNewExpression &&" +
1196 "e instanceof PsiTypeElement &&" +
1197 "f instanceof PsiMethod &&" +
1198 "g instanceof PsiTypeElement &&" +
1199 "h instanceof PsiLocalVariable &&" +
1200 "i instanceof PsiPolyadicExpression &&" +
1201 "j instanceof PsiReferenceExpression &&" +
1202 "k instanceof PsiMethodCallExpression &&" +
1203 "l instanceof PsiAnnotation\n" +
1206 " '_b '_c = new '_d();" +
1207 " @'_l '_e '_f() {" +
1214 assertEquals("Current variable should be available under own name", 1,
1215 findMatchesCount(source2,
1216 "'_a + '_b:[script(\"__log__.info(b)\n__log__.info(__context__)\ntrue\")]"));
1219 public void testCheckScriptValidation() {
1220 final String s1 = "";
1221 final String s2 = "'_b:[script( \"^^^\" )]";
1224 final int count = findMatchesCount(s1, s2);
1225 assertFalse("Validation does not work", true);
1226 } catch (MalformedPatternException ex) {}
1229 //public void testRelationBetweenVars() {
1230 // final String s1 = "public class Foo {\n" +
1231 // " public static final Logger log = Logger.getInstance(Foo.class);\n" +
1232 // " public static final Logger log2 = Logger.getInstance(Foo2.class);\n" +
1233 // " public static final Logger log3 = Logger.getInstance(Foo2.class);\n" +
1235 // final String s2 = "class '_a { static Logger 'log+ = Logger.getInstance('_b:[script( \"_a != _b\" )].class); }";
1237 // "relation between vars in script",
1239 // findMatchesCount(s1,s2)
1243 public void testExprTypeWithObject() {
1244 String s1 = "import java.util.*;\n" +
1247 " Map map = new HashMap();" +
1248 " class AppPreferences {}\n" +
1249 " String key = \"key\";\n" +
1250 " AppPreferences value = new AppPreferences();\n" +
1251 " map.put(key, value );\n" +
1252 " map.put(value, value );\n" +
1253 " map.put(\"key\", value );\n" +
1254 " map.put(\"key\", new AppPreferences());\n" +
1257 String s2 = "'_map:[exprtype( *java\\.util\\.Map )].put('_key:[ exprtype( *Object ) ], '_value:[ exprtype( *AppPreferences ) ]);";
1260 "expr type with object",
1262 findMatchesCount(s1,s2,true)
1266 public void testInterfaceImplementationsSearch() {
1267 String in = "class A implements Cloneable {\n" +
1271 " class B implements Serializable {\n" +
1275 " class C implements Cloneable,Serializable {\n" +
1278 " class C2 implements Serializable,Cloneable {\n" +
1282 " class E extends B implements Cloneable {\n" +
1286 " class F extends A implements Serializable {\n" +
1290 " class D extends C {\n" +
1293 String what = "class 'A implements '_B:*Serializable , '_C:*Cloneable {}";
1295 "search interface within hierarchy",
1297 findMatchesCount(in, what)
1301 public void testSearchBacktracking() {
1303 "backtracking greedy regexp",
1304 findMatchesCount(s89,s90),
1309 "backtracking greedy regexp 2",
1310 findMatchesCount(s89,s90_2),
1315 "backtracking greedy regexp 3",
1316 findMatchesCount(s89,s90_3),
1321 "counted regexp (with back tracking)",
1322 findMatchesCount(s89,s90_4),
1327 "nongreedy regexp (counted, with back tracking)",
1328 findMatchesCount(s89,s90_5),
1333 "nongreedy regexp (counted, with back tracking) 2",
1334 findMatchesCount(s89,s90_6),
1338 String s1000 = "class A {\n" +
1340 " void a(String in, String pattern) {}\n" +
1342 String s1001 = "class '_Class { \n" +
1343 " '_ReturnType+ 'MethodName+ ('_ParameterType* '_Parameter* );\n" +
1346 "handling of no match",
1347 findMatchesCount(s1000,s1001),
1352 public void testSearchSymbol() {
1353 final String s131 = "a.b(); c.d = 1; ";
1354 final String s132 = "'T:b|d";
1359 findMatchesCount(s131,s132)
1362 final String s129 = "A a = new A();";
1363 final String s130 = "'Sym:A";
1365 options.setCaseSensitiveMatch(true);
1367 "case sensitive match",
1368 findMatchesCount(s129,s130),
1372 final String s133 = "class C { int a; int A() { a = 1; }} void c(int a) { a = 2; }";
1373 final String s133_2 = "class C { int a() {} int A() { a(1); }}";
1374 final String s134 = "a";
1376 List<MatchResult> results = findMatches(s133, s134, true, StdFileTypes.JAVA);
1378 "find sym finds declaration",
1383 "find sym finds declaration",
1384 2, findMatchesCount(s133_2, s134, true)
1386 final String in = "class C {" +
1396 final String pattern1 = "'_:[read]";
1397 assertEquals("Find reads of symbol (including operator assignment)", 2, findMatchesCount(in, pattern1));
1399 final String pattern2 = "'_:[write && regex( i )]";
1400 assertEquals("Find writes of symbol", 3, findMatchesCount(in, pattern2));
1402 final String source = "class A {" +
1403 " static A a() {};" +
1408 final String pattern3 = "A";
1409 assertEquals("No duplicate results", 4, findMatchesCount(source, pattern3));
1412 public void testSearchGenerics() {
1414 "parameterized class match",
1415 findMatchesCount(s81,s82),
1420 "parameterized instanceof match",
1421 findMatchesCount(s81,s82_2),
1426 "parameterized cast match",
1427 findMatchesCount(s81,s82_3),
1432 "parameterized symbol without variables matching",
1433 findMatchesCount(s81, "S<T>"),
1438 "parameterized definition match",
1439 findMatchesCount(s81,s82_4),
1444 "parameterized method match",
1445 findMatchesCount(s81,s82_5),
1450 "parameterized constraint match",
1451 findMatchesCount(s81_2,s82_6),
1456 "symbol matches parameterization",
1457 findMatchesCount(s81,s82_7),
1462 "symbol matches parameterization 2",
1463 findMatchesCount(s81_2,s82_7),
1467 String s81_3 = " class A {\n" +
1468 " public static <T> Collection<T> unmodifiableCollection(int c) {\n" +
1469 " return new d<T>(c);\n" +
1471 " static class d<E> implements Collection<E>, Serializable {\n" +
1472 " public <T> T[] toArray(T[] a) {return c.toArray(a);}\n" +
1476 "typed symbol symbol",
1477 findMatchesCount(s81_3,s82_5),
1481 String s81_4="class A<B> { \n" +
1482 " static <C> void c(D<E> f) throws R<S> {\n" +
1483 " if ( f instanceof G<H>) {\n" +
1484 " ((I<G<K>>)l).a();\n" +
1485 " throw new P<Q>();" +
1490 " void d(E f) throws Q {\n" +
1491 " if (g instanceof H) { a.c(); b.d(new A() {}); throw new Exception(((I)k)); }"+
1494 String s82_8 = "'T<'_Subst+>";
1498 findMatchesCount(s81_4,s82_8)
1501 String s81_5 = "class A { HashMap<String, Integer> variable = new HashMap<String, Integer>(\"aaa\");}";
1502 String s82_9 = "'_Type<'_GType, '_GType2> '_instance = new '_Type<'_GType, '_GType2>('_Param);";
1504 "generic vars in new",
1505 findMatchesCount(s81_5,s82_9),
1509 "no exception on searching for diamond operator",
1510 findMatchesCount(s81_5, "new 'Type<>('_Param)"),
1514 "order of parameters matters",
1516 findMatchesCount(s81_5, "HashMap<Integer, String>")
1519 "order of parameters matters 2",
1521 findMatchesCount(s81_5, "HashMap<String, Integer>")
1524 String source1 = "class Comparator<T> { private Comparator<String> c; private Comparator d; private Comparator e; }";
1525 String target1 = "java.util.Comparator 'a;";
1527 "qualified type should not match 1",
1529 findMatchesCount(source1, target1)
1532 String target2 = "java.util.Comparator<String> 'a;";
1534 "qualified type should not match 2",
1536 findMatchesCount(source1, target2)
1540 "unparameterized type query should match",
1542 findMatchesCount(source1, "Comparator 'a;")
1546 "parameterized type query should only match parameterized",
1548 findMatchesCount(source1, "Comparator<'_a> 'b;")
1552 "should find unparameterized only",
1554 findMatchesCount(source1, "Comparator<'_a{0,0}> 'b;")
1557 String source2 = "class A<@Q T> {}\n" +
1560 "find annotated type parameter",
1562 findMatchesCount(source2, "class '_A<@Q '_T> {}")
1565 // @todo typed vars constrains (super),
1566 // @todo generic method invocation
1568 //String s83 = "class A {} List<A> a; List b;";
1569 //String s84 = "'a:List 'c;";
1570 //String s84_2 = "'a:List\\<'_\\> 'c;";
1571 //String s84_3 = "'a:List(?>\\<'_\\>) 'c;";
1575 // findMatchesCount(s83,s84),
1580 // "finding list 2",
1581 // findMatchesCount(s83,s84_2),
1586 // "finding list 3",
1587 // findMatchesCount(s83,s84_3),
1592 public void testSearchSubstitutions() {
1593 // searching for parameterized pattern
1594 assertEquals("search for parameterized pattern",findMatchesCount(s14_1,s15),2);
1596 assertEquals("search for parameterized pattern 2",findMatchesCount(s14_2,s15),5);
1598 options.setRecursiveSearch(false);
1600 assertEquals("search for parameterized pattern-non-recursive",findMatchesCount(s14_1,s15),1);
1602 assertEquals("search for parameterized pattern 2-non-recursive",findMatchesCount(s14_2,s15),2);
1604 // typed vars with arrays
1605 assertEquals("typed pattern with array 2-non-recursive",findMatchesCount(s23,s24_2),4);
1607 options.setRecursiveSearch(true);
1609 // searching for parameterized pattern
1610 assertEquals("search for parameterized pattern 3",findMatchesCount(s14_2,s16),1);
1612 // searching for parameterized pattern in complex expr (with field selection)
1613 assertEquals("search for parameterized pattern in field selection",findMatchesCount(s17,s18_1),1);
1615 // searching for parameterized pattern in complex expr (with method call)
1616 assertEquals("search for parameterized pattern with method call",findMatchesCount(s17,s18_2),1);
1618 // searching for parameterized pattern in complex expr (with method call)
1619 assertEquals("search for parameterized pattern with method call ep.2",findMatchesCount(s17,s18_3),4);
1621 // searching for parameterized pattern in definition with initializer
1622 assertEquals("search for same var constraint",findMatchesCount(s19,s20),1);
1624 // searching for semi anonymous parameterized pattern in definition with initializer
1625 assertEquals("search for same var constraint for semi anonymous typed vars",findMatchesCount(s19,s20_2),1);
1627 // support for type var constraint
1628 assertEquals("search for typed var constraint",findMatchesCount(s22,s21_1),1);
1630 // noncompatible same typed var constraints
1632 findMatchesCount(s22,s21_2);
1633 assertFalse("search for noncompatible typed var constraint",false);
1634 } catch(MalformedPatternException e) {
1637 // compatible same typed var constraints
1638 assertEquals("search for same typed var constraint",findMatchesCount(s22,s21_3),1);
1640 // typed var with instanceof
1641 assertEquals("typed instanceof",findMatchesCount(s65,s66),1);
1644 // warn on incomplete instanceof
1645 findMatchesCount(s65, "'_T instanceof");
1647 } catch (MalformedPatternException e) {
1648 assertEquals("Type expected", e.getMessage());
1651 // typed vars with arrays
1652 assertEquals("typed pattern with array",findMatchesCount(s23,s24_1),2);
1654 // typed vars with arrays
1655 assertEquals("typed pattern with array 2",findMatchesCount(s23,s24_2),6);
1657 // typed vars in class name, method name, its return type, parameter type and name
1658 assertEquals("typed pattern in class name, method name, return type, parameter type and name",findMatchesCount(s25,s26),1);
1661 "finding interface",
1662 findMatchesCount(s27,s28),
1666 // finding anonymous type vars
1668 "anonymous typed vars",
1669 findMatchesCount(s29,s30),
1673 // finding descedants
1675 "finding class descendants",
1676 findMatchesCount(s31,s32),
1680 // finding interface implementation
1682 "interface implementation",
1683 findMatchesCount(s33,s34),
1687 // different order of fields and methods
1689 "different order of fields and methods",
1690 findMatchesCount(s35,s36),
1694 // different order of exceptions in throws
1696 "differend order in throws",
1697 findMatchesCount(s37,s38),
1701 // class pattern without extends matches pattern with extends
1703 "match of class without extends to class with it",
1704 findMatchesCount(s39,s40),
1708 // class pattern without extends matches pattern with extends
1710 "match of class without extends to class with it, ep. 2",
1711 findMatchesCount(s41,s42_1),
1715 // class pattern without extends matches pattern with extends
1717 "match of class without extends to class with it, ep 3",
1719 findMatchesCount(s41,s42_2)
1722 assertEquals("match class with fields without initializers", 2, findMatchesCount(s41, "class '_ { '_T '_T2 = '_T3{0,0}; } "));
1724 // typed reference element
1726 "typed reference element",
1727 findMatchesCount(s51,s52),
1731 // empty name of type var
1733 "empty name for typed var",
1734 findMatchesCount(s59,s60),
1738 // comparing method with constructor
1740 "comparing method with constructor",
1741 findMatchesCount(s63,s64),
1745 // comparing method with constructor
1747 "finding nested class",
1748 findMatchesCount(s63_2,s64),
1752 // comparing method with constructor
1754 "finded nested class by special pattern",
1755 findMatchesCount(s63_2,s64_2),
1760 "* regexp for typed var",
1761 findMatchesCount(s61,s62_1),
1766 "+ regexp for typed var",
1767 findMatchesCount(s61,s62_2),
1772 "? regexp for typed var",
1773 findMatchesCount(s61,s62_3),
1778 "cast in method parameters",
1779 findMatchesCount(s67,s68),
1784 "searching for static field in static call",
1786 findMatchesCount(s69,s70)
1790 "searching for static field in static call, 2",
1792 findMatchesCount(s69,s70_2)
1796 "* regexp for anonymous typed var",
1797 findMatchesCount(s61,s62_4),
1802 "+ regexp for anonymous typed var",
1803 findMatchesCount(s61,s62_5),
1808 "? regexp for anonymous typed var",
1809 findMatchesCount(s61,s62_6),
1814 "statement inside anonymous class",
1815 findMatchesCount(s71,s72),
1820 "clever regexp match",
1821 findMatchesCount(s91,s92),
1826 "clever regexp match 2",
1827 findMatchesCount(s91,s92_2),
1832 "clever regexp match 3",
1833 findMatchesCount(s91,s92_3),
1838 public void testSearchJavaDoc() {
1839 // javadoc comment in class
1841 "java doc comment in class",
1843 findMatchesCount(s57,s58)
1847 "java doc comment in class in file",
1849 findMatchesCount(s57_2,s58,true)
1852 // javadoc comment for field
1854 "javadoc comment for field",
1856 findMatchesCount(s57, s58_2)
1859 // javadoc comment for method
1861 "javadoc comment for method",
1863 findMatchesCount(s57, s58_3)
1866 // just javadoc comment search
1868 "just javadoc comment search",
1870 findMatchesCount(s57,s58_4)
1876 findMatchesCount(s83,s84)
1880 "XDoclet metadata 2",
1882 findMatchesCount(s83,s84_2)
1886 "optional tag value match",
1888 findMatchesCount(s57, s58_5)
1892 "multiple tags match +",
1894 findMatchesCount(s75,s76)
1898 "multiple tags match *",
1900 findMatchesCount(s75, s76_2)
1904 "multiple tags match ?",
1906 findMatchesCount(s75, s76_3)
1909 assertEquals("no infinite loop on javadoc matching", 1, findMatchesCount(s57, "/** 'Text */ class '_ { }"));
1912 public void testNamedPatterns() {
1913 String s133 = "class String1 implements java.io.Serializable { " +
1914 "private static final long serialVersionUID = -6849794470754667710L;" +
1915 "private static final ObjectStreamField[] serialPersistentFields = new ObjectStreamField[0];" +
1917 "class StringBuilder1 implements java.io.Serializable {" +
1918 " private void writeObject(java.io.ObjectOutputStream s)\n" +
1919 " throws java.io.IOException {\n" +
1920 " s.defaultWriteObject();\n" +
1922 "private void readObject(java.io.ObjectInputStream s)\n" +
1923 " throws java.io.IOException, ClassNotFoundException {\n" +
1924 " s.defaultReadObject();\n" +
1926 " static final long serialVersionUID = 4383685877147921099L;" +
1928 String s134 = "class '_ implements '_:*Serializable {\n" +
1929 " static final long 'VersionField?:serialVersionUID = '_?;\n" +
1930 " private static final ObjectStreamField[] '_?:serialPersistentFields = '_?; \n" +
1931 " private void '_SerializationWriteHandler?:writeObject (ObjectOutputStream s) throws IOException;\n" +
1932 " private void '_SerializationReadHandler?:readObject (ObjectInputStream s) throws IOException, ClassNotFoundException;\n" +
1933 " Object '_SpecialSerializationReadHandler?:readResolve () throws ObjectStreamException;" +
1934 " Object '_SpecialSerializationWriteHandler?:writeReplace () throws ObjectStreamException;" +
1938 "serialization match",
1939 findMatchesCount(s133,s134),
1943 String s135 = "class SimpleStudentEventActionImpl extends Action { " +
1944 " public ActionForward execute(ActionMapping mapping,\n" +
1945 " ActionForm _form,\n" +
1946 " HttpServletRequest _request,\n" +
1947 " HttpServletResponse _response)" +
1948 " throws Exception {}" +
1950 "public class DoEnrollStudent extends SimpleStudentEventActionImpl { }" +
1951 "public class DoCancelStudent extends SimpleStudentEventActionImpl { }";
1952 String s136 = "public class 'StrutsActionClass extends '_*:Action {" +
1953 " public ActionForward '_AnActionMethod:*execute (ActionMapping '_,\n" +
1954 " ActionForm '_,\n" +
1955 " HttpServletRequest '_,\n" +
1956 " HttpServletResponse '_);" +
1961 findMatchesCount(s135,s136),
1965 final String s123 = "class NodeFilter {} public class MethodFilter extends NodeFilter {\n" +
1966 " private MethodFilter() {}\n" +
1968 " public static NodeFilter getInstance() {\n" +
1969 " if (instance==null) instance = new MethodFilter();\n" +
1970 " return instance;\n" +
1972 " private static NodeFilter instance;\n" +
1974 final String s124 = "class 'Class {\n" +
1975 " private 'Class('_* '_*) {\n" +
1978 " private static '_Class2:* '_Instance;\n" +
1979 " static '_Class2 '_GetInstance() {\n" +
1981 " return '_Instance;\n" +
1987 findMatchesCount(s123,s124),
1991 String s1111 = "if (true) { a=1; b=1; } else { a=1; }\n" +
1992 "if(true) { a=1; } else { a=1; b=1; }\n" +
1993 "if(true) { a=1; b=2; } else { a = 1; b=2; }";
1994 String s1112 = "if (true) { '_a{1,2}; } else { '_a; }";
1997 "same multiple name pattern",
1998 findMatchesCount(s1111,s1112),
2003 public void testHierarchy() {
2004 final String s105 = "class B {} class A extends B { }";
2005 final String s106 = "class '_ extends '_:[ref('T)] {}";
2008 findMatchesCount(s105,s106),
2012 final String s107 = "interface IA {} interface IB extends IA { } interface IC extends IB {} interface ID extends IC {}" +
2013 "class A implements IA {} class B extends A { } class C extends B implements IC {} class D extends C {}";
2014 final String s108 = "class '_ extends 'Type:+A {}";
2015 final String s108_2 = "class '_ implements 'Type:+IA {}";
2018 "extends navigation match",
2019 findMatchesCount(s107,s108),
2024 "implements navigation match",
2026 findMatchesCount(s107,s108_2)
2029 final String s109 = "interface I {} interface I2 extends I {} class A implements I2 {} class B extends A { } class C extends B {} class D { void e() { C c; B b; A a;} }";
2030 final String s110 = "'_:*A '_;";
2031 final String s110_2 = "'_:*I '_;";
2032 final String s110_3 = "'_:*[regex( I ) && ref('T)] '_;";
2033 final String s110_4 = "'_:*[regex( I ) && ref2('T)] '_;";
2035 "extends navigation match in definition",
2036 findMatchesCount(s109,s110),
2041 "implements navigation match in definition 2",
2042 findMatchesCount(s109,s110_2),
2047 "implements navigation match in definition 2 with nested conditions",
2048 findMatchesCount(s109,s110_3),
2053 findMatchesCount(s109,s110_4);
2054 assertFalse("implements navigation match in definition 2 with nested conditions - incorrect cond",false);
2055 } catch(UnsupportedPatternException ex) {}
2057 final String s111 = "interface E {} class A implements E {} class B extends A { int f = 0; } class C extends B {} class D { void e() { C c; B b; A a;} }";
2058 final String s112 = "'_";
2061 findMatchesCount(s111,s112),
2065 final String s113 = "class B {int c; void d() {} } int a; B b; a = 1; b.d(); ++a; int c=a; System.out.println(a); " +
2066 "b.c = 1; System.out.println(b.c); b.c++;";
2067 final String s114 = "'_:[read]";
2068 final String s114_2 = "'_:[write]";
2070 "read symbol match",
2071 findMatchesCount(s113,s114),
2076 "write symbol match",
2077 findMatchesCount(s113,s114_2),
2081 final String s115 = "class B {} public class C {}";
2082 final String s116 = "public class '_ {}";
2084 "public modifier for class",
2085 findMatchesCount(s115,s116),
2089 final String s117 = "class A { int b; void c() { int e; b=1; this.b=1; e=5; " +
2090 "System.out.println(e); " +
2091 "System.out.println(b); System.out.println(this.b);} }";
2092 final String s118 = "this.'Field";
2093 final String s118_2 = "this.'Field:[read]";
2094 final String s118_3 = "this.'Field:[write]";
2099 findMatchesCount(s117,s118)
2103 "fields of class read",
2105 findMatchesCount(s117,s118_2)
2109 "fields of class written",
2111 findMatchesCount(s117,s118_3)
2114 final String s119 = "try { a.b(); } catch(IOException e) { c(); } catch(Exception ex) { d(); }";
2115 final String s120 = "try { '_; } catch('_ '_) { '_; }";
2116 final String s120_2 = "try { '_; } catch(Throwable '_) { '_; }";
2118 "catches loose matching",
2119 findMatchesCount(s119,s120),
2124 "catches loose matching 2",
2125 findMatchesCount(s119,s120_2),
2129 final String s121 = "class A { private int a; class Inner {} } " +
2130 "class B extends A { private int a; class Inner2 {} }";
2131 final String s122 = "class '_ { int '_:* ; }";
2132 final String s122_2 = "class '_ { int '_:+hashCode (); }";
2133 final String s122_3 = "class '_ { class '_:* {} }";
2135 "hierarchical matching",
2136 findMatchesCount(s121,s122),
2141 "hierarchical matching 2",
2142 findMatchesCount(s121,s122_2),
2147 "hierarchical matching 3",
2148 findMatchesCount(s121,s122_3),
2153 public void testSearchInCommentsAndLiterals() {
2155 "// This is some comment\n" +
2156 "/* This is another\n comment*/\n" +
2157 "// Some garbage\n"+
2158 "/** And now third comment*/\n" +
2159 "/** Some garbage*/ }";
2160 String s2 = "// 'Comment:[regex( .*(?:comment).* )]";
2161 String s3 = "/** 'Comment:[regex( .*(?:comment).* )] */";
2162 String s2_2 = "/* 'Comment:[regex( .*(?:comment).* )] */";
2166 findMatchesCount(s1,s2),
2171 "Comment matching, 2",
2173 findMatchesCount(s1,s2_2)
2177 "Java doc matching",
2178 findMatchesCount(s1,s3),
2182 String s4 = "\"'test\", \"another test\", \"garbage\"";
2183 String s5 = "\"'test:[regex( .*test.* )]\"";
2184 String s6 = "\"''test\"";
2188 findMatchesCount(s4,s5),
2193 "Literal content with escaping",
2194 findMatchesCount(s4,s6),
2198 String s7 = "\"aaa\"";
2199 String s8 = "\"'test:[regex( aaa )]\"";
2202 "Simple literal content",
2203 findMatchesCount(s7,s8),
2207 String s9 = "\" aaa \" \" bbb \" \" ccc ccc aaa\"";
2208 String s10 = "\"'test:[regexw( aaa|ccc )]\"";
2209 String s11 = "\"'test:[regexw( bbb )]\"";
2212 "Whole word literal content with alternations",
2213 findMatchesCount(s9,s10),
2218 "Whole word literal content",
2219 findMatchesCount(s9,s11),
2223 String s12 = "assert agentInfo != null : \"agentInfo is null\";\n" +
2224 "assert addresses != null : \"addresses is null\";";
2225 String s13 = "assert '_exp != null : \"'_exp is null\";";
2228 "reference to substitution in comment",
2229 findMatchesCount(s12,s13),
2233 String s14 = "\"(some text with special chars)\"," +
2236 String s15 = "\"('a:[regexw( some )])\"";
2239 "meta char in literal",
2241 findMatchesCount(s14,s15)
2244 String s16 = "/**\n" +
2245 "* Created by IntelliJ IDEA.\n" +
2247 "* Date: Nov 15, 2005\n" +
2248 "* Time: 4:23:29 PM\n" +
2249 "* To change this template use File | Settings | File Templates.\n" +
2251 "public class Y {\n" +
2253 String s17 = "/**\n" +
2254 "* Created by IntelliJ IDEA.\n" +
2255 "* User: '_USER\n" +
2256 "* Date: '_DATE\n" +
2257 "* Time: '_TIME\n" +
2258 "* To change this template use File | Settings | File Templates.\n" +
2263 "complete comment match",
2265 findMatchesCount(s16,s17,true)
2268 String s18 = "public class A {\n" +
2269 " private void f(int i) {\n" +
2270 " int g=0; //sss\n" +
2273 String s19 = "class '_c {\n" +
2274 " '_type '_f('_t '_p){\n" +
2279 "statement match with comment",
2281 findMatchesCount(s18,s19)
2285 public void testOther() {
2287 "optional init match in definition",
2288 findMatchesCount(s73,s74),
2294 findMatchesCount(s77,s78),
2299 "body of method by block search",
2300 findMatchesCount(s79,s80),
2306 "first matches, next not",
2307 findMatchesCount(s95,s96),
2311 final String s97 = "class A { int c; void b() { C d; } } class C { C() { A a; a.b(); a.c=1; } }";
2312 final String s98 = "'_.'_:[ref('T)] ()";
2313 final String s98_2 = "'_.'_:[ref('T)]";
2314 final String s98_3 = "'_:[ref('T)].'_ ();";
2315 final String s98_4 = "'_:[ref('T)] '_;";
2318 "method predicate match",
2319 findMatchesCount(s97,s98),
2324 "field predicate match",
2325 findMatchesCount(s97,s98_2),
2330 "dcl predicate match",
2331 findMatchesCount(s97,s98_3),
2335 final String s99 = " char s = '\\u1111'; char s1 = '\\n'; ";
2336 final String s100 = " char 'var = '\\u1111'; ";
2337 final String s100_2 = " char 'var = '\\n'; ";
2339 "char constants in pattern",
2340 findMatchesCount(s99,s100),
2345 "char constants in pattern 2",
2346 findMatchesCount(s99,s100_2),
2351 "class predicate match (from definition)",
2352 findMatchesCount(s97,s98_4),
2356 final String s125 = "a=1;";
2357 final String s126 = "'t:[regex(a)]";
2360 findMatchesCount(s125,s126);
2361 assertFalse("spaces around reg exp check",false);
2362 } catch(MalformedPatternException ex) {}
2364 final String s101 = "class A { void b() { String d; String e; String[] f; f.length=1; f.length=1; } }";
2365 final String s102 = "'_:[ref('T)] '_;";
2369 findMatchesCount(s101,s102),
2373 final String s103 = " a=1; ";
2374 final String s104 = "'T:{ ;";
2376 findMatchesCount(s103,s104);
2377 assertFalse("incorrect reg exp",false);
2378 } catch(MalformedPatternException ex) {
2381 final String s106 = "'_ReturnType 'MethodName('_ParameterType '_Parameter);";
2382 final String s105 = " aaa; ";
2385 findMatchesCount(s105,s106);
2386 assertFalse("incorrect reg exp 2",false);
2387 } catch(UnsupportedPatternException ex) {
2390 String s107 = "class A {\n" +
2401 String s108 = " /*" +
2405 assertEquals("finding comments without typed var", 1, findMatchesCount(s107,s108));
2407 String s109 = "class A { void b(); int b(int c); char d(char e); }\n" +
2408 "A a; a.b(1); a.b(2); a.b(); a.d('e'); a.d('f'); a.d('g');";
2409 String s110 = "'_a.'_b:[exprtype( int ) ]('_c*);";
2410 assertEquals("caring about method return type", 2, findMatchesCount(s109,s110));
2412 String s111 = "class A { void getManager() { getManager(); } };\n" +
2413 "class B { void getManager() { getManager(); getManager(); } };";
2414 String s112 = "'Instance?:[exprtype( B )].getManager()";
2415 assertEquals("caring about missing qualifier type", 2, findMatchesCount(s111,s112));
2417 String s112a = "'Instance?:[regex( B )].getManager()";
2418 assertEquals("static query should not match instance method", 0, findMatchesCount(s111, s112a));
2420 String s112b = "B.getManager()";
2421 assertEquals("static query should not match instance method 2", 0, findMatchesCount(s111, s112b));
2423 String s113 = "class A { static void a() { a(); }}\n" +
2424 "class B { static void a() { a(); a(); }}\n";
2425 String s114 = "'_Q?:[regex( B )].a()";
2426 assertEquals("should care about implicit class qualifier", 2, findMatchesCount(s113, s114));
2428 String s114a = "B.a()";
2429 assertEquals("should match simple implicit class qualifier query", 2, findMatchesCount(s113, s114a));
2431 String s114b = "'_Q?:[exprtype( B )].a()";
2432 assertEquals("instance query should not match static method", 0, findMatchesCount(s113, s114b));
2434 String s115 = "class A { int a; int f() { return a; }}\n" +
2435 "class B { int a; int g() { return a + a; }}\n";
2436 String s116 = "'_Instance?:[exprtype( B )].a";
2437 assertEquals("should care about implicit instance qualifier", 2, findMatchesCount(s115, s116));
2439 String s116a = "A.a";
2440 assertEquals("should not match instance method", 0, findMatchesCount(s115, s116a));
2442 String s117 = "class A { static int a; static int f() { return a; }}\n" +
2443 "class B { static int a; static int g() { return a + a; }}\n";
2444 String s118 = "'_Q?:[regex( B )].a";
2445 assertEquals("should care about implicit class qualifier for field", 2, findMatchesCount(s117, s118));
2447 // b) hierarchy navigation support
2448 // c) or search support
2450 // e) xml search (down-up, nested query), navigation from xml representation <-> java code
2451 // f) impl data conversion (jdk 1.5 style) <-> other from (replace support)
2454 // @todo different navigation on sub/supertyping relation (fixed depth), methods implementing interface,
2455 // g. like predicates
2457 // more context for top level classes, difference with interface, etc
2460 // @todo matches out of context
2461 // @todo proper regexp support
2463 // @todo define strict equality of the matches
2464 // @todo search for field selection retrieves packages also
2467 public void testFQNInPatternAndVariableConstraints() {
2468 String s1 = "import java.awt.List;\n" +
2469 "class A { List l; }";
2470 String s1_2 = "import java.util.List;\n" +
2471 "class A { List l; }";
2472 String s2 = "class '_ { 'Type:java\\.util\\.List '_Field; }";
2474 assertEquals("No matches for qualified class",findMatchesCount(s1,s2,true),0);
2475 assertEquals("Matches for qualified class",findMatchesCount(s1_2,s2,true),1);
2477 String s3 = "import java.util.ArrayList;\n" +
2478 "class A { ArrayList l; }";
2479 String s4 = "class '_ { 'Type:*java\\.util\\.Collection '_Field; }";
2480 assertEquals("Matches for qualified class in hierarchy",findMatchesCount(s3,s4,true),1);
2482 String s5 = "import java.util.List;\n" +
2483 "class A { { List l = new List(); l.add(\"1\"); } }";
2484 String s5_2 = "import java.awt.List;\n" +
2485 "class A { { List l = new List(); l.add(\"1\"); } }";
2486 String s6 = "'a:[exprtype( java\\.util\\.List )]";
2487 String s6_2 = "'a:[exprtype( *java\\.util\\.Collection )]";
2488 String s6_3 = "java.util.List '_a = '_b?;";
2490 assertEquals("Matches for qualified expr type",findMatchesCount(s5,s6,true), 2);
2491 assertEquals("No matches for qualified expr type",findMatchesCount(s5_2,s6,true),0);
2492 assertEquals("Matches for qualified expr type in hierarchy",findMatchesCount(s5,s6_2,true), 2);
2494 assertEquals("Matches for qualified var type in pattern",findMatchesCount(s5,s6_3,true),1);
2495 assertEquals("No matches for qualified var type in pattern",findMatchesCount(s5_2,s6_3,true),0);
2497 String s7 = "import java.util.List;\n" +
2498 "class A extends List { }";
2499 String s7_2 = "import java.awt.List;\n" +
2500 "class A extends List {}";
2502 String s8 = "class 'a extends java.util.List {}";
2504 assertEquals("Matches for qualified type in pattern",findMatchesCount(s7,s8,true),1);
2505 assertEquals("No matches for qualified type in pattern",findMatchesCount(s7_2,s8,true),0);
2507 String s9 = "String.intern(\"1\");\n" +
2508 "java.util.Collections.sort(null);" +
2509 "java.util.Collections.sort(null);";
2510 String s10 = "java.lang.String.'_method ( '_params* )";
2511 assertEquals("FQN in class name",1,findMatchesCount(s9,s10,false));
2514 public void testAnnotations() throws Exception {
2515 String s1 = "@MyBean(\"\")\n" +
2516 "@MyBean2(\"\")\n" +
2517 "public class TestBean {}\n" +
2518 "@MyBean2(\"\")\n" +
2519 "@MyBean(value=\"\")\n" +
2520 "public class TestBean2 {}\n" +
2521 "public class TestBean3 {}\n" +
2522 "@MyBean(\"a\")\n" +
2523 "@MyBean2(\"a\")\n" +
2524 "public class TestBean4";
2525 String s2 = "@MyBean(\"\")\n" +
2526 "@MyBean2(\"\")\n" +
2527 "public class '_a {}\n";
2529 assertEquals("Simple find annotated class",2,findMatchesCount(s1,s2,false));
2530 assertEquals("Match value of anonymous name value pair 1", 1, findMatchesCount(s1, "@MyBean(\"a\") class '_a {}"));
2531 assertEquals("Match value of anonymous name value pair 2", 2, findMatchesCount(s1, "@MyBean(\"\") class '_a {}"));
2533 String s3 = "@VisualBean(\"????????? ?????????? ? ??\")\n" +
2534 "public class TestBean\n" +
2536 " @VisualBeanField(\n" +