| 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
 | 
 | 
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 final 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();  | 
 | 
    }  | 
 | 
 | 
 | 
 | 
 | 
}  |