Skip to content

Commit f09e1a7

Browse files
authored
Fix convert to lambda method reference to recognize a lambda parm (#2153)
* Fix convert to lambda method reference to recognize invalid condition - modify ConvertLambdaToMethodReferenceFixCore to recognize when a method invocation in the lambda body is inside a static method call and the method invocation itself is non-static in an interface - add new test to AssistQuickFixTest1d8 - fixes #2152
1 parent 2ceee49 commit f09e1a7

File tree

2 files changed

+60
-5
lines changed

2 files changed

+60
-5
lines changed

org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/ConvertLambdaToMethodReferenceFixCore.java

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2023, 2024 IBM Corporation and others.
2+
* Copyright (c) 2023, 2025 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -216,11 +216,37 @@ public static boolean representsDefiningNode(ASTNode innerNode, ASTNode defining
216216
}
217217

218218
public static boolean isValidLambdaReferenceToMethod(Expression expression) {
219-
return expression instanceof ClassInstanceCreation
219+
if (expression instanceof ClassInstanceCreation
220220
|| expression instanceof ArrayCreation
221221
|| expression instanceof SuperMethodInvocation
222-
|| expression instanceof MethodInvocation
223-
|| expression instanceof InstanceofExpression;
222+
|| expression instanceof InstanceofExpression) {
223+
return true;
224+
}
225+
if (expression instanceof MethodInvocation methodInvocation) {
226+
// Bug546645 - prevent bad code when there is a lambda method invocation body
227+
// inside a static method invocation where the lambda method invocation is non-static
228+
// in an interface (can't make a non-static method reference to the interface and
229+
// can't instantiate the interface via new to reference it)
230+
LambdaExpression lambda= ASTNodes.getFirstAncestorOrNull(expression, LambdaExpression.class);
231+
if (lambda != null) {
232+
MethodInvocation outer= ASTNodes.getFirstAncestorOrNull(lambda, MethodInvocation.class);
233+
if (outer == null) {
234+
return true;
235+
}
236+
IMethodBinding outerBinding= outer.resolveMethodBinding();
237+
if (!Modifier.isStatic(outerBinding.getModifiers())) {
238+
return true;
239+
}
240+
IMethodBinding methodBinding= methodInvocation.resolveMethodBinding();
241+
if (methodBinding != null) {
242+
ITypeBinding typeBinding= methodBinding.getDeclaringClass();
243+
if (typeBinding != null) {
244+
return !typeBinding.isInterface() || Modifier.isStatic(methodBinding.getModifiers());
245+
}
246+
}
247+
}
248+
}
249+
return false;
224250
}
225251

226252
private static class ConvertLambdaToMethodReferenceProposalOperation extends CompilationUnitRewriteOperation {

org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest1d8.java

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2013, 2024 IBM Corporation and others.
2+
* Copyright (c) 2013, 2025 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -5038,6 +5038,35 @@ public boolean foo() {
50385038
assertExpectedExistInProposals(proposals, new String[] { expected1 });
50395039
}
50405040

5041+
@Test
5042+
public void testConvertLambdaToMethodReference7() throws Exception {
5043+
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
5044+
String str= """
5045+
package test1;
5046+
import java.util.function.Function;
5047+
5048+
public class E7 {
5049+
public static void main(String[] args) {
5050+
f(s -> s.m(s));
5051+
}
5052+
5053+
static void f(Function<X, X> f) {}
5054+
5055+
interface X {
5056+
X m(X x);
5057+
}
5058+
}
5059+
""";
5060+
ICompilationUnit cu= pack1.createCompilationUnit("E7.java", str, false, null);
5061+
5062+
int offset= str.indexOf("s ->");
5063+
AssistContext context= getCorrectionContext(cu, offset, 4);
5064+
assertNoErrors(context);
5065+
List<IJavaCompletionProposal> proposals= collectAssists(context, false);
5066+
assertCorrectLabels(proposals);
5067+
assertProposalDoesNotExist(proposals, CorrectionMessages.QuickAssistProcessor_convert_to_method_reference);
5068+
}
5069+
50415070
@Test
50425071
public void testIssue1520() throws Exception {
50435072
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);

0 commit comments

Comments
 (0)