Community
Participate
Working Groups
Upon revealing a IJavaElement in an editor I get thisthe following exception. The IJavaElement represents a method. It was reconstructed from a handle created with IJavaElement.getHandleIdentifier() java.lang.IllegalArgumentException at org.eclipse.jdt.core.Signature.toCharArray(Signature.java:1269) at org.eclipse.jdt.core.Signature.toString(Signature.java:1381) at org.eclipse.jdt.internal.core.Member.findMethods(Member.java:107) at org.eclipse.jdt.internal.core.SourceType.findMethods (SourceType.java:134) at org.eclipse.jdt.internal.core.CompilationUnit.findElements (CompilationUnit.java:268) at org.eclipse.jdt.internal.corext.util.JavaModelUtil.findInCompilationUnit (JavaModelUtil.java:219) at org.eclipse.jdt.internal.ui.javaeditor.EditorUtility.getWorkingCopy (EditorUtility.java:295) at org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor.getCorrespondingEle ment(CompilationUnitEditor.java:679) at org.eclipse.jdt.internal.ui.javaeditor.JavaEditor.setSelection (JavaEditor.java:1422) at org.eclipse.jdt.internal.ui.javaeditor.EditorUtility.revealInEditor (EditorUtility.java:121) at org.eclipse.jdt.ui.JavaUI.revealInEditor(JavaUI.java:564) code: if (element != null) { IEditorPart javaEditor = JavaUI.openInEditor(element); JavaUI.revealInEditor(javaEditor, element); } Frank
example handle that fails: =FPL/src<net.sourceforge.fpl.commands{GlobNode.java [GlobNode~addFolderContent~File~String~boolean~List
Frank, it looks like the handle for the method you're trying to reveal in the editor is malformed. The parameter types should be signatures, i.e. they should be: {"QFile;", "QString;", "Z", "QList;"} Did you create this handle? If you didn't, how did you get it?
The handle was created with the element.getHandleIdentifier() method.... private Max(String name, String per, double value, IJavaElement element) { this(name, per, value); if (element != null) handle = element.getHandleIdentifier(); }
I meant: how was the method (i.e. the IJavaElement you're getting the handle identifier from) created? It looks like this IJavaElement (an IMethod from my investigation) was created using the wrong parameter type signatures. If the IMethod is malformed, then the handle identifier is also malformed, which causes the IAE.
The IMethod was obtained like this, starting with a org.eclipse.jdt.core.dom.MethodDeclaration: private IMethod findMethod(MethodDeclaration m) { IType type = (IType)input; List parms = m.parameters(); String[] argtypes = new String[parms.size()]; int index = 0; for (Iterator i = parms.iterator();i.hasNext();index++) { String svd = i.next().toString(); int space = svd.indexOf(' '); argtypes[index] = svd.substring(0, space); } IMethod im = type.getMethod(m.getName().getIdentifier(), argtypes); if (im == null) { System.err.println("No method found for " + m.getName ().getIdentifier() + " (" + argtypes + ")"); } return im; }
Hmm, I see what you're saying now. I changed the code posted earlier to print the following output, and what I get from the getMethod call is definetely different from a direct listing of all the methods. Code: if (im == null) { System.err.println("No method found for " + m.getName().getIdentifier() + " (" + argtypes + ")"); } else { System.err.println("Found method " + im.getHandleIdentifier()); try { IMethod[] methods = type.getMethods(); for (int i = 0; i < methods.length;i++) { System.err.println("methods[" + i + "] = " + methods [i].getHandleIdentifier()); } } catch (JavaModelException e) { // HACK Auto-generated catch block e.printStackTrace(); } } Found method =FPL/src<net.sourceforge.fpl.commands{FPLNode.java [FPLNode~fireVariableSet~Variable~boolean ... methods[47] = =FPL/src<net.sourceforge.fpl.commands{FPLNode.java [FPLNode~fireVariableSet~QVariable;~Z So why does type.getMethod(m.getName().getIdentifier(), argtypes) find something if I don't pass the correct argument types, or why does the IMethod returned by the getMethod - if it finds a method - not answer the correct handle?
found workaround as follows. This still does not explain differnetce between getMethod(name, argtypes) and getMethods() though... private IMethod findMethod(MethodDeclaration m) { IType type = (IType)input; List parms = m.parameters(); String[] argtypes = new String[parms.size()]; int index = 0; for (Iterator i = parms.iterator();i.hasNext();index++) { String svd = i.next().toString(); int space = svd.indexOf(' '); argtypes[index] = Signature.createTypeSignature(svd.substring(0, space), false); } IMethod im = type.getMethod(m.getName().getIdentifier(), argtypes); if (im == null) { System.err.println("No method found for " + m.getName().getIdentifier() + " (" + argtypes + ")"); } return im; }
As specified in the javadoc of these methods: - getMethod(String name, String[] parameterTypeSignatures) is a handle-only function. The method may or may not be present. You need to call exists() on this method if you want to know if the method is present in the type. - getMethods() returns the methods and constructors declared by this type. So all methods returns by this function are guarantied to exist. I agree that the names of these methods may be too close. The second one should really be 'findMethods()'. However these are here since 1.0, and we cannot change the names any longer. BTW, I don't think you're solution is a workaround. I think that it the right way to get the IMethod handle from the ASTNode. However you don't need to check for null as getMethod(String, String[]) will never return null. You can - if you want - call exists() on this method to ensure it is present in the type.
Frank, with the above explanation is it ok to close?
yes, ok. I agree that the method names could be improved: getMethod(name, argtypes) should be createMethod since it's not really a finder but more of a factory method. Thanks for your help.
Closing.