SSR: javadoc matching fix and tests
[idea/community.git] / platform / structuralsearch / testSource / com / intellij / structuralsearch / StructuralReplaceTest.java
1 /*
2  * Copyright 2000-2016 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.structuralsearch;
17
18 import com.intellij.openapi.fileTypes.StdFileTypes;
19 import com.intellij.psi.CommonClassNames;
20 import com.intellij.testFramework.PlatformTestUtil;
21 import com.intellij.util.ThrowableRunnable;
22 import org.jetbrains.annotations.NotNull;
23
24 import java.io.IOException;
25
26 /**
27  * @by Maxim.Mossienko
28  */
29 @SuppressWarnings({"ALL"})
30 public class StructuralReplaceTest extends StructuralReplaceTestCase {
31
32   @Override
33   protected void setUp() throws Exception {
34     super.setUp();
35     final MatchOptions matchOptions = this.options.getMatchOptions();
36     matchOptions.setFileType(StdFileTypes.JAVA);
37     matchOptions.setLooseMatching(true);
38   }
39
40   public void testReplaceInLiterals() {
41     String s1 = "String ID_SPEED = \"Speed\";";
42     String s2 = "String 'name = \"'_string\";";
43     String s2_2 = "String 'name = \"'_string:[regex( .* )]\";";
44     String s3 = "VSegAttribute $name$ = new VSegAttribute(\"$string$\");";
45     String expectedResult = "VSegAttribute ID_SPEED = new VSegAttribute(\"Speed\");";
46
47     assertEquals(
48       "Matching/replacing literals",
49       expectedResult,
50       replacer.testReplace(s1,s2,s3,options)
51     );
52
53     assertEquals(
54       "Matching/replacing literals",
55       expectedResult,
56       replacer.testReplace(s1,s2_2,s3,options)
57     );
58
59     String s4 = "params.put(\"BACKGROUND\", \"#7B528D\");";
60     String s5 = "params.put(\"$FieldName$\", \"#$exp$\");";
61     String s6 = "String $FieldName$ = \"$FieldName$\";\n" +
62                 "params.put($FieldName$, \"$exp$\");";
63     String expectedResult2 = "String BACKGROUND = \"BACKGROUND\";\n" +
64                              "params.put(BACKGROUND, \"7B528D\");";
65
66     assertEquals(
67       "string literal replacement 2",
68       expectedResult2,
69       replacer.testReplace(s4,s5,s6,options)
70     );
71
72     String s7 = "IconLoader.getIcon(\"/ant/property.png\");\n" +
73                 "IconLoader.getIcon(\"/ant/another/property.png\");\n";
74     String s8 = "IconLoader.getIcon(\"/'_module/'_name:[regex( \\w+ )].png\");";
75     String s9 = "Icons.$module$.$name$;";
76     String expectedResult3 = "Icons.ant.property;\n" +
77                              "IconLoader.getIcon(\"/ant/another/property.png\");\n";
78
79     assertEquals(
80       "string literal replacement 3",
81       expectedResult3,
82       replacer.testReplace(s7,s8,s9,options)
83     );
84
85     String s10 = "configureByFile(path + \"1.html\");\n" +
86                  "    checkResultByFile(path + \"1_after.html\");\n" +
87                  "    checkResultByFile(path + \"1_after2.html\");\n" +
88                  "    checkResultByFile(path + \"1_after3.html\");";
89     String s11 = "\"'a.html\"";
90     String s12 = "\"$a$.\"+ext";
91     String expectedResult4 = "configureByFile(path + \"1.\"+ext);\n" +
92                              "    checkResultByFile(path + \"1_after.\"+ext);\n" +
93                              "    checkResultByFile(path + \"1_after2.\"+ext);\n" +
94                              "    checkResultByFile(path + \"1_after3.\"+ext);";
95
96     assertEquals(
97       "string literal replacement 4",
98       expectedResult4,
99       replacer.testReplace(s10,s11,s12,options)
100     );
101   }
102
103   public void testReplace2() {
104     String s1 = "package com.www.xxx.yyy;\n" +
105                 "\n" +
106                 "import javax.swing.*;\n" +
107                 "\n" +
108                 "public class Test {\n" +
109                 "  public static void main(String[] args) {\n" +
110                 "    if (1==1)\n" +
111                 "      JOptionPane.showMessageDialog(null, \"MESSAGE\");\n" +
112                 "  }\n" +
113                 "}";
114     String s2 = "JOptionPane.'showDialog(null, '_msg);";
115     String s3 = "//FIXME provide a parent frame\n" +
116                 "JOptionPane.$showDialog$(null, $msg$);";
117
118     String expectedResult = "package com.www.xxx.yyy;\n" +
119                             "\n" +
120                             "import javax.swing.*;\n" +
121                             "\n" +
122                             "public class Test {\n" +
123                             "  public static void main(String[] args) {\n" +
124                             "    if (1==1)\n" +
125                             "      //FIXME provide a parent frame\n" +
126                             "JOptionPane.showMessageDialog(null, \"MESSAGE\");\n" +
127                             "  }\n" +
128                             "}";
129
130     assertEquals(
131       "adding comment to statement inside the if body",
132       expectedResult,
133       replacer.testReplace(s1,s2,s3,options)
134     );
135
136     String s4 = "myButton.setText(\"Ok\");";
137     String s5 = "'_Instance.'_MethodCall:[regex( setText )]('_Parameter*:[regex( \"Ok\" )]);";
138     String s6 = "$Instance$.$MethodCall$(\"OK\");";
139
140     String expectedResult2 = "myButton.setText(\"OK\");";
141
142     assertEquals(
143       "adding comment to statement inside the if body",
144       expectedResult2,
145       replacer.testReplace(s4,s5,s6,options)
146     );
147   }
148
149   public void testReplace() {
150     String str = "// searching for several constructions\n" +
151                  "    lastTest = \"several constructions match\";\n" +
152                  "    matches = testMatcher.findMatches(s5,s4, options);\n" +
153                  "    if (matches==null || matches.size()!=3) return false;\n" +
154                  "\n" +
155                  "    // searching for several constructions\n" +
156                  "    lastTest = \"several constructions 2\";\n" +
157                  "    matches = testMatcher.findMatches(s5,s6, options);\n" +
158                  "    if (matches.size()!=0) return false;\n" +
159                  "\n" +
160                  "    //options.setLooseMatching(true);\n" +
161                  "    // searching for several constructions\n" +
162                  "    lastTest = \"several constructions 3\";\n" +
163                  "    matches = testMatcher.findMatches(s7,s8, options);\n" +
164                  "    if (matches.size()!=2) return false;";
165
166     String str2="      lastTest = '_Descr;\n" +
167                 "      matches = testMatcher.findMatches('_In,'_Pattern, options);\n" +
168                 "      if (matches.size()!='_Number) return false;";
169     String str3 = "assertEquals($Descr$,testMatcher.findMatches($In$,$Pattern$, options).size(),$Number$);";
170     String expectedResult1 = "// searching for several constructions\n" +
171                              "    lastTest = \"several constructions match\";\n" +
172                              "    matches = testMatcher.findMatches(s5, s4, options);\n" +
173                              "    if (matches == null || matches.size() != 3) return false;\n" +
174                              "\n" +
175                              "    // searching for several constructions\n" +
176                              "    assertEquals(\"several constructions 2\", testMatcher.findMatches(s5, s6, options).size(), 0);\n" +
177                              "\n" +
178                              "    //options.setLooseMatching(true);\n" +
179                              "    // searching for several constructions\n" +
180                              "    assertEquals(\"several constructions 3\", testMatcher.findMatches(s7, s8, options).size(), 2);";
181
182     String str4 = "";
183
184     options.setToReformatAccordingToStyle(true);
185     assertEquals("Basic replacement with formatter", expectedResult1, replacer.testReplace(str,str2,str3,options));
186     options.setToReformatAccordingToStyle(false);
187
188     String expectedResult2 = "// searching for several constructions\n" +
189                              "    lastTest = \"several constructions match\";\n" +
190                              "    matches = testMatcher.findMatches(s5,s4, options);\n" +
191                              "    if (matches==null || matches.size()!=3) return false;\n" +
192                              "\n" +
193                              "    // searching for several constructions\n" +
194                              "\n" +
195                              "    //options.setLooseMatching(true);\n" +
196                              "    // searching for several constructions";
197     assertEquals("Empty replacement", expectedResult2, replacer.testReplace(str,str2,str4,options));
198
199     String str5 = "testMatcher.findMatches('_In,'_Pattern, options).size()";
200     String str6 = "findMatchesCount($In$,$Pattern$)";
201     String expectedResult3="// searching for several constructions\n" +
202                            "    lastTest = \"several constructions match\";\n" +
203                            "    matches = testMatcher.findMatches(s5, s4, options);\n" +
204                            "    if (matches == null || matches.size() != 3) return false;\n" +
205                            "\n" +
206                            "    // searching for several constructions\n" +
207                            "    assertEquals(\"several constructions 2\", findMatchesCount(s5,s6), 0);\n" +
208                            "\n" +
209                            "    //options.setLooseMatching(true);\n" +
210                            "    // searching for several constructions\n" +
211                            "    assertEquals(\"several constructions 3\", findMatchesCount(s7,s8), 2);";
212     assertEquals("Expression replacement", expectedResult3, replacer.testReplace(expectedResult1,str5,str6,options));
213
214     String str7 = "try { a.doSomething(); b.doSomething(); } catch(IOException ex) {  ex.printStackTrace(); throw new RuntimeException(ex); }";
215     String str8 = "try { 'Statements+; } catch('_ '_) { 'HandlerStatements+; }";
216     String str9 = "$Statements$;";
217     String expectedResult4 = "a.doSomething(); b.doSomething();";
218
219     assertEquals("Multi line match in replacement", expectedResult4, replacer.testReplace(str7,str8,str9,options));
220
221     String str10 = "    parentNode.insert(compositeNode, i);\n" +
222                    "    if (asyncMode) {\n" +
223                    "       myTreeModel.nodesWereInserted(parentNode,new int[] {i} );\n" +
224                    "    }";
225     String str11 = "    '_parentNode.insert('_newNode, '_i);\n" +
226                    "    if (asyncMode) {\n" +
227                    "       myTreeModel.nodesWereInserted('_parentNode,new int[] {'_i} );\n" +
228                    "    }";
229     String str12 = "addChild($parentNode$,$newNode$, $i$);";
230     String expectedResult5 = "    addChild(parentNode,compositeNode, i);";
231
232     assertEquals("Array initializer replacement", expectedResult5, replacer.testReplace(str10,str11,str12,options));
233
234     String str13 = "  aaa(5,6,3,4,1,2);";
235     String str14 = "aaa('_t{2,2},3,4,'_q{2,2});";
236     String str15 = "aaa($q$,3,4,$t$);";
237     String expectedResult6 = "  aaa(1,2,3,4,5,6);";
238
239     assertEquals("Parameter multiple match", expectedResult6, replacer.testReplace(str13,str14,str15,options));
240
241     String str16 = "  int c = a();";
242     String str17 = "'_t:a ('_q*,'_p*)";
243     String str18 = "$t$($q$,1,$p$)";
244     String expectedResult7 = "  int c = a(1);";
245
246     assertEquals("Replacement of init in definition + empty substitution", expectedResult7, replacer.testReplace(str16,str17,str18,options));
247
248     String str19 = "  aaa(bbb);";
249     String str20 = "'t('_);";
250     String str21 = "$t$(ccc);";
251     String expectedResult8 = "  aaa(ccc);";
252
253     assertEquals("One substition replacement", expectedResult8, replacer.testReplace(str19,str20,str21,options));
254
255     String str22 = "  instance.setAAA(anotherInstance.getBBB());";
256     String str23 = "  '_i.'_m:set(.+) ('_a.'_m2:get(.+) ());";
257     String str24 = "  $a$.set$m2_1$( $i$.get$m_1$() );";
258     String expectedResult9 = "  anotherInstance.setBBB( instance.getAAA() );";
259
260     assertEquals("Reg exp substitution replacement", expectedResult9, replacer.testReplace(str22,str23,str24,options));
261
262     String str25 = "  LaterInvocator.invokeLater(new Runnable() {\n" +
263                    "          public void run() {\n" +
264                    "            LOG.info(\"refreshFilesAsync, modalityState=\" + ModalityState.current());\n" +
265                    "            myHandler.getFiles().refreshFilesAsync(new Runnable() {\n" +
266                    "              public void run() {\n" +
267                    "                semaphore.up();\n" +
268                    "              }\n" +
269                    "            });\n" +
270                    "          }\n" +
271                    "        });";
272     String str26 = "  LaterInvocator.invokeLater('Params{1,10});";
273     String str27 = "  com.intellij.openapi.application.ApplicationManager.getApplication().invokeLater($Params$);";
274     String expectedResult10 = "  com.intellij.openapi.application.ApplicationManager.getApplication().invokeLater(new Runnable() {\n" +
275                               "          public void run() {\n" +
276                               "            LOG.info(\"refreshFilesAsync, modalityState=\" + ModalityState.current());\n" +
277                               "            myHandler.getFiles().refreshFilesAsync(new Runnable() {\n" +
278                               "              public void run() {\n" +
279                               "                semaphore.up();\n" +
280                               "              }\n" +
281                               "            });\n" +
282                               "          }\n" +
283                               "        });";
284
285     assertEquals("Anonymous in parameter", expectedResult10, replacer.testReplace(str25,str26,str27,options));
286
287     String str28 = "UTElementNode elementNode = new UTElementNode(myProject, processedElement, psiFile,\n" +
288                    "                                                          processedElement.getTextOffset(), true,\n" +
289                    "                                                          !myUsageViewDescriptor.toMarkInvalidOrReadonlyUsages(), null);";
290     String str29 = "new UTElementNode('_param, '_directory, '_null, '_0, '_true, !'_descr.toMarkInvalidOrReadonlyUsages(),\n" +
291                    "  'referencesWord)";
292     String str30 = "new UTElementNode($param$, $directory$, $null$, $0$, $true$, true,\n" +
293                    "  $referencesWord$)";
294
295     String expectedResult11 = "UTElementNode elementNode = new UTElementNode(myProject, processedElement, psiFile, processedElement.getTextOffset(), true, true,\n" +
296                               "  null);";
297     assertEquals("Replace in def initializer", expectedResult11, replacer.testReplace(str28,str29,str30,options));
298
299     String s31 = "a = b; b = c; a=a; c=c;";
300     String s32 = "'a = 'a;";
301     String s33 = "1 = 1;";
302     String expectedResult12 = "a = b; b = c; 1 = 1; 1 = 1;";
303
304     assertEquals("replace silly assignments", expectedResult12, replacer.testReplace(s31,s32,s33,options));
305
306     String s34 = "ParamChecker.isTrue(1==1, \"!!!\");";
307     String s35 = "ParamChecker.isTrue('_expr, '_msg);";
308     String s36 = "assert $expr$ : $msg$;";
309
310     String expectedResult13 = "assert 1==1 : \"!!!\";";
311     assertEquals("replace with assert", expectedResult13, replacer.testReplace(s34,s35,s36,options));
312
313     String s37 = "try { \n" +
314                  "  ParamChecker.isTrue(1==1, \"!!!\");\n  \n" +
315                  "  // comment we want to leave\n  \n" +
316                  "  ParamChecker.isTrue(2==2, \"!!!\");\n" +
317                  "} catch(Exception ex) {}";
318     String s38 = "try {\n" +
319                  "  'Statement{0,100};\n" +
320                  "} catch(Exception ex) {}";
321     String s39 = "$Statement$;";
322
323     String expectedResult14 = "ParamChecker.isTrue(1==1, \"!!!\");\n  \n" +
324                               "  // comment we want to leave\n  \n" +
325                               "  ParamChecker.isTrue(2==2, \"!!!\");";
326     assertEquals("remove try with comments inside", expectedResult14, replacer.testReplace(s37,s38,s39,options));
327
328     String s40 = "ParamChecker.instanceOf(queryKey, GroupBySqlTypePolicy.GroupKey.class);";
329     String s41 = "ParamChecker.instanceOf('_obj, '_class.class);";
330     String s42 = "assert $obj$ instanceof $class$ : \"$obj$ is an instance of \" + $obj$.getClass() + \"; expected \" + $class$.class;";
331     String expectedResult15 = "assert queryKey instanceof GroupBySqlTypePolicy.GroupKey : \"queryKey is an instance of \" + queryKey.getClass() + \"; expected \" + GroupBySqlTypePolicy.GroupKey.class;";
332
333     assertEquals("Matching/replacing .class literals", expectedResult15, replacer.testReplace(s40,s41,s42,options));
334
335     String s43 = "class Wpd {\n" +
336                  "  static final String TAG_BEAN_VALUE = \"\";\n" +
337                  "}\n" +
338                  "XmlTag beanTag = rootTag.findSubTag(Wpd.TAG_BEAN_VALUE);";
339     String s44 = "'_Instance?.findSubTag( '_Parameter:[exprtype( *String ) ])";
340     String s45 = "jetbrains.fabrique.util.XmlApiUtil.findSubTag($Instance$, $Parameter$)";
341     String expectedResult16 = "class Wpd {\n" +
342                               "  static final String TAG_BEAN_VALUE = \"\";\n" +
343                               "}\n" +
344                               "XmlTag beanTag = jetbrains.fabrique.util.XmlApiUtil.findSubTag(rootTag, Wpd.TAG_BEAN_VALUE);";
345
346     assertEquals("Matching/replacing static fields", expectedResult16, replacer.testReplace(s43,s44,s45,options));
347
348     String s46 = "Rectangle2D rec = new Rectangle2D.Double(\n" +
349                  "                drec.getX(),\n" +
350                  "                drec.getY(),\n" +
351                  "                drec.getWidth(),\n" +
352                  "                drec.getWidth());";
353     String s47 = "$Instance$.$MethodCall$()";
354     String s48 = "OtherClass.round($Instance$.$MethodCall$(),5)";
355     String expectedResult17 = "Rectangle2D rec = new Rectangle2D.Double(\n" +
356                               "                OtherClass.round(drec.getX(),5),\n" +
357                               "                OtherClass.round(drec.getY(),5),\n" +
358                               "                OtherClass.round(drec.getWidth(),5),\n" +
359                               "                OtherClass.round(drec.getWidth(),5));";
360     assertEquals("Replace in constructor", expectedResult17, replacer.testReplace(s46,s47,s48,options));
361
362     String s49 = "class A {}\n" +
363                  "class B extends A {}\n" +
364                  "A a = new B();";
365     String s50 = "A '_b = new '_B:*A ();";
366     String s51 = "A $b$ = new $B$(\"$b$\");";
367     String expectedResult18 = "class A {}\n" +
368                               "class B extends A {}\n" +
369                               "A a = new B(\"a\");";
370
371     assertEquals("Class navigation", expectedResult18, replacer.testReplace(s49,s50,s51,options));
372
373     String s52 = "try {\n" +
374                  "  aaa();\n" +
375                  "} finally {\n" +
376                  "  System.out.println();" +
377                  "}\n" +
378                  "try {\n" +
379                  "  aaa2();\n" +
380                  "} catch(Exception ex) {\n" +
381                  "  aaa3();\n" +
382                  "}\n" +
383                  "finally {\n" +
384                  "  System.out.println();\n" +
385                  "}\n" +
386                  "try {\n" +
387                  "  aaa4();\n" +
388                  "} catch(Exception ex) {\n" +
389                  "  aaa5();\n" +
390                  "}\n";
391     String s53 = "try { '_a; } finally {\n" +
392                  "  '_b;" +
393                  "}";
394     String s54 = "$a$;";
395     String expectedResult19 = "aaa();\n" +
396                               "try {\n" +
397                               "  aaa2();\n" +
398                               "} catch(Exception ex) {\n" +
399                               "  aaa3();\n" +
400                               "}\n" +
401                               "finally {\n" +
402                               "  System.out.println();\n" +
403                               "}\n" +
404                               "try {\n" +
405                               "  aaa4();\n" +
406                               "} catch(Exception ex) {\n" +
407                               "  aaa5();\n" +
408                               "}\n";
409
410     options.getMatchOptions().setLooseMatching(false);
411     try {
412       assertEquals("Try/finally unwrapped with strict matching", expectedResult19, replacer.testReplace(s52, s53, s54, options));
413     } finally {
414       options.getMatchOptions().setLooseMatching(true);
415     }
416
417     String expectedResult19Loose = "aaa();\n" +
418                                    "aaa2();\n" +
419                                    "try {\n" +
420                                    "  aaa4();\n" +
421                                    "} catch(Exception ex) {\n" +
422                                    "  aaa5();\n" +
423                                    "}\n";
424     assertEquals("Try/finally unwrapped with loose matching", expectedResult19Loose, replacer.testReplace(s52, s53, s54, options));
425
426
427     String s55 = "for(Iterator<String> iterator = stringlist.iterator(); iterator.hasNext();) {\n" +
428                  "      String str = iterator.next();\n" +
429                  "      System.out.println( str );\n" +
430                  "}";
431     String s56 = "for (Iterator<$Type$> $variable$ = $container$.iterator(); $variable$.hasNext();) {\n" +
432                  "    $Type$ $var$ = $variable$.next();\n" +
433                  "    $Statements$;\n" +
434                  "}";
435     String s57 = "for($Type$ $var$:$container$) {\n" +
436                  "  $Statements$;\n" +
437                  "}";
438     String expectedResult20 = "for(String str:stringlist) {\n" +
439                               "  System.out.println( str );\n" +
440                               "}";
441
442     assertEquals("for with foreach", expectedResult20, replacer.testReplace(s55,s56,s57,options));
443
444     String s58 = "class A {\n" +
445                  "  static Set<String> b_MAP = new HashSet<String>();\n" +
446                  "  int c;\n" +
447                  "}";
448     String s59 = "'a:[ regex( (.*)_MAP ) ]";
449     String s60 = "$a_1$_SET";
450     String expectedResult21 = "class A {\n" +
451                               "  static Set<String> b_SET = new HashSet<String>();\n" +
452                               "  int c;\n" +
453                               "}";
454
455     assertEquals("replace symbol in definition", expectedResult21, replacer.testReplace(s58,s59,s60,options));
456
457     String s64 = "int x = 42;\n" +
458                  "int y = 42; // Stuff";
459     String s65 = "'_Type '_Variable = '_Value; // '_Comment";
460     String s66 = "/**\n" +
461                  " *$Comment$\n" +
462                  " */\n" +
463                  "$Type$ $Variable$ = $Value$;";
464     String expectedResult23 = "int x = 42;\n" +
465                               "/**\n" +
466                               " * Stuff\n" +
467                               " */\n" +
468                               "int y = 42;";
469
470     assertEquals("Replacement of the comment with javadoc", expectedResult23, replacer.testReplace(s64,s65,s66,options));
471
472     String s61 = "try { 1=1; } catch(Exception e) { 1=1; } catch(Throwable t) { 2=2; }";
473     String s62 = "try { '_a; } catch(Exception e) { '_b; }";
474     String s63 = "try { $a$; } catch(Exception1 e) { $b$; } catch(Exception2 e) { $b$; }";
475     String expectedResult22 = "try { 1=1; } catch(Exception1 e) { 1=1; } catch(Exception2 e) { 1=1; } catch(Throwable t) { 2=2; }";
476
477     assertEquals("try replacement by another try will leave the unmatched catch",
478                  expectedResult22,
479                  replacer.testReplace(s61,s62,s63,options));
480
481   }
482
483   public void testReplaceExpr() {
484     String s1 = "new SimpleDateFormat(\"yyyyMMddHHmmss\")";
485     String s2 = "'expr";
486     String s3 = "new AtomicReference<DateFormat>($expr$)";
487     String expectedResult = "new AtomicReference<DateFormat>(new SimpleDateFormat(\"yyyyMMddHHmmss\"))";
488
489     assertEquals("Replacement of top-level expression only", expectedResult, replacer.testReplace(s1, s2, s3, options));
490
491     String s4 = "get(\"smth\")";
492     String s5 = "'expr";
493     String s6 = "new Integer($expr$)";
494     String expectedResult1 = "new Integer(get(\"smth\"))";
495
496     assertEquals("Replacement of top-level expression only", expectedResult1, replacer.testReplace(s4, s5, s6, options));
497   }
498
499   public void testReplaceParameter() {
500     String s1 = "class A { void b(int c, int d, int e) {} }";
501     String s2 = "int d;";
502     String s3 = "int d2;";
503     String expectedResult = "class A { void b(int c, int d2, int e) {} }";
504
505     assertEquals("replace method parameter", expectedResult, replacer.testReplace(s1,s2,s3,options));
506   }
507
508   public void testReplaceWithComments() {
509     String s1 = "map.put(key, value); // line 1";
510     String s2 = "map.put(key, value); // line 1";
511     String s3 = "map.put(key, value); // line 1";
512     String expectedResult = "map.put(key, value); // line 1";
513
514     assertEquals("replace self with comment after", expectedResult, replacer.testReplace(s1,s2,s3,options));
515
516     String s4 = "if (true) System.out.println(\"1111\"); else System.out.println(\"2222\");\n" +
517                 "while(true) System.out.println(\"1111\");";
518     String s5 = "System.out.println('Test);";
519     String s6 = "/* System.out.println($Test$); */";
520     String expectedResult2 = "if (true) /* System.out.println(\"1111\"); */; else /* System.out.println(\"2222\"); */;\n" +
521                              "while(true) /* System.out.println(\"1111\"); */;";
522     assertEquals("replace with comment", expectedResult2, replacer.testReplace(s4,s5,s6,options));
523   }
524
525   public void testSeveralStatements() {
526     String s1 = "{\n" +
527                 "        System.out.println(1);\n" +
528                 "        System.out.println(2);\n" +
529                 "        System.out.println(3);\n" +
530                 "      }\n" +
531                 "{\n" +
532                 "        System.out.println(1);\n" +
533                 "        System.out.println(2);\n" +
534                 "        System.out.println(3);\n" +
535                 "      }\n" +
536                 "{\n" +
537                 "        System.out.println(1);\n" +
538                 "        System.out.println(2);\n" +
539                 "        System.out.println(3);\n" +
540                 "      }";
541     String s2 =
542                 "        System.out.println(1);\n" +
543                 "        System.out.println(2);\n" +
544                 "        System.out.println(3);\n";
545     String s3 = "        System.out.println(3);\n" +
546                 "        System.out.println(2);\n" +
547                 "        System.out.println(1);\n";
548     String expectedResult1 = "    {\n" +
549                              "        System.out.println(3);\n" +
550                              "        System.out.println(2);\n" +
551                              "        System.out.println(1);\n" +
552                              "    }\n" +
553                              "    {\n" +
554                              "        System.out.println(3);\n" +
555                              "        System.out.println(2);\n" +
556                              "        System.out.println(1);\n" +
557                              "    }\n" +
558                              "    {\n" +
559                              "        System.out.println(3);\n" +
560                              "        System.out.println(2);\n" +
561                              "        System.out.println(1);\n" +
562                              "    }";
563     options.setToReformatAccordingToStyle(true);
564     assertEquals("three statements replacement", expectedResult1, replacer.testReplace(s1,s2,s3,options));
565     options.setToReformatAccordingToStyle(false);
566
567     String s4 = "ProgressManager.getInstance().startNonCancelableAction();\n" +
568                 "    try {\n" +
569                 "      read(id, READ_PARENT);\n" +
570                 "      return myViewport.parent;\n" +
571                 "    }\n" +
572                 "    finally {\n" +
573                 "      ProgressManager.getInstance().finishNonCancelableAction();\n" +
574                 "    }";
575     String s5 = "ProgressManager.getInstance().startNonCancelableAction();\n" +
576                 "    try {\n" +
577                 "      '_statement{2,2};\n" +
578                 "    }\n" +
579                 "    finally {\n" +
580                 "      ProgressManager.getInstance().finishNonCancelableAction();\n" +
581                 "    }";
582     String s6 = "$statement$;";
583     String expectedResult2 = "read(id, READ_PARENT);\n" +
584                              "      return myViewport.parent;";
585     assertEquals("extra ;", expectedResult2, replacer.testReplace(s4,s5,s6,options));
586
587     String s7 = "public class A {\n" +
588                 "    void f() {\n" +
589                 "        new Runnable() {\n" +
590                 "            public void run() {\n" +
591                 "                l();\n" +
592                 "            }\n" +
593                 "\n" +
594                 "            private void l() {\n" +
595                 "                int i = 9;\n" +
596                 "                int j = 9;\n" +
597                 "            }\n" +
598                 "        };\n" +
599                 "        new Runnable() {\n" +
600                 "            public void run() {\n" +
601                 "                l();\n" +
602                 "            }\n" +
603                 "\n" +
604                 "            private void l() {\n" +
605                 "                l();\n" +
606                 "                l();\n" +
607                 "            }\n" +
608                 "        };\n" +
609                 "    }\n" +
610                 "\n" +
611                 "}";
612     String s8 = "new Runnable() {\n" +
613                 "    public void run() {\n" +
614                 "        '_l ();\n" +
615                 "    }\n" +
616                 "    private void '_l () {\n" +
617                 "        '_st{2,2};\n" +
618                 "    }\n" +
619                 "};";
620     String s9 = "new My() {\n" +
621                 "    public void f() {\n" +
622                 "        $st$;\n" +
623                 "    }\n" +
624                 "};";
625
626     String expectedResult3 = "public class A {\n" +
627                              "    void f() {\n" +
628                              "        new My() {\n" +
629                              "            public void f() {\n" +
630                              "                int i = 9;\n" +
631                              "                int j = 9;\n" +
632                              "            }\n" +
633                              "        };\n" +
634                              "        new My() {\n" +
635                              "            public void f() {\n" +
636                              "                l();\n" +
637                              "                l();\n" +
638                              "            }\n" +
639                              "        };\n" +
640                              "    }\n" +
641                              "\n" +
642                              "}";
643     boolean formatAccordingToStyle = options.isToReformatAccordingToStyle();
644     options.setToReformatAccordingToStyle(true);
645     assertEquals("extra ; 2", expectedResult3, replacer.testReplace(s7,s8,s9,options));
646
647     String s10 = "public class A {\n" +
648                  "    void f() {\n" +
649                  "        new Runnable() {\n" +
650                  "            public void run() {\n" +
651                  "                l();\n" +
652                  "                l();\n" +
653                  "            }\n" +
654                  "            public void run2() {\n" +
655                  "                l();\n" +
656                  "                l();\n" +
657                  "            }\n" +
658                  "\n" +
659                  "        };\n" +
660                  "        new Runnable() {\n" +
661                  "            public void run() {\n" +
662                  "                l();\n" +
663                  "                l();\n" +
664                  "            }\n" +
665                  "            public void run2() {\n" +
666                  "                l();\n" +
667                  "                l();\n" +
668                  "            }\n" +
669                  "\n" +
670                  "        };\n" +
671                  "new Runnable() {\n" +
672                  "            public void run() {\n" +
673                  "                l();\n" +
674                  "                l();\n" +
675                  "            }\n" +
676                  "            public void run2() {\n" +
677                  "                l2();\n" +
678                  "                l2();\n" +
679                  "            }\n" +
680                  "\n" +
681                  "        };\n" +
682                  "    }\n" +
683                  "\n" +
684                  "    private void l() {\n" +
685                  "        int i = 9;\n" +
686                  "        int j = 9;\n" +
687                  "    }\n" +
688                  "}\n" +
689                  "\n" +
690                  "abstract class My {\n" +
691                  "    abstract void f();\n" +
692                  "}";
693     String s11 = "new Runnable() {\n" +
694                  "            public void run() {\n" +
695                  "                'l{2,2};\n" +
696                  "            }\n" +
697                  "            public void run2() {\n" +
698                  "                'l;\n" +
699                  "            }\n" +
700                  "\n" +
701                  "        };";
702     String s12 = "new My() {\n" +
703                  "            public void f() {\n" +
704                  "                $l$;\n" +
705                  "            }\n" +
706                  "        };";
707     String expectedResult4 = "public class A {\n" +
708                              "    void f() {\n" +
709                              "        new My() {\n" +
710                              "            public void f() {\n" +
711                              "                l();\n" +
712                              "                l();\n" +
713                              "            }\n" +
714                              "        };\n" +
715                              "        new My() {\n" +
716                              "            public void f() {\n" +
717                              "                l();\n" +
718                              "                l();\n" +
719                              "            }\n" +
720                              "        };\n" +
721                              "        new Runnable() {\n" +
722                              "            public void run() {\n" +
723                              "                l();\n" +
724                              "                l();\n" +
725                              "            }\n" +
726                              "\n" +
727                              "            public void run2() {\n" +
728                              "                l2();\n" +
729                              "                l2();\n" +
730                              "            }\n" +
731                              "\n" +
732                              "        };\n" +
733                              "    }\n" +
734                              "\n" +
735                              "    private void l() {\n" +
736                              "        int i = 9;\n" +
737                              "        int j = 9;\n" +
738                              "    }\n" +
739                              "}\n" +
740                              "\n" +
741                              "abstract class My {\n" +
742                              "    abstract void f();\n" +
743                              "}";
744
745     assertEquals("same multiple occurences 2 times", expectedResult4, replacer.testReplace(s10,s11,s12,options));
746
747     options.setToReformatAccordingToStyle(formatAccordingToStyle);
748
749     String s13 = "    PsiLock.LOCK.acquire();\n" +
750                  "    try {\n" +
751                  "      return value;\n" +
752                  "    }\n" +
753                  "    finally {\n" +
754                  "      PsiLock.LOCK.release();\n" +
755                  "    }";
756     String s13_2 = "    PsiLock.LOCK.acquire();\n" +
757                    "    try {\n" +
758                    "      if (true) { return value; }\n" +
759                    "    }\n" +
760                    "    finally {\n" +
761                    "      PsiLock.LOCK.release();\n" +
762                    "    }";
763     String s13_3 = "    PsiLock.LOCK.acquire();\n" +
764                    "    try {\n" +
765                    "      if (true) { return value; }\n\n" +
766                    "      if (true) { return value; }\n" +
767                    "    }\n" +
768                    "    finally {\n" +
769                    "      PsiLock.LOCK.release();\n" +
770                    "    }";
771     String s14 = "    PsiLock.LOCK.acquire();\n" +
772                  "    try {\n" +
773                  "      'T{1,1000};\n" +
774                  "    }\n" +
775                  "    finally {\n" +
776                  "      PsiLock.LOCK.release();\n" +
777                  "    }";
778     String s15 = "synchronized(PsiLock.LOCK) {\n" +
779                  "  $T$;\n" +
780                  "}";
781
782     String expectedResult5 = "    synchronized (PsiLock.LOCK) {\n" +
783                              "        return value;\n" +
784                              "    }";
785     options.setToReformatAccordingToStyle(true);
786     assertEquals("extra ; over return", expectedResult5, replacer.testReplace(s13,s14,s15,options));
787     options.setToReformatAccordingToStyle(false);
788
789
790     String expectedResult6 = "    synchronized (PsiLock.LOCK) {\n" +
791                              "        if (true) {\n" +
792                              "            return value;\n" +
793                              "        }\n" +
794                              "    }";
795     options.setToReformatAccordingToStyle(true);
796     assertEquals("extra ; over if", expectedResult6, replacer.testReplace(s13_2,s14,s15,options));
797     options.setToReformatAccordingToStyle(false);
798
799
800     String expectedResult7 = "    synchronized (PsiLock.LOCK) {\n" +
801                              "        if (true) {\n" +
802                              "            return value;\n" +
803                              "        }\n" +
804                              "\n" +
805                              "        if (true) {\n" +
806                              "            return value;\n" +
807                              "        }\n" +
808                              "    }";
809     options.setToReformatAccordingToStyle(true);
810     assertEquals("newlines in matches of several lines", expectedResult7, replacer.testReplace(s13_3,s14,s15,options));
811     options.setToReformatAccordingToStyle(false);
812
813     String s16 = "public class SSTest {\n" +
814                  "  Object lock;\n" +
815                  "  public Object getProducts (String[] productNames) {\n" +
816                  "    synchronized (lock) {\n" +
817                  "      Object o = new Object ();\n" +
818                  "      assert o != null;\n" +
819                  "      return o;\n" +
820                  "    }\n" +
821                  "  }\n" +
822                  "}";
823     String s16_2 = "public class SSTest {\n" +
824                    "  Object lock;\n" +
825                    "  public void getProducts (String[] productNames) {\n" +
826                    "    synchronized (lock) {\n" +
827                    "      boolean[] v = {true};\n" +
828                    "    }\n" +
829                    "  }\n" +
830                    "}";
831
832     String s17 = "synchronized(lock) {\n" +
833                  "  'Statement*;\n" +
834                  "}";
835
836     String s18 = "$Statement$;";
837     String expectedResult8 = "public class SSTest {\n" +
838                              "  Object lock;\n" +
839                              "  public Object getProducts (String[] productNames) {\n" +
840                              "    Object o = new Object ();\n" +
841                              "      assert o != null;\n" +
842                              "      return o;\n" +
843                              "  }\n" +
844                              "}";
845     String expectedResult8_2 = "public class SSTest {\n" +
846                                "  Object lock;\n" +
847                                "  public void getProducts (String[] productNames) {\n" +
848                                "    boolean[] v = {true};\n" +
849                                "  }\n" +
850                                "}";
851
852     assertEquals("extra ;", expectedResult8, replacer.testReplace(s16,s17,s18,options));
853
854     assertEquals("missed ;", expectedResult8_2, replacer.testReplace(s16_2,s17,s18,options));
855   }
856
857   public void testClassReplacement() {
858     boolean formatAccordingToStyle = options.isToReformatAccordingToStyle();
859     options.setToReformatAccordingToStyle(true);
860
861     String s1 = "class A { public void b() {} }";
862     String s2 = "class 'a { '_Other* }";
863     String s3 = "class $a$New { Logger LOG; $Other$ }";
864     String expectedResult = "    class ANew {\n" +
865                             "        Logger LOG;\n\n" +
866                             "        public void b() {\n" +
867                             "        }\n" +
868                             "    }";
869     assertEquals(
870       "Basic class replacement",
871       expectedResult,
872       replacer.testReplace(s1,s2,s3,options)
873     );
874
875     String s4 = "class A { class C {} public void b() {} int f; }";
876     String s5 = "class 'a { '_Other* }";
877     String s6 = "class $a$ { Logger LOG; $Other$ }";
878     String expectedResult2 = "    class A {\n" +
879                              "        Logger LOG;\n\n" +
880                              "        class C {\n" +
881                              "        }\n\n" +
882                              "        public void b() {\n" +
883                              "        }\n\n" +
884                              "        int f;\n" +
885                              "    }";
886
887     assertEquals("Order of members in class replacement", expectedResult2, replacer.testReplace(s4,s5,s6,options));
888
889     String s7 = "class A extends B { int c; void b() {} { a = 1; } }";
890     String s8 = "class 'A extends B { '_Other* }";
891     String s9 = "class $A$ extends B2 { $Other$ }";
892     String expectedResult3 = "    class A extends B2 {\n" +
893                              "        int c;\n\n" +
894                              "        void b() {\n" +
895                              "        }\n\n" +
896                              "        {\n" +
897                              "            a = 1;\n" +
898                              "        }\n" +
899                              "    }";
900
901     assertEquals("Unsupported pattern exception", expectedResult3, replacer.testReplace(s7, s8, s9, options));
902     options.setToReformatAccordingToStyle(formatAccordingToStyle);
903
904     String s10 = "/** @example */\n" +
905                  "class A {\n" +
906                  "  class C {}\n" +
907                  "  public void b() {}\n" +
908                  "  int f;\n" +
909                  "}";
910     String s11 = "class 'a { '_Other* }";
911     String s12 = "public class $a$ {\n" +
912                  "  $Other$\n" +
913                  "}";
914     String expectedResult4 = "    /**\n" +
915                              "     * @example\n" +
916                              "     */\n" +
917                              "    public class A {\n" +
918                              "        class C {\n" +
919                              "        }\n\n" +
920                              "        public void b() {\n" +
921                              "        }\n\n" +
922                              "        int f;\n" +
923                              "    }";
924
925     options.setToReformatAccordingToStyle(true);
926     assertEquals("Make class public", expectedResult4, replacer.testReplace(s10, s11, s12, options));
927     options.setToReformatAccordingToStyle(false);
928
929     String s13 = "class CustomThread extends Thread {\n" +
930                  "public CustomThread(InputStream in, OutputStream out, boolean closeOutOnExit) {\n" +
931                  "    super(CustomThreadGroup.getThreadGroup(), \"CustomThread\");\n" +
932                  "    setDaemon(true);\n" +
933                  "    if (in instanceof BufferedInputStream) {\n" +
934                  "        bis = (BufferedInputStream)in;\n" +
935                  "    } else {\n" +
936                  "    bis = new BufferedInputStream(in);\n" +
937                  "    }\n" +
938                  "    this.out = out;\n" +
939                  "    this.closeOutOnExit = closeOutOnExit;\n" +
940                  "}\n" +
941                  "}";
942     String s14 = "class 'Class extends Thread {\n" +
943                  "  'Class('_ParameterType* '_ParameterName*) {\n" +
944                  "\t  super (CustomThreadGroup.getThreadGroup(), '_superarg* );\n" +
945                  "    '_Statement*;\n" +
946                  "  }\n" +
947                  "}";
948     String s15 = "class $Class$ extends CustomThread {\n" +
949                  "  $Class$($ParameterType$ $ParameterName$) {\n" +
950                  "\t  super($superarg$);\n" +
951                  "    $Statement$;\n" +
952                  "  }\n" +
953                  "}";
954
955     String expectedResult5 = "    class CustomThread extends CustomThread {\n" +
956                              "        CustomThread(InputStream in, OutputStream out, boolean closeOutOnExit) {\n" +
957                              "            super(\"CustomThread\");\n" +
958                              "            setDaemon(true);\n" +
959                              "            if (in instanceof BufferedInputStream) {\n" +
960                              "                bis = (BufferedInputStream) in;\n" +
961                              "            } else {\n" +
962                              "                bis = new BufferedInputStream(in);\n" +
963                              "            }\n" +
964                              "            this.out = out;\n" +
965                              "            this.closeOutOnExit = closeOutOnExit;\n" +
966                              "        }\n" +
967                              "    }";
968     options.setToReformatAccordingToStyle(true);
969     assertEquals("Constructor replacement", expectedResult5, replacer.testReplace(s13, s14, s15, options));
970     options.setToReformatAccordingToStyle(false);
971
972     String s16 = "public class A {}\n" +
973                  "final class B {}";
974     String s17 = "class 'A { '_Other* }";
975     String s17_2 = "class 'A { private Log log = LogFactory.createLog(); '_Other* }";
976     String s18 = "class $A$ { private Log log = LogFactory.createLog(); $Other$ }";
977     String s18_2 = "class $A$ { $Other$ }";
978
979     String expectedResult6 = "public class A { private Log log = LogFactory.createLog();  }\n" +
980                              "final class B { private Log log = LogFactory.createLog();  }";
981     assertEquals("Modifier list for class", expectedResult6, replacer.testReplace(s16, s17, s18, options));
982
983     String expectedResult7 = "public class A {  }\n" +
984                              "final class B {  }";
985     assertEquals("Removing field", expectedResult7, replacer.testReplace(expectedResult6, s17_2, s18_2, options));
986
987     String s19 = "public class A extends Object implements Cloneable {}\n";
988     String s20 = "class 'A { '_Other* }";
989     String s21 = "class $A$ { private Log log = LogFactory.createLog(); $Other$ }";
990
991     String expectedResult8 = "public class A extends Object implements Cloneable { private Log log = LogFactory.createLog();  }\n";
992     assertEquals("Extends / implements list for class", expectedResult8, replacer.testReplace(s19, s20, s21, options));
993
994     String s22 = "public class A<T> { int Afield; }\n";
995     String s23 = "class 'A { '_Other* }";
996     String s24 = "class $A$ { private Log log = LogFactory.createLog(); $Other$ }";
997
998     String expectedResult9 = "public class A<T> { private Log log = LogFactory.createLog(); int Afield; }\n";
999     assertEquals("Type parameters for the class", expectedResult9, replacer.testReplace(s22, s23, s24, options));
1000
1001     String s25 = "class A {\n" +
1002                  "  // comment before\n" +
1003                  "  protected short a; //  comment after\n" +
1004                  "}";
1005     String s26 = "short a;";
1006     String s27 = "Object a;";
1007     String expectedResult10 = "class A {\n" +
1008                               "  // comment before\n" +
1009                               "  protected Object a; //  comment after\n" +
1010                               "}";
1011
1012     assertEquals(
1013       "Replacing dcl with saving access modifiers",
1014       expectedResult10,
1015       replacer.testReplace(s25,s26,s27,options)
1016     );
1017
1018     String s28 = "aaa";
1019     String s29 = "class 'Class {\n" +
1020                  " 'Class('_ParameterType '_ParameterName) {\n" +
1021                  "    'Class('_ParameterName);\n" +
1022                  "  }\n" +
1023                  "}";
1024     String s30 = "class $Class$ {\n" +
1025                  "  $Class$($ParameterType$ $ParameterName$) {\n" +
1026                  "     this($ParameterName$);\n" +
1027                  "  }\n" +
1028                  "}";
1029     String expectedResult11 = "aaa";
1030
1031     assertEquals(
1032       "Complex class replacement",
1033       expectedResult11,
1034       replacer.testReplace(s28,s29,s30,options)
1035     );
1036
1037     String s31 = "class A {\n" +
1038                  "  int a; // comment\n" +
1039                  "  char b;\n" +
1040                  "  int c; // comment2\n" +
1041                  "}";
1042
1043     String s32 = "'_Type 'Variable = '_Value?; //'_Comment";
1044     String s33 = "/**$Comment$*/\n" +
1045                  "$Type$ $Variable$ = $Value$;";
1046
1047     String expectedResult12 = "    class A {\n" +
1048                               "        /**\n" +
1049                               "         * comment\n" +
1050                               "         */\n" +
1051                               "        int a;\n" +
1052                               "        char b;\n" +
1053                               "        /**\n" +
1054                               "         * comment2\n" +
1055                               "         */\n" +
1056                               "        int c;\n" +
1057                               "    }";
1058     options.setToReformatAccordingToStyle(true);
1059     assertEquals(
1060       "Replacing comments with javadoc for fields",
1061       expectedResult12,
1062       replacer.testReplace(s31,s32,s33,options)
1063     );
1064     options.setToReformatAccordingToStyle(false);
1065
1066     String s34 = "/**\n" +
1067                  " * This interface stores XXX\n" +
1068                  " * <p/>\n" +
1069                  " */\n" +
1070                  "public interface X {\n" +
1071                  "    public static final String HEADER = Headers.HEADER;\n" +
1072                  "\n" +
1073                  "}";
1074
1075     String s35 = "public interface 'MessageInterface {\n" +
1076                  "    public static final String '_X = '_VALUE;\n" +
1077                  "    'blah*" +
1078                  "}";
1079     String s36 = "public interface $MessageInterface$ {\n" +
1080                  "    public static final String HEADER = $VALUE$;\n" +
1081                  "    $blah$\n" +
1082                  "}";
1083
1084     String expectedResult13 = "/**\n" +
1085                               " * This interface stores XXX\n" +
1086                               " * <p/>\n" +
1087                               " */\n" +
1088                               "public interface X {\n" +
1089                               "    public static final String HEADER = Headers.HEADER;\n" +
1090                               "    \n" +
1091                               "}";
1092
1093     assertEquals(
1094       "Replacing interface with interface, saving comments properly",
1095       expectedResult13,
1096       replacer.testReplace(s34,s35,s36,options, true)
1097     );
1098   }
1099
1100   public void testClassReplacement3() {
1101     if (true) return;
1102     String s37 = "class A { int a = 1; void B() {} int C(char ch) { int z = 1; } int b = 2; }";
1103
1104     String s38 = "class 'A { 'T* 'M*('PT* 'PN*) { 'S*; } 'O* }";
1105     String s39 = "class $A$ { $T$ $M$($PT$ $PN$) { System.out.println(\"$M$\"); $S$; } $O$ }";
1106
1107     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;}";
1108     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;}";
1109
1110     assertEquals(
1111       "Multiple methods replacement",
1112       expectedResult14,
1113       replacer.testReplace(s37,s38,s39,options, true)
1114     );
1115   }
1116
1117   public void testClassReplacement4() {
1118     String s1 = "class A {\n" +
1119                 "  int a = 1;\n" +
1120                 "  int b;\n" +
1121                 "  private int c = 2;\n" +
1122                 "}";
1123
1124     String s2 = "@Modifier(\"packageLocal\") '_Type '_Instance = '_Init?;";
1125     String s3 = "public $Type$ $Instance$ = $Init$;";
1126
1127     String expectedResult = "class A {\n" +
1128                             "  public int a = 1;\n" +
1129                             "  public int b ;\n" +
1130                             "  private int c = 2;\n" +
1131                             "}";
1132
1133     assertEquals(
1134       "Multiple fields replacement",
1135       expectedResult,
1136       replacer.testReplace(s1,s2,s3,options, true)
1137     );
1138   }
1139
1140   public void testClassReplacement5() {
1141     String s1 = "public class X {\n" +
1142                 "    /**\n" +
1143                 "     * zzz\n" +
1144                 "     */\n" +
1145                 "    void f() {\n" +
1146                 "\n" +
1147                 "    }\n" +
1148                 "}";
1149
1150     String s2 = "class 'c {\n" +
1151                 "    /**\n" +
1152                 "     * zzz\n" +
1153                 "     */\n" +
1154                 "    void f(){}\n" +
1155                 "}";
1156     String s3 = "class $c$ {\n" +
1157                 "    /**\n" +
1158                 "     * ppp\n" +
1159                 "     */\n" +
1160                 "    void f(){}\n" +
1161                 "}";
1162
1163     String expectedResult = "public class X {\n" +
1164                             "    /**\n" +
1165                             "     * ppp\n" +
1166                             "     */\n" +
1167                             "    void f(){}\n" +
1168                             "}";
1169
1170     assertEquals(
1171       "Not preserving comment if it is present",
1172       expectedResult,
1173       replacer.testReplace(s1,s2,s3,options, true)
1174     );
1175   }
1176
1177   public void testClassReplacement6() {
1178     String s1 = "public class X {\n" +
1179                 "   /**\n" +
1180                 "    * zzz\n" +
1181                 "    */\n" +
1182                 "   private void f(int i) {\n" +
1183                 "       //s\n" +
1184                 "   }\n" +
1185                 "}";
1186     String s1_2 = "public class X {\n" +
1187                 "   /**\n" +
1188                 "    * zzz\n" +
1189                 "    */\n" +
1190                 "   private void f(int i) {\n" +
1191                 "       int a = 1;\n" +
1192                 "       //s\n" +
1193                 "   }\n" +
1194                 "}";
1195
1196     String s2 = "class 'c {\n" +
1197                 "   /**\n" +
1198                 "    * zzz\n" +
1199                 "    */\n" +
1200                 "   void f('_t '_p){'_s+;}\n" +
1201                 "}";
1202     String s3 = "class $c$ {\n" +
1203                 "   /**\n" +
1204                 "    * ppp\n" +
1205                 "    */\n" +
1206                 "   void f($t$ $p$){$s$;}\n" +
1207                 "}";
1208
1209     String expectedResult = "public class X {\n" +
1210                             "   /**\n" +
1211                             "    * ppp\n" +
1212                             "    */\n" +
1213                             "   private void f(int i ){//s\n" +
1214                             "}\n" +
1215                             "}";
1216
1217     assertEquals(
1218       "Correct class replacement",
1219       expectedResult,
1220       replacer.testReplace(s1,s2,s3,options)
1221     );
1222
1223     String expectedResult2 = "public class X {\n" +
1224                             "   /**\n" +
1225                             "    * ppp\n" +
1226                             "    */\n" +
1227                             "   private void f(int i ){int a = 1;\n" +
1228                             "       //s\n" +
1229                             "}\n" +
1230                             "}";
1231
1232     assertEquals(
1233       "Correct class replacement, 2",
1234       expectedResult2,
1235       replacer.testReplace(s1_2,s2,s3,options)
1236     );
1237   }
1238
1239   public void testClassReplacement7() {
1240     String s1 = "/**\n" +
1241                 "* Created by IntelliJ IDEA.\n" +
1242                 "* User: cdr\n" +
1243                 "* Date: Nov 15, 2005\n" +
1244                 "* Time: 4:23:29 PM\n" +
1245                 "* To change this template use File | Settings | File Templates.\n" +
1246                 "*/\n" +
1247                 "public class CC {\n" +
1248                 "   /** My Comment */ int a = 3; // aaa\n" +
1249                 "   // bbb\n" +
1250                 "   long c = 2;\n" +
1251                 "   void f() {\n" +
1252                 "   }\n" +
1253                 "}";
1254     String s2 = "/**\n" +
1255                 "* Created by IntelliJ IDEA.\n" +
1256                 "* User: '_USER\n" +
1257                 "* Date: '_DATE\n" +
1258                 "* Time: '_TIME\n" +
1259                 "* To change this template use File | Settings | File Templates.\n" +
1260                 "*/\n" +
1261                 "class 'c {\n" +
1262                 "  '_other*\n" +
1263                 "}";
1264     String s3 = "/**\n" +
1265                 "* by: $USER$\n" +
1266                 "*/\n" +
1267                 "class $c$ {\n" +
1268                 "  $other$\n" +
1269                 "}";
1270     String expectedResult = "/**\n" +
1271                             "* by: cdr\n" +
1272                             "*/\n" +
1273                             "public class CC {\n" +
1274                             "  /** My Comment */ int a = 3; // aaa\n" +
1275                             "// bbb\n" +
1276                             "   long c = 2;\n" +
1277                             "void f() {\n" +
1278                             "   }\n" +
1279                             "}";
1280
1281     assertEquals("Class with comment replacement", expectedResult, replacer.testReplace(s1,s2,s3,options,true));
1282   }
1283
1284   public void testClassReplacement8() {
1285     String s1 = "public class CC {\n" +
1286                 "   /** AAA*/ int b = 1; // comment\n" +
1287                 "}";
1288     String s2 = "int b = 1;";
1289     String s3 = "long c = 2;";
1290     String expectedResult = "public class CC {\n" +
1291                             "   /** AAA*/ long c = 2; // comment\n" +
1292                             "}";
1293
1294     assertEquals("Class field replacement with simple pattern",
1295                  expectedResult, replacer.testReplace(s1,s2,s3,options,true));
1296   }
1297
1298   @NotNull
1299   @Override
1300   protected String getTestDataPath() {
1301     return PlatformTestUtil.getCommunityPath() + "/platform/structuralsearch/testData/";
1302   }
1303
1304   public void testClassReplacement9() throws IOException {
1305     String s1 = loadFile("before1.java");
1306     String s2 = "class 'A extends '_TestCaseCass:[regex( .*TestCase ) ] {\n" +
1307                 "  '_OtherStatement*;\n" +
1308                 "  public void '_testMethod*:[regex( test.* )] () {\n" +
1309                 "  }\n" +
1310                 "  '_OtherStatement2*;\n" +
1311                 "}";
1312     String s3 = "class $A$ extends $TestCaseCass$ {\n" +
1313                 "    $OtherStatement$;\n" +
1314                 "    $OtherStatement2$;\n" +
1315                 "}";
1316     String expectedResult = loadFile("after1.java");
1317
1318     options.setToReformatAccordingToStyle(true);
1319     assertEquals("Class replacement 9", expectedResult, replacer.testReplace(s1,s2,s3,options,true));
1320   }
1321
1322   public void testReplaceReturnWithArrayInitializer() {
1323     String searchIn = "return ( new String[]{CoreVars.CMUAudioPort + \"\"} );";
1324     String searchFor = "return ( 'A );";
1325     String replaceBy = "return $A$;";
1326     String expectedResult = "return new String[]{CoreVars.CMUAudioPort + \"\"};";
1327
1328     assertEquals("ReplaceReturnWithArrayInitializer", expectedResult, replacer.testReplace(searchIn,searchFor,replaceBy,options));
1329   }
1330
1331   public void _testClassReplacement10() throws IOException {
1332     String s1 = loadFile("before2.java");
1333     String s2 = "class '_Class {\n" +
1334                 "  '_ReturnType+ '_MethodName+('_ParameterType* '_Parameter*){\n" +
1335                 "    '_content*;\n" +
1336                 "  }\n" +
1337                 "  '_remainingclass*" +
1338                 "}";
1339     String s3 = "class $Class$ {\n" +
1340                 "  $remainingclass$\n" +
1341                 "  @Override $ReturnType$ $MethodName$($ParameterType$ $Parameter$){\n" +
1342                 "    $content$;\n" +
1343                 "  }\n" +
1344                 "}";
1345     String expectedResult = loadFile("after2.java");
1346
1347     options.setToReformatAccordingToStyle(true);
1348     assertEquals("Class replacement 10", expectedResult, replacer.testReplace(s1,s2,s3,options,true));
1349   }
1350
1351   public void testCatchReplacement() throws Exception {
1352     String s1 = "try {\n" +
1353                 "  aaa();\n" +
1354                 "} catch(Exception ex) {\n" +
1355                 "  LOG.assertTrue(false);\n" +
1356                 "}";
1357     String s2 = "{  LOG.assertTrue(false); }";
1358     String s3 = "{  if (false) LOG.assertTrue(false); }";
1359     String expectedResult = "try {\n" +
1360                 "  aaa();\n" +
1361                 "} catch (Exception ex) {\n" +
1362                 "    if (false) LOG.assertTrue(false);\n" +
1363                 "}";
1364     options.setToReformatAccordingToStyle(true);
1365     assertEquals("Catch replacement by block", expectedResult, replacer.testReplace(s1,s2,s3,options));
1366     options.setToReformatAccordingToStyle(false);
1367
1368   }
1369
1370   public void testSavingAccessModifiersDuringClassReplacement() {
1371     String s43 = "public @Deprecated class Foo implements Comparable<Foo> {\n  int x;\n  void m(){}\n }";
1372     String s44 = "class 'Class implements '_Interface { '_Content* }";
1373     String s45 = "@MyAnnotation\n" +
1374                  "class $Class$ implements $Interface$ {$Content$}";
1375     String expectedResult16 = "@MyAnnotation public @Deprecated\n" +
1376                               "class Foo implements Comparable<Foo> {int x;\n" +
1377                               "void m(){}}";
1378
1379     assertEquals(
1380       "Preserving var modifiers and generic information in type during replacement",
1381       expectedResult16,
1382       replacer.testReplace(s43, s44, s45, options, true)
1383     );
1384
1385     String in1 = "public class A {" +
1386                  "  public class B {}" +
1387                  "}";
1388     String what1 = "class '_A {" +
1389                    "  class '_B {}" +
1390                    "}";
1391     String by1 = "class $A$ {" +
1392                  "  private class $B$ {}" +
1393                  "}";
1394     String expected1 = "public class A {  private class B {}}";
1395     assertEquals("No illegal modifier combinations during replacement", expected1, replacer.testReplace(in1, what1, by1, options));
1396   }
1397
1398   public void testDontRequireSpecialVarsForUnmatchedContent() {
1399
1400     String s43 = "public @Deprecated class Foo implements Comparable<Foo> {\n" +
1401                  "  int x;\n" +
1402                  "  void m(){}\n" +
1403                  " }";
1404     String s44 = "class 'Class implements '_Interface {}";
1405     String s45 = "@MyAnnotation\n" +
1406                  "class $Class$ implements $Interface$ {}";
1407     String expectedResult16 = "@MyAnnotation public @Deprecated\n" +
1408                               "class Foo implements Comparable<Foo> {\n" +
1409                               "  int x;\n" +
1410                               "  void m(){}\n" +
1411                               " }";
1412
1413     assertEquals(
1414       "Preserving class modifiers and generic information in type during replacement",
1415       expectedResult16,
1416       replacer.testReplace(s43, s44, s45, options, true)
1417     );
1418
1419     String in = "public class A {\n" +
1420                 "  int i,j, k;\n" +
1421                 "  void m1() {}\n" +
1422                 "\n" +
1423                 "  public void m2() {}\n" +
1424                 "  void m3() {}\n" +
1425                 "}";
1426     String what = "class '_A {\n" +
1427                   "  public void '_m();\n" +
1428                   "}";
1429     String by = "class $A$ {\n" +
1430                 "\tprivate void $m$() {}\n" +
1431                 "}";
1432     assertEquals("Should keep member order when replacing",
1433                  "public class A {\n" +
1434                  "  int i ,j , k;\n" +
1435                  "  void m1() {}\n" +
1436                  "\n" +
1437                  "  private void m2() {}\n" +
1438                  "  void m3() {}\n" +
1439                  "}",
1440                  replacer.testReplace(in, what, by, options));
1441   }
1442
1443   public void testClassReplacement2() {
1444     String s40 = "class A {\n" +
1445                  "  /* special comment*/\n" +
1446                  "  private List<String> a = new ArrayList();\n" +
1447                  "  static {\n" +
1448                  "    int a = 1;" +
1449                  "  }\n" +
1450                  "}";
1451     String s41 = "class '_Class {\n" +
1452                  "  '_Stuff2*\n" +
1453                  "  '_FieldType '_FieldName = '_Init?;\n" +
1454                  "  static {\n" +
1455                  "    '_Stmt*;\n" +
1456                  "  }\n" +
1457                  "  '_Stuff*\n" +
1458                  "}";
1459     String s42 = "class $Class$ {\n" +
1460                  "  $Stuff2$\n" +
1461                  "  $FieldType$ $FieldName$ = build$FieldName$Map();\n" +
1462                  "  private static $FieldType$ build$FieldName$Map() {\n" +
1463                  "    $FieldType$ $FieldName$ = $Init$;\n" +
1464                  "    $Stmt$;\n" +
1465                  "    return $FieldName$;\n" +
1466                  "  }\n" +
1467                  "  $Stuff$\n" +
1468                  "}";
1469     String expectedResult15 = "class A {\n" +
1470                               "  \n" +
1471                               "  /* special comment*/\n" +
1472                               "  private List<String> a = buildaMap();\n" +
1473                               "  private static List<String> buildaMap() {\n" +
1474                               "    List<String> a = new ArrayList();\n" +
1475                               "    int a = 1;\n" +
1476                               "    return a;\n" +
1477                               "  }\n" +
1478                               "  \n" +
1479                               "}";
1480
1481     assertEquals("Preserving var modifiers and generic information in type during replacement",
1482       expectedResult15, replacer.testReplace(s40,s41,s42,options, true));
1483
1484     String s46 = "class Foo { int xxx; void foo() { assert false; } void yyy() {}}";
1485     String s47 = "class '_Class { void '_foo:[regex( foo )](); }";
1486     String s48 = "class $Class$ { void $foo$(int a); }";
1487     String expectedResult17 = "class Foo { int xxx; void foo(int a) { assert false; } void yyy() {}}";
1488
1489     assertEquals(
1490       "Preserving method bodies",
1491       expectedResult17,
1492       replacer.testReplace(s46,s47,s48,options, true)
1493     );
1494   }
1495
1496   public void testReplaceExceptions() {
1497     String s1 = "a=a;";
1498     String s2 = "'a";
1499     String s3 = "$b$";
1500
1501     try {
1502       replacer.testReplace(s1,s2,s3,options);
1503       assertTrue("Undefined replace variable is not checked",false);
1504     } catch(UnsupportedPatternException ex) {
1505
1506     }
1507
1508     String s4 = "a=a;";
1509     String s5 = "a=a;";
1510     String s6 = "a=a";
1511
1512     try {
1513       replacer.testReplace(s4,s5,s6,options);
1514       assertTrue("Undefined no ; in replace",false);
1515     } catch(UnsupportedPatternException ex) {
1516     }
1517
1518     try {
1519       replacer.testReplace(s4,s6,s5,options);
1520       assertTrue("Undefined no ; in search",false);
1521     } catch(UnsupportedPatternException ex) {
1522     }
1523   }
1524
1525   public void testActualParameterReplacementInConstructorInvokation() {
1526     String s1 = "filterActions[0] = new Action(TEXT,\n" +
1527                 "    LifeUtil.getIcon(\"search\")) {\n" +
1528                 "        void test() {\n" +
1529                 "            int a = 1;\n" +
1530                 "        }\n" +
1531                 "};";
1532     String s2 = "LifeUtil.getIcon(\"search\")";
1533     String s3 = "StdIcons.SEARCH_LIFE";
1534     String expectedResult = "filterActions[0] = new Action(TEXT,\n" +
1535                 "        StdIcons.SEARCH_LIFE) {\n" +
1536                 "        void test() {\n" +
1537                 "            int a = 1;\n" +
1538                 "        }\n" +
1539                 "};";
1540     options.setToReformatAccordingToStyle(true);
1541     options.setToShortenFQN(true);
1542
1543     assertEquals("Replace in anonymous class parameter", expectedResult, replacer.testReplace(s1, s2, s3, options));
1544     options.setToShortenFQN(false);
1545     options.setToReformatAccordingToStyle(false);
1546   }
1547
1548   public void testRemove() {
1549     String s1 = "class A {\n" +
1550                 "  /* */\n" +
1551                 "  void a() {\n" +
1552                 "  }\n" +
1553                 "  /*\n" +
1554                 "  */\n" +
1555                 "  int b = 1;\n" +
1556                 "  /*\n" +
1557                 "   *\n" +
1558                 "   */\n" +
1559                 "   class C {}\n" +
1560                 "  {\n" +
1561                 "    /* aaa */\n" +
1562                 "    int a;\n" +
1563                 "    /* */\n" +
1564                 "    a = 1;\n" +
1565                 "  }\n" +
1566                 "}";
1567     String s2 = "/* 'a:[regex( .* )] */";
1568     String s2_2 = "/* */";
1569     String s3 = "";
1570     String expectedResult = "class A {\n" +
1571                             "    void a() {\n" +
1572                             "    }\n" +
1573                             "\n" +
1574                             "    int b = 1;\n" +
1575                             "\n" +
1576                             "    class C {\n" +
1577                             "    }\n" +
1578                             "\n" +
1579                             "    {\n" +
1580                             "        int a;\n" +
1581                             "        a = 1;\n" +
1582                             "    }\n" +
1583                             "}";
1584     options.setToReformatAccordingToStyle(true);
1585     assertEquals("Removing comments", expectedResult, replacer.testReplace(s1,s2,s3,options));
1586     options.setToReformatAccordingToStyle(false);
1587
1588
1589     String expectedResult2 = "class A {\n" +
1590                              "  void a() {\n" +
1591                              "  }\n" +
1592                              "  /*\n" +
1593                              "  */\n" +
1594                              "  int b = 1;\n" +
1595                              "  /*\n" +
1596                              "   *\n" +
1597                              "   */\n" +
1598                              "   class C {}\n" +
1599                              "  {\n" +
1600                              "    /* aaa */\n" +
1601                              "    int a;\n" +
1602                              "    a = 1;\n" +
1603                              "  }\n" +
1604                              "}";
1605
1606     assertEquals("Removing comments", expectedResult2, replacer.testReplace(s1,s2_2,s3,options));
1607   }
1608
1609   public void testTryCatchInLoop() throws Exception {
1610     String code = "for (int i = 0; i < MIMEHelper.MIME_MAP.length; i++)\n" +
1611                 "{\n" +
1612                 "  String s = aFileNameWithOutExtention + MIMEHelper.MIME_MAP[i][0][0];\n" +
1613                 "  try\n" +
1614                 "  {\n" +
1615                 "    if (ENABLE_Z107_READING)\n" +
1616                 "    { in = aFileNameWithOutExtention.getClass().getResourceAsStream(s); }\n" +
1617                 "    else\n" +
1618                 "    { data = ResourceHelper.readResource(s); }\n" +
1619                 "    mime = MIMEHelper.MIME_MAP[i][1][0];\n" +
1620                 "    break;\n" +
1621                 "  }\n" +
1622                 "  catch (final Exception e)\n" +
1623                 "  { continue; }\n" +
1624                 "}";
1625     String toFind = "try { '_TryStatement*; } catch(Exception '_ExceptionDcl) { '_CatchStatement*; }";
1626     String replacement = "try { $TryStatement$; }\n" + "catch(Throwable $ExceptionDcl$) { $CatchStatement$; }";
1627     String expectedResult = "for (int i = 0; i < MIMEHelper.MIME_MAP.length; i++)\n" +
1628                             "{\n" +
1629                             "  String s = aFileNameWithOutExtention + MIMEHelper.MIME_MAP[i][0][0];\n" +
1630                             "  try { if (ENABLE_Z107_READING)\n" +
1631                             "    { in = aFileNameWithOutExtention.getClass().getResourceAsStream(s); }\n" +
1632                             "    else\n" +
1633                             "    { data = ResourceHelper.readResource(s); }\n" +
1634                             "    mime = MIMEHelper.MIME_MAP[i][1][0];\n" +
1635                             "    break; }\n" +
1636                             "catch(final Throwable e) { continue; }\n" +
1637                             "}";
1638
1639     assertEquals("Replacing try/catch in loop", expectedResult, replacer.testReplace(code,toFind,replacement,options));
1640   }
1641
1642   public void testUseStaticImport() {
1643     final String in = "class X {{ Math.abs(-1); }}";
1644     final String what = "Math.abs('a)";
1645     final String by = "Math.abs($a$)";
1646     final boolean save = options.isToUseStaticImport();
1647     options.setToUseStaticImport(true);
1648     try {
1649       final String expected = "import static java.lang.Math.abs;class X {{ abs(-1); }}";
1650       assertEquals("Replacing with static import", expected, replacer.testReplace(in, what, by, options, true));
1651
1652       final String in2 = "class X { void m(java.util.Random r) { Math.abs(r.nextInt()); }}";
1653       final String expected2 = "import static java.lang.Math.abs;class X { void m(java.util.Random r) { abs(r.nextInt()); }}";
1654       assertEquals("don't add broken static imports", expected2, replacer.testReplace(in2, what, by, options, true));
1655
1656       final String by2 = "new java.util.Map.Entry() {}";
1657       final String expected3 = "import static java.util.Map.Entry;class X {{ new Entry() {}; }}";
1658       assertEquals("", expected3, replacer.testReplace(in, what, by2, options, true));
1659
1660       final String in3 = "import java.util.Collections;" +
1661                          "class X {" +
1662                          "  void m() {" +
1663                          "    System.out.println(Collections.<String>emptyList());" +
1664                          "  }" +
1665                          "}";
1666       final String what3 = "'_q.'_method:[regex( println )]('a)";
1667       final String by3 = "$q$.$method$($a$)";
1668       final String expected4 = "import java.util.Collections;" +
1669                                "import static java.lang.System.out;" +
1670                                "class X {" +
1671                                "  void m() {" +
1672                                "    out.println(Collections.<String>emptyList());" +
1673                                "  }" +
1674                                "}";
1675       assertEquals("don't break references with type parameters", expected4, replacer.testReplace(in3, what3, by3, options, true));
1676
1677       final String in4 = "import java.util.Collections;\n" +
1678                          "public class X {\n" +
1679                          "    void some() {\n" +
1680                          "        System.out.println(1);\n" +
1681                          "        boolean b = Collections.eq(null, null);\n" +
1682                          "    }\n" +
1683                          "}";
1684       final String what4 = "System.out.println(1);";
1685       final String by4 = "System.out.println(2);";
1686       final String expected5 = "import java.util.Collections;import static java.lang.System.out;\n" +
1687                                "public class X {\n" +
1688                                "    void some() {\n" +
1689                                "        out.println(2);\n" +
1690                                "        boolean b = Collections.eq(null, null);\n" +
1691                                "    }\n" +
1692                                "}";
1693       assertEquals("don't add static import to inaccessible members", expected5, replacer.testReplace(in4, what4, by4, options, true));
1694     } finally {
1695       options.setToUseStaticImport(save);
1696     }
1697   }
1698
1699   public void testUseStaticStarImport() {
1700     final String in = "class ImportTest {{\n" +
1701                       "    Math.abs(-0.5);\n" +
1702                       "    Math.sin(0.5);\n" +
1703                       "    Math.max(1, 2);\n" +
1704                       "}}";
1705     final String what = "Math.'m('_a*)";
1706     final String by = "Math.$m$($a$)";
1707     final boolean save = options.isToUseStaticImport();
1708     options.setToUseStaticImport(true);
1709     try {
1710
1711       // depends on default setting being equal to 3 for names count to use import on demand
1712       final String expected = "import static java.lang.Math.*;class ImportTest {{\n" +
1713                               "    abs(-0.5);\n" +
1714                               "    sin(0.5);\n" +
1715                               "    max(1,2);\n" +
1716                               "}}";
1717       assertEquals("Replacing with static star import", expected, replacer.testReplace(in, what, by, options, true));
1718     } finally {
1719       options.setToUseStaticImport(save);
1720     }
1721   }
1722
1723   public void testReformatAndShortenClassRefPerformance() throws IOException {
1724     final String testName = getTestName(false);
1725     final String ext = "java";
1726     final String message = "Reformat And Shorten Class Ref Performance";
1727
1728     options.setToReformatAccordingToStyle(true);
1729     options.setToShortenFQN(true);
1730
1731     try {
1732       PlatformTestUtil.startPerformanceTest("SSR should work fast", 3500, new ThrowableRunnable() {
1733                                               public void run() {
1734                                                 doTest(testName, ext, message);
1735                                               }
1736                                             }
1737       ).cpuBound().useLegacyScaling().assertTiming();
1738     } finally {
1739       options.setToReformatAccordingToStyle(false);
1740       options.setToShortenFQN(false);
1741     }
1742   }
1743
1744   private void doTest(final String testName, final String ext, final String message) {
1745     try {
1746       String source = loadFile(testName + "_source." + ext);
1747       String pattern = loadFile(testName + "_pattern." + ext);
1748       String replacement = loadFile(testName + "_replacement." + ext);
1749       String expected = loadFile(testName + "_result." + ext);
1750
1751       assertEquals(message, expected, replacer.testReplace(source,pattern,replacement,options));
1752     }
1753     catch (IOException e) {
1754       throw new RuntimeException(e);
1755     }
1756   }
1757
1758   public void testLeastSurprise() {
1759     String s1 = "@Nullable (a=String.class) @String class Test {\n" +
1760                 "  void aaa(String t) {\n" +
1761                 "    String a = String.valueOf(' ');" +
1762                 "    String2 a2 = String2.valueOf(' ');" +
1763                 "  }\n" +
1764                 "}";
1765     String s2 = "'String:String";
1766     String s2_2 = "String";
1767     String s2_3 = "'String:java\\.lang\\.String";
1768     String s2_4 = "java.lang.String";
1769     String replacement = CommonClassNames.JAVA_UTIL_LIST;
1770     String expected = "@Nullable (a=java.util.List.class) @java.util.List class Test {\n" +
1771                 "  void aaa(java.util.List t) {\n" +
1772                 "    java.util.List a = java.util.List.valueOf(' ');" +
1773                 "    String2 a2 = String2.valueOf(' ');" +
1774                 "  }\n" +
1775                 "}";
1776
1777     assertEquals(expected, replacer.testReplace(s1,s2,replacement,options));
1778     assertEquals(expected, replacer.testReplace(s1,s2_2,replacement,options));
1779     assertEquals(expected, replacer.testReplace(s1,s2_3,replacement,options));
1780     assertEquals(expected, replacer.testReplace(s1,s2_4,replacement,options));
1781   }
1782
1783   public void testLeastSurprise2() {
1784     String s1 = "class B { int s(int a) { a = 1; a = 2; c(a); } }";
1785     String s2 = "a";
1786     String replacement = "a2";
1787     String expected = "class B { int s(int a2) { a2 = 1; a2 = 2; c(a2); } }";
1788
1789     assertEquals(expected, replacer.testReplace(s1,s2,replacement,options));
1790   }
1791
1792   public void testReplaceTry() {
1793     String s1 = "try {\n" +
1794                 "            em.persist(p);\n" +
1795                 "        } catch (PersistenceException e) {\n" +
1796                 "            // good\n" +
1797                 "        }";
1798     String s2 = "try { '_TryStatement; } catch('_ExceptionType '_ExceptionDcl) { /* '_CommentContent */ }";
1799     String replacement = "try { $TryStatement$; } catch($ExceptionType$ $ExceptionDcl$) { _logger.warning(\"$CommentContent$\", $ExceptionDcl$); }";
1800     String expected = "try { em.persist(p); } catch(PersistenceException e) { _logger.warning(\" good\", e); }";
1801
1802     assertEquals(expected, replacer.testReplace(s1,s2,replacement,options));
1803
1804     final String in1 = "try {\n" +
1805                        "  System.out.println(1);\n" +
1806                        "} catch (RuntimeException e) {\n" +
1807                        "  System.out.println(2);\n" +
1808                        "} finally {\n" +
1809                        "  System.out.println(3);\n" +
1810                        "}\n";
1811     final String what1 = "try {\n" +
1812                          "  '_Statement1;\n" +
1813                          "} finally {\n" +
1814                          "  '_Statement2;\n" +
1815                          "}";
1816     final String by1 = "try {\n" +
1817                        "  // comment1\n" +
1818                        "  $Statement1$;\n" +
1819                        "} finally {\n" +
1820                        "  // comment2\n" +
1821                        "  $Statement2$;\n" +
1822                        "}";
1823     final String expected1 = "try {\n" +
1824                              "  // comment1\n" +
1825                              "  System.out.println(1);\n" +
1826                              "} catch (RuntimeException e) {\n" +
1827                              "  System.out.println(2);\n" +
1828                              "} finally {\n" +
1829                              "  // comment2\n" +
1830                              "  System.out.println(3);\n" +
1831                              "}\n";
1832     assertEquals("Replacing try/finally should leave unmatched catch sections alone",
1833                  expected1, replacer.testReplace(in1, what1, by1, options));
1834
1835     final String in2 = "try (AutoCloseable a = null) {" +
1836                        "  System.out.println(1);" +
1837                        "} catch (Exception e) {" +
1838                        "  System.out.println(2);" +
1839                        "} finally {" +
1840                        "  System.out.println(3);" +
1841                        "}";
1842     final String what2 = "try {" +
1843                          "  '_Statement*;" +
1844                          "}";
1845     final String by2 = "try {" +
1846                        "  /* comment */" +
1847                        "  $Statement$;" +
1848                        "}";
1849     final String expected2 = "try (AutoCloseable a = null) {" +
1850                              "  /* comment */  System.out.println(1);" +
1851                              "} catch (Exception e) {" +
1852                              "  System.out.println(2);" +
1853                              "} finally {" +
1854                              "  System.out.println(3);" +
1855                              "}";
1856     assertEquals("Replacing try/finally should also keep unmatched resource lists and finally blocks",
1857                  expected2,
1858                  replacer.testReplace(in2, what2, by2, options));
1859   }
1860
1861   public void testReplaceExtraSemicolon() {
1862     String s1 = "try {\n" +
1863                 "      String[] a = {\"a\"};\n" +
1864                 "      System.out.println(\"blah\");\n" +
1865                 "} finally {\n" +
1866                 "}\n";
1867     String s2 = "try {\n" + " 'statement*;\n" + "} finally {\n" + "  \n" + "}";
1868     String replacement = "$statement$;";
1869     String expected = "String[] a = {\"a\"};\n" +
1870                 "      System.out.println(\"blah\");\n";
1871
1872     assertEquals(expected, replacer.testReplace(s1,s2,replacement,options));
1873
1874     String s1_2 = "try {\n" +
1875                   "    if (args == null) return ;\n" +
1876                   "    while(true) return ;\n" +
1877                   "    System.out.println(\"blah2\");\n" +
1878                   "} finally {\n" +
1879                   "}";
1880     String expected_2 = "if (args == null) return ;\n" +
1881                   "    while(true) return ;\n" +
1882                   "    System.out.println(\"blah2\");";
1883
1884     assertEquals(expected_2, replacer.testReplace(s1_2,s2,replacement,options));
1885
1886     String s1_3 = "{\n" +
1887                   "    try {\n" +
1888                   "        System.out.println(\"blah1\");\n" +
1889                   "\n" +
1890                   "        System.out.println(\"blah2\");\n" +
1891                   "    } finally {\n" +
1892                   "    }\n" +
1893                   "}";
1894     String expected_3 = "{\n" +
1895                   "    System.out.println(\"blah1\");\n" +
1896                   "\n" +
1897                   "        System.out.println(\"blah2\");\n" +
1898                   "}";
1899     assertEquals(expected_3, replacer.testReplace(s1_3,s2,replacement,options));
1900
1901     String s1_4 = "{\n" +
1902                   "    try {\n" +
1903                   "        System.out.println(\"blah1\");\n" +
1904                   "        // indented comment\n" +
1905                   "        System.out.println(\"blah2\");\n" +
1906                   "    } finally {\n" +
1907                   "    }\n" +
1908                   "}";
1909     String expected_4 = "{\n" +
1910                   "    System.out.println(\"blah1\");\n" +
1911                   "        // indented comment\n" +
1912                   "        System.out.println(\"blah2\");\n" +
1913                   "}";
1914     assertEquals(expected_4, replacer.testReplace(s1_4,s2,replacement,options));
1915   }
1916
1917   public void testReplaceFinalModifier() throws Exception {
1918     String s1 = "class Foo {\n" +
1919                 "  void foo(final int i,final int i2, final int i3) {\n" +
1920                 "     final int x = 5;\n" +
1921                 "  }\n" +
1922                 "}";
1923     String s2 = "final '_type 'var = '_init?;";
1924     String s3 = "$type$ $var$ = $init$;";
1925
1926     String expected = "class Foo {\n" +
1927                       "  void foo(int i, int i2, int i3) {\n" +
1928                       "     int x = 5;\n" +
1929                       "  }\n" +
1930                       "}";
1931
1932     assertEquals(expected, replacer.testReplace(s1,s2,s3,options));
1933   }
1934
1935   public void testRemovingRedundancy() throws Exception {
1936     String s1 = "int a = 1;\n" +
1937                 "a = 2;\n" +
1938                 "int b = a;\n" +
1939                 "b2 = 3;";
1940     String s2 = "int '_a = '_i;\n" +
1941                 "'_st*;\n" +
1942                 "'_a = '_c;";
1943     String s3 = "$st$;\n" +
1944                 "$c$ = $i$;";
1945
1946     String expected = "2 = 1;\nint b = a;\nb2 = 3;";
1947
1948     assertEquals(expected, replacer.testReplace(s1,s2,s3,options));
1949
1950     String s2_2 = "int '_a = '_i;\n" +
1951                   "'_st*;\n" +
1952                   "int '_c = '_a;";
1953     String s3_2 = "$st$;\n" +
1954                   "int $c$ = $i$;";
1955     String expected_2 = "a = 2;\nint b = 1;\nb2 = 3;";
1956
1957     assertEquals(expected_2, replacer.testReplace(s1,s2_2,s3_2,options));
1958   }
1959
1960   public void testReplaceWithEmptyString() {
1961     String source = "public class Peepers {\n    public long serialVersionUID = 1L;    \n}";
1962     String search = "long serialVersionUID = $value$;";
1963     String replace = "";
1964     String expectedResult = "public class Peepers {    \n}";
1965
1966     assertEquals(expectedResult, replacer.testReplace(source, search, replace, options, true));
1967   }
1968
1969   public void testReplaceMultipleFieldsInSingleDeclaration() {
1970     String source = "abstract class MyClass implements java.util.List {\n  private String a, b;\n}";
1971     String search = "class 'Name implements java.util.List {\n  '_ClassContent*\n}";
1972     String replace = "class $Name$ {\n  $ClassContent$\n}";
1973     String expectedResult = "abstract class MyClass {\n  private String a,b;\n}";
1974
1975     assertEquals(expectedResult, replacer.testReplace(source, search, replace, options, true));
1976   }
1977
1978   public void testReplaceInImplementsList() {
1979     String source = "import java.io.Externalizable;\n" +
1980                     "import java.io.Serializable;\n" +
1981                     "abstract class MyClass implements Serializable, java.util.List, Externalizable {}";
1982     String search = "class 'TestCase implements java.util.List, '_others* {\n    '_MyClassContent\n}";
1983     String replace = "class $TestCase$ implements $others$ {\n    $MyClassContent$\n}";
1984     String expectedResult = "import java.io.Externalizable;\n" +
1985                             "import java.io.Serializable;\n" +
1986                             "abstract class MyClass implements Externalizable,Serializable {\n    \n}";
1987
1988     assertEquals(expectedResult, replacer.testReplace(source, search, replace, options, true));
1989   }
1990
1991   public void testReplaceFieldWithEndOfLineComment() {
1992     String source = "class MyClass {\n" +
1993                     "    private String b;// comment\n" +
1994                     "    public void foo() {\n" +
1995                     "    }\n" +
1996                     "}";
1997     String search = "class 'Class {\n    '_Content*\n}";
1998     String replace = "class $Class$ {\n" +
1999                      "    void x() {}\n" +
2000                      "    $Content$\n" +
2001                      "    void bar() {}\n" +
2002                      "}";
2003     String expectedResult = "class MyClass {\n" +
2004                             "    void x() {}\n" +
2005                             "    private String b;// comment\n" +
2006                             "public void foo() {\n" +
2007                             "    }\n" +
2008                             "    void bar() {}\n" +
2009                             "}";
2010
2011     assertEquals(expectedResult, replacer.testReplace(source, search, replace, options, true));
2012   }
2013
2014   public void testReplaceAnnotation() {
2015     String in = "@SuppressWarnings(\"ALL\")\n" +
2016                 "public class A {}";
2017     String what = "@SuppressWarnings(\"ALL\")";
2018
2019     final String by1 = "";
2020     assertEquals("public class A {}", replacer.testReplace(in, what, by1, options, false));
2021
2022     final String by2 = "@SuppressWarnings(\"NONE\") @Deprecated";
2023     assertEquals("@SuppressWarnings(\"NONE\") @Deprecated\n" +
2024                  "public class A {}", replacer.testReplace(in, what, by2, options, false));
2025   }
2026
2027   public void testReplacePolyadicExpression() {
2028     final String in1 = "class A {" +
2029                       "  int i = 1 + 2 + 3;" +
2030                       "}";
2031     final String what1 = "1 + '_a+";
2032
2033     final String by1 = "4";
2034     assertEquals("class A {  int i = 4;}", replacer.testReplace(in1, what1, by1, options, false));
2035
2036     final String by2 = "$a$";
2037     assertEquals("class A {  int i = 2+3;}", replacer.testReplace(in1, what1, by2, options, false));
2038
2039     final String by3 = "$a$+4";
2040     assertEquals("class A {  int i = 2+3+4;}", replacer.testReplace(in1, what1, by3, options, false));
2041
2042     final String what2 = "1 + 2 + 3 + '_a*";
2043     final String by4 = "1 + 3 + $a$";
2044     assertEquals("class A {  int i = 1 + 3;}", replacer.testReplace(in1, what2, by4, options, false));
2045
2046     final String by5 = "$a$ + 1 + 3";
2047     assertEquals("class A {  int i = 1 + 3;}", replacer.testReplace(in1, what2, by5, options, false));
2048
2049     final String by6 = "1 + $a$ + 3";
2050     assertEquals("class A {  int i = 1  + 3;}", replacer.testReplace(in1, what2, by6, options, false));
2051
2052     final String in2 = "class A {" +
2053                        "  boolean b = true && true;" +
2054                        "}";
2055     final String what3 = "true && true && '_a*";
2056     final String by7 = "true && true && $a$";
2057     assertEquals("class A {  boolean b = true && true;}", replacer.testReplace(in2, what3, by7, options, false));
2058
2059     final String by8 = "$a$ && true && true";
2060     assertEquals("class A {  boolean b = true && true;}", replacer.testReplace(in2, what3, by8, options, false));
2061
2062   }
2063
2064   public void testReplaceAssert() {
2065     final String in = "class A {" +
2066                       "  void m(int i) {" +
2067                       "    assert 10 > i;" +
2068                       "  }" +
2069                       "}";
2070
2071     final String what = "assert '_a > '_b : '_c?;";
2072     final String by = "assert $b$ < $a$ : $c$;";
2073     assertEquals("class A {  void m(int i) {    assert i < 10 ;  }}", replacer.testReplace(in, what, by, options, false));
2074   }
2075
2076   public void testReplaceMultipleVariablesInOneDeclaration() {
2077     final String in = "class A {" +
2078                       "  private int i, j, k;" +
2079                       "  void m() {" +
2080                       "    int i,j,k;" +
2081                       "  }" +
2082                       "}";
2083     final String what1 = "int '_i+;";
2084     final String by1 = "float $i$;";
2085     assertEquals("class A {  private float i,j,k;  void m() {    float i,j,k;  }}", replacer.testReplace(in, what1, by1, options));
2086
2087     final String what2 = "int '_a, '_b, '_c = '_d?;";
2088     final String by2 = "float $a$, $b$, $c$ = $d$;";
2089     assertEquals("class A {  private float i, j, k ;  void m() {    float i, j, k ;  }}", replacer.testReplace(in, what2, by2, options));
2090   }
2091
2092   public void testReplaceWithScriptedVariable() {
2093     final String in = "class A {\n" +
2094                       "  void method(Object... os) {}\n" +
2095                       "  void f(Object a, Object b, Object c) {\n" +
2096                       "    method(a, b, c, \"one\" + \"two\");\n" +
2097                       "    method(a);\n" +
2098                       "  }\n" +
2099                       "}";
2100     final String what = "method('_arg+)";
2101     final String by = "method($newarg$)";
2102     final ReplacementVariableDefinition variable = new ReplacementVariableDefinition();
2103     variable.setName("newarg");
2104     variable.setScriptCodeConstraint("arg.collect { \"(String)\" + it.getText() }.join(',')");
2105     options.addVariableDefinition(variable);
2106
2107     final String expected = "class A {\n" +
2108                             "  void method(Object... os) {}\n" +
2109                             "  void f(Object a, Object b, Object c) {\n" +
2110                             "    method((String)a,(String)b,(String)c,(String)\"one\" + \"two\");\n" +
2111                             "    method((String)a);\n" +
2112                             "  }\n" +
2113                             "}";
2114     assertEquals(expected, replacer.testReplace(in, what, by, options));
2115
2116     options.clearVariableDefinitions();
2117   }
2118
2119   public void testMethodContentReplacement() {
2120     final String in = "class A extends TestCase {\n" +
2121                       "  void testOne() {\n" +
2122                       "    System.out.println();\n" +
2123                       "  }\n" +
2124                       "}\n";
2125     final String what = "class '_A { void '_b:[regex( test.* )](); }";
2126     final String by = "class $A$ {\n  @java.lang.Override void $b$();\n}";
2127     assertEquals("class A extends TestCase {\n" +
2128                  "  @Override void testOne() {\n" +
2129                  "    System.out.println();\n" +
2130                  "  }\n" +
2131                  "}\n", replacer.testReplace(in, what, by, options));
2132
2133     final String what2 = "void '_a:[regex( test.* )]();";
2134     final String by2 = "@org.junit.Test void $a$();";
2135     assertEquals("class A extends TestCase {\n" +
2136                  "  @org.junit.Test void testOne() {\n" +
2137                  "    System.out.println();\n" +
2138                  "  }\n" +
2139                  "}\n",
2140                  replacer.testReplace(in, what2, by2, options));
2141   }
2142
2143   public void testReplaceMethodWithoutBody() {
2144     final String in = "abstract class A {\n" +
2145                       "  abstract void a();\n" +
2146                       "}";
2147     final String what = "void '_a();";
2148     final String by = "void $a$(int i);";
2149     assertEquals("abstract class A {\n" +
2150                  "  abstract void a(int i);\n" +
2151                  "}",
2152                  replacer.testReplace(in, what, by, options));
2153   }
2154
2155   public void testReplaceParameterWithComment() {
2156     final String in = "class A {\n" +
2157                       "  void a(int b) {}\n" +
2158                       "}";
2159     final String what = "int '_a = '_b{0,1};";
2160     final String by = "final long /*!*/ $a$ = $b$;";
2161     assertEquals("class A {\n" +
2162                  "  void a(final long /*!*/ b) {}\n" +
2163                  "}",
2164                  replacer.testReplace(in, what, by, options));
2165   }
2166
2167   public void testReplaceInnerClass() {
2168     String in = "public class A {\n" +
2169                  "  public class B<T> extends A implements java.io.Serializable {}\n" +
2170                  "}";
2171     String what = "class '_A {" +
2172                    "  class '_B {}" +
2173                    "}";
2174     String by = "class $A$ {\n" +
2175                  "  private class $B$ {\n" +
2176                  "  }\n" +
2177                  "}";
2178     assertEquals("public class A {\n" +
2179                  "  private class B<T> extends A implements java.io.Serializable {\n" +
2180                  "  }\n" +
2181                  "}",
2182                  replacer.testReplace(in, what, by, options));
2183
2184     String in2 = "public class A {\n" +
2185                  "  void m1() {}\n" +
2186                  "  public void m2() {}\n" +
2187                  "  public class B<T> extends A implements java.io.Serializable {\n" +
2188                  "    int zero() {\n" +
2189                  "      return 0;\n" +
2190                  "    }\n" +
2191                  "  }\n" +
2192                  "  void m3() {}\n" +
2193                  "}";
2194     assertEquals("should replace unmatched class content correctly",
2195                  "public class A {\n" +
2196                  "  void m1() {}\n" +
2197                  "  public void m2() {}\n" +
2198                  "  private class B<T> extends A implements java.io.Serializable {\n" +
2199                  "    int zero() {\n" +
2200                  "      return 0;\n" +
2201                  "    }\n" +
2202                  "  }\n" +
2203                  "  void m3() {}\n" +
2204                  "}",
2205                  replacer.testReplace(in2, what, by, options));
2206   }
2207
2208   public void testReplaceQualifiedReference() {
2209     String in = "class A {" +
2210                 "  String s;" +
2211                 "  void setS(String s) {" +
2212                 "    System.out.println(this.s);" +
2213                 "    this.s = s;" +
2214                 "  }" +
2215                 "}";
2216     String what = "System.out.println('_a);";
2217     String by = "System.out.println(\"$a$\" + $a$);";
2218     assertEquals("don't drop this",
2219                  "class A {" +
2220                  "  String s;" +
2221                  "  void setS(String s) {" +
2222                  "    System.out.println(\"this.s\" + this.s);" +
2223                  "    this.s = s;" +
2224                  "  }" +
2225                  "}",
2226                  replacer.testReplace(in, what, by, options));
2227   }
2228 }