Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Language IDEs » Java Development Tools (JDT) » ASTVisitor: Strange behaviour when resolving overloaded methods(methodInvocation.resolveMethodBinding().getMethodDeclaration() yields wrong IMethodBinding when applied to overloaded methods)
ASTVisitor: Strange behaviour when resolving overloaded methods [message #715611] Sun, 14 August 2011 20:16 Go to next message
Eclipse UserFriend
Hello,

i am currently working on an academic project which employs an ASTVisitor to create a basic calltree.
For this purpose it is needed to associate the invocation of a method with its declaration.

The code below shows a minimal visitor which prints invocations and associated declarations to console:

import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.MethodInvocation;

/**
 * Visits all method invocations and prints the declaration of the caller to
 * console.
 */
public class InvocationLoggerASTVisitor extends ASTVisitor {

    @Override
    public boolean visit(MethodInvocation methodInvocation) {

	if (methodInvocation.resolveMethodBinding() != null) {
	    IMethodBinding declarationOfInvokedMethod = methodInvocation
		.resolveMethodBinding().getMethodDeclaration();

	    System.out.println(String.format(
		    "invocation of \"%s\" is resolved to declaration \"%s\"",
		    methodInvocation, declarationOfInvokedMethod));

	}
	return super.visit(methodInvocation);
    }

}


The visitor works for some tested scenarios.
Strangely, when applying it to compilation units which contain overloaded methods, some invocations get associated with wrong declarations:

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.HashSet;

@SuppressWarnings({ "unchecked", "rawtypes" })
public class OverloadedMethodsAndRawTypes implements ICallGraphTestSource {

    void f(HashSet objects) {
	f(new ArrayDeque(objects));
    }

    void f(ArrayDeque objects) {
	f(new ArrayList(objects));
    }

    void f(ArrayList objects) {
	f(new HashSet(objects));
    }

}


When visiting this compilation unit, the console output is:
invocation of "f(new ArrayDeque(objects))" is resolved to declaration "void f(HashSet) "
invocation of "f(new ArrayList(objects))" is resolved to declaration "void f(HashSet )"
invocation of "f(new HashSet(list))" is resolved to declaration "void f(HashSet) "


I would expect this output:
invocation of "f(new ArrayDeque(objects))" is resolved to declaration "void f(ArrayDeque) "
invocation of "f(new ArrayList(objects))" is resolved to declaration "void f(ArrayList )"
invocation of "f(new HashSet(list))" is resolved to declaration "void f(HashSet) "


I've noticed, that invocations of overloaded methods always resolve to the first occurring declaration matching the invoked method name, which seems not right to me.

To prove, that method overloading is to blame i attach the same code without method overloading:
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.HashSet;

@SuppressWarnings({ "unchecked", "rawtypes" })
public class RawTypes implements ICallGraphTestSource {

    void f_set(HashSet objects) {
	f_deque(new ArrayDeque(objects));
    }

    void f_deque(ArrayDeque objects) {
	f_list(new ArrayList(objects));
    }

    void f_list(ArrayList objects) {
	f_set(new HashSet(objects));
    }

}


When visited, it yields the correct output:
invocation of "f_deque(new ArrayDeque(objects))" is resolved to declaration "void f_deque(ArrayDeque) "
invocation of "f_list(new ArrayList(objects))" is resolved to declaration "void f_list(ArrayList) "
invocation of "f_set(new HashSet(list))" is resolved to declaration "void f_set(HashSet) "



My ASTParser is configured as following:

 public static ASTNode getAST(ICompilationUnit compilationUnit) {
	ASTParser parser = ASTParser.newParser(AST.JLS3);
	parser.setSource(compilationUnit);
	parser.setResolveBindings(true);
	parser.setBindingsRecovery(true);
	parser.setProject(getJavaProject());
	return parser.createAST(null);
    }


Does somebody in the community know a solution for this problem? Is there another approach or workaround?

Thank you for your time and help.

kind regards,
Mateusz


[Updated on: Sun, 14 August 2011 20:24] by Moderator

Report message to a moderator

Re: ASTVisitor: Strange behaviour when resolving overloaded methods [message #716062 is a reply to message #715611] Tue, 16 August 2011 11:35 Go to previous messageGo to next message
Eclipse UserFriend
Which version of Eclipse are you using? I am getting it correctly using 3.7. I get the following output
invocation of "f(new ArrayDeque(objects))" is resolved to declaration "void f(ArrayDeque#RAW) "
invocation of "f(new ArrayList(objects))" is resolved to declaration "void f(ArrayList#RAW) "
invocation of "f(new HashSet(objects))" is resolved to declaration "void f(HashSet#RAW) "
Re: ASTVisitor: Strange behaviour when resolving overloaded methods [message #716139 is a reply to message #716062] Tue, 16 August 2011 14:28 Go to previous messageGo to next message
Eclipse UserFriend
Satyam Kandula wrote on Tue, 16 August 2011 07:35
Which version of Eclipse are you using? I am getting it correctly using 3.7
.

I am using Eclipse 3.6.2.

Quote:
I get the following output
invocation of "f(new ArrayDeque(objects))" is resolved to declaration "void f(ArrayDeque#RAW) "
invocation of "f(new ArrayList(objects))" is resolved to declaration "void f(ArrayList#RAW) "
invocation of "f(new HashSet(objects))" is resolved to declaration "void f(HashSet#RAW) "


Lucky you Smile The output looks right, i've never seen any "#RAW" string in the console yet. Thanks a lot, now i know it has to do something with the version of eclipse or some bundle. Unfortunately i can't try a 3.7 right now, but hopefully i manage soon.
Re: ASTVisitor: Strange behaviour when resolving overloaded methods [message #716187 is a reply to message #716062] Tue, 16 August 2011 16:11 Go to previous messageGo to next message
Eclipse UserFriend
Satyam Kandula wrote on Tue, 16 August 2011 07:35
I am getting it correctly using 3.7.

Unfortunately switching to 3.7 does not solve the problem... I tried Indigo RCP with the newest JDT dependencies but the output is the same.
Dear Satyam, would you mind attaching me the code you use to create the AST from the source? You seem to do something different then me when creating it.

Thanks in advance!
Re: ASTVisitor: Strange behaviour when resolving overloaded methods [message #716329 is a reply to message #716187] Wed, 17 August 2011 04:22 Go to previous messageGo to next message
Eclipse UserFriend
Attached my plugin here
Re: ASTVisitor: Strange behaviour when resolving overloaded methods [message #716775 is a reply to message #716329] Thu, 18 August 2011 12:32 Go to previous message
Eclipse UserFriend
Satyam Kandula wrote on Wed, 17 August 2011 00:22
Attached my plugin here


Thank you very much! The problem is solved to a large extent: It works in a standalone plugin, as i was able to determine when testing the outcome manually.

My JUnit-test it is not working yet. The wrong resolving must therefor have to do something with the applied workflow of testing ASTVisitors. I'am creating a temporary JavaProject for the time of the test, and the visited source code is read into this project. This must somehow introduce a condition which leads to this error.
It seems, that my testing workflow is just not so common or maybe plain wrong.

It would be interesting how the mainstream approach of Unit-esting ASTVisitors looks like. Do you start with a special prepared workspace? But this is different question stated properly elsewhere... So far, i'm happy that the plugin itself will work, although the case of overloaded methods can't be tested reliable via automatic unit testing yet.
Previous Topic:Why JDT is not in eclipse market?
Next Topic:does anyone know how to configure this java editor feature - better picture
Goto Forum:
  


Current Time: Sat Feb 08 17:43:54 GMT 2025

Powered by FUDForum. Page generated in 0.04194 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top