|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
package sun.reflect.generics.visitor; |
|
|
|
|
|
import java.lang.reflect.Type; |
|
import java.util.List; |
|
import java.util.Iterator; |
|
import sun.reflect.generics.tree.*; |
|
import sun.reflect.generics.factory.*; |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public class Reifier implements TypeTreeVisitor<Type> { |
|
private Type resultType; |
|
private GenericsFactory factory; |
|
|
|
private Reifier(GenericsFactory f){ |
|
factory = f; |
|
} |
|
|
|
private GenericsFactory getFactory(){ return factory;} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public static Reifier make(GenericsFactory f){ |
|
return new Reifier(f); |
|
} |
|
|
|
// Helper method. Visits an array of TypeArgument and produces |
|
|
|
private Type[] reifyTypeArguments(TypeArgument[] tas) { |
|
Type[] ts = new Type[tas.length]; |
|
for (int i = 0; i < tas.length; i++) { |
|
tas[i].accept(this); |
|
ts[i] = resultType; |
|
} |
|
return ts; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public Type getResult() { assert resultType != null;return resultType;} |
|
|
|
public void visitFormalTypeParameter(FormalTypeParameter ftp){ |
|
resultType = getFactory().makeTypeVariable(ftp.getName(), |
|
ftp.getBounds()); |
|
} |
|
|
|
|
|
public void visitClassTypeSignature(ClassTypeSignature ct){ |
|
// This method examines the pathname stored in ct, which has the form |
|
// n1.n2...nk<targs>.... |
|
// where n1 ... nk-1 might not exist OR |
|
// nk might not exist (but not both). It may be that k equals 1. |
|
// The idea is that nk is the simple class type name that has |
|
// any type parameters associated with it. |
|
// We process this path in two phases. |
|
// First, we scan until we reach nk (if it exists). |
|
// If nk does not exist, this identifies a raw class n1 ... nk-1 |
|
// which we can return. |
|
// if nk does exist, we begin the 2nd phase. |
|
// Here nk defines a parameterized type. Every further step nj (j > k) |
|
// down the path must also be represented as a parameterized type, |
|
// whose owner is the representation of the previous step in the path, |
|
// n{j-1}. |
|
|
|
|
|
List<SimpleClassTypeSignature> scts = ct.getPath(); |
|
assert(!scts.isEmpty()); |
|
Iterator<SimpleClassTypeSignature> iter = scts.iterator(); |
|
SimpleClassTypeSignature sc = iter.next(); |
|
StringBuilder n = new StringBuilder(sc.getName()); |
|
boolean dollar = sc.getDollar(); |
|
|
|
// phase 1: iterate over simple class types until |
|
|
|
while (iter.hasNext() && sc.getTypeArguments().length == 0) { |
|
sc = iter.next(); |
|
dollar = sc.getDollar(); |
|
n.append(dollar?"$":".").append(sc.getName()); |
|
} |
|
|
|
// Now, either sc is the last element of the list, or |
|
|
|
assert(!(iter.hasNext()) || (sc.getTypeArguments().length > 0)); |
|
|
|
Type c = getFactory().makeNamedType(n.toString()); |
|
|
|
if (sc.getTypeArguments().length == 0) { |
|
|
|
assert(!iter.hasNext()); |
|
resultType = c; |
|
} else { |
|
assert(sc.getTypeArguments().length > 0); |
|
// otherwise, we have type arguments, so we create a parameterized |
|
// type, whose declaration is the raw type c, and whose owner is |
|
// the declaring class of c (if any). This latter fact is indicated |
|
// by passing null as the owner. |
|
|
|
Type[] pts = reifyTypeArguments(sc.getTypeArguments()); |
|
|
|
Type owner = getFactory().makeParameterizedType(c, pts, null); |
|
|
|
dollar =false; |
|
while (iter.hasNext()) { |
|
sc = iter.next(); |
|
dollar = sc.getDollar(); |
|
n.append(dollar?"$":".").append(sc.getName()); |
|
c = getFactory().makeNamedType(n.toString()); |
|
pts = reifyTypeArguments(sc.getTypeArguments()); |
|
// Create a parameterized type, based on type args, raw type |
|
|
|
owner = getFactory().makeParameterizedType(c, pts, owner); |
|
} |
|
resultType = owner; |
|
} |
|
} |
|
|
|
public void visitArrayTypeSignature(ArrayTypeSignature a){ |
|
|
|
a.getComponentType().accept(this); |
|
Type ct = resultType; |
|
resultType = getFactory().makeArrayType(ct); |
|
} |
|
|
|
public void visitTypeVariableSignature(TypeVariableSignature tv){ |
|
resultType = getFactory().findTypeVariable(tv.getIdentifier()); |
|
} |
|
|
|
public void visitWildcard(Wildcard w){ |
|
resultType = getFactory().makeWildcard(w.getUpperBounds(), |
|
w.getLowerBounds()); |
|
} |
|
|
|
public void visitSimpleClassTypeSignature(SimpleClassTypeSignature sct){ |
|
resultType = getFactory().makeNamedType(sct.getName()); |
|
} |
|
|
|
public void visitBottomSignature(BottomSignature b){ |
|
|
|
} |
|
|
|
public void visitByteSignature(ByteSignature b){ |
|
resultType = getFactory().makeByte(); |
|
} |
|
|
|
public void visitBooleanSignature(BooleanSignature b){ |
|
resultType = getFactory().makeBool(); |
|
} |
|
|
|
public void visitShortSignature(ShortSignature s){ |
|
resultType = getFactory().makeShort(); |
|
} |
|
|
|
public void visitCharSignature(CharSignature c){ |
|
resultType = getFactory().makeChar(); |
|
} |
|
|
|
public void visitIntSignature(IntSignature i){ |
|
resultType = getFactory().makeInt(); |
|
} |
|
|
|
public void visitLongSignature(LongSignature l){ |
|
resultType = getFactory().makeLong(); |
|
} |
|
|
|
public void visitFloatSignature(FloatSignature f){ |
|
resultType = getFactory().makeFloat(); |
|
} |
|
|
|
public void visitDoubleSignature(DoubleSignature d){ |
|
resultType = getFactory().makeDouble(); |
|
} |
|
|
|
public void visitVoidDescriptor(VoidDescriptor v){ |
|
resultType = getFactory().makeVoid(); |
|
} |
|
|
|
|
|
} |