Save This Page
Home » openjdk-7 » sun.reflect.generics » visitor » [javadoc | source]
    1   /*
    2    * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   package sun.reflect.generics.visitor;
   27   
   28   
   29   import java.lang.reflect.Type;
   30   import java.util.List;
   31   import java.util.Iterator;
   32   import sun.reflect.generics.tree;
   33   import sun.reflect.generics.factory;
   34   
   35   
   36   
   37   /**
   38    * Visitor that converts AST to reified types.
   39    */
   40   public class Reifier implements TypeTreeVisitor<Type> {
   41       private Type resultType;
   42       private GenericsFactory factory;
   43   
   44       private Reifier(GenericsFactory f){
   45           factory = f;
   46       }
   47   
   48       private GenericsFactory getFactory(){ return factory;}
   49   
   50       /**
   51        * Factory method. The resulting visitor will convert an AST
   52        * representing generic signatures into corresponding reflective
   53        * objects, using the provided factory, <tt>f</tt>.
   54        * @param f - a factory that can be used to manufacture reflective
   55        * objects returned by this visitor
   56        * @return A visitor that can be used to reify ASTs representing
   57        * generic type information into reflective objects
   58        */
   59       public static Reifier make(GenericsFactory f){
   60           return new Reifier(f);
   61       }
   62   
   63       // Helper method. Visits an array of TypeArgument and produces
   64       // reified Type array.
   65       private Type[] reifyTypeArguments(TypeArgument[] tas) {
   66           Type[] ts = new Type[tas.length];
   67           for (int i = 0; i < tas.length; i++) {
   68               tas[i].accept(this);
   69               ts[i] = resultType;
   70           }
   71           return ts;
   72       }
   73   
   74   
   75       /**
   76        * Accessor for the result of the last visit by this visitor,
   77        * @return The type computed by this visitor based on its last
   78        * visit
   79        */
   80       public Type getResult() { assert resultType != null;return resultType;}
   81   
   82       public void visitFormalTypeParameter(FormalTypeParameter ftp){
   83           resultType = getFactory().makeTypeVariable(ftp.getName(),
   84                                                      ftp.getBounds());
   85       }
   86   
   87   
   88       public void visitClassTypeSignature(ClassTypeSignature ct){
   89           // This method examines the pathname stored in ct, which has the form
   90           // n1.n2...nk<targs>....
   91           // where n1 ... nk-1 might not exist OR
   92           // nk might not exist (but not both). It may be that k equals 1.
   93           // The idea is that nk is the simple class type name that has
   94           // any type parameters associated with it.
   95           //  We process this path in two phases.
   96           //  First, we scan until we reach nk (if it exists).
   97           //  If nk does not exist, this identifies a raw class n1 ... nk-1
   98           // which we can return.
   99           // if nk does exist, we begin the 2nd phase.
  100           // Here nk defines a parameterized type. Every further step nj (j > k)
  101           // down the path must also be represented as a parameterized type,
  102           // whose owner is the representation of the previous step in the path,
  103           // n{j-1}.
  104   
  105           // extract iterator on list of simple class type sigs
  106           List<SimpleClassTypeSignature> scts = ct.getPath();
  107           assert(!scts.isEmpty());
  108           Iterator<SimpleClassTypeSignature> iter = scts.iterator();
  109           SimpleClassTypeSignature sc = iter.next();
  110           StringBuilder n = new StringBuilder(sc.getName());
  111           boolean dollar = sc.getDollar();
  112   
  113           // phase 1: iterate over simple class types until
  114           // we are either done or we hit one with non-empty type parameters
  115           while (iter.hasNext() && sc.getTypeArguments().length == 0) {
  116               sc = iter.next();
  117               dollar = sc.getDollar();
  118               n.append(dollar?"$":".").append(sc.getName());
  119           }
  120   
  121           // Now, either sc is the last element of the list, or
  122           // it has type arguments (or both)
  123           assert(!(iter.hasNext()) || (sc.getTypeArguments().length > 0));
  124           // Create the raw type
  125           Type c = getFactory().makeNamedType(n.toString());
  126           // if there are no type arguments
  127           if (sc.getTypeArguments().length == 0) {
  128               //we have surely reached the end of the path
  129               assert(!iter.hasNext());
  130               resultType = c; // the result is the raw type
  131           } else {
  132               assert(sc.getTypeArguments().length > 0);
  133               // otherwise, we have type arguments, so we create a parameterized
  134               // type, whose declaration is the raw type c, and whose owner is
  135               // the declaring class of c (if any). This latter fact is indicated
  136               // by passing null as the owner.
  137               // First, we reify the type arguments
  138               Type[] pts = reifyTypeArguments(sc.getTypeArguments());
  139   
  140               Type owner = getFactory().makeParameterizedType(c, pts, null);
  141               // phase 2: iterate over remaining simple class types
  142               dollar =false;
  143               while (iter.hasNext()) {
  144                   sc = iter.next();
  145                   dollar = sc.getDollar();
  146                   n.append(dollar?"$":".").append(sc.getName()); // build up raw class name
  147                   c = getFactory().makeNamedType(n.toString()); // obtain raw class
  148                   pts = reifyTypeArguments(sc.getTypeArguments());// reify params
  149                   // Create a parameterized type, based on type args, raw type
  150                   // and previous owner
  151                   owner = getFactory().makeParameterizedType(c, pts, owner);
  152               }
  153               resultType = owner;
  154           }
  155       }
  156   
  157       public void visitArrayTypeSignature(ArrayTypeSignature a){
  158           // extract and reify component type
  159           a.getComponentType().accept(this);
  160           Type ct = resultType;
  161           resultType = getFactory().makeArrayType(ct);
  162       }
  163   
  164       public void visitTypeVariableSignature(TypeVariableSignature tv){
  165           resultType = getFactory().findTypeVariable(tv.getIdentifier());
  166       }
  167   
  168       public void visitWildcard(Wildcard w){
  169           resultType = getFactory().makeWildcard(w.getUpperBounds(),
  170                                                  w.getLowerBounds());
  171       }
  172   
  173       public void visitSimpleClassTypeSignature(SimpleClassTypeSignature sct){
  174           resultType = getFactory().makeNamedType(sct.getName());
  175       }
  176   
  177       public void visitBottomSignature(BottomSignature b){
  178   
  179       }
  180   
  181       public void visitByteSignature(ByteSignature b){
  182           resultType = getFactory().makeByte();
  183       }
  184   
  185       public void visitBooleanSignature(BooleanSignature b){
  186           resultType = getFactory().makeBool();
  187       }
  188   
  189       public void visitShortSignature(ShortSignature s){
  190           resultType = getFactory().makeShort();
  191       }
  192   
  193       public void visitCharSignature(CharSignature c){
  194           resultType = getFactory().makeChar();
  195       }
  196   
  197       public void visitIntSignature(IntSignature i){
  198           resultType = getFactory().makeInt();
  199       }
  200   
  201       public void visitLongSignature(LongSignature l){
  202           resultType = getFactory().makeLong();
  203       }
  204   
  205       public void visitFloatSignature(FloatSignature f){
  206           resultType = getFactory().makeFloat();
  207       }
  208   
  209       public void visitDoubleSignature(DoubleSignature d){
  210           resultType = getFactory().makeDouble();
  211       }
  212   
  213       public void visitVoidDescriptor(VoidDescriptor v){
  214           resultType = getFactory().makeVoid();
  215       }
  216   
  217   
  218   }

Save This Page
Home » openjdk-7 » sun.reflect.generics » visitor » [javadoc | source]