Added WildcardTypeImpl implementation (minimal support).
[jpf-core.git] / src / classes / sun / reflect / generics / reflectiveObjects / WildcardTypeImpl.java
1 package sun.reflect.generics.reflectiveObjects;
2
3
4 import java.lang.reflect.Type;
5 import java.lang.reflect.WildcardType;
6 import sun.reflect.generics.factory.GenericsFactory;
7 import sun.reflect.generics.tree.FieldTypeSignature;
8 import sun.reflect.generics.visitor.Reifier;
9 import java.util.Arrays;
10
11
12 /**
13  * MJI model class for sun.reflect.generics.reflectiveObjects.WildcardTypeImpl
14  *
15  * This is a JPF specific version of a system class because we can't use the real,
16  * platform VM specific version (it's native all over the place, its field
17  * structure isn't documented, most of its methods are private, hence we can't
18  * even instantiate it properly).
19  *
20  * Note that this class never gets seen by the real VM - it's for JPF's eyes only.
21  *
22  */
23 public class WildcardTypeImpl extends LazyReflectiveObjectGenerator
24         implements WildcardType {
25
26     private Type[] upperBounds;
27     private Type[] lowerBounds;
28     private FieldTypeSignature[] upperBoundASTs;
29     private FieldTypeSignature[] lowerBoundASTs;
30
31     // constructor is private to enforce access through static factory
32     private WildcardTypeImpl(FieldTypeSignature[] ubs,
33                              FieldTypeSignature[] lbs,
34                              GenericsFactory f) {
35         super(f);
36         upperBoundASTs = ubs;
37         lowerBoundASTs = lbs;
38     }
39
40     public static WildcardTypeImpl make(FieldTypeSignature[] ubs,
41                                         FieldTypeSignature[] lbs,
42                                         GenericsFactory f) {
43         return new WildcardTypeImpl(ubs, lbs, f);
44     }
45
46     // Accessors
47     private FieldTypeSignature[] getUpperBoundASTs() {
48         throw new UnsupportedOperationException();
49     }
50
51     private FieldTypeSignature[] getLowerBoundASTs() {
52         throw new UnsupportedOperationException();
53     }
54
55     public Type[] getUpperBounds() {
56         return upperBounds;
57     }
58
59     public Type[] getLowerBounds() {
60         return lowerBounds;
61     }
62
63     public String toString() {
64         Type[] lowerBounds = getLowerBounds();
65         Type[] bounds = lowerBounds;
66         StringBuilder sb = new StringBuilder();
67
68         if (lowerBounds.length > 0)
69             sb.append("? super ");
70         else {
71             Type[] upperBounds = getUpperBounds();
72             if (upperBounds.length > 0 && !upperBounds[0].equals(Object.class) ) {
73                 bounds = upperBounds;
74                 sb.append("? extends ");
75             } else
76                 return "?";
77         }
78
79         // TODO: Commented out since it's producing <clinit> that blocks us from getting a new object without
80         // TODO: initializing it through the constructor.
81         //assert bounds.length > 0;
82
83         boolean first = true;
84         for(Type bound: bounds) {
85             if (!first)
86                 sb.append(" & ");
87
88             first = false;
89             sb.append(bound.getTypeName());
90         }
91         return sb.toString();
92     }
93
94     @Override
95     public boolean equals(Object o) {
96         if (o instanceof WildcardType) {
97             WildcardType that = (WildcardType) o;
98             return
99                     Arrays.equals(this.getLowerBounds(),
100                             that.getLowerBounds()) &&
101                             Arrays.equals(this.getUpperBounds(),
102                                     that.getUpperBounds());
103         } else
104             return false;
105     }
106
107     @Override
108     public int hashCode() {
109         Type [] lowerBounds = getLowerBounds();
110         Type [] upperBounds = getUpperBounds();
111
112         return Arrays.hashCode(lowerBounds) ^ Arrays.hashCode(upperBounds);
113     }
114 }