Main Page   Packages   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

ClassTokenArray.java

00001 package edu.ksu.cis.bandera.bofa;
00002 
00003 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00004  * Bandera, a Java(TM) analysis and transformation toolkit           *
00005  * Copyright (C) 1998, 1999   Shawn Laubach (laubach@acm.org)        *
00006  * All rights reserved.                                              *
00007  *                                                                   *
00008  * This work was done as a project in the SAnToS Laboratory,         *
00009  * Department of Computing and Information Sciences, Kansas State    *
00010  * University, USA (http://www.cis.ksu.edu/santos).                  *
00011  * It is understood that any modification not identified as such is  *
00012  * not covered by the preceding statement.                           *
00013  *                                                                   *
00014  * This work is free software; you can redistribute it and/or        *
00015  * modify it under the terms of the GNU Library General Public       *
00016  * License as published by the Free Software Foundation; either      *
00017  * version 2 of the License, or (at your option) any later version.  *
00018  *                                                                   *
00019  * This work is distributed in the hope that it will be useful,      *
00020  * but WITHOUT ANY WARRANTY; without even the implied warranty of    *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *
00022  * Library General Public License for more details.                  *
00023  *                                                                   *
00024  * You should have received a copy of the GNU Library General Public *
00025  * License along with this toolkit; if not, write to the             *
00026  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,      *
00027  * Boston, MA  02111-1307, USA.                                      *
00028  *                                                                   *
00029  * Java is a trademark of Sun Microsystems, Inc.                     *
00030  *                                                                   *
00031  * To submit a bug report, send a comment, or get the latest news on *
00032  * this project and other SAnToS projects, please visit the web-site *
00033  *                http://www.cis.ksu.edu/santos                      *
00034  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00035 
00036 import ca.mcgill.sable.soot.*;
00037 import ca.mcgill.sable.util.*;
00038 
00039 /*
00040  * ClassTokenArray.java
00041  * $Id: ClassTokenArray.java,v 1.1.1.1 2002/01/24 03:42:07 pserver Exp $
00042  */
00043 
00044 /**
00045  * This class represents the class token for array types in the analysis.  In
00046  * java array types are represented as classes.
00047  *
00048  * @author <A HREF="http://www.cis.ksu.edu/~hatcliff">John Hatcliff</A>
00049  * @author
00050  * <a href="http://www.cis.ksu.edu/~rvprasad">Venkatesh Prasad Ranganath</a>
00051  *
00052  * @version $Name:  $($Revision: 1.1.1.1 $)
00053  */
00054 public class ClassTokenArray implements ClassToken
00055 {
00056     /**
00057      * Maps an array type to a class token,<code>ClassToken</code>.
00058      * 
00059      * An integer array of 3 dimension is an array type.
00060      */
00061     private static Map allocatedTokens = new HashMap();
00062 
00063     /**
00064      * The ArrayType object associated with this class token object.
00065      */
00066     ArrayType arrayType;
00067 
00068     /**
00069      * Creates a new object.
00070      *
00071      * @param arrayType the array type associated with this class token.
00072      */
00073     private ClassTokenArray(ArrayType arrayType)
00074     {
00075         this.arrayType = arrayType;
00076     }
00077     /** 
00078      * Extracts the component type of the given array type.
00079      *
00080      * @param arrayType the array type whose component type is requested.
00081      * @return the component type of the given array type.
00082      */ 
00083     public static Type arrayTypeToComponentType(ArrayType arrayType)
00084     {
00085         if (arrayType.numDimensions == 1) {
00086             return arrayType.baseType;
00087         } else {
00088             return ArrayType.v(arrayType.baseType,
00089                                arrayType.numDimensions - 1);
00090         }
00091     }
00092     /**
00093      * Constructs a new array type in which the component type is of the given
00094      * type.
00095      *
00096      * @param componentType the component type of the requested array type.
00097      * @return the new array type with the given component type.
00098      */
00099     public static ArrayType componentToArrayType(Type componentType)
00100     {
00101         if (componentType instanceof BaseType) {
00102             return ArrayType.v((BaseType) componentType, 1);
00103         } else 
00104             if (componentType instanceof ArrayType) {
00105                 return ArrayType.v(((ArrayType) componentType).baseType,
00106                                    ((ArrayType) componentType).numDimensions +
00107                                    1); 
00108             } else
00109                 throw new RuntimeException("Invalid type");
00110     }
00111     /**
00112      * Returns the ArrayType associated with this class token.
00113      *
00114      * @return a soot object representing the array type associated with this
00115      * class token. 
00116      */
00117     public ArrayType getArrayType()
00118     {
00119         return arrayType;
00120     }
00121     /** 
00122      * Provides the class token associated with the given array type.
00123      *
00124      * In this method, array types are tested for logical equality rather
00125      * than object equality.  It is the case that there may be more than one
00126      * SootClass object pertaining to equivalent array types.  Hence, the name
00127      * getCanonicalArrayTypeInstance.
00128      *
00129      * @param arrayType the array type which needs to be checked if registered
00130      * @return the class token associated with the array type, if any, else null.
00131      */
00132     private static ArrayType getCanonicalArrayTypeInstance(ArrayType arrayType)
00133     {
00134         /**
00135          *  Iterates over stored array types in allocatedTokens map to see if we
00136          *  have already allocated a ClassTokenArray for a logically
00137          *  equivalent array type.  If we have, return that array type
00138          *  instance.  If we have * not, return null.  
00139          */
00140         ArrayType storedArrayType;
00141         for (Iterator i = allocatedTokens.keySet().iterator(); i.hasNext();)
00142             {
00143                 storedArrayType = (ArrayType) i.next();
00144                 if (storedArrayType.equals(arrayType)) {
00145                     return storedArrayType;
00146                 } 
00147             }
00148         return null;
00149     }
00150     /**
00151      * Provides the class token associated with the given array type.
00152      *
00153      * @param arrayType the array type for which the class token is requested.
00154      * @return the class token associated with the array type.
00155      */
00156     public static ClassTokenArray select(ArrayType arrayType)
00157     {
00158         ClassTokenArray classTokenArray;
00159  
00160         /* 
00161          * Currently, Soot allows multiple array type instances to describe the
00162          * same array type.  We want a single ClassTokenArray instance for each
00163          * distinct logical array type.  in simple words, Soot associates a
00164          * unique SootClass object with each 3 dimensional array of type A
00165          * whereas we require one SootClass object to be associated with all 3
00166          * dimensional arrays of type A.  Therefore, before allocating a new
00167          * ClassTokenArray instance, we want to check to see if a
00168          * ClassTokenArray instance has already been allocated for a given
00169          * logical type.
00170          */
00171 
00172         /* 
00173          * First, check to see if the the given array type is already stored in
00174          * the table.
00175          */
00176         if (allocatedTokens.containsKey(arrayType)) {
00177             classTokenArray = (ClassTokenArray) allocatedTokens.get(arrayType);
00178         } else {
00179             /*
00180              * Check if a logically equivalent array type is stored in the
00181              * table.  If so, use that or create a new one.
00182              */
00183             ArrayType canonicalArrayType =
00184                 getCanonicalArrayTypeInstance(arrayType);
00185 
00186             if (canonicalArrayType != null) {
00187                 // return the classToken associated with the array type
00188                 classTokenArray = (ClassTokenArray)
00189                     allocatedTokens.get(canonicalArrayType);
00190             } else {
00191                 // there is no logically equivalent stored array type, so
00192                 // create a new class token for it, and the current array type
00193                 // becomes the canonical representation.
00194                 classTokenArray = new ClassTokenArray(arrayType);
00195                 allocatedTokens.put(arrayType,classTokenArray);
00196             }
00197         }
00198         return classTokenArray;
00199     }
00200 }

Generated at Thu Feb 7 06:42:31 2002 for Bandera by doxygen1.2.10 written by Dimitri van Heesch, © 1997-2001