Now maintains a set of "compatible" Languages that contribute types to the given ClassHierarchy, which has a unique root type.

git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@2114 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
rmfuhrer 2007-12-06 14:53:29 +00:00
parent 728b86d817
commit 10dfaf51b3
1 changed files with 50 additions and 14 deletions

View File

@ -64,12 +64,19 @@ public class ClassHierarchy implements IClassHierarchy {
private static final boolean DEBUG = false;
/**
* Language of classes represented in this hierarchy
* Languages that contribute classes to the set represented in this hierarchy.
* The languages may for example be related by inheritance (e.g. X10 derives
* from Java, and shares a common type hierarchy rooted at java.lang.Object).
*/
private final Language language;
private final Set<Language> languages = new HashSet<Language>();
final private HashMap<IClass, Node> map = HashMapFactory.make();
/**
* TypeReference for the root type
*/
private TypeReference rootTypeRef;
/**
* root node of the class hierarchy
*/
@ -140,13 +147,23 @@ public class ClassHierarchy implements IClassHierarchy {
return result;
}
protected ClassHierarchy(AnalysisScope scope, ClassLoaderFactory factory, IProgressMonitor monitor)
throws ClassHierarchyException {
this(scope, factory, Language.JAVA, monitor);
}
// protected ClassHierarchy(AnalysisScope scope, ClassLoaderFactory factory, IProgressMonitor monitor)
// throws ClassHierarchyException {
// this(scope, factory, Language.JAVA, monitor);
// }
private ClassHierarchy(AnalysisScope scope, ClassLoaderFactory factory, Language language, IProgressMonitor progressMonitor)
throws ClassHierarchyException, IllegalArgumentException {
this(scope, factory, Collections.singleton(language), progressMonitor);
}
private ClassHierarchy(AnalysisScope scope, ClassLoaderFactory factory, IProgressMonitor progressMonitor)
throws ClassHierarchyException, IllegalArgumentException {
this(scope, factory, scope.getLanguages(), progressMonitor);
}
private ClassHierarchy(AnalysisScope scope, ClassLoaderFactory factory, Set<Language> languages, IProgressMonitor progressMonitor)
throws ClassHierarchyException, IllegalArgumentException {
// now is a good time to clear the warnings globally.
// TODO: think of a better way to guard against warning leaks.
Warnings.clear();
@ -154,16 +171,30 @@ public class ClassHierarchy implements IClassHierarchy {
if (factory == null) {
throw new IllegalArgumentException();
}
if (language == null) {
throw new IllegalArgumentException();
if (scope.getLanguages().size() == 0) {
throw new IllegalArgumentException("AnalysisScope must contain at least 1 language");
}
this.scope = scope;
this.factory = factory;
this.language = language;
Set<Atom> langNames= new HashSet<Atom>();
for(Language lang: languages) {
this.languages.add(lang);
this.languages.addAll(lang.getDerivedLanguages());
langNames.add(lang.getName());
}
for(Language lang: this.languages) {
if (lang.getRootType() != null) {
if (this.rootTypeRef != null) {
throw new IllegalArgumentException("AnalysisScope must have only 1 root type");
} else {
this.rootTypeRef= lang.getRootType();
}
}
}
try {
int numLoaders = 0;
for (ClassLoaderReference ref : scope.getLoaders()) {
if (ref.getLanguage().equals(language.getName())) {
if (langNames.contains(ref.getLanguage())) {
numLoaders++;
}
}
@ -181,7 +212,7 @@ public class ClassHierarchy implements IClassHierarchy {
}
}
if (ref.getLanguage().equals(language.getName())) {
if (langNames.contains(ref.getLanguage())) {
IClassLoader icl = factory.getLoader(ref, this, scope);
loaders[idx++] = icl;
addAllClasses(icl, progressMonitor);
@ -200,7 +231,7 @@ public class ClassHierarchy implements IClassHierarchy {
}
if (root == null) {
throw new ClassHierarchyException("failed to load root " + language.getRootType() + " of class hierarchy");
throw new ClassHierarchyException("failed to load root " + rootTypeRef + " of class hierarchy");
}
// perform numbering for subclass tests.
@ -262,7 +293,7 @@ public class ClassHierarchy implements IClassHierarchy {
}
Node node = findOrCreateNode(klass);
if (klass.getReference().equals(language.getRootType())) {
if (klass.getReference().equals(this.rootTypeRef)) {
// there is only one root
Assertions._assert(root == null);
root = node;
@ -284,7 +315,7 @@ public class ClassHierarchy implements IClassHierarchy {
Trace.println("addChild " + node.getJavaClass() + " to " + supernode.getJavaClass());
}
supernode.addChild(node);
if (supernode.getJavaClass().getReference().equals(language.getRootType())) {
if (supernode.getJavaClass().getReference().equals(rootTypeRef)) {
node = null;
} else {
node = supernode;
@ -1123,6 +1154,11 @@ public class ClassHierarchy implements IClassHierarchy {
return new ClassHierarchy(scope, factory, monitor);
}
public static ClassHierarchy make(AnalysisScope scope, ClassLoaderFactory factory, Set<Language> languages)
throws ClassHierarchyException {
return new ClassHierarchy(scope, factory, languages, new NullProgressMonitor());
}
public static ClassHierarchy make(AnalysisScope scope, ClassLoaderFactory factory, Language language)
throws ClassHierarchyException {
return new ClassHierarchy(scope, factory, language, new NullProgressMonitor());