extract method: shorten qualified names for new return type (IDEA-155518)
[idea/community.git] / java / java-tests / testSrc / com / intellij / refactoring / ExtractMethodTest.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.refactoring;
17
18 import com.intellij.JavaTestUtil;
19 import com.intellij.codeInsight.CodeInsightUtil;
20 import com.intellij.lang.java.JavaLanguage;
21 import com.intellij.openapi.application.ApplicationManager;
22 import com.intellij.openapi.editor.Editor;
23 import com.intellij.openapi.project.Project;
24 import com.intellij.psi.*;
25 import com.intellij.psi.codeStyle.CodeStyleSettings;
26 import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
27 import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
28 import com.intellij.psi.search.GlobalSearchScope;
29 import com.intellij.psi.util.PsiTreeUtil;
30 import com.intellij.refactoring.extractMethod.ExtractMethodHandler;
31 import com.intellij.refactoring.extractMethod.ExtractMethodProcessor;
32 import com.intellij.refactoring.extractMethod.PrepareFailedException;
33 import com.intellij.refactoring.introduceVariable.IntroduceVariableBase;
34 import com.intellij.refactoring.util.duplicates.Match;
35 import com.intellij.testFramework.LightCodeInsightTestCase;
36 import com.intellij.util.IncorrectOperationException;
37 import org.jetbrains.annotations.NonNls;
38 import org.jetbrains.annotations.NotNull;
39
40 import java.util.List;
41
42 public class ExtractMethodTest extends LightCodeInsightTestCase {
43   @NonNls private static final String BASE_PATH = "/refactoring/extractMethod/";
44   private boolean myCatchOnNewLine = true;
45
46   @NotNull
47   @Override
48   protected String getTestDataPath() {
49     return JavaTestUtil.getJavaTestDataPath();
50   }
51
52   public void testExitPoints1() throws Exception {
53     doExitPointsTest(true);
54   }
55
56   public void testExitPoints2() throws Exception {
57     doTest();
58   }
59
60   public void testExitPoints3() throws Exception {
61     doExitPointsTest(true);
62   }
63
64   public void testExitPoints4() throws Exception {
65     doTest();
66   }
67
68   public void testExitPoints4Nullable() throws Exception {
69     doExitPointsTest(false);
70   }
71
72   public void testExitPointsInsideLoop() throws Exception {
73     doExitPointsTest(true);
74   }
75
76   public void testExitPoints5() throws Exception {
77     doTest();
78   }
79
80   public void testExitPoints6() throws Exception {
81     doExitPointsTest(false);
82   }
83
84   public void testExitPoints7() throws Exception {
85     doExitPointsTest(false);
86   }
87
88   public void testExitPoints8() throws Exception {
89     doTest();
90   }
91
92   public void testExitPoints9() throws Exception {
93     doTest();
94   }
95
96   public void testNotNullCheckNameConflicts() throws Exception {
97     doTest();
98   }
99
100   public void testContinueInside() throws Exception {
101     doTest();
102   }
103
104   public void testBooleanExpression() throws Exception {
105     doTest();
106   }
107
108   public void testScr6241() throws Exception {
109     doTest();
110   }
111
112   public void testScr7091() throws Exception {
113     doTest();
114   }
115
116   public void testScr10464() throws Exception {
117     doTest();
118   }
119
120   public void testScr9852() throws Exception {
121     doTest();
122   }
123
124   public void testUseVarAfterTry() throws Exception {
125     doTest();
126   }
127
128   public void testOneBranchAssignment() throws Exception {
129     doTest();
130   }
131
132   public void testExtractFromCodeBlock() throws Exception {
133     doTest();
134   }
135
136   public void testUnusedInitializedVar() throws Exception {
137     doTest();
138   }
139
140   public void testTryFinally() throws Exception {
141     doTest();
142   }
143
144   public void testFinally() throws Exception {
145     doTest();
146   }
147
148   public void testExtractFromAnonymous() throws Exception {
149     doTest();
150   }
151
152   public void testSCR12245() throws Exception {
153     doTest();
154   }
155
156   public void testLeaveCommentsWhenExpressionExtracted() throws Exception {
157     doTest();
158   }
159
160   public void testSCR15815() throws Exception {
161     doTest();
162   }
163
164   public void testSCR27887() throws Exception {
165     doTest();
166   }
167
168   public void testSCR28427() throws Exception {
169     doTest();
170   }
171
172   public void testTryFinallyInsideFor() throws Exception {
173     doTest();
174   }
175
176   public void testExtractFromTryFinally() throws Exception {
177     doTest();
178   }
179
180   public void testExtractAssignmentExpression() throws Exception {
181     doTest();
182   }
183
184   public void testExtractAssignmentExpressionFromStatement() throws Exception {
185     doTest();
186   }
187
188   public void _testExtractFromTryFinally2() throws Exception {  // IDEADEV-11844
189     doTest();
190   }
191
192   public void testLesyaBug() throws Exception {
193     myCatchOnNewLine = false;
194     doTest();
195   }
196
197   public void testForEach() throws Exception {
198     doTest();
199   }
200
201   public void testAnonInner() throws Exception {
202     doTest();
203   }
204
205
206   public void testConflictingAnonymous() throws Exception {
207     doTest();
208   }
209
210   public void testVarDeclAfterExpressionExtraction() throws Exception {
211     doTest();
212   }
213
214   public void testFinalParamUsedInsideAnon() throws Exception {
215     CodeStyleSettingsManager.getSettings(getProject()).GENERATE_FINAL_PARAMETERS = false;
216     doTest();
217   }
218
219   public void testNonFinalWritableParam() throws Exception {
220     CodeStyleSettingsManager.getSettings(getProject()).GENERATE_FINAL_PARAMETERS = true;
221     doTest();
222   }
223
224   public void testCodeDuplicatesWithContinue() throws Exception {
225     doDuplicatesTest();
226   }
227
228   public void testDuplicatesFromAnonymous() throws Exception {
229     doDuplicatesTest();
230   }
231
232   public void testCodeDuplicatesWithContinueNoReturn() throws Exception {
233     doDuplicatesTest();
234   }
235
236   public void testCodeDuplicatesWithStaticInitializer() throws Exception {
237     doDuplicatesTest();
238   }
239
240   public void testDuplicateInUnreachableCode() throws Exception {
241     doDuplicatesTest();
242   }
243
244   public void testExpressionDuplicates() throws Exception {
245     doDuplicatesTest();
246   }
247
248   public void testCodeDuplicates() throws Exception {
249     doDuplicatesTest();
250   }
251
252   public void testCodeDuplicates2() throws Exception {
253     doDuplicatesTest();
254   }
255
256   public void testCodeDuplicates3() throws Exception {
257     doDuplicatesTest();
258   }
259
260   public void testCodeDuplicates4() throws Exception {
261     doDuplicatesTest();
262   }
263
264   public void testCodeDuplicates5() throws Exception {
265     doDuplicatesTest();
266   }
267
268   public void testCodeDuplicatesWithOutputValue() throws Exception {
269     doDuplicatesTest();
270   }
271
272   public void testCodeDuplicatesWithOutputValue1() throws Exception {
273     doDuplicatesTest();
274   }
275
276   public void testCodeDuplicatesWithMultExitPoints() throws Exception {
277     doDuplicatesTest();
278   }
279
280   public void testCodeDuplicatesWithReturn() throws Exception {
281     doDuplicatesTest();
282   }
283
284   public void testCodeDuplicatesWithReturn2() throws Exception {
285     doDuplicatesTest();
286   }
287
288   public void testCodeDuplicatesWithReturnInAnonymous() throws Exception {
289     doDuplicatesTest();
290   }
291
292   public void testCodeDuplicatesWithComments() throws Exception {
293     doDuplicatesTest();
294   }
295
296   public void testSCR32924() throws Exception {
297     doDuplicatesTest();
298   }
299
300   public void testFinalOutputVar() throws Exception {
301     doDuplicatesTest();
302   }
303
304   public void testIdeaDev2291() throws Exception {
305     doTest();
306   }
307
308   public void testOxfordBug() throws Exception {
309     doTest();
310   }
311
312   public void testIDEADEV33368() throws Exception {
313     doTest();
314   }
315
316   public void testInlineCreated2ReturnLocalVariablesOnly() throws Exception {
317     doTest();
318   }
319
320   public void testGuardMethodDuplicates() throws Exception {
321     doDuplicatesTest();
322   }
323
324   public void testGuardMethodDuplicates1() throws Exception {
325     doDuplicatesTest();
326   }
327
328   public void testInstanceMethodDuplicatesInStaticContext() throws Exception {
329     doDuplicatesTest();
330   }
331
332
333   public void testLValueNotDuplicate() throws Exception {
334     doDuplicatesTest();
335   }
336
337   protected void doDuplicatesTest() throws Exception {
338     doTest(true);
339   }
340
341   public void testExtractFromFinally() throws Exception {
342     doTest();
343   }
344
345   public void testNoShortCircuit() throws Exception {
346     doTest();
347   }
348
349   public void testStopFolding() throws Exception {
350     doTest();
351   }
352
353   public void testStopFoldingPostfixInside() throws Exception {
354     doTest();
355   }
356
357   public void testFoldingWithFieldInvolved() throws Exception {
358     doTest();
359   }
360
361   public void testIDEADEV11748() throws Exception {
362     doTest();
363   }
364
365   public void testIDEADEV11848() throws Exception {
366     doTest();
367   }
368
369   public void testIDEADEV11036() throws Exception {
370     doTest();
371   }
372
373   public void testLocalClass() throws Exception {
374     doPrepareErrorTest("Cannot extract method because the selected code fragment uses local classes defined outside of the fragment");
375   }
376
377   public void testLocalClassUsage() throws Exception {
378     doPrepareErrorTest("Cannot extract method because the selected code fragment defines local classes used outside of the fragment");
379   }
380
381   public void testStaticImport() throws Exception {
382     doTest();
383   }
384
385   public void testThisCall() throws Exception {
386     doTest();
387   }
388
389   public void testChainedConstructor() throws Exception {
390     doChainedConstructorTest(false);
391   }
392
393   public void testChainedConstructorDuplicates() throws Exception {
394     doChainedConstructorTest(true);
395   }
396
397   public void testChainedConstructorInvalidDuplicates() throws Exception {
398     doChainedConstructorTest(true);
399   }
400
401   public void testReturnFromTry() throws Exception {
402     doTest();
403   }
404
405   public void testLocalClassDefinedInMethodWhichIsUsedLater() throws Exception {
406     doPrepareErrorTest("Cannot extract method because the selected code fragment defines variable of local class type used outside of the fragment");
407   }
408
409   public void testForceBraces() throws Exception {
410     final CommonCodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject()).getCommonSettings(JavaLanguage.INSTANCE);
411     int old = settings.IF_BRACE_FORCE;
412     settings.IF_BRACE_FORCE = CommonCodeStyleSettings.FORCE_BRACES_ALWAYS;
413     try {
414       doTest();
415     }
416     finally {
417       settings.IF_BRACE_FORCE = old;
418     }
419   }
420
421   public void testConstantConditionsAffectingControlFlow() throws Exception {
422     doTest();
423   }
424
425   public void testConstantConditionsAffectingControlFlow1() throws Exception {
426     doTest();
427   }
428   public void testNotInitializedInsideFinally() throws Exception {
429     doTest();
430   }
431
432   public void testGenericsParameters() throws Exception {
433     doTest();
434   }
435
436   public void testUnusedGenerics() throws Exception {
437     doTest();
438   }
439
440   public void testParamsUsedInLocalClass() throws Exception {
441     doTest();
442   }
443
444   private void doChainedConstructorTest(final boolean replaceAllDuplicates) throws Exception {
445     configureByFile(BASE_PATH + getTestName(false) + ".java");
446     boolean success = performExtractMethod(true, replaceAllDuplicates, getEditor(), getFile(), getProject(), true);
447     assertTrue(success);
448     checkResultByFile(BASE_PATH + getTestName(false) + "_after.java");
449   }
450
451   public void testReassignedVarAfterCall() throws Exception {
452     final CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject());
453     boolean oldGenerateFinalLocals = settings.GENERATE_FINAL_LOCALS;
454     try {
455       settings.GENERATE_FINAL_LOCALS = true;
456       doTest();
457     }
458     finally {
459       settings.GENERATE_FINAL_LOCALS = oldGenerateFinalLocals;
460     }
461   }
462
463   public void testNonPhysicalAssumptions() throws Exception {
464     doTest();
465   }
466
467   public void testNullableCheck() throws Exception {
468     doTest();
469   }
470   
471   public void testNullableCheck1() throws Exception {
472     doTest();
473   }
474
475   public void testNullableCheckVoid() throws Exception {
476     doTest();
477   }
478
479   public void testNullableCheckDontMissFinal() throws Exception {
480     doTest();
481   }
482
483   public void testNullableCheckBreak() throws Exception {
484     doTest();
485   }
486
487   public void testSimpleArrayAccess() throws Exception {
488     doTest();
489   }
490
491   public void testArrayAccess() throws Exception {
492     doTest();
493   }
494
495   public void testArrayAccess1() throws Exception {
496     doTest();
497   }
498
499   public void testArrayAccessWithLocalIndex() throws Exception {
500     doTest();
501   }
502
503   public void testArrayAccessWithTopExpression() throws Exception {
504     doTest();
505   }
506
507   public void testArrayAccessWithDuplicates() throws Exception {
508     doDuplicatesTest();
509   }
510
511   public void testVerboseArrayAccess() throws Exception {
512     doTest();
513   }
514
515   public void testReturnStatementFolding() throws Exception {
516     doTest();
517   }
518
519   public void testWriteArrayAccess() throws Exception {
520     doTest();
521   }
522
523   public void testShortCircuit() throws Exception {
524     doTest();
525   }
526
527   public void testRecursiveCallToExtracted() throws Exception {
528     doTest();
529   }
530
531   public void testCodeDuplicatesVarargsShouldNotChangeReturnType() throws Exception {
532     doDuplicatesTest();
533   }
534
535   public void testParametersFromAnonymous() throws Exception {
536     doTest();
537   }
538
539   public void testCast4ParamGeneration() throws Exception {
540     doTest();
541   }
542
543   public void testNearComment() throws Exception {
544     doTest();
545   }
546
547   public void testFoldInWhile() throws Exception {
548     doTest();
549   }
550
551   public void testFoldedParamNameSuggestion() throws Exception {
552     doTest();
553   }
554
555   public void testNonFoldInIfBody() throws Exception {
556     doTest();
557   }
558
559   public void testComplexTypeParams() throws Exception {
560     doTest();
561   }
562
563   public void testExtractWithLeadingComment() throws Exception {
564     doTest();
565   }
566
567   public void testInvalidReference() throws Exception {
568     doTest();
569   }
570
571   public void testRedundantCast() throws Exception {
572     doTest();
573   }
574   
575   public void testDisabledParam() throws Exception {
576     doTestDisabledParam();
577   } 
578
579   public void testTypeParamsList() throws Exception {
580     doTest();
581   }
582
583   public void testFromLambdaBody() throws Exception {
584     doTest();
585   }
586
587   public void testFromLambdaBody1() throws Exception {
588     doTest();
589   }
590
591   public void testFromLambdaBodyToAnonymous() throws Exception {
592     doTest();
593   }
594   
595   public void testFromLambdaBodyToToplevelInsideCodeBlock() throws Exception {
596     doTest();
597   }
598
599   public void testFromLambdaBodyWithReturn() throws Exception {
600     doTest();
601   }
602
603   public void testOneLineLambda() throws Exception {
604     doTest();
605   }
606
607   public void testMethod2Interface() throws Exception {
608     doTest();
609   }
610   
611   public void testMethod2InterfaceFromStatic() throws Exception {
612     doTest();
613   }
614
615   public void testMethod2InterfaceFromConstant() throws Exception {
616     doTest();
617   }
618
619   public void testParamDetection() throws Exception {
620     doTest();
621   }
622
623   public void testSkipComments() throws Exception {
624     doTest();
625   }
626
627   public void testFinalParams4LocalClasses() throws Exception {
628     doTest();
629   }
630
631   public void testIncompleteExpression() throws Exception {
632     doTest();
633   }
634
635   public void testTwoFromThreeEqStatements() throws Exception {
636     doDuplicatesTest();
637   }
638
639   public void testCastWhenDuplicateReplacement() throws Exception {
640     doDuplicatesTest();
641   }
642
643   public void testCheckQualifierMapping() throws Exception {
644     doDuplicatesTest();
645   }
646
647   public void testArrayReturnType() throws Exception {
648     doDuplicatesTest();
649   }
650
651   public void testOverloadedMethods() throws Exception {
652     doDuplicatesTest();
653   }
654
655   public void testSuggestChangeSignatureOneParam() throws Exception {
656     doDuplicatesTest();
657   }
658
659   public void testSuggestChangeSignatureOneParamMultipleTimesInside() throws Exception {
660     doDuplicatesTest();
661   }
662
663   public void testSuggestChangeSignatureLeaveSameExpressionsUntouched() throws Exception {
664     doDuplicatesTest();
665   }
666
667   public void testSuggestChangeSignatureSameParamNames() throws Exception {
668     doDuplicatesTest();
669   }
670
671   public void testSuggestChangeSignatureCallToSameClassMethod() throws Exception {
672     doDuplicatesTest();
673   }
674
675   public void testSuggestChangeSignatureInitialParameterUnused() throws Exception {
676     doDuplicatesTest();
677   }
678
679   public void testSuggestChangeSignatureWithFolding() throws Exception {
680     doDuplicatesTest();
681   }
682
683   public void testSuggestChangeSignatureWithOutputVariables() throws Exception {
684     doDuplicatesTest();
685   }
686
687   public void testSuggestChangeSignatureWithChangedParameterName() throws Exception {
688     configureByFile(BASE_PATH + getTestName(false) + ".java");
689     boolean success = performExtractMethod(true, true, getEditor(), getFile(), getProject(), false, null, false, "p");
690     assertTrue(success);
691     checkResultByFile(BASE_PATH + getTestName(false) + "_after.java");
692   }
693
694   public void testTargetAnonymous() throws Exception {
695     doTest();
696   }
697
698   public void testExtractUnresolvedLambdaParameter() throws Exception {
699     doTest();
700   }
701
702   public void testExtractUnresolvedLambdaExpression() throws Exception {
703     doTest();
704   }
705
706   public void testTheOnlyParenthesisExpressionWhichIsSkippedInControlFlow() throws Exception {
707     doTest();
708   }
709
710   public void testExpression() throws Exception {
711     doTest();
712   }
713
714   public void testCopyParamAnnotations() throws Exception {
715     doTest();
716   }
717
718   public void testInferredNotNullInReturnStatement() throws Exception {
719     doTest();
720   }
721
722   public void testSkipThrowsDeclaredInLambda() throws Exception {
723     doTest();
724   }
725
726   public void testChangedReturnType() throws Exception {
727     doTestReturnTypeChanged(PsiType.getJavaLangObject(getPsiManager(), GlobalSearchScope.allScope(getProject())));
728   }
729
730   public void testMakeVoidMethodReturnVariable() throws Exception {
731     doTestReturnTypeChanged(PsiType.INT);
732   }
733
734   public void testNoReturnTypesSuggested() throws Exception {
735     doTestReturnTypeChanged(PsiType.INT);
736   }
737
738   public void testMultipleVarsInMethodNoReturnStatementAndAssignment() throws Exception {
739     //return type should not be suggested but still 
740     doTestReturnTypeChanged(PsiType.INT);
741   }
742
743   public void testReassignFinalFieldInside() throws Exception {
744     doTestReturnTypeChanged(PsiType.INT);
745   }
746
747   public void testShortenClassRefsInNewReturnType() throws Exception {
748     doTestReturnTypeChanged(PsiType.getTypeByName(CommonClassNames.JAVA_UTIL_COLLECTION, getProject(), GlobalSearchScope.allScope(getProject())));
749   }
750
751   public void testPassFieldAsParameterAndMakeStatic() throws Exception {
752     doTestPassFieldsAsParams();
753   }
754
755   public void testDefaultNamesConflictResolution() throws Exception {
756     final CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject());
757     final String oldPrefix = settings.LOCAL_VARIABLE_NAME_PREFIX;
758     try {
759       settings.LOCAL_VARIABLE_NAME_PREFIX = "_";
760       doTest();
761     }
762     finally {
763       settings.LOCAL_VARIABLE_NAME_PREFIX = oldPrefix;
764     }
765   }
766
767   public void testInferredNotNull() throws Exception {
768     doTest();
769   }
770
771   public void testCantPassFieldAsParameter() throws Exception {
772     try {
773       doTestPassFieldsAsParams();
774       fail("Field was modified inside. Make static should be disabled");
775     }
776     catch (PrepareFailedException ignore) {
777     }
778   }
779
780   public void testConditionalExitCombinedWithNullabilityShouldPreserveVarsUsedInExitStatements() throws Exception {
781     doTest();
782   }
783
784   public void testSingleExitPOintWithTryFinally() throws Exception {
785     doTest();
786   }
787
788   public void testQualifyWhenConflictingNamePresent() throws Exception {
789     final CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject());
790     settings.ELSE_ON_NEW_LINE = true;
791     settings.CATCH_ON_NEW_LINE = myCatchOnNewLine;
792     configureByFile(BASE_PATH + getTestName(false) + ".java");
793     final PsiClass psiClass = PsiTreeUtil.getParentOfType(getFile().findElementAt(getEditor().getSelectionModel().getLeadSelectionOffset()), PsiClass.class);
794     assertNotNull(psiClass);
795     boolean success = performExtractMethod(true, true, getEditor(), getFile(), getProject(), false, null, false, null, psiClass.getContainingClass());
796     assertTrue(success);
797     checkResultByFile(BASE_PATH + getTestName(false) + "_after.java");
798   }
799
800   private void doTestDisabledParam() throws PrepareFailedException {
801     final CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject());
802     settings.ELSE_ON_NEW_LINE = true;
803     settings.CATCH_ON_NEW_LINE = myCatchOnNewLine;
804     configureByFile(BASE_PATH + getTestName(false) + ".java");
805     boolean success = performExtractMethod(true, true, getEditor(), getFile(), getProject(), false, 0);
806     assertTrue(success);
807     checkResultByFile(BASE_PATH + getTestName(false) + "_after.java");
808   }
809
810   private void doTestReturnTypeChanged(PsiType type) throws PrepareFailedException {
811     final CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject());
812     settings.ELSE_ON_NEW_LINE = true;
813     settings.CATCH_ON_NEW_LINE = myCatchOnNewLine;
814     configureByFile(BASE_PATH + getTestName(false) + ".java");
815     boolean success = performExtractMethod(true, true, getEditor(), getFile(), getProject(), false, type, false, null);
816     assertTrue(success);
817     checkResultByFile(BASE_PATH + getTestName(false) + "_after.java");
818   }
819
820   private void doTestPassFieldsAsParams() throws PrepareFailedException {
821     final CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject());
822     settings.ELSE_ON_NEW_LINE = true;
823     settings.CATCH_ON_NEW_LINE = myCatchOnNewLine;
824     configureByFile(BASE_PATH + getTestName(false) + ".java");
825     boolean success = performExtractMethod(true, true, getEditor(), getFile(), getProject(), false, null, true, null);
826     assertTrue(success);
827     checkResultByFile(BASE_PATH + getTestName(false) + "_after.java");
828   }
829
830   private void doPrepareErrorTest(final String expectedMessage) throws Exception {
831     String expectedError = null;
832     try {
833       doExitPointsTest(false);
834     }
835     catch(PrepareFailedException ex) {
836       expectedError = ex.getMessage();
837     }
838     assertEquals(expectedMessage, expectedError);
839   }
840
841   private void doExitPointsTest(boolean shouldSucceed) throws Exception {
842     String fileName = getTestName(false) + ".java";
843     configureByFile(BASE_PATH + fileName);
844     boolean success = performAction(false, false);
845     assertEquals(shouldSucceed, success);
846   }
847
848   void doTest() throws Exception {
849     final CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject());
850     settings.ELSE_ON_NEW_LINE = true;
851     settings.CATCH_ON_NEW_LINE = myCatchOnNewLine;
852     doTest(true);
853   }
854
855   private void doTest(boolean duplicates) throws Exception {
856     configureByFile(BASE_PATH + getTestName(false) + ".java");
857     boolean success = performAction(true, duplicates);
858     assertTrue(success);
859     checkResultByFile(BASE_PATH + getTestName(false) + "_after.java");
860   }
861
862   private static boolean performAction(boolean doRefactor, boolean replaceAllDuplicates) throws Exception {
863     return performExtractMethod(doRefactor, replaceAllDuplicates, getEditor(), getFile(), getProject());
864   }
865
866   public static boolean performExtractMethod(boolean doRefactor, boolean replaceAllDuplicates, Editor editor, PsiFile file, Project project)
867     throws PrepareFailedException, IncorrectOperationException {
868     return performExtractMethod(doRefactor, replaceAllDuplicates, editor, file, project, false);
869   }
870
871   public static boolean performExtractMethod(boolean doRefactor, boolean replaceAllDuplicates, Editor editor, PsiFile file, Project project,
872                                              final boolean extractChainedConstructor)
873     throws PrepareFailedException, IncorrectOperationException {
874     return performExtractMethod(doRefactor, replaceAllDuplicates, editor, file, project, extractChainedConstructor, null);
875   }
876
877   public static boolean performExtractMethod(boolean doRefactor,
878                                              boolean replaceAllDuplicates,
879                                              Editor editor,
880                                              PsiFile file,
881                                              Project project,
882                                              final boolean extractChainedConstructor,
883                                              int... disabledParams)
884     throws PrepareFailedException, IncorrectOperationException {
885     return performExtractMethod(doRefactor, replaceAllDuplicates, editor, file, project, extractChainedConstructor, null, false, null, disabledParams);
886   }
887
888   public static boolean performExtractMethod(boolean doRefactor,
889                                              boolean replaceAllDuplicates,
890                                              Editor editor,
891                                              PsiFile file,
892                                              Project project,
893                                              final boolean extractChainedConstructor,
894                                              PsiType returnType,
895                                              boolean makeStatic,
896                                              String newNameOfFirstParam,
897                                              int... disabledParams)
898     throws PrepareFailedException, IncorrectOperationException {
899     return performExtractMethod(doRefactor, replaceAllDuplicates, editor, file, project, extractChainedConstructor, returnType, makeStatic,
900                                 newNameOfFirstParam, null, disabledParams);
901   }
902
903   public static boolean performExtractMethod(boolean doRefactor,
904                                              boolean replaceAllDuplicates,
905                                              Editor editor,
906                                              PsiFile file,
907                                              Project project,
908                                              final boolean extractChainedConstructor,
909                                              PsiType returnType,
910                                              boolean makeStatic,
911                                              String newNameOfFirstParam,
912                                              PsiClass targetClass,
913                                              int... disabledParams)
914     throws PrepareFailedException, IncorrectOperationException {
915     int startOffset = editor.getSelectionModel().getSelectionStart();
916     int endOffset = editor.getSelectionModel().getSelectionEnd();
917
918     PsiElement[] elements;
919     PsiExpression expr = CodeInsightUtil.findExpressionInRange(file, startOffset, endOffset);
920     if (expr != null) {
921       elements = new PsiElement[]{expr};
922     }
923     else {
924       elements = CodeInsightUtil.findStatementsInRange(file, startOffset, endOffset);
925     }
926     if (elements.length == 0) {
927       final PsiExpression expression = IntroduceVariableBase.getSelectedExpression(project, file, startOffset, endOffset);
928       if (expression != null) {
929         elements = new PsiElement[]{expression};
930       }
931     }
932     assertTrue(elements.length > 0);
933
934     final ExtractMethodProcessor processor =
935       new ExtractMethodProcessor(project, editor, elements, null, "Extract Method", "newMethod", null);
936     processor.setShowErrorDialogs(false);
937     processor.setChainedConstructor(extractChainedConstructor);
938
939     if (!processor.prepare()) {
940       return false;
941     }
942
943     if (doRefactor) {
944       processor.testTargetClass(targetClass);
945       processor.testPrepare(returnType, makeStatic);
946       processor.testNullness();
947       if (disabledParams != null) {
948         for (int param : disabledParams) {
949           processor.doNotPassParameter(param);
950         }
951       }
952       if (newNameOfFirstParam != null) {
953         processor.changeParamName(0, newNameOfFirstParam);
954       }
955       ExtractMethodHandler.run(project, editor, processor);
956     }
957
958     if (replaceAllDuplicates) {
959       final Boolean hasDuplicates = processor.hasDuplicates();
960       if (hasDuplicates == null || hasDuplicates.booleanValue()) {
961         final List<Match> duplicates = processor.getDuplicates();
962         for (final Match match : duplicates) {
963           if (!match.getMatchStart().isValid() || !match.getMatchEnd().isValid()) continue;
964           PsiDocumentManager.getInstance(project).commitAllDocuments();
965           ApplicationManager.getApplication().runWriteAction(new Runnable() {
966             @Override
967             public void run() {
968               processor.processMatch(match);
969             }
970           });
971         }
972       }
973     }
974
975     return true;
976   }
977 }