Bug 32563 - IAE in org.eclipse.jdt.core.Signature.toCharArray (M5)
Summary: IAE in org.eclipse.jdt.core.Signature.toCharArray (M5)
Status: RESOLVED INVALID
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 2.1   Edit
Hardware: PC Windows 2000
: P3 normal (vote)
Target Milestone: 2.1 RC2   Edit
Assignee: Jerome Lanneluc CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2003-02-22 14:55 EST by Frank Sauer CLA
Modified: 2003-02-25 09:20 EST (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Frank Sauer CLA 2003-02-22 14:55:13 EST
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
Comment 1 Frank Sauer CLA 2003-02-22 15:02:51 EST
example handle that fails:

=FPL/src<net.sourceforge.fpl.commands{GlobNode.java
[GlobNode~addFolderContent~File~String~boolean~List
Comment 2 Jerome Lanneluc CLA 2003-02-23 06:21:34 EST
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?
Comment 3 Frank Sauer CLA 2003-02-23 10:06:25 EST
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();
}
Comment 4 Jerome Lanneluc CLA 2003-02-23 11:42:27 EST
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.
Comment 5 Frank Sauer CLA 2003-02-23 11:58:48 EST
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;
}
Comment 6 Frank Sauer CLA 2003-02-23 13:59:38 EST
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?
Comment 7 Frank Sauer CLA 2003-02-23 18:31:07 EST
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;
}
Comment 8 Jerome Lanneluc CLA 2003-02-24 04:57:45 EST
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.
Comment 9 Jerome Lanneluc CLA 2003-02-25 05:37:44 EST
Frank, with the above explanation is it ok to close?
Comment 10 Frank Sauer CLA 2003-02-25 09:10:51 EST
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.
Comment 11 Jerome Lanneluc CLA 2003-02-25 09:20:20 EST
Closing.