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:
parent
728b86d817
commit
10dfaf51b3
|
@ -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());
|
||||||
|
|
Loading…
Reference in New Issue