views:

212

answers:

3

I am new to eclipse plugin development and I am trying to convert a IMethod to a string representation of the full method name. I.E.

my.full.package.ClassName.methodName(int param, String string)

so far I have had to hand roll my own solution. Is there a better way?

private static String getMethodFullName(IMethod iMethod)
{
 String packageString = "[Default Package]";
 try {
  IPackageDeclaration[] declarations = iMethod.getCompilationUnit().getPackageDeclarations();
  if(declarations.length > 0)
  {
   packageString = declarations[0].getElementName(); 
  }   
 } catch (JavaModelException e) {
 }

 String classString = iMethod.getCompilationUnit().getElementName();
 classString = classString.replaceAll(".java", "");

 String methodString = iMethod.getElementName() + "(";
 for (String type : iMethod.getParameterTypes()) {
  methodString += type + ",";
 }
 methodString += ")";

 return packageString + "." + classString + "." + methodString;
}
A: 

I am not sure it would take into account all cases (method within an internal class, an anonymous class, with generic parameters...)

When it comes to methods signatures, the classes to look into are:

You need to get the jdt.core.dom.IMethodBinding, from which you can extract all what you need.

If you have a MethodInvocation, you can:

//MethodInvocation node
ITypeBinding type = node.getExpression().resolveTypeBinding();
IMethodBinding  method=node.resolveMethodBinding();
VonC
Yep. VonC makes a good point. ITypeBindings representing local classes and anonymous classes will return the empty string when getFullyQualifiedName() is called. This makes sense, since they have no official name, but if you are using fully-qualified names in order to have a unique identifier, you may want to consider using getKey() instead...
Nels Beckman
+2  A: 

You can get the Fully qualified name for the type using

method.getDeclaringType().getFullyQualifiedName();

This is probably easier than accessing the package from the compilation unit. The rest of you function looks correct.

One small point: you should use StringBuilder to build up the string instead of adding to a standard String. Strings are immutable so addition creates loads of unrecesary temparary objects.

private static String getMethodFullName(IMethod iMethod)
{
        StringBuilder name = new StringBuilder();
        name.append(iMethod.getDeclaringType().getFullyQualifiedName());
        name.append(".");
        name.append(iMethod.getElementName());
        name.append("(");

        String comma = "";
        for (String type : iMethod.getParameterTypes()) {
                name.append(comma);
                comma = ", ";
                name.append(type);
        }
        name.append(")");

        return name.toString();
}
iain
This looks good. I found a way to make the parameter types more readable so I will combine this solution with mine.
James Van Boxtel
+1  A: 

Thanks to iain and some more research I have come up with this solution. It seems like something like this should be built into the JDT....

import org.eclipse.jdt.core.Signature;

private static String getMethodFullName(IMethod iMethod)
{
        StringBuilder name = new StringBuilder();
        name.append(iMethod.getDeclaringType().getFullyQualifiedName());
        name.append(".");
        name.append(iMethod.getElementName());
        name.append("(");

        String comma = "";
  String[] parameterTypes = iMethod.getParameterTypes();
        try {
   String[] parameterNames = iMethod.getParameterNames();
   for (int i=0; i<iMethod.getParameterTypes().length; ++i) {
    name.append(comma);
    name.append(Signature.toString(parameterTypes[i]));
    name.append(" ");
    name.append(parameterNames[i]);
                comma = ", ";
   }
  } catch (JavaModelException e) {
  }

        name.append(")");

        return name.toString();
}
James Van Boxtel
That is nice I never saw the Signature class before
iain