Home | History | Annotate | Download | only in analysis
      1 /*
      2  * Javassist, a Java-bytecode translator toolkit.
      3  * Copyright (C) 1999-2007 Shigeru Chiba, and others. All Rights Reserved.
      4  *
      5  * The contents of this file are subject to the Mozilla Public License Version
      6  * 1.1 (the "License"); you may not use this file except in compliance with
      7  * the License.  Alternatively, the contents of this file may be used under
      8  * the terms of the GNU Lesser General Public License Version 2.1 or later.
      9  *
     10  * Software distributed under the License is distributed on an "AS IS" basis,
     11  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
     12  * for the specific language governing rights and limitations under the
     13  * License.
     14  */
     15 package javassist.bytecode.analysis;
     16 
     17 import javassist.ClassPool;
     18 import javassist.CtClass;
     19 import javassist.NotFoundException;
     20 
     21 /**
     22  * Represents an array of {@link MultiType} instances.
     23  *
     24  * @author Jason T. Greene
     25  */
     26 public class MultiArrayType extends Type {
     27     private MultiType component;
     28     private int dims;
     29 
     30     public MultiArrayType(MultiType component, int dims) {
     31         super(null);
     32         this.component = component;
     33         this.dims = dims;
     34     }
     35 
     36     public CtClass getCtClass() {
     37         CtClass clazz = component.getCtClass();
     38         if (clazz == null)
     39             return null;
     40 
     41         ClassPool pool = clazz.getClassPool();
     42         if (pool == null)
     43             pool = ClassPool.getDefault();
     44 
     45         String name = arrayName(clazz.getName(), dims);
     46 
     47         try {
     48             return pool.get(name);
     49         } catch (NotFoundException e) {
     50             throw new RuntimeException(e);
     51         }
     52     }
     53 
     54     boolean popChanged() {
     55         return component.popChanged();
     56     }
     57 
     58     public int getDimensions() {
     59         return dims;
     60     }
     61 
     62     public Type getComponent() {
     63        return dims == 1 ? (Type)component : new MultiArrayType(component, dims - 1);
     64     }
     65 
     66     public int getSize() {
     67         return 1;
     68     }
     69 
     70     public boolean isArray() {
     71         return true;
     72     }
     73 
     74     public boolean isAssignableFrom(Type type) {
     75         throw new UnsupportedOperationException("Not implemented");
     76     }
     77 
     78     public boolean isReference() {
     79        return true;
     80     }
     81 
     82     public boolean isAssignableTo(Type type) {
     83         if (eq(type.getCtClass(), Type.OBJECT.getCtClass()))
     84             return true;
     85 
     86         if (eq(type.getCtClass(), Type.CLONEABLE.getCtClass()))
     87             return true;
     88 
     89         if (eq(type.getCtClass(), Type.SERIALIZABLE.getCtClass()))
     90             return true;
     91 
     92         if (! type.isArray())
     93             return false;
     94 
     95         Type typeRoot = getRootComponent(type);
     96         int typeDims = type.getDimensions();
     97 
     98         if (typeDims > dims)
     99             return false;
    100 
    101         if (typeDims < dims) {
    102             if (eq(typeRoot.getCtClass(), Type.OBJECT.getCtClass()))
    103                 return true;
    104 
    105             if (eq(typeRoot.getCtClass(), Type.CLONEABLE.getCtClass()))
    106                 return true;
    107 
    108             if (eq(typeRoot.getCtClass(), Type.SERIALIZABLE.getCtClass()))
    109                 return true;
    110 
    111             return false;
    112         }
    113 
    114         return component.isAssignableTo(typeRoot);
    115     }
    116 
    117     public boolean equals(Object o) {
    118         if (! (o instanceof MultiArrayType))
    119             return false;
    120         MultiArrayType multi = (MultiArrayType)o;
    121 
    122         return component.equals(multi.component) && dims == multi.dims;
    123     }
    124 
    125     public String toString() {
    126         // follows the same detailed formating scheme as component
    127         return arrayName(component.toString(), dims);
    128     }
    129 }
    130