diff options
Diffstat (limited to 'platform/structuralsearch/testSource')
8 files changed, 5490 insertions, 0 deletions
diff --git a/platform/structuralsearch/testSource/com/intellij/structuralsearch/OptimizedSearchScanTest.java b/platform/structuralsearch/testSource/com/intellij/structuralsearch/OptimizedSearchScanTest.java new file mode 100644 index 000000000000..f17c45bfcf3d --- /dev/null +++ b/platform/structuralsearch/testSource/com/intellij/structuralsearch/OptimizedSearchScanTest.java @@ -0,0 +1,22 @@ +package com.intellij.structuralsearch; + +import com.intellij.structuralsearch.impl.matcher.compiler.PatternCompiler; +import com.intellij.idea.Bombed; + +import java.util.Calendar; + +/** + * @author Maxim.Mossienko + */ +@Bombed(day = 28, description = "support it", month = Calendar.JULY, user = "maxim.mossienko") +public abstract class OptimizedSearchScanTest extends StructuralSearchTestCase { + public void _testClassByQName() throws Exception { + String plan = findWordsToBeUsedWhenSearchingFor("A.f"); + assertEquals("[in code:f]", plan); + } + + private String findWordsToBeUsedWhenSearchingFor(final String s) { + findMatchesCount("{}",s); + return PatternCompiler.getLastFindPlan(); + } +} diff --git a/platform/structuralsearch/testSource/com/intellij/structuralsearch/SSBasedInspectionTest.java b/platform/structuralsearch/testSource/com/intellij/structuralsearch/SSBasedInspectionTest.java new file mode 100644 index 000000000000..ff2083ebfbfa --- /dev/null +++ b/platform/structuralsearch/testSource/com/intellij/structuralsearch/SSBasedInspectionTest.java @@ -0,0 +1,47 @@ +package com.intellij.structuralsearch; + +import com.intellij.codeInspection.ex.LocalInspectionToolWrapper; +import com.intellij.structuralsearch.inspection.highlightTemplate.SSBasedInspection; +import com.intellij.structuralsearch.plugin.ui.Configuration; +import com.intellij.structuralsearch.plugin.ui.SearchConfiguration; +import com.intellij.testFramework.InspectionTestCase; +import com.intellij.testFramework.PlatformTestUtil; + +import java.util.ArrayList; +import java.util.List; + +public class SSBasedInspectionTest extends InspectionTestCase { + private LocalInspectionToolWrapper myWrapper; + + @Override + protected void setUp() throws Exception { + super.setUp(); + SSBasedInspection inspection = new SSBasedInspection(); + List<Configuration> configurations = new ArrayList<Configuration>(); + SearchConfiguration configuration = new SearchConfiguration(); + MatchOptions options = new MatchOptions(); + options.setSearchPattern("int i;"); + configuration.setMatchOptions(options); + configurations.add(configuration); + configuration = new SearchConfiguration(); + options = new MatchOptions(); + options.setSearchPattern("f();"); + configuration.setMatchOptions(options); + configurations.add(configuration); + inspection.setConfigurations(configurations, myProject); + inspection.projectOpened(getProject()); + myWrapper = new LocalInspectionToolWrapper(inspection); + } + + public void testSimple() throws Exception { + doTest(); + } + + private void doTest() throws Exception { + doTest("ssBased/" + getTestName(true), myWrapper,"java 1.5"); + } + + protected String getTestDataPath() { + return PlatformTestUtil.getCommunityPath() + "/platform/structuralsearch/testData/"; + } +} diff --git a/platform/structuralsearch/testSource/com/intellij/structuralsearch/SSRCodeInsightTest.java b/platform/structuralsearch/testSource/com/intellij/structuralsearch/SSRCodeInsightTest.java new file mode 100644 index 000000000000..95cd33b0845a --- /dev/null +++ b/platform/structuralsearch/testSource/com/intellij/structuralsearch/SSRCodeInsightTest.java @@ -0,0 +1,75 @@ +package com.intellij.structuralsearch; + +import com.intellij.structuralsearch.inspection.highlightTemplate.SSBasedInspection; +import com.intellij.structuralsearch.plugin.ui.Configuration; +import com.intellij.structuralsearch.plugin.ui.SearchConfiguration; +import com.intellij.testFramework.IdeaTestCase; +import com.intellij.testFramework.PlatformTestUtil; +import com.intellij.testFramework.UsefulTestCase; +import com.intellij.testFramework.fixtures.*; +import com.intellij.testFramework.fixtures.impl.LightTempDirTestFixtureImpl; + +import java.util.Collections; + +public class SSRCodeInsightTest extends UsefulTestCase { + protected CodeInsightTestFixture myFixture; + private SSBasedInspection myInspection; + + public SSRCodeInsightTest() { + IdeaTestCase.initPlatformPrefix(); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + IdeaTestFixtureFactory factory = IdeaTestFixtureFactory.getFixtureFactory(); + TestFixtureBuilder<IdeaProjectTestFixture> fixtureBuilder = factory.createLightFixtureBuilder(new DefaultLightProjectDescriptor()); + final IdeaProjectTestFixture fixture = fixtureBuilder.getFixture(); + myFixture = IdeaTestFixtureFactory.getFixtureFactory().createCodeInsightFixture(fixture, + new LightTempDirTestFixtureImpl(true)); + myInspection = new SSBasedInspection(); + myFixture.enableInspections(myInspection); + myFixture.setUp(); + myFixture.setTestDataPath(getTestDataPath()); + } + + @Override + protected void tearDown() throws Exception { + myFixture.tearDown(); + myFixture = null; + myInspection = null; + super.tearDown(); + } + + public void testExpressionStatement() { + doTest("File.createTempFile($p1$, $p2$)", "Forbid File.createTempFile"); + } + + public void testTwoStatementPattern() { + doTest("$field$ = $something$;\n" + + "if ($field$ == null) {\n" + + " throw new $Exception$($msg$);\n" + + "}", + "silly null check"); + } + + private void doTest(final String searchPattern, final String patternName) { + final SearchConfiguration configuration = new SearchConfiguration(); + //display name + configuration.setName(patternName); + + //search pattern + final MatchOptions options = new MatchOptions(); + options.setSearchPattern(searchPattern); + configuration.setMatchOptions(options); + + myInspection.setConfigurations(Collections.<Configuration>singletonList(configuration), myFixture.getProject()); + myInspection.projectOpened(myFixture.getProject()); + + myFixture.testHighlighting(true, false, false, getTestName(false) + ".java"); + } + + protected String getTestDataPath() { + return PlatformTestUtil.getCommunityPath() + "/platform/structuralsearch/testData/ssBased"; + } +} diff --git a/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralReplaceTest.java b/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralReplaceTest.java new file mode 100644 index 000000000000..de9b668be4d3 --- /dev/null +++ b/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralReplaceTest.java @@ -0,0 +1,2132 @@ +package com.intellij.structuralsearch; + +import com.intellij.psi.CommonClassNames; +import com.intellij.testFramework.PlatformTestUtil; +import com.intellij.util.ThrowableRunnable; +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +/** + * @by Maxim.Mossienko + */ +@SuppressWarnings({"ALL"}) +public class StructuralReplaceTest extends StructuralReplaceTestCase { + public void testReplaceInLiterals() { + String s1 = "String ID_SPEED = \"Speed\";"; + String s2 = "String 'name = \"'string\";"; + String s2_2 = "String 'name = \"'string:[regex( .* )]\";"; + String s3 = "VSegAttribute $name$ = new VSegAttribute(\"$string$\");"; + String expectedResult = "VSegAttribute ID_SPEED = new VSegAttribute(\"Speed\");"; + + String actualResult = replacer.testReplace(s1,s2,s3,options); + assertEquals( + "Matching/replacing literals", + expectedResult, + actualResult + ); + + actualResult = replacer.testReplace(s1,s2_2,s3,options); + assertEquals( + "Matching/replacing literals", + expectedResult, + actualResult + ); + + String s4 = "params.put(\"BACKGROUND\", \"#7B528D\");"; + String s5 = "params.put(\"$FieldName$\", \"#$exp$\");"; + String s6 = "String $FieldName$ = \"$FieldName$\";\n" + + "params.put($FieldName$, \"$exp$\");"; + String expectedResult2 = "String BACKGROUND = \"BACKGROUND\";\n" + + "params.put(BACKGROUND, \"7B528D\");"; + + actualResult = replacer.testReplace(s4,s5,s6,options); + + assertEquals( + "string literal replacement 2", + expectedResult2, + actualResult + ); + + String s7 = "IconLoader.getIcon(\"/ant/property.png\");\n" + + "IconLoader.getIcon(\"/ant/another/property.png\");\n"; + String s8 = "IconLoader.getIcon(\"/'module/'name:[regex( \\w+ )].png\");"; + String s9 = "Icons.$module$.$name$;"; + String expectedResult3 = "Icons.ant.property;\n" + + "IconLoader.getIcon(\"/ant/another/property.png\");\n"; + + actualResult = replacer.testReplace(s7,s8,s9,options); + + assertEquals( + "string literal replacement 3", + expectedResult3, + actualResult + ); + + String s10 = "configureByFile(path + \"1.html\");\n" + + " checkResultByFile(path + \"1_after.html\");\n" + + " checkResultByFile(path + \"1_after2.html\");\n" + + " checkResultByFile(path + \"1_after3.html\");"; + String s11 = "\"'a.html\""; + String s12 = "\"$a$.\"+ext"; + String expectedResult4 = "configureByFile(path + \"1.\"+ext);\n" + + " checkResultByFile(path + \"1_after.\"+ext);\n" + + " checkResultByFile(path + \"1_after2.\"+ext);\n" + + " checkResultByFile(path + \"1_after3.\"+ext);"; + + actualResult = replacer.testReplace(s10,s11,s12,options); + assertEquals( + "string literal replacement 4", + expectedResult4, + actualResult + ); + } + + public void testReplace2() { + String s1 = "package com.www.xxx.yyy;\n" + + "\n" + + "import javax.swing.*;\n" + + "\n" + + "public class Test {\n" + + " public static void main(String[] args) {\n" + + " if (1==1)\n" + + " JOptionPane.showMessageDialog(null, \"MESSAGE\");\n" + + " }\n" + + "}"; + String s2 = "JOptionPane.'showDialog(null, 'msg);"; + String s3 = "//FIXME provide a parent frame\n" + + "JOptionPane.$showDialog$(null, $msg$);"; + + String expectedResult = "package com.www.xxx.yyy;\n" + + "\n" + + "import javax.swing.*;\n" + + "\n" + + "public class Test {\n" + + " public static void main(String[] args) {\n" + + " if (1==1)\n" + + " //FIXME provide a parent frame\n" + + "JOptionPane.showMessageDialog(null, \"MESSAGE\");\n" + + " }\n" + + "}"; + + actualResult = replacer.testReplace(s1,s2,s3,options); + assertEquals( + "adding comment to statement inside the if body", + expectedResult, + actualResult + ); + + String s4 = "myButton.setText(\"Ok\");"; + String s5 = "'Instance.'MethodCall:[regex( setText )]('Parameter*:[regex( \"Ok\" )]);"; + String s6 = "$Instance$.$MethodCall$(\"OK\");"; + + String expectedResult2 = "myButton.setText(\"OK\");"; + + actualResult = replacer.testReplace(s4,s5,s6,options); + assertEquals( + "adding comment to statement inside the if body", + expectedResult2, + actualResult + ); + } + + public void testReplace() { + String str = "// searching for several constructions\n" + + " lastTest = \"several constructions match\";\n" + + " matches = testMatcher.findMatches(s5,s4, options);\n" + + " if (matches==null || matches.size()!=3) return false;\n" + + "\n" + + " // searching for several constructions\n" + + " lastTest = \"several constructions 2\";\n" + + " matches = testMatcher.findMatches(s5,s6, options);\n" + + " if (matches.size()!=0) return false;\n" + + "\n" + + " //options.setLooseMatching(true);\n" + + " // searching for several constructions\n" + + " lastTest = \"several constructions 3\";\n" + + " matches = testMatcher.findMatches(s7,s8, options);\n" + + " if (matches.size()!=2) return false;"; + + String str2=" lastTest = 'Descr;\n" + + " matches = testMatcher.findMatches('In,'Pattern, options);\n" + + " if (matches.size()!='Number) return false;"; + String str3 = "assertEquals($Descr$,testMatcher.findMatches($In$,$Pattern$, options).size(),$Number$);"; + String expectedResult1 = "// searching for several constructions\n" + + " lastTest = \"several constructions match\";\n" + + " matches = testMatcher.findMatches(s5, s4, options);\n" + + " if (matches == null || matches.size() != 3) return false;\n" + + "\n" + + " // searching for several constructions\n" + + " assertEquals(\"several constructions 2\", testMatcher.findMatches(s5, s6, options).size(), 0);\n" + + "\n" + + " //options.setLooseMatching(true);\n" + + " // searching for several constructions\n" + + " assertEquals(\"several constructions 3\", testMatcher.findMatches(s7, s8, options).size(), 2);"; + + String str4 = ""; + + options.setToReformatAccordingToStyle(true); + actualResult = replacer.testReplace(str,str2,str3,options); + options.setToReformatAccordingToStyle(false); + assertEquals("Basic replacement with formatter",expectedResult1,actualResult); + + actualResult = replacer.testReplace(str,str2,str4,options); + String expectedResult2 = "// searching for several constructions\n" + + " lastTest = \"several constructions match\";\n" + + " matches = testMatcher.findMatches(s5,s4, options);\n" + + " if (matches==null || matches.size()!=3) return false;\n" + + "\n" + + " // searching for several constructions\n" + + "\n" + + " //options.setLooseMatching(true);\n" + + " // searching for several constructions"; + + assertEquals("Empty replacement",expectedResult2,actualResult); + + String str5 = "testMatcher.findMatches('In,'Pattern, options).size()"; + String str6 = "findMatchesCount($In$,$Pattern$)"; + String expectedResult3="// searching for several constructions\n" + + " lastTest = \"several constructions match\";\n" + + " matches = testMatcher.findMatches(s5, s4, options);\n" + + " if (matches == null || matches.size() != 3) return false;\n" + + "\n" + + " // searching for several constructions\n" + + " assertEquals(\"several constructions 2\", findMatchesCount(s5,s6), 0);\n" + + "\n" + + " //options.setLooseMatching(true);\n" + + " // searching for several constructions\n" + + " assertEquals(\"several constructions 3\", findMatchesCount(s7,s8), 2);"; + actualResult = replacer.testReplace(expectedResult1,str5,str6,options); + + assertEquals( "Expression replacement", expectedResult3,actualResult ); + + String str7 = "try { a.doSomething(); b.doSomething(); } catch(IOException ex) { ex.printStackTrace(); throw new RuntimeException(ex); }"; + String str8 = "try { 'Statements+; } catch('_ '_) { 'HandlerStatements+; }"; + String str9 = "$Statements$;"; + String expectedResult4 = "a.doSomething(); b.doSomething();"; + + actualResult = replacer.testReplace(str7,str8,str9,options); + assertEquals( "Multi line match in replacement", expectedResult4,actualResult ); + + String str10 = " parentNode.insert(compositeNode, i);\n" + + " if (asyncMode) {\n" + + " myTreeModel.nodesWereInserted(parentNode,new int[] {i} );\n" + + " }"; + String str11 = " 'parentNode.insert('newNode, 'i);\n" + + " if (asyncMode) {\n" + + " myTreeModel.nodesWereInserted('parentNode,new int[] {'i} );\n" + + " }"; + String str12 = "addChild($parentNode$,$newNode$, $i$);"; + String expectedResult5 = " addChild(parentNode,compositeNode, i);"; + + actualResult = replacer.testReplace(str10,str11,str12,options); + assertEquals( "Array initializer replacement", expectedResult5,actualResult); + + String str13 = " aaa(5,6,3,4,1,2);"; + String str14 = "aaa('t{2,2},3,4,'q{2,2});"; + String str15 = "aaa($q$,3,4,$t$);"; + String expectedResult6 = " aaa(1,2,3,4,5,6);"; + + actualResult = replacer.testReplace(str13,str14,str15,options); + assertEquals("Parameter multiple match",expectedResult6,actualResult); + + String str16 = " int c = a();"; + String str17 = "'t:a ('q*,'p*)"; + String str18 = "$t$($q$,1,$p$)"; + String expectedResult7 = " int c = a(1);"; + + actualResult = replacer.testReplace(str16,str17,str18,options); + assertEquals("Replacement of init in definition + empty substitution",expectedResult7,actualResult); + + String str19 = " aaa(bbb);"; + String str20 = "'t('_);"; + String str21 = "$t$(ccc);"; + String expectedResult8 = " aaa(ccc);"; + + actualResult = replacer.testReplace(str19,str20,str21,options); + assertEquals("One substition replacement",expectedResult8,actualResult); + + String str22 = " instance.setAAA(anotherInstance.getBBB());"; + String str23 = " 'i.'m:set(.+) ('a.'m2:get(.+) ());"; + String str24 = " $a$.set$m2_1$( $i$.get$m_1$() );"; + String expectedResult9 = " anotherInstance.setBBB( instance.getAAA() );"; + + actualResult = replacer.testReplace(str22,str23,str24,options); + assertEquals("Reg exp substitution replacement",expectedResult9,actualResult); + + String str25 = " LaterInvocator.invokeLater(new Runnable() {\n" + + " public void run() {\n" + + " LOG.info(\"refreshFilesAsync, modalityState=\" + ModalityState.current());\n" + + " myHandler.getFiles().refreshFilesAsync(new Runnable() {\n" + + " public void run() {\n" + + " semaphore.up();\n" + + " }\n" + + " });\n" + + " }\n" + + " });"; + String str26 = " LaterInvocator.invokeLater('Params{1,10});"; + String str27 = " com.intellij.openapi.application.ApplicationManager.getApplication().invokeLater($Params$);"; + String expectedResult10 = " com.intellij.openapi.application.ApplicationManager.getApplication().invokeLater(new Runnable() {\n" + + " public void run() {\n" + + " LOG.info(\"refreshFilesAsync, modalityState=\" + ModalityState.current());\n" + + " myHandler.getFiles().refreshFilesAsync(new Runnable() {\n" + + " public void run() {\n" + + " semaphore.up();\n" + + " }\n" + + " });\n" + + " }\n" + + " });"; + + actualResult = replacer.testReplace(str25,str26,str27,options); + assertEquals("Anonymous in parameter",expectedResult10,actualResult); + + String str28 = "UTElementNode elementNode = new UTElementNode(myProject, processedElement, psiFile,\n" + + " processedElement.getTextOffset(), true,\n" + + " !myUsageViewDescriptor.toMarkInvalidOrReadonlyUsages(), null);"; + String str29 = "new UTElementNode('param, 'directory, 'null, '0, 'true, !'descr.toMarkInvalidOrReadonlyUsages(),\n" + + " 'referencesWord)"; + String str30 = "new UTElementNode($param$, $directory$, $null$, $0$, $true$, true,\n" + + " $referencesWord$)"; + + String expectedResult11 = "UTElementNode elementNode = new UTElementNode(myProject, processedElement, psiFile, processedElement.getTextOffset(), true, true,\n" + + " null);"; + actualResult = replacer.testReplace(str28,str29,str30,options); + assertEquals("Replace in def initializer",expectedResult11,actualResult); + + String s31 = "a = b; b = c; a=a; c=c;"; + String s32 = "'a = 'a;"; + String s33 = "1 = 1;"; + String expectedResult12 = "a = b; b = c; 1 = 1; 1 = 1;"; + + actualResult = replacer.testReplace(s31,s32,s33,options); + assertEquals( + "replace silly assignments", + expectedResult12, + actualResult + ); + + String s34 = "ParamChecker.isTrue(1==1, \"!!!\");"; + String s35 = "ParamChecker.isTrue('expr, 'msg)"; + String s36 = "assert $expr$ : $msg$"; + + String expectedResult13 = "assert 1==1 : \"!!!\";"; + actualResult = replacer.testReplace(s34,s35,s36,options); + assertEquals( + "replace with assert", + expectedResult13, + actualResult + ); + + String s37 = "try { \n" + + " ParamChecker.isTrue(1==1, \"!!!\");\n \n" + + " // comment we want to leave\n \n" + + " ParamChecker.isTrue(2==2, \"!!!\");\n" + + "} catch(Exception ex) {}"; + String s38 = "try {\n" + + " 'Statement{0,100};\n" + + "} catch(Exception ex) {}"; + String s39 = "$Statement$;"; + + String expectedResult14 = "ParamChecker.isTrue(1==1, \"!!!\");\n \n" + + " // comment we want to leave\n \n" + + " ParamChecker.isTrue(2==2, \"!!!\");"; + actualResult = replacer.testReplace(s37,s38,s39,options); + assertEquals( + "remove try with comments inside", + expectedResult14, + actualResult + ); + + String s40 = "ParamChecker.instanceOf(queryKey, GroupBySqlTypePolicy.GroupKey.class);"; + String s41 = "ParamChecker.instanceOf('obj, 'class.class);"; + String s42 = "assert $obj$ instanceof $class$ : \"$obj$ is an instance of \" + $obj$.getClass() + \"; expected \" + $class$.class;"; + String expectedResult15 = "assert queryKey instanceof GroupBySqlTypePolicy.GroupKey : \"queryKey is an instance of \" + queryKey.getClass() + \"; expected \" + GroupBySqlTypePolicy.GroupKey.class;"; + + actualResult = replacer.testReplace(s40,s41,s42,options); + assertEquals( + "Matching/replacing .class literals", + expectedResult15, + actualResult + ); + + String s43 = "class Wpd {\n" + + " static final String TAG_BEAN_VALUE = \"\";\n" + + "}\n" + + "XmlTag beanTag = rootTag.findSubTag(Wpd.TAG_BEAN_VALUE);"; + String s44 = "'Instance?.findSubTag( 'Parameter:[exprtype( *String ) ])"; + String s45 = "jetbrains.fabrique.util.XmlApiUtil.findSubTag($Instance$, $Parameter$)"; + String expectedResult16 = "class Wpd {\n" + + " static final String TAG_BEAN_VALUE = \"\";\n" + + "}\n" + + "XmlTag beanTag = jetbrains.fabrique.util.XmlApiUtil.findSubTag(rootTag, Wpd.TAG_BEAN_VALUE);"; + + actualResult = replacer.testReplace(s43,s44,s45,options); + assertEquals( + "Matching/replacing static fields", + expectedResult16, + actualResult + ); + + String s46 = "Rectangle2D rec = new Rectangle2D.Double(\n" + + " drec.getX(),\n" + + " drec.getY(),\n" + + " drec.getWidth(),\n" + + " drec.getWidth());"; + String s47 = "$Instance$.$MethodCall$()"; + String s48 = "OtherClass.round($Instance$.$MethodCall$(),5)"; + String expectedResult17 = "Rectangle2D rec = new Rectangle2D.Double(\n" + + " OtherClass.round(drec.getX(),5),\n" + + " OtherClass.round(drec.getY(),5),\n" + + " OtherClass.round(drec.getWidth(),5),\n" + + " OtherClass.round(drec.getWidth(),5));"; + actualResult = replacer.testReplace(s46,s47,s48,options); + + assertEquals( + "Replace in constructor", + expectedResult17, + actualResult + ); + + String s49 = "class A {}\n" + + "class B extends A {}\n" + + "A a = new B();"; + String s50 = "A 'b = new 'B:*A ();"; + String s51 = "A $b$ = new $B$(\"$b$\");"; + String expectedResult18 = "class A {}\n" + + "class B extends A {}\n" + + "A a = new B(\"a\");"; + + actualResult = replacer.testReplace(s49,s50,s51,options); + + assertEquals( + "Class navigation", + expectedResult18, + actualResult + ); + + String s52 = "try {\n" + + " aaa();\n" + + "} finally {\n" + + " System.out.println();" + + "}\n" + + "try {\n" + + " aaa2();\n" + + "} catch(Exception ex) {\n" + + " aaa3();\n" + + "}\n" + + "finally {\n" + + " System.out.println();\n" + + "}\n" + + "try {\n" + + " aaa4();\n" + + "} catch(Exception ex) {\n" + + " aaa5();\n" + + "}\n"; + String s53 = "try { 'a; } finally {\n" + + " 'b;" + + "}"; + String s54 = "$a$;"; + String expectedResult19 = "aaa();\n" + + "try {\n" + + " aaa2();\n" + + "} catch(Exception ex) {\n" + + " aaa3();\n" + + "}\n" + + "finally {\n" + + " System.out.println();\n" + + "}\n" + + "try {\n" + + " aaa4();\n" + + "} catch(Exception ex) {\n" + + " aaa5();\n" + + "}\n"; + + actualResult = replacer.testReplace(s52,s53,s54,options); + + assertEquals( + "Try/ catch/ finally is replace with try/finally", + expectedResult19, + actualResult + ); + + String s55 = "for(Iterator<String> iterator = stringlist.iterator(); iterator.hasNext();) {\n" + + " String str = iterator.next();\n" + + " System.out.println( str );\n" + + "}"; + String s56 = "for (Iterator<$Type$> $variable$ = $container$.iterator(); $variable$.hasNext();) {\n" + + " $Type$ $var$ = $variable$.next();\n" + + " $Statements$;\n" + + "}"; + String s57 = "for($Type$ $var$:$container$) {\n" + + " $Statements$;\n" + + "}"; + String expectedResult20 = "for(String str :stringlist) {\n" + + " System.out.println( str );\n" + + "}"; + + actualResult = replacer.testReplace(s55,s56,s57,options); + + assertEquals( + "for with foreach", + expectedResult20, + actualResult + ); + + String s58 = "class A {\n" + + " static Set<String> b_MAP = new HashSet<String>();\n" + + " int c;\n" + + "}"; + String s59 = "'a:[ regex( (.*)_MAP ) ]"; + String s60 = "$a_1$_SET"; + String expectedResult21 = "class A {\n" + + " static Set<String> b_SET = new HashSet<String>();\n" + + " int c;\n" + + "}"; + + actualResult = replacer.testReplace(s58,s59,s60,options); + + assertEquals( + "replace symbol in definition", + expectedResult21, + actualResult + ); + + String s64 = "int x = 42;\n" + + "int y = 42; // Stuff"; + String s65 = "'Type 'Variable = 'Value; // 'Comment"; + String s66 = "/**\n" + + " *$Comment$\n" + + " */\n" + + "$Type$ $Variable$ = $Value$;"; + String expectedResult23 = "int x = 42;\n" + + "/**\n" + + " * Stuff\n" + + " */\n" + + "int y = 42;"; + + actualResult = replacer.testReplace(s64,s65,s66,options); + + assertEquals( + "Replacement of the comment with javadoc", + expectedResult23, + actualResult + ); + + String s61 = "try { 1=1; } catch(Exception e) { 1=1; } catch(Throwable t) { 2=2; }"; + String s62 = "try { 'a; } catch(Exception e) { 'b; }"; + String s63 = "try { $a$; } catch(Exception1 e) { $b$; } catch(Exception2 e) { $b$; }"; + String expectedResult22 = "try { 1=1; } catch(Exception1 e) { 1=1; } catch(Exception2 e) { 1=1; } catch (Throwable t) { 2=2; }"; + + actualResult = replacer.testReplace(s61,s62,s63,options); + + assertEquals( + "try replacement by another try will leave the unmatched catch", + expectedResult22, + actualResult + ); + + } + + public void testReplaceExpr() { + String s1 = "new SimpleDateFormat(\"yyyyMMddHHmmss\")"; + String s2 = "'expr"; + String s3 = "new AtomicReference<DateFormat>($expr$)"; + String expectedResult = "new AtomicReference<DateFormat>(new SimpleDateFormat(\"yyyyMMddHHmmss\"))"; + + actualResult = replacer.testReplace(s1, s2, s3, options); + + assertEquals("Replacement of top-level expression only", expectedResult, actualResult); + + String s4 = "get(\"smth\")"; + String s5 = "'expr"; + String s6 = "new Integer($expr$)"; + String expectedResult1 = "new Integer(get(\"smth\"))"; + + actualResult = replacer.testReplace(s4, s5, s6, options); + assertEquals("Replacement of top-level expression only", expectedResult1, actualResult); + } + + public void testReplaceParameter() { + String s1 = "class A { void b(int c, int d, int e) {} }"; + String s2 = "int d"; + String s3 = "int d2"; + String expectedResult = "class A { void b(int c, int d2, int e) {} }"; + + actualResult = replacer.testReplace(s1,s2,s3,options); + + assertEquals( + "replace method parameter", + expectedResult, + actualResult + ); + } + + public void testReplaceWithComments() { + String s1 = "map.put(key, value); // line 1"; + String s2 = "map.put(key, value); // line 1"; + String s3 = "map.put(key, value); // line 1"; + String expectedResult = "map.put(key, value); // line 1"; + + actualResult = replacer.testReplace(s1,s2,s3,options); + + assertEquals( + "replace self with comment after", + expectedResult, + actualResult + ); + + String s4 = "if (true) System.out.println(\"1111\"); else System.out.println(\"2222\");\n" + + "while(true) System.out.println(\"1111\");"; + String s5 = "System.out.println('Test);"; + String s6 = "/* System.out.println($Test$); */"; + actualResult = replacer.testReplace(s4,s5,s6,options); + String expectedResult2 = "if (true) /* System.out.println(\"1111\"); */; else /* System.out.println(\"2222\"); */;\n" + + "while(true) /* System.out.println(\"1111\"); */;"; + + assertEquals( + "replace with comment", + expectedResult2, + actualResult + ); + } + + public void testSeveralStatements() { + String s1 = "{\n" + + " System.out.println(1);\n" + + " System.out.println(2);\n" + + " System.out.println(3);\n" + + " }\n" + + "{\n" + + " System.out.println(1);\n" + + " System.out.println(2);\n" + + " System.out.println(3);\n" + + " }\n" + + "{\n" + + " System.out.println(1);\n" + + " System.out.println(2);\n" + + " System.out.println(3);\n" + + " }"; + String s2 = + " System.out.println(1);\n" + + " System.out.println(2);\n" + + " System.out.println(3);\n"; + String s3 = " System.out.println(3);\n" + + " System.out.println(2);\n" + + " System.out.println(1);\n"; + String expectedResult1 = " {\n" + + " System.out.println(3);\n" + + " System.out.println(2);\n" + + " System.out.println(1);\n" + + " }\n" + + " {\n" + + " System.out.println(3);\n" + + " System.out.println(2);\n" + + " System.out.println(1);\n" + + " }\n" + + " {\n" + + " System.out.println(3);\n" + + " System.out.println(2);\n" + + " System.out.println(1);\n" + + " }"; + options.setToReformatAccordingToStyle(true); + actualResult = replacer.testReplace(s1,s2,s3,options); + options.setToReformatAccordingToStyle(false); + assertEquals( + "three statements replacement", + expectedResult1, + actualResult + ); + + String s4 = "ProgressManager.getInstance().startNonCancelableAction();\n" + + " try {\n" + + " read(id, READ_PARENT);\n" + + " return myViewport.parent;\n" + + " }\n" + + " finally {\n" + + " ProgressManager.getInstance().finishNonCancelableAction();\n" + + " }"; + String s5 = "ProgressManager.getInstance().startNonCancelableAction();\n" + + " try {\n" + + " '_statement{2,2};\n" + + " }\n" + + " finally {\n" + + " ProgressManager.getInstance().finishNonCancelableAction();\n" + + " }"; + String s6 = "$statement$;"; + String expectedResult2 = "read(id, READ_PARENT);\n" + + " return myViewport.parent;"; + actualResult = replacer.testReplace(s4,s5,s6,options); + assertEquals( + "extra ;", + expectedResult2, + actualResult + ); + + String s7 = "public class A {\n" + + " void f() {\n" + + " new Runnable() {\n" + + " public void run() {\n" + + " l();\n" + + " }\n" + + "\n" + + " private void l() {\n" + + " int i = 9;\n" + + " int j = 9;\n" + + " }\n" + + " };\n" + + " new Runnable() {\n" + + " public void run() {\n" + + " l();\n" + + " }\n" + + "\n" + + " private void l() {\n" + + " l();\n" + + " l();\n" + + " }\n" + + " };\n" + + " }\n" + + "\n" + + "}"; + String s8 = "new Runnable() {\n" + + " public void run() {\n" + + " 'l ();\n" + + " }\n" + + " private void 'l () {\n" + + " 'st{2,2};\n" + + " }\n" + + "};"; + String s9 = "new My() {\n" + + " public void f() {\n" + + " $st$;\n" + + " }\n" + + "};"; + + String expectedResult3 = "public class A {\n" + + " void f() {\n" + + " new My() {\n" + + " public void f() {\n" + + " int i = 9;\n" + + " int j = 9;\n" + + " }\n" + + " };\n" + + " new My() {\n" + + " public void f() {\n" + + " l();\n" + + " l();\n" + + " }\n" + + " };\n" + + " }\n" + + "\n" + + "}"; + boolean formatAccordingToStyle = options.isToReformatAccordingToStyle(); + options.setToReformatAccordingToStyle(true); + actualResult = replacer.testReplace(s7,s8,s9,options); + assertEquals( + "extra ; 2", + expectedResult3, + actualResult + ); + + String s10 = "public class A {\n" + + " void f() {\n" + + " new Runnable() {\n" + + " public void run() {\n" + + " l();\n" + + " l();\n" + + " }\n" + + " public void run2() {\n" + + " l();\n" + + " l();\n" + + " }\n" + + "\n" + + " };\n" + + " new Runnable() {\n" + + " public void run() {\n" + + " l();\n" + + " l();\n" + + " }\n" + + " public void run2() {\n" + + " l();\n" + + " l();\n" + + " }\n" + + "\n" + + " };\n" + + "new Runnable() {\n" + + " public void run() {\n" + + " l();\n" + + " l();\n" + + " }\n" + + " public void run2() {\n" + + " l2();\n" + + " l2();\n" + + " }\n" + + "\n" + + " };\n" + + " }\n" + + "\n" + + " private void l() {\n" + + " int i = 9;\n" + + " int j = 9;\n" + + " }\n" + + "}\n" + + "\n" + + "abstract class My {\n" + + " abstract void f();\n" + + "}"; + String s11 = "new Runnable() {\n" + + " public void run() {\n" + + " 'l{2,2};\n" + + " }\n" + + " public void run2() {\n" + + " 'l{2,2};\n" + + " }\n" + + "\n" + + " };"; + String s12 = "new My() {\n" + + " public void f() {\n" + + " $l$;\n" + + " }\n" + + " };"; + String expectedResult4 = "public class A {\n" + + " void f() {\n" + + " new My() {\n" + + " public void f() {\n" + + " l();\n" + + " l();\n" + + " }\n" + + " };\n" + + " new My() {\n" + + " public void f() {\n" + + " l();\n" + + " l();\n" + + " }\n" + + " };\n" + + " new Runnable() {\n" + + " public void run() {\n" + + " l();\n" + + " l();\n" + + " }\n" + + "\n" + + " public void run2() {\n" + + " l2();\n" + + " l2();\n" + + " }\n" + + "\n" + + " };\n" + + " }\n" + + "\n" + + " private void l() {\n" + + " int i = 9;\n" + + " int j = 9;\n" + + " }\n" + + "}\n" + + "\n" + + "abstract class My {\n" + + " abstract void f();\n" + + "}"; + + actualResult = replacer.testReplace(s10,s11,s12,options); + assertEquals( + "same multiple occurences 2 times", + expectedResult4, + actualResult + ); + + options.setToReformatAccordingToStyle(formatAccordingToStyle); + + String s13 = " PsiLock.LOCK.acquire();\n" + + " try {\n" + + " return value;\n" + + " }\n" + + " finally {\n" + + " PsiLock.LOCK.release();\n" + + " }"; + String s13_2 = " PsiLock.LOCK.acquire();\n" + + " try {\n" + + " if (true) { return value; }\n" + + " }\n" + + " finally {\n" + + " PsiLock.LOCK.release();\n" + + " }"; + String s13_3 = " PsiLock.LOCK.acquire();\n" + + " try {\n" + + " if (true) { return value; }\n\n" + + " if (true) { return value; }\n" + + " }\n" + + " finally {\n" + + " PsiLock.LOCK.release();\n" + + " }"; + String s14 = " PsiLock.LOCK.acquire();\n" + + " try {\n" + + " 'T{1,1000};\n" + + " }\n" + + " finally {\n" + + " PsiLock.LOCK.release();\n" + + " }"; + String s15 = "synchronized(PsiLock.LOCK) {\n" + + " $T$;\n" + + "}"; + + String expectedResult5 = " synchronized (PsiLock.LOCK) {\n" + + " return value;\n" + + " }"; + options.setToReformatAccordingToStyle(true); + actualResult = replacer.testReplace(s13,s14,s15,options); + options.setToReformatAccordingToStyle(false); + + assertEquals( + "extra ; over return", + expectedResult5, + actualResult + ); + + String expectedResult6 = " synchronized (PsiLock.LOCK) {\n" + + " if (true) {\n" + + " return value;\n" + + " }\n" + + " }"; + options.setToReformatAccordingToStyle(true); + actualResult = replacer.testReplace(s13_2,s14,s15,options); + options.setToReformatAccordingToStyle(false); + + assertEquals( + "extra ; over if", + expectedResult6, + actualResult + ); + + String expectedResult7 = " synchronized (PsiLock.LOCK) {\n" + + " if (true) {\n" + + " return value;\n" + + " }\n" + + "\n" + + " if (true) {\n" + + " return value;\n" + + " }\n" + + " }"; + options.setToReformatAccordingToStyle(true); + actualResult = replacer.testReplace(s13_3,s14,s15,options); + options.setToReformatAccordingToStyle(false); + assertEquals( + "newlines in matches of several lines", + expectedResult7, + actualResult + ); + + String s16 = "public class SSTest {\n" + + " Object lock;\n" + + " public Object getProducts (String[] productNames) {\n" + + " synchronized (lock) {\n" + + " Object o = new Object ();\n" + + " assert o != null;\n" + + " return o;\n" + + " }\n" + + " }\n" + + "}"; + String s16_2 = "public class SSTest {\n" + + " Object lock;\n" + + " public void getProducts (String[] productNames) {\n" + + " synchronized (lock) {\n" + + " boolean[] v = {true};\n" + + " }\n" + + " }\n" + + "}"; + + String s17 = "synchronized(lock) {\n" + + " 'Statement*;\n" + + "}"; + + String s18 = "$Statement$;"; + String expectedResult8 = "public class SSTest {\n" + + " Object lock;\n" + + " public Object getProducts (String[] productNames) {\n" + + " Object o = new Object ();\n" + + " assert o != null;\n" + + " return o;\n" + + " }\n" + + "}"; + String expectedResult8_2 = "public class SSTest {\n" + + " Object lock;\n" + + " public void getProducts (String[] productNames) {\n" + + " boolean[] v = {true};\n" + + " }\n" + + "}"; + + actualResult = replacer.testReplace(s16,s17,s18,options); + assertEquals( + "extra ;", + expectedResult8, + actualResult + ); + + actualResult = replacer.testReplace(s16_2,s17,s18,options); + assertEquals( + "missed ;", + expectedResult8_2, + actualResult + ); + } + + public void testClassReplacement() { + boolean formatAccordingToStyle = options.isToReformatAccordingToStyle(); + options.setToReformatAccordingToStyle(true); + + String s1 = "class A { public void b() {} }"; + String s2 = "class 'a { 'Other* }"; + String s3 = "class $a$New { Logger LOG; $Other$ }"; + String expectedResult = " class ANew {\n" + + " Logger LOG;\n\n" + + " public void b() {\n" + + " }\n" + + " }"; + String actualResult; + actualResult = replacer.testReplace(s1,s2,s3,options); + assertEquals( + "Basic class replacement", + expectedResult, + actualResult + ); + + String s4 = "class A { class C {} public void b() {} int f; }"; + String s5 = "class 'a { 'Other* }"; + String s6 = "class $a$ { Logger LOG; $Other$ }"; + String expectedResult2 = " class A {\n" + + " Logger LOG;\n\n" + + " class C {\n" + + " }\n\n" + + " public void b() {\n" + + " }\n\n" + + " int f;\n" + + " }"; + + actualResult = replacer.testReplace(s4,s5,s6,options); + assertEquals( + "Order of members in class replacement", + expectedResult2, + actualResult + ); + + String s7 = "class A extends B { int c; void b() {} { a = 1; } }"; + String s8 = "class 'A extends B { 'Other* }"; + String s9 = "class $A$ extends B2 { $Other$ }"; + String expectedResult3 = " class A extends B2 {\n" + + " int c;\n\n" + + " void b() {\n" + + " }\n\n" + + " {\n" + + " a = 1;\n" + + " }\n" + + " }"; + + actualResult = replacer.testReplace(s7,s8,s9,options); + assertEquals("Unsupported pattern exception",actualResult,expectedResult3); + options.setToReformatAccordingToStyle(formatAccordingToStyle); + + String s10 = "/** @example */\n" + + "class A {\n" + + " class C {}\n" + + " public void b() {}\n" + + " int f;\n" + + "}"; + String s11 = "class 'a { 'Other* }"; + String s12 = "public class $a$ {\n" + + " $Other$\n" + + "}"; + String expectedResult4 = "/** @example */\n" + + " public class A {\n" + + " class C {\n" + + " }\n\n" + + " public void b() {\n" + + " }\n\n" + + " int f;\n" + + " }"; + + options.setToReformatAccordingToStyle(true); + actualResult = replacer.testReplace(s10,s11,s12,options); + options.setToReformatAccordingToStyle(false); + assertEquals("Make class public",expectedResult4,actualResult); + + String s13 = "class CustomThread extends Thread {\n" + + "public CustomThread(InputStream in, OutputStream out, boolean closeOutOnExit) {\n" + + " super(CustomThreadGroup.getThreadGroup(), \"CustomThread\");\n" + + " setDaemon(true);\n" + + " if (in instanceof BufferedInputStream) {\n" + + " bis = (BufferedInputStream)in;\n" + + " } else {\n" + + " bis = new BufferedInputStream(in);\n" + + " }\n" + + " this.out = out;\n" + + " this.closeOutOnExit = closeOutOnExit;\n" + + "}\n" + + "}"; + String s14 = "class 'Class extends Thread {\n" + + " 'Class('ParameterType* 'ParameterName*) {\n" + + "\t super (CustomThreadGroup.getThreadGroup(), 'superarg* );\n" + + " 'Statement*;\n" + + " }\n" + + "}"; + String s15 = "class $Class$ extends CustomThread {\n" + + " $Class$($ParameterType$ $ParameterName$) {\n" + + "\t super($superarg$);\n" + + " $Statement$;\n" + + " }\n" + + "}"; + + String expectedResult5 = " class CustomThread extends CustomThread {\n" + + " CustomThread(InputStream in, OutputStream out, boolean closeOutOnExit) {\n" + + " super(\"CustomThread\");\n" + + " setDaemon(true);\n" + + " if (in instanceof BufferedInputStream) {\n" + + " bis = (BufferedInputStream) in;\n" + + " } else {\n" + + " bis = new BufferedInputStream(in);\n" + + " }\n" + + " this.out = out;\n" + + " this.closeOutOnExit = closeOutOnExit;\n" + + " }\n" + + " }"; + options.setToReformatAccordingToStyle(true); + actualResult = replacer.testReplace(s13,s14,s15,options); + options.setToReformatAccordingToStyle(false); + assertEquals("Constructor replacement",expectedResult5,actualResult); + + String s16 = "public class A {}\n" + + "final class B {}"; + String s17 = "class 'A { 'Other* }"; + String s17_2 = "class 'A { private Log log = LogFactory.createLog(); 'Other* }"; + String s18 = "class $A$ { private Log log = LogFactory.createLog(); $Other$ }"; + String s18_2 = "class $A$ { $Other$ }"; + + actualResult = replacer.testReplace(s16,s17,s18,options); + String expectedResult6 = "public class A { private Log log = LogFactory.createLog(); }\n" + + "final class B { private Log log = LogFactory.createLog(); }"; + assertEquals("Modifier list for class",expectedResult6,actualResult); + + actualResult = replacer.testReplace(actualResult,s17_2,s18_2,options); + String expectedResult7 = "public class A { }\n" + + "final class B { }"; + assertEquals("Removing field",expectedResult7,actualResult); + + String s19 = "public class A extends Object implements Cloneable {}\n"; + String s20 = "class 'A { 'Other* }"; + String s21 = "class $A$ { private Log log = LogFactory.createLog(); $Other$ }"; + + actualResult = replacer.testReplace(s19,s20,s21,options); + String expectedResult8 = "public class A extends Object implements Cloneable { private Log log = LogFactory.createLog(); }\n"; + assertEquals("Extends / implements list for class",expectedResult8,actualResult); + + String s22 = "public class A<T> { int Afield; }\n"; + String s23 = "class 'A { 'Other* }"; + String s24 = "class $A$ { private Log log = LogFactory.createLog(); $Other$ }"; + + actualResult = replacer.testReplace(s22,s23,s24,options); + String expectedResult9 = "public class A<T> { private Log log = LogFactory.createLog(); int Afield; }\n"; + assertEquals("Type parameters for the class",expectedResult9,actualResult); + + String s25 = "class A {\n" + + " // comment before\n" + + " protected short a; // comment after\n" + + "}"; + String s26 = "short a;"; + String s27 = "Object a;"; + String expectedResult10 = "class A {\n" + + " // comment before\n" + + " protected Object a; // comment after\n" + + "}"; + + actualResult = replacer.testReplace(s25,s26,s27,options); + + assertEquals( + "Replacing dcl with saving access modifiers", + expectedResult10, + actualResult + ); + + String s28 = "aaa"; + String s29 = "class 'Class {\n" + + " 'Class('ParameterType 'ParameterName) {\n" + + " 'Class('ParameterName);\n" + + " }\n" + + "}"; + String s30 = "class $Class$ {\n" + + " $Class$($ParameterType$ $ParameterName$) {\n" + + " this($ParameterName$);\n" + + " }\n" + + "}"; + String expectedResult11 = "aaa"; + + actualResult = replacer.testReplace(s28,s29,s30,options); + + assertEquals( + "Complex class replacement", + expectedResult11, + actualResult + ); + + String s31 = "class A {\n" + + " int a; // comment\n" + + " char b;\n" + + " int c; // comment2\n" + + "}"; + + String s32 = "'Type 'Variable = 'Value?; //'Comment"; + String s33 = "/**$Comment$*/\n" + + "$Type$ $Variable$ = $Value$;"; + + String expectedResult12 = " class A {\n" + + " /**\n" + + " * comment\n" + + " */\n" + + " int a;\n" + + " char b;\n" + + " /**\n" + + " * comment2\n" + + " */\n" + + " int c;\n" + + " }"; + options.setToReformatAccordingToStyle(true); + actualResult = replacer.testReplace(s31,s32,s33,options); + options.setToReformatAccordingToStyle(false); + + assertEquals( + "Replacing comments with javadoc for fields", + expectedResult12, + actualResult + ); + + String s34 = "/**\n" + + " * This interface stores XXX\n" + + " * <p/>\n" + + " */\n" + + "public interface X {\n" + + " public static final String HEADER = Headers.HEADER;\n" + + "\n" + + "}"; + + String s35 = "public interface 'MessageInterface {\n" + + " public static final String 'X = 'VALUE;\n" + + " 'blah*" + + "}"; + String s36 = "public interface $MessageInterface$ {\n" + + " public static final String HEADER = $VALUE$;\n" + + " $blah$\n" + + "}"; + + String expectedResult13 = "/**\n" + + " * This interface stores XXX\n" + + " * <p/>\n" + + " */\n" + + "public interface X {\n" + + " public static final String HEADER = Headers.HEADER;\n" + + " \n" + + "}"; + + actualResult = replacer.testReplace(s34,s35,s36,options, true); + + assertEquals( + "Replacing interface with interface, saving comments properly", + expectedResult13, + actualResult + ); + } + + public void testClassReplacement3() { + if (true) return; + final String actualResult; + String s37 = "class A { int a = 1; void B() {} int C(char ch) { int z = 1; } int b = 2; }"; + + String s38 = "class 'A { 'T* 'M*('PT* 'PN*) { 'S*; } 'O* }"; + String s39 = "class $A$ { $T$ $M$($PT$ $PN$) { System.out.println(\"$M$\"); $S$; } $O$ }"; + + String expectedResult14 = "class A { int a = 1; void B( ) { System.out.println(\"B\"); } int C(char ch) { System.out.println(\"C\"); int z = 1; } int b = 2;}"; + String expectedResult14_2 = "class A { int a = 1; void B( ) { System.out.println(\"B\"); } int C(char ch) { System.out.println(\"C\"); int z = 1; } int b = 2;}"; + + actualResult = replacer.testReplace(s37,s38,s39,options, true); + + assertEquals( + "Multiple methods replacement", + expectedResult14, + actualResult + ); + } + + public void testClassReplacement4() { + final String actualResult; + String s1 = "class A {\n" + + " int a = 1;\n" + + " int b;\n" + + " private int c = 2;\n" + + "}"; + + String s2 = "@Modifier(\"PackageLocal\") 'Type 'Instance = 'Init?;"; + String s3 = "public $Type$ $Instance$ = $Init$;"; + + String expectedResult = "class A {\n" + + " public int a = 1;\n" + + " public int b ;\n" + + " private int c = 2;\n" + + "}"; + + actualResult = replacer.testReplace(s1,s2,s3,options, true); + + assertEquals( + "Multiple fields replacement", + expectedResult, + actualResult + ); + } + + public void testClassReplacement5() { + final String actualResult; + String s1 = "public class X {\n" + + " /**\n" + + " * zzz\n" + + " */\n" + + " void f() {\n" + + "\n" + + " }\n" + + "}"; + + String s2 = "class 'c {\n" + + " /**\n" + + " * zzz\n" + + " */\n" + + " void f(){}\n" + + "}"; + String s3 = "class $c$ {\n" + + " /**\n" + + " * ppp\n" + + " */\n" + + " void f(){}\n" + + "}"; + + String expectedResult = "public class X {\n" + + " /**\n" + + " * ppp\n" + + " */\n" + + " void f(){}\n" + + "}"; + + actualResult = replacer.testReplace(s1,s2,s3,options, true); + + assertEquals( + "Not preserving comment if it is present", + expectedResult, + actualResult + ); + } + + public void testClassReplacement6() { + String actualResult; + String s1 = "public class X {\n" + + " /**\n" + + " * zzz\n" + + " */\n" + + " private void f(int i) {\n" + + " //s\n" + + " }\n" + + "}"; + String s1_2 = "public class X {\n" + + " /**\n" + + " * zzz\n" + + " */\n" + + " private void f(int i) {\n" + + " int a = 1;\n" + + " //s\n" + + " }\n" + + "}"; + + String s2 = "class 'c {\n" + + " /**\n" + + " * zzz\n" + + " */\n" + + " void f('t 'p){'s+;}\n" + + "}"; + String s3 = "class $c$ {\n" + + " /**\n" + + " * ppp\n" + + " */\n" + + " void f($t$ $p$){$s$;}\n" + + "}"; + + String expectedResult = "public class X {\n" + + " /**\n" + + " * ppp\n" + + " */\n" + + " private void f(int i ){//s\n" + + "}\n" + + "}"; + + actualResult = replacer.testReplace(s1,s2,s3,options); + + assertEquals( + "Correct class replacement", + expectedResult, + actualResult + ); + + String expectedResult2 = "public class X {\n" + + " /**\n" + + " * ppp\n" + + " */\n" + + " private void f(int i ){int a = 1;\n" + + " //s\n" + + "}\n" + + "}"; + + actualResult = replacer.testReplace(s1_2,s2,s3,options); + + assertEquals( + "Correct class replacement, 2", + expectedResult2, + actualResult + ); + } + + public void testClassReplacement7() { + String s1 = "/**\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 CC {\n" + + " /** My Comment */ int a = 3; // aaa\n" + + " // bbb\n" + + " long c = 2;\n" + + " void f() {\n" + + " }\n" + + "}"; + String s2 = "/**\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" + + " 'other*\n" + + "}"; + String s3 = "/**\n" + + "* by: $USER$\n" + + "*/\n" + + "class $c$ {\n" + + " $other$\n" + + "}"; + String expectedResult = "/**\n" + + "* by: cdr\n" + + "*/\n" + + "public class CC {\n" + + " /** My Comment */ int a = 3; // aaa\n" + + "// bbb\n" + + " long c = 2;\n" + + "void f() {\n" + + " }\n" + + "}"; + + actualResult = replacer.testReplace(s1,s2,s3,options,true); + + assertEquals( + "Class with comment replacement", + expectedResult, + actualResult + ); + } + + public void testClassReplacement8() { + String s1 = "public class CC {\n" + + " /** AAA*/ int b = 1; // comment\n" + + "}"; + String s2 = "int b = 1;"; + String s3 = "long c = 2;"; + String expectedResult = "public class CC {\n" + + " /** AAA*/ long c = 2; // comment\n" + + "}"; + + actualResult = replacer.testReplace(s1,s2,s3,options,true); + + assertEquals( + "Class field replacement with simple pattern", + expectedResult, + actualResult + ); + } + + @NotNull + @Override + protected String getTestDataPath() { + return PlatformTestUtil.getCommunityPath() + "/platform/structuralsearch/testData/"; + } + + public void testClassReplacement9() throws IOException { + String s1 = loadFile("before1.java"); + String s2 = "class 'A extends 'TestCaseCass:[regex( .*TestCase ) ] {\n" + + " 'OtherStatement*;\n" + + " public void 'testMethod*:[regex( test.* )] () {\n" + + " }\n" + + " 'OtherStatement2*;\n" + + "}"; + String s3 = "class $A$ extends $TestCaseCass$ {\n" + + " $OtherStatement$;\n" + + " $OtherStatement2$;\n" + + "}"; + String expectedResult = loadFile("after1.java"); + + options.setToReformatAccordingToStyle(true); + actualResult = replacer.testReplace(s1,s2,s3,options,true); + + assertEquals( + "Class replacement 9", + expectedResult, + actualResult + ); + } + + public void testReplaceReturnWithArrayInitializer() { + String searchIn = "return ( new String[]{CoreVars.CMUAudioPort + \"\"} );"; + String searchFor = "return ( 'A );"; + String replaceBy = "return $A$;"; + String expectedResult = "return new String[]{CoreVars.CMUAudioPort + \"\"};"; + + actualResult = replacer.testReplace(searchIn,searchFor,replaceBy,options); + + assertEquals( + "ReplaceReturnWithArrayInitializer", + expectedResult, + actualResult + ); + } + + public void _testClassReplacement10() throws IOException { + String s1 = loadFile("before2.java"); + String s2 = "class '_Class {\n" + + " '_ReturnType+ '_MethodName+('_ParameterType* '_Parameter*){\n" + + " '_content*;\n" + + " }\n" + + " '_remainingclass*" + + "}"; + String s3 = "class $Class$ {\n" + + " $remainingclass$\n" + + " @Override $ReturnType$ $MethodName$($ParameterType$ $Parameter$){\n" + + " $content$;\n" + + " }\n" + + "}"; + String expectedResult = loadFile("after2.java"); + + options.setToReformatAccordingToStyle(true); + actualResult = replacer.testReplace(s1,s2,s3,options,true); + + assertEquals( + "Class replacement 10", + expectedResult, + actualResult + ); + } + + public void testCatchReplacement() throws Exception { + String s1 = "try {\n" + + " aaa();\n" + + "} catch(Exception ex) {\n" + + " LOG.assertTrue(false);\n" + + "}"; + String s2 = "{ LOG.assertTrue(false); }"; + String s3 = "{ if (false) LOG.assertTrue(false); }"; + String expectedResult = "try {\n" + + " aaa();\n" + + "} catch (Exception ex) {\n" + + " if (false) LOG.assertTrue(false);\n" + + "}"; + options.setToReformatAccordingToStyle(true); + actualResult = replacer.testReplace(s1,s2,s3,options); + options.setToReformatAccordingToStyle(false); + + assertEquals( + "Catch replacement by block", + expectedResult, + actualResult + ); + } + + public void testSavingAccessModifiersDuringClassReplacement() { + String actualResult; + + String s43 = "public @Deprecated class Foo implements Comparable<Foo> {\n int x;\n void m(){}\n }"; + String s44 = "class 'Class implements 'Interface { 'Content* }"; + String s45 = "@MyAnnotation\n" + + "class $Class$ implements $Interface$ {$Content$}"; + String expectedResult16 = "@MyAnnotation public @Deprecated\n" + + "class Foo implements Comparable<Foo> {int x;\n" + + "void m(){}}"; + + actualResult = replacer.testReplace(s43,s44,s45,options, true); + assertEquals( + "Preserving var modifiers and generic information in type during replacement", + expectedResult16, + actualResult + ); + } + + public void testDontRequireSpecialVarsForUnmatchedContent() { + String actualResult; + + String s43 = "public @Deprecated class Foo implements Comparable<Foo> {\n int x;\n void m(){}\n }"; + String s44 = "class 'Class implements 'Interface {}"; + String s45 = "@MyAnnotation\n" + + "class $Class$ implements $Interface$ {}"; + String expectedResult16 = "@MyAnnotation public @Deprecated\n" + + "class Foo implements Comparable<Foo> {int x;\nvoid m(){}}"; + + actualResult = replacer.testReplace(s43,s44,s45,options, true); + assertEquals( + "Preserving class modifiers and generic information in type during replacement", + expectedResult16, + actualResult + ); + } + + public void _testClassReplacement2() { + final String actualResult; + String s40 = "class A {\n" + + " /* special comment*/\n" + + " private List<String> a = new ArrayList();\n" + + " static {\n" + + " int a = 1;" + + " }\n" + + "}"; + String s41 = "class 'Class {\n" + + " 'Stuff2*\n" + + " 'FieldType 'FieldName = 'Init?;\n" + + " static {\n" + + " 'Stmt*;\n" + + " }\n" + + " 'Stuff*\n" + + "}"; + String s42 = "class $Class$ {\n" + + " $Stuff2$\n" + + " $FieldType$ $FieldName$ = build$FieldName$Map();\n" + + " private static $FieldType$ build$FieldName$Map() {\n" + + " $FieldType$ $FieldName$ = $Init$;\n" + + " $Stmt$;\n" + + " return $FieldName$;\n" + + " }\n" + + " $Stuff$\n" + + "}"; + String expectedResult15 = "class A {\n" + + " \n" + + " /* special comment*/\n" + + " private List<String> a = buildaMap();\n" + + " private static List<String> buildaMap() {\n" + + " List<String> a = new ArrayList();\n" + + " int a = 1;\n" + + " return a;\n" + + " }\n" + + " \n" + + "}"; + + actualResult = replacer.testReplace(s40,s41,s42,options, true); + + assertEquals( + "Preserving var modifiers and generic information in type during replacement", + expectedResult15, + actualResult + ); + + String s46 = "class Foo { int xxx; void foo() { assert false; } void yyy() {}}"; + String s47 = "class 'Class { void 'foo:[regex( foo )](); }"; + String s48 = "class $Class$ { void $foo$(int a); }"; + String expectedResult17 = "class Foo { int xxx; void foo(int a) { assert false; } void yyy() {}}"; + + String actualResult2 = replacer.testReplace(s46,s47,s48,options, true); + assertEquals( + "Preserving method bodies", + expectedResult17, + actualResult2 + ); + } + + public void testReplaceExceptions() { + String s1 = "a=a;"; + String s2 = "'a"; + String s3 = "$b$"; + + try { + replacer.testReplace(s1,s2,s3,options); + assertTrue("Undefined replace variable is not checked",false); + } catch(UnsupportedPatternException ex) { + + } + + String s4 = "a=a;"; + String s5 = "a=a;"; + String s6 = "a=a"; + + try { + replacer.testReplace(s4,s5,s6,options); + assertTrue("Undefined no ; in replace",false); + } catch(UnsupportedPatternException ex) { + } + + try { + replacer.testReplace(s4,s6,s5,options); + assertTrue("Undefined no ; in search",false); + } catch(UnsupportedPatternException ex) { + } + } + + public void testActualParameterReplacementInConstructorInvokation() { + String s1 = "filterActions[0] = new Action(TEXT,\n" + + " LifeUtil.getIcon(\"search\")) {\n" + + " void test() {\n" + + " int a = 1;\n" + + " }\n" + + "};"; + String s2 = "LifeUtil.getIcon(\"search\")"; + String s3 = "StdIcons.SEARCH_LIFE"; + String expectedResult = "filterActions[0] = new Action(TEXT,\n" + + " StdIcons.SEARCH_LIFE) {\n" + + " void test() {\n" + + " int a = 1;\n" + + " }\n" + + "};"; + options.setToReformatAccordingToStyle(true); + options.setToShortenFQN(true); + + String actualResult = replacer.testReplace(s1, s2, s3, options); + assertEquals("Replace in anonymous class parameter", expectedResult, actualResult); + options.setToShortenFQN(false); + options.setToReformatAccordingToStyle(false); + } + + public void testRemove() { + String s1 = "class A {\n" + + " /* */\n" + + " void a() {\n" + + " }\n" + + " /*\n" + + " */\n" + + " int b = 1;\n" + + " /*\n" + + " *\n" + + " */\n" + + " class C {}\n" + + " {\n" + + " /* aaa */\n" + + " int a;\n" + + " /* */\n" + + " a = 1;\n" + + " }\n" + + "}"; + String s2 = "/* 'a:[regex( .* )] */"; + String s2_2 = "/* */"; + String s3 = ""; + String expectedResult = "class A {\n" + + " void a() {\n" + + " }\n" + + "\n" + + " int b = 1;\n" + + "\n" + + " class C {\n" + + " }\n" + + "\n" + + " {\n" + + " int a;\n" + + " a = 1;\n" + + " }\n" + + "}"; + options.setToReformatAccordingToStyle(true); + actualResult = replacer.testReplace(s1,s2,s3,options); + options.setToReformatAccordingToStyle(false); + + assertEquals( + "Removing comments", + expectedResult, + actualResult + ); + + String expectedResult2 = "class A {\n" + + " void a() {\n" + + " }\n" + + " /*\n" + + " */\n" + + " int b = 1;\n" + + " /*\n" + + " *\n" + + " */\n" + + " class C {}\n" + + " {\n" + + " /* aaa */\n" + + " int a;\n" + + " a = 1;\n" + + " }\n" + + "}"; + + actualResult = replacer.testReplace(s1,s2_2,s3,options); + + assertEquals( + "Removing comments", + expectedResult2, + actualResult + ); + } + + public void testTryCatchInLoop() throws Exception { + String code = "for (int i = 0; i < MIMEHelper.MIME_MAP.length; i++)\n" + + "{\n" + + " String s = aFileNameWithOutExtention + MIMEHelper.MIME_MAP[i][0][0];\n" + + " try\n" + + " {\n" + + " if (ENABLE_Z107_READING)\n" + + " { in = aFileNameWithOutExtention.getClass().getResourceAsStream(s); }\n" + + " else\n" + + " { data = ResourceHelper.readResource(s); }\n" + + " mime = MIMEHelper.MIME_MAP[i][1][0];\n" + + " break;\n" + + " }\n" + + " catch (final Exception e)\n" + + " { continue; }\n" + + "}"; + String toFind = "try { 'TryStatement*; } catch(Exception 'ExceptionDcl) { 'CatchStatement*; }"; + String replacement = "try { $TryStatement$; }\n" + "catch(Throwable $ExceptionDcl$) { $CatchStatement$; }"; + String expectedResult = "for (int i = 0; i < MIMEHelper.MIME_MAP.length; i++)\n" + + "{\n" + + " String s = aFileNameWithOutExtention + MIMEHelper.MIME_MAP[i][0][0];\n" + + " try { if (ENABLE_Z107_READING)\n" + + " { in = aFileNameWithOutExtention.getClass().getResourceAsStream(s); }\n" + + " else\n" + + " { data = ResourceHelper.readResource(s); }\n" + + " mime = MIMEHelper.MIME_MAP[i][1][0];\n" + + " break; }\n" + + "catch(final Throwable e) { continue; }\n" + + "}"; + + actualResult = replacer.testReplace(code,toFind,replacement,options); + + assertEquals( + "Replacing try/catch in loop", + expectedResult, + actualResult + ); + } + + public void testReformatAndShortenClassRefPerformance() throws IOException { + final String testName = getTestName(false); + final String ext = "java"; + final String message = "Reformat And Shorten Class Ref Performance"; + + options.setToReformatAccordingToStyle(true); + options.setToShortenFQN(true); + + PlatformTestUtil.startPerformanceTest("SSR should work fast", 3500, new ThrowableRunnable() { + public void run() { + doTest(testName, ext, message); + } + } + ).cpuBound().assertTiming(); + + options.setToReformatAccordingToStyle(false); + options.setToShortenFQN(false); + } + + private void doTest(final String testName, final String ext, final String message) { + try { + String source = loadFile(testName + "_source." + ext); + String pattern = loadFile(testName + "_pattern." + ext); + String replacement = loadFile(testName + "_replacement." + ext); + String expected = loadFile(testName + "_result." + ext); + + actualResult = replacer.testReplace(source,pattern,replacement,options); + + assertEquals( + message, + expected, + actualResult + ); + } + catch (IOException e) { + throw new RuntimeException(e); + } + } + + public void testLeastSurprise() { + String s1 = "@Nullable (a=String.class) @String class Test {\n" + + " void aaa(String t) {\n" + + " String a = String.valueOf(' ');" + + " String2 a2 = String2.valueOf(' ');" + + " }\n" + + "}"; + String s2 = "'String:String"; + String s2_2 = "String"; + String s2_3 = "'String:java\\.lang\\.String"; + String s2_4 = "java.lang.String"; + String replacement = CommonClassNames.JAVA_UTIL_LIST; + String expected = "@Nullable (a=java.util.List.class) @java.util.List class Test {\n" + + " void aaa(java.util.List t) {\n" + + " java.util.List a = java.util.List.valueOf(' ');" + + " String2 a2 = String2.valueOf(' ');" + + " }\n" + + "}"; + + actualResult = replacer.testReplace(s1,s2,replacement,options); + + assertEquals( + expected, + actualResult + ); + + actualResult = replacer.testReplace(s1,s2_2,replacement,options); + + assertEquals( + expected, + actualResult + ); + + actualResult = replacer.testReplace(s1,s2_3,replacement,options); + + assertEquals( + expected, + actualResult + ); + + actualResult = replacer.testReplace(s1,s2_4,replacement,options); + + assertEquals( + expected, + actualResult + ); + } + + public void testLeastSurprise2() { + String s1 = "class B { int s(int a) { a = 1; a = 2; c(a); } }"; + String s2 = "a"; + String replacement = "a2"; + String expected = "class B { int s(int a2) { a2 = 1; a2 = 2; c(a2); } }"; + + actualResult = replacer.testReplace(s1,s2,replacement,options); + + assertEquals( + expected, + actualResult + ); + } + + public void testReplaceTry() { + String s1 = "try {\n" + + " em.persist(p);\n" + + " } catch (PersistenceException e) {\n" + + " // good\n" + + " }"; + String s2 = "try { 'TryStatement; } catch('ExceptionType 'ExceptionDcl) { /* 'CommentContent */ }"; + String replacement = "try { $TryStatement$; } catch($ExceptionType$ $ExceptionDcl$) { _logger.warning(\"$CommentContent$\", $ExceptionDcl$); }"; + String expected = "try { em.persist(p); } catch(PersistenceException e) { _logger.warning(\" good\", e); }"; + + actualResult = replacer.testReplace(s1,s2,replacement,options); + + assertEquals( + expected, + actualResult + ); + } + + public void testReplaceExtraSemicolon() { + String s1 = "try {\n" + + " String[] a = {\"a\"};\n" + + " System.out.println(\"blah\");\n" + + "} finally {\n" + + "}\n"; + String s2 = "try {\n" + " 'statement*;\n" + "} finally {\n" + " \n" + "}"; + String replacement = "$statement$;"; + String expected = "String[] a = {\"a\"};\n" + + " System.out.println(\"blah\");\n"; + + actualResult = replacer.testReplace(s1,s2,replacement,options); + + assertEquals( + expected, + actualResult + ); + + String s1_2 = "try {\n" + + " if (args == null) return ;\n" + + " while(true) return ;\n" + + " System.out.println(\"blah2\");\n" + + "} finally {\n" + + "}"; + String expected_2 = "if (args == null) return ;\n" + + " while(true) return ;\n" + + " System.out.println(\"blah2\");"; + + actualResult = replacer.testReplace(s1_2,s2,replacement,options); + + assertEquals( + expected_2, + actualResult + ); + + String s1_3 = "{\n" + + " try {\n" + + " System.out.println(\"blah1\");\n" + + "\n" + + " System.out.println(\"blah2\");\n" + + " } finally {\n" + + " }\n" + + "}"; + String expected_3 = "{\n" + + " System.out.println(\"blah1\");\n" + + "\n" + + " System.out.println(\"blah2\");\n" + + "}"; + actualResult = replacer.testReplace(s1_3,s2,replacement,options); + + assertEquals( + expected_3, + actualResult + ); + + String s1_4 = "{\n" + + " try {\n" + + " System.out.println(\"blah1\");\n" + + " // indented comment\n" + + " System.out.println(\"blah2\");\n" + + " } finally {\n" + + " }\n" + + "}"; + String expected_4 = "{\n" + + " System.out.println(\"blah1\");\n" + + " // indented comment\n" + + " System.out.println(\"blah2\");\n" + + "}"; + actualResult = replacer.testReplace(s1_4,s2,replacement,options); + + assertEquals( + expected_4, + actualResult + ); + } + + public void _testReplaceFinalModifier() throws Exception { + String s1 = "class Foo {\n" + + " void foo(final int i,final int i2, final int i3) {\n" + + " final int x = 5;\n" + + " }\n" + + "}"; + String s2 = "final '_type 'var = '_init?"; + String s3 = "$type$ $var$ = $init$"; + + String expected = "2 = 1;\nint b = a;\nb2 = 3;"; + + actualResult = replacer.testReplace(s1,s2,s3,options); + + assertEquals( + expected, + actualResult + ); + } + + public void testRemovingRedundancy() throws Exception { + String s1 = "int a = 1;\n" + + "a = 2;\n" + + "int b = a;\n" + + "b2 = 3;"; + String s2 = "int 'a = 'i;\n" + + "'st*;\n" + + "'a = 'c;"; + String s3 = "$st$;\n" + + "$c$ = $i$;"; + + String expected = "2 = 1;\nint b = a;\nb2 = 3;"; + + actualResult = replacer.testReplace(s1,s2,s3,options); + + assertEquals( + expected, + actualResult + ); + + String s2_2 = "int 'a = 'i;\n" + + "'st*;\n" + + "int 'c = 'a;"; + String s3_2 = "$st$;\n" + + "int $c$ = $i$;"; + String expected_2 = "a = 2;\nint b = 1;\nb2 = 3;"; + + actualResult = replacer.testReplace(s1,s2_2,s3_2,options); + + assertEquals( + expected_2, + actualResult + ); + } + + public void testReplaceWithEmptyString() { + String source = "public class Peepers {\n public long serialVersionUID = 1L; \n}"; + String search = "long serialVersionUID = $value$;"; + String replace = ""; + String expectedResult = "public class Peepers { \n}"; + + String actualResult = replacer.testReplace(source, search, replace, options, true); + + assertEquals( + expectedResult, + actualResult + ); + } + + public void testReplaceMultipleFieldsInSingleDeclaration() { + String source = "abstract class MyClass implements java.util.List {\n private String a, b;\n}"; + String search = "class 'Name implements java.util.List {\n 'ClassContent*\n}"; + String replace = "class $Name$ {\n $ClassContent$\n}"; + String expectedResult = "abstract class MyClass {\n private String a,b;\n}"; + + String actualResult = replacer.testReplace(source, search, replace, options, true); + + assertEquals( + expectedResult, + actualResult + ); + } + + public void testReplaceInImplementsList() { + String source = "import java.io.Externalizable;\n" + + "import java.io.Serializable;\n" + + "abstract class MyClass implements Serializable, java.util.List, Externalizable {}"; + String search = "class 'TestCase implements java.util.List, 'others* {\n 'MyClassContent\n}"; + String replace = "class $TestCase$ implements $others$ {\n $MyClassContent$\n}"; + String expectedResult = "import java.io.Externalizable;\n" + + "import java.io.Serializable;\n" + + "abstract class MyClass implements Externalizable,Serializable {\n \n}"; + + String actualResult = replacer.testReplace(source, search, replace, options, true); + assertEquals( + expectedResult, + actualResult + ); + } + + public void testReplaceFieldWithEndOfLineComment() { + String source = "class MyClass {\n" + + " private String b;// comment\n" + + " public void foo() {\n" + + " }\n" + + "}"; + String search = "class 'Class {\n 'Content*\n}"; + String replace = "class $Class$ {\n" + + " void x() {}\n" + + " $Content$\n" + + " void bar() {}\n" + + "}"; + String expectedResult = "class MyClass {\n" + + " void x() {}\n" + + " private String b;// comment\n" + + "public void foo() {\n" + + " }\n" + + " void bar() {}\n" + + "}"; + + String actualResult = replacer.testReplace(source, search, replace, options, true); + assertEquals( + expectedResult, + actualResult + ); + } +}
\ No newline at end of file diff --git a/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralReplaceTestCase.java b/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralReplaceTestCase.java new file mode 100644 index 000000000000..9a9fbb362a63 --- /dev/null +++ b/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralReplaceTestCase.java @@ -0,0 +1,42 @@ +package com.intellij.structuralsearch; + +import com.intellij.codeInsight.daemon.quickFix.LightQuickFixTestCase; +import com.intellij.openapi.roots.LanguageLevelProjectExtension; +import com.intellij.openapi.util.io.FileUtilRt; +import com.intellij.openapi.vfs.CharsetToolkit; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.structuralsearch.plugin.replace.ReplaceOptions; +import com.intellij.structuralsearch.plugin.replace.impl.Replacer; + +import java.io.File; +import java.io.IOException; + +/** + * Created by IntelliJ IDEA. + * User: maxim.mossienko + * Date: Oct 11, 2005 + * Time: 10:10:48 PM + * To change this template use File | Settings | File Templates. + */ +abstract class StructuralReplaceTestCase extends LightQuickFixTestCase { + protected Replacer replacer; + protected ReplaceOptions options; + protected String actualResult; + + @Override + protected void setUp() throws Exception { + super.setUp(); + + StructuralSearchUtil.ourUseUniversalMatchingAlgorithm = false; + + LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(LanguageLevel.JDK_1_4); + + options = new ReplaceOptions(); + options.setMatchOptions(new MatchOptions()); + replacer = new Replacer(getProject(), null); + } + + protected String loadFile(String fileName) throws IOException { + return FileUtilRt.loadFile(new File(getTestDataPath() + FileUtilRt.getExtension(fileName) + "/" + fileName), CharsetToolkit.UTF8, true); + } +} diff --git a/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralSearchTest.java b/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralSearchTest.java new file mode 100644 index 000000000000..da479a70f93c --- /dev/null +++ b/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralSearchTest.java @@ -0,0 +1,2946 @@ +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)); + } +} diff --git a/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralSearchTestCase.java b/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralSearchTestCase.java new file mode 100644 index 000000000000..6b8aceaba590 --- /dev/null +++ b/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralSearchTestCase.java @@ -0,0 +1,98 @@ +package com.intellij.structuralsearch; + +import com.intellij.codeInsight.daemon.quickFix.LightQuickFixTestCase; +import com.intellij.lang.Language; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.roots.LanguageLevelProjectExtension; +import com.intellij.openapi.util.io.FileUtilRt; +import com.intellij.openapi.vfs.CharsetToolkit; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.structuralsearch.impl.matcher.MatcherImpl; +import com.intellij.structuralsearch.impl.matcher.MatcherImplUtil; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +abstract class StructuralSearchTestCase extends LightQuickFixTestCase { + protected MatchOptions options; + protected Matcher testMatcher; + + @Override + protected void setUp() throws Exception { + super.setUp(); + + StructuralSearchUtil.ourUseUniversalMatchingAlgorithm = false; + testMatcher = new Matcher(getProject()); + options = new MatchOptions(); + options.setLooseMatching(true); + options.setRecursiveSearch(true); + LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(LanguageLevel.JDK_1_5); + } + + @Override + protected void tearDown() throws Exception { + testMatcher = null; + options = null; + super.tearDown(); + } + + protected int findMatchesCount(String in, String pattern, boolean filePattern, FileType fileType) { + return findMatches(in,pattern,filePattern, fileType).size(); + } + + protected List<MatchResult> findMatches(String in, + String pattern, + boolean filePattern, + FileType patternFileType, + Language patternLanugage, + FileType sourceFileType, + String sourceExtension, + boolean physicalSourceFile) { + return findMatches(in, pattern, filePattern, patternFileType, patternLanugage, sourceFileType, sourceExtension, physicalSourceFile, + true); + } + + protected List<MatchResult> findMatches(String in, + String pattern, + boolean filePattern, + FileType patternFileType, + Language patternLanugage, + FileType sourceFileType, + String sourceExtension, + boolean physicalSourceFile, + boolean transform) { + options.clearVariableConstraints(); + options.setSearchPattern(pattern); + if (transform) { + MatcherImplUtil.transform(options); + } + pattern = options.getSearchPattern(); + options.setFileType(patternFileType); + options.setDialect(patternLanugage); + + MatcherImpl.validate(getProject(), options); + return testMatcher.testFindMatches(in, pattern, options, filePattern, sourceFileType, sourceExtension, physicalSourceFile); + } + + protected List<MatchResult> findMatches(String in, String pattern, boolean filePattern, FileType patternFileType) { + return findMatches(in, pattern, filePattern, patternFileType, null, patternFileType, null, false); + } + + protected int findMatchesCount(String in, String pattern, boolean filePattern) { + return findMatchesCount(in, pattern,filePattern, StdFileTypes.JAVA); + } + + protected int findMatchesCount(String in, String pattern) { + return findMatchesCount(in,pattern,false); + } + + protected List<MatchResult> findMatches(String in, String pattern) { + return findMatches(in,pattern,false, StdFileTypes.JAVA); + } + + protected String loadFile(String fileName) throws IOException { + return FileUtilRt.loadFile(new File(getTestDataPath() + fileName), CharsetToolkit.UTF8, true); + } +} diff --git a/platform/structuralsearch/testSource/com/intellij/structuralsearch/impl/matcher/compiler/StringToConstraintsTransformerTest.java b/platform/structuralsearch/testSource/com/intellij/structuralsearch/impl/matcher/compiler/StringToConstraintsTransformerTest.java new file mode 100644 index 000000000000..dc1cbc5802f2 --- /dev/null +++ b/platform/structuralsearch/testSource/com/intellij/structuralsearch/impl/matcher/compiler/StringToConstraintsTransformerTest.java @@ -0,0 +1,128 @@ +package com.intellij.structuralsearch.impl.matcher.compiler; + +import com.intellij.structuralsearch.MalformedPatternException; +import com.intellij.structuralsearch.MatchOptions; +import com.intellij.structuralsearch.MatchVariableConstraint; +import com.intellij.structuralsearch.UnsupportedPatternException; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * @author Bas Leijdekkers + */ +public class StringToConstraintsTransformerTest { + + private MatchOptions myOptions; + + @Before + public void setUp() throws Exception { + myOptions = new MatchOptions(); + } + + @Test(expected = MalformedPatternException.class) + public void testCharacterExpectedAfterQuote() { + test("' asdf"); + } + + @Test(expected = MalformedPatternException.class) + public void testUnexpectedEndOfPattern() { + test("'_a{"); + } + + @Test(expected = MalformedPatternException.class) + public void testDigitExpected() { + test("'a{a"); + } + + @Test(expected = MalformedPatternException.class) + public void testDigitExpected2() { + test("'a{1,a}"); + } + + @Test + public void testZeroOccurs() { + test("'a{,}"); + final MatchVariableConstraint constraint = myOptions.getVariableConstraint("a"); + assertEquals(0, constraint.getMinCount()); + assertEquals(0, constraint.getMaxCount()); + } + + @Test(expected = MalformedPatternException.class) + public void testOverflow() { + test("'a{2147483648}"); + } + + @Test(expected = MalformedPatternException.class) + public void testMissingBrace() { + test("'a{1,3"); + } + + @Test(expected = MalformedPatternException.class) + public void testNoOptions() { + test("'a:"); + } + + @Test + public void testColon() { + test("for('_t 'a : '_b) {}"); + assertEquals("for($t$ $a$ : $b$) {}", myOptions.getSearchPattern()); + } + + @Test(expected = MalformedPatternException.class) + public void testNoOptions2() { + test("'a:+"); + } + + @Test(expected = MalformedPatternException.class) + public void testUnclosedCondition() { + test("'a:["); + } + + @Test(expected = MalformedPatternException.class) + public void testClosedCondition() { + test("'a:[]"); + } + + @Test(expected = MalformedPatternException.class) + public void testEmptyNegated() { + test("'a:[!]"); + } + + @Test(expected = UnsupportedPatternException.class) + public void testCondition() { + test("'a:[aap()]"); + } + + @Test(expected = UnsupportedPatternException.class) + public void testIncompleteCondition() { + test("'a:[regex(]"); + } + + @Test(expected = MalformedPatternException.class) + public void testIncompleteCondition2() { + test("'a:[regex()]"); + } + + @Test(expected = MalformedPatternException.class) + public void testIncompleteMultipleCondition() { + test("'a:[regex( a ) &&]"); + } + + @Test(expected = MalformedPatternException.class) + public void testInvalidRegularExpression() { + test("'a:x!("); + } + + @Test + public void testMethodReference() { + test("'_a::'_b"); + assertEquals("$a$::$b$", myOptions.getSearchPattern()); + } + + private void test(String pattern) { + myOptions.setSearchPattern(pattern); + StringToConstraintsTransformer.transformOldPattern(myOptions); + } +} |