Summary: | MalformedTreeException on Inline Method | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
Product: | [Eclipse Project] JDT | Reporter: | David Saff <david> | ||||||||
Component: | Core | Assignee: | Jerome Lanneluc <jerome_lanneluc> | ||||||||
Status: | VERIFIED FIXED | QA Contact: | |||||||||
Severity: | normal | ||||||||||
Priority: | P3 | CC: | dirk_baeumer, kagrama | ||||||||
Version: | 3.1 | ||||||||||
Target Milestone: | 3.1 RC3 | ||||||||||
Hardware: | PC | ||||||||||
OS: | Windows XP | ||||||||||
Whiteboard: | |||||||||||
Attachments: |
|
Description
David Saff
2005-06-14 11:16:26 EDT
Created attachment 23061 [details]
The file that generates the error
The problem comes from the fact that JDT/Core considers two bindings as equal although the aren't. The bindings are: The method binding representing the method declaration of java.lang.String methodNameFor(java.lang.String) and the binding representing the method invocation methodNameFor(sline) inside of the following method: private Object evaluateLine(String line,ArithmeticContext context) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { SayTestLine sline=new SayTestLine(line); String methodName=methodNameFor(sline); Method[] methods=getClass().getMethods(); for ( Method method : methods) { if (method.getName().equals(methodName)) { return method.invoke(this,argsArray(context,method,sline)); } } return null; } Both method bindings are first "normalized" using IMethodBinding#getMethodDeclaration. The binding key of the method declaration is Lp/SayTests;.methodNameFor(Ljava/lang/String;)Ljava/lang/String; and for the method invocation Lp/SayTests;.methodNameFor(Lp/SayTests$SayTestLine;)Ljava/lang/String; So the keys aren't equal. Moving to JDT/Core. Philippe, can you consider this for RC3 since UI is relying on isEqualTo now and not on the keys anymore. Other invocations to String methodNameFor(SayTestLine sline) are consider equal as well. The invocation that leads to the malformed tree exception is the one inside of methodNameFor(String line) which is the method to be inlined. To reproduce: - create a 1.5 project - add the attached source - set a conditional break point at TargetProvider line 306. As condition use Bindings.equals(fBinding, ((IMethodBinding)binding).getMethodDeclaration()) (e.g the same as the return method) - select the method java.lang.String methodNameFor(java.lang.String) in the editor and call Inline - press Next or OK on the wizard. When the breakpoint is hit the third and forth time the bindings shouldn't be equal. The test case requires a version of JUnit that I don't have. Where could I get it from ? Jerome, I'll send a jar of my JUnit version to you by private e-mail. Sorry for the oversight. Created attachment 23211 [details] Change in BindingComparator Fix for bug 93408 was not quite right. All traversed types were added to the know types. In the case of this bug, String was added, and we would not compare it to SayTestLine. However the recursion the vistedTypes HashSet is trying to prevent can only occur on a type variable (its declaring element can contain the type variable). The fix consists in adding type variables only to the visitedTypes. Created attachment 23212 [details]
Regression test
+1 for RC3. Dirk - pls vote. +1 for RC3. Thanks Dirk. Released fix and test. Verified using N20050616-0010 + JDT/Core HEAD *** Bug 100494 has been marked as a duplicate of this bug. *** |