| package com.intellij.structuralsearch; |
| |
| import com.intellij.idea.Bombed; |
| import com.intellij.openapi.application.PluginPathManager; |
| import com.intellij.openapi.fileTypes.StdFileTypes; |
| import com.intellij.psi.*; |
| import com.intellij.structuralsearch.impl.matcher.MatcherImplUtil; |
| import com.intellij.testFramework.PlatformTestUtil; |
| import org.jetbrains.annotations.NotNull; |
| |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.Calendar; |
| import java.util.List; |
| |
| /** |
| * @author Maxim.Mossienko |
| */ |
| @SuppressWarnings({"HardCodedStringLiteral"}) |
| public class StructuralSearchTest extends StructuralSearchTestCase { |
| private static final String s1 = |
| "debug(\"In action performed:\"+event);"+ |
| "project = (Project)event.getDataContext().getData(DataConstants.PROJECT);" + |
| "CodeEditorManager.getInstance(project).commitAllToPsiFile();" + |
| "file = (PsiFile) event.getDataContext().getData(\"psi.File\"); " + |
| "((dialog==null)?" + |
| " (dialog = new SearchDialog()):" + |
| " dialog" + |
| ").show();"; |
| |
| private static final String s2 = "((dialog==null)? (dialog = new SearchDialog()): dialog).show();"; |
| private static final String s3 = "dialog = new SearchDialog()"; |
| |
| private static final String s4 = |
| " do { " + |
| " pattern = pattern.getNextSibling(); " + |
| " } " + |
| " while (pattern!=null && filterLexicalNodes(pattern));"; |
| |
| private static final String s5 = |
| "{ System.out.println();" + |
| " while(false) { " + |
| " do { " + |
| " pattern = pattern.getNextSibling(); " + |
| " } " + |
| " while (pattern!=null && filterLexicalNodes(pattern)); " + |
| " } " + |
| " do { " + |
| " pattern = pattern.getNextSibling(); " + |
| " } while (pattern!=null && filterLexicalNodes(pattern));" + |
| " { { " + |
| " do { " + |
| " pattern = pattern.getNextSibling(); " + |
| " } while (pattern!=null && filterLexicalNodes(pattern));" + |
| " } }" + |
| "}"; |
| |
| private static final String s6 = |
| " do { " + |
| " pattern.getNextSibling(); " + |
| " } " + |
| " while (pattern!=null && filterLexicalNodes(pattern));"; |
| |
| private static final String s7 = |
| " if (true) throw new UnsupportedPatternException(statement.toString());" + |
| " if (true) { " + |
| " throw new UnsupportedPatternException(statement.toString());" + |
| " } "; |
| |
| private static final String s8 = |
| " if (true) { " + |
| " throw new UnsupportedPatternException(statement.toString());" + |
| " } "; |
| |
| private static final String s9 = " if (true) throw new UnsupportedPatternException(statement.toString());"; |
| |
| private static final String s10 = "listener.add(new Runnable() { public void run() {} });"; |
| private static final String s11 = " new XXX()"; |
| |
| private static final String s12 = |
| "new Runnable() {" + |
| " public void run() {" + |
| " matchContext.getSink().matchingFinished();" + |
| " } " + |
| " }"; |
| |
| private static final String s13 = "new Runnable() {}"; |
| private static final String s14_1 = "if (true) { aaa(var); }"; |
| private static final String s14_2 = "if (true) { aaa(var); bbb(var2); }\n if(1==1) { system.out.println('o'); }"; |
| private static final String s15 = "'T;"; |
| private static final String s16 = "if('_T) { '_T2; }"; |
| private static final String s17 = |
| "token.getText().equals(token2.getText());" + |
| "token.getText().equals(token2.getText2());" + |
| "token.a.equals(token2.b);" + |
| "token.a.equals(token2.a);"; |
| private static final String s18_1 = "'_T1.'_T2.equals('_T3.'_T2);"; |
| private static final String s18_2 = "'_T1.'_T2().equals('_T3.'_T2());"; |
| private static final String s18_3 = "'_T1.'_T2"; |
| private static final String s19 = "Aaa a = (Aaa)b; Aaa c = (Bbb)d;"; |
| private static final String s20 = "'_T1 'T2 = ('_T1)'_T3;"; |
| private static final String s20_2 = "'_T1 '_T2 = ('_T1)'_T3;"; |
| private static final String s21_1 = "'_T1:Aa* 'T2 = ('_T1)'_T3;"; |
| private static final String s21_2 = "'_T1:A* 'T2 = ( '_T1:A+ )'_T3;"; |
| private static final String s21_3 = "'_T1:Aa* 'T2 = ( '_T1:Aa* )'_T3;"; |
| |
| private static final String s22 = "Aaa a = (Aaa)b; Bbb c = (Bbb)d;"; |
| |
| private static final String s23 = "a[i] = 1; b[a[i]] = f(); if (a[i]==1) return b[c[i]];"; |
| private static final String s24_1 = "'T['_T2:.*i.* ] = '_T3;"; |
| private static final String s24_2 = "'T['_T2:.*i.* ]"; |
| private static final String s25 = "class MatcherImpl { void doMatch(int a) {} }\n" + |
| "class Matcher { abstract void doMatch(int a);}\n " + |
| "class Matcher2Impl { void doMatch(int a, int b) {} } "; |
| private static final String s26 = "class 'T:.*Impl { '_T2 '_T3('_T4 '_T5) {\n\n} } "; |
| private static final String s27 = "class A {} interface B {}"; |
| private static final String s28 = "interface 'T {}"; |
| |
| private static final String s29 = "class A { void B(int C) {} } class D { void E(double e) {} }"; |
| private static final String s30 = "class '_ { void '_('_:int '_); } "; |
| |
| private static final String s31 = "class A extends B { } class D extends B { } class C extends C {}"; |
| private static final String s32 = "class '_ extends B { } "; |
| |
| private static final String s33 = "class A implements B,C { } class D implements B,D { } class C2 implements C,B {}"; |
| private static final String s34 = "class '_ implements B,C { } "; |
| |
| private static final String s35 = "class A { int b; double c; void d() {} int e() {} } " + |
| "class A2 { int b; void d() {} }"; |
| private static final String s36 = "class '_ { double '_; int '_; int '_() {} void '_() {} } "; |
| |
| private static final String s37 = "class A { void d() throws B,C,D {} } class A2 { void d() throws B,C {} }"; |
| private static final String s38 = "class 'T { '_ '_() throws D,C {} } "; |
| |
| private static final String s39 = "class A extends B { } class A2 { }"; |
| private static final String s40 = "class 'T { } "; |
| |
| private static final String s41 = "class A extends B { int a = 1; } class B { int[] c= new int[2]; } " + |
| "class D { double e; } class E { int d; } "; |
| private static final String s42_1 = "class '_ { '_T '_T2 = '_T3; } "; |
| private static final String s42_2 = "class '_ { '_T '_T2; } "; |
| |
| private static final String s43 = "interface A extends B { int B = 1; } " + |
| "interface D { public final static double e = 1; } " + |
| "interface E { final static ind d = 2; } " + |
| "interface F { } "; |
| private static final String s44 = "interface '_ { '_T 'T2 = '_T3; } "; |
| private static final String s45 = "class A extends B { private static final int B = 1; } " + |
| "class C extends D { int B = 1; }" + |
| "class E { }"; |
| |
| private static final String s46 = "class '_ { final static private '_T 'T2 = '_T3; } "; |
| private static final String s46_2 = "class '_ { '_T 'T2 = '_T3; } "; |
| |
| private static final String s47 = "class C { java.lang.String t; } class B { BufferedString t2;} class A { String p;} "; |
| private static final String s48 = "class '_ { String '_; }"; |
| |
| private static final String s49 = "class C { void a() throws java.lang.RuntimeException {} } class B { BufferedString t2;}"; |
| private static final String s50 = "class '_ { '_ '_() throws RuntimeException; }"; |
| |
| private static final String s51 = "class C extends B { } class B extends A { } class E {}"; |
| private static final String s52 = "class '_ extends '_ { }"; |
| |
| private static final String s53 = "class C { " + |
| " String a = System.getProperty(\"abcd\"); " + |
| " static { String s = System.getProperty(a); }" + |
| " static void b() { String s = System.getProperty(a); }" + |
| " }"; |
| private static final String s54 = "System.getProperty('T)"; |
| |
| private static final String s55 = " a = b.class; "; |
| private static final String s56 = "'T.class"; |
| |
| private static final String s57 = "{ /** @author Maxim */ class C { " + |
| "} " + |
| "class D {" + |
| "/** @serializable */ private int value; " + |
| "/** @since 1.4 */ void a() {} "+ |
| "}" + |
| "class F { " + |
| "/** @since 1.4 */ void a() {} "+ |
| "/** @serializable */ private int value2; " + |
| "}" + |
| "class G { /** @param a*/ void a() {} } }"; |
| private static final String s57_2 = "/** @author Maxim */ class C { " + |
| "} " + |
| "class D {" + |
| "/** @serializable */ private int value; " + |
| "/** @since 1.4 */ void a() {} "+ |
| "}" + |
| "class F { " + |
| "/** @since 1.4 */ void a() {} "+ |
| "/** @serializable */ private int value2; " + |
| "}" + |
| "class G { /** @param a*/ void a() {} }"; |
| private static final String s58 = "/** @'T '_T2 */ class '_ { }"; |
| private static final String s58_2 = "class '_ { /** @serializable '_ */ '_ '_; }"; |
| private static final String s58_3 = "class '_ { /** @'T 1.4 */ '_ '_() {} }"; |
| private static final String s58_4 = "/** @'T '_T2 */"; |
| private static final String s58_5 = "/** @'T '_T2? */"; |
| |
| private static final String s59 = "interface A { void B(); }"; |
| private static final String s60 = "interface '_ { void '_(); }"; |
| |
| private static final String s61 = "{ a=b; c=d; return; } { e=f; } {}"; |
| private static final String s62_1 = "{ 'T*; }"; |
| private static final String s62_2 = "{ 'T+; }"; |
| private static final String s62_3 = "{ 'T?; }"; |
| |
| private static final String s62_4 = "{ '_*; }"; |
| private static final String s62_5 = "{ '_+; }"; |
| private static final String s62_6 = "{ '_?; }"; |
| |
| private static final String s63 = " class A { A() {} } class B { public void run() {} }"; |
| private static final String s63_2 = " class A { A() {} " + |
| "class B { public void run() {} } " + |
| "class D { public void run() {} } " + |
| "} " + |
| "class C {}"; |
| private static final String s64 = " class 'T { public void '_T2:run () {} }"; |
| private static final String s64_2 = "class '_ { class 'T { public void '_T2:run () {} } }"; |
| |
| private static final String s65 = " if (A instanceof B) {} else if (B instanceof C) {}"; |
| private static final String s66 = " '_T instanceof '_T2:B"; |
| |
| private static final String s67 = " buf.append((VirtualFile)a);"; |
| private static final String s68 = " (VirtualFile)'T"; |
| |
| private static final String s69 = " System.getProperties(); System.out.println(); java.lang.System.out.println(); some.other.System.out.println();"; |
| private static final String s70 = " System.out "; |
| private static final String s70_2 = " java.lang.System.out "; |
| |
| private static final String s71 = " class A { " + |
| "class D { D() { c(); } }" + |
| "void a() { c(); new MouseListenener() { void b() { c(); } } }" + |
| " }"; |
| private static final String s72 = " c(); "; |
| |
| private static final String s73 = " class A { int A; static int B=5; public abstract void a(int c); void q() { ind d=7; } }"; |
| private static final String s74 = " '_Type 'Var = '_Init?; "; |
| private static final String s75 = "{ /** @class aClass\n @author the author */ class A {}\n" + |
| " /** */ class B {}\n" + |
| " /** @class aClass */ class C {} }"; |
| private static final String s76 = " /** @'_tag+ '_value+ */"; |
| private static final String s76_2 = " /** @'_tag* '_value* */"; |
| private static final String s76_3 = " /** @'_tag? '_value? */ class 't {}"; |
| |
| private static final String s77 = " new ActionListener() {} "; |
| private static final String s78 = " class 'T:.*aaa {} "; |
| |
| private static final String s79 = " class A { static { int c; } void a() { int b; b=1; }} "; |
| private static final String s80 = " { '_T 'T3 = '_T2?; '_*; } "; |
| |
| private static final String s81 = "class Pair<First,Second> {" + |
| " <C,F> void a(B<C> b, D<F> e) throws C {" + |
| " P<Q> r = (S<T>)null;"+ |
| " Q q = null; "+ |
| " if (r instanceof S<T>) {}"+ |
| " } " + |
| "} class Q { void b() {} } "; |
| |
| private static final String s81_2 = "class Double<T> {} class T {} class Single<First extends A & B> {}"; |
| |
| private static final String s82 = "class '_<'T+> {}"; |
| private static final String s82_2 = "'_Expr instanceof '_Type<'_Parameter+>"; |
| private static final String s82_3 = "( '_Type<'_Parameter+> ) '_Expr"; |
| private static final String s82_4 = "'_Type<'_Parameter+> 'a = '_Init?;"; |
| private static final String s82_5 = "class '_ { <'_+> '_Type 'Method('_* '_*); }"; |
| private static final String s82_6 = "class '_<'_+ extends 'res+> {}"; |
| private static final String s82_7 = "'Type"; |
| |
| private static final String s83 = "/**\n" + |
| " * @hibernate.class\n" + |
| " * table=\"CATS\"\n" + |
| " */\n" + |
| "public class Cat {\n" + |
| " private Long id; // identifier\n" + |
| " private Date birthdate;\n" + |
| " /**\n" + |
| " * @hibernate.id\n" + |
| " * generator-class=\"native\"\n" + |
| " * column=\"CAT_ID\"\n" + |
| " */\n" + |
| " public Long getId() {\n" + |
| " return id;\n" + |
| " }\n" + |
| " private void setId(Long id) {\n" + |
| " this.id=id;\n" + |
| " }\n" + |
| "\n" + |
| " /**\n" + |
| " * @hibernate.property\n" + |
| " * column=\"BIRTH_DATE\"\n" + |
| " */\n" + |
| " public Date getBirthdate() {\n" + |
| " return birthdate;\n" + |
| " }\n" + |
| " void setBirthdate(Date date) {\n" + |
| " birthdate = date;\n" + |
| " }\n" + |
| " /**\n" + |
| " * @hibernate.property\n" + |
| " * column=\"SEX\"\n" + |
| " * not-null=\"true\"\n" + |
| " * update=\"false\"\n" + |
| " */\n" + |
| " public char getSex() {\n" + |
| " return sex;\n" + |
| " }\n" + |
| " void setSex(char sex) {\n" + |
| " this.sex=sex;\n" + |
| " }\n" + |
| "}"; |
| |
| private static final String s84 = " /**\n" + |
| " * @hibernate.property\n" + |
| " * 'Property+\n" + |
| " */\n"; |
| |
| private static final String s84_2 = " /**\n" + |
| " * @hibernate.property\n" + |
| " * update=\"fa.se\"\n" + |
| " */\n"; |
| |
| private static final String s85 = "{ int a; a=1; a=1; return a; }"; |
| private static final String s86 = "'T; 'T;"; |
| |
| private static final String s87 = " getSomething(\"1\"); a.call(); "; |
| private static final String s88 = " '_Instance.'Call('_*); "; |
| private static final String s88_2 = " 'Call('_*); "; |
| private static final String s88_3 = " '_Instance?.'Call('_*); "; |
| private static final String s89 = "{ a = 1; b = 2; c=3; }"; |
| private static final String s90 = "{ '_T*; '_T2*; }"; |
| private static final String s90_2 = " { '_T*; '_T2*; '_T3+; } "; |
| private static final String s90_3 = " { '_T+; '_T2+; '_T3+; '_T4+; } "; |
| private static final String s90_4 = " { '_T{1,3}; '_T2{2}; } "; |
| private static final String s90_5 = " { '_T{1}?; '_T2*?; '_T3+?; } "; |
| private static final String s90_6 = " { '_T{1}?; '_T2{1,2}?; '_T3+?; '_T4+?; } "; |
| |
| private static final String s91 = "class a {\n" + |
| " void b() {\n" + |
| " int c;\n" + |
| "\n" + |
| " c = 1;\n" + |
| " b();\n" + |
| " a a1;\n" + |
| " }\n" + |
| "}"; |
| private static final String s92 = "'T:a"; |
| private static final String s92_2 = "'T:b"; |
| private static final String s92_3 = "'T:c"; |
| |
| private static final String s93 = " class A {" + |
| "private int field;" + |
| "public void b() {}" + |
| "}"; |
| private static final String s94 = " class '_ {" + |
| "private void b() {}" + |
| "}"; |
| private static final String s94_2 = " class '_ {" + |
| "public void b() {}" + |
| "}"; |
| private static final String s94_3 = " class '_ {" + |
| "protected int field;" + |
| "}"; |
| private static final String s94_4 = " class '_ {" + |
| "private int field;" + |
| "}"; |
| |
| private static final String s95 = " class Clazz {" + |
| "private int field;" + |
| "private int field2;" + |
| "private int fiel-d2;" + |
| "}"; |
| |
| private static final String s96 = " class '_ {" + |
| "private int 'T+:field.* ;" + |
| "}"; |
| |
| public void testSearchExpressions() { |
| assertFalse("subexpr match",findMatchesCount(s2,s3)==0); |
| assertEquals("search for new ",findMatchesCount(s10,s11),0); |
| assertEquals("search for anonymous classes",findMatchesCount(s12,s13),1); |
| // expr in definition initializer |
| assertEquals( |
| "expr in def initializer", |
| 3, |
| findMatchesCount(s53,s54) |
| ); |
| |
| // a.class expression search |
| assertEquals( |
| "a.class pattern", |
| findMatchesCount(s55,s56), |
| 1 |
| ); |
| |
| String complexCode = "interface I { void b(); } interface I2 extends I {} class I3 extends I {} " + |
| "class A implements I2 { void b() {} } class B implements I3 { void b() {}} " + |
| "I2 a; I3 b; a.b(); b.b(); b.b(); A c; B d; c.b(); d.b(); d.b(); "; |
| |
| String exprTypePattern1 = "'t:[exprtype( I2 )].b();"; |
| String exprTypePattern2 = "'t:[!exprtype( I2 )].b();"; |
| |
| String exprTypePattern3 = "'t:[exprtype( *I2 )].b();"; |
| String exprTypePattern4 = "'t:[!exprtype( *I2 )].b();"; |
| |
| assertEquals( |
| "expr type condition", |
| findMatchesCount(complexCode,exprTypePattern1), |
| 1 |
| ); |
| |
| assertEquals( |
| "expr type condition 2", |
| 5, |
| findMatchesCount(complexCode,exprTypePattern2) |
| ); |
| |
| assertEquals( |
| "expr type condition 3", |
| findMatchesCount(complexCode,exprTypePattern3), |
| 2 |
| ); |
| |
| assertEquals( |
| "expr type condition 4", |
| findMatchesCount(complexCode,exprTypePattern4), |
| 4 |
| ); |
| |
| String complexCode2 = "enum X { XXX, YYY }\n class C { static void ordinal() {} void test() { C c; c.ordinal(); c.ordinal(); X.XXX.ordinal(); } }"; |
| assertEquals( |
| "expr type condition with enums", |
| findMatchesCount(complexCode2, "'t:[exprtype( *java\\.lang\\.Enum )].ordinal()"), |
| 1 |
| ); |
| |
| assertEquals( |
| "no smart detection of search target", |
| findMatchesCount("processInheritors(1,2,3,4); processInheritors(1,2,3); processInheritors(1,2,3,4,5,6);","'instance?.processInheritors('_param1{1,6});"), |
| 3 |
| ); |
| |
| String arrays = "int[] a = new int[20];\n" + |
| "byte[] b = new byte[30]"; |
| String arrayPattern = "new int[$a$]"; |
| assertEquals( |
| "Improper array search", |
| 1, |
| findMatchesCount(arrays,arrayPattern) |
| ); |
| |
| String someCode = "a *= 2; a+=2;"; |
| String otherCode = "a *= 2;"; |
| |
| assertEquals( |
| "Improper *= 2 search", |
| 1, |
| findMatchesCount(someCode,otherCode) |
| ); |
| |
| String s1 = "Thread t = new Thread(\"my thread\",\"my another thread\") {\n" + |
| " public void run() {\n" + |
| " // do stuff\n" + |
| " }\n" + |
| "}"; |
| String s2 = "new Thread('args*) { '_Other* }"; |
| |
| assertEquals( |
| "Find inner class parameters", |
| 2, |
| findMatchesCount(s1,s2) |
| ); |
| |
| String s3 = "Thread t = new Thread(\"my thread\") {\n" + |
| " public void run() {\n" + |
| " // do stuff\n" + |
| " }\n" + |
| "};"; |
| String s4 = "new Thread($args$)"; |
| |
| assertEquals( |
| "Find inner class by new", |
| 1, |
| findMatchesCount(s3,s4) |
| ); |
| |
| String s5 = "class A {\n" + |
| "public static <T> T[] copy(T[] array, Class<T> aClass) {\n" + |
| " int i = (int)0;\n" + |
| " int b = (int)0;\n" + |
| " return (T[])array.clone();\n" + |
| " }\n" + |
| "}"; |
| String s6 = "($T$[])$expr$"; |
| |
| assertEquals( |
| "Find cast to array", |
| 1, |
| findMatchesCount(s5,s6) |
| ); |
| |
| String s7 = "import java.math.BigDecimal;\n" + |
| "\n" + |
| "public class Prorator {\n" + |
| " public void prorate(BigDecimal[] array) {\n" + |
| " // do nothing\n" + |
| " }\n" + |
| " public void prorate2(java.math.BigDecimal[] array) {\n" + |
| " // do nothing\n" + |
| " }\n" + |
| " public void prorate(BigDecimal bd) {\n" + |
| " // do nothing\n" + |
| " }\n" + |
| "\n" + |
| " public static void main(String[] args) {\n" + |
| " BigDecimal[] something = new BigDecimal[2];\n" + |
| " java.math.BigDecimal[] something2 = new BigDecimal[2];\n" + |
| " something[0] = new BigDecimal(1.0);\n" + |
| " something[1] = new BigDecimal(1.0);\n" + |
| "\n" + |
| " Prorator prorator = new Prorator();\n" + |
| "\n" + |
| "// ---------------------------------------------------\n" + |
| "// the line below should've been found, in my opinion.\n" + |
| "// --------------------------------------------------\n" + |
| " prorator.prorate(something);\n" + |
| " prorator.prorate(something2);\n" + |
| |
| " prorator.prorate(something[0]);\n" + |
| " prorator.prorate(something[1]);\n" + |
| " prorator.prorate(something[0]);\n" + |
| " }\n" + |
| "}"; |
| String s8 = "'_Instance.'_MethodCall:[regex( prorate )]('_Param:[exprtype( BigDecimal\\[\\] )]) "; |
| |
| assertEquals( |
| "Find method call with array for parameter expr type", |
| 2, |
| findMatchesCount(s7,s8,true) |
| ); |
| |
| String s13 = "try { } catch(Exception e) { e.printStackTrace(); }"; |
| String s14 = "'_Instance.'_MethodCall('_Parameter*)"; |
| |
| assertEquals( |
| "Find statement in catch", |
| 1, |
| findMatchesCount(s13,s14) |
| ); |
| |
| String s9 = "int a[] = new int[] { 1,2,3,4};\n" + |
| "int b[] = { 2,3,4,5 };\n" + |
| "Object[] c = new Object[] { \"\", null};"; |
| String s10 = "new '_ []{ '_* }"; |
| String s10_2 = "new int []{ '_* }"; |
| |
| assertEquals( |
| "Find array instatiation", |
| 3, |
| findMatchesCount(s9,s10) |
| ); |
| |
| assertEquals( |
| "Find array instatiation, 2", |
| 2, |
| findMatchesCount(s9,s10_2) |
| ); |
| } |
| |
| public void testLiteral() { |
| String s = "class A {\n" + |
| " static String a = 1;\n" + |
| " static String s = \"aaa\";\n" + |
| " static String s2;\n" + |
| "}"; |
| String s2 = "static String '_FieldName = '_Init?:[!regex( \".*\" )];"; |
| String s2_2 = "static String '_FieldName = '_Init:[!regex( \".*\" )];"; |
| |
| assertEquals( |
| "Literal", |
| 2, |
| findMatchesCount(s,s2) |
| ); |
| |
| assertEquals( |
| "Literal, 2", |
| 1, |
| findMatchesCount(s,s2_2) |
| ); |
| } |
| |
| public void testCovariantArraySearch() { |
| String s1 = "String[] argv;"; |
| String s2 = "String argv;"; |
| String s3 = "'T[] argv;"; |
| String s3_2 = "'T:*Object [] argv;"; |
| |
| assertEquals( |
| "Find array types", |
| 0, |
| findMatchesCount(s1,s2) |
| ); |
| |
| assertEquals( |
| "Find array types, 2", |
| 0, |
| findMatchesCount(s2,s1) |
| ); |
| |
| assertEquals( |
| "Find array types, 3", |
| 0, |
| findMatchesCount(s2,s3) |
| ); |
| |
| assertEquals( |
| "Find array types, 3", |
| 1, |
| findMatchesCount(s1,s3_2) |
| ); |
| |
| String s11 = "class A {\n" + |
| " void main(String[] argv);" + |
| " void main(String argv[]);" + |
| " void main(String argv);" + |
| "}"; |
| String s12 = "'_t:[regex( *Object\\[\\] ) ] '_t2"; |
| String s12_2 = "'_t:[regex( *Object ) ] '_t2 []"; |
| String s12_3 = "'_t:[regex( *Object ) ] '_t2"; |
| |
| assertEquals( |
| "Find array covariant types", |
| 2, |
| findMatchesCount(s11,s12) |
| ); |
| |
| assertEquals( |
| "Find array covariant types, 2", |
| 2, |
| findMatchesCount(s11,s12_2) |
| ); |
| |
| assertEquals( |
| "Find array covariant types, 3", |
| 1, |
| findMatchesCount(s11,s12_3) |
| ); |
| |
| String source = "class A { String ss[][]; }"; |
| String target = "String[][] $s$;"; |
| assertEquals( |
| "should find multi dimensional c-style array declarations", |
| 1, |
| findMatchesCount(source, target) |
| ); |
| } |
| |
| // @todo support back references (\1 in another reg exp or as fild member) |
| //private static final String s1002 = " setSSS( instance.getSSS() ); " + |
| // " setSSS( instance.SSS ); "; |
| //private static final String s1003 = " 't:set(.+) ( '_.get't_1() ); "; |
| //private static final String s1003_2 = " 't:set(.+) ( '_.'t_1 ); "; |
| |
| public void testSearchStatements() { |
| assertEquals("statement search",findMatchesCount(s1,s2),1); |
| assertEquals("several constructions match",findMatchesCount(s5,s4),3); |
| assertFalse("several constructions 2",(findMatchesCount(s5,s6))!=0); |
| |
| assertEquals("several constructions 3",findMatchesCount(s7,s8),2); |
| assertEquals("several constructions 4",findMatchesCount(s7,s9),2); |
| |
| final String s1000 = "{ lastTest = \"search for parameterized pattern\";\n" + |
| " matches = testMatcher.findMatches(s14_1,s15, options);\n" + |
| " if (matches.size()!=2 ) return false;\n" + |
| "lastTest = \"search for parameterized pattern\";\n" + |
| " matches = testMatcher.findMatches(s14_1,s15, options);\n" + |
| " if (matches.size()!=2 ) return false; }"; |
| final String s1001 = "lastTest = '_Descr; " + |
| " matches = testMatcher.findMatches('_In,'_Pattern, options);\n" + |
| " if (matches.size()!='_Number ) return false;"; |
| |
| assertEquals("several operators 5",findMatchesCount(s1000,s1001),2); |
| |
| assertEquals( |
| "two the same statements search", |
| findMatchesCount(s85,s86), |
| 1 |
| ); |
| |
| assertEquals( |
| "search for simple call", |
| findMatchesCount(s87,s88), |
| 1 |
| ); |
| |
| assertEquals( |
| "search for simple call 2", |
| findMatchesCount(s87,s88_2), |
| 1 |
| ); |
| |
| assertEquals( |
| "search for simple call 3", |
| findMatchesCount(s87,s88_3), |
| 2 |
| ); |
| |
| String s10015 = "DocumentListener[] listeners = getCachedListeners();"; |
| String s10016 = "'_Type 'Var = '_Call();"; |
| |
| assertEquals( |
| "search for definition with init", |
| 1, |
| findMatchesCount(s10015,s10016) |
| ); |
| |
| String s10017 = "a = b; b = c; a=a; c=c;"; |
| String s10018 = "'_a = '_a;"; |
| |
| assertEquals( |
| "search silly assignments", |
| 2, |
| findMatchesCount(s10017,s10018) |
| ); |
| |
| String s10019 = "a.b(); a.b(null); a.b(null, 1);"; |
| String s10020 = "a.b(null);"; |
| |
| assertEquals( |
| "search parameter", |
| 1, |
| findMatchesCount(s10019,s10020) |
| ); |
| |
| String s1008 = "int a, b, c, d; int a,b,c; int c,d; int e;"; |
| String s1009 = "int '_a{3,4};"; |
| |
| assertEquals( |
| "search many declarations", |
| 2, |
| findMatchesCount(s1008,s1009) |
| ); |
| |
| String s1 = "super(1,1); call(1,1); call(2,2);"; |
| String s2 = "super('_t*);"; |
| |
| assertEquals( |
| "search super", |
| 1, |
| findMatchesCount(s1,s2) |
| ); |
| |
| String s10021 = "short a = 1;\n" + |
| "short b = 2;\n" + |
| "short c = a.b();"; |
| String s10022 = "short '_a = '_b.b();"; |
| |
| assertEquals( |
| "search def init bug", |
| 1, |
| findMatchesCount(s10021,s10022) |
| ); |
| |
| String s10023 = "abstract class A { public abstract short getType(); }\n" + |
| "A a;\n" + |
| "switch(a.getType()) {\n" + |
| " default:\n" + |
| " return 0;\n" + |
| "}\n" + |
| "switch(a.getType()) {\n" + |
| " case 1:\n" + |
| " { return 0; }\n" + |
| "}"; |
| String s10024 = "switch('_a:[exprtype( short )]) { '_statement*; }"; |
| assertEquals( |
| "finding switch", |
| 2, |
| findMatchesCount(s10023,s10024) |
| ); |
| |
| String s10025 = "A[] a;\n" + |
| "A b[];\n" + |
| "A c;"; |
| String s10026 = "A[] 'a;"; |
| String s10026_2 = "A 'a[];"; |
| |
| assertEquals( |
| "array types in dcl", |
| 2, |
| findMatchesCount(s10025,s10026) |
| ); |
| |
| assertEquals( |
| "array types in dcl 2", |
| 2, |
| findMatchesCount(s10025,s10026_2) |
| ); |
| |
| String s10027 = "try { a(); } catch(Exception ex) {}\n" + |
| "try { a(); } finally {}\n" + |
| "try { a(); } catch(Exception ex) {} finally {} \n"; |
| String s10028 = "try { a(); } finally {}\n"; |
| assertEquals( |
| "finally matching", |
| 2, |
| findMatchesCount(s10027,s10028) |
| ); |
| |
| String s10029 = "for(String a:b) { System.out.println(a); }"; |
| String s10030 = "for(String a:b) { '_a; }"; |
| assertEquals( |
| "for each matching", |
| 1, |
| findMatchesCount(s10029,s10030) |
| ); |
| |
| String s10031 = "try { a(); } catch(Exception ex) {} catch(Error error) { 1=1; }\n" + |
| "try { a(); } catch(Exception ex) {}"; |
| String s10032 = "try { a(); } catch('_Type+ 'Arg+) { 'Statements*; }\n"; |
| assertEquals( |
| "finally matching", |
| 2, |
| findMatchesCount(s10031,s10032) |
| ); |
| |
| String s10033 = "return x;\n" + |
| "return !x;\n" + |
| "return (x);\n" + |
| "return (x);\n" + |
| "return !(x);"; |
| String s10034 = "return ('a);"; |
| assertEquals("Find statement with parenthesized expr",2,findMatchesCount(s10033,s10034)); |
| } |
| |
| public void testSearchClass() { |
| // no modifier list in interface vars |
| assertEquals( |
| "no modifier for interface vars", |
| findMatchesCount(s43,s44), |
| 3 |
| ); |
| |
| // different order of access modifiers |
| assertEquals( |
| "different order of access modifiers", |
| findMatchesCount(s45,s46), |
| 1 |
| ); |
| |
| // no access modifiers |
| assertEquals( |
| "no access modifier", |
| findMatchesCount(s45,s46_2), |
| 2 |
| ); |
| |
| // type could differ with package |
| assertEquals( |
| "type differs with package", |
| findMatchesCount(s47,s48), |
| 2 |
| ); |
| |
| // reference element could differ in package |
| assertEquals( |
| "reference could differ in package", |
| findMatchesCount(s49,s50), |
| 1 |
| ); |
| |
| String s51 = "class C extends java.awt.List {} class A extends java.util.List {} class B extends java.awt.List {} "; |
| String s52 = "class 'B extends '_C:java\\.awt\\.List {}"; |
| |
| assertEquals( |
| "reference could differ in package 2", |
| findMatchesCount(s51,s52), |
| 2 |
| ); |
| |
| assertEquals( |
| "method access modifier", |
| findMatchesCount(s93,s94), |
| 0 |
| ); |
| |
| assertEquals( |
| "method access modifier 2", |
| findMatchesCount(s93,s94_2), |
| 1 |
| ); |
| |
| assertEquals( |
| "field access modifier", |
| findMatchesCount(s93,s94_3), |
| 0 |
| ); |
| |
| assertEquals( |
| "field access modifier 2", |
| findMatchesCount(s93,s94_4), |
| 1 |
| ); |
| |
| final String s127 = "class a { void b() { new c() {}; } }"; |
| final String s128 = "class 't {}"; |
| assertEquals( |
| "class finds anonymous class", |
| findMatchesCount(s127,s128), |
| 2 |
| ); |
| |
| final String s129 = "class a { public void run() {} }\n" + |
| "class a2 { public void run() { run(); } }\n" + |
| "class a3 { public void run() { run(); } }\n" + |
| "class a4 { public void run(); }"; |
| |
| final String s130 = "class 'a { public void run() {} }"; |
| final String s130_2 = "class 'a { public void run() { '_statement; } }"; |
| final String s130_3 = "class 'a { public void run(); }"; |
| |
| assertEquals( |
| "empty method finds empty method only", |
| findMatchesCount(s129,s130), |
| 1 |
| ); |
| |
| assertEquals( |
| "nonempty method finds nonempty method", |
| findMatchesCount(s129,s130_2), |
| 2 |
| ); |
| |
| assertEquals( |
| "nonempty method finds nonempty method", |
| findMatchesCount(s129,s130_3), |
| 4 |
| ); |
| |
| final String s133 = "class S {\n" + |
| "void cc() {\n" + |
| " new Runnable() {\n" + |
| " public void run() {\n" + |
| " f();\n" + |
| " }\n" + |
| " private void f() {\n" + |
| " //To change body of created methods use File | Settings | File Templates.\n" + |
| " }\n" + |
| " };\n" + |
| " new Runnable() {\n" + |
| " public void run() {\n" + |
| " f();\n" + |
| " }\n" + |
| " private void g() {\n" + |
| " //To change body of created methods use File | Settings | File Templates.\n" + |
| " }\n" + |
| " };\n" + |
| " new Runnable() {\n" + |
| " public void run() {\n" + |
| " f();\n" + |
| " }\n" + |
| " };\n" + |
| " }\n" + |
| " private void f() {\n" + |
| " //To change body of created methods use File | Settings | File Templates.\n" + |
| " }\n" + |
| "} "; |
| final String s134 = "new Runnable() {\n" + |
| " public void run() {\n" + |
| " '_f ();\n" + |
| " }\n" + |
| " private void '_f ();\n" + |
| " }"; |
| assertEquals( |
| "complex expr matching", |
| 1, |
| findMatchesCount(s133,s134) |
| ); |
| |
| final String s135 = "abstract class My {\n" + |
| " abstract void f();\n" + |
| "}\n" + |
| "abstract class My2 {\n" + |
| " abstract void f();\n" + |
| " void fg() {}\n" + |
| "}"; |
| final String s136 = "class 'm {\n" + |
| " void f();\n" + |
| " '_type '_method{0,0} ('_paramtype* '_paramname* );\n" + |
| "}"; |
| assertEquals( |
| "reject method with 0 max occurence", |
| findMatchesCount(s135,s136), |
| 1 |
| ); |
| |
| final String s137 = "abstract class My {\n" + |
| " int a;\n" + |
| "}\n" + |
| "abstract class My2 {\n" + |
| " Project b;\n" + |
| "}" + |
| "abstract class My3 {\n" + |
| " Class clazz;"+ |
| " Project b = null;\n" + |
| "}" + |
| "abstract class My {\n" + |
| " int a = 1;\n" + |
| "}\n"; |
| final String s138 = "class 'm {\n" + |
| " Project '_f{0,0} = '_t?;\n" + |
| "}"; |
| assertEquals( |
| "reject field with 0 max occurence", |
| findMatchesCount(s137,s138), |
| 2 |
| ); |
| |
| final String s139 = "class My { boolean equals(Object o); int hashCode(); }"; |
| final String s139_2 = "class My { boolean equals(Object o); }"; |
| final String s140 = "class 'A { boolean equals(Object '_o ); int '_hashCode{0,0}:hashCode (); }"; |
| |
| assertEquals( |
| "reject method with constraint", |
| findMatchesCount(s139,s140), |
| 0 |
| ); |
| |
| assertEquals( |
| "reject field with 0 max occurence", |
| findMatchesCount(s139_2,s140), |
| 1 |
| ); |
| |
| final String s141 = "class A { static { a = 10 } }\n" + |
| "class B { { a = 10; } }\n" + |
| "class C { { a = 10; } }"; |
| final String s142 = "class '_ { static { a = 10; } } "; |
| assertEquals( |
| "static block search", |
| findMatchesCount(s141,s142), |
| 1 |
| ); |
| } |
| |
| public void testParameterlessContructorSearch() { |
| final String s143 = "class A { A() {} };\n" + |
| "class B { B(int a) {} };\n" + |
| "class C { C() {} C(int a) {} };\n" + |
| "class D {}\n" + |
| "class E {}"; |
| final String s144 = "class '_a { '_d{0,0}:[ script( \"__context__.constructor\" ) ]('_b+ '_c+); }"; |
| assertEquals( |
| "parameterless contructor search", |
| 3, |
| findMatchesCount(s143,s144) |
| ); |
| } |
| |
| public void testCheckScriptValidation() { |
| final String s1 = ""; |
| final String s2 = "'_b:[script( \"^^^\" )]"; |
| |
| try { |
| final int count = findMatchesCount(s1, s2); |
| assertFalse("Validation does not work", true); |
| } catch (MalformedPatternException ex) {} |
| } |
| |
| //public void testRelationBetweenVars() { |
| // final String s1 = "public class Foo {\n" + |
| // " public static final Logger log = Logger.getInstance(Foo.class);\n" + |
| // " public static final Logger log2 = Logger.getInstance(Foo2.class);\n" + |
| // " public static final Logger log3 = Logger.getInstance(Foo2.class);\n" + |
| // "}"; |
| // final String s2 = "class '_a { static Logger 'log+ = Logger.getInstance('_b:[script( \"_a != _b\" )].class); }"; |
| // assertEquals( |
| // "relation between vars in script", |
| // 2, |
| // findMatchesCount(s1,s2) |
| // ); |
| //} |
| |
| public void testExprTypeWithObject() { |
| String s1 = "import java.util.*;\n" + |
| "class A {\n" + |
| " void b() {\n" + |
| " Map map = new HashMap();" + |
| " class AppPreferences {}\n" + |
| " String key = \"key\";\n" + |
| " AppPreferences value = new AppPreferences();\n" + |
| " map.put(key, value );\n" + |
| " map.put(value, value );\n" + |
| " map.put(\"key\", value );\n" + |
| " map.put(\"key\", new AppPreferences());\n" + |
| " }\n" + |
| "}"; |
| String s2 = "'_map:[exprtype( *java\\.util\\.Map )].put('_key:[ exprtype( *Object ) ], '_value:[ exprtype( *AppPreferences ) ]);"; |
| |
| assertEquals( |
| "expr type with object", |
| 4, |
| findMatchesCount(s1,s2,true) |
| ); |
| } |
| |
| public void testInterfaceImplementationsSearch() { |
| String in = "class A implements Cloneable {\n" + |
| " \n" + |
| " }\n" + |
| " \n" + |
| " class B implements Serializable {\n" + |
| " \n" + |
| " }\n" + |
| " \n" + |
| " class C implements Cloneable,Serializable {\n" + |
| " \n" + |
| " }\n" + |
| " class C2 implements Serializable,Cloneable {\n" + |
| " \n" + |
| " }\n" + |
| " \n" + |
| " class E extends B implements Cloneable {\n" + |
| " \n" + |
| " }\n" + |
| " \n" + |
| " class F extends A implements Serializable {\n" + |
| " \n" + |
| " }\n" + |
| " \n" + |
| " class D extends C {\n" + |
| " \n" + |
| " }"; |
| String what = "class 'A implements '_B:*Serializable , '_C:*Cloneable {}"; |
| assertEquals( |
| "search interface within hierarchy", |
| 5, |
| findMatchesCount(in, what) |
| ); |
| } |
| |
| public void testSearchBacktracking() { |
| assertEquals( |
| "backtracking greedy regexp", |
| findMatchesCount(s89,s90), |
| 1 |
| ); |
| |
| assertEquals( |
| "backtracking greedy regexp 2", |
| findMatchesCount(s89,s90_2), |
| 1 |
| ); |
| |
| assertEquals( |
| "backtracking greedy regexp 3", |
| findMatchesCount(s89,s90_3), |
| 0 |
| ); |
| |
| assertEquals( |
| "counted regexp (with back tracking)", |
| findMatchesCount(s89,s90_4), |
| 1 |
| ); |
| |
| assertEquals( |
| "nongreedy regexp (counted, with back tracking)", |
| findMatchesCount(s89,s90_5), |
| 1 |
| ); |
| |
| assertEquals( |
| "nongreedy regexp (counted, with back tracking) 2", |
| findMatchesCount(s89,s90_6), |
| 0 |
| ); |
| |
| String s1000 = "class A {\n" + |
| " void _() {}\n" + |
| " void a(String in, String pattern) {}\n" + |
| " }"; |
| String s1001 = "class '_Class { \n" + |
| " '_ReturnType+ 'MethodName+ ('_ParameterType* '_Parameter* );\n" + |
| "}"; |
| assertEquals( |
| "handling of no match", |
| findMatchesCount(s1000,s1001), |
| 2 |
| ); |
| } |
| |
| public void testSearchSymbol() { |
| final String s131 = "a.b(); c.d = 1; "; |
| final String s132 = "'T:b|d"; |
| |
| assertEquals( |
| "symbol match", |
| 2, |
| findMatchesCount(s131,s132) |
| ); |
| |
| final String s129 = "A a = new A();"; |
| final String s130 = "'Sym:A"; |
| |
| options.setCaseSensitiveMatch(true); |
| assertEquals( |
| "case sensitive match", |
| findMatchesCount(s129,s130), |
| 2 |
| ); |
| |
| options.setDistinct(true); |
| assertEquals( |
| "case sensitive disitinct match", |
| findMatchesCount(s129,s130), |
| 1 |
| ); |
| |
| options.setDistinct(false); |
| |
| final String s133 = "class C { int a; int A() { a = 1; }} void c(int a) { a = 2; }"; |
| final String s133_2 = "class C { int a() {} int A() { a(1); }}"; |
| final String s134 = "a"; |
| |
| List<MatchResult> results = findMatches(s133, s134, true, StdFileTypes.JAVA); |
| assertEquals( |
| "find sym finds declaration", |
| 4, results.size() |
| ); |
| |
| assertEquals( |
| "find sym finds declaration", |
| 2, findMatchesCount(s133_2, s134, true) |
| ); |
| } |
| |
| public void testSearchGenerics() { |
| assertEquals( |
| "parameterized class match", |
| findMatchesCount(s81,s82), |
| 2 |
| ); |
| |
| assertEquals( |
| "parameterized instanceof match", |
| findMatchesCount(s81,s82_2), |
| 1 |
| ); |
| |
| assertEquals( |
| "parameterized cast match", |
| findMatchesCount(s81,s82_3), |
| 1 |
| ); |
| |
| assertEquals( |
| "parameterized definition match", |
| findMatchesCount(s81,s82_4), |
| 3 |
| ); |
| |
| assertEquals( |
| "parameterized method match", |
| findMatchesCount(s81,s82_5), |
| 1 |
| ); |
| |
| assertEquals( |
| "parameterized constraint match", |
| findMatchesCount(s81_2,s82_6), |
| 2 |
| ); |
| |
| assertEquals( |
| "symbol matches parameterization", |
| findMatchesCount(s81,s82_7), |
| 29 |
| ); |
| |
| assertEquals( |
| "symbol matches parameterization 2", |
| findMatchesCount(s81_2,s82_7), |
| 7 |
| ); |
| |
| String s81_3 = " class A {\n" + |
| " public static <T> Collection<T> unmodifiableCollection(int c) {\n" + |
| " return new d<T>(c);\n" + |
| " }\n" + |
| " static class d<E> implements Collection<E>, Serializable {\n" + |
| " public <T> T[] toArray(T[] a) {return c.toArray(a);}\n" + |
| " }\n" + |
| "}"; |
| assertEquals( |
| "typed symbol symbol", |
| findMatchesCount(s81_3,s82_5), |
| 2 |
| ); |
| |
| String s81_4="class A<B> { \n" + |
| " static <C> void c(D<E> f) throws R<S> {\n" + |
| " if ( f instanceof G<H>) {\n" + |
| " ((I<G<K>>)l).a();\n" + |
| " throw new P<Q>();" + |
| " }\n" + |
| " }\n" + |
| "} " + |
| "class C {\n" + |
| " void d(E f) throws Q {\n" + |
| " if (g instanceof H) { a.c(); b.d(new A() {}); throw new Exception(((I)k)); }"+ |
| " }\n" + |
| "}"; |
| String s82_8 = "'T<'_Subst+>"; |
| assertEquals( |
| "typed symbol", |
| findMatchesCount(s81_4,s82_8), |
| 6 |
| ); |
| |
| String s81_5 = "class A { HashMap<String, Integer> variable = new HashMap<String, Integer>(\"aaa\");}"; |
| String s82_9 = "'_Type<'_GType, '_GType2> '_instance = new '_Type<'_GType, '_GType2>('_Param);"; |
| assertEquals( |
| "generic vars in new", |
| findMatchesCount(s81_5,s82_9), |
| 1 |
| ); |
| String source1 = "class Comparator<T> { private Comparator<String> c; private Comparator d; }"; |
| String target1 = "java.util.Comparator 'a;"; |
| assertEquals( |
| "qualified type should not match 1", |
| 0, |
| findMatchesCount(source1, target1) |
| ); |
| |
| String target2 = "java.util.Comparator<String> 'a;"; |
| assertEquals( |
| "qualified type should not match 2", |
| 0, |
| findMatchesCount(source1, target2) |
| ); |
| |
| // @todo typed vars constrains (super), |
| // @todo generic method invocation |
| |
| //String s83 = "class A {} List<A> a; List b;"; |
| //String s84 = "'a:List 'c;"; |
| //String s84_2 = "'a:List\\<'_\\> 'c;"; |
| //String s84_3 = "'a:List(?>\\<'_\\>) 'c;"; |
| // |
| //assertEquals( |
| // "finding list", |
| // findMatchesCount(s83,s84), |
| // 2 |
| //); |
| // |
| //assertEquals( |
| // "finding list 2", |
| // findMatchesCount(s83,s84_2), |
| // 1 |
| //); |
| // |
| //assertEquals( |
| // "finding list 3", |
| // findMatchesCount(s83,s84_3), |
| // 1 |
| //); |
| } |
| |
| public void testSearchSubstitutions() { |
| // searching for parameterized pattern |
| assertEquals("search for parameterized pattern",findMatchesCount(s14_1,s15),2); |
| |
| assertEquals("search for parameterized pattern 2",findMatchesCount(s14_2,s15),5); |
| |
| options.setRecursiveSearch(false); |
| |
| assertEquals("search for parameterized pattern-non-recursive",findMatchesCount(s14_1,s15),1); |
| |
| assertEquals("search for parameterized pattern 2-non-recursive",findMatchesCount(s14_2,s15),2); |
| |
| // typed vars with arrays |
| assertEquals("typed pattern with array 2-non-recursive",findMatchesCount(s23,s24_2),4); |
| |
| options.setRecursiveSearch(true); |
| |
| // searching for parameterized pattern |
| assertEquals("search for parameterized pattern 3",findMatchesCount(s14_2,s16),1); |
| |
| // searching for parameterized pattern in complex expr (with field selection) |
| assertEquals("search for parameterized pattern in field selection",findMatchesCount(s17,s18_1),1); |
| |
| // searching for parameterized pattern in complex expr (with method call) |
| assertEquals("search for parameterized pattern with method call",findMatchesCount(s17,s18_2),1); |
| |
| // searching for parameterized pattern in complex expr (with method call) |
| assertEquals("search for parameterized pattern with method call ep.2",findMatchesCount(s17,s18_3),4); |
| |
| // searching for parameterized pattern in definition with initializer |
| assertEquals("search for same var constraint",findMatchesCount(s19,s20),1); |
| |
| // searching for semi anonymous parameterized pattern in definition with initializer |
| assertEquals("search for same var constraint for semi anonymous typed vars",findMatchesCount(s19,s20_2),1); |
| |
| // support for type var constraint |
| assertEquals("search for typed var constraint",findMatchesCount(s22,s21_1),1); |
| |
| // noncompatible same typed var constraints |
| try { |
| findMatchesCount(s22,s21_2); |
| assertFalse("search for noncompatible typed var constraint",false); |
| } catch(MalformedPatternException e) { |
| } |
| |
| // compatible same typed var constraints |
| assertEquals("search for same typed var constraint",findMatchesCount(s22,s21_3),1); |
| |
| // typed var with instanceof |
| assertEquals("typed instanceof",findMatchesCount(s65,s66),1); |
| |
| // typed vars with arrays |
| assertEquals("typed pattern with array",findMatchesCount(s23,s24_1),2); |
| |
| // typed vars with arrays |
| assertEquals("typed pattern with array 2",findMatchesCount(s23,s24_2),6); |
| |
| // typed vars in class name, method name, its return type, parameter type and name |
| assertEquals("typed pattern in class name, method name, return type, parameter type and name",findMatchesCount(s25,s26),1); |
| |
| assertEquals( |
| "finding interface", |
| findMatchesCount(s27,s28), |
| 1 |
| ); |
| |
| // finding anonymous type vars |
| assertEquals( |
| "anonymous typed vars", |
| findMatchesCount(s29,s30), |
| 1 |
| ); |
| |
| // finding descedants |
| assertEquals( |
| "finding class descendants", |
| findMatchesCount(s31,s32), |
| 2 |
| ); |
| |
| // finding interface implementation |
| assertEquals( |
| "interface implementation", |
| findMatchesCount(s33,s34), |
| 2 |
| ); |
| |
| // different order of fields and methods |
| assertEquals( |
| "different order of fields and methods", |
| findMatchesCount(s35,s36), |
| 1 |
| ); |
| |
| // different order of exceptions in throws |
| assertEquals( |
| "differend order in throws", |
| findMatchesCount(s37,s38), |
| 1 |
| ); |
| |
| // class pattern without extends matches pattern with extends |
| assertEquals( |
| "match of class without extends to class with it", |
| findMatchesCount(s39,s40), |
| 2 |
| ); |
| |
| // class pattern without extends matches pattern with extends |
| assertEquals( |
| "match of class without extends to class with it, ep. 2", |
| findMatchesCount(s41,s42_1), |
| 2 |
| ); |
| |
| // class pattern without extends matches pattern with extends |
| assertEquals( |
| "match of class without extends to class with it, ep 3", |
| findMatchesCount(s41,s42_2), |
| 2 |
| ); |
| |
| // typed reference element |
| assertEquals( |
| "typed reference element", |
| findMatchesCount(s51,s52), |
| 2 |
| ); |
| |
| // empty name of type var |
| assertEquals( |
| "empty name for typed var", |
| findMatchesCount(s59,s60), |
| 1 |
| ); |
| |
| // comparing method with constructor |
| assertEquals( |
| "comparing method with constructor", |
| findMatchesCount(s63,s64), |
| 1 |
| ); |
| |
| // comparing method with constructor |
| assertEquals( |
| "finding nested class", |
| findMatchesCount(s63_2,s64), |
| 2 |
| ); |
| |
| // comparing method with constructor |
| assertEquals( |
| "finded nested class by special pattern", |
| findMatchesCount(s63_2,s64_2), |
| 1 |
| ); |
| |
| assertEquals( |
| "* regexp for typed var", |
| findMatchesCount(s61,s62_1), |
| 5 |
| ); |
| |
| assertEquals( |
| "+ regexp for typed var", |
| findMatchesCount(s61,s62_2), |
| 4 |
| ); |
| |
| assertEquals( |
| "? regexp for typed var", |
| findMatchesCount(s61,s62_3), |
| 2 |
| ); |
| |
| assertEquals( |
| "cast in method parameters", |
| findMatchesCount(s67,s68), |
| 1 |
| ); |
| |
| assertEquals( |
| "searching for static field in static call", |
| 2, |
| findMatchesCount(s69,s70) |
| ); |
| |
| assertEquals( |
| "searching for static field in static call, 2", |
| 2, |
| findMatchesCount(s69,s70_2) |
| ); |
| |
| assertEquals( |
| "* regexp for anonymous typed var", |
| findMatchesCount(s61,s62_4), |
| 3 |
| ); |
| |
| assertEquals( |
| "+ regexp for anonymous typed var", |
| findMatchesCount(s61,s62_5), |
| 2 |
| ); |
| |
| assertEquals( |
| "? regexp for anonymous typed var", |
| findMatchesCount(s61,s62_6), |
| 2 |
| ); |
| |
| assertEquals( |
| "statement inside anonymous class", |
| findMatchesCount(s71,s72), |
| 3 |
| ); |
| |
| assertEquals( |
| "clever regexp match", |
| findMatchesCount(s91,s92), |
| 2 |
| ); |
| |
| assertEquals( |
| "clever regexp match 2", |
| findMatchesCount(s91,s92_2), |
| 2 |
| ); |
| |
| assertEquals( |
| "clever regexp match 3", |
| findMatchesCount(s91,s92_3), |
| 2 |
| ); |
| } |
| |
| public void testSearchJavaDoc() { |
| // javadoc comment in class |
| assertEquals( |
| "java doc comment in class", |
| 1, |
| findMatchesCount(s57,s58) |
| ); |
| |
| assertEquals( |
| "java doc comment in class in file", |
| 1, |
| findMatchesCount(s57_2,s58,true) |
| ); |
| |
| // javadoc comment for field |
| assertEquals( |
| "javadoc comment for field", |
| 2, |
| findMatchesCount(s57, s58_2) |
| ); |
| |
| // javadoc comment for method |
| assertEquals( |
| "javadoc comment for method", |
| 3, |
| findMatchesCount(s57, s58_3) |
| ); |
| |
| // just javadoc comment search |
| assertEquals( |
| "just javadoc comment search", |
| 4, |
| findMatchesCount(s57,s58_4) |
| ); |
| |
| assertEquals( |
| "XDoclet metadata", |
| 2, |
| findMatchesCount(s83,s84) |
| ); |
| |
| assertEquals( |
| "XDoclet metadata 2", |
| 1, |
| findMatchesCount(s83,s84_2) |
| ); |
| |
| assertEquals( |
| "optional tag value match", |
| 6, |
| findMatchesCount(s57, s58_5) |
| ); |
| |
| assertEquals( |
| "multiple tags match +", |
| 2, |
| findMatchesCount(s75,s76) |
| ); |
| |
| assertEquals( |
| "multiple tags match *", |
| 3, |
| findMatchesCount(s75, s76_2) |
| ); |
| |
| assertEquals( |
| "multiple tags match ?", |
| 3, |
| findMatchesCount(s75, s76_3) |
| ); |
| |
| } |
| |
| public void testNamedPatterns() { |
| String s133 = "class String1 implements java.io.Serializable { " + |
| "private static final long serialVersionUID = -6849794470754667710L;" + |
| "private static final ObjectStreamField[] serialPersistentFields = new ObjectStreamField[0];" + |
| "}" + |
| "class StringBuilder1 implements java.io.Serializable {" + |
| " private void writeObject(java.io.ObjectOutputStream s)\n" + |
| " throws java.io.IOException {\n" + |
| " s.defaultWriteObject();\n" + |
| " }" + |
| "private void readObject(java.io.ObjectInputStream s)\n" + |
| " throws java.io.IOException, ClassNotFoundException {\n" + |
| " s.defaultReadObject();\n" + |
| " }" + |
| " static final long serialVersionUID = 4383685877147921099L;" + |
| "}"; |
| String s134 = "class '_ implements '_:*Serializable {\n" + |
| " static final long 'VersionField?:serialVersionUID = '_?;\n" + |
| " private static final ObjectStreamField[] '_?:serialPersistentFields = '_?; \n" + |
| " private void '_SerializationWriteHandler?:writeObject (ObjectOutputStream s) throws IOException;\n" + |
| " private void '_SerializationReadHandler?:readObject (ObjectInputStream s) throws IOException, ClassNotFoundException;\n" + |
| " Object '_SpecialSerializationReadHandler?:readResolve () throws ObjectStreamException;" + |
| " Object '_SpecialSerializationWriteHandler?:writeReplace () throws ObjectStreamException;" + |
| "}"; |
| |
| assertEquals( |
| "serialization match", |
| findMatchesCount(s133,s134), |
| 2 |
| ); |
| |
| String s135 = "class SimpleStudentEventActionImpl extends Action { " + |
| " public ActionForward execute(ActionMapping mapping,\n" + |
| " ActionForm _form,\n" + |
| " HttpServletRequest _request,\n" + |
| " HttpServletResponse _response)" + |
| " throws Exception {}" + |
| "} " + |
| "public class DoEnrollStudent extends SimpleStudentEventActionImpl { }" + |
| "public class DoCancelStudent extends SimpleStudentEventActionImpl { }"; |
| String s136 = "public class 'StrutsActionClass extends '_*:Action {" + |
| " public ActionForward '_AnActionMethod:*execute (ActionMapping '_,\n" + |
| " ActionForm '_,\n" + |
| " HttpServletRequest '_,\n" + |
| " HttpServletResponse '_);" + |
| "}"; |
| |
| assertEquals( |
| "Struts actions", |
| findMatchesCount(s135,s136), |
| 2 |
| ); |
| |
| final String s123 = "class NodeFilter {} public class MethodFilter extends NodeFilter {\n" + |
| " private MethodFilter() {}\n" + |
| "\n" + |
| " public static NodeFilter getInstance() {\n" + |
| " if (instance==null) instance = new MethodFilter();\n" + |
| " return instance;\n" + |
| " }\n" + |
| " private static NodeFilter instance;\n" + |
| "}"; |
| final String s124 = "class 'Class {\n" + |
| " private 'Class('_* '_*) {\n" + |
| " '_*;\n" + |
| " }\n" + |
| " private static '_Class2:* '_Instance;\n" + |
| " static '_Class2:* '_GetInstance() {\n" + |
| " '_*;\n" + |
| " return '_Instance;\n" + |
| " }\n" + |
| "}"; |
| |
| assertEquals( |
| "singleton search", |
| findMatchesCount(s123,s124), |
| 1 |
| ); |
| |
| String s1111 = "if (true) { a=1; b=1; } else { a=1; }\n" + |
| "if(true) { a=1; } else { a=1; b=1; }\n" + |
| "if(true) { a=1; b=2; } else { a = 1; b=2; }"; |
| String s1112 = "if (true) { '_a{1,2}; } else { '_a; }"; |
| |
| assertEquals( |
| "same multiple name pattern", |
| findMatchesCount(s1111,s1112), |
| 1 |
| ); |
| } |
| |
| public void testHierarchy() { |
| final String s105 = "class B {} class A extends B { }"; |
| final String s106 = "class '_ extends '_:[ref('T)] {}"; |
| assertEquals( |
| "extends match", |
| findMatchesCount(s105,s106), |
| 1 |
| ); |
| |
| final String s107 = "interface IA {} interface IB extends IA { } interface IC extends IB {} interface ID extends IC {}" + |
| "class A implements IA {} class B extends A { } class C extends B implements IC {} class D extends C {}"; |
| final String s108 = "class '_ extends 'Type:+A {}"; |
| final String s108_2 = "class '_ implements 'Type:+IA {}"; |
| |
| assertEquals( |
| "extends navigation match", |
| findMatchesCount(s107,s108), |
| 2 |
| ); |
| |
| assertEquals( |
| "implements navigation match", |
| 3, |
| findMatchesCount(s107,s108_2) |
| ); |
| |
| 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;} }"; |
| final String s110 = "'_:*A '_;"; |
| final String s110_2 = "'_:*I '_;"; |
| final String s110_3 = "'_:*[regex( I ) && ref('T)] '_;"; |
| final String s110_4 = "'_:*[regex( I ) && ref2('T)] '_;"; |
| assertEquals( |
| "extends navigation match in definition", |
| findMatchesCount(s109,s110), |
| 3 |
| ); |
| |
| assertEquals( |
| "implements navigation match in definition 2", |
| findMatchesCount(s109,s110_2), |
| 3 |
| ); |
| |
| assertEquals( |
| "implements navigation match in definition 2 with nested conditions", |
| findMatchesCount(s109,s110_3), |
| 1 |
| ); |
| |
| try { |
| findMatchesCount(s109,s110_4); |
| assertFalse("implements navigation match in definition 2 with nested conditions - incorrect cond",false); |
| } catch(UnsupportedPatternException ex) {} |
| |
| 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;} }"; |
| final String s112 = "'_"; |
| assertEquals( |
| "symbol match", |
| findMatchesCount(s111,s112), |
| 17 |
| ); |
| |
| 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); " + |
| "b.c = 1; System.out.println(b.c); b.c++;"; |
| final String s114 = "'_:[read]"; |
| final String s114_2 = "'_:[write]"; |
| assertEquals( |
| "read symbol match", |
| findMatchesCount(s113,s114), |
| 11 |
| ); |
| |
| assertEquals( |
| "write symbol match", |
| findMatchesCount(s113,s114_2), |
| 5 |
| ); |
| |
| final String s115 = "class B {} public class C {}"; |
| final String s116 = "public class '_ {}"; |
| assertEquals( |
| "public modifier for class", |
| findMatchesCount(s115,s116), |
| 1 |
| ); |
| |
| final String s117 = "class A { int b; void c() { int e; b=1; this.b=1; e=5; " + |
| "System.out.println(e); " + |
| "System.out.println(b); System.out.println(this.b);} }"; |
| final String s118 = "this.'Field"; |
| final String s118_2 = "this.'Field:[read]"; |
| final String s118_3 = "this.'Field:[write]"; |
| |
| assertEquals( |
| "fields of class", |
| 4, |
| findMatchesCount(s117,s118) |
| ); |
| |
| assertEquals( |
| "fields of class read", |
| findMatchesCount(s117,s118_2), |
| 2 |
| ); |
| |
| assertEquals( |
| "fields of class written", |
| findMatchesCount(s117,s118_3), |
| 2 |
| ); |
| |
| final String s119 = "try { a.b(); } catch(IOException e) { c(); } catch(Exception ex) { d(); }"; |
| final String s120 = "try { '_; } catch('_ '_) { '_; }"; |
| final String s120_2 = "try { '_; } catch(Throwable '_) { '_; }"; |
| assertEquals( |
| "catches loose matching", |
| findMatchesCount(s119,s120), |
| 1 |
| ); |
| |
| assertEquals( |
| "catches loose matching 2", |
| findMatchesCount(s119,s120_2), |
| 0 |
| ); |
| |
| final String s121 = "class A { private int a; class Inner {} } " + |
| "class B extends A { private int a; class Inner2 {} }"; |
| final String s122 = "class '_ { int '_:* ; }"; |
| final String s122_2 = "class '_ { int '_:+hashCode (); }"; |
| final String s122_3 = "class '_ { class '_:* {} }"; |
| assertEquals( |
| "hierarchical matching", |
| findMatchesCount(s121,s122), |
| 2 |
| ); |
| |
| assertEquals( |
| "hierarchical matching 2", |
| findMatchesCount(s121,s122_2), |
| 4 |
| ); |
| |
| assertEquals( |
| "hierarchical matching 3", |
| findMatchesCount(s121,s122_3), |
| 2 |
| ); |
| } |
| |
| public void testSearchInCommentsAndLiterals() { |
| String s1 = "{" + |
| "// This is some comment\n" + |
| "/* This is another\n comment*/\n" + |
| "// Some garbage\n"+ |
| "/** And now third comment*/\n" + |
| "/** Some garbage*/ }"; |
| String s2 = "// 'Comment:[regex( .*(?:comment).* )]"; |
| String s3 = "/** 'Comment:[regex( .*(?:comment).* )] */"; |
| String s2_2 = "/* 'Comment:[regex( .*(?:comment).* )] */"; |
| |
| assertEquals( |
| "Comment matching", |
| findMatchesCount(s1,s2), |
| 3 |
| ); |
| |
| assertEquals( |
| "Comment matching, 2", |
| 3, |
| findMatchesCount(s1,s2_2) |
| ); |
| |
| assertEquals( |
| "Java doc matching", |
| findMatchesCount(s1,s3), |
| 1 |
| ); |
| |
| String s4 = "\"'test\", \"another test\", \"garbage\""; |
| String s5 = "\"'test:[regex( .*test.* )]\""; |
| String s6 = "\"''test\""; |
| |
| assertEquals( |
| "Literal content", |
| findMatchesCount(s4,s5), |
| 2 |
| ); |
| |
| assertEquals( |
| "Literal content with escaping", |
| findMatchesCount(s4,s6), |
| 1 |
| ); |
| |
| String s7 = "\"aaa\""; |
| String s8 = "\"'test:[regex( aaa )]\""; |
| |
| assertEquals( |
| "Simple literal content", |
| findMatchesCount(s7,s8), |
| 1 |
| ); |
| |
| String s9 = "\" aaa \" \" bbb \" \" ccc ccc aaa\""; |
| String s10 = "\"'test:[regexw( aaa|ccc )]\""; |
| String s11 = "\"'test:[regexw( bbb )]\""; |
| |
| assertEquals( |
| "Whole word literal content with alternations", |
| findMatchesCount(s9,s10), |
| 2 |
| ); |
| |
| assertEquals( |
| "Whole word literal content", |
| findMatchesCount(s9,s11), |
| 1 |
| ); |
| |
| String s12 = "assert agentInfo != null : \"agentInfo is null\";\n" + |
| "assert addresses != null : \"addresses is null\";"; |
| String s13 = "assert $exp$ != null : \"$exp$ is null\";"; |
| |
| assertEquals( |
| "reference to substitution in comment", |
| findMatchesCount(s12,s13), |
| 2 |
| ); |
| |
| String s14 = "\"(some text with special chars)\"," + |
| "\" some\"," + |
| "\"(some)\""; |
| String s15 = "\"('a:[regexw( some )])\""; |
| |
| assertEquals( |
| "meta char in literal", |
| 2, |
| findMatchesCount(s14,s15) |
| ); |
| |
| String s16 = "/**\n" + |
| "* Created by IntelliJ IDEA.\n" + |
| "* User: cdr\n" + |
| "* Date: Nov 15, 2005\n" + |
| "* Time: 4:23:29 PM\n" + |
| "* To change this template use File | Settings | File Templates.\n" + |
| "*/\n" + |
| "public class Y {\n" + |
| "}"; |
| String s17 = "/**\n" + |
| "* Created by IntelliJ IDEA.\n" + |
| "* User: '_USER\n" + |
| "* Date: '_DATE\n" + |
| "* Time: '_TIME\n" + |
| "* To change this template use File | Settings | File Templates.\n" + |
| "*/\n" + |
| "class 'c {\n" + |
| "}"; |
| assertEquals( |
| "complete comment match", |
| 1, |
| findMatchesCount(s16,s17,true) |
| ); |
| |
| String s18 = "public class A {\n" + |
| " private void f(int i) {\n" + |
| " int g=0; //sss\n" + |
| " }\n" + |
| "}"; |
| String s19 = "class $c$ {\n" + |
| " $type$ $f$($t$ $p$){\n" + |
| " $s$; // sss\n" + |
| " }\n" + |
| "}"; |
| assertEquals( |
| "statement match with comment", |
| 1, |
| findMatchesCount(s18,s19) |
| ); |
| } |
| |
| public void testOther() { |
| assertEquals( |
| "optional init match in definition", |
| findMatchesCount(s73,s74), |
| 4 |
| ); |
| |
| assertEquals( |
| "null match", |
| findMatchesCount(s77,s78), |
| 0 |
| ); |
| |
| assertEquals( |
| "body of method by block search", |
| findMatchesCount(s79,s80), |
| 2 |
| ); |
| |
| |
| assertEquals( |
| "first matches, next not", |
| findMatchesCount(s95,s96), |
| 2 |
| ); |
| |
| final String s97 = "class A { int c; void b() { C d; } } class C { C() { A a; a.b(); a.c=1; } }"; |
| final String s98 = "'_.'_:[ref('T)] ()"; |
| final String s98_2 = "'_.'_:[ref('T)]"; |
| final String s98_3 = "'_:[ref('T)].'_ ();"; |
| final String s98_4 = "'_:[ref('T)] '_;"; |
| |
| assertEquals( |
| "method predicate match", |
| findMatchesCount(s97,s98), |
| 1 |
| ); |
| |
| assertEquals( |
| "field predicate match", |
| findMatchesCount(s97,s98_2), |
| 1 |
| ); |
| |
| assertEquals( |
| "dcl predicate match", |
| findMatchesCount(s97,s98_3), |
| 1 |
| ); |
| |
| final String s99 = " char s = '\\u1111'; char s1 = '\\n'; "; |
| final String s100 = " char 'var = '\\u1111'; "; |
| final String s100_2 = " char 'var = '\\n'; "; |
| assertEquals( |
| "char constants in pattern", |
| findMatchesCount(s99,s100), |
| 1 |
| ); |
| |
| assertEquals( |
| "char constants in pattern 2", |
| findMatchesCount(s99,s100_2), |
| 1 |
| ); |
| |
| assertEquals( |
| "class predicate match (from definition)", |
| findMatchesCount(s97,s98_4), |
| 3 |
| ); |
| |
| final String s125 = "a=1;"; |
| final String s126 = "'t:[regex(a)]"; |
| |
| try { |
| findMatchesCount(s125,s126); |
| assertFalse("spaces around reg exp check",false); |
| } catch(MalformedPatternException ex) {} |
| |
| options.setDistinct(true); |
| |
| final String s101 = "class A { void b() { String d; String e; String[] f; f.length=1; f.length=1; } }"; |
| final String s102 = "'_:[ref('T)] '_;"; |
| |
| assertEquals( |
| "distinct match", |
| findMatchesCount(s101,s102), |
| 1 |
| ); |
| |
| options.setDistinct(false); |
| |
| final String s103 = " a=1; "; |
| final String s104 = "'T:{ ;"; |
| try { |
| findMatchesCount(s103,s104); |
| assertFalse("incorrect reg exp",false); |
| } catch(MalformedPatternException ex) { |
| } |
| |
| final String s106 = "$_ReturnType$ $MethodName$($_ParameterType$ $_Parameter$);"; |
| final String s105 = " aaa; "; |
| |
| try { |
| findMatchesCount(s105,s106); |
| assertFalse("incorrect reg exp 2",false); |
| } catch(UnsupportedPatternException ex) { |
| } |
| |
| String s107 = "class A {\n" + |
| " /* */\n" + |
| " void a() {\n" + |
| " }" + |
| " /* */\n" + |
| " int b = 1;\n" + |
| " /*" + |
| " *" + |
| " */\n" + |
| " class C {}" + |
| "}"; |
| String s108 = " /*" + |
| " *" + |
| " */"; |
| |
| assertEquals("finding comments without typed var", 1, findMatchesCount(s107,s108)); |
| |
| String s109 = "class A { void b(); int b(int c); char d(char e); }\n" + |
| "A a; a.b(1); a.b(2); a.b(); a.d('e'); a.d('f'); a.d('g');"; |
| String s110 = "'_a.'_b:[exprtype( int ) ]('_c*);"; |
| assertEquals("caring about method return type", 2, findMatchesCount(s109,s110)); |
| |
| String s111 = "class A { void getManager() { getManager(); } };\n" + |
| "class B { void getManager() { getManager(); getManager(); } };"; |
| String s112 = "'Instance?:[exprtype( B )].getManager()"; |
| assertEquals("caring about missing qualifier type", 2, findMatchesCount(s111,s112)); |
| |
| String s112a = "'Instance?:[regex( B )].getManager()"; |
| assertEquals("static query should not match instance method", 0, findMatchesCount(s111, s112a)); |
| |
| String s112b = "B.getManager()"; |
| assertEquals("static query should not match instance method 2", 0, findMatchesCount(s111, s112b)); |
| |
| String s113 = "class A { static void a() { a(); }}\n" + |
| "class B { static void a() { a(); a(); }}\n"; |
| String s114 = "'_Q?:[regex( B )].a()"; |
| assertEquals("should care about implicit class qualifier", 2, findMatchesCount(s113, s114)); |
| |
| String s114a = "B.a()"; |
| assertEquals("should match simple implicit class qualifier query", 2, findMatchesCount(s113, s114a)); |
| |
| String s114b = "'_Q?:[exprtype( B )].a()"; |
| assertEquals("instance query should not match static method", 0, findMatchesCount(s113, s114b)); |
| |
| String s115 = "class A { int a; int f() { return a; }}\n" + |
| "class B { int a; int g() { return a + a; }}\n"; |
| String s116 = "'_Instance?:[exprtype( B )].a"; |
| assertEquals("should care about implicit instance qualifier", 2, findMatchesCount(s115, s116)); |
| |
| String s116a = "A.a"; |
| assertEquals("should not match instance method", 0, findMatchesCount(s115, s116a)); |
| |
| String s117 = "class A { static int a; static int f() { return a; }}\n" + |
| "class B { static int a; static int g() { return a + a; }}\n"; |
| String s118 = "'_Q?:[regex( B )].a"; |
| assertEquals("should care about implicit class qualifier for field", 2, findMatchesCount(s117, s118)); |
| |
| // b) hierarchy navigation support |
| // c) or search support |
| |
| // e) xml search (down-up, nested query), navigation from xml representation <-> java code |
| // f) impl data conversion (jdk 1.5 style) <-> other from (replace support) |
| |
| // Directions: |
| // @todo different navigation on sub/supertyping relation (fixed depth), methods implementing interface, |
| // g. like predicates |
| // i. performance |
| // more context for top level classes, difference with interface, etc |
| |
| // global issues: |
| // @todo matches out of context |
| // @todo proper regexp support |
| |
| // @todo define strict equality of the matches |
| // @todo search for field selection retrieves packages also |
| } |
| |
| public void testFQNInPatternAndVariableConstraints() { |
| String s1 = "import java.awt.List;\n" + |
| "class A { List l; }"; |
| String s1_2 = "import java.util.List;\n" + |
| "class A { List l; }"; |
| String s2 = "class '_ { 'Type:java\\.util\\.List '_Field; }"; |
| |
| assertEquals("No matches for qualified class",findMatchesCount(s1,s2,true),0); |
| assertEquals("Matches for qualified class",findMatchesCount(s1_2,s2,true),1); |
| |
| String s3 = "import java.util.ArrayList;\n" + |
| "class A { ArrayList l; }"; |
| String s4 = "class '_ { 'Type:*java\\.util\\.Collection '_Field; }"; |
| assertEquals("Matches for qualified class in hierarchy",findMatchesCount(s3,s4,true),1); |
| |
| String s5 = "import java.util.List;\n" + |
| "class A { { List l = new List(); l.add(\"1\"); } }"; |
| String s5_2 = "import java.awt.List;\n" + |
| "class A { { List l = new List(); l.add(\"1\"); } }"; |
| String s6 = "'a:[exprtype( java\\.util\\.List )]"; |
| String s6_2 = "'a:[exprtype( *java\\.util\\.Collection )]"; |
| String s6_3 = "java.util.List '_a = '_b?;"; |
| |
| assertEquals("Matches for qualified expr type",findMatchesCount(s5,s6,true), 2); |
| assertEquals("No matches for qualified expr type",findMatchesCount(s5_2,s6,true),0); |
| assertEquals("Matches for qualified expr type in hierarchy",findMatchesCount(s5,s6_2,true), 2); |
| |
| assertEquals("Matches for qualified var type in pattern",findMatchesCount(s5,s6_3,true),1); |
| assertEquals("No matches for qualified var type in pattern",findMatchesCount(s5_2,s6_3,true),0); |
| |
| String s7 = "import java.util.List;\n" + |
| "class A extends List { }"; |
| String s7_2 = "import java.awt.List;\n" + |
| "class A extends List {}"; |
| |
| String s8 = "class 'a extends java.util.List {}"; |
| |
| assertEquals("Matches for qualified type in pattern",findMatchesCount(s7,s8,true),1); |
| assertEquals("No matches for qualified type in pattern",findMatchesCount(s7_2,s8,true),0); |
| |
| String s9 = "String.intern(\"1\");\n" + |
| "java.util.Collections.sort(null);" + |
| "java.util.Collections.sort(null);"; |
| String s10 = "java.lang.String.'_method ( '_params* )"; |
| assertEquals("FQN in class name",1,findMatchesCount(s9,s10,false)); |
| } |
| |
| public void testAnnotations() throws Exception { |
| String s1 = "@MyBean(\"\")\n" + |
| "@MyBean2(\"\")\n" + |
| "public class TestBean {}\n" + |
| "@MyBean2(\"\")\n" + |
| "@MyBean(value=\"\")\n" + |
| "public class TestBean2 {}\n" + |
| "public class TestBean3 {}\n" + |
| "@MyBean(\"a\")\n" + |
| "@MyBean2(\"a\")\n" + |
| "public class TestBean4"; |
| String s2 = "@MyBean(\"\")\n" + |
| "@MyBean2(\"\")\n" + |
| "public class $a$ {}\n"; |
| |
| assertEquals("Simple find annotated class",2,findMatchesCount(s1,s2,false)); |
| assertEquals("Match value of anonymous name value pair 1", 1, findMatchesCount(s1, "@MyBean(\"a\") class $a$ {}")); |
| assertEquals("Match value of anonymous name value pair 2", 2, findMatchesCount(s1, "@MyBean(\"\") class $a$ {}")); |
| |
| String s3 = "@VisualBean(\"????????? ?????????? ? ??\")\n" + |
| "public class TestBean\n" + |
| "{\n" + |
| " @VisualBeanField(\n" + |
| " name = \"??? ????????????\",\n" + |
| " initialValue = \"?????????????\"\n" + |
| " )\n" + |
| " public String user;\n" + |
| "\n" + |
| " @VisualBeanField(\n" + |
| " name = \"??????\",\n" + |
| " initialValue = \"\",\n" + |
| " fieldType = FieldTypeEnum.PASSWORD_FIELD\n" + |
| " )\n" + |
| " public String password;\n" + |
| "\n" + |
| " @VisualBeanField(\n" + |
| " initialValue = \"User\",\n" + |
| " name = \"????? ???????\",\n" + |
| " name = \"Second name\",\n" + |
| " fieldType = FieldTypeEnum.COMBOBOX_FIELD,\n" + |
| " comboValues = {\n" + |
| " @ComboFieldValue(\"Administrator\"),\n" + |
| " @ComboFieldValue(\"User\"),\n" + |
| " @ComboFieldValue(\"Guest\")}\n" + |
| " ) \n" + |
| " public String accessRights;\n" + |
| " \n" + |
| " public String otherField;\n" + |
| "}"; |
| String s4 = "class '_a {\n" + |
| " @'_Annotation+ ( 'AnnotationMember*:name = '_AnnotationValue* )\n" + |
| " String '_field* ;\n" + |
| "}"; |
| String s4_2 = "class '_a {\n" + |
| " @'_Annotation+ ()\n" + |
| " String 'field* ;\n" + |
| "}"; |
| |
| assertEquals("Find annotation members of annotated field class",4,findMatchesCount(s3,s4,false)); |
| assertEquals("Find annotation fields",3,findMatchesCount(s3,s4_2,false)); |
| |
| String s5 = "class A {" + |
| " @NotNull private static Collection<PsiElement> resolveElements(final PsiReference reference, final Project project) {}\n" + |
| " @NotNull private static Collection resolveElements2(final PsiReference reference, final Project project) {}\n" + |
| "}"; |
| String s6 = "class '_c {@NotNull '_rt 'method* ('_pt* '_p*){ '_inst*; } }"; |
| String s6_2 = "class '_c {@'_:NotNull '_rt 'method* ('_pt* '_p*){ '_inst*; } }"; |
| |
| assertEquals("Find annotated methods",2,findMatchesCount(s5,s6)); |
| assertEquals("Find annotated methods, 2",2,findMatchesCount(s5,s6_2)); |
| |
| String s7 = "class A { void message(@NonNls String msg); }\n" + |
| "class B { void message2(String msg); }\n" + |
| "class C { void message2(String msg); }"; |
| String s8 = "class '_A { void 'b( @'_Ann{0,0}:NonNls String '_); }"; |
| assertEquals("Find not annotated methods",2,findMatchesCount(s7,s8)); |
| |
| String s9 = "class A {\n" + |
| " Object[] method1() {}\n" + |
| " Object method1_2() {}\n" + |
| " Object method1_3() {}\n" + |
| " Object method1_4() {}\n" + |
| " @MyAnnotation Object[] method2(int a) {}\n" + |
| " @NonNls Object[] method3() {}\n" + |
| "}"; |
| String s10 = "class '_A { @'_Ann{0,0}:NonNls '_Type:Object\\[\\] 'b+( '_pt* '_p* ); }"; |
| String s10_2 = "class '_A { @'_Ann{0,0}:NonNls '_Type [] 'b+( '_pt* '_p* ); }"; |
| String s10_3 = "class '_A { @'_Ann{0,0}:NonNls '_Type:Object [] 'b+( '_pt* '_p* ); }"; |
| assertEquals("Find not annotated methods, 2",2,findMatchesCount(s9,s10)); |
| assertEquals("Find not annotated methods, 2",2,findMatchesCount(s9,s10_2)); |
| assertEquals("Find not annotated methods, 2",2,findMatchesCount(s9,s10_3)); |
| |
| String s11 = "class A {\n" + |
| "@Foo(value=baz) int a;\n" + |
| "@Foo(value=baz2) int a2;\n" + |
| "@Foo(value=baz2) int a3;\n" + |
| "@Foo(value2=baz3) int a3;\n" + |
| "@Foo(value2=baz3) int a3;\n" + |
| "@Foo(value2=baz3) int a3;\n" + |
| "@Foo(value2=baz4) int a3;\n" + |
| "}"; |
| String s12 = "@Foo(value=baz) int 'a;)"; |
| String s12_2 = "@Foo(value='baz:baz2 ) int 'a;)"; |
| String s12_3 = "@Foo('value:value2 = baz3 ) int 'a;)"; |
| String s12_4 = "@Foo('value:value2 = 'baz3:baz3 ) int 'a;)"; |
| String s12_5 = "@Foo('value:value2 = 'baz3:baz ) int 'a;)"; |
| String s12_6 = "@Foo('value:value2 = 'baz3 ) int 'a;)"; |
| String s12_7 = "@Foo('value:value2 = ) int 'a;"; |
| |
| assertEquals("Find anno parameter value",1,findMatchesCount(s11,s12)); |
| assertEquals("Find anno parameter value",2,findMatchesCount(s11,s12_2)); |
| assertEquals("Find anno parameter value",3,findMatchesCount(s11,s12_3)); |
| assertEquals("Find anno parameter value",3,findMatchesCount(s11,s12_4)); |
| assertEquals("Find anno parameter value",0,findMatchesCount(s11,s12_5)); |
| assertEquals("Find anno parameter value",4,findMatchesCount(s11,s12_6)); |
| assertEquals("Find anno parameter value",4,findMatchesCount(s11,s12_7)); |
| } |
| |
| public void testBoxingAndUnboxing() { |
| String s1 = " class A { void b(Integer i); void b2(int i); void c(int d); void c2(Integer d); }\n" + |
| "A a;\n" + |
| "a.b2(1)\n;" + |
| "a.b2(1)\n;" + |
| "a.b(1)\n;" + |
| "a.b( new Integer(0) )\n;" + |
| "a.b( new Integer(0) )\n;" + |
| "a.c(new Integer(2));\n" + |
| "a.c(new Integer(3));\n" + |
| "a.c2(new Integer(3));\n" + |
| "a.c(3);"; |
| String s2 = "a.'b('_Params:[formal( Integer ) && exprtype( int ) ])"; |
| String s2_2 = "a.c('_Params:[formal( int ) && exprtype( Integer ) ])"; |
| |
| assertEquals("Find boxing in method call",1,findMatchesCount(s1,s2,false)); |
| assertEquals("Find unboxing in method call",2,findMatchesCount(s1,s2_2,false)); |
| } |
| |
| public void testCommentsInDclSearch() { |
| String s1 = "class A {\n" + |
| " int a; // comment\n" + |
| " char b;\n" + |
| " int c; // comment2\n" + |
| "}"; |
| String s1_2 = "class A {\n" + |
| " // comment\n" + |
| " int a;\n" + |
| " char b;\n" + |
| " // comment2\n" + |
| " int c;\n" + |
| "}"; |
| |
| String s2 = "'_Type '_Variable = '_Value?; //'Comment"; |
| String s2_2 = "//'Comment\n" + |
| "'_Type '_Variable = '_Value?;"; |
| |
| assertEquals("Find field by dcl with comment",2,findMatchesCount(s1,s2)); |
| assertEquals("Find field by dcl with comment 2",2,findMatchesCount(s1_2,s2_2)); |
| } |
| |
| public void testSearchingEmptyModifiers() { |
| |
| String s1 = "class A {\n" + |
| " int a;\n" + |
| " private char b;\n" + |
| " private char b2;\n" + |
| " public int c;\n" + |
| " public int c2;\n" + |
| "}"; |
| String s2 = "@Modifier(\"packageLocal\") '_Type '_Variable = '_Value?;"; |
| String s2_2 = "@Modifier({\"packageLocal\",\"private\"}) '_Type '_Variable = '_Value?;"; |
| String s2_3 = "@Modifier({\"PackageLocal\",\"private\"}) '_Type '_Variable = '_Value?;"; |
| |
| assertEquals("Finding package local dcls",1,findMatchesCount(s1,s2)); |
| assertEquals("Finding package local dcls",3,findMatchesCount(s1,s2_2)); |
| |
| try { |
| findMatchesCount(s1,s2_3); |
| assertTrue("Finding package local dcls",false); |
| } catch(MalformedPatternException ex) { |
| |
| } |
| |
| String s3 = "class A {\n" + |
| " int a;\n" + |
| " static char b;\n" + |
| " static char b2;\n" + |
| "}"; |
| String s4 = "@Modifier(\"Instance\") '_Type '_Variable = '_Value?;"; |
| String s4_2 = "@Modifier({\"static\",\"Instance\"}) '_Type '_Variable = '_Value?;"; |
| assertEquals("Finding instance fields",1,findMatchesCount(s3,s4)); |
| assertEquals("Finding all fields",3,findMatchesCount(s3,s4_2)); |
| |
| String s5 = "class A {}\n" + |
| "abstract class B {}\n" + |
| "final class C {}\n" + |
| "class D {}"; |
| String s6 = "@Modifier(\"Instance\") class 'Type {}"; |
| String s6_2 = "@Modifier({\"abstract\",\"final\",\"Instance\"}) class 'Type {}"; |
| assertEquals("Finding instance classes",3,findMatchesCount(s5,s6)); |
| assertEquals("Finding all classes",4,findMatchesCount(s5,s6_2)); |
| } |
| |
| public void testSearchTransientFieldsWithModifier() { |
| String source = |
| "public class TestClass {\n" + |
| " transient private String field1;\n" + |
| " transient String field2;\n" + |
| " String field3;\n" + |
| "}"; |
| |
| String template = "transient @Modifier(\"packageLocal\") '_Type '_Variable = '_Value?;"; |
| |
| assertEquals("Finding package-local transient fields", 1, findMatchesCount(source, template)); |
| } |
| |
| public void test() { |
| String s1 = "if (LOG.isDebugEnabled()) {\n" + |
| " int a = 1;\n" + |
| " int a = 1;\n" + |
| "}"; |
| String s2 = "if ('_Log.isDebugEnabled()) {\n" + |
| " '_ThenStatement;\n" + |
| " '_ThenStatement;\n" + |
| "}"; |
| assertEquals("Comparing declarations",1,findMatchesCount(s1,s2)); |
| } |
| |
| public void testFindStaticMethodsWithinHierarchy() { |
| String s1 = "class A {}\n" + |
| "class B extends A { static void foo(); }\n" + |
| "class B2 extends A { static void foo(int a); }\n" + |
| "class B3 extends A { static void foo(int a, int b); }\n" + |
| "class C { static void foo(); }\n" + |
| "B.foo();\n" + |
| "B2.foo(1);\n" + |
| "B3.foo(2,3);\n" + |
| "C.foo();"; |
| String s2 = "'_Instance:[regex( *A )].'_Method:[regex( foo )] ( '_Params* )"; |
| assertEquals("Find static methods within expr type hierarchy", 3, findMatchesCount(s1,s2)); |
| } |
| |
| public void testFindClassesWithinHierarchy() { |
| String s1 = "class A implements I {}\n" + |
| "interface I {}\n" + |
| "class B extends A implements I { }\n" + |
| "class B2 implements I { }\n" + |
| "class B3 extends A { }\n" + |
| "class C extends B2 { static void foo(); }\n"; |
| String s2 = "class '_ extends '_Extends:[!regex( *A )] implements '_Implements:[regex( I )] {}"; |
| String s2_2 = "class '_ extends '_Extends:[!regex( *A )]{}"; |
| assertEquals("Find class within type hierarchy with not", 1, findMatchesCount(s1,s2)); |
| assertEquals("Find class within type hierarchy with not, 2", 1, findMatchesCount(s1,s2_2)); |
| } |
| |
| public void testFindTryWithoutProperFinally() { |
| String s1 = "try {\n" + |
| " conn = 1;\n" + |
| "} finally {\n" + |
| " conn.close();\n" + |
| "}\n" + |
| "try {\n" + |
| " conn = 1;\n" + |
| "} finally {\n" + |
| " int a = 1;\n" + |
| "}\n" + |
| "try {\n" + |
| " conn = 1;\n" + |
| "} finally {\n" + |
| " int a = 1;\n" + |
| "}"; |
| String s2 = "try { '_StatementBefore*; '_Dcl:[regex( conn = 1 )]; '_StatementAfter*; } finally { '_Finally*:[!regex( .*conn.* ) ]; }"; |
| assertEquals("FindTryWithoutProperFinally", 2, findMatchesCount(s1,s2)); |
| } |
| |
| public void testBug() { |
| String s1 = "public class DiallingNumber extends DataGroup\n" + "{\n" + " protected static byte [] CLEAR = { };\n" + "\n" + |
| " private static DataItemTemplate template;\n" + "\n" + "\tprotected DataTemplate createDefaultTemplate()\n" + "\t{\n" + |
| " return null;\n" + " }\n" + "}"; |
| String s2 = "class '_Class {\n" + " static '_FieldType '_FieldName:.*template.* = '_FieldInitial?;\n" + |
| " '_RetType createDefaultTemplate() { '_Statements*; }\n" + "\t'_Content*\n" + "}"; |
| assertEquals("Bug in class matching", 1, findMatchesCount(s1,s2)); |
| } |
| |
| //public void testFindFieldUsageByQName() { |
| // String s1 = "{ class A { int b; { b = 1; } } class B extends A { { this.b = 2} } { B i; i.b = 3; } }"; |
| // String s2 = "A.b"; |
| // assertEquals( 3, findMatchesCount(s1,s2)); |
| //} |
| // |
| //public void testFindMethodUsageByQName() { |
| // String s1 = "{ class A { void b(int a) {} { b(1); } } class B extends A { { this.b(2); } } { B i; i.b(3); } }"; |
| // String s2 = "A.b"; |
| // assertEquals( 3, findMatchesCount(s1,s2)); |
| //} |
| |
| public void _testStaticInstanceInitializers() { |
| String s1 = "public class DiallingNumber {\n static { int a = 1; } static { int b = 1; } { int c = 2; }}"; |
| String s2 = "class '_Class {\n" + " static { 't*; } }"; |
| String s2_2 = "class '_Class {\n" + " { 't*; } }"; |
| String s2_3 = "class '_Class {\n" + " @Modifier(\"Instance\") { 't*; } }"; |
| assertEquals("Static / instance initializers", 2, findMatchesCount(s1,s2)); |
| assertEquals("Static / instance initializers", 1, findMatchesCount(s1,s2_3)); |
| assertEquals("Static / instance initializers", 3, findMatchesCount(s1,s2_2)); |
| } |
| |
| @NotNull |
| @Override |
| protected String getTestDataPath() { |
| return PlatformTestUtil.getCommunityPath() + "/platform/structuralsearch/testData/java/"; |
| } |
| |
| public void testDoNotFindReturn() throws IOException { |
| String s1 = loadFile(getTestName(false) + ".java"); |
| String s2 = "ApplicationManager.getApplication().runReadAction(new Runnable() {\n" + |
| " public void run() {\n" + |
| " 't*:[ !regex( .*return.* ) ];\n" + |
| " }});"; |
| assertEquals(0, findMatchesCount(s1,s2)); |
| } |
| |
| public void testDownUpMatch() { |
| String s1 = "class A {\n" + |
| " int bbb(int c, int ddd, int eee) {\n" + |
| " int a = 1;\n" + |
| " try { int b = 1; } catch(Type t) { a = 2; } catch(Type2 t2) { a = 3; }\n" + |
| " }\n" + |
| "}"; |
| String s2 = "try { '_st*; } catch('_Type 't+) { '_st2*; }"; |
| |
| final List<PsiVariable> vars = new ArrayList<PsiVariable>(); |
| final PsiFile file = PsiFileFactory.getInstance(getProject()).createFileFromText("_.java", s1); |
| |
| file.acceptChildren(new JavaRecursiveElementWalkingVisitor() { |
| @Override public void visitVariable(final PsiVariable variable) { |
| super.visitVariable(variable); |
| vars.add(variable); |
| } |
| }); |
| |
| assertEquals(7, vars.size()); |
| List<MatchResult> results = new ArrayList<MatchResult>(); |
| |
| Matcher testMatcher = new Matcher(getProject()); |
| MatchOptions options = new MatchOptions(); |
| options.setSearchPattern(s2); |
| MatcherImplUtil.transform(options); |
| options.setFileType(StdFileTypes.JAVA); |
| |
| for(PsiVariable var:vars) { |
| final MatchResult matchResult = testMatcher.isMatchedByDownUp(var, options); |
| if (matchResult != null) results.add(matchResult); |
| assertTrue( |
| (var instanceof PsiParameter && var.getParent() instanceof PsiCatchSection && matchResult != null) || |
| matchResult == null |
| ); |
| } |
| |
| assertEquals(2, results.size()); |
| MatchResult result = results.get(0); |
| assertEquals("t", result.getMatchImage()); |
| |
| result = results.get(1); |
| assertEquals("t2", result.getMatchImage()); |
| |
| results.clear(); |
| String s2_2 = "try { '_st*; } catch('Type:Type2 '_t) { '_st2*; }"; |
| |
| options.clearVariableConstraints(); |
| options.setSearchPattern(s2_2); |
| MatcherImplUtil.transform(options); |
| |
| for(PsiVariable var:vars) { |
| final PsiTypeElement typeElement = var.getTypeElement(); |
| final MatchResult matchResult = testMatcher.isMatchedByDownUp(typeElement, options); |
| if (matchResult != null) results.add(matchResult); |
| assertTrue( |
| (var instanceof PsiParameter && var.getParent() instanceof PsiCatchSection && matchResult != null) || |
| matchResult == null |
| ); |
| } |
| |
| assertEquals(1, results.size()); |
| |
| result = results.get(0); |
| assertEquals("Type2", result.getMatchImage()); |
| } |
| |
| @Bombed(day = 28, description = "support it", month = Calendar.JULY, user = "maxim.mossienko") |
| public void _testContainsPredicate() { |
| String s1 = "{{\n" + |
| " int a;\n" + |
| " a = 1;\n" + |
| "}\n" + |
| "{\n" + |
| " int b = 1;\n" + |
| " b = 1;\n" + |
| "}\n" + |
| "{\n" + |
| " int c = 2;\n" + |
| " c = 2;\n" + |
| "}}"; |
| String s2 = "{\n" + |
| " '_a*:[contains( \"'type $a$ = $b$;\" )];\n" + |
| "}"; |
| |
| String s2_2 = "{\n" + |
| " '_a*:[!contains( \"$type$ $a$ = $b$;\" )];\n" + |
| "}"; |
| |
| assertEquals(2, findMatchesCount(s1, s2)); |
| assertEquals(1, findMatchesCount(s1, s2_2)); |
| } |
| |
| public void testWithinPredicate() { |
| String s1 = "if (true) {\n" + |
| " int a = 1;\n" + |
| "}\n" + |
| "if (true) {\n" + |
| " int b = 1;\n" + |
| "}\n" + |
| "while(true) {\n" + |
| " int c = 2;\n" + |
| "}"; |
| String s2 = "'_type 'a:[within( \"if ('_a) { '_st*; }\" )] = '_b;"; |
| String s2_2 = "'_type 'a:[!within( \"if ('_a) { '_st*; }\" )] = '_b;"; |
| |
| assertEquals(2,findMatchesCount(s1, s2)); |
| assertEquals(1,findMatchesCount(s1, s2_2)); |
| |
| // TODO: xxx |
| //String s3 = "if (true) {\n" + |
| // " if (true) return;\n" + |
| // " int a = 1;\n" + |
| // "}\n else if (true) {\n" + |
| // " return;\n" + |
| // "}"; |
| //assertEquals(2,findMatchesCount(s3, s2)); |
| //assertEquals(1,findMatchesCount(s3, s2_2)); |
| } |
| |
| public void testWithinPredicate2() { |
| String s3 = "class C {\n" + |
| " void aaa() {\n" + |
| " LOG.debug(true);\n" + |
| " LOG.debug(true);\n" + |
| " LOG.debug(true);\n" + |
| " LOG.debug(true);\n" + |
| " LOG.debug(true);\n" + |
| " if (true) {\n" + |
| " LOG.debug(true);\n" + |
| " }\n" + |
| " if (true) LOG.debug(true);\n" + |
| " if (true) { int 1 = 1; } else { LOG.debug(true); }\n" + |
| " }" + |
| "}"; |
| String s4 = "LOG.debug('_params*:[!within( \"if('_a) { 'st*; }\" )]);"; |
| |
| assertEquals(6,findMatchesCount(s3, s4)); |
| } |
| |
| public void testMultiStatementPatternWithTypedVariable() throws Exception { |
| String s = "Integer i;\ni.valueOf();"; |
| String s_2 = "Integer i;\nint a = 1;\ni.valueOf();"; |
| String s2 = "Integer '_i;\n'_i.valueOf();"; |
| String s2_2 = "Integer '_i;\n'_st; '_i.valueOf();"; |
| String s2_3 = "Integer '_i;\n'_st*; '_i.valueOf();"; |
| |
| assertEquals(1, findMatchesCount(s,s2)); |
| assertEquals(1, findMatchesCount(s_2,s2_2)); |
| assertEquals(1, findMatchesCount(s_2,s2_3)); |
| assertEquals(1, findMatchesCount(s,s2_3)); |
| } |
| |
| public void testFindAnnotationDeclarations() throws Exception { |
| String s = "interface Foo {} interface Bar {} @interface X {}"; |
| String s2 = "@interface 'x {}"; |
| |
| assertEquals(1, findMatchesCount(s,s2)); |
| } |
| |
| public void testFindEnums() throws Exception { |
| String s = "class Foo {} class Bar {} enum X {}"; |
| String s2 = "enum 'x {}"; |
| |
| assertEquals(1, findMatchesCount(s,s2)); |
| } |
| |
| public void testFindDeclaration() throws Exception { |
| String s = "public class F {\n" + |
| " static Category cat = Category.getInstance(F.class.getName());\n" + |
| " Category cat2 = Category.getInstance(F.class.getName());\n" + |
| " Category cat3 = Category.getInstance(F.class.getName());\n" + |
| "}"; |
| String s2 = "static $Category$ $cat$ = $Category$.getInstance($Arg$);"; |
| |
| assertEquals(1, findMatchesCount(s,s2)); |
| } |
| |
| public void testFindMethodCallWithTwoOrThreeParameters() { |
| String source = "{ String.format(\"\"); String.format(\"\", 1); String.format(\"\", 1, 2); String.format(\"\", 1, 2, 3); }"; |
| String pattern = "'_Instance.'_MethodCall('_Parameter{2,3})"; |
| |
| assertEquals(2, findMatchesCount(source, pattern)); |
| } |
| |
| public void testFindMethodWithCountedExceptionsInThrows() { |
| String source = "class A {" + |
| " void a() {}" + |
| " void b() throws E1 {}" + |
| " void c() throws E1, E2{}" + |
| " void d() throws E1, E2, E3 {}" + |
| "}"; |
| |
| String pattern1 = "class '_A {" + |
| " '_type+ 'method+ () throws '_E{0,0}" + |
| "}"; |
| assertEquals(1, findMatchesCount(source, pattern1)); |
| |
| String pattern2 = "class '_A {" + |
| " '_type+ 'method+ () throws '_E{1,2}" + |
| "}"; |
| assertEquals(2, findMatchesCount(source, pattern2)); |
| |
| String pattern3 = "class '_A {" + |
| " '_type+ 'method+ () throws '_E{2,2}" + |
| "}"; |
| assertEquals(1, findMatchesCount(source, pattern3)); |
| |
| String pattern4 = "class '_A {" + |
| " '_type+ 'method+ () throws '_E{0,0}:[ regex( E2 )]" + |
| "}"; |
| assertEquals(2, findMatchesCount(source, pattern4)); |
| } |
| |
| public void testFindMethodsCalledWithinClass() { |
| String source = "class A {" + |
| " void a() {}" + |
| " static void b() {}" + |
| " void c() {" + |
| " a();" + |
| " b();" + |
| " }" + |
| "}" + |
| "class B extends A {" + |
| " void d() {" + |
| " a();" + |
| " b();" + |
| " }" + |
| "}"; |
| String pattern1 = "this.a()"; |
| assertEquals(2, findMatchesCount(source, pattern1)); |
| } |
| |
| public void testFindReferenceWithParentheses() { |
| String source = "class A {" + |
| " String value;" + |
| " A(String v) {" + |
| " value = (value);" + |
| " System.out.println(((2)));" + |
| " System.out.println(2);" + |
| " }" + |
| "}"; |
| |
| String pattern1 = "'_value='_value"; |
| assertEquals(1, findMatchesCount(source, pattern1)); |
| |
| String pattern2 = "System.out.println('_v);" + |
| "System.out.println('_v);"; |
| assertEquals(1, findMatchesCount(source, pattern2)); |
| } |
| |
| public void testFindSelfAssignment() { |
| String source = "class A {" + |
| " protected String s;" + |
| " A(String t) {" + |
| " this.s = s;" + |
| " t = t;" + |
| " s = this.s;" + |
| " }" + |
| //"}" + |
| //"class B {" + |
| //" B(String t) {" + |
| //" super.s = s;" + // would be nice if found also |
| //" }" + |
| "}"; |
| |
| String pattern = "'_var='_var"; |
| assertEquals(3, findMatchesCount(source, pattern)); |
| } |
| |
| public void testFindLambdas() { |
| String source = "public interface IntFunction<R> {" + |
| " R apply(int value);" + |
| "}" + |
| "public interface Function<T, R> {" + |
| " R apply(T t);" + |
| "}" + |
| "class A {" + |
| " void m() {" + |
| " Runnable q = () -> { /*comment*/ };" + |
| " Runnable r = () -> { System.out.println(); };" + |
| " IntFunction<String> f = a -> \"hello\";" + |
| " Function<String, String> g = a -> \"world\";" + |
| " }" + |
| "}"; |
| |
| String pattern1 = "() ->"; |
| assertEquals("should find lamdas", 4, findMatchesCount(source, pattern1)); |
| |
| String pattern2 = "(int '_a) -> {}"; |
| assertEquals("should find lambdas with specific parameter type", 1, findMatchesCount(source, pattern2)); |
| |
| String pattern3 = "('_a{0,0})->{}"; |
| assertEquals("should find lambdas without any parameters", 2, findMatchesCount(source, pattern3)); |
| |
| String pattern4 = "()->System.out.println()"; |
| assertEquals("should find lambdas with matching body", 1, findMatchesCount(source, pattern4)); |
| |
| String pattern5 = "()->{/*comment*/}"; |
| assertEquals("should find lambdas with comment body", 1, findMatchesCount(source, pattern5)); |
| } |
| |
| public void testFindDefaultMethods() { |
| String source = "interface XYZ {" + |
| " default void m() {" + |
| " System.out.println();" + |
| " }" + |
| " void f();" + |
| " void g();" + |
| "}" + |
| "interface ABC {" + |
| " void m();" + |
| "}"; |
| |
| String pattern1 = "interface '_Class { default '_ReturnType+ 'MethodName+('_ParameterType* '_Parameter*);}"; |
| assertEquals("should find default method", 1, findMatchesCount(source, pattern1)); |
| |
| String pattern2 = "interface 'Class { default '_ReturnType+ '_MethodName{0,0}('_ParameterType* '_Parameter*);}"; |
| assertEquals("should find interface without default methods", 1, findMatchesCount(source, pattern2)); |
| } |
| |
| public void testFindMethodReferences() { |
| String source = "class A {" + |
| " Runnable r = System.out::println;" + |
| " Runnable s = this::hashCode;" + |
| " Runnable t = this::new;" + |
| " static {" + |
| " System.out.println();" + |
| " }" + |
| "}"; |
| |
| String pattern1 = "System . out :: println"; |
| assertEquals("should find method reference", 1, findMatchesCount(source, pattern1)); |
| |
| String pattern2 = "this::'_a"; |
| assertEquals("should find method reference 2", 2, findMatchesCount(source, pattern2)); |
| |
| String pattern3 = "'_a::'_b"; |
| assertEquals("should find all method references", 3, findMatchesCount(source, pattern3)); |
| } |
| |
| public void testNoUnexpectedException() { |
| String source = "{}"; |
| |
| String pattern1 = "/*$A$a*/"; |
| MalformedPatternException ex = null; |
| try { |
| findMatchesCount(source, pattern1); |
| } catch (MalformedPatternException e) { |
| ex = e; |
| } |
| assertNotNull(ex); |
| |
| String pattern2 = "class $A$Visitor {}"; |
| try { |
| findMatchesCount(source, pattern2); |
| } catch (MalformedPatternException e) { |
| ex = e; |
| } |
| assertNotNull(ex); |
| |
| String pattern3 = "class $Class$ { \n" + |
| " class $n$$FieldType$ $FieldName$ = $Init$;\n" + |
| "}"; |
| try { |
| findMatchesCount(source, pattern3); |
| } catch (MalformedPatternException e) { |
| ex = e; |
| } |
| assertNotNull(ex); |
| } |
| } |