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