diff --git a/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java b/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java index 83c297b32498..93510032dc83 100644 --- a/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java +++ b/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java @@ -357,7 +357,8 @@ public class RefactoringUtil { public static PsiType getTypeByExpressionWithExpectedType(PsiExpression expr) { PsiElementFactory factory = JavaPsiFacade.getInstance(expr.getProject()).getElementFactory(); - PsiType type = getTypeByExpression(expr, factory); + PsiType typeByExpression = getTypeByExpression(expr, factory); + PsiType type = typeByExpression; final boolean isFunctionalType = LambdaUtil.notInferredType(type); final boolean isDenotable = PsiTypesUtil.isDenotableType(expr.getType()); if (type != null && !isFunctionalType && isDenotable) { @@ -365,6 +366,9 @@ public class RefactoringUtil { } ExpectedTypeInfo[] expectedTypes = ExpectedTypesProvider.getExpectedTypes(expr, false); if (expectedTypes.length == 1 || (isFunctionalType || !isDenotable)&& expectedTypes.length > 0 ) { + if (typeByExpression != null && Arrays.stream(expectedTypes).anyMatch(typeInfo -> typeInfo.getType().equals(typeByExpression))) { + return type; + } type = expectedTypes[0].getType(); if (!type.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) return type; } diff --git a/java/java-tests/testData/refactoring/introduceVariable/ChooseTypeExpressionWhenNotDenotable.after.java b/java/java-tests/testData/refactoring/introduceVariable/ChooseTypeExpressionWhenNotDenotable.after.java new file mode 100644 index 000000000000..7997db519538 --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceVariable/ChooseTypeExpressionWhenNotDenotable.after.java @@ -0,0 +1,17 @@ + +import java.util.List; + +class CloseAction { + public void performAction() throws IOException { + } +} + +class Foo { + void performAction() { + } + + void bar(List f) { + Foo m = f.get(0); + m.performAction(); + } +} diff --git a/java/java-tests/testData/refactoring/introduceVariable/ChooseTypeExpressionWhenNotDenotable.java b/java/java-tests/testData/refactoring/introduceVariable/ChooseTypeExpressionWhenNotDenotable.java new file mode 100644 index 000000000000..08ae7c767d10 --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceVariable/ChooseTypeExpressionWhenNotDenotable.java @@ -0,0 +1,16 @@ + +import java.util.List; + +class CloseAction { + public void performAction() throws IOException { + } +} + +class Foo { + void performAction() { + } + + void bar(List f) { + f.get(0).performAction(); + } +} diff --git a/java/java-tests/testSrc/com/intellij/java/refactoring/IntroduceVariableTest.java b/java/java-tests/testSrc/com/intellij/java/refactoring/IntroduceVariableTest.java index 86c4eb1aacec..953fab9ef99e 100644 --- a/java/java-tests/testSrc/com/intellij/java/refactoring/IntroduceVariableTest.java +++ b/java/java-tests/testSrc/com/intellij/java/refactoring/IntroduceVariableTest.java @@ -567,6 +567,10 @@ public class IntroduceVariableTest extends LightCodeInsightTestCase { doTest(new MockIntroduceVariableHandler("m", false, false, false, "IA")); } + public void testChooseTypeExpressionWhenNotDenotable() throws Exception { + doTest(new MockIntroduceVariableHandler("m", false, false, false, "Foo")); + } + private void doTest(IntroduceVariableBase testMe) { String baseName = "/refactoring/introduceVariable/" + getTestName(false); configureByFile(baseName + ".java");