Bug 140643 - [compiler] $foo() not found in anonymous type
Summary: [compiler] $foo() not found in anonymous type
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.2   Edit
Hardware: PC Linux
: P3 major (vote)
Target Milestone: 3.2 RC4   Edit
Assignee: Philipe Mulet CLA
QA Contact:
URL:
Whiteboard:
Keywords: greatbug
Depends on:
Blocks:
 
Reported: 2006-05-08 15:13 EDT by Stephan Herrmann CLA
Modified: 2006-05-11 22:22 EDT (History)
3 users (show)

See Also:


Attachments
Proposed patch (3.30 KB, patch)
2006-05-09 05:13 EDT, Philipe Mulet CLA
no flags Details | Diff
Additional patch (1.68 KB, patch)
2006-05-10 09:32 EDT, Frederic Fusier CLA
no flags Details | Diff
alternative methods (2.03 KB, text/plain)
2006-05-10 12:44 EDT, Stephan Herrmann CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Stephan Herrmann CLA 2006-05-08 15:13:51 EDT
Here is a white-box test against 3.2RC3, which shows that TypeDeclaration.createDefaultConstructorWithBinding()
may break method sorting in a - admittedly contrived - situation:

public class T {
    interface I { }
    void test() {
        new I() {
            void foo() { }
        }.foo(); // compiles OK.
        new I() {
            void $foo() { }
        }.$foo(); // The method $foo() is undefined for the type new T.I(){}
    }
}

I constructed this test to prove the assumption wrong 
that constructors should always be the first methods in the
sorted array of methods. The legal character '$' is less then '<'.

I was inspired by bug 137744, where the issue of adding methods to
the sorted array of methods is discussed. The above situation seems
to be the only remaining situation where methods are indeed added after
sorting.

In our own adaptation of the compiler we have several situations of adding
(generated) fields/methods after sorting and so I implemented methods
ReferenceBinding.sortedInsert(..), which for individual members should
be faster than resorting the whole array. Would you be interested in
such a solution? Of course, the downside of sorted insertion is that
the array has to grow for each individual member being inserted.
Comment 1 Philipe Mulet CLA 2006-05-09 04:52:20 EDT
This is a regression over 3.2M5. Problem started to appear in 3.2M6.
Comment 2 Philipe Mulet CLA 2006-05-09 04:55:40 EDT
Thanks for reporting this in such a nice and simple way.
I will candidate this for being a "great bug".
Comment 3 Philipe Mulet CLA 2006-05-09 05:13:19 EDT
Created attachment 40693 [details]
Proposed patch

This patch doesn't perform sorting eagerly, simply reset the tagbits, so that next client will cause sorting. In case multiple members were to be inserted, this could allow batching them all.
Comment 4 Philipe Mulet CLA 2006-05-09 05:18:10 EDT
Raising severity since this is a regression introduced during 3.2 cycle (as a consequence of sorting methods for improved performance).
Fix is very local and uses same approach as already used in other places (just one place ommitted).

Dani/Martin: pls cast your vote. Without the fix, we reject valid code by mistake, and though this is a corner situation, it is still real code (considering code generators etc...).
Comment 5 Philipe Mulet CLA 2006-05-09 05:19:46 EDT
Added LookupTest#test070
Comment 6 Martin Aeschlimann CLA 2006-05-09 06:41:01 EDT
patch reviewed and ok for 3.2 RC4. 
Comment 7 Philipe Mulet CLA 2006-05-09 09:18:06 EDT
Adding Darin, since Dani is presenting at a conf right now.
Darin - would you cast your vote ?
Comment 8 Darin Wright CLA 2006-05-09 09:57:11 EDT
+1 
Comment 9 Philipe Mulet CLA 2006-05-09 10:59:41 EDT
Fixed released.
Comment 10 Frederic Fusier CLA 2006-05-10 09:32:26 EDT
Created attachment 40932 [details]
Additional patch

Resort methods explicitely instead of make it lazy as DOM needs eager sorting...
Comment 11 Philipe Mulet CLA 2006-05-10 10:05:43 EDT
New fix proved better, as UI tests need it.
Comment 12 Martin Aeschlimann CLA 2006-05-10 10:10:41 EDT
The TagBits.AreMethodsSorted bit gives the impression that there are states when the methods are not sorted. Are you saying that can not be the case (is TagBits.AreMethodsSorted dispensable?)
Comment 13 Philipe Mulet CLA 2006-05-10 11:17:07 EDT
The bit is used to record the fact the method array got sorted. We do not eagerly sort methods, until someone is trying to access them.
Comment 14 Stephan Herrmann CLA 2006-05-10 12:44:43 EDT
Created attachment 40964 [details]
alternative methods

Since eager vs. lazy seems to be an issue after all,
here are the methods we use for sorted insertion.
The first one (basically copied from binarySearch)
sits in ReferenceBinding, the second in SourceTypeBinding. 
With that, TypeDeclaration.createDefaultConstructorWithBinding
simply calls
   this.binding.addMethod(constructor.binding);
Use it if you like, else ignore it ;-)

PS: how come DOM seems to succeed reading an unsorted list?
Is someone bypassing ReferenceBinding.methods()?
Comment 15 Philipe Mulet CLA 2006-05-10 13:10:42 EDT
Thanks, looks nice. A bit overkill, but may include post 3.2.
The DOM didn't read unsorted list, simply failed to sort it lazily (since the code is also lazily resolving the methods, which is unneeded here, and a scope is required, but missing in DOM case after cleanup has run).

Comment 16 Olivier Thomann CLA 2006-05-11 22:22:08 EDT
Verified with I20060511-2000 for 3.2RC4.
Failed with RC3 and fixed with RC4.