/* * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.intellij.refactoring; import com.intellij.JavaTestUtil; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.impl.source.resolve.PsiResolveHelperImpl; import com.intellij.psi.impl.source.resolve.graphInference.PsiGraphInferenceHelper; import com.intellij.refactoring.introduce.inplace.OccurrencesChooser; import com.intellij.refactoring.introduceVariable.InputValidator; import com.intellij.refactoring.introduceVariable.IntroduceVariableBase; import com.intellij.refactoring.introduceVariable.IntroduceVariableSettings; import com.intellij.refactoring.ui.TypeSelectorManagerImpl; import com.intellij.testFramework.LightCodeInsightTestCase; import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; import java.util.Collection; /** * @author dsl */ public class IntroduceVariableTest extends LightCodeInsightTestCase { @NotNull @Override protected String getTestDataPath() { return JavaTestUtil.getJavaTestDataPath(); } public void testSimpleExpression() { doTest(new MockIntroduceVariableHandler("i", false, false, true, "int")); } public void testInsideFor() { doTest(new MockIntroduceVariableHandler("temp", false, false, true, "int")); } public void testReplaceAll() { doTest(new MockIntroduceVariableHandler("s", true, true, true, CommonClassNames.JAVA_LANG_STRING)); } public void testIDEADEV3678() { doTest(new MockIntroduceVariableHandler("component", true, true, true, CommonClassNames.JAVA_LANG_OBJECT)); } public void testIDEADEV13369() { doTest(new MockIntroduceVariableHandler("ints", true, true, true, "int[]")); } public void testAnonymousClass() { doTest(new MockIntroduceVariableHandler("temp", true, false, true, "int")); } public void testAnonymousClass1() { doTest(new MockIntroduceVariableHandler("runnable", false, false, false, CommonClassNames.JAVA_LANG_RUNNABLE)); } public void testAnonymousClass2() { doTest(new MockIntroduceVariableHandler("j", true, false, false, "int")); } public void testAnonymousClass3() { doTest(new MockIntroduceVariableHandler("j", true, false, false, "Foo")); } public void testAnonymousClass4() { doTest(new MockIntroduceVariableHandler("j", true, false, false, "int")); } public void testAnonymousClass5() { doTest(new MockIntroduceVariableHandler("j", true, false, false, "int")); } public void testLambda() { doTest(new MockIntroduceVariableHandler("j", true, false, false, "int")); } public void testParenthized() { doTest(new MockIntroduceVariableHandler("temp", true, false, false, "int")); } public void testExpectedType8Inference() { final PsiResolveHelperImpl helper = (PsiResolveHelperImpl)JavaPsiFacade.getInstance(getProject()).getResolveHelper(); helper.setTestHelper(new PsiGraphInferenceHelper(getPsiManager())); try { doTest(new MockIntroduceVariableHandler("temp", true, false, false, "java.util.Map>")); } finally { helper.setTestHelper(null); } } public void testMethodCall() { doTest(new MockIntroduceVariableHandler("temp", true, true, true, CommonClassNames.JAVA_LANG_OBJECT)); } public void testMethodCallInSwitch() { doTest(new MockIntroduceVariableHandler("i", true, true, true, "int")); } public void testParenthizedOccurence() { doTest(new MockIntroduceVariableHandler("empty", true, true, true, "boolean")); } public void testParenthizedOccurence1() { doTest(new MockIntroduceVariableHandler("s", true, true, true, CommonClassNames.JAVA_LANG_STRING)); } public void testConflictingField() { doTest(new MockIntroduceVariableHandler("name", true, false, true, CommonClassNames.JAVA_LANG_STRING)); } public void testConflictingFieldInExpression() { doTest(new MockIntroduceVariableHandler("name", false, false, true, "int")); } public void testStaticConflictingField() { doTest(new MockIntroduceVariableHandler("name", false, false, true, "int")); } public void testNonConflictingField() { doTest(new MockIntroduceVariableHandler("name", false, false, true, "int")); } public void testScr16910() { doTest(new MockIntroduceVariableHandler("i", true, true, false, "int")); } public void testSCR18295() { doTest(new MockIntroduceVariableHandler("it", true, false, false, CommonClassNames.JAVA_LANG_STRING)); } public void testSCR18295a() { doTest(new MockIntroduceVariableHandler("it", false, false, false, CommonClassNames.JAVA_LANG_STRING)); } public void testFromInjected() { doTest(new MockIntroduceVariableHandler("regexp", false, false, false, CommonClassNames.JAVA_LANG_STRING)); } public void testSCR10412() { doTest(new MockIntroduceVariableHandler("newVar", false, false, false, "java.lang.String[]")); } public void testSCR22718() { doTest(new MockIntroduceVariableHandler("object", true, true, false, CommonClassNames.JAVA_LANG_OBJECT)); } public void testSCR26075() { doTest(new MockIntroduceVariableHandler("wrong", false, false, false, CommonClassNames.JAVA_LANG_STRING) { @Override protected void assertValidationResult(boolean validationResult) { assertFalse(validationResult); } @Override protected boolean reportConflicts(MultiMap conflicts, final Project project, IntroduceVariableSettings dialog) { assertEquals(2, conflicts.size()); Collection conflictsMessages = conflicts.values(); assertTrue(conflictsMessages.contains("Introducing variable may break code logic")); assertTrue(conflictsMessages.contains("Local variable c is modified in loop body")); return false; } }); } public void testConflictingFieldInOuterClass() { doTest(new MockIntroduceVariableHandler("text", true, true, false, CommonClassNames.JAVA_LANG_STRING)); } public void testSkipSemicolon() { doTest(new MockIntroduceVariableHandler("mi5", false, false, false, "int")); } public void testInsideIf() { doTest(new MockIntroduceVariableHandler("s1", false, false, false, CommonClassNames.JAVA_LANG_STRING)); } public void testInsideElse() { doTest(new MockIntroduceVariableHandler("s1", false, false, false, CommonClassNames.JAVA_LANG_STRING)); } public void testInsideWhile() { doTest(new MockIntroduceVariableHandler("temp", false, false, false, "int")); } public void testSCR40281() { doTest(new MockIntroduceVariableHandler("temp", false, false, false, "Set.Entry>")); } public void testWithIfBranches() { doTest(new MockIntroduceVariableHandler("temp", true, false, false, "int")); } public void testInsideForLoop() { doTest(new MockIntroduceVariableHandler("temp", true, false, false, "int")); } public void testDuplicateGenericExpressions() { doTest(new MockIntroduceVariableHandler("temp", true, false, false, "Foo2")); } public void testStaticImport() { doTest(new MockIntroduceVariableHandler("i", true, true, false, "int")); } public void testThisQualifier() { doTest(new MockIntroduceVariableHandler("count", true, true, false, "int")); } public void testSubLiteral() { doTest(new MockIntroduceVariableHandler("str", false, false, false, CommonClassNames.JAVA_LANG_STRING)); } public void testSubLiteral1() { doTest(new MockIntroduceVariableHandler("str", false, false, false, CommonClassNames.JAVA_LANG_STRING)); } public void testSubLiteralFailure() { try { doTest(new MockIntroduceVariableHandler("str", false, false, false, "int")); } catch (Exception e) { assertEquals(e.getMessage(), "Error message:Cannot perform refactoring.\n" + "Selected block should represent an expression"); return; } fail("Should not be able to perform refactoring"); } public void testSubLiteralFromExpression() { doTest(new MockIntroduceVariableHandler("str", false, false, false, CommonClassNames.JAVA_LANG_STRING)); } public void testSubExpressionFromIntellijidearulezzz() { doTest(new MockIntroduceVariableHandler("str", false, false, false, CommonClassNames.JAVA_LANG_STRING)); } public void testSubPrimitiveLiteral() { doTest(new MockIntroduceVariableHandler("str", false, false, false, "boolean")); } public void testArrayFromVarargs() { doTest(new MockIntroduceVariableHandler("strs", false, false, false, "java.lang.String[]")); } public void testArrayFromVarargs1() { doTest(new MockIntroduceVariableHandler("strs", false, false, false, "java.lang.String[]")); } public void testEnumArrayFromVarargs() { doTest(new MockIntroduceVariableHandler("strs", false, false, false, "E[]")); } public void testFromFinalFieldOnAssignment() { doTest(new MockIntroduceVariableHandler("strs", false, false, false, CommonClassNames.JAVA_LANG_STRING)); } public void testNoArrayFromVarargs() { try { doTest(new MockIntroduceVariableHandler("strs", false, false, false, "java.lang.String[]")); } catch (Exception e) { assertEquals(e.getMessage(), "Error message:Cannot perform refactoring.\n" + "Selected block should represent an expression"); return; } fail("Should not be able to perform refactoring"); } public void testNoArrayFromVarargs1() { try { doTest(new MockIntroduceVariableHandler("strs", false, false, false, "java.lang.String[]")); } catch (Exception e) { assertEquals(e.getMessage(), "Error message:Cannot perform refactoring.\n" + "Selected block should represent an expression"); return; } fail("Should not be able to perform refactoring"); } public void testNonExpression() { doTest(new MockIntroduceVariableHandler("sum", true, true, false, "int")); } public void testTypeAnnotations() { doTest(new MockIntroduceVariableHandler("y1", true, false, false, "@TA C")); } public void testReturnStatementWithoutSemicolon() { doTest(new MockIntroduceVariableHandler("b", true, true, false, CommonClassNames.JAVA_LANG_STRING)); } public void testAndAndSubexpression() { doTest(new MockIntroduceVariableHandler("ab", true, true, false, "boolean")); } public void testSubexpressionWithSpacesInSelection() { doTest(new MockIntroduceVariableHandler("ab", true, true, false, "boolean")); } public void testDuplicatesAnonymousClassCreationWithSimilarParameters () { doTest(new MockIntroduceVariableHandler("foo1", true, true, false, "Foo")); } public void testDifferentForeachParameters () { doTest(new MockIntroduceVariableHandler("tostr", true, true, false, CommonClassNames.JAVA_LANG_STRING)); } public void testCollapsedToDiamond() { doTest(new MockIntroduceVariableHandler("a", true, true, true, "java.util.ArrayList")); } public void testCantCollapsedToDiamond() { doTest(new MockIntroduceVariableHandler("a", true, true, true, "Foo")); } public void testFromForInitializer() { doTest(new MockIntroduceVariableHandler("list", true, true, true, "java.util.List")); } public void testInvalidPostfixExpr() { doTest(new MockIntroduceVariableHandler("a1", true, false, true, "int[]")); } public void testPolyadic() { doTest(new MockIntroduceVariableHandler("b1", true, true, true, "boolean")); } public void testAssignmentToUnresolvedReference() { doTest(new MockIntroduceVariableHandler("collection", true, true, true, "java.util.List>")); } public void testNameSuggestion() { final String expectedTypeName = "Path"; doTest(new MockIntroduceVariableHandler("path", true, false, false, expectedTypeName) { @Override public IntroduceVariableSettings getSettings(Project project, Editor editor, PsiExpression expr, PsiExpression[] occurrences, TypeSelectorManagerImpl typeSelectorManager, boolean declareFinalIfAll, boolean anyAssignmentLHS, InputValidator validator, PsiElement anchor, final OccurrencesChooser.ReplaceChoice replaceChoice) { final PsiType type = typeSelectorManager.getDefaultType(); assertTrue(type.getPresentableText(), type.getPresentableText().equals(expectedTypeName)); assertEquals("path", IntroduceVariableBase.getSuggestedName(type, expr).names[0]); return super.getSettings(project, editor, expr, occurrences, typeSelectorManager, declareFinalIfAll, anyAssignmentLHS, validator, anchor, replaceChoice); } }); } public void testSiblingInnerClassType() { doTest(new MockIntroduceVariableHandler("vari", true, false, false, "A.B") { @Override public IntroduceVariableSettings getSettings(Project project, Editor editor, PsiExpression expr, PsiExpression[] occurrences, TypeSelectorManagerImpl typeSelectorManager, boolean declareFinalIfAll, boolean anyAssignmentLHS, InputValidator validator, PsiElement anchor, final OccurrencesChooser.ReplaceChoice replaceChoice) { final PsiType type = typeSelectorManager.getDefaultType(); assertTrue(type.getPresentableText(), type.getPresentableText().equals("B")); return super.getSettings(project, editor, expr, occurrences, typeSelectorManager, declareFinalIfAll, anyAssignmentLHS, validator, anchor, replaceChoice); } }); } public void testNonExpressionPriorityFailure() { doTest(new MockIntroduceVariableHandler("sum", true, true, false, "int"){ @Override protected void showErrorMessage(Project project, Editor editor, String message) { assertEquals("Cannot perform refactoring.\n" + "Extracting selected expression would change the semantic of the whole expression.", message); } }); } public void testIncorrectExpressionSelected() { try { doTest(new MockIntroduceVariableHandler("toString", false, false, false, CommonClassNames.JAVA_LANG_STRING)); } catch (Exception e) { assertEquals(e.getMessage(), "Error message:Cannot perform refactoring.\n" + "Selected block should represent an expression"); return; } fail("Should not be able to perform refactoring"); } public void testMultiCatchSimple() { doTest(new MockIntroduceVariableHandler("e", true, true, false, "java.lang.Exception", true)); } public void testMultiCatchTyped() { doTest(new MockIntroduceVariableHandler("b", true, true, false, "java.lang.Exception", true)); } public void testBeforeVoidStatement() { doTest(new MockIntroduceVariableHandler("c", false, false, false, CommonClassNames.JAVA_LANG_OBJECT)); } public void testWriteUsages() { doTest(new MockIntroduceVariableHandler("c", true, false, false, CommonClassNames.JAVA_LANG_STRING)); } public void testLambdaExpr() { doTest(new MockIntroduceVariableHandler("c", false, false, false, "SAM")); } public void testMethodRef() { doTest(new MockIntroduceVariableHandler("c", false, false, false, "Test.Bar")); } public void testLambdaExprNotAccepted() { doTest(new MockIntroduceVariableHandler("c", false, false, false, "SAM")); } public void testOneLineLambdaVoidCompatible() { doTest(new MockIntroduceVariableHandler("c", false, false, false, CommonClassNames.JAVA_LANG_STRING)); } public void testOneLineLambdaValueCompatible() { doTest(new MockIntroduceVariableHandler("c", false, false, false, "int")); } public void testNormalizeDeclarations() { doTest(new MockIntroduceVariableHandler("i3", false, false, false, "int")); } public void testMethodReferenceExpr() { doTest(new MockIntroduceVariableHandler("m", false, false, false, "Foo.I")); } public void testReturnNonExportedArray() { doTest(new MockIntroduceVariableHandler("i", false, false, false, "java.io.File[]") { @Override protected boolean isInplaceAvailableInTestMode() { return true; } }); } private void doTest(IntroduceVariableBase testMe) { String baseName = "/refactoring/introduceVariable/" + getTestName(false); configureByFile(baseName + ".java"); testMe.invoke(getProject(), getEditor(), getFile(), null); checkResultByFile(baseName + ".after.java"); } }