Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

changeMethodTarget() has unexpected effect on static method invocation #17

Open
gunnarmorling opened this issue Oct 27, 2017 · 1 comment

Comments

@gunnarmorling
Copy link
Contributor

I'm having these classes:

package com.a;

public class A {

	public void foo() {}
}
package com.a;

public class AFactory {

	public static A make() {
		return new A();
	}
}
package com.b;

import com.a.A;
import com.a.AFactory;

public class B {

	A a1 = new A();
	A a2 = new A();

	public void test() {
		a1.foo();
		AFactory.make().foo();
	}
}

And I'm applying the following refactoring:

Path sourceDir = ...;

List<Path> paths = Arrays.asList(
		sourceDir.resolve( "com/a/A.java" ),
		sourceDir.resolve( "com/a/AFactory.java" ),
		sourceDir.resolve( "com/b/B.java" )
);

CompilationUnit cu = parser.parse( paths ).get( 2 );

Class aType = Type.Class.build( "com.a.A", Collections.emptyList(), null, Collections.emptyList() );

CompilationUnit fix = cu.refactor()
	.changeMethodTarget(
			cu.findMethodCalls( "com.a.A *(..)" ), "a2",
			aType
	)
	.fix();

System.out.println( fix.print() );

Then both method invocations in B#test() are modified:

public void test() {
	a2.foo();
	a2.foo();
}

The change of AFactory.make() is surprising. I see how that expression is the target of in invocation of foo(), so it makes sense in a way. Am I just missing the right way to exclude this invocation?

I think in the end a way would be needed to tie a selected invocation not to the type declaring the method but to the element (field, local variable etc.) it is invoked on.

@gunnarmorling
Copy link
Contributor Author

So I solved this by filtering out all method calls whose select is of type MethodInvocation. Perhaps one could have some way to control the result set of findMethodCalls() more specifically for such purposes?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant