Bug 103044 - [import rewrite] Problems with nested captures in quick fixes and extract ... refactorings
Summary: [import rewrite] Problems with nested captures in quick fixes and extract ......
Status: RESOLVED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 3.1   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.2 M4   Edit
Assignee: Martin Aeschlimann CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-07-07 13:39 EDT by Markus Keller CLA
Modified: 2005-12-08 12:06 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 Markus Keller CLA 2005-07-07 13:39:06 EDT
I20050627-1435 (3.1)

We have a problem calculating the correct type declaration of variables to which
an expression with a type of the form A<B<capture-of-?>> should be assigned.

Such an expression cannot be assigned to a variable of type A<B<?>>, since the
type arguments B<capture-of-?> and B<?> are not equal.
An A<B<capture-of-?>> can only be assigned to a variable of type A<? extends B<?>>.

Example: Assigning Collections.nCopies(2, list) to a new local results in a
compile error here:

void assignToNewLocal(ArrayList<?> list) {
    List<ArrayList<?>> dups= Collections.nCopies(2, list); // illegal
    List<? extends ArrayList<?>> extDups= Collections.nCopies(2, list); //legal
}

The javadoc of ImportRewrite#addImport(ITypeBinding, AST) already tells: "The
returned type node represents a type to which the type binding can be assigned
or casted to.". Easiest would be if the ImportRewrite could also handle this
situation correctly. I.e. it should replace the pattern 'B<capture-of-?>' by '?
extends B<?>' if it occurs in a type argument list. If 'B<capture-of-?>' appears
as top-level type, it should be replaced by 'B<?>' (works already).


Here are some more examples:

void extractLocal(HashMap<String, ? extends Number> nameToNumber) {
    // legal:
    Entry<String, ? extends Number> item=
        nameToNumber.entrySet().iterator().next();

    // illegal:
    Set<Entry> set= nameToNumber.entrySet();
    Set<Entry<String, ? extends Number>> entrySet= nameToNumber.entrySet();

    // legal:
    Set<? extends Entry> extSet= nameToNumber.entrySet();
    Set<? extends Entry<String, ? extends Number>> extEntrySet=
        nameToNumber.entrySet();
}
Comment 1 Dirk Baeumer CLA 2005-07-13 17:57:50 EDT
Martin, can you please comment on adding this to the import rewrite ?
Comment 2 Dirk Baeumer CLA 2005-07-14 11:16:31 EDT
And is this something we want to fix for 3.1.1 as well ?
Comment 3 Dirk Baeumer CLA 2005-07-26 06:51:42 EDT
Ping...
Comment 4 Martin Aeschlimann CLA 2005-07-26 07:00:42 EDT
It's not a trivial topic. Changing the import rewrite seems to much for me for
3.1.1. 
Comment 5 Dirk Baeumer CLA 2005-07-28 08:51:11 EDT
Martin, from the discussion I remember that the problem is that we have to
distinguish between LHS and RHS types. Since the majority of the cases will be
the LHS case could we fix it for this case only ?
Comment 6 Martin Aeschlimann CLA 2005-07-28 10:36:30 EDT
Changing the import rewrite to automatically normalize the type for LHS types, 
makes it impossible for me to use it for my code that does the RHS transformation.

It seems we can't avoid to add another boolean to the import rewrite.
Comment 7 Martin Aeschlimann CLA 2005-08-19 09:55:20 EDT
I would have to do this after my absense. But, I think it's too advanced for 3.1.1.
Comment 8 Dirk Baeumer CLA 2005-08-19 11:39:19 EDT
This only is an issue if the wildcard shows up on the first level of a
parameterized type and the method taking such a parameterized type and wraps it
into another parameterized type. 

Therefore opt to only fix it in 3.2.
Comment 9 Martin Aeschlimann CLA 2005-12-08 12:06:06 EST
fixed in NewImportRewrite > 20051208