Skip to content

Commit b9ea766

Browse files
Mikhail Pyltsinintellij-monorepo-bot
authored andcommitted
[java-intentions] IDEA-381804 Error after applying Extract to method reference in the Compact Source File
GitOrigin-RevId: 9944b7f6aa92ca80a9527f5ef230fb0f30da3406
1 parent 1056d51 commit b9ea766

File tree

5 files changed

+69
-4
lines changed

5 files changed

+69
-4
lines changed

java/java-impl-refactorings/src/com/siyeh/ipp/functional/ExtractToMethodReferenceIntention.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,14 @@ public boolean isAvailable(@NotNull Project project, @NotNull Editor editor, @No
7373
return false;
7474
}
7575

76+
//not directly inside an implicitly declared class
77+
PsiClass targetClass = PsiUtil.getContainingClass(lambdaExpression);
78+
PsiMethod method = PsiTreeUtil.getParentOfType(lambdaExpression, PsiMethod.class, true);
79+
if (targetClass == null ||
80+
(targetClass instanceof PsiImplicitClass && method != null && method.hasModifierProperty(PsiModifier.STATIC))) {
81+
return false;
82+
}
83+
7684
PsiExpression asMethodReference = LambdaCanBeMethodReferenceInspection
7785
.canBeMethodReferenceProblem(body, lambdaExpression.getParameterList().getParameters(), functionalInterfaceType, null);
7886
if (asMethodReference != null) return false;
@@ -82,8 +90,7 @@ public boolean isAvailable(@NotNull Project project, @NotNull Editor editor, @No
8290
wrapper.prepareAndCheckExitStatements(toExtract, body);
8391
PsiVariable[] outputVariables = wrapper.getOutputVariables();
8492
List<PsiVariable> inputVariables = wrapper.getInputVariables(body, toExtract, outputVariables);
85-
return inputVariables.stream()
86-
.allMatch(variable -> variable instanceof PsiParameter && ((PsiParameter)variable).getDeclarationScope() == lambdaExpression);
93+
return ContainerUtil.and(inputVariables, variable -> variable instanceof PsiParameter && ((PsiParameter)variable).getDeclarationScope() == lambdaExpression);
8794
}
8895
catch (PrepareFailedException | ControlFlowWrapper.ExitStatementsNotSameException ignored) {
8996
}
@@ -102,7 +109,8 @@ public void invoke(@NotNull Project project, @NotNull Editor editor, @NotNull Ps
102109
PsiElement[] elements = body.getStatements();
103110

104111
HashSet<PsiField> usedFields = new HashSet<>();
105-
boolean canBeStatic = CommonJavaRefactoringUtil.canBeStatic(targetClass, lambdaExpression, elements, usedFields) && usedFields.isEmpty();
112+
boolean canBeStatic = CommonJavaRefactoringUtil.canBeStatic(targetClass, lambdaExpression, elements, usedFields) &&
113+
usedFields.isEmpty() && !(targetClass instanceof PsiImplicitClass);
106114
PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(targetClass.getProject());
107115
PsiType functionalInterfaceType = lambdaExpression.getFunctionalInterfaceType();
108116

@@ -144,7 +152,7 @@ private static void startInplaceRename(Editor editor, PsiMethod method, PsiMetho
144152
PsiIdentifier nameIdentifier = method.getNameIdentifier();
145153
if (nameIdentifier == null) return;
146154
nameIdentifier = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(nameIdentifier);
147-
155+
if (nameIdentifier == null) return;
148156
//try to navigate to reference name
149157
editor.getCaretModel().moveToOffset(ObjectUtils.notNull(methodReference.getReferenceNameElement(), nameIdentifier).getTextOffset());
150158

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
void main(String[] args) throws IOException {
2+
List.of("1").forEach(line -> {
3+
Person person = new Person(line);
4+
IO.println(person);
5+
<caret>});
6+
}
7+
8+
private record Person(String name) {
9+
@Override
10+
public String toString() {
11+
return "Person{" +
12+
"name='" + name + '\'' +
13+
'}';
14+
}
15+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
void main(String[] args) throws IOException {
2+
List.of("1").forEach(this::<caret>accept);
3+
}
4+
5+
private record Person(String name) {
6+
@Override
7+
public String toString() {
8+
return "Person{" +
9+
"name='" + name + '\'' +
10+
'}';
11+
}
12+
}
13+
14+
private void accept(String line) {
15+
Person person = new Person(line);
16+
IO.println(person);
17+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
static void main(String[] args) throws IOException {
2+
List.of("1").forEach(line -> {
3+
Person person = new Person(line);
4+
IO.println(person);
5+
<caret>});
6+
}
7+
8+
private record Person(String name) {
9+
@Override
10+
public String toString() {
11+
return "Person{" +
12+
"name='" + name + '\'' +
13+
'}';
14+
}
15+
}

java/java-tests/testSrc/com/siyeh/ipp/functional/ExtractToMethodReferenceTest.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
*/
1616
package com.siyeh.ipp.functional;
1717

18+
import com.intellij.pom.java.JavaFeature;
19+
import com.intellij.testFramework.IdeaTestUtil;
1820
import com.intellij.testFramework.LightProjectDescriptor;
1921
import com.siyeh.IntentionPowerPackBundle;
2022
import com.siyeh.ipp.IPPTestCase;
@@ -86,6 +88,14 @@ public void testAnnotatedLambdaParameterVar() {
8688
doTest();
8789
}
8890

91+
public void testLambdaInImplicitClass() {
92+
IdeaTestUtil.withLevel(getModule(), JavaFeature.IMPLICIT_CLASSES.getStandardLevel(), this::doTest);
93+
}
94+
95+
public void testStaticLambdaInImplicitClass() {
96+
IdeaTestUtil.withLevel(getModule(), JavaFeature.IMPLICIT_CLASSES.getStandardLevel(), this::assertIntentionNotAvailable);
97+
}
98+
8999
@Override
90100
protected String getIntentionName() {
91101
return IntentionPowerPackBundle.message("extract.to.method.reference.intention.name");

0 commit comments

Comments
 (0)