get rid of intellij.build.toolbox.litegen parameter and use BuildOptions.TOOLBOX_LITE...
[idea/community.git] / java / java-tests / testSrc / com / intellij / java / refactoring / inline / InlineMethodTest.java
1 /*
2  * Copyright 2000-2017 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.java.refactoring.inline;
17
18 import com.intellij.JavaTestUtil;
19 import com.intellij.codeInsight.TargetElementUtil;
20 import com.intellij.java.refactoring.LightRefactoringTestCase;
21 import com.intellij.openapi.projectRoots.Sdk;
22 import com.intellij.pom.java.LanguageLevel;
23 import com.intellij.psi.*;
24 import com.intellij.refactoring.BaseRefactoringProcessor;
25 import com.intellij.refactoring.MockInlineMethodOptions;
26 import com.intellij.refactoring.inline.InlineMethodProcessor;
27 import com.intellij.refactoring.inline.InlineOptions;
28 import com.intellij.refactoring.util.InlineUtil;
29 import com.intellij.testFramework.IdeaTestUtil;
30 import org.jetbrains.annotations.NonNls;
31 import org.jetbrains.annotations.NotNull;
32
33 public class InlineMethodTest extends LightRefactoringTestCase {
34   @NotNull
35   @Override
36   protected String getTestDataPath() {
37     return JavaTestUtil.getJavaTestDataPath();
38   }
39
40   public void testInlineParms() {
41     doTest();
42   }
43
44   public void testInlineWithQualifier() {
45     doTest();
46   }
47
48   public void testInlineWithQualifierFromSuper() { doTest(); }
49   public void testTry() {
50     doTest();
51   }
52
53   public void testTrySynchronized() {
54     doTest();
55   }
56
57   public void testStaticSynchronized() {
58     doTest();
59   }
60
61   public void testSuperInsideHierarchy() {
62     doTest();
63   }
64
65   public void testSideEffect() { doTest(); }
66
67   public void testInlineWithTry() { doTest(); }
68
69   public void testVoidWithReturn() { doTest(); }
70   public void testVoidWithReturn1() { doTest(); }
71
72   public void testScr10884() {
73     doTest();
74   }
75   public void testFinalParameters() { doTest(); }
76   public void testFinalParameters1() { doTest(); }
77
78   public void testScr13831() { doTest(); }
79
80   public void testNameClash() { doTest(); }
81
82   public void testArrayAccess() { doTest(); }
83
84   public void testConflictingField() { doTest(); }
85
86   public void testCallInFor() { doTest(); }
87
88   public void testSCR20655() { doTest(); }
89   public void testGenericArrayCreation() { doTest(); }
90
91
92   public void testFieldInitializer() { doTest(); }
93
94   public void testMethodCallInOtherAnonymousOrInner() { doTest(); }
95
96   public void testStaticFieldInitializer() { doTest(); }
97   public void testSCR22644() { doTest(); }
98   public void testChangeContextForThisInNestedClasses() { doTest(); }
99
100   public void testCallUnderIf() { doTest(); }
101   public void testInlineEnumArgsChangeContext() { doTest(); }
102
103   //This gives extra 'result' local variable, currently I don't see a way to cope with it, todo: think about addional inline possibilities
104   //public void testLocalVariableResult() throws Exception { doTest(); }
105
106   public void testSCR31093() { doTest(); }
107
108   public void testSCR37742() { doTest(); }
109   
110   public void testChainingConstructor() { doTest(); }
111
112   public void testChainingConstructor1() {
113     BaseRefactoringProcessor.ConflictsInTestsException.withIgnoredConflicts(()->doTest());
114   }
115
116   public void testNestedCall() { doTest(); }
117
118   public void testIDEADEV3672() { doTest(); }
119
120   public void testIDEADEV5806() { doTest(); }
121
122   public void testIDEADEV6807() { doTest(); }
123
124   public void testIDEADEV12616() { doTest(); }
125
126   public void testVarargs() { doTest(); }
127
128   public void testVarargs1() { doTest(); }
129
130   public void testFlatVarargs() {doTest();}
131   public void testFlatVarargs1() {doTest();}
132
133   public void testEnumConstructor() { doTest(); }
134
135   public void testEnumConstantConstructorParameter() {  // IDEADEV-26133
136     doTest(); 
137   }
138
139   public void testEnumConstantConstructorParameterComplex() {  // IDEADEV-26133
140     doTest();
141   }
142
143   public void testEnumConstantConstructorParameterComplex2() {  // IDEADEV-26133
144     doTest();
145   }
146
147   public void testEnumConstantConstructorParameterNestedLambda() {
148     doTest();
149   }
150
151   public void testEnumConstantConstructorWithArgs() {
152     doTest();
153   }
154
155   public void testConstantInChainingConstructor() {   // IDEADEV-28136
156     doTest();
157   }
158
159   public void testReplaceParameterWithArgumentForConstructor() {   // IDEADEV-23652
160     doTest();
161   }
162
163   public void testTailCallReturn() {  // IDEADEV-27983
164     doTest();
165   }
166
167   public void testTailCallSimple() {  // IDEADEV-27983
168     doTest();
169   }
170
171   public void testTailComment() {   //IDEADEV-33638
172     doTest();
173   }
174
175   public void testInferredType() {
176     setLanguageLevel(LanguageLevel.JDK_1_7);
177     doTest();
178   }
179
180   public void testReplaceGenericsInside() {
181     doTest();
182   }
183
184   public void testStaticMethodWithoutParams() {
185     doTest();
186   }
187
188   public void testWithSuperInside() {
189     doTest();
190   }
191
192   public void testRawSubstitution() {
193     doTest();
194   }
195   
196   public void testSubstitution() {
197     doTest();
198   }
199
200   public void testSubstitutionForWildcards() {
201     doTest();
202   }
203
204   public void testParamNameConflictsWithLocalVar() {
205     doTest();
206   }
207
208   public void testArrayTypeInferenceFromVarargs() {
209     doTest();
210   }
211
212   public void testSuperMethodInAnonymousClass() {
213     doTest();
214   }
215   
216   public void testInlineAnonymousClassWithPrivateMethodInside() {
217     doTest();
218   }
219
220   public void testChainedConstructor() {
221     doTestInlineThisOnly();
222   }
223
224   public void testChainedConstructor1() {
225     doTest();
226   }
227
228   public void testMethodUsedInJavadoc() {
229     doTestConflict("Inlined method is used in javadoc");
230   }
231
232   public void testMethodUsedReflectively() {
233     doTestConflict("Inlined method is used reflectively");
234   }
235
236   public void testNotAStatement() {
237     doTest();
238   }
239
240   public void testNotAStatement2() {
241     doTest();
242   }
243   
244   public void testNotAStatement3() {
245     doTest();
246   }
247   
248   public void testNotAStatement4() {
249     doTest();
250   }
251   
252   public void testForContinue() {
253     doTest();
254   }
255   
256   public void testSingleReturn1() {
257     doTestAssertBadReturn();
258   }
259   
260   public void testSingleReturn1NotFinal() {
261     doTestAssertBadReturn();
262   }
263   
264   public void testSingleReturn2() {
265     doTestAssertBadReturn();
266   }
267
268   public void testInSuperCall() {
269     doTestConflict("Inline cannot be applied to multiline method in constructor call");
270   }
271
272   public void testMethodReferenceInsideMethodCall() {
273     doTest();
274   }
275   
276   public void testVolatilePassed() {
277     doTest();
278   }
279
280   private void doTestConflict(final String conflict) {
281     try {
282       doTest();
283       fail("Conflict was not detected");
284     }
285     catch (BaseRefactoringProcessor.ConflictsInTestsException e) {
286       assertEquals(conflict, e.getMessage());
287     }
288   }
289
290   public void testInlineRunnableRun() {
291     doTestInlineThisOnly();
292   }
293
294   public void testPreserveLeadingTailingComments() {
295     doTestInlineThisOnly();
296   }
297
298   public void testSkipEmptyMethod() {
299     doTestInlineThisOnly();
300   }
301
302   public void testOneLineLambdaVoidCompatibleToBlock() {
303     doTestInlineThisOnly();
304   }
305
306   public void testOneLineLambdaValueCompatibleToBlock() {
307     doTestInlineThisOnly();
308   }
309
310   public void testOneLineLambdaVoidCompatibleOneLine() {
311     doTestInlineThisOnly();
312   }
313  
314   public void testOneLineLambdaValueCompatibleOneLine() {
315     doTestInlineThisOnly();
316   }
317
318   public void testOnMethodReference() {
319     doTestInlineThisOnly();
320   }
321
322   public void testOnLambda() {
323     doTestInlineThisOnly();
324   }
325
326   public void testNonCodeUsage() {
327     doTest(true);
328   }
329
330   public void testMethodInsideChangeIfStatement() {
331     doTest();
332   }
333
334   public void testSameVarMethodNames() {
335     doTest();
336   }
337
338   public void testThisNameConflict() {
339     doTest();
340   }
341
342   public void testStringPlusOverload() {
343     doTest();
344   }
345   
346   public void testReturnStatementWithoutBraces() {
347     doTestInlineThisOnly();
348   }
349
350   public void testIfElseIfWithSingleStatement() {
351     doTestInlineThisOnly();
352   }
353
354   public void testUnresolvedArgPassedToSameNameParameter() {
355     doTestInlineThisOnly();
356   }
357
358   public void testMakeTypesDenotable() {
359     doTestInlineThisOnly();
360   }
361
362   public void testInlineIntoMethodRef() {
363     doTestInlineThisOnly();
364   }
365
366   public void testInlineIntoConstructorRef() {
367     doTestInlineThisOnly();
368   }
369
370   public void testSideEffectsInMethodRefQualifier() {
371     doTestConflict("Inlined method is used in method reference with side effects in qualifier");
372   }
373
374   public void testUnableToInlineCodeBlockToSuper() {
375     doTestConflict("Inline cannot be applied to multiline method in constructor call");
376   }
377
378   public void testRedundantCastOnMethodReferenceToLambda() {
379     doTest();
380   }
381
382   public void testInaccessibleSuperCallWhenQualifiedInline() {
383     doTestConflict("Inlined method calls super.bar() which won't be accessed in class <b><code>B</code></b>");
384   }
385
386   public void testInaccessibleSuperCallWhenQualifiedInInheritor() {
387     doTestConflict("Inlined method calls super.foo() which won't be accessible on qualifier c");
388   }
389
390   public void testInaccessibleConstructorInInlinedMethod() {
391     doTestConflict("Constructor <b><code>SomeClass.SomeClass()</code></b> that is used in inlined method is not accessible from call site(s) in method <b><code>InlineWithPrivateConstructorAccessMain.main(String...)</code></b>");
392   }
393
394   public void testPreserveResultedVariableIfInitializerIsNotSideEffectsFree() {
395     doTestInlineThisOnly();
396   }
397
398   public void testExprLambdaExpandToCodeBlock() {
399     doTestInlineThisOnly();
400   }
401
402   public void testSuperCallWhenUnqualifiedInline() {
403     doTestInlineThisOnly();
404   }
405
406   public void testRemoveReturnForTailTypeSimpleWhenNoSideEffectsPossible() {
407     doTestInlineThisOnly();
408   }
409
410   public void testDeleteOverrideAnnotations() {
411     doTest();
412   }
413
414   public void testNegativeArguments() {
415     doTest();
416   }
417
418   public void testInaccessibleFieldInSuperClass() {
419     doTestConflict("Field <b><code>A.i</code></b> that is used in inlined method is not accessible from call site(s) in method <b><code>B.bar()</code></b>");
420   }
421
422   public void testPrivateFieldInSuperClassInSameFile() {
423     doTest();
424   }
425   
426   public void testWidenArgument() {
427     doTest();
428   }
429
430   public void testInlineMultipleOccurrencesInFieldInitializer() {
431     doTest();
432   }
433
434   public void testAvoidMultipleSubstitutionInParameterTypes() {
435     doTest();
436   }
437
438   public void testRespectProjectScopeSrc() {
439     doTest();
440   }
441
442   public void testRespectProjectScopeSrcConstructorCall() {
443     doTest();
444   }
445
446   public void testChainedConstructorWithMultipleStatements() {
447     doTestInlineThisOnly();
448   }
449
450   public void testThisExpressionValidationForLocalClasses() {
451     doTestInlineThisOnly();
452   }
453
454   public void testTailCallInsideIf() {
455     doTest();
456   }
457
458   public void testTailCallInsideLambda() {
459     doTest();
460   }
461
462   public void testChainedBuilderCall() {
463     doTest();
464   }
465
466   public void testMissedQualifierWithSideEffectsOnInliningEmptyMethod() {
467     doTest();
468   }
469
470   public void testNotTailCallInsideIf() {
471     doTestAssertBadReturn();
472   }
473   
474   public void testConvertToSingleReturnWithFinished() {
475     doTestAssertBadReturn();
476   }
477
478   public void testConvertToSingleReturnWithFinishedUnusedResult() {
479     doTestAssertBadReturn();
480   }
481
482   public void testUnusedResult() {
483     doTest();
484   }
485   
486   public void testReuseResultVar() {
487     doTest();
488   }
489
490   public void testSpecializeClassGetName() {
491     doTest();
492   }
493   
494   public void testSpecializeEnumName() {
495     doTest();
496   }
497   
498   public void testSpecializeEnumValueOf() {
499     doTest();
500   }
501   
502   public void testBooleanModelSimple() {
503     doTestAssertBadReturn();
504   }
505   
506   public void testBooleanModelMultiReturns() {
507     doTestAssertBadReturn();
508   }
509   
510   public void testBooleanModelIfElse() {
511     doTestAssertBadReturn();
512   }
513
514   public void testBooleanModelIfElse2() {
515     doTestAssertBadReturn();
516   }
517
518   public void testBooleanModelContinue() {
519     doTestAssertBadReturn();
520   }
521
522   public void testBooleanModelFinalCondition() {
523     doTestAssertBadReturn();
524   }
525   
526   public void testInvertMethod() {
527     doTest();
528   }
529
530   @Override
531   protected Sdk getProjectJDK() {
532     return getTestName(false).contains("Src") ? IdeaTestUtil.getMockJdk17() : super.getProjectJDK();
533   }
534
535   private void doTestInlineThisOnly() {
536     @NonNls String fileName = configure();
537     performAction(new MockInlineMethodOptions(){
538       @Override
539       public boolean isInlineThisOnly() {
540         return true;
541       }
542     }, false, false);
543     checkResultByFile(fileName + ".after");
544   }
545
546   private void doTest() {
547     doTest(false);
548   }
549
550   private void doTest(final boolean nonCode) {
551     @NonNls String fileName = configure();
552     performAction(nonCode);
553     checkResultByFile(fileName + ".after");
554   }
555
556   private void doTestAssertBadReturn() {
557     @NonNls String fileName = configure();
558     BaseRefactoringProcessor.ConflictsInTestsException.withIgnoredConflicts(() -> performAction(new MockInlineMethodOptions(), false, true));
559     checkResultByFile(fileName + ".after");
560   }
561
562   @NotNull
563   private String configure() {
564     @NonNls String fileName = "/refactoring/inlineMethod/" + getTestName(false) + ".java";
565     configureByFile(fileName);
566     return fileName;
567   }
568
569   private static void performAction(final boolean nonCode) {
570     performAction(new MockInlineMethodOptions(), nonCode, false);
571   }
572
573   private static void performAction(final InlineOptions options, final boolean nonCode, final boolean assertBadReturn) {
574     PsiElement element = TargetElementUtil
575       .findTargetElement(myEditor, TargetElementUtil.ELEMENT_NAME_ACCEPTED | TargetElementUtil.REFERENCED_ELEMENT_ACCEPTED);
576     final PsiReference ref = myFile.findReferenceAt(myEditor.getCaretModel().getOffset());
577     if (ref instanceof PsiJavaCodeReferenceElement) {
578       final PsiElement parent = ((PsiJavaCodeReferenceElement)ref).getParent();
579       if (parent instanceof PsiNewExpression) {
580         element = ((PsiNewExpression)parent).resolveConstructor();
581       }
582     }
583     PsiReferenceExpression refExpr = ref instanceof PsiReferenceExpression ? (PsiReferenceExpression)ref : null;
584     assertTrue(element instanceof PsiMethod);
585     PsiMethod method = (PsiMethod)element.getNavigationElement();
586     final boolean condition = InlineMethodProcessor.checkBadReturns(method) && !InlineUtil.allUsagesAreTailCalls(method);
587     if (assertBadReturn) {
588       assertTrue("Bad returns not found", condition);
589     } else {
590       assertFalse("Bad returns found", condition);
591     }
592     final InlineMethodProcessor processor =
593       new InlineMethodProcessor(getProject(), method, refExpr, myEditor, options.isInlineThisOnly(), nonCode, nonCode,
594                                 !options.isKeepTheDeclaration());
595     processor.run();
596   }
597 }