Bug 264443

Summary: [parser] ASTParser.createASTs and IVariableBinding
Product: [Eclipse Project] JDT Reporter: Nikola Mihajloviæ <alamothe>
Component: CoreAssignee: Olivier Thomann <Olivier_Thomann>
Status: VERIFIED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: jerome_lanneluc, Olivier_Thomann
Version: 3.4.1Flags: Olivier_Thomann: review? (jerome_lanneluc)
Target Milestone: 3.5 M6   
Hardware: PC   
OS: Windows XP   
Whiteboard:
Attachments:
Description Flags
Proposed fix + regression tests none

Description Nikola Mihajloviæ CLA 2009-02-10 19:06:34 EST
Build ID: M20080911-1700

Steps To Reproduce:
When passing a variable binding to createASTs method of ASTParser, in a acceptBinding callback a method binding is passed instead
Comment 1 Olivier Thomann CLA 2009-02-10 19:17:59 EST
Would you have steps to reproduce a little more concrete ?
Comment 2 Nikola Mihajloviæ CLA 2009-02-10 19:29:06 EST
(In reply to comment #1)
> Would you have steps to reproduce a little more concrete ?

Sorry, I'll try

I have a key of a variable binding got from a previous parse. It is a variable binding of a local variable in a method (it reads something like "Lexample/Test;.test()V|Ljava/lang/Throwable;#b"). When I pass this key and the same compilation unit to createASTs, in acceptBinding(String bindingKey, IBinding binding) of the supplied requestor I get a IMethodBinding instead (the method binding is of the method containing this local variable)

ASTParser parser = ASTParser.newParser(AST.JLS3);
parser.setProject(cu.getJavaProject());
parser.setResolveBindings(true);

parser.createASTs(new ICompilationUnit[] {cu}, new String[] {key}, new ASTRequestor() {
    public void acceptBinding(String bindingKey, IBinding binding) {
        // IBinding is IMethodBinding
    }

    public void acceptAST(ICompilationUnit source, CompilationUnit ast) {
        result.unit = ast;
    }
}, null);

Contents of a ICompilationUnit:

package jvd.example;

public class Test {	
    public void test() throws Throwable {
        B b = new B();
    }
}
Comment 3 Olivier Thomann CLA 2009-02-10 19:31:48 EST
Thanks. I'll give it a try.
Comment 4 Olivier Thomann CLA 2009-02-11 10:49:32 EST
Reproduced with HEAD.
The problem comes from the BindingKeyParser when it parses the thrown exceptions. Once the thrown exceptions are parsed, the current token type is TYPE and not METHOD.
Therefore the '#b' part of the signature is seen as a malformed key.

I believe the parser should reset the token to its value before it parses the exceptions once the exceptions are parsed.

The side-effect comes from the fact that the sub parser used to parse the exceptions is sharing the scanner of the outer parser. So the current token value is lost while parsing the exception types.
Comment 5 Olivier Thomann CLA 2009-02-11 11:03:01 EST
Created attachment 125400 [details]
Proposed fix + regression tests

3 regression tests:
- one with one thrown exception
- one with two thrown exceptions
- one with none (this one works without the fix, but I wanted to make sure this was also tested)
Comment 6 Olivier Thomann CLA 2009-02-11 11:03:26 EST
Jérôme, please review.
Comment 7 Olivier Thomann CLA 2009-02-11 11:09:45 EST
Released for 3.5M6.
Added regression tests for:
org.eclipse.jdt.core.tests.dom.ASTConverterTestAST3_2#test0699
org.eclipse.jdt.core.tests.dom.ASTConverterTestAST3_2#test0700
org.eclipse.jdt.core.tests.dom.ASTConverterTestAST3_2#test0701
Comment 8 Kent Johnson CLA 2009-03-10 10:53:39 EDT
Verified for 3.5M6 using I20090310-0100

But Jerome still needs to review it