package bluej.debugger.gentype;
import java.util.*;
| Represents an intersection type, eg. I1&I2&I3 as specified in the Java Language
| Specification.
|
| @author Davin McCall
|
public class IntersectionType
extends GenTypeSolid{
private GenTypeSolid [] intersectTypes;
private IntersectionType(GenTypeSolid [] types)
{
if (types.length == 0) {
throw new IllegalArgumentException();
}
intersectTypes = types;
}
| Factory method. Avoids creation of an intersection to hold only one type.
|
| @param types The types to create an intersection of
| @return The intersection of the given types
|
public static GenTypeSolid getIntersection(GenTypeSolid [] types)
{
if (types.length == 1)
return types[0];
List<GenTypeSolid> allTypes = new ArrayList<GenTypeSolid>(types.length);
for (GenTypeSolid type : types) {
for (GenTypeSolid itype : type.getIntersectionTypes()) {
allTypes.add(itype);
}
}
ArrayList<GenTypeSolid> nonclasstypes = new ArrayList<GenTypeSolid>();
GenTypeClass classtype = null;
for (int i = 0; i < types.length; i++) {
GenTypeClass tclass = types[i].asClass();
if (tclass != null && ! tclass.isInterface()) {
if (classtype == null)
classtype = tclass;
else {
classtype = combineClasses(tclass, classtype);
}
}
else {
nonclasstypes.add(types[i]);
}
}
if (classtype != null)
nonclasstypes.listIterator().add(classtype);
if (nonclasstypes.size() == 1)
return nonclasstypes.get(0);
return new IntersectionType(nonclasstypes.toArray(new GenTypeSolid[nonclasstypes.size()]));
}
| Convenience method to get the intersection of two types.
| @param a The first type
| @param b The second type
| @return The intersection of the two types
|
public static GenTypeSolid getIntersection(GenTypeSolid a, GenTypeSolid b)
{
return getIntersection(new GenTypeSolid [] {a, b
});
}
| Combine two classes, to yield one class which is the intersection of both.
| @param a The first class
| @param b The second class
| @return The intersection (as a single class)
|
public static GenTypeClass combineClasses(GenTypeClass a, GenTypeClass b)
{
GenTypeClass aE = (GenTypeClass) a.getErasedType();
GenTypeClass bE = (GenTypeClass) b.getErasedType();
if (! aE.equals(bE)) {
if (aE.isAssignableFrom(bE)) {
a = (GenTypeClass) a.mapToDerived(bE.reflective);
}
else {
b = (GenTypeClass) b.mapToDerived(aE.reflective);
}
}
if (a.isRaw())
return b;
if (b.isRaw())
return a;
GenTypeClass outer = null;
if (a.outer != null) {
outer = combineClasses(a.outer, b.outer);
}
List<GenTypeParameter> newParams = null;
if (a.params != null) {
newParams = new ArrayList<GenTypeParameter>();
Iterator<? extends GenTypeParameter> ia = a.params.iterator();
Iterator<? extends GenTypeParameter> ib = b.params.iterator();
while (ia.hasNext()){
GenTypeParameter tpa = ia.next();
GenTypeParameter tpb = ib.next();
newParams.add(tpa.precisify(tpb));
}
}
return new GenTypeClass(a.reflective, newParams, outer);
}
public String toString(NameTransform nt)
{
String xx = intersectTypes[0].toString();
if (intersectTypes.length > 1 && xx.equals("java.lang.Object")) {
return intersectTypes[1].toString(nt);
}
else {
return intersectTypes[0].toString(nt);
}
}
public String toTypeArgString(NameTransform nt)
{
return "? extends " + toString(nt);
}
public boolean isInterface()
{
return false;
}
public GenTypeSolid[] getLowerBounds()
{
return new GenTypeSolid[] {this
};
}
public GenTypeSolid mapTparsToTypes(Map<String, ? extends GenTypeParameter> tparams)
{
GenTypeSolid [] newIsect = new GenTypeSolid[intersectTypes.length];
for (int i = 0; i < intersectTypes.length; i++) {
newIsect[i] = (GenTypeSolid) intersectTypes[i].mapTparsToTypes(tparams);
}
return new IntersectionType(newIsect);
}
public boolean equals(JavaType other)
{
if (other == null)
return false;
if (other instanceof JavaType) {
JavaType otherJT = (JavaType) other;
return isAssignableFrom(otherJT) && otherJT.isAssignableFrom(this);
}
return false;
}
public void getParamsFromTemplate(Map<String,GenTypeParameter> map, GenTypeParameter template)
{
return;
}
public GenTypeParameter precisify(GenTypeParameter other)
{
throw new UnsupportedOperationException();
}
public String arrayComponentName()
{
return getErasedType().arrayComponentName();
}
public JavaType getErasedType()
{
return intersectTypes[0].getErasedType();
}
public boolean isAssignableFrom(JavaType t)
{
for (int i = 0; i < intersectTypes.length; i++) {
if (intersectTypes[i].isAssignableFrom(t))
return true;
}
return false;
}
public boolean isAssignableFromRaw(JavaType t)
{
for (int i = 0; i < intersectTypes.length; i++) {
if (intersectTypes[i].isAssignableFromRaw(t))
return true;
}
return false;
}
public void erasedSuperTypes(Set<Reflective> s)
{
for (int i = 0; i < intersectTypes.length; i++) {
intersectTypes[i].erasedSuperTypes(s);
}
}
public GenTypeClass [] getReferenceSupertypes()
{
ArrayList<GenTypeClass> rsupTypes = new ArrayList<GenTypeClass>();
for (int i = 0; i < intersectTypes.length; i++) {
GenTypeClass [] isTypes = intersectTypes[i].getReferenceSupertypes();
for (int j = 0; j < isTypes.length; j++) {
rsupTypes.add(isTypes[j]);
}
}
return rsupTypes.toArray(new GenTypeClass[rsupTypes.size()]);
}
@Override
public GenTypeArray getArray()
{
return new GenTypeArray(this);
}
@Override
public GenTypeSolid[] getIntersectionTypes()
{
return intersectTypes;
}
}
top,
use,
map,
class IntersectionType
. IntersectionType
. getIntersection
. getIntersection
. combineClasses
. toString
. toTypeArgString
. isInterface
. getLowerBounds
. mapTparsToTypes
. equals
. getParamsFromTemplate
. precisify
. arrayComponentName
. getErasedType
. isAssignableFrom
. isAssignableFromRaw
. erasedSuperTypes
. getReferenceSupertypes
. getArray
. getIntersectionTypes
326 neLoCode
+ 14 LoComm