package bluej.debugger.gentype;

import java.util.*;


| Represent a (possibly generic) type. This can include wildcard types, | type parameters, etc; ie. anything that JDK 1.5 "Type" can represent. |* * Objects of this type are immutable. * * @author Davin McCall */ public class GenTypeClass extends GenTypeSolid{ // ---------- Instance fields ----------- /** List of type parameters; null if none (there may be an outer class with parameters) protected List<? extends GenTypeParameter> params = null; protected Reflective reflective = null;
| Outer class, *iff* an outer class has type parameters; otherwise null | protected GenTypeClass outer = null; | Constructor for a non-generic class type. | | @param r The Reflective representing the class. | public GenTypeClass(Reflective r) { reflective = r; }
| New GenTypeClass from a reflective and an ordered list of type parameters | | @param r The Reflective representing the class. | @param params A list of GenTypeParameterizables giving the type | parameters in declaration order | public GenTypeClass(Reflective r, List<GenTypeParameter> params) { this(r, params, null); }
| New GenTypeClass from a reflective and an ordered list of type | parameters, representing an inner class of a specified class. | This should only be used if the outer class is generic AND this inner | class is a non-static inner class.<p> | | <i>outer</i> may be null, to specify no outer class. In this case this | constructor is equivalent to GenTypeClass(r, params). | | @param r The Reflective representing the class. | @param params A list of GenTypeParameter giving the type | parameters in declaration order | public GenTypeClass(Reflective r, List<? extends GenTypeParameter> params, GenTypeClass outer) { reflective = r; if (params != null && ! params.isEmpty()) { this.params = params; } this.outer = outer; }
| New GenTypeClass from a reflective and map of type parameter names to | types. For type parameters not in the map, the base type is used (as | a wilcard with "extends" clause). If the map is null however, the type |* is treated as a raw type. * * @param r The Reflective representing the class. * @param mparams A map of String -> GenTypeParameter giving the | type parameters. The map may be modified (if it is not | empty) by this constructor. | public GenTypeClass(Reflective r, Map<String,GenTypeParameter> mparams) { reflective = r; if (mparams == null) { return; } List<GenTypeParameter> params = new ArrayList<GenTypeParameter>(); Iterator<GenTypeDeclTpar> declParmsI = r.getTypeParams().iterator(); while ( declParmsI.hasNext() ) { GenTypeDeclTpar next = declParmsI.next(); String nextName = next.getTparName(); if (mparams.get(nextName) == null) params.add(new GenTypeExtends(next.getBound())); else { params.add((GenTypeParameter) mparams.get(nextName)); mparams.remove(nextName); } } if (params.isEmpty()) { params = null; } this.params = params; if (! mparams.isEmpty() && ! r.isStatic()) { Reflective outerReflective = r.getOuterClass(); if (outerReflective != null) { outer = new GenTypeClass(outerReflective, mparams); } } } public GenTypeClass asClass() { return this; } public GenTypeClass getErasedType() { return new GenTypeClass(reflective); }
| Get the name of the type as known to the classloader. The name returned is | encoded so that it can be passed to a ClassLoader's "loadClass" method (dots |* between outer and inner class names are changed to '$', and arrays are * encoded). */ public String classloaderName() { return reflective.getName(); } public String arrayComponentName() | |{ | |return "L" + classloaderName() + ";"; } /** * Return an unmodifiable list of the type parameters applied to the * innermost class in this generic type. */ public List<? extends GenTypeParameter> getTypeParamList() | |{ | |if (params == null) | |return Collections.emptyList(); | |else{ return params; | |} | |} | |/** | Get the containing type. If this is a generic type whose class is an | inner class, and an outer class is also generic, this will return the | outer class of the class type. NOTE, it will not necessarily work if | no outer class is generic, or if this is a raw type! | public GenTypeClass getOuterType() { return outer; }
| Determine whether this class is an inner type. This works regardless | of whether outer types are generic etc. | public boolean isInnerType() { return reflective.getName().indexOf('$') != -1; }
| Check whether the type is a generic type (with type parameters). | Returns false for parameterless types and raw types. | | @return true if the type has type parameters | public boolean isGeneric() { if (outer != null) return true; else{ return (params != null); } }
| Check whether this is a raw type, ie. a generic class type with no | type parameter substitutions supplied. (Return is false for a non- | generic class type). | | @return true if the type is a raw type | public boolean isRaw() { if (outer != null || params != null) { return false; } Reflective r = reflective; List<?> formalParams = reflective.getTypeParams(); while (formalParams.isEmpty()){ if (r.isStatic()) { return false; } r = r.getOuterClass(); if (r == null) { return false; } formalParams = r.getTypeParams(); } return true; } public boolean isInterface() { return reflective.isInterface(); } public String toString(NameTransform nt) { String baseClass = classloaderName(); if (outer != null) { int i = baseClass.lastIndexOf('$'); baseClass = outer.toString(nt) + '.' + baseClass.substring(i + 1); } else { baseClass = nt.transform(baseClass); baseClass = baseClass.replace('$', '.'); } if (params == null) return baseClass; String r = baseClass + '<'; for (Iterator<? extends GenTypeParameter> i = params.iterator(); i.hasNext(); ) { r += i.next().toTypeArgString(nt); if ( i.hasNext() ) r += ','; } r += '>'; return r; } public String toTypeArgString(NameTransform nt) { return toString(nt); } public boolean equals(JavaType other) { if (other == this) return true; if (other == null) return false; GenTypeClass oClass = other.asClass(); if (oClass == null) { return false; } JavaType arrayComponent = getArrayComponent(); JavaType oarrayComponent = oClass.getArrayComponent(); if (arrayComponent != null) { return arrayComponent.equals(oarrayComponent); } else if (oarrayComponent != null) { return false; } if (! classloaderName().equals(oClass.classloaderName())) return false; if (outer == null && oClass.outer != null) return false; if (outer != null) if (! outer.equals(oClass.outer)) return false; if (params == null) { return oClass.params == null; } else if (oClass.params == null) { return false; } Iterator<? extends GenTypeParameter> i = params.iterator(); Iterator<? extends GenTypeParameter> j = oClass.params.iterator(); while ( i.hasNext() ) { if ( ! j.hasNext() || ! i.next().equals(j.next())) { return false; } } if ( j.hasNext() ) return false; return true; }
| Get the reflective represented by this GenTypeClass. This can return null | if the GenTypeClass represents an array. | public Reflective getReflective() { return reflective; }
| | Note this does not handle boxing/unboxing conversions. | | (non-Javadoc) | @see bluej.debugger.gentype.JavaType#isAssignableFrom(bluej.debugger.gentype.JavaType) | public boolean isAssignableFrom(JavaType t) { if (t.isNull()) return true; if (! (t instanceof GenTypeSolid) ) return false; GenTypeClass tc = t.asClass(); if (tc != null) { if (isRaw()) { return reflective.isAssignableFrom(tc.reflective); } GenTypeClass cclass = this; GenTypeClass tclass; try { tclass = tc.mapToSuper(reflective.getName()); } catch (BadInheritanceChainException bice) { return false; } if (tclass.isRaw()) return false; while (cclass != null){ if (cclass.params != null) { Iterator<? extends GenTypeParameter> i = cclass.params.iterator(); Iterator<? extends GenTypeParameter> j = tclass.params.iterator(); while (i.hasNext()){ GenTypeParameter cpar = i.next(); GenTypeParameter tpar = j.next(); if (! cpar.contains(tpar)) return false; } } cclass = cclass.outer; tclass = tclass.outer; } return true; } GenTypeClass [] stypes = ((GenTypeSolid) t).getReferenceSupertypes(); for (int i = 0; i < stypes.length; i++) { if (isAssignableFrom(stypes[i])) return true; } return false; } public boolean isAssignableFrom(GenTypeClass c) { Reflective r = c.reflective; if ( getInheritanceChain(r, reflective.getName()) != null) { GenTypeClass other = c.mapToSuper(reflective.getName()); if (isRaw() || other.isRaw()) return true; if (outer != null) { if (! outer.isAssignableFrom(other.outer)) return false; } if (params != null) { Iterator<? extends GenTypeParameter> i = params.iterator(); Iterator<? extends GenTypeParameter> j = other.params.iterator(); while (i.hasNext()){ GenTypeParameter myParam = i.next(); GenTypeParameter oParam = j.next(); if (! myParam.contains(oParam)) return false; } } return true; } return false; } public boolean isAssignableFromRaw(JavaType t) { if (! (t instanceof GenTypeClass)) return false; GenTypeClass c = (GenTypeClass) t; Reflective r = c.reflective; if ( getInheritanceChain(r, reflective.getName()) != null) return true; else{ return false; } }
| Map the type parameters in a base type to a super type, apply the | resulting type parameters to the super type, and return the result. | | For instance, if A<T> extends B<U>, Then to map an instance | of A<Integer> to B, pass "B" as the super type; The return is |* then B<Integer>. * * @param subType the supertype to map from * @param basename the fully-qualified name of the base type to map to * * @throws BadInheritanceChainException public GenTypeClass mapToSuper(String basename) { if ( classloaderName().equals(basename)) return this; Stack<Reflective> inheritanceStack = getInheritanceChain(reflective, basename); if ( inheritanceStack == null ) { throw new BadInheritanceChainException(); } String bname; Iterator<Reflective> i = inheritanceStack.iterator(); i.next(); Reflective baseType; Reflective subType = reflective; GenTypeClass ccc = this; do { baseType = (Reflective)i.next(); bname = baseType.getName(); Map<String,GenTypeParameter> tparams = ccc.getMap(); ccc = mapGenericParamsToDirectBase(tparams, subType, baseType); subType = baseType; } while ( ! bname.equals(basename) ); return ccc; }
| Worker function for mapGenericParamsToBase. Maps only to a direct base. | @param tparams a Map of String -> GenTypeClass | @param subType the derived type | @param baseType the base type | private static GenTypeClass mapGenericParamsToDirectBase(Map<String,? extends GenTypeParameter> tparams, Reflective subType, Reflective baseType) { GenTypeClass baseClass = subType.superTypeByName(baseType.getName()); if (tparams == null) { return new GenTypeClass(baseClass.reflective); } baseClass = (GenTypeClass) baseClass.mapTparsToTypes(tparams); return baseClass; }
| Return the corresponding type if all type parameters are replaced with | corresponding actual types, as defined by a Map (String -> GenType). | | @param tparams A map defining the translation from type parameter | name (String) to its actual type (GenType). The map | can be null to return the raw type. | @return the corresponding type structure, with parameters mapped. | public GenTypeClass mapTparsToTypes(Map<String, ? extends GenTypeParameter> tparams) { if ( params == null && outer == null ) return this; if (tparams == null) { return new GenTypeClass(reflective); } List<GenTypeParameter> retlist = new ArrayList<GenTypeParameter>(); if (params != null) { Iterator<? extends GenTypeParameter> i = params.iterator(); while ( i.hasNext() ) { retlist.add(i.next().mapTparsToTypes(tparams)); } } GenTypeClass newOuter = null; if (outer != null) { newOuter = (GenTypeClass) outer.mapTparsToTypes(tparams); } return new GenTypeClass(reflective, retlist, newOuter); } public GenTypeClass mapToDerived(Reflective derivedType) { if (! isGeneric() ) return new GenTypeClass(derivedType); if ( derivedType.getName().equals(classloaderName())) return this; Stack<Reflective> classes = getInheritanceChain(derivedType, classloaderName()); if ( classes == null ) return null; GenTypeClass curBaseC = this; classes.pop(); while ( ! classes.empty() ) { Reflective curSubtype = (Reflective)classes.pop(); HashMap<String,GenTypeParameter> newMap = new HashMap<String,GenTypeParameter>(); GenTypeClass baseDecl = curSubtype.superTypeByName(curBaseC.classloaderName()); if (baseDecl.isRaw()) { return new GenTypeClass(derivedType); } baseDecl.getParamsFromTemplate(newMap, curBaseC); curBaseC = new GenTypeClass(curSubtype, newMap); } return curBaseC; }
| Get a map of type parameter names to the corresponding types, for this | type. The returned map is a mutable copy, that is, it can freely be | modified by the caller without affecting this GenTypeClass object. | | <p>Returns null if this represents a raw type, or an empty map if the | type is not a generic type. | | <p>Note that a map is not enough to completely describe a type, due to | the possibility of inner/outer types having type parameters with the | same name. | | @return the map (of String -> GenTypeParameterizable). | public Map getMap() { if (isRaw()) { return null; } HashMap<String,GenTypeParameter> r = new HashMap<String,GenTypeParameter>(); mergeMap(r); return r; }
| Get a map of type parameter names to the corresponding types, for this | type. Existing entries in the map will be overwritten. | | The returned does not indicate if this type is a raw type. | public void mergeMap(Map<String, GenTypeParameter> m) { if (outer != null) { outer.mergeMap(m); } List<GenTypeDeclTpar> formalParams = reflective.getTypeParams(); if ( params == null ) { return; } Iterator<? extends GenTypeParameter> paramIterator = params.iterator(); Iterator<GenTypeDeclTpar> formalIterator = formalParams.iterator(); while (paramIterator.hasNext() && formalIterator.hasNext()) { GenTypeParameter paramType = paramIterator.next(); GenTypeDeclTpar formalType = (GenTypeDeclTpar)formalIterator.next(); String paramName = formalType.getTparName(); m.put(paramName, paramType); } }
| Determine the inheritance, or implementation chain between two different | types. For instance, if A extends B and B extends C, the chain between | A and C is "A,B,C". Likewise, if D implements E which extends F, the |* chain between D and F is "D,E,F". * * returns a Stack of Reflective. */ private static Stack<Reflective> getInheritanceChain(Reflective top, String bottom) { Stack<Reflective> r = new Stack<Reflective>(); r.push(top); | |if ( top.getName().equals(bottom )) { | |return r; | |} | |// Go through each base/interface and try to discover the hieararchy | |List<Reflective> l = top.getSuperTypesR(); | |for (Iterator<Reflective> i = l.iterator(); i.hasNext(); ) { | |Reflective next = i.next(); | |Stack<Reflective> r2 = getInheritanceChain(next, bottom); | |if ( r2 != null ) { | |r.addAll(r2); | |return r; | |} | |} | |return null; | |} | |/* | see bluej.debugger.gentype.GenTypeSolid#getParamsFromTemplate(java.util.Map, bluej.debugger.gentype.GenTypeParameterizable) | public void getParamsFromTemplate(Map<String,GenTypeParameter> r, GenTypeParameter template) { if (template instanceof GenTypeClass) { GenTypeClass classTemplate = (GenTypeClass) template; if (classTemplate.classloaderName().equals(classloaderName())) { if (params == null || classTemplate.params == null) return; Iterator<? extends GenTypeParameter> i = params.iterator(); Iterator<? extends GenTypeParameter> j = classTemplate.params.iterator(); if (outer != null) outer.getParamsFromTemplate(r, classTemplate.outer); while (i.hasNext() && j.hasNext()){ GenTypeSolid ip = (GenTypeSolid) i.next(); GenTypeParameter jp = j.next(); ip.getParamsFromTemplate(r, jp); } } } return; } public void erasedSuperTypes(Set<Reflective> s) { Stack<Reflective> refs = new Stack<Reflective>(); refs.push(reflective); while (! refs.empty()) { Reflective r = (Reflective) refs.pop(); if (! s.contains(r)) { s.add(r); refs.addAll(r.getSuperTypesR()); } } } public GenTypeClass [] getReferenceSupertypes() { return new GenTypeClass[] {this }; } @Override public GenTypeClass getArray() { return new GenTypeArrayClass(reflective.getArrayOf(), this); } @Override public GenTypeClass getCapture() { if (outer == null && params == null) { return this; } GenTypeClass outerCapture = outer == null ? null : outer.getCapture(); boolean isDifferent = outerCapture != outer; List<JavaType> capturedParams = null; if (params != null) { capturedParams = new ArrayList<JavaType>(params.size()); for (GenTypeParameter param : params) { JavaType captured = param.getTparCapture(); isDifferent |= captured != param; capturedParams.add(captured); } } if (isDifferent) { return new GenTypeClass(reflective, capturedParams, outerCapture); } return this; } }

.   GenTypeClass
.   GenTypeClass
.   GenTypeClass
.   GenTypeClass
.   asClass
.   getErasedType
.   getOuterType
.   isInnerType
.   isGeneric
.   isRaw
.   isInterface
.   toString
.   toTypeArgString
.   equals
.   getReflective
.   isAssignableFrom
.   isAssignableFrom
.   isAssignableFromRaw
.   mapToSuper
.   mapGenericParamsToDirectBase
.   mapTparsToTypes
.   mapToDerived
.   getMap
.   mergeMap
.   getParamsFromTemplate
.   erasedSuperTypes
.   getReferenceSupertypes
.   getArray
.   getCapture




793 neLoCode + 99 LoComm