[java-intentions] IDEA-381804 Error after applying Extract to method reference in the Compact Source File

GitOrigin-RevId: 9944b7f6aa92ca80a9527f5ef230fb0f30da3406
This commit is contained in:
Mikhail Pyltsin
2025-11-07 18:43:04 +00:00
committed by intellij-monorepo-bot
parent 1056d51067
commit b9ea76639f
5 changed files with 69 additions and 4 deletions
@@ -73,6 +73,14 @@ public final class ExtractToMethodReferenceIntention extends BaseElementAtCaretI
return false;
}
//not directly inside an implicitly declared class
PsiClass targetClass = PsiUtil.getContainingClass(lambdaExpression);
PsiMethod method = PsiTreeUtil.getParentOfType(lambdaExpression, PsiMethod.class, true);
if (targetClass == null ||
(targetClass instanceof PsiImplicitClass && method != null && method.hasModifierProperty(PsiModifier.STATIC))) {
return false;
}
PsiExpression asMethodReference = LambdaCanBeMethodReferenceInspection
.canBeMethodReferenceProblem(body, lambdaExpression.getParameterList().getParameters(), functionalInterfaceType, null);
if (asMethodReference != null) return false;
@@ -82,8 +90,7 @@ public final class ExtractToMethodReferenceIntention extends BaseElementAtCaretI
wrapper.prepareAndCheckExitStatements(toExtract, body);
PsiVariable[] outputVariables = wrapper.getOutputVariables();
List<PsiVariable> inputVariables = wrapper.getInputVariables(body, toExtract, outputVariables);
return inputVariables.stream()
.allMatch(variable -> variable instanceof PsiParameter && ((PsiParameter)variable).getDeclarationScope() == lambdaExpression);
return ContainerUtil.and(inputVariables, variable -> variable instanceof PsiParameter && ((PsiParameter)variable).getDeclarationScope() == lambdaExpression);
}
catch (PrepareFailedException | ControlFlowWrapper.ExitStatementsNotSameException ignored) {
}
@@ -102,7 +109,8 @@ public final class ExtractToMethodReferenceIntention extends BaseElementAtCaretI
PsiElement[] elements = body.getStatements();
HashSet<PsiField> usedFields = new HashSet<>();
boolean canBeStatic = CommonJavaRefactoringUtil.canBeStatic(targetClass, lambdaExpression, elements, usedFields) && usedFields.isEmpty();
boolean canBeStatic = CommonJavaRefactoringUtil.canBeStatic(targetClass, lambdaExpression, elements, usedFields) &&
usedFields.isEmpty() && !(targetClass instanceof PsiImplicitClass);
PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(targetClass.getProject());
PsiType functionalInterfaceType = lambdaExpression.getFunctionalInterfaceType();
@@ -144,7 +152,7 @@ public final class ExtractToMethodReferenceIntention extends BaseElementAtCaretI
PsiIdentifier nameIdentifier = method.getNameIdentifier();
if (nameIdentifier == null) return;
nameIdentifier = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(nameIdentifier);
if (nameIdentifier == null) return;
//try to navigate to reference name
editor.getCaretModel().moveToOffset(ObjectUtils.notNull(methodReference.getReferenceNameElement(), nameIdentifier).getTextOffset());
@@ -0,0 +1,15 @@
void main(String[] args) throws IOException {
List.of("1").forEach(line -> {
Person person = new Person(line);
IO.println(person);
<caret>});
}
private record Person(String name) {
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
}
@@ -0,0 +1,17 @@
void main(String[] args) throws IOException {
List.of("1").forEach(this::<caret>accept);
}
private record Person(String name) {
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
}
private void accept(String line) {
Person person = new Person(line);
IO.println(person);
}
@@ -0,0 +1,15 @@
static void main(String[] args) throws IOException {
List.of("1").forEach(line -> {
Person person = new Person(line);
IO.println(person);
<caret>});
}
private record Person(String name) {
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
}
@@ -15,6 +15,8 @@
*/
package com.siyeh.ipp.functional;
import com.intellij.pom.java.JavaFeature;
import com.intellij.testFramework.IdeaTestUtil;
import com.intellij.testFramework.LightProjectDescriptor;
import com.siyeh.IntentionPowerPackBundle;
import com.siyeh.ipp.IPPTestCase;
@@ -86,6 +88,14 @@ public class ExtractToMethodReferenceTest extends IPPTestCase {
doTest();
}
public void testLambdaInImplicitClass() {
IdeaTestUtil.withLevel(getModule(), JavaFeature.IMPLICIT_CLASSES.getStandardLevel(), this::doTest);
}
public void testStaticLambdaInImplicitClass() {
IdeaTestUtil.withLevel(getModule(), JavaFeature.IMPLICIT_CLASSES.getStandardLevel(), this::assertIntentionNotAvailable);
}
@Override
protected String getIntentionName() {
return IntentionPowerPackBundle.message("extract.to.method.reference.intention.name");