WALA/com.ibm.wala.core/src/com/ibm/wala/classLoader/ArrayClassLoader.java

90 lines
3.0 KiB
Java

/*******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package com.ibm.wala.classLoader;
import java.util.HashMap;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.types.TypeName;
import com.ibm.wala.types.TypeReference;
import com.ibm.wala.util.collections.HashMapFactory;
/**
* Pseudo-classloader for all array classes; all other IClassLoader
* implementations should delegate to this one for array classes only.
*/
public class ArrayClassLoader {
private final static boolean DEBUG = false;
/**
* map: TypeReference -> ArrayClass
*/
final private HashMap<TypeReference, ArrayClass> arrayClasses = HashMapFactory.make();
/**
* @param className
* name of the array class
* @param delegator
* class loader to look up element type with
*/
public IClass lookupClass(TypeName className, IClassLoader delegator, IClassHierarchy cha) throws IllegalArgumentException {
ArrayClass arrayClass;
if (DEBUG) {
assert className.toString().startsWith("[");
}
if (delegator == null) {
throw new IllegalArgumentException("delegator must not be null");
}
TypeReference type = TypeReference.findOrCreate(delegator.getReference(), className);
TypeReference elementType = type.getArrayElementType();
if (elementType.isPrimitiveType()) {
TypeReference aRef = TypeReference.findOrCreateArrayOf(elementType);
arrayClass = arrayClasses.get(aRef);
IClassLoader primordial = getRootClassLoader(delegator);
if (arrayClass == null) {
arrayClasses.put(aRef, arrayClass=new ArrayClass(aRef,primordial,cha));
}
} else {
arrayClass = arrayClasses.get(type);
if (arrayClass == null) {
// check that the element class is loadable. If not, return null.
IClass elementCls = delegator.lookupClass(elementType.getName());
if (elementCls == null) {
return null;
}
TypeReference realType = TypeReference.findOrCreateArrayOf(elementCls.getReference());
arrayClass = arrayClasses.get(realType);
if (arrayClass == null) {
arrayClass = new ArrayClass(realType, elementCls.getClassLoader(), cha);
}
}
arrayClasses.put(type, arrayClass);
}
return arrayClass;
}
private static IClassLoader getRootClassLoader(IClassLoader l) {
while (l.getParent() != null) {
l = l.getParent();
}
return l;
}
public int getNumberOfClasses() {
return arrayClasses.size();
}
}