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; 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(); final private HashMap<IClass, Node> map = HashMapFactory.make();
/**
* TypeReference for the root type
*/
private TypeReference rootTypeRef;
/** /**
* root node of the class hierarchy * root node of the class hierarchy
*/ */
@ -140,13 +147,23 @@ public class ClassHierarchy implements IClassHierarchy {
return result; return result;
} }
protected ClassHierarchy(AnalysisScope scope, ClassLoaderFactory factory, IProgressMonitor monitor) // protected ClassHierarchy(AnalysisScope scope, ClassLoaderFactory factory, IProgressMonitor monitor)
throws ClassHierarchyException { // throws ClassHierarchyException {
this(scope, factory, Language.JAVA, monitor); // this(scope, factory, Language.JAVA, monitor);
} // }
private ClassHierarchy(AnalysisScope scope, ClassLoaderFactory factory, Language language, IProgressMonitor progressMonitor) private ClassHierarchy(AnalysisScope scope, ClassLoaderFactory factory, Language language, IProgressMonitor progressMonitor)
throws ClassHierarchyException, IllegalArgumentException { 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. // now is a good time to clear the warnings globally.
// TODO: think of a better way to guard against warning leaks. // TODO: think of a better way to guard against warning leaks.
Warnings.clear(); Warnings.clear();
@ -154,16 +171,30 @@ public class ClassHierarchy implements IClassHierarchy {
if (factory == null) { if (factory == null) {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
if (language == null) { if (scope.getLanguages().size() == 0) {
throw new IllegalArgumentException(); throw new IllegalArgumentException("AnalysisScope must contain at least 1 language");
} }
this.scope = scope; this.scope = scope;
this.factory = factory; 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 { try {
int numLoaders = 0; int numLoaders = 0;
for (ClassLoaderReference ref : scope.getLoaders()) { for (ClassLoaderReference ref : scope.getLoaders()) {
if (ref.getLanguage().equals(language.getName())) { if (langNames.contains(ref.getLanguage())) {
numLoaders++; 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); IClassLoader icl = factory.getLoader(ref, this, scope);
loaders[idx++] = icl; loaders[idx++] = icl;
addAllClasses(icl, progressMonitor); addAllClasses(icl, progressMonitor);
@ -200,7 +231,7 @@ public class ClassHierarchy implements IClassHierarchy {
} }
if (root == null) { 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. // perform numbering for subclass tests.
@ -262,7 +293,7 @@ public class ClassHierarchy implements IClassHierarchy {
} }
Node node = findOrCreateNode(klass); Node node = findOrCreateNode(klass);
if (klass.getReference().equals(language.getRootType())) { if (klass.getReference().equals(this.rootTypeRef)) {
// there is only one root // there is only one root
Assertions._assert(root == null); Assertions._assert(root == null);
root = node; root = node;
@ -284,7 +315,7 @@ public class ClassHierarchy implements IClassHierarchy {
Trace.println("addChild " + node.getJavaClass() + " to " + supernode.getJavaClass()); Trace.println("addChild " + node.getJavaClass() + " to " + supernode.getJavaClass());
} }
supernode.addChild(node); supernode.addChild(node);
if (supernode.getJavaClass().getReference().equals(language.getRootType())) { if (supernode.getJavaClass().getReference().equals(rootTypeRef)) {
node = null; node = null;
} else { } else {
node = supernode; node = supernode;
@ -1123,6 +1154,11 @@ public class ClassHierarchy implements IClassHierarchy {
return new ClassHierarchy(scope, factory, monitor); 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) public static ClassHierarchy make(AnalysisScope scope, ClassLoaderFactory factory, Language language)
throws ClassHierarchyException { throws ClassHierarchyException {
return new ClassHierarchy(scope, factory, language, new NullProgressMonitor()); return new ClassHierarchy(scope, factory, language, new NullProgressMonitor());