Bug 99931 - [DOM] Consider surfacing intersection types in ITypeBindings
Summary: [DOM] Consider surfacing intersection types in ITypeBindings
Status: NEW
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.1   Edit
Hardware: All All
: P3 enhancement (vote)
Target Milestone: ---   Edit
Assignee: JDT-Core-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 418756 (view as bug list)
Depends on:
Blocks: 204586 349875 349880 432175
  Show dependency tree
 
Reported: 2005-06-14 07:04 EDT by Markus Keller CLA
Modified: 2018-05-16 01:30 EDT (History)
11 users (show)

See Also:


Attachments
Proposed fix (9.77 KB, patch)
2011-04-04 16:08 EDT, Olivier Thomann CLA
no flags Details | Diff
New draft (22.96 KB, patch)
2011-04-05 11:19 EDT, Olivier Thomann CLA
no flags Details | Diff
Draft for JDT/UI (12.95 KB, patch)
2011-04-08 11:31 EDT, Markus Keller CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Markus Keller CLA 2005-06-14 07:04:10 EDT
I20050610-1757 (3.1RC2)

This is certainly not for 3.1, but we should discuss surfacing of intersection
types in ITypeBindings for 3.2.

Here's an example:
    void test(String s, Integer i) {
        combine(s, i).compareTo(null); //1
        Comparable comp= combine(s, i); //2
        java.io.Serializable ser= combine(s, i); //3
        combine(s, i); //4
        //bug99922 java.util.Arrays.asList(s, i);
    }

The type binding for combine(s, i) is currently a wildcard type
'? extends java.lang.Object'. Still, on line //1, the method
Comparable<?>#compareTo(?) is called on the wildcard type.

On lines //2 and //3, the RHS is of type '? extends java.lang.Object', which
cannot be assigned to Comparable or Serializable.

On line //4, the quick assist can only offer to create a local variable of type
Object, but Comparable and Serializable should also be proposed.

The only solution I see to solve these problems, is to surface intersection types.
Comment 1 Markus Keller CLA 2005-08-23 12:23:29 EDT
Oops, I forgot to post the declaration of combine(..):

    <T> T combine(T t1, T t2) {
        return Math.random() > 0 ? t1 : t2;
    }

Comment 2 Jerome Lanneluc CLA 2007-09-11 05:09:20 EDT
Item added on the 3.4 plan.
Comment 3 Jerome Lanneluc CLA 2008-02-13 12:03:03 EST
Time permitting for 3.4
Comment 4 Frederic Fusier CLA 2008-03-27 17:05:29 EDT
Unfortunately we could not handle this requirement on time before API freeze...
So, remove from 3.4 plan
Comment 5 Olivier Thomann CLA 2011-04-01 12:02:19 EDT
What APIs do you need for intersection types ?
Comment 6 Olivier Thomann CLA 2011-04-01 13:29:06 EDT
I think we need at least:
org.eclipse.jdt.core.dom.ITypeBinding.getIntersectionBounds()

The method org.eclipse.jdt.core.dom.ITypeBinding#getTypeBounds() would have been a good name, but in this case, the javadoc of the method makes it impossible to extend for intersection types.

We can also have isIntersectionType().

Beside this we might need to update sightly existing APIs to cover the intersection type case. Let me know if you want some other APIs.
Comment 7 Olivier Thomann CLA 2011-04-01 20:55:31 EDT
We need to adjust the getQualifiedName(), find a way to retrieve the bounds and update all ITypeBinding's methods to reflect the expected values for intersection types.
I'll work on that on Monday once we agree on the APIs.
Comment 8 Markus Keller CLA 2011-04-04 10:12:41 EDT
Currently, the ITypeBinding for intersection types is just plain wrong. Clients that relied on such bindings are already broken as of today, so I don't think it's a problem to "break" them again by making the bindings correct.

Proposed API changes:
- add isIntersection() (or isIntersectionType(), but the "Type" is redundant)
- use getTypeBounds() to return the components of the intersection type

