provide more options for choosing classfiles vs source files. Thanks to Dan Marino.

git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@3852 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
dolby-oss 2010-07-19 14:05:19 +00:00
parent 3fcb6de3ba
commit 086c22dc13
5 changed files with 88 additions and 77 deletions

View File

@ -1677,15 +1677,30 @@ public class JDTJava2CAstTranslator implements TranslatorToCAst {
*/
private ITypeBinding findClosestEnclosingClassSubclassOf(ITypeBinding typeOfThis, ITypeBinding owningType, boolean isPrivate) {
// GENERICS
if (owningType.isParameterizedType())
owningType = owningType.getTypeDeclaration();
if (typeOfThis.isParameterizedType())
typeOfThis = typeOfThis.getTypeDeclaration();
// typeOfThis.getTypeDeclaration()
// if (owningType.isParameterizedType())
// owningType = owningType.getTypeDeclaration();
// if (typeOfThis.isParameterizedType())
// typeOfThis = typeOfThis.getTypeDeclaration();
// // typeOfThis.getTypeDeclaration()
owningType = owningType.getErasure();
ITypeBinding current = typeOfThis;
while (current != null) {
boolean isInSubtype = current.isSubTypeCompatible(owningType);
current = current.getErasure();
// Walk the hierarchy rather than using isSubTypeCompatible to handle
// generics -- we need to perform erasure of super types
boolean isInSubtype = false;//current.isSubTypeCompatible(owningType);
ITypeBinding supertp = current;
while (supertp != null){
supertp = supertp.getErasure();
// Use isSubTypeCompatible even though we are manually walking type hierarchy --
// that way interfaces are handled without us having to do it manually.
if (supertp.isSubTypeCompatible(owningType)){
isInSubtype = true;
break;
}
supertp = supertp.getSuperclass();
}
// how could it be in the subtype and private? this only happens the supertype is also an
// enclosing type. in that case the variable refers to the field in the enclosing instance.

View File

@ -132,11 +132,11 @@ public class JDTSourceModuleTranslator implements SourceModuleTranslator {
}
final ASTParser parser = ASTParser.newParser(AST.JLS3);
parser.setResolveBindings(true);
for (IProject proj : projectsFiles.keySet()) {
parser.setProject(JavaCore.create(proj));
ArrayList<ICompilationUnit> files = projectsFiles.get(proj);
parser.setResolveBindings(true);
ArrayList<ICompilationUnit> files = projectsFiles.get(proj);
parser.createASTs(files.toArray(new ICompilationUnit[files.size()]), new String[0], new ASTRequestor() {
public void acceptAST(ICompilationUnit source, CompilationUnit ast) {

View File

@ -103,21 +103,29 @@ public abstract class JavaSourceLoaderImpl extends ClassLoaderImpl {
}
public IClass getSuperclass() {
boolean excludedSupertype=false;
for (Iterator iter = superTypeNames.iterator(); iter.hasNext();) {
TypeName name = (TypeName) iter.next();
IClass domoType = lookupClass(name);
if (domoType != null && !domoType.isInterface()) {
return domoType;
}
if (domoType == null && getClassHierarchy().getScope().getExclusions().contains(name.toString().substring(1))){
excludedSupertype = true;
}
}
// The following test allows the root class to reside in source; without
// it, the assertion requires all classes represented by a JavaClass to
// have a superclass.
if (!getName().equals(JavaSourceLoaderImpl.this.getLanguage().getRootType().getName())) {
if (!getName().equals(JavaSourceLoaderImpl.this.getLanguage().getRootType().getName()) && !excludedSupertype) {
Assertions.UNREACHABLE("Cannot find super class for " + this + " in " + superTypeNames);
}
if (excludedSupertype){
System.err.println("Not tracking calls through excluded superclass of " + getName() + " extends " + superTypeNames);
}
return null;
}
@ -127,15 +135,11 @@ public abstract class JavaSourceLoaderImpl extends ClassLoaderImpl {
TypeName name = (TypeName) iter.next();
IClass domoType = lookupClass(name);
if (domoType != null && domoType.isInterface()) {
result.add(domoType);
result.add(domoType);
}
if (domoType == null && !getClassHierarchy().getScope().getExclusions().contains(name.toString().substring(1))){
assert false : "Failed to find all non-excluded interfaces.";
}
}
// The following computation allows the root class to reside in source
int numSuperClasses = (getName().equals(JavaSourceLoaderImpl.this.getLanguage().getRootType().getName())) ? 0 : 1; // 0 if the root class
if (result.size() != (superTypeNames.size() - numSuperClasses)) {
assert result.size() == superTypeNames.size() - numSuperClasses : "found " + result + " interfaces for " + superTypeNames
+ " for " + this;
}
return result;

View File

@ -65,17 +65,17 @@ public abstract class AbstractJavaAnalysisAction implements IObjectActionDelegat
* Compute an analysis scope for the current selection
*/
public static AnalysisScope computeScope(IStructuredSelection selection) throws IOException {
return computeScope(selection, false, true);
return computeScope(selection, EclipseProjectPath.AnalysisScopeType.NO_SOURCE);
}
/**
* Compute an analysis scope for the current selection
*
* @param includeSource should files from the source folders in Eclipse projects be included
* @param includeClassFiles should class files built by Eclipse, in the project output folders, be include?
* @param scopeType should analysis use the source files in the Eclipse projects rather than the class files.
*/
public static AnalysisScope computeScope(final IStructuredSelection selection, final boolean includeSource,
final boolean includeClassFiles) throws IOException {
public static AnalysisScope computeScope(final IStructuredSelection selection,
final EclipseProjectPath.AnalysisScopeType scopeType) throws IOException
{
if (selection == null) {
throw new IllegalArgumentException("null selection");
}
@ -91,7 +91,7 @@ public abstract class AbstractJavaAnalysisAction implements IObjectActionDelegat
IJavaElement e = (IJavaElement) object;
IJavaProject jp = e.getJavaProject();
try {
projectPaths.add(EclipseProjectPath.make(jp, includeSource, includeClassFiles));
projectPaths.add(EclipseProjectPath.make(jp, scopeType));
} catch (CoreException e1) {
e1.printStackTrace();
// skip and continue

View File

@ -59,9 +59,10 @@ import com.ibm.wala.util.debug.Assertions;
* We set up classloaders as follows:
* <ul>
* <li>The project being analyzed is in the Application Loader
* <li>Projects on which the main project depends are in the Extension loader
* <li>Frameworks, application libraries, and linked projects on which the main project depends are in the Extension loader
* <li>System libraries are in the primordial loader.
* <li>Source modules go in a special Source loader.
* <li>All source modules go in a special Source loader. This includes source from linked projects if
* SOURCE_FOR_PROJ_AND_LINKED_PROJS is specified.
* </ul>
*/
@SuppressWarnings("restriction")
@ -80,6 +81,10 @@ public class EclipseProjectPath {
this.ref = ref;
}
};
public enum AnalysisScopeType {
NO_SOURCE, SOURCE_FOR_PROJ, SOURCE_FOR_PROJ_AND_LINKED_PROJS
}
/**
* The project whose path this object represents
@ -101,27 +106,23 @@ public class EclipseProjectPath {
private final Collection<IClasspathEntry> alreadyResolved = HashSetFactory.make();
/**
* Should the analysis scope include source files
* Which source files, if any, should be included in the analysis scope.
*/
private final boolean includeSource;
private final AnalysisScopeType scopeType;
/**
* Should the analysis scope include class files generated by the Eclipse build process?
*/
private final boolean includeClassFiles;
protected EclipseProjectPath(IJavaProject project, boolean includeSource, boolean includeClassFiles) throws IOException,
protected EclipseProjectPath(IJavaProject project, AnalysisScopeType scopeType) throws IOException,
CoreException {
if (project == null) {
throw new IllegalArgumentException("null project");
}
this.includeSource = includeSource;
this.includeClassFiles = includeClassFiles;
this.scopeType = scopeType;
this.project = project;
assert project != null;
for (Loader loader : Loader.values()) {
MapUtil.findOrCreateList(modules, loader);
}
boolean includeSource = (scopeType != AnalysisScopeType.NO_SOURCE);
resolveProjectClasspathEntries(includeSource);
if (isPluginProject(project)) {
resolvePluginClassPath(project.getProject(), includeSource);
@ -129,19 +130,20 @@ public class EclipseProjectPath {
}
public static EclipseProjectPath make(IJavaProject project) throws IOException, CoreException {
return make(project, false, true);
return make(project, AnalysisScopeType.NO_SOURCE);
}
public static EclipseProjectPath make(IJavaProject project, boolean includeSource, boolean includeClassFiles) throws IOException,
public static EclipseProjectPath make(IJavaProject project, AnalysisScopeType scopeType) throws IOException,
CoreException {
return new EclipseProjectPath(project, includeSource, includeClassFiles);
return new EclipseProjectPath(project, scopeType);
}
/**
* Figure out what a classpath entry means and add it to the appropriate set of modules
*/
private void resolveClasspathEntry(IClasspathEntry entry, Loader loader, boolean includeSource) throws JavaModelException,
IOException {
private void resolveClasspathEntry(IClasspathEntry entry, Loader loader, boolean includeSource, boolean cpeFromMainProject)
throws JavaModelException, IOException
{
IClasspathEntry e = JavaCore.getResolvedClasspathEntry(entry);
if (alreadyResolved.contains(e)) {
return;
@ -153,7 +155,7 @@ public class EclipseProjectPath {
IClasspathContainer cont = JavaCore.getClasspathContainer(entry.getPath(), project);
IClasspathEntry[] entries = cont.getClasspathEntries();
resolveClasspathEntries(entries, cont.getKind() == IClasspathContainer.K_APPLICATION ? loader : Loader.PRIMORDIAL,
includeSource);
includeSource, false);
} else if (e.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
File file = makeAbsolute(e.getPath()).toFile();
JarFile j;
@ -171,14 +173,12 @@ public class EclipseProjectPath {
s.add(file.isDirectory() ? (Module) new BinaryDirectoryTreeModule(file) : (Module) new JarFileModule(j));
}
} else if (e.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
List<Module> s = MapUtil.findOrCreateList(modules, loader);
if (includeSource) {
List<Module> s = MapUtil.findOrCreateList(modules, Loader.APPLICATION);
s.add(new EclipseSourceDirectoryTreeModule(e.getPath()));
}
if (e.getOutputLocation() != null) {
}else if (e.getOutputLocation() != null) {
File output = makeAbsolute(e.getOutputLocation()).toFile();
s = MapUtil.findOrCreateList(modules, loader);
List<Module> s = MapUtil.findOrCreateList(modules, cpeFromMainProject ? Loader.APPLICATION : loader);
s.add(new BinaryDirectoryTreeModule(output));
}
} else if (e.getEntryKind() == IClasspathEntry.CPE_PROJECT) {
@ -192,10 +192,13 @@ public class EclipseProjectPath {
if (isPluginProject(javaProject)) {
resolvePluginClassPath(javaProject.getProject(), includeSource);
}
resolveClasspathEntries(javaProject.getRawClasspath(), loader, includeSource);
resolveClasspathEntries(javaProject.getRawClasspath(), loader,
scopeType==AnalysisScopeType.SOURCE_FOR_PROJ_AND_LINKED_PROJS ? includeSource : false, false);
File output = makeAbsolute(javaProject.getOutputLocation()).toFile();
List<Module> s = MapUtil.findOrCreateList(modules, loader);
s.add(new BinaryDirectoryTreeModule(output));
if (!includeSource){
s.add(new BinaryDirectoryTreeModule(output));
}
}
} catch (CoreException e1) {
e1.printStackTrace();
@ -262,7 +265,7 @@ public class EclipseProjectPath {
IClasspathEntry e = (IClasspathEntry) o;
entries[i++] = e;
}
resolveClasspathEntries(entries, loader, includeSource);
resolveClasspathEntries(entries, loader, includeSource, false);
// recurse to handle dependencies. put these in the Extension loader
for (BundleDescription b : PDEStateHelper.getImportedBundles(bd)) {
@ -305,10 +308,10 @@ public class EclipseProjectPath {
return true;
}
protected void resolveClasspathEntries(IClasspathEntry[] entries, Loader loader, boolean includeSource)
protected void resolveClasspathEntries(IClasspathEntry[] entries, Loader loader, boolean includeSource, boolean entriesFromTopLevelProject)
throws JavaModelException, IOException {
for (int i = 0; i < entries.length; i++) {
resolveClasspathEntry(entries[i], loader, includeSource);
resolveClasspathEntry(entries[i], loader, includeSource, entriesFromTopLevelProject);
}
}
@ -326,7 +329,18 @@ public class EclipseProjectPath {
}
private void resolveProjectClasspathEntries(boolean includeSource) throws JavaModelException, IOException {
resolveClasspathEntries(project.getRawClasspath(), Loader.EXTENSION, includeSource);
resolveClasspathEntries(project.getRawClasspath(), Loader.EXTENSION, includeSource, true);
if (!includeSource){
File dir = makeAbsolute(project.getOutputLocation()).toFile();
if (!dir.isDirectory()) {
System.err.println("PANIC: project output location is not a directory: " + dir);
} else {
MapUtil.findOrCreateList(modules, Loader.APPLICATION).add(new BinaryDirectoryTreeModule(dir));
}
}
}
/**
@ -341,24 +355,6 @@ public class EclipseProjectPath {
}
public AnalysisScope toAnalysisScope(AnalysisScope scope) {
try {
List<Module> l = MapUtil.findOrCreateList(modules, Loader.APPLICATION);
if (includeClassFiles) {
File dir = makeAbsolute(project.getOutputLocation()).toFile();
if (!dir.isDirectory()) {
System.err.println("PANIC: project output location is not a directory: " + dir);
} else {
l.add(new BinaryDirectoryTreeModule(dir));
}
}
if (includeSource) {
for (IClasspathEntry e : project.getRawClasspath()) {
if (e.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
l.add(new EclipseSourceDirectoryTreeModule(e.getPath()));
}
}
}
for (Loader loader : Loader.values()) {
for (Module m : modules.get(loader)) {
@ -366,11 +362,7 @@ public class EclipseProjectPath {
}
}
return scope;
} catch (JavaModelException e) {
e.printStackTrace();
Assertions.UNREACHABLE();
return null;
}
}
public AnalysisScope toAnalysisScope(final File exclusionsFile) throws IOException {