Home | History | Annotate | Download | only in reflect
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package libcore.reflect;
     18 
     19 import java.lang.reflect.AccessibleObject;
     20 import java.lang.reflect.Constructor;
     21 import java.lang.reflect.GenericDeclaration;
     22 import java.lang.reflect.Method;
     23 import java.lang.reflect.Type;
     24 import java.lang.reflect.TypeVariable;
     25 
     26 
     27 public final class TypeVariableImpl<D extends GenericDeclaration> implements TypeVariable<D> {
     28     private TypeVariableImpl<D> formalVar;
     29     private final GenericDeclaration declOfVarUser;
     30     private final String name;
     31     private D genericDeclaration;
     32     private ListOfTypes bounds;
     33 
     34     @Override
     35     public boolean equals(Object o) {
     36         if(!(o instanceof TypeVariable)) {
     37             return false;
     38         }
     39         TypeVariable<?> that = (TypeVariable<?>) o;
     40         return getName().equals(that.getName()) &&
     41                 getGenericDeclaration().equals(that.getGenericDeclaration());
     42     }
     43 
     44 
     45     @Override
     46     public int hashCode() {
     47         return 31 * getName().hashCode() + getGenericDeclaration().hashCode();
     48     }
     49 
     50     /**
     51      * @param genericDecl declaration where a type variable is declared
     52      * @param name type variable name
     53      * @param bounds class and interface bounds
     54      */
     55     TypeVariableImpl(D genericDecl, String name, ListOfTypes bounds) {
     56         this.genericDeclaration = genericDecl;
     57         this.name = name;
     58         this.bounds = bounds;
     59         this.formalVar = this;
     60         this.declOfVarUser = null;
     61     }
     62 
     63     /**
     64      * @param genericDecl declaration where a type variable is used
     65      * @param name type variable name
     66      */
     67     TypeVariableImpl(D genericDecl, String name) {
     68         this.name = name;
     69         this.declOfVarUser = genericDecl;
     70     }
     71 
     72     static TypeVariable findFormalVar(GenericDeclaration layer, String name) {
     73         TypeVariable[] formalVars = layer.getTypeParameters();
     74         for (TypeVariable var : formalVars) {
     75             if (name.equals(var.getName())) {
     76                 return var;
     77             }
     78         }
     79         // resolve() looks up the next level only, if null is returned
     80         return null;
     81     }
     82 
     83     private static GenericDeclaration nextLayer(GenericDeclaration decl) {
     84         if (decl instanceof Class) {
     85             // FIXME: Is the following hierarchy correct?:
     86             Class cl = (Class)decl;
     87             Method m = cl.getEnclosingMethod();
     88             decl = (GenericDeclaration) m != null ? m : cl.getEnclosingConstructor();
     89             if (decl != null) {
     90                 return decl;
     91             }
     92             return cl.getEnclosingClass();
     93         } else if (decl instanceof Method) {
     94             return ((Method)decl).getDeclaringClass();
     95         } else if (decl instanceof Constructor) {
     96             return ((Constructor)decl).getDeclaringClass();
     97         } else {
     98             throw new AssertionError();
     99         }
    100     }
    101 
    102     void resolve() {
    103         if (formalVar != null) {
    104             return;
    105         }
    106         GenericDeclaration curLayer = declOfVarUser;
    107         TypeVariable var;
    108         while ((var = findFormalVar(curLayer, name)) == null) {
    109             curLayer = nextLayer(curLayer);
    110             if (curLayer == null) {
    111                 throw new AssertionError("illegal type variable reference");
    112             }
    113         }
    114         formalVar = (TypeVariableImpl<D>) var;
    115         this.genericDeclaration = formalVar.genericDeclaration;
    116         this.bounds = formalVar.bounds;
    117     }
    118 
    119     public Type[] getBounds() {
    120         resolve();
    121         return bounds.getResolvedTypes().clone();
    122     }
    123 
    124     public D getGenericDeclaration() {
    125         resolve();
    126         return genericDeclaration;
    127     }
    128 
    129     public String getName() {
    130         return name;
    131     }
    132 
    133     @Override
    134     public String toString() {
    135         return name;
    136     }
    137 }
    138