The next question is whether isIntersection() returns true for capture types and type variables that have multiple bounds. Given the existing Javadoc for isCapture() and isTypeVariable(), I'd say it should return false for those.
Comment 9 Olivier Thomann CLA 2011-04-04 16:08:02 EDT
Created attachment 192499 [details]
Proposed fix

Need to define the binding's key for intersection type and get the org.eclipse.jdt.internal.core.util.BindingKeyResolver being able to handle the new key.
Comment 10 Markus Keller CLA 2011-04-05 10:59:19 EDT
(In reply to comment #9)
> Created attachment 192499 [details] [diff]
> Proposed fix

The Javadoc of ITypeBinding#isIntersection() contains some wrongly copied statements about capture types.

Javadoc of other methods of ITypeBinding and IBinding that mention specific kinds of types (e.g. capture types) also need to mention intersection types (e.g. getJavaElement(), getDeclaredTypes(), etc.).
Comment 11 Olivier Thomann CLA 2011-04-05 11:19:35 EDT
Created attachment 192567 [details]
New draft

This should fix most documentation and contains a first draft of the intersection type key. This is untested for now.
Comment 12 Markus Keller CLA 2011-04-05 11:30:29 EDT
More problems in Javadoc of getQualifiedName():

 * <li>For intersection types, the fully qualified name is "?" optionally followed by
 * a single space followed by the keyword "extends"
 * followed a single space followed by the fully qualified name of the bound
 * (as computed by this method) when present followed by other bounds separated with '&'.

=> The "optionally" is ambiguous (problem as already in spec for wildcard types): It can also mean that just the space is optional. Better write like this:
 * <li>For intersection types, the fully qualified name is "?", optionally
 * followed by " extends ", the fully qualified name of the bound
 * (as computed by this method) when present, and the other bounds separated with " & ".
=> Also note the added spaces around the '&'.
Comment 13 Olivier Thomann CLA 2011-04-05 12:00:34 EDT
I think we should really go for:
=> 
 * <li>For intersection types, the fully qualified name is "?",
 * followed by " extends ", the fully qualified name of the bound
 * (as computed by this method), and the fully qualified name of other bounds 
 * (as computed by this method) separated with " & ".

Intersection types always have a bound and other bounds.
Comment 14 Olivier Thomann CLA 2011-04-05 12:50:18 EDT
I think the key work doesn't work well. Right now I tried to mimic the intersection type binding key with what has been done for wildcard, but the bounds are not preserved properly once the key is converted to a signature.
So this goes back to bug 340059 where we need a good support for intersection type signature.
Comment 15 Markus Keller CLA 2011-04-06 15:15:55 EDT
I looked some more into this, and I'm not sure any more if it's a good idea to try to push this into 3.7 or 3.7.1 or 3.7+BETA_JAVA7.

We've been living with this problem for quite some time now without anybody even noticing. The example from bug 340059 comment 7 is also contrived. In practice, I think most disjunctive types will have a normal reference type as lub (not an intersection type). To get an intersection type, you need to have interfaces in the game (which are rarely used for exceptions).
Comment 16 Markus Keller CLA 2011-04-08 11:31:07 EDT
Created attachment 192848 [details]
Draft for JDT/UI

Based on the latest JDT Core patch. This would need quite some more work (complete TTypes support, check all references to ITypeBinding).
Comment 17 Markus Keller CLA 2014-04-07 13:05:28 EDT
We should take this up for 4.5.

With the new IntersectionCastTypeBinding, things got worse, and with Java 8, intersection types can show up in more situations than the ones considered rare in comment 15. See e.g. bug 432175.
Comment 18 Markus Keller CLA 2014-04-29 11:04:19 EDT
*** Bug 418756 has been marked as a duplicate of this bug. ***
Comment 19 Manoj N Palat CLA 2015-04-07 23:19:21 EDT
Early 4.6 target would be ideal. moving this out of 4.5
Comment 20 Manoj N Palat CLA 2018-05-16 01:30:43 EDT
Bulk move out of 4.8