Skip to content

Commit e6b6ecb

Browse files
authored
Allow inlining in lambda to support multiple statement methods (eclipse-jdt#2126)
* Allow inlining in lambda to support multiple statement methods - modify CallInliner.checkInvocationContext() to allow a non-simple method in a lambda body - also modify CallInliner.replaceCall() to add support for replacing a lambda body or a method reference with the contents of a non-simple method - add new tests to InlineMethodTests - fixes eclipse-jdt#2111
1 parent ad4ea63 commit e6b6ecb

File tree

6 files changed

+130
-5
lines changed

6 files changed

+130
-5
lines changed

org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/code/CallInliner.java

Lines changed: 60 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -376,9 +376,9 @@ private void checkInvocationContext(RefactoringStatus result, int severity) {
376376
RefactoringStatusCodes.INLINE_METHOD_EXECUTION_FLOW, severity);
377377
return;
378378
}
379-
if (isAssignment(parent) || isSingleDeclaration(parent)) {
380-
// we support inlining expression in assigment and initializers as
381-
// long as the execution flow isn't interrupted.
379+
if (isAssignment(parent) || isSingleDeclaration(parent) || isLambda(parent)) {
380+
// we support inlining expression in assignment and initializers as
381+
// long as the execution flow isn't interrupted. we also aupport lambda bodies.
382382
return;
383383
} else {
384384
boolean isFieldDeclaration= ASTNodes.getParent(fInvocation, FieldDeclaration.class) != null;
@@ -448,6 +448,13 @@ private static boolean isSingleDeclaration(ASTNode node) {
448448
return false;
449449
}
450450

451+
private static boolean isLambda(ASTNode node) {
452+
int type= node.getNodeType();
453+
if (type == ASTNode.LAMBDA_EXPRESSION)
454+
return true;
455+
return false;
456+
}
457+
451458
private static boolean isMultiDeclarationFragment(ASTNode node) {
452459
int nodeType= node.getNodeType();
453460
if (nodeType == ASTNode.VARIABLE_DECLARATION_FRAGMENT) {
@@ -672,13 +679,61 @@ private void replaceCall(RefactoringStatus status, String[] blocks, TextEditGrou
672679
separator= ", "; //$NON-NLS-1$
673680
}
674681
builder.append(") -> {}"); //$NON-NLS-1$
675-
ASTNode newNode= fRewrite.createStringPlaceholder(builder.toString(), ASTNode.LAMBDA_EXPRESSION);
676-
fRewrite.replace(fTargetNode, newNode, textEditGroup);
682+
ASTNode newNode= fRewrite.createStringPlaceholder(builder.toString(), ASTNode.LAMBDA_EXPRESSION);
683+
fRewrite.replace(fTargetNode, newNode, textEditGroup);
677684
}
678685
} else {
679686
fRewrite.remove(fTargetNode, textEditGroup);
680687
}
681688
}
689+
} else if (fTargetNode instanceof MethodReference methodRef) {
690+
IMethodBinding binding= methodRef.resolveMethodBinding();
691+
if (binding == null) {
692+
status.addError(RefactoringCoreMessages.CallInliner_unexpected_model_exception,
693+
JavaStatusContext.create(fCUnit, fInvocation));
694+
return;
695+
}
696+
StringBuilder builder= new StringBuilder("("); //$NON-NLS-1$
697+
String[] parmNames= binding.getParameterNames();
698+
String separator= ""; //$NON-NLS-1$
699+
for (String parmName : parmNames) {
700+
builder.append(separator + parmName);
701+
separator= ", "; //$NON-NLS-1$
702+
}
703+
builder.append(") -> {"); //$NON-NLS-1$
704+
String allblocks= ""; //$NON-NLS-1$
705+
for (int i= 0; i < blocks.length; ++i) {
706+
allblocks += blocks[i];
707+
}
708+
String[] lines= allblocks.split("\n"); //$NON-NLS-1$
709+
separator= lines.length == 1 ? "" : "\n\t"; //$NON-NLS-1$ //$NON-NLS-2$
710+
for (int i= 0; i < lines.length; ++i) {
711+
builder.append(separator);
712+
builder.append(lines[i]);
713+
separator= "\n\t"; //$NON-NLS-1$
714+
}
715+
separator= lines.length == 1 ? "" : "\n"; //$NON-NLS-1$ //$NON-NLS-2$
716+
builder.append(separator + "}"); //$NON-NLS-1$
717+
ASTNode newNode= fRewrite.createStringPlaceholder(builder.toString(), ASTNode.LAMBDA_EXPRESSION);
718+
fRewrite.replace(fTargetNode, newNode, textEditGroup);
719+
} else if (fTargetNode != null && fTargetNode.getLocationInParent() == LambdaExpression.BODY_PROPERTY) {
720+
String allblocks= ""; //$NON-NLS-1$
721+
for (int i= 0; i < blocks.length; ++i) {
722+
allblocks += blocks[i];
723+
}
724+
StringBuilder builder= new StringBuilder();
725+
builder.append("{"); //$NON-NLS-1$
726+
String[] lines= allblocks.split("\n"); //$NON-NLS-1$
727+
String separator= lines.length == 1 ? "" : "\n\t"; //$NON-NLS-1$ //$NON-NLS-2$
728+
for (int i= 0; i < lines.length; ++i) {
729+
builder.append(separator);
730+
builder.append(lines[i]);
731+
separator= "\n\t"; //$NON-NLS-1$
732+
}
733+
separator= lines.length == 1 ? "" : "\n"; //$NON-NLS-1$ //$NON-NLS-2$
734+
builder.append(separator + "}"); //$NON-NLS-1$
735+
ASTNode newNode= fRewrite.createStringPlaceholder(builder.toString(), ASTNode.BLOCK);
736+
fRewrite.replace(fTargetNode, newNode, textEditGroup);
682737
} else {
683738
ASTNode node= null;
684739
boolean needsMethodInvocation= true;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package bugs_in;
2+
3+
public class Test_issue_2111_2 {
4+
public interface A {
5+
void doSomething(int a, int b);
6+
}
7+
8+
protected void foo() {
9+
A a = (m, n) -> b(m, n);
10+
}
11+
12+
public void /*]*/b/*[*/(int x, int y) {
13+
System.out.println(x);
14+
System.out.println(y);
15+
}
16+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package bugs_in;
2+
3+
public class Test_issue_2118_3 {
4+
public interface A {
5+
void doSomething(int a, int b);
6+
}
7+
8+
protected void foo() {
9+
A a = this::b;
10+
}
11+
12+
public void /*]*/b/*[*/(int x, int y) {
13+
System.out.println(x);
14+
System.out.println(y);
15+
}
16+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package bugs_in;
2+
3+
public class Test_issue_2111_2 {
4+
public interface A {
5+
void doSomething(int a, int b);
6+
}
7+
8+
protected void foo() {
9+
A a = (m, n) -> {
10+
System.out.println(m);
11+
System.out.println(n);
12+
};
13+
}
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package bugs_in;
2+
3+
public class Test_issue_2118_3 {
4+
public interface A {
5+
void doSomething(int a, int b);
6+
}
7+
8+
protected void foo() {
9+
A a = (x, y) -> {
10+
System.out.println(x);
11+
System.out.println(y);
12+
};
13+
}
14+
}

org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/InlineMethodTests.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,11 @@ public void test_issue_2111_1() throws Exception {
507507
performBugTest();
508508
}
509509

510+
@Test
511+
public void test_issue_2111_2() throws Exception {
512+
performBugTest();
513+
}
514+
510515
@Test
511516
public void test_issue_2118_1() throws Exception {
512517
performBugTest();
@@ -517,6 +522,11 @@ public void test_issue_2118_2() throws Exception {
517522
performBugTest();
518523
}
519524

525+
@Test
526+
public void test_issue_2118_3() throws Exception {
527+
performBugTest();
528+
}
529+
520530
/* *********************** Argument Tests ******************************* */
521531

522532
private void performArgumentTest() throws Exception {

0 commit comments

Comments
 (0)