Skip to content

Commit f83ca82

Browse files
authored
Fix inline method to handle local classes referencing receivers (#3088)
* Fix inline method to handle local classes referencing receivers - modify SourceAnalyzer.UpdateCollector to recognize when method invocations, constructor instantiations, and field references are within a local class but are referring to methods, constructors, and fields in the receiver class instead of the local one - add new test to InlineMethodTests - fixes #3069 * Fix test failures
1 parent 23babec commit f83ca82

4 files changed

Lines changed: 109 additions & 10 deletions

File tree

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

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
import org.eclipse.jdt.core.dom.SuperMethodInvocation;
6262
import org.eclipse.jdt.core.dom.ThisExpression;
6363
import org.eclipse.jdt.core.dom.TypeDeclaration;
64+
import org.eclipse.jdt.core.dom.TypeDeclarationStatement;
6465
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
6566
import org.eclipse.jdt.core.manipulation.ImportReferencesCollector;
6667

@@ -175,6 +176,7 @@ private IMethodBinding getBinding() {
175176

176177
private class UpdateCollector extends ASTVisitor {
177178
private int fTypeCounter;
179+
private int fLocalTypeCounter;
178180
@Override
179181
public boolean visit(TypeDeclaration node) {
180182
return visitType(node);
@@ -192,6 +194,15 @@ public void endVisit(EnumDeclaration node) {
192194
fTypeCounter--;
193195
}
194196
@Override
197+
public boolean visit(TypeDeclarationStatement node) {
198+
fLocalTypeCounter++;
199+
return true;
200+
}
201+
@Override
202+
public void endVisit(TypeDeclarationStatement node) {
203+
fLocalTypeCounter--;
204+
}
205+
@Override
195206
public boolean visit(AnnotationTypeDeclaration node) {
196207
return visitType(node);
197208
}
@@ -234,10 +245,21 @@ public boolean visit(MethodDeclaration node) {
234245
}
235246
@Override
236247
public boolean visit(MethodInvocation node) {
237-
if (fTypeCounter == 0) {
238-
Expression receiver= node.getExpression();
239-
if (receiver == null && !isStaticallyImported(node.getName())) {
248+
Expression receiver= node.getExpression();
249+
if (receiver == null && !isStaticallyImported(node.getName())) {
250+
if (fTypeCounter == 0) {
240251
fImplicitReceivers.add(node);
252+
} else if (fLocalTypeCounter > 0) {
253+
IMethodBinding methodBinding= node.resolveMethodBinding();
254+
if (methodBinding != null) {
255+
ITypeBinding typeBinding= methodBinding.getDeclaringClass();
256+
while (typeBinding != null && typeBinding.isMember()) {
257+
typeBinding= typeBinding.getDeclaringClass();
258+
}
259+
if (typeBinding != null && !typeBinding.isLocal()) {
260+
fImplicitReceivers.add(node);
261+
}
262+
}
241263
}
242264
}
243265
return true;
@@ -265,12 +287,10 @@ public boolean visit(SuperConstructorInvocation node) {
265287
}
266288
@Override
267289
public boolean visit(ClassInstanceCreation node) {
268-
if (fTypeCounter == 0) {
269-
Expression receiver= node.getExpression();
270-
if (receiver == null) {
271-
if (node.resolveTypeBinding().isMember())
272-
fImplicitReceivers.add(node);
273-
}
290+
Expression receiver= node.getExpression();
291+
if (receiver == null) {
292+
if (node.resolveTypeBinding().isMember())
293+
fImplicitReceivers.add(node);
274294
}
275295
return true;
276296
}
@@ -303,7 +323,17 @@ public boolean visit(SimpleName node) {
303323
StructuralPropertyDescriptor location= node.getLocationInParent();
304324
if (location != SingleVariableDeclaration.NAME_PROPERTY
305325
&& location != VariableDeclarationFragment.NAME_PROPERTY) {
306-
fImplicitReceivers.add(node);
326+
if (fTypeCounter == 0) {
327+
fImplicitReceivers.add(node);
328+
} else if (fLocalTypeCounter > 0) {
329+
ITypeBinding typeBinding= vb.getDeclaringClass();
330+
while (typeBinding != null && typeBinding.isMember()) {
331+
typeBinding= typeBinding.getDeclaringClass();
332+
}
333+
if (typeBinding != null && !typeBinding.isLocal()) {
334+
fImplicitReceivers.add(node);
335+
}
336+
}
307337
}
308338
}
309339
} else if (!vb.isField()) {
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package bugs_in;
2+
3+
public class Test_issue_3069 {
4+
5+
int x;
6+
7+
public static void main(String[] args) {
8+
Test_issue_3069 obj= new Test_issue_3069();
9+
int result= obj.f();
10+
}
11+
12+
int helper() {
13+
return 7;
14+
}
15+
16+
int /*]*/ f()/*[*/ {
17+
class H {
18+
int y;
19+
int j() {
20+
return helper();
21+
}
22+
class K {
23+
int g() {
24+
return helper();
25+
}
26+
int h() {
27+
return g() + x + y;
28+
}
29+
}
30+
}
31+
return H.class.getSimpleName().length() + helper();
32+
}
33+
34+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package bugs_in;
2+
3+
public class Test_issue_3069 {
4+
5+
int x;
6+
7+
public static void main(String[] args) {
8+
Test_issue_3069 obj= new Test_issue_3069();
9+
class H {
10+
int y;
11+
int j() {
12+
return obj.helper();
13+
}
14+
class K {
15+
int g() {
16+
return obj.helper();
17+
}
18+
int h() {
19+
return g() + obj.x + y;
20+
}
21+
}
22+
}
23+
int result= H.class.getSimpleName().length() + obj.helper();
24+
}
25+
26+
int helper() {
27+
return 7;
28+
}
29+
30+
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,11 @@ public void test_issue_2376() throws Exception {
572572
performBugTest();
573573
}
574574

575+
@Test
576+
public void test_issue_3069() throws Exception {
577+
performBugTest();
578+
}
579+
575580
@Test
576581
public void test_issue_3070_1() throws Exception {
577582
performBugTest();

0 commit comments

Comments
 (0)