/*******************************************************************************
* 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.shrikeBT.analysis;
import java.util.HashMap;
import java.util.Iterator;
import com.ibm.wala.shrikeBT.Constants;
/**
* This implementation of ClassHierarchyProvider is a simple writable data structure representing a class hierarchy. You call
* setClassInfo to record information about a class.
*/
public final class ClassHierarchyStore implements ClassHierarchyProvider {
private static final String[] noClasses = new String[0];
final static class ClassInfo {
final boolean isInterface;
final boolean isFinal;
final String superClass;
final String[] superInterfaces;
ClassInfo(boolean isInterface, boolean isFinal, String superClass, String[] superInterfaces) {
this.isInterface = isInterface;
this.isFinal = isFinal;
this.superClass = superClass;
this.superInterfaces = superInterfaces;
}
}
final private HashMap<String, ClassInfo> contents = new HashMap<String, ClassInfo>();
/**
* Create an empty store.
*/
public ClassHierarchyStore() {
}
/**
* Append some class information to the store.
*
* @param cl the JVM type of the class being added (e.g., Ljava/lang/Object;)
* @param isInterface true iff it's an interface
* @param isFinal true iff it's final
* @param superClass the JVM type of the superclass, or null if this is Object
* @param superInterfaces the JVM types of its implemented interfaces
*/
public void setClassInfo(String cl, boolean isInterface, boolean isFinal, String superClass, String[] superInterfaces)
throws IllegalArgumentException {
if (superClass != null && superClass.equals(cl)) {
throw new IllegalArgumentException("Class " + cl + " cannot be its own superclass");
}
contents.put(cl, new ClassInfo(isInterface, isFinal, superClass, superInterfaces));
}
/**
* Delete the class information from the store.
*/
public void removeClassInfo(String cl) {
contents.remove(cl);
}
/**
* Iterate through all classes in the store.
*/
public Iterator<String> iterateOverClasses() {
return contents.keySet().iterator();
}
/**
* @see ClassHierarchyProvider#getSuperClass(String)
*/
@Override
public String getSuperClass(String cl) {
ClassInfo info = contents.get(cl);
return info == null ? null : info.superClass;
}
/*
* @see ClassHierarchyProvider#getSuperInterfaces(String)
*/
@Override
public String[] getSuperInterfaces(String cl) {
ClassInfo info = contents.get(cl);
return info == null ? null : info.superInterfaces;
}
/*
* @see ClassHierarchyProvider#getSubClasses(String)
*/
@Override
public String[] getSubClasses(String cl) {
ClassInfo info = contents.get(cl);
return (info == null || !info.isFinal) ? null : noClasses;
}
/*
* @see ClassHierarchyProvider#isInterface(String)
*/
@Override
public int isInterface(String cl) {
ClassInfo info = contents.get(cl);
return info == null ? Constants.MAYBE : (info.isInterface ? Constants.YES : Constants.NO);
}
}