Major refactoring to introduce com.ibm.wala.ide. Many related changes and patches from Marcelo Paternostro.
git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@3693 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
parent
5f319b8bde
commit
a0efbee8ff
|
@ -13,5 +13,9 @@ Require-Bundle: com.ibm.wala.cast;bundle-version="1.0.0",
|
|||
com.ibm.wala.core.tests;bundle-version="1.1.3",
|
||||
com.ibm.wala.cast.java.jdt;bundle-version="1.0.0",
|
||||
org.junit;bundle-version="3.8.2",
|
||||
org.eclipse.core.runtime
|
||||
org.eclipse.core.runtime,
|
||||
com.ibm.wala.ide;bundle-version="1.1.3",
|
||||
org.eclipse.core.resources;bundle-version="3.4.1",
|
||||
com.ibm.wala.ide.tests;bundle-version="1.1.3",
|
||||
org.eclipse.jdt.core;bundle-version="3.4.2"
|
||||
Bundle-ActivationPolicy: lazy
|
||||
|
|
|
@ -18,7 +18,7 @@ import com.ibm.wala.cast.java.ipa.callgraph.JavaSourceAnalysisScope;
|
|||
import com.ibm.wala.cast.java.translator.jdt.JDTJavaSourceAnalysisEngine;
|
||||
import com.ibm.wala.core.tests.callGraph.CallGraphTestUtil;
|
||||
import com.ibm.wala.core.tests.plugin.CoreTestsPlugin;
|
||||
import com.ibm.wala.core.tests.util.EclipseTestUtil;
|
||||
import com.ibm.wala.ide.tests.util.EclipseTestUtil;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
import com.ibm.wala.ipa.callgraph.Entrypoint;
|
||||
import com.ibm.wala.ipa.callgraph.impl.Util;
|
||||
|
|
|
@ -48,7 +48,7 @@ import com.ibm.wala.cast.java.ipa.callgraph.JavaSourceAnalysisScope;
|
|||
import com.ibm.wala.cast.java.translator.jdt.JDTJavaSourceAnalysisEngine;
|
||||
import com.ibm.wala.core.tests.callGraph.CallGraphTestUtil;
|
||||
import com.ibm.wala.core.tests.plugin.CoreTestsPlugin;
|
||||
import com.ibm.wala.core.tests.util.EclipseTestUtil;
|
||||
import com.ibm.wala.ide.tests.util.EclipseTestUtil;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
import com.ibm.wala.ipa.callgraph.Entrypoint;
|
||||
import com.ibm.wala.ipa.callgraph.impl.Util;
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
/******************************************************************************
|
||||
* 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
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Oct 3, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.java.test.ide;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IWorkspace;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.jdt.core.IJavaProject;
|
||||
|
||||
import com.ibm.wala.cast.java.client.JavaSourceAnalysisEngine;
|
||||
import com.ibm.wala.cast.java.test.IRTests;
|
||||
import com.ibm.wala.classLoader.JarFileModule;
|
||||
import com.ibm.wala.classLoader.SourceDirectoryTreeModule;
|
||||
import com.ibm.wala.classLoader.SourceFileModule;
|
||||
import com.ibm.wala.ide.classloader.EclipseSourceFileModule;
|
||||
import com.ibm.wala.ide.tests.util.EclipseTestUtil;
|
||||
|
||||
public abstract class IDEIRTests extends IRTests {
|
||||
public IDEIRTests(String name, String projectName) {
|
||||
super(name, projectName);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void populateScope(JavaSourceAnalysisEngine engine, Collection<String> sources, List<String> libs) throws IOException {
|
||||
boolean foundLib = false;
|
||||
for (String lib : libs) {
|
||||
File libFile = new File(lib);
|
||||
if (libFile.exists()) {
|
||||
foundLib = true;
|
||||
engine.addSystemModule(new JarFileModule(new JarFile(libFile)));
|
||||
}
|
||||
}
|
||||
assert foundLib : "couldn't find library file from " + libs;
|
||||
|
||||
IWorkspace w = null;
|
||||
IJavaProject project = null;
|
||||
try {
|
||||
if (projectName != null) {
|
||||
w = ResourcesPlugin.getWorkspace();
|
||||
project = EclipseTestUtil.getNamedProject(projectName);
|
||||
}
|
||||
} catch (IllegalStateException e) {
|
||||
// use Workspace only if it exists
|
||||
}
|
||||
|
||||
for (String srcFilePath : sources) {
|
||||
|
||||
if (w != null) {
|
||||
IFile file = project.getProject().getFile(srcFilePath);
|
||||
try {
|
||||
engine.addSourceModule(EclipseSourceFileModule.createEclipseSourceFileModule(file));
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertTrue(e.getMessage(), false);
|
||||
}
|
||||
|
||||
} else {
|
||||
String srcFileName = srcFilePath.substring(srcFilePath.lastIndexOf(File.separator) + 1);
|
||||
File f = new File(srcFilePath);
|
||||
Assert.assertTrue("couldn't find " + srcFilePath, f.exists());
|
||||
if (f.isDirectory()) {
|
||||
engine.addSourceModule(new SourceDirectoryTreeModule(f));
|
||||
} else {
|
||||
engine.addSourceModule(new SourceFileModule(f, srcFileName));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,14 +1,18 @@
|
|||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Jdt Plug-in
|
||||
Bundle-SymbolicName: com.ibm.wala.cast.java.jdt
|
||||
Bundle-Version: 1.0.0
|
||||
Bundle-Activator: com.ibm.wala.cast.java.jdt.Activator
|
||||
Bundle-Vendor: IBM
|
||||
Require-Bundle: org.eclipse.core.runtime,
|
||||
com.ibm.wala.cast;bundle-version="1.0.0",
|
||||
com.ibm.wala.cast.java;bundle-version="1.0.0",
|
||||
com.ibm.wala.core;bundle-version="1.1.3"
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Export-Package: com.ibm.wala.cast.java.jdt,
|
||||
com.ibm.wala.cast.java.translator.jdt
|
||||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Jdt Plug-in
|
||||
Bundle-SymbolicName: com.ibm.wala.cast.java.jdt
|
||||
Bundle-Version: 1.0.0
|
||||
Bundle-Activator: com.ibm.wala.cast.java.jdt.Activator
|
||||
Bundle-Vendor: IBM
|
||||
Require-Bundle: com.ibm.wala.cast,
|
||||
com.ibm.wala.cast.java,
|
||||
com.ibm.wala.core,
|
||||
org.eclipse.core.runtime,
|
||||
org.eclipse.jdt.core,
|
||||
org.eclipse.core.resources,
|
||||
com.ibm.wala.shrike,
|
||||
com.ibm.wala.ide
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Export-Package: com.ibm.wala.cast.java.jdt,
|
||||
com.ibm.wala.cast.java.translator.jdt
|
||||
|
|
|
@ -1,166 +1,166 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* This file is a derivative of code released by the University of
|
||||
* California under the terms listed below.
|
||||
*
|
||||
* WALA JDT Frontend is Copyright (c) 2008 The Regents of the
|
||||
* University of California (Regents). Provided that this notice and
|
||||
* the following two paragraphs are included in any distribution of
|
||||
* Refinement Analysis Tools or its derivative work, Regents agrees
|
||||
* not to assert any of Regents' copyright rights in Refinement
|
||||
* Analysis Tools against recipient for recipient's reproduction,
|
||||
* preparation of derivative works, public display, public
|
||||
* performance, distribution or sublicensing of Refinement Analysis
|
||||
* Tools and derivative works, in source code and object code form.
|
||||
* This agreement not to assert does not confer, by implication,
|
||||
* estoppel, or otherwise any license or rights in any intellectual
|
||||
* property of Regents, including, but not limited to, any patents
|
||||
* of Regents or Regents' employees.
|
||||
*
|
||||
* IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT,
|
||||
* INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
|
||||
* INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE
|
||||
* AND ITS DOCUMENTATION, EVEN IF REGENTS HAS BEEN ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND FURTHER DISCLAIMS ANY STATUTORY
|
||||
* WARRANTY OF NON-INFRINGEMENT. THE SOFTWARE AND ACCOMPANYING
|
||||
* DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS
|
||||
* IS". REGENTS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
|
||||
* UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*/
|
||||
package com.ibm.wala.cast.java.translator.jdt;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.jdt.core.ICompilationUnit;
|
||||
import org.eclipse.jdt.core.JavaCore;
|
||||
import org.eclipse.jdt.core.JavaModelException;
|
||||
import org.eclipse.jdt.core.compiler.IProblem;
|
||||
import org.eclipse.jdt.core.dom.AST;
|
||||
import org.eclipse.jdt.core.dom.ASTParser;
|
||||
import org.eclipse.jdt.core.dom.ASTRequestor;
|
||||
import org.eclipse.jdt.core.dom.CompilationUnit;
|
||||
|
||||
import com.ibm.wala.cast.java.translator.Java2IRTranslator;
|
||||
import com.ibm.wala.cast.java.translator.SourceModuleTranslator;
|
||||
import com.ibm.wala.classLoader.DirectoryTreeModule;
|
||||
import com.ibm.wala.classLoader.EclipseSourceFileModule;
|
||||
import com.ibm.wala.classLoader.JarFileModule;
|
||||
import com.ibm.wala.classLoader.Module;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
/**
|
||||
* A SourceModuleTranslator whose implementation of loadAllSources() uses the PolyglotFrontEnd pseudo-compiler to generate DOMO IR
|
||||
* for the sources in the compile-time classpath.
|
||||
*
|
||||
* @author rfuhrer
|
||||
*/
|
||||
// remove me comment: Jdt little-case = not OK, upper case = OK
|
||||
public class JDTSourceModuleTranslator implements SourceModuleTranslator {
|
||||
private JDTSourceLoaderImpl sourceLoader;
|
||||
|
||||
public JDTSourceModuleTranslator(AnalysisScope scope, JDTSourceLoaderImpl sourceLoader) {
|
||||
computeClassPath(scope);
|
||||
this.sourceLoader = sourceLoader;
|
||||
}
|
||||
|
||||
private void computeClassPath(AnalysisScope scope) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
|
||||
ClassLoaderReference cl = scope.getApplicationLoader();
|
||||
|
||||
while (cl != null) {
|
||||
List<Module> modules = scope.getModules(cl);
|
||||
|
||||
for (Iterator<Module> iter = modules.iterator(); iter.hasNext();) {
|
||||
Module m = (Module) iter.next();
|
||||
|
||||
if (buf.length() > 0)
|
||||
buf.append(File.pathSeparator);
|
||||
if (m instanceof JarFileModule) {
|
||||
JarFileModule jarFileModule = (JarFileModule) m;
|
||||
|
||||
buf.append(jarFileModule.getAbsolutePath());
|
||||
} else if (m instanceof DirectoryTreeModule) {
|
||||
DirectoryTreeModule directoryTreeModule = (DirectoryTreeModule) m;
|
||||
|
||||
buf.append(directoryTreeModule.getPath());
|
||||
} else
|
||||
Assertions.UNREACHABLE("Module entry is neither jar file nor directory");
|
||||
}
|
||||
cl = cl.getParent();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Project -> AST code from org.eclipse.jdt.core.tests.performance
|
||||
*/
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void loadAllSources(Set modules) {
|
||||
// TODO: we might need one AST (-> "Object" class) for all files.
|
||||
// TODO: group by project and send 'em in
|
||||
JDTJava2CAstTranslator jdt2cast = new JDTJava2CAstTranslator(sourceLoader);
|
||||
final Java2IRTranslator java2ir = new Java2IRTranslator(jdt2cast, sourceLoader);
|
||||
|
||||
System.out.println(modules);
|
||||
|
||||
// sort files into projects
|
||||
HashMap<IProject, ArrayList<ICompilationUnit>> projectsFiles = new HashMap<IProject, ArrayList<ICompilationUnit>>();
|
||||
for (Object m : modules) {
|
||||
assert m instanceof EclipseSourceFileModule : "Expecing EclipseSourceFileModule";
|
||||
EclipseSourceFileModule entry = (EclipseSourceFileModule) m;
|
||||
IProject proj = entry.getIFile().getProject();
|
||||
if (!projectsFiles.containsKey(proj))
|
||||
projectsFiles.put(proj, new ArrayList<ICompilationUnit>());
|
||||
projectsFiles.get(proj).add(JavaCore.createCompilationUnitFrom(entry.getIFile()));
|
||||
}
|
||||
|
||||
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.createASTs(files.toArray(new ICompilationUnit[files.size()]), new String[0], new ASTRequestor() {
|
||||
public void acceptAST(ICompilationUnit source, CompilationUnit ast) {
|
||||
|
||||
try {
|
||||
java2ir.translate(ast, source.getUnderlyingResource().getLocation().toOSString());
|
||||
} catch (JavaModelException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
IProblem[] problems = ast.getProblems();
|
||||
int length = problems.length;
|
||||
if (length > 0) {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
for (int i = 0; i < length; i++) {
|
||||
buffer.append(problems[i].getMessage());
|
||||
buffer.append('\n');
|
||||
}
|
||||
if (length != 0)
|
||||
System.err.println("Unexpected problems in " + source.getElementName() + buffer.toString());
|
||||
}
|
||||
}
|
||||
}, null);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* This file is a derivative of code released by the University of
|
||||
* California under the terms listed below.
|
||||
*
|
||||
* WALA JDT Frontend is Copyright (c) 2008 The Regents of the
|
||||
* University of California (Regents). Provided that this notice and
|
||||
* the following two paragraphs are included in any distribution of
|
||||
* Refinement Analysis Tools or its derivative work, Regents agrees
|
||||
* not to assert any of Regents' copyright rights in Refinement
|
||||
* Analysis Tools against recipient for recipient's reproduction,
|
||||
* preparation of derivative works, public display, public
|
||||
* performance, distribution or sublicensing of Refinement Analysis
|
||||
* Tools and derivative works, in source code and object code form.
|
||||
* This agreement not to assert does not confer, by implication,
|
||||
* estoppel, or otherwise any license or rights in any intellectual
|
||||
* property of Regents, including, but not limited to, any patents
|
||||
* of Regents or Regents' employees.
|
||||
*
|
||||
* IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT,
|
||||
* INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
|
||||
* INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE
|
||||
* AND ITS DOCUMENTATION, EVEN IF REGENTS HAS BEEN ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND FURTHER DISCLAIMS ANY STATUTORY
|
||||
* WARRANTY OF NON-INFRINGEMENT. THE SOFTWARE AND ACCOMPANYING
|
||||
* DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS
|
||||
* IS". REGENTS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
|
||||
* UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*/
|
||||
package com.ibm.wala.cast.java.translator.jdt;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.jdt.core.ICompilationUnit;
|
||||
import org.eclipse.jdt.core.JavaCore;
|
||||
import org.eclipse.jdt.core.JavaModelException;
|
||||
import org.eclipse.jdt.core.compiler.IProblem;
|
||||
import org.eclipse.jdt.core.dom.AST;
|
||||
import org.eclipse.jdt.core.dom.ASTParser;
|
||||
import org.eclipse.jdt.core.dom.ASTRequestor;
|
||||
import org.eclipse.jdt.core.dom.CompilationUnit;
|
||||
|
||||
import com.ibm.wala.cast.java.translator.Java2IRTranslator;
|
||||
import com.ibm.wala.cast.java.translator.SourceModuleTranslator;
|
||||
import com.ibm.wala.classLoader.DirectoryTreeModule;
|
||||
import com.ibm.wala.classLoader.JarFileModule;
|
||||
import com.ibm.wala.classLoader.Module;
|
||||
import com.ibm.wala.ide.classloader.EclipseSourceFileModule;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
/**
|
||||
* A SourceModuleTranslator whose implementation of loadAllSources() uses the PolyglotFrontEnd pseudo-compiler to generate DOMO IR
|
||||
* for the sources in the compile-time classpath.
|
||||
*
|
||||
* @author rfuhrer
|
||||
*/
|
||||
// remove me comment: Jdt little-case = not OK, upper case = OK
|
||||
public class JDTSourceModuleTranslator implements SourceModuleTranslator {
|
||||
private JDTSourceLoaderImpl sourceLoader;
|
||||
|
||||
public JDTSourceModuleTranslator(AnalysisScope scope, JDTSourceLoaderImpl sourceLoader) {
|
||||
computeClassPath(scope);
|
||||
this.sourceLoader = sourceLoader;
|
||||
}
|
||||
|
||||
private void computeClassPath(AnalysisScope scope) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
|
||||
ClassLoaderReference cl = scope.getApplicationLoader();
|
||||
|
||||
while (cl != null) {
|
||||
List<Module> modules = scope.getModules(cl);
|
||||
|
||||
for (Iterator<Module> iter = modules.iterator(); iter.hasNext();) {
|
||||
Module m = (Module) iter.next();
|
||||
|
||||
if (buf.length() > 0)
|
||||
buf.append(File.pathSeparator);
|
||||
if (m instanceof JarFileModule) {
|
||||
JarFileModule jarFileModule = (JarFileModule) m;
|
||||
|
||||
buf.append(jarFileModule.getAbsolutePath());
|
||||
} else if (m instanceof DirectoryTreeModule) {
|
||||
DirectoryTreeModule directoryTreeModule = (DirectoryTreeModule) m;
|
||||
|
||||
buf.append(directoryTreeModule.getPath());
|
||||
} else
|
||||
Assertions.UNREACHABLE("Module entry is neither jar file nor directory");
|
||||
}
|
||||
cl = cl.getParent();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Project -> AST code from org.eclipse.jdt.core.tests.performance
|
||||
*/
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void loadAllSources(Set modules) {
|
||||
// TODO: we might need one AST (-> "Object" class) for all files.
|
||||
// TODO: group by project and send 'em in
|
||||
JDTJava2CAstTranslator jdt2cast = new JDTJava2CAstTranslator(sourceLoader);
|
||||
final Java2IRTranslator java2ir = new Java2IRTranslator(jdt2cast, sourceLoader);
|
||||
|
||||
System.out.println(modules);
|
||||
|
||||
// sort files into projects
|
||||
HashMap<IProject, ArrayList<ICompilationUnit>> projectsFiles = new HashMap<IProject, ArrayList<ICompilationUnit>>();
|
||||
for (Object m : modules) {
|
||||
assert m instanceof EclipseSourceFileModule : "Expecing EclipseSourceFileModule";
|
||||
EclipseSourceFileModule entry = (EclipseSourceFileModule) m;
|
||||
IProject proj = entry.getIFile().getProject();
|
||||
if (!projectsFiles.containsKey(proj))
|
||||
projectsFiles.put(proj, new ArrayList<ICompilationUnit>());
|
||||
projectsFiles.get(proj).add(JavaCore.createCompilationUnitFrom(entry.getIFile()));
|
||||
}
|
||||
|
||||
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.createASTs(files.toArray(new ICompilationUnit[files.size()]), new String[0], new ASTRequestor() {
|
||||
public void acceptAST(ICompilationUnit source, CompilationUnit ast) {
|
||||
|
||||
try {
|
||||
java2ir.translate(ast, source.getUnderlyingResource().getLocation().toOSString());
|
||||
} catch (JavaModelException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
IProblem[] problems = ast.getProblems();
|
||||
int length = problems.length;
|
||||
if (length > 0) {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
for (int i = 0; i < length; i++) {
|
||||
buffer.append(problems[i].getMessage());
|
||||
buffer.append('\n');
|
||||
}
|
||||
if (length != 0)
|
||||
System.err.println("Unexpected problems in " + source.getElementName() + buffer.toString());
|
||||
}
|
||||
}
|
||||
}, null);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,7 +8,11 @@ Bundle-Vendor: IBM
|
|||
Require-Bundle: com.ibm.wala.cast.java;bundle-version="1.0.0",
|
||||
com.ibm.wala.cast;bundle-version="1.0.0",
|
||||
com.ibm.wala.core;bundle-version="1.1.3",
|
||||
org.eclipse.core.runtime
|
||||
org.eclipse.core.runtime,
|
||||
com.ibm.wala.shrike;bundle-version="1.1.3",
|
||||
com.ibm.wala.ide;bundle-version="1.1.3",
|
||||
org.eclipse.jdt.core;bundle-version="3.4.2",
|
||||
org.eclipse.core.resources;bundle-version="3.4.1"
|
||||
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Export-Package: com.ibm.wala.cast.java.client.polyglot,
|
||||
|
|
|
@ -20,7 +20,7 @@ import org.eclipse.jdt.core.IJavaProject;
|
|||
|
||||
import com.ibm.wala.cast.java.client.impl.ZeroCFABuilderFactory;
|
||||
import com.ibm.wala.client.AbstractAnalysisEngine;
|
||||
import com.ibm.wala.eclipse.util.EclipseProjectPath;
|
||||
import com.ibm.wala.ide.util.EclipseProjectPath;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraphBuilder;
|
||||
|
|
|
@ -26,8 +26,8 @@ import com.ibm.wala.classLoader.ClassLoaderFactory;
|
|||
import com.ibm.wala.classLoader.Module;
|
||||
import com.ibm.wala.classLoader.SourceDirectoryTreeModule;
|
||||
import com.ibm.wala.core.plugin.CorePlugin;
|
||||
import com.ibm.wala.eclipse.util.EclipseProjectPath;
|
||||
import com.ibm.wala.eclipse.util.EclipseProjectPath.Loader;
|
||||
import com.ibm.wala.ide.util.EclipseProjectPath;
|
||||
import com.ibm.wala.ide.util.EclipseProjectPath.Loader;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Java AST WALA Test Plug-in
|
||||
Bundle-SymbolicName: com.ibm.wala.cast.java.test
|
||||
Bundle-Version: 1.0.0
|
||||
Bundle-Activator: com.ibm.wala.cast.java.test.TestPlugin
|
||||
Bundle-Vendor: IBM
|
||||
Require-Bundle: com.ibm.wala.core.tests,
|
||||
com.ibm.wala.cast.java,
|
||||
com.ibm.wala.cast,
|
||||
com.ibm.wala.core,
|
||||
org.eclipse.core.runtime,
|
||||
org.junit4
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Export-Package: com.ibm.wala.cast.java.test
|
||||
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
||||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Java AST WALA Test Plug-in
|
||||
Bundle-SymbolicName: com.ibm.wala.cast.java.test
|
||||
Bundle-Version: 1.0.0
|
||||
Bundle-Activator: com.ibm.wala.cast.java.test.TestPlugin
|
||||
Bundle-Vendor: IBM
|
||||
Require-Bundle: org.junit4,
|
||||
com.ibm.wala.core.tests,
|
||||
com.ibm.wala.cast.java,
|
||||
com.ibm.wala.cast,
|
||||
com.ibm.wala.core,
|
||||
com.ibm.wala.shrike,
|
||||
org.eclipse.core.runtime
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Export-Package: com.ibm.wala.cast.java.test
|
||||
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
||||
|
|
|
@ -1,448 +1,419 @@
|
|||
/******************************************************************************
|
||||
* 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
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Oct 3, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.java.test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IWorkspace;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.jdt.core.IJavaProject;
|
||||
|
||||
import com.ibm.wala.cast.java.client.JavaSourceAnalysisEngine;
|
||||
import com.ibm.wala.cast.java.ipa.callgraph.JavaSourceAnalysisScope;
|
||||
import com.ibm.wala.classLoader.EclipseSourceFileModule;
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.classLoader.IClassLoader;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.classLoader.JarFileModule;
|
||||
import com.ibm.wala.classLoader.Language;
|
||||
import com.ibm.wala.classLoader.SourceDirectoryTreeModule;
|
||||
import com.ibm.wala.classLoader.SourceFileModule;
|
||||
import com.ibm.wala.core.tests.util.EclipseTestUtil;
|
||||
import com.ibm.wala.core.tests.util.WalaTestCase;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.properties.WalaProperties;
|
||||
import com.ibm.wala.ssa.IR;
|
||||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
import com.ibm.wala.types.MethodReference;
|
||||
import com.ibm.wala.types.TypeName;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.collections.Pair;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.strings.Atom;
|
||||
|
||||
public abstract class IRTests extends WalaTestCase {
|
||||
public IRTests(String name, String projectName) {
|
||||
super(name);
|
||||
this.projectName = projectName;
|
||||
}
|
||||
|
||||
protected final String projectName;
|
||||
|
||||
protected static String javaHomePath;
|
||||
|
||||
private String testSrcPath = "." + File.separator + "src";
|
||||
|
||||
public static List<String> rtJar;
|
||||
|
||||
protected static List<IRAssertion> emptyList = Collections.emptyList();
|
||||
|
||||
static {
|
||||
boolean found = false;
|
||||
try {
|
||||
rtJar = new LinkedList<String>();
|
||||
|
||||
Properties p = WalaProperties.loadProperties();
|
||||
javaHomePath = p.getProperty(WalaProperties.J2SE_DIR);
|
||||
|
||||
if (new File(javaHomePath).isDirectory()) {
|
||||
if ("Mac OS X".equals(System.getProperty("os.name"))) { // nick
|
||||
/**
|
||||
* todo: {@link WalaProperties#getJ2SEJarFiles()}
|
||||
*/
|
||||
rtJar.add(javaHomePath + "/classes.jar");
|
||||
rtJar.add(javaHomePath + "/ui.jar");
|
||||
} else {
|
||||
rtJar.add(javaHomePath + File.separator + "classes.jar");
|
||||
rtJar.add(javaHomePath + File.separator + "rt.jar");
|
||||
rtJar.add(javaHomePath + File.separator + "core.jar");
|
||||
rtJar.add(javaHomePath + File.separator + "vm.jar");
|
||||
}
|
||||
found = true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// no properties
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
javaHomePath = System.getProperty("java.home");
|
||||
if ("Mac OS X".equals(System.getProperty("os.name"))) { // nick
|
||||
rtJar.add(javaHomePath + "/../Classes/classes.jar");
|
||||
rtJar.add(javaHomePath + "/../Classes/ui.jar");
|
||||
} else {
|
||||
rtJar.add(javaHomePath + File.separator + "lib" + File.separator + "rt.jar");
|
||||
rtJar.add(javaHomePath + File.separator + "lib" + File.separator + "core.jar");
|
||||
rtJar.add(javaHomePath + File.separator + "lib" + File.separator + "vm.jar");
|
||||
rtJar.add(javaHomePath + File.separator + "lib" + File.separator + "classes.jar");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface IRAssertion {
|
||||
|
||||
void check(CallGraph cg) throws Exception;
|
||||
|
||||
}
|
||||
|
||||
protected static class EdgeAssertions implements IRAssertion {
|
||||
public final String srcDescriptor;
|
||||
|
||||
public final List/* <String> */<String> tgtDescriptors = new ArrayList<String>();
|
||||
|
||||
public EdgeAssertions(String srcDescriptor) {
|
||||
this.srcDescriptor = srcDescriptor;
|
||||
}
|
||||
|
||||
public static EdgeAssertions make(String srcDescriptor, String tgtDescriptor) {
|
||||
EdgeAssertions ea = new EdgeAssertions(srcDescriptor);
|
||||
ea.tgtDescriptors.add(tgtDescriptor);
|
||||
return ea;
|
||||
}
|
||||
|
||||
public static EdgeAssertions make(String srcDescriptor, String tgtDescriptor1, String tgtDescriptor2) {
|
||||
EdgeAssertions ea = new EdgeAssertions(srcDescriptor);
|
||||
ea.tgtDescriptors.add(tgtDescriptor1);
|
||||
ea.tgtDescriptors.add(tgtDescriptor2);
|
||||
return ea;
|
||||
}
|
||||
|
||||
public static EdgeAssertions make(String srcDescriptor, String tgtDescriptor1, String tgtDescriptor2, String tgtDescriptor3) {
|
||||
EdgeAssertions ea = new EdgeAssertions(srcDescriptor);
|
||||
ea.tgtDescriptors.add(tgtDescriptor1);
|
||||
ea.tgtDescriptors.add(tgtDescriptor2);
|
||||
ea.tgtDescriptors.add(tgtDescriptor3);
|
||||
return ea;
|
||||
}
|
||||
|
||||
public static EdgeAssertions make(String srcDescriptor, String tgtDescriptor1, String tgtDescriptor2, String tgtDescriptor3,
|
||||
String tgtDescriptor4) {
|
||||
EdgeAssertions ea = new EdgeAssertions(srcDescriptor);
|
||||
ea.tgtDescriptors.add(tgtDescriptor1);
|
||||
ea.tgtDescriptors.add(tgtDescriptor2);
|
||||
ea.tgtDescriptors.add(tgtDescriptor3);
|
||||
ea.tgtDescriptors.add(tgtDescriptor4);
|
||||
return ea;
|
||||
}
|
||||
|
||||
public void check(CallGraph callGraph) {
|
||||
MethodReference srcMethod = descriptorToMethodRef(this.srcDescriptor, callGraph.getClassHierarchy());
|
||||
Set<CGNode> srcNodes = callGraph.getNodes(srcMethod);
|
||||
|
||||
if (srcNodes.size() == 0) {
|
||||
System.err.println(("Unreachable/non-existent method: " + srcMethod));
|
||||
return;
|
||||
}
|
||||
if (srcNodes.size() > 1) {
|
||||
System.err.println("Context-sensitive call graph?");
|
||||
}
|
||||
|
||||
// Assume only one node for src method
|
||||
CGNode srcNode = srcNodes.iterator().next();
|
||||
|
||||
for (String target : this.tgtDescriptors) {
|
||||
MethodReference tgtMethod = descriptorToMethodRef(target, callGraph.getClassHierarchy());
|
||||
// Assume only one node for target method
|
||||
Set<CGNode> tgtNodes = callGraph.getNodes(tgtMethod);
|
||||
if (tgtNodes.size() == 0) {
|
||||
System.err.println(("Unreachable/non-existent method: " + tgtMethod));
|
||||
continue;
|
||||
}
|
||||
CGNode tgtNode = tgtNodes.iterator().next();
|
||||
|
||||
boolean found = false;
|
||||
for (Iterator<? extends CGNode> succIter = callGraph.getSuccNodes(srcNode); succIter.hasNext();) {
|
||||
CGNode succ = succIter.next();
|
||||
|
||||
if (tgtNode == succ) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
System.err.println(("Missing edge: " + srcMethod + " -> " + tgtMethod));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static class SourceMapAssertion implements IRAssertion {
|
||||
private final String method;
|
||||
|
||||
private final String variableName;
|
||||
|
||||
private final int definingLineNumber;
|
||||
|
||||
protected SourceMapAssertion(String method, String variableName, int definingLineNumber) {
|
||||
this.method = method;
|
||||
this.variableName = variableName;
|
||||
this.definingLineNumber = definingLineNumber;
|
||||
}
|
||||
|
||||
public void check(CallGraph cg) {
|
||||
|
||||
MethodReference mref = descriptorToMethodRef(method, cg.getClassHierarchy());
|
||||
|
||||
for (CGNode cgNode : cg.getNodes(mref)) {
|
||||
Assert.assertTrue("failed for " + this.variableName + " in " + cgNode, this.check(cgNode.getMethod(), cgNode.getIR()));
|
||||
}
|
||||
}
|
||||
|
||||
boolean check(IMethod m, IR ir) {
|
||||
System.err.println(("check for " + variableName + " defined at " + definingLineNumber));
|
||||
SSAInstruction[] insts = ir.getInstructions();
|
||||
for (int i = 0; i < insts.length; i++) {
|
||||
if (insts[i] != null) {
|
||||
int ln = m.getLineNumber(i);
|
||||
if (ln == definingLineNumber) {
|
||||
System.err.println((" found " + insts[i] + " at " + ln));
|
||||
for (int j = 0; j < insts[i].getNumberOfDefs(); j++) {
|
||||
int def = insts[i].getDef(j);
|
||||
System.err.println((" looking at def " + j + ": " + def));
|
||||
String[] names = ir.getLocalNames(i, def);
|
||||
if (names != null) {
|
||||
for (String name : names) {
|
||||
System.err.println((" looking at name " + name));
|
||||
if (name.equals(variableName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected Collection<String> singleTestSrc() {
|
||||
return Collections.singletonList(getTestSrcPath() + File.separator + singleJavaInputForTest());
|
||||
}
|
||||
|
||||
protected Collection<String> singleTestSrc(final String folder) {
|
||||
return Collections.singletonList(getTestSrcPath() + File.separator + folder + File.separator + singleJavaInputForTest());
|
||||
}
|
||||
|
||||
protected Collection<String> singlePkgTestSrc(String pkgName) {
|
||||
return Collections.singletonList(getTestSrcPath() + File.separator + singleJavaPkgInputForTest(pkgName));
|
||||
}
|
||||
|
||||
protected String[] simpleTestEntryPoint() {
|
||||
return new String[] { "L" + getName().substring(4) };
|
||||
}
|
||||
|
||||
protected String[] simplePkgTestEntryPoint(String pkgName) {
|
||||
return new String[] { "L" + pkgName + "/" + getName().substring(4) };
|
||||
}
|
||||
|
||||
protected abstract JavaSourceAnalysisEngine getAnalysisEngine(String[] mainClassDescriptors);
|
||||
|
||||
public Pair runTest(Collection<String> sources, List<String> libs, String[] mainClassDescriptors, List<? extends IRAssertion> ca,
|
||||
boolean assertReachable) {
|
||||
try {
|
||||
JavaSourceAnalysisEngine engine = getAnalysisEngine(mainClassDescriptors);
|
||||
|
||||
populateScope(engine, sources, libs);
|
||||
|
||||
CallGraph callGraph = engine.buildDefaultCallGraph();
|
||||
System.err.println(callGraph.toString());
|
||||
|
||||
// If we've gotten this far, IR has been produced.
|
||||
dumpIR(callGraph, assertReachable);
|
||||
|
||||
// Now check any assertions as to source mapping
|
||||
for (IRAssertion IRAssertion : ca) {
|
||||
IRAssertion.check(callGraph);
|
||||
}
|
||||
|
||||
return Pair.make(callGraph, engine.getPointerAnalysis());
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.assertTrue(e.toString(), false);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected static void dumpIR(CallGraph cg, boolean assertReachable) throws IOException {
|
||||
Set<IMethod> unreachable = HashSetFactory.make();
|
||||
IClassHierarchy cha = cg.getClassHierarchy();
|
||||
IClassLoader sourceLoader = cha.getLoader(JavaSourceAnalysisScope.SOURCE);
|
||||
for (Iterator iter = sourceLoader.iterateAllClasses(); iter.hasNext();) {
|
||||
IClass clazz = (IClass) iter.next();
|
||||
|
||||
System.err.println(clazz);
|
||||
if (clazz.isInterface())
|
||||
continue;
|
||||
|
||||
for (IMethod m : clazz.getDeclaredMethods()) {
|
||||
if (m.isAbstract()) {
|
||||
System.err.println(m);
|
||||
} else {
|
||||
Iterator nodeIter = cg.getNodes(m.getReference()).iterator();
|
||||
if (!nodeIter.hasNext()) {
|
||||
System.err.println(("Method " + m.getReference() + " not reachable?"));
|
||||
unreachable.add(m);
|
||||
continue;
|
||||
}
|
||||
CGNode node = (CGNode) nodeIter.next();
|
||||
System.err.println(node.getIR());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (assertReachable) {
|
||||
Assert.assertTrue("unreachable methods: " + unreachable.toString(), unreachable.isEmpty());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param srcMethodDescriptor
|
||||
* a full method descriptor of the form ldr#type#methName#methSig
|
||||
* example: Source#Simple1#main#([Ljava/lang/String;)V
|
||||
* @param cha
|
||||
* @return
|
||||
*/
|
||||
public static MethodReference descriptorToMethodRef(String srcMethodDescriptor, IClassHierarchy cha) {
|
||||
String[] ldrTypeMeth = srcMethodDescriptor.split("\\#");
|
||||
|
||||
String loaderName = ldrTypeMeth[0];
|
||||
String typeStr = ldrTypeMeth[1];
|
||||
String methName = ldrTypeMeth[2];
|
||||
String methSig = ldrTypeMeth[3];
|
||||
|
||||
TypeReference typeRef = findOrCreateTypeReference(loaderName, typeStr, cha);
|
||||
|
||||
Language l = cha.getLoader(typeRef.getClassLoader()).getLanguage();
|
||||
return MethodReference.findOrCreate(l, typeRef, methName, methSig);
|
||||
}
|
||||
|
||||
static TypeReference findOrCreateTypeReference(String loaderName, String typeStr, IClassHierarchy cha) {
|
||||
ClassLoaderReference clr = findLoader(loaderName, cha);
|
||||
TypeName typeName = TypeName.string2TypeName("L" + typeStr);
|
||||
TypeReference typeRef = TypeReference.findOrCreate(clr, typeName);
|
||||
return typeRef;
|
||||
}
|
||||
|
||||
private static ClassLoaderReference findLoader(String loaderName, IClassHierarchy cha) {
|
||||
Atom loaderAtom = Atom.findOrCreateUnicodeAtom(loaderName);
|
||||
IClassLoader[] loaders = cha.getLoaders();
|
||||
for (IClassLoader loader : loaders) {
|
||||
if (loader.getName() == loaderAtom) {
|
||||
return loader.getReference();
|
||||
}
|
||||
}
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void populateScope(JavaSourceAnalysisEngine engine,
|
||||
Collection<String> sources,
|
||||
List<String> libs)
|
||||
throws IOException
|
||||
{
|
||||
boolean foundLib = false;
|
||||
for (String lib : libs) {
|
||||
File libFile = new File(lib);
|
||||
if (libFile.exists()) {
|
||||
foundLib = true;
|
||||
engine.addSystemModule(new JarFileModule(new JarFile(libFile)));
|
||||
}
|
||||
}
|
||||
assert foundLib : "couldn't find library file from " + libs;
|
||||
|
||||
IWorkspace w = null;
|
||||
IJavaProject project = null;
|
||||
try {
|
||||
if (projectName != null) {
|
||||
w = ResourcesPlugin.getWorkspace();
|
||||
project = EclipseTestUtil.getNamedProject(projectName);
|
||||
}
|
||||
} catch (IllegalStateException e) {
|
||||
// use Workspace only if it exists
|
||||
}
|
||||
|
||||
for (String srcFilePath : sources) {
|
||||
|
||||
if (w != null) {
|
||||
IFile file = project.getProject().getFile(srcFilePath);
|
||||
try {
|
||||
engine.addSourceModule(EclipseSourceFileModule.createEclipseSourceFileModule(file));
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertTrue(e.getMessage(), false);
|
||||
}
|
||||
|
||||
} else {
|
||||
String srcFileName = srcFilePath.substring(srcFilePath.lastIndexOf(File.separator) + 1);
|
||||
File f = new File(srcFilePath);
|
||||
Assert.assertTrue("couldn't find " + srcFilePath, f.exists());
|
||||
if (f.isDirectory()) {
|
||||
engine.addSourceModule(new SourceDirectoryTreeModule(f));
|
||||
} else {
|
||||
engine.addSourceModule(new SourceFileModule(f, srcFileName));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void setTestSrcPath(String testSrcPath) {
|
||||
this.testSrcPath = testSrcPath;
|
||||
}
|
||||
|
||||
protected String getTestSrcPath() {
|
||||
return testSrcPath;
|
||||
}
|
||||
|
||||
protected String singleJavaInputForTest() {
|
||||
return getName().substring(4) + ".java";
|
||||
}
|
||||
|
||||
protected String singleInputForTest() {
|
||||
return getName().substring(4);
|
||||
}
|
||||
|
||||
protected String singleJavaPkgInputForTest(String pkgName) {
|
||||
return pkgName + File.separator + getName().substring(4) + ".java";
|
||||
}
|
||||
|
||||
}
|
||||
/******************************************************************************
|
||||
* 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
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Oct 3, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.java.test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import com.ibm.wala.cast.java.client.JavaSourceAnalysisEngine;
|
||||
import com.ibm.wala.cast.java.ipa.callgraph.JavaSourceAnalysisScope;
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.classLoader.IClassLoader;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.classLoader.JarFileModule;
|
||||
import com.ibm.wala.classLoader.Language;
|
||||
import com.ibm.wala.classLoader.SourceDirectoryTreeModule;
|
||||
import com.ibm.wala.classLoader.SourceFileModule;
|
||||
import com.ibm.wala.core.tests.util.WalaTestCase;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.properties.WalaProperties;
|
||||
import com.ibm.wala.ssa.IR;
|
||||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
import com.ibm.wala.types.MethodReference;
|
||||
import com.ibm.wala.types.TypeName;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.collections.Pair;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.strings.Atom;
|
||||
|
||||
public abstract class IRTests extends WalaTestCase {
|
||||
public IRTests(String name, String projectName) {
|
||||
super(name);
|
||||
this.projectName = projectName;
|
||||
}
|
||||
|
||||
protected final String projectName;
|
||||
|
||||
protected static String javaHomePath;
|
||||
|
||||
private String testSrcPath = "." + File.separator + "src";
|
||||
|
||||
public static List<String> rtJar;
|
||||
|
||||
protected static List<IRAssertion> emptyList = Collections.emptyList();
|
||||
|
||||
static {
|
||||
boolean found = false;
|
||||
try {
|
||||
rtJar = new LinkedList<String>();
|
||||
|
||||
Properties p = WalaProperties.loadProperties();
|
||||
javaHomePath = p.getProperty(WalaProperties.J2SE_DIR);
|
||||
|
||||
if (new File(javaHomePath).isDirectory()) {
|
||||
if ("Mac OS X".equals(System.getProperty("os.name"))) { // nick
|
||||
/**
|
||||
* todo: {@link WalaProperties#getJ2SEJarFiles()}
|
||||
*/
|
||||
rtJar.add(javaHomePath + "/classes.jar");
|
||||
rtJar.add(javaHomePath + "/ui.jar");
|
||||
} else {
|
||||
rtJar.add(javaHomePath + File.separator + "classes.jar");
|
||||
rtJar.add(javaHomePath + File.separator + "rt.jar");
|
||||
rtJar.add(javaHomePath + File.separator + "core.jar");
|
||||
rtJar.add(javaHomePath + File.separator + "vm.jar");
|
||||
}
|
||||
found = true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// no properties
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
javaHomePath = System.getProperty("java.home");
|
||||
if ("Mac OS X".equals(System.getProperty("os.name"))) { // nick
|
||||
rtJar.add(javaHomePath + "/../Classes/classes.jar");
|
||||
rtJar.add(javaHomePath + "/../Classes/ui.jar");
|
||||
} else {
|
||||
rtJar.add(javaHomePath + File.separator + "lib" + File.separator + "rt.jar");
|
||||
rtJar.add(javaHomePath + File.separator + "lib" + File.separator + "core.jar");
|
||||
rtJar.add(javaHomePath + File.separator + "lib" + File.separator + "vm.jar");
|
||||
rtJar.add(javaHomePath + File.separator + "lib" + File.separator + "classes.jar");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface IRAssertion {
|
||||
|
||||
void check(CallGraph cg) throws Exception;
|
||||
|
||||
}
|
||||
|
||||
protected static class EdgeAssertions implements IRAssertion {
|
||||
public final String srcDescriptor;
|
||||
|
||||
public final List/* <String> */<String> tgtDescriptors = new ArrayList<String>();
|
||||
|
||||
public EdgeAssertions(String srcDescriptor) {
|
||||
this.srcDescriptor = srcDescriptor;
|
||||
}
|
||||
|
||||
public static EdgeAssertions make(String srcDescriptor, String tgtDescriptor) {
|
||||
EdgeAssertions ea = new EdgeAssertions(srcDescriptor);
|
||||
ea.tgtDescriptors.add(tgtDescriptor);
|
||||
return ea;
|
||||
}
|
||||
|
||||
public static EdgeAssertions make(String srcDescriptor, String tgtDescriptor1, String tgtDescriptor2) {
|
||||
EdgeAssertions ea = new EdgeAssertions(srcDescriptor);
|
||||
ea.tgtDescriptors.add(tgtDescriptor1);
|
||||
ea.tgtDescriptors.add(tgtDescriptor2);
|
||||
return ea;
|
||||
}
|
||||
|
||||
public static EdgeAssertions make(String srcDescriptor, String tgtDescriptor1, String tgtDescriptor2, String tgtDescriptor3) {
|
||||
EdgeAssertions ea = new EdgeAssertions(srcDescriptor);
|
||||
ea.tgtDescriptors.add(tgtDescriptor1);
|
||||
ea.tgtDescriptors.add(tgtDescriptor2);
|
||||
ea.tgtDescriptors.add(tgtDescriptor3);
|
||||
return ea;
|
||||
}
|
||||
|
||||
public static EdgeAssertions make(String srcDescriptor, String tgtDescriptor1, String tgtDescriptor2, String tgtDescriptor3,
|
||||
String tgtDescriptor4) {
|
||||
EdgeAssertions ea = new EdgeAssertions(srcDescriptor);
|
||||
ea.tgtDescriptors.add(tgtDescriptor1);
|
||||
ea.tgtDescriptors.add(tgtDescriptor2);
|
||||
ea.tgtDescriptors.add(tgtDescriptor3);
|
||||
ea.tgtDescriptors.add(tgtDescriptor4);
|
||||
return ea;
|
||||
}
|
||||
|
||||
public void check(CallGraph callGraph) {
|
||||
MethodReference srcMethod = descriptorToMethodRef(this.srcDescriptor, callGraph.getClassHierarchy());
|
||||
Set<CGNode> srcNodes = callGraph.getNodes(srcMethod);
|
||||
|
||||
if (srcNodes.size() == 0) {
|
||||
System.err.println(("Unreachable/non-existent method: " + srcMethod));
|
||||
return;
|
||||
}
|
||||
if (srcNodes.size() > 1) {
|
||||
System.err.println("Context-sensitive call graph?");
|
||||
}
|
||||
|
||||
// Assume only one node for src method
|
||||
CGNode srcNode = srcNodes.iterator().next();
|
||||
|
||||
for (String target : this.tgtDescriptors) {
|
||||
MethodReference tgtMethod = descriptorToMethodRef(target, callGraph.getClassHierarchy());
|
||||
// Assume only one node for target method
|
||||
Set<CGNode> tgtNodes = callGraph.getNodes(tgtMethod);
|
||||
if (tgtNodes.size() == 0) {
|
||||
System.err.println(("Unreachable/non-existent method: " + tgtMethod));
|
||||
continue;
|
||||
}
|
||||
CGNode tgtNode = tgtNodes.iterator().next();
|
||||
|
||||
boolean found = false;
|
||||
for (Iterator<? extends CGNode> succIter = callGraph.getSuccNodes(srcNode); succIter.hasNext();) {
|
||||
CGNode succ = succIter.next();
|
||||
|
||||
if (tgtNode == succ) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
System.err.println(("Missing edge: " + srcMethod + " -> " + tgtMethod));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static class SourceMapAssertion implements IRAssertion {
|
||||
private final String method;
|
||||
|
||||
private final String variableName;
|
||||
|
||||
private final int definingLineNumber;
|
||||
|
||||
protected SourceMapAssertion(String method, String variableName, int definingLineNumber) {
|
||||
this.method = method;
|
||||
this.variableName = variableName;
|
||||
this.definingLineNumber = definingLineNumber;
|
||||
}
|
||||
|
||||
public void check(CallGraph cg) {
|
||||
|
||||
MethodReference mref = descriptorToMethodRef(method, cg.getClassHierarchy());
|
||||
|
||||
for (CGNode cgNode : cg.getNodes(mref)) {
|
||||
Assert.assertTrue("failed for " + this.variableName + " in " + cgNode, this.check(cgNode.getMethod(), cgNode.getIR()));
|
||||
}
|
||||
}
|
||||
|
||||
boolean check(IMethod m, IR ir) {
|
||||
System.err.println(("check for " + variableName + " defined at " + definingLineNumber));
|
||||
SSAInstruction[] insts = ir.getInstructions();
|
||||
for (int i = 0; i < insts.length; i++) {
|
||||
if (insts[i] != null) {
|
||||
int ln = m.getLineNumber(i);
|
||||
if (ln == definingLineNumber) {
|
||||
System.err.println((" found " + insts[i] + " at " + ln));
|
||||
for (int j = 0; j < insts[i].getNumberOfDefs(); j++) {
|
||||
int def = insts[i].getDef(j);
|
||||
System.err.println((" looking at def " + j + ": " + def));
|
||||
String[] names = ir.getLocalNames(i, def);
|
||||
if (names != null) {
|
||||
for (String name : names) {
|
||||
System.err.println((" looking at name " + name));
|
||||
if (name.equals(variableName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected Collection<String> singleTestSrc() {
|
||||
return Collections.singletonList(getTestSrcPath() + File.separator + singleJavaInputForTest());
|
||||
}
|
||||
|
||||
protected Collection<String> singleTestSrc(final String folder) {
|
||||
return Collections.singletonList(getTestSrcPath() + File.separator + folder + File.separator + singleJavaInputForTest());
|
||||
}
|
||||
|
||||
protected Collection<String> singlePkgTestSrc(String pkgName) {
|
||||
return Collections.singletonList(getTestSrcPath() + File.separator + singleJavaPkgInputForTest(pkgName));
|
||||
}
|
||||
|
||||
protected String[] simpleTestEntryPoint() {
|
||||
return new String[] { "L" + getName().substring(4) };
|
||||
}
|
||||
|
||||
protected String[] simplePkgTestEntryPoint(String pkgName) {
|
||||
return new String[] { "L" + pkgName + "/" + getName().substring(4) };
|
||||
}
|
||||
|
||||
protected abstract JavaSourceAnalysisEngine getAnalysisEngine(String[] mainClassDescriptors);
|
||||
|
||||
public Pair runTest(Collection<String> sources, List<String> libs, String[] mainClassDescriptors, List<? extends IRAssertion> ca,
|
||||
boolean assertReachable) {
|
||||
try {
|
||||
JavaSourceAnalysisEngine engine = getAnalysisEngine(mainClassDescriptors);
|
||||
|
||||
populateScope(engine, sources, libs);
|
||||
|
||||
CallGraph callGraph = engine.buildDefaultCallGraph();
|
||||
System.err.println(callGraph.toString());
|
||||
|
||||
// If we've gotten this far, IR has been produced.
|
||||
dumpIR(callGraph, assertReachable);
|
||||
|
||||
// Now check any assertions as to source mapping
|
||||
for (IRAssertion IRAssertion : ca) {
|
||||
IRAssertion.check(callGraph);
|
||||
}
|
||||
|
||||
return Pair.make(callGraph, engine.getPointerAnalysis());
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.assertTrue(e.toString(), false);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected static void dumpIR(CallGraph cg, boolean assertReachable) throws IOException {
|
||||
Set<IMethod> unreachable = HashSetFactory.make();
|
||||
IClassHierarchy cha = cg.getClassHierarchy();
|
||||
IClassLoader sourceLoader = cha.getLoader(JavaSourceAnalysisScope.SOURCE);
|
||||
for (Iterator iter = sourceLoader.iterateAllClasses(); iter.hasNext();) {
|
||||
IClass clazz = (IClass) iter.next();
|
||||
|
||||
System.err.println(clazz);
|
||||
if (clazz.isInterface())
|
||||
continue;
|
||||
|
||||
for (IMethod m : clazz.getDeclaredMethods()) {
|
||||
if (m.isAbstract()) {
|
||||
System.err.println(m);
|
||||
} else {
|
||||
Iterator nodeIter = cg.getNodes(m.getReference()).iterator();
|
||||
if (!nodeIter.hasNext()) {
|
||||
System.err.println(("Method " + m.getReference() + " not reachable?"));
|
||||
unreachable.add(m);
|
||||
continue;
|
||||
}
|
||||
CGNode node = (CGNode) nodeIter.next();
|
||||
System.err.println(node.getIR());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (assertReachable) {
|
||||
Assert.assertTrue("unreachable methods: " + unreachable.toString(), unreachable.isEmpty());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param srcMethodDescriptor
|
||||
* a full method descriptor of the form ldr#type#methName#methSig
|
||||
* example: Source#Simple1#main#([Ljava/lang/String;)V
|
||||
* @param cha
|
||||
* @return
|
||||
*/
|
||||
public static MethodReference descriptorToMethodRef(String srcMethodDescriptor, IClassHierarchy cha) {
|
||||
String[] ldrTypeMeth = srcMethodDescriptor.split("\\#");
|
||||
|
||||
String loaderName = ldrTypeMeth[0];
|
||||
String typeStr = ldrTypeMeth[1];
|
||||
String methName = ldrTypeMeth[2];
|
||||
String methSig = ldrTypeMeth[3];
|
||||
|
||||
TypeReference typeRef = findOrCreateTypeReference(loaderName, typeStr, cha);
|
||||
|
||||
Language l = cha.getLoader(typeRef.getClassLoader()).getLanguage();
|
||||
return MethodReference.findOrCreate(l, typeRef, methName, methSig);
|
||||
}
|
||||
|
||||
static TypeReference findOrCreateTypeReference(String loaderName, String typeStr, IClassHierarchy cha) {
|
||||
ClassLoaderReference clr = findLoader(loaderName, cha);
|
||||
TypeName typeName = TypeName.string2TypeName("L" + typeStr);
|
||||
TypeReference typeRef = TypeReference.findOrCreate(clr, typeName);
|
||||
return typeRef;
|
||||
}
|
||||
|
||||
private static ClassLoaderReference findLoader(String loaderName, IClassHierarchy cha) {
|
||||
Atom loaderAtom = Atom.findOrCreateUnicodeAtom(loaderName);
|
||||
IClassLoader[] loaders = cha.getLoaders();
|
||||
for (IClassLoader loader : loaders) {
|
||||
if (loader.getName() == loaderAtom) {
|
||||
return loader.getReference();
|
||||
}
|
||||
}
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void populateScope(JavaSourceAnalysisEngine engine,
|
||||
Collection<String> sources,
|
||||
List<String> libs)
|
||||
throws IOException
|
||||
{
|
||||
boolean foundLib = false;
|
||||
for (String lib : libs) {
|
||||
File libFile = new File(lib);
|
||||
if (libFile.exists()) {
|
||||
foundLib = true;
|
||||
engine.addSystemModule(new JarFileModule(new JarFile(libFile)));
|
||||
}
|
||||
}
|
||||
assert foundLib : "couldn't find library file from " + libs;
|
||||
|
||||
for (String srcFilePath : sources) {
|
||||
String srcFileName = srcFilePath.substring(srcFilePath.lastIndexOf(File.separator) + 1);
|
||||
File f = new File(srcFilePath);
|
||||
Assert.assertTrue("couldn't find " + srcFilePath, f.exists());
|
||||
if (f.isDirectory()) {
|
||||
engine.addSourceModule(new SourceDirectoryTreeModule(f));
|
||||
} else {
|
||||
engine.addSourceModule(new SourceFileModule(f, srcFileName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void setTestSrcPath(String testSrcPath) {
|
||||
this.testSrcPath = testSrcPath;
|
||||
}
|
||||
|
||||
protected String getTestSrcPath() {
|
||||
return testSrcPath;
|
||||
}
|
||||
|
||||
protected String singleJavaInputForTest() {
|
||||
return getName().substring(4) + ".java";
|
||||
}
|
||||
|
||||
protected String singleInputForTest() {
|
||||
return getName().substring(4);
|
||||
}
|
||||
|
||||
protected String singleJavaPkgInputForTest(String pkgName) {
|
||||
return pkgName + File.separator + getName().substring(4) + ".java";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,24 +1,26 @@
|
|||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Java Source WALA Front End
|
||||
Bundle-SymbolicName: com.ibm.wala.cast.java
|
||||
Bundle-Version: 1.0.0
|
||||
Bundle-Activator: com.ibm.wala.cast.java.JavaSourcePlugin
|
||||
Bundle-Vendor: rfuhrer@watson.ibm.com
|
||||
Require-Bundle: com.ibm.wala.cast;visibility:=reexport,
|
||||
com.ibm.wala.core;visibility:=reexport
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Export-Package: com.ibm.wala.cast.java,
|
||||
com.ibm.wala.cast.java.analysis.typeInference,
|
||||
com.ibm.wala.cast.java.client,
|
||||
com.ibm.wala.cast.java.client.impl,
|
||||
com.ibm.wala.cast.java.examples.ast,
|
||||
com.ibm.wala.cast.java.ipa.callgraph,
|
||||
com.ibm.wala.cast.java.ipa.modref,
|
||||
com.ibm.wala.cast.java.ipa.slicer,
|
||||
com.ibm.wala.cast.java.loader,
|
||||
com.ibm.wala.cast.java.ssa,
|
||||
com.ibm.wala.cast.java.translator,
|
||||
com.ibm.wala.cast.java.types
|
||||
Bundle-ClassPath: .
|
||||
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
||||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Java Source WALA Front End
|
||||
Bundle-SymbolicName: com.ibm.wala.cast.java
|
||||
Bundle-Version: 1.0.0
|
||||
Bundle-Activator: com.ibm.wala.cast.java.JavaSourcePlugin
|
||||
Bundle-Vendor: rfuhrer@watson.ibm.com
|
||||
Require-Bundle: com.ibm.wala.cast,
|
||||
com.ibm.wala.core,
|
||||
com.ibm.wala.shrike,
|
||||
org.eclipse.core.runtime
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Export-Package: com.ibm.wala.cast.java,
|
||||
com.ibm.wala.cast.java.analysis.typeInference,
|
||||
com.ibm.wala.cast.java.client,
|
||||
com.ibm.wala.cast.java.client.impl,
|
||||
com.ibm.wala.cast.java.examples.ast,
|
||||
com.ibm.wala.cast.java.ipa.callgraph,
|
||||
com.ibm.wala.cast.java.ipa.modref,
|
||||
com.ibm.wala.cast.java.ipa.slicer,
|
||||
com.ibm.wala.cast.java.loader,
|
||||
com.ibm.wala.cast.java.ssa,
|
||||
com.ibm.wala.cast.java.translator,
|
||||
com.ibm.wala.cast.java.types
|
||||
Bundle-ClassPath: .
|
||||
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
||||
|
|
|
@ -1,114 +1,114 @@
|
|||
package com.ibm.wala.cast.java.ipa.slicer;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import com.ibm.wala.cast.ir.ssa.AstAssertInstruction;
|
||||
import com.ibm.wala.cast.java.ipa.modref.AstJavaModRef;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.impl.PartialCallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
|
||||
import com.ibm.wala.ipa.slicer.NormalStatement;
|
||||
import com.ibm.wala.ipa.slicer.SDG;
|
||||
import com.ibm.wala.ipa.slicer.Slicer;
|
||||
import com.ibm.wala.ipa.slicer.Statement;
|
||||
import com.ibm.wala.ssa.IR;
|
||||
import com.ibm.wala.ssa.SSAArrayLoadInstruction;
|
||||
import com.ibm.wala.ssa.SSAArrayStoreInstruction;
|
||||
import com.ibm.wala.ssa.SSAGetInstruction;
|
||||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
import com.ibm.wala.ssa.SSAMonitorInstruction;
|
||||
import com.ibm.wala.ssa.SSAPutInstruction;
|
||||
import com.ibm.wala.util.collections.Filter;
|
||||
import com.ibm.wala.util.collections.Pair;
|
||||
import com.ibm.wala.util.graph.traverse.DFS;
|
||||
|
||||
public class AstJavaSlicer extends Slicer {
|
||||
|
||||
/*
|
||||
* Use the passed-in SDG
|
||||
*/
|
||||
public static Collection<Statement> computeBackwardSlice(SDG sdg, Collection<Statement> ss) throws IllegalArgumentException,
|
||||
CancelException {
|
||||
return computeSlice(sdg, ss, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ss a collection of statements of interest
|
||||
* @throws CancelException
|
||||
*/
|
||||
public static Collection<Statement> computeSlice(SDG sdg, Collection<Statement> ss, boolean backward) throws CancelException {
|
||||
return new AstJavaSlicer().slice(sdg, ss, backward);
|
||||
}
|
||||
|
||||
public static Set<Statement> gatherStatements(CallGraph CG, Collection<CGNode> partialRoots, Filter<SSAInstruction> filter) {
|
||||
Set<Statement> result = new HashSet<Statement>();
|
||||
for (Iterator<CGNode> ns = DFS.getReachableNodes(CG, partialRoots).iterator(); ns.hasNext();) {
|
||||
CGNode n = ns.next();
|
||||
IR nir = n.getIR();
|
||||
if (nir != null) {
|
||||
SSAInstruction insts[] = nir.getInstructions();
|
||||
for (int i = 0; i < insts.length; i++) {
|
||||
if (filter.accepts(insts[i])) {
|
||||
result.add(new NormalStatement(n, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Set<Statement> gatherAssertions(CallGraph CG, Collection<CGNode> partialRoots) {
|
||||
return gatherStatements(CG, partialRoots, new Filter<SSAInstruction>() {
|
||||
public boolean accepts(SSAInstruction o) {
|
||||
return o instanceof AstAssertInstruction;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static Set<Statement> gatherMonitors(CallGraph CG, Collection<CGNode> partialRoots) {
|
||||
return gatherStatements(CG, partialRoots, new Filter<SSAInstruction>() {
|
||||
public boolean accepts(SSAInstruction o) {
|
||||
return o instanceof SSAMonitorInstruction;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static Set<Statement> gatherWrites(CallGraph CG, Collection<CGNode> partialRoots) {
|
||||
return gatherStatements(CG, partialRoots, new Filter<SSAInstruction>() {
|
||||
public boolean accepts(SSAInstruction o) {
|
||||
return (o instanceof SSAPutInstruction) || (o instanceof SSAArrayStoreInstruction);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static Set<Statement> gatherReads(CallGraph CG, Collection<CGNode> partialRoots) {
|
||||
return gatherStatements(CG, partialRoots, new Filter<SSAInstruction>() {
|
||||
public boolean accepts(SSAInstruction o) {
|
||||
return (o instanceof SSAGetInstruction) || (o instanceof SSAArrayLoadInstruction);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static Pair<Collection<Statement>, SDG> computeAssertionSlice(CallGraph CG, PointerAnalysis pa,
|
||||
Collection<CGNode> partialRoots, boolean multiThreadedCode) throws IllegalArgumentException, CancelException {
|
||||
CallGraph pcg = PartialCallGraph.make(CG, new LinkedHashSet<CGNode>(partialRoots));
|
||||
SDG sdg = new SDG(pcg, pa, new AstJavaModRef(), DataDependenceOptions.FULL, ControlDependenceOptions.FULL);
|
||||
System.err.println(("SDG:\n" + sdg));
|
||||
Set<Statement> stmts = gatherAssertions(CG, partialRoots);
|
||||
if (multiThreadedCode) {
|
||||
// Grab anything that has "side effects" under JMM
|
||||
stmts.addAll(gatherReads(CG, partialRoots));
|
||||
stmts.addAll(gatherWrites(CG, partialRoots));
|
||||
stmts.addAll(gatherMonitors(CG, partialRoots));
|
||||
}
|
||||
return Pair.make(AstJavaSlicer.computeBackwardSlice(sdg, stmts), sdg);
|
||||
}
|
||||
|
||||
}
|
||||
package com.ibm.wala.cast.java.ipa.slicer;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import com.ibm.wala.cast.ir.ssa.AstAssertInstruction;
|
||||
import com.ibm.wala.cast.java.ipa.modref.AstJavaModRef;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.impl.PartialCallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
|
||||
import com.ibm.wala.ipa.slicer.NormalStatement;
|
||||
import com.ibm.wala.ipa.slicer.SDG;
|
||||
import com.ibm.wala.ipa.slicer.Slicer;
|
||||
import com.ibm.wala.ipa.slicer.Statement;
|
||||
import com.ibm.wala.ssa.IR;
|
||||
import com.ibm.wala.ssa.SSAArrayLoadInstruction;
|
||||
import com.ibm.wala.ssa.SSAArrayStoreInstruction;
|
||||
import com.ibm.wala.ssa.SSAGetInstruction;
|
||||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
import com.ibm.wala.ssa.SSAMonitorInstruction;
|
||||
import com.ibm.wala.ssa.SSAPutInstruction;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.collections.Filter;
|
||||
import com.ibm.wala.util.collections.Pair;
|
||||
import com.ibm.wala.util.graph.traverse.DFS;
|
||||
|
||||
public class AstJavaSlicer extends Slicer {
|
||||
|
||||
/*
|
||||
* Use the passed-in SDG
|
||||
*/
|
||||
public static Collection<Statement> computeBackwardSlice(SDG sdg, Collection<Statement> ss) throws IllegalArgumentException,
|
||||
CancelException {
|
||||
return computeSlice(sdg, ss, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ss a collection of statements of interest
|
||||
* @throws CancelException
|
||||
*/
|
||||
public static Collection<Statement> computeSlice(SDG sdg, Collection<Statement> ss, boolean backward) throws CancelException {
|
||||
return new AstJavaSlicer().slice(sdg, ss, backward);
|
||||
}
|
||||
|
||||
public static Set<Statement> gatherStatements(CallGraph CG, Collection<CGNode> partialRoots, Filter<SSAInstruction> filter) {
|
||||
Set<Statement> result = new HashSet<Statement>();
|
||||
for (Iterator<CGNode> ns = DFS.getReachableNodes(CG, partialRoots).iterator(); ns.hasNext();) {
|
||||
CGNode n = ns.next();
|
||||
IR nir = n.getIR();
|
||||
if (nir != null) {
|
||||
SSAInstruction insts[] = nir.getInstructions();
|
||||
for (int i = 0; i < insts.length; i++) {
|
||||
if (filter.accepts(insts[i])) {
|
||||
result.add(new NormalStatement(n, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Set<Statement> gatherAssertions(CallGraph CG, Collection<CGNode> partialRoots) {
|
||||
return gatherStatements(CG, partialRoots, new Filter<SSAInstruction>() {
|
||||
public boolean accepts(SSAInstruction o) {
|
||||
return o instanceof AstAssertInstruction;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static Set<Statement> gatherMonitors(CallGraph CG, Collection<CGNode> partialRoots) {
|
||||
return gatherStatements(CG, partialRoots, new Filter<SSAInstruction>() {
|
||||
public boolean accepts(SSAInstruction o) {
|
||||
return o instanceof SSAMonitorInstruction;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static Set<Statement> gatherWrites(CallGraph CG, Collection<CGNode> partialRoots) {
|
||||
return gatherStatements(CG, partialRoots, new Filter<SSAInstruction>() {
|
||||
public boolean accepts(SSAInstruction o) {
|
||||
return (o instanceof SSAPutInstruction) || (o instanceof SSAArrayStoreInstruction);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static Set<Statement> gatherReads(CallGraph CG, Collection<CGNode> partialRoots) {
|
||||
return gatherStatements(CG, partialRoots, new Filter<SSAInstruction>() {
|
||||
public boolean accepts(SSAInstruction o) {
|
||||
return (o instanceof SSAGetInstruction) || (o instanceof SSAArrayLoadInstruction);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static Pair<Collection<Statement>, SDG> computeAssertionSlice(CallGraph CG, PointerAnalysis pa,
|
||||
Collection<CGNode> partialRoots, boolean multiThreadedCode) throws IllegalArgumentException, CancelException {
|
||||
CallGraph pcg = PartialCallGraph.make(CG, new LinkedHashSet<CGNode>(partialRoots));
|
||||
SDG sdg = new SDG(pcg, pa, new AstJavaModRef(), DataDependenceOptions.FULL, ControlDependenceOptions.FULL);
|
||||
System.err.println(("SDG:\n" + sdg));
|
||||
Set<Statement> stmts = gatherAssertions(CG, partialRoots);
|
||||
if (multiThreadedCode) {
|
||||
// Grab anything that has "side effects" under JMM
|
||||
stmts.addAll(gatherReads(CG, partialRoots));
|
||||
stmts.addAll(gatherWrites(CG, partialRoots));
|
||||
stmts.addAll(gatherMonitors(CG, partialRoots));
|
||||
}
|
||||
return Pair.make(AstJavaSlicer.computeBackwardSlice(sdg, stmts), sdg);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,8 +14,8 @@ import java.io.IOException;
|
|||
import java.net.URL;
|
||||
|
||||
import com.ibm.wala.cast.js.translator.JavaScriptTranslatorFactory;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
|
||||
public class TestAjaxsltCallGraphShape extends TestJSCallGraphShape {
|
||||
|
||||
|
|
|
@ -14,8 +14,8 @@ import java.io.IOException;
|
|||
import java.net.URL;
|
||||
|
||||
import com.ibm.wala.cast.js.translator.JavaScriptTranslatorFactory;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
|
||||
public class TestMediawikiCallGraphShape extends TestJSCallGraphShape {
|
||||
|
||||
|
|
|
@ -13,9 +13,9 @@ package com.ibm.wala.cast.js.test;
|
|||
import java.io.IOException;
|
||||
|
||||
import com.ibm.wala.cast.js.translator.JavaScriptTranslatorFactory;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PropagationCallGraphBuilder;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
|
||||
public class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
||||
|
||||
|
|
|
@ -14,8 +14,8 @@ import java.io.IOException;
|
|||
import java.net.URL;
|
||||
|
||||
import com.ibm.wala.cast.js.translator.JavaScriptTranslatorFactory;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
|
||||
public class TestSimplePageCallGraphShape extends TestJSCallGraphShape {
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@ import com.ibm.wala.cast.js.loader.JavaScriptLoader;
|
|||
import com.ibm.wala.cast.js.loader.JavaScriptLoaderFactory;
|
||||
import com.ibm.wala.cast.js.util.WebUtil;
|
||||
import com.ibm.wala.classLoader.SourceFileModule;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
|
@ -33,6 +32,7 @@ import com.ibm.wala.ipa.callgraph.propagation.PropagationCallGraphBuilder;
|
|||
import com.ibm.wala.ipa.callgraph.propagation.cfa.ZeroXInstanceKeys;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
|
||||
public class Util extends com.ibm.wala.cast.js.ipa.callgraph.Util {
|
||||
|
||||
|
|
|
@ -89,5 +89,8 @@ Export-Package: com.ibm.wala.cast.js,
|
|||
org.mozilla.javascript.xmlimpl
|
||||
Require-Bundle: com.ibm.wala.cast,
|
||||
com.ibm.wala.core,
|
||||
com.ibm.wala.cast
|
||||
com.ibm.wala.cast,
|
||||
com.ibm.wala.shrike;bundle-version="1.1.3",
|
||||
org.eclipse.equinox.common;bundle-version="3.4.0",
|
||||
org.eclipse.core.runtime;bundle-version="3.4.0"
|
||||
Bundle-ActivationPolicy: lazy
|
||||
|
|
|
@ -18,7 +18,6 @@ import com.ibm.wala.cast.js.types.JavaScriptTypes;
|
|||
import com.ibm.wala.cfg.InducedCFG;
|
||||
import com.ibm.wala.classLoader.CallSiteReference;
|
||||
import com.ibm.wala.classLoader.NewSiteReference;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
|
@ -77,7 +76,7 @@ public class JSCallGraph extends AstCallGraph {
|
|||
return null;
|
||||
}
|
||||
|
||||
protected CGNode makeFakeRootNode() throws CancelException {
|
||||
protected CGNode makeFakeRootNode() throws com.ibm.wala.util.CancelException {
|
||||
return findOrCreateNode(new JSFakeRoot(cha, options, getAnalysisCache()), Everywhere.EVERYWHERE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: CAst Test Plug-in
|
||||
Bundle-SymbolicName: com.ibm.wala.cast.test
|
||||
Bundle-Version: 1.0.0
|
||||
Bundle-Vendor: IBM
|
||||
Require-Bundle:
|
||||
com.ibm.wala.core.tests,
|
||||
com.ibm.wala.cast,
|
||||
com.ibm.wala.core,
|
||||
org.junit4
|
||||
Export-Package: com.ibm.wala.cast.test
|
||||
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
||||
|
||||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: CAst Test Plug-in
|
||||
Bundle-SymbolicName: com.ibm.wala.cast.test
|
||||
Bundle-Version: 1.0.0
|
||||
Bundle-Vendor: IBM
|
||||
Require-Bundle:
|
||||
org.junit4,
|
||||
com.ibm.wala.core.tests,
|
||||
com.ibm.wala.cast,
|
||||
com.ibm.wala.core,
|
||||
com.ibm.wala.shrike,
|
||||
org.eclipse.core.runtime
|
||||
Export-Package: com.ibm.wala.cast.test
|
||||
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
||||
|
||||
|
|
|
@ -1,27 +1,28 @@
|
|||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: WALA CAst core Plug-in
|
||||
Bundle-SymbolicName: com.ibm.wala.cast
|
||||
Bundle-Version: 1.0.0
|
||||
Bundle-Activator: com.ibm.wala.cast.plugin.AstPlugin
|
||||
Bundle-Vendor: IBM
|
||||
Require-Bundle: org.eclipse.core.runtime,
|
||||
com.ibm.wala.core
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Export-Package: com.ibm.wala.cast.analysis.typeInference,
|
||||
com.ibm.wala.cast.ipa.callgraph,
|
||||
com.ibm.wala.cast.ipa.cha,
|
||||
com.ibm.wala.cast.ipa.modref,
|
||||
com.ibm.wala.cast.ir.cfg,
|
||||
com.ibm.wala.cast.ir.ssa,
|
||||
com.ibm.wala.cast.ir.ssa.analysis,
|
||||
com.ibm.wala.cast.ir.translator,
|
||||
com.ibm.wala.cast.loader,
|
||||
com.ibm.wala.cast.plugin,
|
||||
com.ibm.wala.cast.tree,
|
||||
com.ibm.wala.cast.tree.impl,
|
||||
com.ibm.wala.cast.tree.visit,
|
||||
com.ibm.wala.cast.types,
|
||||
com.ibm.wala.cast.util
|
||||
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
||||
|
||||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: WALA CAst core Plug-in
|
||||
Bundle-SymbolicName: com.ibm.wala.cast
|
||||
Bundle-Version: 1.0.0
|
||||
Bundle-Activator: com.ibm.wala.cast.plugin.AstPlugin
|
||||
Bundle-Vendor: IBM
|
||||
Require-Bundle: com.ibm.wala.core,
|
||||
com.ibm.wala.shrike,
|
||||
org.eclipse.core.runtime
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Export-Package: com.ibm.wala.cast.analysis.typeInference,
|
||||
com.ibm.wala.cast.ipa.callgraph,
|
||||
com.ibm.wala.cast.ipa.cha,
|
||||
com.ibm.wala.cast.ipa.modref,
|
||||
com.ibm.wala.cast.ir.cfg,
|
||||
com.ibm.wala.cast.ir.ssa,
|
||||
com.ibm.wala.cast.ir.ssa.analysis,
|
||||
com.ibm.wala.cast.ir.translator,
|
||||
com.ibm.wala.cast.loader,
|
||||
com.ibm.wala.cast.plugin,
|
||||
com.ibm.wala.cast.tree,
|
||||
com.ibm.wala.cast.tree.impl,
|
||||
com.ibm.wala.cast.tree.visit,
|
||||
com.ibm.wala.cast.types,
|
||||
com.ibm.wala.cast.util
|
||||
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
||||
|
||||
|
|
|
@ -1,191 +1,191 @@
|
|||
/******************************************************************************
|
||||
* 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.cast.ipa.callgraph;
|
||||
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import com.ibm.wala.cast.ir.cfg.AstInducedCFG;
|
||||
import com.ibm.wala.cast.ir.ssa.AstLexicalRead;
|
||||
import com.ibm.wala.cfg.InducedCFG;
|
||||
import com.ibm.wala.classLoader.CallSiteReference;
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.Context;
|
||||
import com.ibm.wala.ipa.callgraph.impl.AbstractRootMethod;
|
||||
import com.ibm.wala.ipa.callgraph.impl.Everywhere;
|
||||
import com.ibm.wala.ipa.callgraph.impl.ExplicitCallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.impl.FakeRootMethod;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.ssa.DefUse;
|
||||
import com.ibm.wala.ssa.IR;
|
||||
import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
|
||||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
import com.ibm.wala.types.MethodReference;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.functions.Function;
|
||||
|
||||
public class AstCallGraph extends ExplicitCallGraph {
|
||||
public AstCallGraph(IClassHierarchy cha, AnalysisOptions options, AnalysisCache cache) {
|
||||
super(cha, options, cache);
|
||||
}
|
||||
|
||||
public static class AstFakeRoot extends AbstractRootMethod {
|
||||
|
||||
public AstFakeRoot(MethodReference rootMethod, IClass declaringClass, IClassHierarchy cha, AnalysisOptions options, AnalysisCache cache) {
|
||||
super(rootMethod, declaringClass, cha, options, cache);
|
||||
}
|
||||
|
||||
public AstFakeRoot(MethodReference rootMethod, IClassHierarchy cha, AnalysisOptions options, AnalysisCache cache) {
|
||||
super(rootMethod, cha, options, cache);
|
||||
}
|
||||
|
||||
public InducedCFG makeControlFlowGraph(SSAInstruction[] statements) {
|
||||
return new AstInducedCFG(statements, this, Everywhere.EVERYWHERE);
|
||||
}
|
||||
|
||||
public AstLexicalRead addGlobalRead(TypeReference type, String name) {
|
||||
AstLexicalRead s = new AstLexicalRead(nextLocal++, null, name);
|
||||
statements.add(s);
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
public static abstract class ScriptFakeRoot extends AstFakeRoot {
|
||||
|
||||
public ScriptFakeRoot(MethodReference rootMethod, IClass declaringClass, IClassHierarchy cha, AnalysisOptions options, AnalysisCache cache) {
|
||||
super(rootMethod, declaringClass, cha, options, cache);
|
||||
}
|
||||
|
||||
public ScriptFakeRoot(MethodReference rootMethod, IClassHierarchy cha, AnalysisOptions options, AnalysisCache cache) {
|
||||
super(rootMethod, cha, options, cache);
|
||||
}
|
||||
|
||||
public abstract SSAAbstractInvokeInstruction addDirectCall(int functionVn, int[] argVns, CallSiteReference callSite);
|
||||
|
||||
}
|
||||
|
||||
public class AstCGNode extends ExplicitNode {
|
||||
private Set<Function<Object, Object>> callbacks;
|
||||
|
||||
private boolean lexicalScopingChanges = false;
|
||||
|
||||
private IR cachedIR;
|
||||
|
||||
private DefUse cachedDU;
|
||||
|
||||
private AstCGNode(IMethod method, Context context) {
|
||||
super(method, context);
|
||||
}
|
||||
|
||||
private void fireCallbacks() {
|
||||
if (callbacks != null) {
|
||||
boolean done = false;
|
||||
while (!done) {
|
||||
try {
|
||||
for (Iterator<Function<Object, Object>> x = callbacks.iterator(); x.hasNext();) {
|
||||
x.next().apply(null);
|
||||
}
|
||||
} catch (ConcurrentModificationException e) {
|
||||
done = false;
|
||||
continue;
|
||||
}
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasCallback(Function<Object, Object> callback) {
|
||||
return callbacks != null && callbacks.contains(callback);
|
||||
}
|
||||
|
||||
private boolean hasAllCallbacks(Set<Function<Object, Object>> callbacks) {
|
||||
return callbacks != null && callbacks.containsAll(callbacks);
|
||||
}
|
||||
|
||||
public void addCallback(Function<Object, Object> callback) {
|
||||
if (!hasCallback(callback)) {
|
||||
if (callbacks == null) {
|
||||
callbacks = HashSetFactory.make(1);
|
||||
}
|
||||
|
||||
callbacks.add(callback);
|
||||
|
||||
for (Iterator ps = getCallGraph().getPredNodes(this); ps.hasNext();) {
|
||||
((AstCGNode) ps.next()).addCallback(callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addAllCallbacks(Set<Function<Object, Object>> callback) {
|
||||
if (!hasAllCallbacks(callbacks)) {
|
||||
if (callbacks == null) {
|
||||
callbacks = HashSetFactory.make(1);
|
||||
}
|
||||
|
||||
callbacks.addAll(callbacks);
|
||||
|
||||
for (Iterator ps = getCallGraph().getPredNodes(this); ps.hasNext();) {
|
||||
((AstCGNode) ps.next()).addAllCallbacks(callbacks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setLexicallyMutatedIR(IR ir) {
|
||||
lexicalScopingChanges = true;
|
||||
cachedIR = ir;
|
||||
cachedDU = new DefUse(ir);
|
||||
}
|
||||
|
||||
public IR getLexicallyMutatedIR() {
|
||||
if (lexicalScopingChanges) {
|
||||
return cachedIR;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public DefUse getLexicallyMutatedDU() {
|
||||
if (lexicalScopingChanges) {
|
||||
return cachedDU;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean addTarget(CallSiteReference site, CGNode node) {
|
||||
if (super.addTarget(site, node)) {
|
||||
if (((AstCGNode) node).callbacks != null) {
|
||||
((AstCGNode) node).fireCallbacks();
|
||||
addAllCallbacks(((AstCGNode) node).callbacks);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected ExplicitNode makeNode(IMethod method, Context context) {
|
||||
return new AstCGNode(method, context);
|
||||
}
|
||||
|
||||
protected CGNode makeFakeRootNode() throws CancelException {
|
||||
return findOrCreateNode(new AstFakeRoot(FakeRootMethod.rootMethod, cha, options, getAnalysisCache()), Everywhere.EVERYWHERE);
|
||||
}
|
||||
|
||||
}
|
||||
/******************************************************************************
|
||||
* 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.cast.ipa.callgraph;
|
||||
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import com.ibm.wala.cast.ir.cfg.AstInducedCFG;
|
||||
import com.ibm.wala.cast.ir.ssa.AstLexicalRead;
|
||||
import com.ibm.wala.cfg.InducedCFG;
|
||||
import com.ibm.wala.classLoader.CallSiteReference;
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.Context;
|
||||
import com.ibm.wala.ipa.callgraph.impl.AbstractRootMethod;
|
||||
import com.ibm.wala.ipa.callgraph.impl.Everywhere;
|
||||
import com.ibm.wala.ipa.callgraph.impl.ExplicitCallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.impl.FakeRootMethod;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.ssa.DefUse;
|
||||
import com.ibm.wala.ssa.IR;
|
||||
import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
|
||||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
import com.ibm.wala.types.MethodReference;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.functions.Function;
|
||||
|
||||
public class AstCallGraph extends ExplicitCallGraph {
|
||||
public AstCallGraph(IClassHierarchy cha, AnalysisOptions options, AnalysisCache cache) {
|
||||
super(cha, options, cache);
|
||||
}
|
||||
|
||||
public static class AstFakeRoot extends AbstractRootMethod {
|
||||
|
||||
public AstFakeRoot(MethodReference rootMethod, IClass declaringClass, IClassHierarchy cha, AnalysisOptions options, AnalysisCache cache) {
|
||||
super(rootMethod, declaringClass, cha, options, cache);
|
||||
}
|
||||
|
||||
public AstFakeRoot(MethodReference rootMethod, IClassHierarchy cha, AnalysisOptions options, AnalysisCache cache) {
|
||||
super(rootMethod, cha, options, cache);
|
||||
}
|
||||
|
||||
public InducedCFG makeControlFlowGraph(SSAInstruction[] statements) {
|
||||
return new AstInducedCFG(statements, this, Everywhere.EVERYWHERE);
|
||||
}
|
||||
|
||||
public AstLexicalRead addGlobalRead(TypeReference type, String name) {
|
||||
AstLexicalRead s = new AstLexicalRead(nextLocal++, null, name);
|
||||
statements.add(s);
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
public static abstract class ScriptFakeRoot extends AstFakeRoot {
|
||||
|
||||
public ScriptFakeRoot(MethodReference rootMethod, IClass declaringClass, IClassHierarchy cha, AnalysisOptions options, AnalysisCache cache) {
|
||||
super(rootMethod, declaringClass, cha, options, cache);
|
||||
}
|
||||
|
||||
public ScriptFakeRoot(MethodReference rootMethod, IClassHierarchy cha, AnalysisOptions options, AnalysisCache cache) {
|
||||
super(rootMethod, cha, options, cache);
|
||||
}
|
||||
|
||||
public abstract SSAAbstractInvokeInstruction addDirectCall(int functionVn, int[] argVns, CallSiteReference callSite);
|
||||
|
||||
}
|
||||
|
||||
public class AstCGNode extends ExplicitNode {
|
||||
private Set<Function<Object, Object>> callbacks;
|
||||
|
||||
private boolean lexicalScopingChanges = false;
|
||||
|
||||
private IR cachedIR;
|
||||
|
||||
private DefUse cachedDU;
|
||||
|
||||
private AstCGNode(IMethod method, Context context) {
|
||||
super(method, context);
|
||||
}
|
||||
|
||||
private void fireCallbacks() {
|
||||
if (callbacks != null) {
|
||||
boolean done = false;
|
||||
while (!done) {
|
||||
try {
|
||||
for (Iterator<Function<Object, Object>> x = callbacks.iterator(); x.hasNext();) {
|
||||
x.next().apply(null);
|
||||
}
|
||||
} catch (ConcurrentModificationException e) {
|
||||
done = false;
|
||||
continue;
|
||||
}
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasCallback(Function<Object, Object> callback) {
|
||||
return callbacks != null && callbacks.contains(callback);
|
||||
}
|
||||
|
||||
private boolean hasAllCallbacks(Set<Function<Object, Object>> callbacks) {
|
||||
return callbacks != null && callbacks.containsAll(callbacks);
|
||||
}
|
||||
|
||||
public void addCallback(Function<Object, Object> callback) {
|
||||
if (!hasCallback(callback)) {
|
||||
if (callbacks == null) {
|
||||
callbacks = HashSetFactory.make(1);
|
||||
}
|
||||
|
||||
callbacks.add(callback);
|
||||
|
||||
for (Iterator ps = getCallGraph().getPredNodes(this); ps.hasNext();) {
|
||||
((AstCGNode) ps.next()).addCallback(callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addAllCallbacks(Set<Function<Object, Object>> callback) {
|
||||
if (!hasAllCallbacks(callbacks)) {
|
||||
if (callbacks == null) {
|
||||
callbacks = HashSetFactory.make(1);
|
||||
}
|
||||
|
||||
callbacks.addAll(callbacks);
|
||||
|
||||
for (Iterator ps = getCallGraph().getPredNodes(this); ps.hasNext();) {
|
||||
((AstCGNode) ps.next()).addAllCallbacks(callbacks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setLexicallyMutatedIR(IR ir) {
|
||||
lexicalScopingChanges = true;
|
||||
cachedIR = ir;
|
||||
cachedDU = new DefUse(ir);
|
||||
}
|
||||
|
||||
public IR getLexicallyMutatedIR() {
|
||||
if (lexicalScopingChanges) {
|
||||
return cachedIR;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public DefUse getLexicallyMutatedDU() {
|
||||
if (lexicalScopingChanges) {
|
||||
return cachedDU;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean addTarget(CallSiteReference site, CGNode node) {
|
||||
if (super.addTarget(site, node)) {
|
||||
if (((AstCGNode) node).callbacks != null) {
|
||||
((AstCGNode) node).fireCallbacks();
|
||||
addAllCallbacks(((AstCGNode) node).callbacks);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected ExplicitNode makeNode(IMethod method, Context context) {
|
||||
return new AstCGNode(method, context);
|
||||
}
|
||||
|
||||
protected CGNode makeFakeRootNode() throws CancelException {
|
||||
return findOrCreateNode(new AstFakeRoot(FakeRootMethod.rootMethod, cha, options, getAnalysisCache()), Everywhere.EVERYWHERE);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,168 +1,168 @@
|
|||
/******************************************************************************
|
||||
* 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.cast.ipa.callgraph;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.ibm.wala.cast.ir.ssa.AstLexicalRead;
|
||||
import com.ibm.wala.cast.util.TargetLanguageSelector;
|
||||
import com.ibm.wala.classLoader.CallSiteReference;
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.impl.AbstractRootMethod;
|
||||
import com.ibm.wala.ipa.callgraph.impl.Everywhere;
|
||||
import com.ibm.wala.ipa.callgraph.impl.FakeRootMethod;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.shrikeBT.IInvokeInstruction;
|
||||
import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
|
||||
import com.ibm.wala.ssa.SSAInvokeInstruction;
|
||||
import com.ibm.wala.ssa.SSANewInstruction;
|
||||
import com.ibm.wala.types.FieldReference;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.collections.HashMapFactory;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.strings.Atom;
|
||||
|
||||
/**
|
||||
* A CallGraph implementation adapted to work for graphs that contain code
|
||||
* entities from multiple languages, and hence multiple specialized forms of IR.
|
||||
* The root node delegates to one of several language-specific root nodes,
|
||||
* allowing each language to use its own specialized IR constructs for entry
|
||||
* points.
|
||||
*
|
||||
* @author Julian Dolby (dolby@us.ibm.com)
|
||||
*/
|
||||
public class CrossLanguageCallGraph extends AstCallGraph {
|
||||
|
||||
public CrossLanguageCallGraph(TargetLanguageSelector<AbstractRootMethod, CrossLanguageCallGraph> roots, IClassHierarchy cha,
|
||||
AnalysisOptions options, AnalysisCache cache) {
|
||||
super(cha, options, cache);
|
||||
this.roots = roots;
|
||||
}
|
||||
|
||||
private final TargetLanguageSelector<AbstractRootMethod, CrossLanguageCallGraph> roots;
|
||||
|
||||
private final Set<CGNode> languageRootNodes = HashSetFactory.make();
|
||||
|
||||
private final Map<Atom,IMethod> languageRoots = HashMapFactory.make();
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public AbstractRootMethod getLanguageRoot(Atom language){
|
||||
if (!languageRoots.containsKey(language)) {
|
||||
AbstractRootMethod languageRoot = roots.get(language, this);
|
||||
|
||||
CGNode languageRootNode = null;
|
||||
try {
|
||||
languageRootNode = findOrCreateNode(languageRoot, Everywhere.EVERYWHERE);
|
||||
} catch (CancelException e) {
|
||||
e.printStackTrace();
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
|
||||
languageRootNodes.add(languageRootNode);
|
||||
|
||||
CallSiteReference site = CallSiteReference.make(1, languageRoot.getReference(), IInvokeInstruction.Dispatch.STATIC);
|
||||
|
||||
CGNode fakeRootNode = getFakeRootNode();
|
||||
CrossLanguageFakeRoot fakeRootMethod = (CrossLanguageFakeRoot) fakeRootNode.getMethod();
|
||||
|
||||
site = fakeRootMethod.addInvocationInternal(new int[0], site).getCallSite();
|
||||
|
||||
fakeRootNode.addTarget(site, languageRootNode);
|
||||
|
||||
languageRoots.put(language, languageRoot);
|
||||
}
|
||||
|
||||
return (AbstractRootMethod) languageRoots.get(language);
|
||||
}
|
||||
|
||||
public class CrossLanguageFakeRoot extends ScriptFakeRoot {
|
||||
|
||||
public CrossLanguageFakeRoot(IClass declaringClass, IClassHierarchy cha, AnalysisOptions options, AnalysisCache cache) {
|
||||
super(FakeRootMethod.rootMethod, declaringClass, cha, options, cache);
|
||||
}
|
||||
|
||||
public CrossLanguageFakeRoot(IClassHierarchy cha, AnalysisOptions options, AnalysisCache cache) {
|
||||
super(FakeRootMethod.rootMethod, cha, options, cache);
|
||||
}
|
||||
|
||||
public int addPhi(TypeReference type, int[] values) {
|
||||
Atom language = type.getClassLoader().getLanguage();
|
||||
AbstractRootMethod root = getLanguageRoot(language);
|
||||
return root.addPhi(values);
|
||||
}
|
||||
|
||||
public int addGetInstance(FieldReference ref, int object) {
|
||||
TypeReference type = ref.getDeclaringClass();
|
||||
Atom language = type.getClassLoader().getLanguage();
|
||||
AbstractRootMethod root = getLanguageRoot(language);
|
||||
return root.addGetInstance(ref, object);
|
||||
}
|
||||
|
||||
public int addGetStatic(FieldReference ref) {
|
||||
TypeReference type = ref.getDeclaringClass();
|
||||
Atom language = type.getClassLoader().getLanguage();
|
||||
AbstractRootMethod root = getLanguageRoot(language);
|
||||
return root.addGetStatic(ref);
|
||||
}
|
||||
|
||||
public int addCheckcast(TypeReference type, int rv) {
|
||||
Atom language = type.getClassLoader().getLanguage();
|
||||
AbstractRootMethod root = getLanguageRoot(language);
|
||||
return root.addCheckcast(type, rv);
|
||||
}
|
||||
|
||||
public SSANewInstruction addAllocation(TypeReference type) {
|
||||
Atom language = type.getClassLoader().getLanguage();
|
||||
AbstractRootMethod root = getLanguageRoot(language);
|
||||
return root.addAllocation(type);
|
||||
}
|
||||
|
||||
public SSAInvokeInstruction addInvocation(int[] params, CallSiteReference site) {
|
||||
TypeReference type = site.getDeclaredTarget().getDeclaringClass();
|
||||
Atom language = type.getClassLoader().getLanguage();
|
||||
AbstractRootMethod root = getLanguageRoot(language);
|
||||
return root.addInvocation(params, site);
|
||||
}
|
||||
|
||||
public SSAInvokeInstruction addInvocationInternal(int[] params, CallSiteReference site) {
|
||||
return super.addInvocation(params, site);
|
||||
}
|
||||
|
||||
public AstLexicalRead addGlobalRead(TypeReference type, String name) {
|
||||
Atom language = type.getClassLoader().getLanguage();
|
||||
AbstractRootMethod root = getLanguageRoot(language);
|
||||
return ((AstFakeRoot) root).addGlobalRead(type, name);
|
||||
}
|
||||
|
||||
public SSAAbstractInvokeInstruction addDirectCall(int functionVn, int[] argVns, CallSiteReference callSite) {
|
||||
TypeReference type = callSite.getDeclaredTarget().getDeclaringClass();
|
||||
Atom language = type.getClassLoader().getLanguage();
|
||||
AbstractRootMethod root = getLanguageRoot(language);
|
||||
return ((ScriptFakeRoot) root).addDirectCall(functionVn, argVns, callSite);
|
||||
}
|
||||
}
|
||||
|
||||
Iterator getLanguageRoots() {
|
||||
return languageRootNodes.iterator();
|
||||
}
|
||||
|
||||
protected CGNode makeFakeRootNode() throws CancelException {
|
||||
return findOrCreateNode(new CrossLanguageFakeRoot(cha, options, getAnalysisCache()), Everywhere.EVERYWHERE);
|
||||
}
|
||||
}
|
||||
/******************************************************************************
|
||||
* 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.cast.ipa.callgraph;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.ibm.wala.cast.ir.ssa.AstLexicalRead;
|
||||
import com.ibm.wala.cast.util.TargetLanguageSelector;
|
||||
import com.ibm.wala.classLoader.CallSiteReference;
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.impl.AbstractRootMethod;
|
||||
import com.ibm.wala.ipa.callgraph.impl.Everywhere;
|
||||
import com.ibm.wala.ipa.callgraph.impl.FakeRootMethod;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.shrikeBT.IInvokeInstruction;
|
||||
import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
|
||||
import com.ibm.wala.ssa.SSAInvokeInstruction;
|
||||
import com.ibm.wala.ssa.SSANewInstruction;
|
||||
import com.ibm.wala.types.FieldReference;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.collections.HashMapFactory;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.strings.Atom;
|
||||
|
||||
/**
|
||||
* A CallGraph implementation adapted to work for graphs that contain code
|
||||
* entities from multiple languages, and hence multiple specialized forms of IR.
|
||||
* The root node delegates to one of several language-specific root nodes,
|
||||
* allowing each language to use its own specialized IR constructs for entry
|
||||
* points.
|
||||
*
|
||||
* @author Julian Dolby (dolby@us.ibm.com)
|
||||
*/
|
||||
public class CrossLanguageCallGraph extends AstCallGraph {
|
||||
|
||||
public CrossLanguageCallGraph(TargetLanguageSelector<AbstractRootMethod, CrossLanguageCallGraph> roots, IClassHierarchy cha,
|
||||
AnalysisOptions options, AnalysisCache cache) {
|
||||
super(cha, options, cache);
|
||||
this.roots = roots;
|
||||
}
|
||||
|
||||
private final TargetLanguageSelector<AbstractRootMethod, CrossLanguageCallGraph> roots;
|
||||
|
||||
private final Set<CGNode> languageRootNodes = HashSetFactory.make();
|
||||
|
||||
private final Map<Atom,IMethod> languageRoots = HashMapFactory.make();
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public AbstractRootMethod getLanguageRoot(Atom language){
|
||||
if (!languageRoots.containsKey(language)) {
|
||||
AbstractRootMethod languageRoot = roots.get(language, this);
|
||||
|
||||
CGNode languageRootNode = null;
|
||||
try {
|
||||
languageRootNode = findOrCreateNode(languageRoot, Everywhere.EVERYWHERE);
|
||||
} catch (CancelException e) {
|
||||
e.printStackTrace();
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
|
||||
languageRootNodes.add(languageRootNode);
|
||||
|
||||
CallSiteReference site = CallSiteReference.make(1, languageRoot.getReference(), IInvokeInstruction.Dispatch.STATIC);
|
||||
|
||||
CGNode fakeRootNode = getFakeRootNode();
|
||||
CrossLanguageFakeRoot fakeRootMethod = (CrossLanguageFakeRoot) fakeRootNode.getMethod();
|
||||
|
||||
site = fakeRootMethod.addInvocationInternal(new int[0], site).getCallSite();
|
||||
|
||||
fakeRootNode.addTarget(site, languageRootNode);
|
||||
|
||||
languageRoots.put(language, languageRoot);
|
||||
}
|
||||
|
||||
return (AbstractRootMethod) languageRoots.get(language);
|
||||
}
|
||||
|
||||
public class CrossLanguageFakeRoot extends ScriptFakeRoot {
|
||||
|
||||
public CrossLanguageFakeRoot(IClass declaringClass, IClassHierarchy cha, AnalysisOptions options, AnalysisCache cache) {
|
||||
super(FakeRootMethod.rootMethod, declaringClass, cha, options, cache);
|
||||
}
|
||||
|
||||
public CrossLanguageFakeRoot(IClassHierarchy cha, AnalysisOptions options, AnalysisCache cache) {
|
||||
super(FakeRootMethod.rootMethod, cha, options, cache);
|
||||
}
|
||||
|
||||
public int addPhi(TypeReference type, int[] values) {
|
||||
Atom language = type.getClassLoader().getLanguage();
|
||||
AbstractRootMethod root = getLanguageRoot(language);
|
||||
return root.addPhi(values);
|
||||
}
|
||||
|
||||
public int addGetInstance(FieldReference ref, int object) {
|
||||
TypeReference type = ref.getDeclaringClass();
|
||||
Atom language = type.getClassLoader().getLanguage();
|
||||
AbstractRootMethod root = getLanguageRoot(language);
|
||||
return root.addGetInstance(ref, object);
|
||||
}
|
||||
|
||||
public int addGetStatic(FieldReference ref) {
|
||||
TypeReference type = ref.getDeclaringClass();
|
||||
Atom language = type.getClassLoader().getLanguage();
|
||||
AbstractRootMethod root = getLanguageRoot(language);
|
||||
return root.addGetStatic(ref);
|
||||
}
|
||||
|
||||
public int addCheckcast(TypeReference type, int rv) {
|
||||
Atom language = type.getClassLoader().getLanguage();
|
||||
AbstractRootMethod root = getLanguageRoot(language);
|
||||
return root.addCheckcast(type, rv);
|
||||
}
|
||||
|
||||
public SSANewInstruction addAllocation(TypeReference type) {
|
||||
Atom language = type.getClassLoader().getLanguage();
|
||||
AbstractRootMethod root = getLanguageRoot(language);
|
||||
return root.addAllocation(type);
|
||||
}
|
||||
|
||||
public SSAInvokeInstruction addInvocation(int[] params, CallSiteReference site) {
|
||||
TypeReference type = site.getDeclaredTarget().getDeclaringClass();
|
||||
Atom language = type.getClassLoader().getLanguage();
|
||||
AbstractRootMethod root = getLanguageRoot(language);
|
||||
return root.addInvocation(params, site);
|
||||
}
|
||||
|
||||
public SSAInvokeInstruction addInvocationInternal(int[] params, CallSiteReference site) {
|
||||
return super.addInvocation(params, site);
|
||||
}
|
||||
|
||||
public AstLexicalRead addGlobalRead(TypeReference type, String name) {
|
||||
Atom language = type.getClassLoader().getLanguage();
|
||||
AbstractRootMethod root = getLanguageRoot(language);
|
||||
return ((AstFakeRoot) root).addGlobalRead(type, name);
|
||||
}
|
||||
|
||||
public SSAAbstractInvokeInstruction addDirectCall(int functionVn, int[] argVns, CallSiteReference callSite) {
|
||||
TypeReference type = callSite.getDeclaredTarget().getDeclaringClass();
|
||||
Atom language = type.getClassLoader().getLanguage();
|
||||
AbstractRootMethod root = getLanguageRoot(language);
|
||||
return ((ScriptFakeRoot) root).addDirectCall(functionVn, argVns, callSite);
|
||||
}
|
||||
}
|
||||
|
||||
Iterator getLanguageRoots() {
|
||||
return languageRootNodes.iterator();
|
||||
}
|
||||
|
||||
protected CGNode makeFakeRootNode() throws CancelException {
|
||||
return findOrCreateNode(new CrossLanguageFakeRoot(cha, options, getAnalysisCache()), Everywhere.EVERYWHERE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,317 +1,317 @@
|
|||
/******************************************************************************
|
||||
* 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.cast.ir.ssa.analysis;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.ibm.wala.cfg.ControlFlowGraph;
|
||||
import com.ibm.wala.dataflow.graph.AbstractMeetOperator;
|
||||
import com.ibm.wala.dataflow.graph.BitVectorSolver;
|
||||
import com.ibm.wala.dataflow.graph.BitVectorUnion;
|
||||
import com.ibm.wala.dataflow.graph.IKilldallFramework;
|
||||
import com.ibm.wala.dataflow.graph.ITransferFunctionProvider;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.eclipse.util.CancelRuntimeException;
|
||||
import com.ibm.wala.fixedpoint.impl.UnaryOperator;
|
||||
import com.ibm.wala.fixpoint.BitVectorVariable;
|
||||
import com.ibm.wala.ssa.IR;
|
||||
import com.ibm.wala.ssa.ISSABasicBlock;
|
||||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
import com.ibm.wala.ssa.SSAPhiInstruction;
|
||||
import com.ibm.wala.ssa.SymbolTable;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.graph.Graph;
|
||||
import com.ibm.wala.util.graph.impl.GraphInverter;
|
||||
import com.ibm.wala.util.intset.BitVector;
|
||||
import com.ibm.wala.util.intset.BitVectorIntSet;
|
||||
import com.ibm.wala.util.intset.IntSet;
|
||||
|
||||
/**
|
||||
* @author Julian Dolby
|
||||
*
|
||||
* Live-value analysis for a method's IR (or {@link ControlFlowGraph} and {@link SymbolTable}) using a {@link IKilldallFramework}
|
||||
* based implementation.
|
||||
*
|
||||
* Pre-requisites
|
||||
* - Knowledge of SSA form: control flow graphs, basic blocks, Phi instructions
|
||||
* - Knowledge of data flow analysis theory: see http://en.wikipedia.org/wiki/Data_flow_analysis
|
||||
*
|
||||
* Implementation notes:
|
||||
*
|
||||
* - The solver uses node transfer functions only.
|
||||
* - Performance: inverts the CFG to traverse backwards (backward analysis).
|
||||
*/
|
||||
public class LiveAnalysis {
|
||||
|
||||
public interface Result {
|
||||
boolean isLiveEntry(ISSABasicBlock bb, int valueNumber);
|
||||
|
||||
boolean isLiveExit(ISSABasicBlock bb, int valueNumber);
|
||||
|
||||
BitVector getLiveBefore(int instr);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static Result perform(IR ir) {
|
||||
return perform(ir.getControlFlowGraph(), ir.getSymbolTable());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static Result perform(final ControlFlowGraph<SSAInstruction, ISSABasicBlock> cfg, final SymbolTable symtab) {
|
||||
return perform(cfg, symtab, new BitVector());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param considerLiveAtExit given set (of variables) to consider to be live after the exit.
|
||||
*
|
||||
* todo: used once in {@link com.ibm.wala.cast.ir.ssa.SSAConversion}; Explain better the purpose.
|
||||
*/
|
||||
public static Result perform(final ControlFlowGraph<SSAInstruction, ISSABasicBlock> cfg, final SymbolTable symtab, final BitVector considerLiveAtExit) {
|
||||
final BitVectorIntSet liveAtExit = new BitVectorIntSet(considerLiveAtExit);
|
||||
final SSAInstruction[] instructions = (SSAInstruction[]) cfg.getInstructions();
|
||||
|
||||
/**
|
||||
* Gen/kill operator specific to exit basic blocks
|
||||
*/
|
||||
final class ExitBlockGenKillOperator extends UnaryOperator<BitVectorVariable> {
|
||||
public String toString() {
|
||||
return "ExitGenKill";
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return o == this;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return 37721;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate the transfer between two nodes in the flow graph within an exit block.
|
||||
*/
|
||||
public byte evaluate(BitVectorVariable lhs, BitVectorVariable rhs) {
|
||||
boolean changed = lhs.getValue() == null ? !considerLiveAtExit.isZero() : !lhs.getValue().sameValue(liveAtExit);
|
||||
|
||||
lhs.addAll(considerLiveAtExit);
|
||||
|
||||
return changed ? CHANGED : NOT_CHANGED;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gen/kill operator for a regular basic block.
|
||||
*/
|
||||
final class BlockValueGenKillOperator extends UnaryOperator<BitVectorVariable> {
|
||||
private final ISSABasicBlock block;
|
||||
|
||||
BlockValueGenKillOperator(ISSABasicBlock block) {
|
||||
this.block = block;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "GenKill:" + block;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return (o instanceof BlockValueGenKillOperator) && ((BlockValueGenKillOperator) o).block.equals(block);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return block.hashCode() * 17;
|
||||
}
|
||||
|
||||
/**
|
||||
* Kills the definitions (variables written to).
|
||||
*/
|
||||
private void processDefs(SSAInstruction inst, BitVector bits) {
|
||||
for (int j = 0; j < inst.getNumberOfDefs(); j++) {
|
||||
bits.clear(inst.getDef(j));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates variables that are read (skips constants).
|
||||
*/
|
||||
private void processUses(SSAInstruction inst, BitVector bits) {
|
||||
for (int j = 0; j < inst.getNumberOfUses(); j++) {
|
||||
assert inst.getUse(j) != -1 : inst.toString();
|
||||
if (!symtab.isConstant(inst.getUse(j))) {
|
||||
bits.set(inst.getUse(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate the transfer between two nodes in the flow graph within one basic block.
|
||||
*/
|
||||
public byte evaluate(BitVectorVariable lhs, BitVectorVariable rhs) {
|
||||
// Calculate here the result of the transfer
|
||||
BitVectorIntSet bits = new BitVectorIntSet();
|
||||
|
||||
IntSet s = rhs.getValue();
|
||||
if (s != null) {
|
||||
bits.addAll(s);
|
||||
}
|
||||
// Include all uses generated by the current basic block into the successor's Phi instructions todo: rephrase
|
||||
for (Iterator<? extends ISSABasicBlock> succBBs = cfg.getSuccNodes(block); succBBs.hasNext();) {
|
||||
ISSABasicBlock succBB = succBBs.next();
|
||||
|
||||
int rval = com.ibm.wala.cast.ir.cfg.Util.whichPred(cfg, succBB, block);
|
||||
for (Iterator<SSAPhiInstruction> sphis = succBB.iteratePhis(); sphis.hasNext();) {
|
||||
bits.add(sphis.next().getUse(rval));
|
||||
}
|
||||
}
|
||||
// For all instructions, in reverse order, 'kill' variables written to and 'gen' variables read.
|
||||
for (int i = block.getLastInstructionIndex(); i >= block.getFirstInstructionIndex(); i--) {
|
||||
SSAInstruction inst = instructions[i];
|
||||
if (inst != null) {
|
||||
processDefs(inst, bits.getBitVector());
|
||||
processUses(inst, bits.getBitVector());
|
||||
}
|
||||
}
|
||||
// 'kill' the variables defined by the Phi instructions in the current block.
|
||||
for (Iterator<? extends SSAInstruction> SS = block.iteratePhis(); SS.hasNext();) {
|
||||
processDefs(SS.next(), bits.getBitVector());
|
||||
}
|
||||
|
||||
BitVectorVariable U = new BitVectorVariable();
|
||||
U.addAll(bits.getBitVector());
|
||||
|
||||
if (!lhs.sameValue(U)) {
|
||||
lhs.copyState(U);
|
||||
return CHANGED;
|
||||
} else {
|
||||
return NOT_CHANGED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the solver
|
||||
*/
|
||||
final BitVectorSolver<ISSABasicBlock> S = new BitVectorSolver<ISSABasicBlock>(new IKilldallFramework<ISSABasicBlock, BitVectorVariable>() {
|
||||
private final Graph<ISSABasicBlock> G = GraphInverter.invert(cfg);
|
||||
|
||||
public Graph<ISSABasicBlock> getFlowGraph() {
|
||||
return G;
|
||||
}
|
||||
|
||||
public ITransferFunctionProvider<ISSABasicBlock, BitVectorVariable> getTransferFunctionProvider() {
|
||||
return new ITransferFunctionProvider<ISSABasicBlock, BitVectorVariable>() {
|
||||
|
||||
public boolean hasNodeTransferFunctions() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean hasEdgeTransferFunctions() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the specialized operator for regular and exit basic blocks.
|
||||
*/
|
||||
public UnaryOperator<BitVectorVariable> getNodeTransferFunction(ISSABasicBlock node) {
|
||||
if (node.isExitBlock()) {
|
||||
return new ExitBlockGenKillOperator();
|
||||
} else {
|
||||
return new BlockValueGenKillOperator(node);
|
||||
}
|
||||
}
|
||||
|
||||
public UnaryOperator<BitVectorVariable> getEdgeTransferFunction(ISSABasicBlock s, ISSABasicBlock d) {
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Live analysis uses 'union' as 'meet operator'
|
||||
*/
|
||||
public AbstractMeetOperator<BitVectorVariable> getMeetOperator() {
|
||||
return BitVectorUnion.instance();
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Solve the analysis problem
|
||||
*/
|
||||
try {
|
||||
S.solve(null);
|
||||
} catch (CancelException e) {
|
||||
throw new CancelRuntimeException(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the lazy result with a closure.
|
||||
*/
|
||||
return new Result() {
|
||||
|
||||
public String toString() {
|
||||
StringBuffer s = new StringBuffer();
|
||||
for (int i = 0; i < cfg.getNumberOfNodes(); i++) {
|
||||
ISSABasicBlock bb = cfg.getNode(i);
|
||||
s.append("live entering ").append(bb).append(":").append(S.getOut(bb)).append("\n");
|
||||
s.append("live exiting ").append(bb).append(":").append(S.getIn(bb)).append("\n");
|
||||
}
|
||||
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
public boolean isLiveEntry(ISSABasicBlock bb, int valueNumber) {
|
||||
return S.getOut(bb).get(valueNumber);
|
||||
}
|
||||
|
||||
public boolean isLiveExit(ISSABasicBlock bb, int valueNumber) {
|
||||
return S.getIn(bb).get(valueNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate set of variables live before instruction
|
||||
* @param instr
|
||||
*
|
||||
* @see <a href="http://en.wikipedia.org/wiki/Data_flow_analysis#Backward_Analysis">
|
||||
* how the 'in' and 'out' variable sets work</a>
|
||||
*/
|
||||
public BitVector getLiveBefore(int instr) {
|
||||
ISSABasicBlock bb = cfg.getBlockForInstruction(instr);
|
||||
|
||||
// Start with the variables live at the 'in' of the basic block of the instruction. todo???
|
||||
BitVectorIntSet bits = new BitVectorIntSet();
|
||||
IntSet s = S.getIn(bb).getValue();
|
||||
if (s != null) {
|
||||
bits.addAll(s);
|
||||
}
|
||||
// For all instructions in the basic block, going backwards, from the last,
|
||||
// up to the desired instruction, 'kill' written variables and 'gen' read variables.
|
||||
for (int i = bb.getLastInstructionIndex(); i >= instr; i--) {
|
||||
SSAInstruction inst = instructions[i];
|
||||
if (inst != null) {
|
||||
for (int j = 0; j < inst.getNumberOfDefs(); j++) {
|
||||
bits.remove(inst.getDef(j));
|
||||
}
|
||||
for (int j = 0; j < inst.getNumberOfUses(); j++) {
|
||||
if (!symtab.isConstant(inst.getUse(j))) {
|
||||
bits.add(inst.getUse(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bits.getBitVector();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
/******************************************************************************
|
||||
* 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.cast.ir.ssa.analysis;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.ibm.wala.cfg.ControlFlowGraph;
|
||||
import com.ibm.wala.dataflow.graph.AbstractMeetOperator;
|
||||
import com.ibm.wala.dataflow.graph.BitVectorSolver;
|
||||
import com.ibm.wala.dataflow.graph.BitVectorUnion;
|
||||
import com.ibm.wala.dataflow.graph.IKilldallFramework;
|
||||
import com.ibm.wala.dataflow.graph.ITransferFunctionProvider;
|
||||
import com.ibm.wala.fixedpoint.impl.UnaryOperator;
|
||||
import com.ibm.wala.fixpoint.BitVectorVariable;
|
||||
import com.ibm.wala.ssa.IR;
|
||||
import com.ibm.wala.ssa.ISSABasicBlock;
|
||||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
import com.ibm.wala.ssa.SSAPhiInstruction;
|
||||
import com.ibm.wala.ssa.SymbolTable;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.CancelRuntimeException;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.graph.Graph;
|
||||
import com.ibm.wala.util.graph.impl.GraphInverter;
|
||||
import com.ibm.wala.util.intset.BitVector;
|
||||
import com.ibm.wala.util.intset.BitVectorIntSet;
|
||||
import com.ibm.wala.util.intset.IntSet;
|
||||
|
||||
/**
|
||||
* @author Julian Dolby
|
||||
*
|
||||
* Live-value analysis for a method's IR (or {@link ControlFlowGraph} and {@link SymbolTable}) using a {@link IKilldallFramework}
|
||||
* based implementation.
|
||||
*
|
||||
* Pre-requisites
|
||||
* - Knowledge of SSA form: control flow graphs, basic blocks, Phi instructions
|
||||
* - Knowledge of data flow analysis theory: see http://en.wikipedia.org/wiki/Data_flow_analysis
|
||||
*
|
||||
* Implementation notes:
|
||||
*
|
||||
* - The solver uses node transfer functions only.
|
||||
* - Performance: inverts the CFG to traverse backwards (backward analysis).
|
||||
*/
|
||||
public class LiveAnalysis {
|
||||
|
||||
public interface Result {
|
||||
boolean isLiveEntry(ISSABasicBlock bb, int valueNumber);
|
||||
|
||||
boolean isLiveExit(ISSABasicBlock bb, int valueNumber);
|
||||
|
||||
BitVector getLiveBefore(int instr);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static Result perform(IR ir) {
|
||||
return perform(ir.getControlFlowGraph(), ir.getSymbolTable());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static Result perform(final ControlFlowGraph<SSAInstruction, ISSABasicBlock> cfg, final SymbolTable symtab) {
|
||||
return perform(cfg, symtab, new BitVector());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param considerLiveAtExit given set (of variables) to consider to be live after the exit.
|
||||
*
|
||||
* todo: used once in {@link com.ibm.wala.cast.ir.ssa.SSAConversion}; Explain better the purpose.
|
||||
*/
|
||||
public static Result perform(final ControlFlowGraph<SSAInstruction, ISSABasicBlock> cfg, final SymbolTable symtab, final BitVector considerLiveAtExit) {
|
||||
final BitVectorIntSet liveAtExit = new BitVectorIntSet(considerLiveAtExit);
|
||||
final SSAInstruction[] instructions = (SSAInstruction[]) cfg.getInstructions();
|
||||
|
||||
/**
|
||||
* Gen/kill operator specific to exit basic blocks
|
||||
*/
|
||||
final class ExitBlockGenKillOperator extends UnaryOperator<BitVectorVariable> {
|
||||
public String toString() {
|
||||
return "ExitGenKill";
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return o == this;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return 37721;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate the transfer between two nodes in the flow graph within an exit block.
|
||||
*/
|
||||
public byte evaluate(BitVectorVariable lhs, BitVectorVariable rhs) {
|
||||
boolean changed = lhs.getValue() == null ? !considerLiveAtExit.isZero() : !lhs.getValue().sameValue(liveAtExit);
|
||||
|
||||
lhs.addAll(considerLiveAtExit);
|
||||
|
||||
return changed ? CHANGED : NOT_CHANGED;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gen/kill operator for a regular basic block.
|
||||
*/
|
||||
final class BlockValueGenKillOperator extends UnaryOperator<BitVectorVariable> {
|
||||
private final ISSABasicBlock block;
|
||||
|
||||
BlockValueGenKillOperator(ISSABasicBlock block) {
|
||||
this.block = block;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "GenKill:" + block;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return (o instanceof BlockValueGenKillOperator) && ((BlockValueGenKillOperator) o).block.equals(block);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return block.hashCode() * 17;
|
||||
}
|
||||
|
||||
/**
|
||||
* Kills the definitions (variables written to).
|
||||
*/
|
||||
private void processDefs(SSAInstruction inst, BitVector bits) {
|
||||
for (int j = 0; j < inst.getNumberOfDefs(); j++) {
|
||||
bits.clear(inst.getDef(j));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates variables that are read (skips constants).
|
||||
*/
|
||||
private void processUses(SSAInstruction inst, BitVector bits) {
|
||||
for (int j = 0; j < inst.getNumberOfUses(); j++) {
|
||||
assert inst.getUse(j) != -1 : inst.toString();
|
||||
if (!symtab.isConstant(inst.getUse(j))) {
|
||||
bits.set(inst.getUse(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate the transfer between two nodes in the flow graph within one basic block.
|
||||
*/
|
||||
public byte evaluate(BitVectorVariable lhs, BitVectorVariable rhs) {
|
||||
// Calculate here the result of the transfer
|
||||
BitVectorIntSet bits = new BitVectorIntSet();
|
||||
|
||||
IntSet s = rhs.getValue();
|
||||
if (s != null) {
|
||||
bits.addAll(s);
|
||||
}
|
||||
// Include all uses generated by the current basic block into the successor's Phi instructions todo: rephrase
|
||||
for (Iterator<? extends ISSABasicBlock> succBBs = cfg.getSuccNodes(block); succBBs.hasNext();) {
|
||||
ISSABasicBlock succBB = succBBs.next();
|
||||
|
||||
int rval = com.ibm.wala.cast.ir.cfg.Util.whichPred(cfg, succBB, block);
|
||||
for (Iterator<SSAPhiInstruction> sphis = succBB.iteratePhis(); sphis.hasNext();) {
|
||||
bits.add(sphis.next().getUse(rval));
|
||||
}
|
||||
}
|
||||
// For all instructions, in reverse order, 'kill' variables written to and 'gen' variables read.
|
||||
for (int i = block.getLastInstructionIndex(); i >= block.getFirstInstructionIndex(); i--) {
|
||||
SSAInstruction inst = instructions[i];
|
||||
if (inst != null) {
|
||||
processDefs(inst, bits.getBitVector());
|
||||
processUses(inst, bits.getBitVector());
|
||||
}
|
||||
}
|
||||
// 'kill' the variables defined by the Phi instructions in the current block.
|
||||
for (Iterator<? extends SSAInstruction> SS = block.iteratePhis(); SS.hasNext();) {
|
||||
processDefs(SS.next(), bits.getBitVector());
|
||||
}
|
||||
|
||||
BitVectorVariable U = new BitVectorVariable();
|
||||
U.addAll(bits.getBitVector());
|
||||
|
||||
if (!lhs.sameValue(U)) {
|
||||
lhs.copyState(U);
|
||||
return CHANGED;
|
||||
} else {
|
||||
return NOT_CHANGED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the solver
|
||||
*/
|
||||
final BitVectorSolver<ISSABasicBlock> S = new BitVectorSolver<ISSABasicBlock>(new IKilldallFramework<ISSABasicBlock, BitVectorVariable>() {
|
||||
private final Graph<ISSABasicBlock> G = GraphInverter.invert(cfg);
|
||||
|
||||
public Graph<ISSABasicBlock> getFlowGraph() {
|
||||
return G;
|
||||
}
|
||||
|
||||
public ITransferFunctionProvider<ISSABasicBlock, BitVectorVariable> getTransferFunctionProvider() {
|
||||
return new ITransferFunctionProvider<ISSABasicBlock, BitVectorVariable>() {
|
||||
|
||||
public boolean hasNodeTransferFunctions() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean hasEdgeTransferFunctions() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the specialized operator for regular and exit basic blocks.
|
||||
*/
|
||||
public UnaryOperator<BitVectorVariable> getNodeTransferFunction(ISSABasicBlock node) {
|
||||
if (node.isExitBlock()) {
|
||||
return new ExitBlockGenKillOperator();
|
||||
} else {
|
||||
return new BlockValueGenKillOperator(node);
|
||||
}
|
||||
}
|
||||
|
||||
public UnaryOperator<BitVectorVariable> getEdgeTransferFunction(ISSABasicBlock s, ISSABasicBlock d) {
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Live analysis uses 'union' as 'meet operator'
|
||||
*/
|
||||
public AbstractMeetOperator<BitVectorVariable> getMeetOperator() {
|
||||
return BitVectorUnion.instance();
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Solve the analysis problem
|
||||
*/
|
||||
try {
|
||||
S.solve(null);
|
||||
} catch (CancelException e) {
|
||||
throw new CancelRuntimeException(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the lazy result with a closure.
|
||||
*/
|
||||
return new Result() {
|
||||
|
||||
public String toString() {
|
||||
StringBuffer s = new StringBuffer();
|
||||
for (int i = 0; i < cfg.getNumberOfNodes(); i++) {
|
||||
ISSABasicBlock bb = cfg.getNode(i);
|
||||
s.append("live entering ").append(bb).append(":").append(S.getOut(bb)).append("\n");
|
||||
s.append("live exiting ").append(bb).append(":").append(S.getIn(bb)).append("\n");
|
||||
}
|
||||
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
public boolean isLiveEntry(ISSABasicBlock bb, int valueNumber) {
|
||||
return S.getOut(bb).get(valueNumber);
|
||||
}
|
||||
|
||||
public boolean isLiveExit(ISSABasicBlock bb, int valueNumber) {
|
||||
return S.getIn(bb).get(valueNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate set of variables live before instruction
|
||||
* @param instr
|
||||
*
|
||||
* @see <a href="http://en.wikipedia.org/wiki/Data_flow_analysis#Backward_Analysis">
|
||||
* how the 'in' and 'out' variable sets work</a>
|
||||
*/
|
||||
public BitVector getLiveBefore(int instr) {
|
||||
ISSABasicBlock bb = cfg.getBlockForInstruction(instr);
|
||||
|
||||
// Start with the variables live at the 'in' of the basic block of the instruction. todo???
|
||||
BitVectorIntSet bits = new BitVectorIntSet();
|
||||
IntSet s = S.getIn(bb).getValue();
|
||||
if (s != null) {
|
||||
bits.addAll(s);
|
||||
}
|
||||
// For all instructions in the basic block, going backwards, from the last,
|
||||
// up to the desired instruction, 'kill' written variables and 'gen' read variables.
|
||||
for (int i = bb.getLastInstructionIndex(); i >= instr; i--) {
|
||||
SSAInstruction inst = instructions[i];
|
||||
if (inst != null) {
|
||||
for (int j = 0; j < inst.getNumberOfDefs(); j++) {
|
||||
bits.remove(inst.getDef(j));
|
||||
}
|
||||
for (int j = 0; j < inst.getNumberOfUses(); j++) {
|
||||
if (!symtab.isConstant(inst.getUse(j))) {
|
||||
bits.add(inst.getUse(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bits.getBitVector();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,47 +1,36 @@
|
|||
/******************************************************************************
|
||||
* 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.cast.ir.translator;
|
||||
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
|
||||
import com.ibm.wala.cast.tree.CAst;
|
||||
|
||||
public class NativeBridge {
|
||||
|
||||
protected final CAst Ast;
|
||||
|
||||
protected static boolean isInitialized;
|
||||
|
||||
protected NativeBridge(CAst Ast) {
|
||||
this.Ast = Ast;
|
||||
}
|
||||
|
||||
protected static native void initialize();
|
||||
|
||||
private static boolean amRunningInEclipse() {
|
||||
try {
|
||||
return ResourcesPlugin.getWorkspace() != null;
|
||||
} catch (IllegalStateException e) {
|
||||
return false;
|
||||
} catch (Error e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
isInitialized = false;
|
||||
if (amRunningInEclipse()) {
|
||||
System.loadLibrary("cast");
|
||||
initialize();
|
||||
isInitialized = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
/******************************************************************************
|
||||
* 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.cast.ir.translator;
|
||||
|
||||
import com.ibm.wala.cast.tree.CAst;
|
||||
import com.ibm.wala.core.plugin.CorePlugin;
|
||||
|
||||
public class NativeBridge {
|
||||
|
||||
protected final CAst Ast;
|
||||
|
||||
protected static boolean isInitialized;
|
||||
|
||||
protected NativeBridge(CAst Ast) {
|
||||
this.Ast = Ast;
|
||||
}
|
||||
|
||||
protected static native void initialize();
|
||||
|
||||
static {
|
||||
isInitialized = false;
|
||||
if (CorePlugin.IS_RESOURCES_BUNDLE_AVAILABLE) {
|
||||
System.loadLibrary("cast");
|
||||
initialize();
|
||||
isInitialized = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,8 +5,9 @@ Bundle-SymbolicName: com.ibm.wala.core.tests;singleton:=true
|
|||
Bundle-Version: 1.1.3.qualifier
|
||||
Bundle-Vendor: %providerName
|
||||
Require-Bundle: org.junit,
|
||||
org.eclipse.ui.ide,
|
||||
com.ibm.wala.core;bundle-version="1.1.3"
|
||||
com.ibm.wala.shrike,
|
||||
com.ibm.wala.core,
|
||||
org.eclipse.core.runtime
|
||||
Bundle-Localization: plugin
|
||||
Export-Package: com.ibm.wala.core.tests.basic,
|
||||
com.ibm.wala.core.tests.callGraph,
|
||||
|
@ -17,7 +18,6 @@ Export-Package: com.ibm.wala.core.tests.basic,
|
|||
com.ibm.wala.core.tests.slicer,
|
||||
com.ibm.wala.core.tests.util,
|
||||
com.ibm.wala.demandpa.driver,
|
||||
com.ibm.wala.eclipse.headless,
|
||||
com.ibm.wala.examples.drivers,
|
||||
com.ibm.wala.examples.properties
|
||||
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/SWTTypeHierarchy.java"/>
|
||||
<listEntry value="/com.ibm.wala.core.tests"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="1"/>
|
||||
<listEntry value="4"/>
|
||||
</listAttribute>
|
||||
<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.ibm.wala.examples.drivers.SWTTypeHierarchy"/>
|
||||
|
|
|
@ -19,9 +19,9 @@ import com.ibm.wala.dataflow.graph.BitVectorSolver;
|
|||
import com.ibm.wala.dataflow.graph.BitVectorUnion;
|
||||
import com.ibm.wala.dataflow.graph.BitVectorUnionConstant;
|
||||
import com.ibm.wala.dataflow.graph.ITransferFunctionProvider;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.fixedpoint.impl.UnaryOperator;
|
||||
import com.ibm.wala.fixpoint.BitVectorVariable;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.graph.Graph;
|
||||
import com.ibm.wala.util.graph.impl.SlowSparseNumberedGraph;
|
||||
|
|
|
@ -19,7 +19,6 @@ import com.ibm.wala.classLoader.IClass;
|
|||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.core.tests.util.TestConstants;
|
||||
import com.ibm.wala.core.tests.util.WalaTestCase;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
|
@ -36,6 +35,7 @@ import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
|||
import com.ibm.wala.ssa.ISSABasicBlock;
|
||||
import com.ibm.wala.types.Descriptor;
|
||||
import com.ibm.wala.types.MethodReference;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.graph.Graph;
|
||||
|
|
|
@ -12,7 +12,6 @@ package com.ibm.wala.core.tests.callGraph;
|
|||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
|
@ -21,6 +20,7 @@ import com.ibm.wala.ipa.callgraph.CallGraphBuilder;
|
|||
import com.ibm.wala.ipa.callgraph.Entrypoint;
|
||||
import com.ibm.wala.ipa.callgraph.impl.Util;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.config.AnalysisScopeReader;
|
||||
import com.ibm.wala.util.io.FileProvider;
|
||||
import com.ibm.wala.util.perf.StopwatchGC;
|
||||
|
|
|
@ -17,7 +17,6 @@ import junit.framework.Assert;
|
|||
|
||||
import com.ibm.wala.core.tests.util.TestConstants;
|
||||
import com.ibm.wala.core.tests.util.WalaTestCase;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
|
@ -30,6 +29,7 @@ import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
|||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
import com.ibm.wala.types.MethodReference;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
|
||||
/**
|
||||
* Check handling of class constants (test for part of 1.5 support)
|
||||
|
|
|
@ -17,7 +17,6 @@ import java.util.Set;
|
|||
import com.ibm.wala.classLoader.CallSiteReference;
|
||||
import com.ibm.wala.core.tests.util.TestConstants;
|
||||
import com.ibm.wala.core.tests.util.WalaTestCase;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
|
@ -30,6 +29,7 @@ import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
|||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
import com.ibm.wala.types.MethodReference;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
|
||||
/**
|
||||
* Check properties of a call to clone() in RTA
|
||||
|
|
|
@ -13,8 +13,8 @@ package com.ibm.wala.core.tests.callGraph;
|
|||
import java.io.IOException;
|
||||
|
||||
import com.ibm.wala.core.tests.util.WalaTestCase;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.intset.BimodalMutableIntSetFactory;
|
||||
import com.ibm.wala.util.intset.BitVectorIntSetFactory;
|
||||
import com.ibm.wala.util.intset.DebuggingMutableIntSetFactory;
|
||||
|
|
|
@ -17,7 +17,6 @@ import java.util.Set;
|
|||
import com.ibm.wala.classLoader.CallSiteReference;
|
||||
import com.ibm.wala.core.tests.util.TestConstants;
|
||||
import com.ibm.wala.core.tests.util.WalaTestCase;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
|
@ -34,6 +33,7 @@ import com.ibm.wala.types.MemberReference;
|
|||
import com.ibm.wala.types.MethodReference;
|
||||
import com.ibm.wala.types.TypeName;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.strings.Atom;
|
||||
|
||||
|
|
|
@ -15,13 +15,10 @@ import java.util.Collection;
|
|||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.core.JavaModelException;
|
||||
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.core.tests.util.TestConstants;
|
||||
import com.ibm.wala.core.tests.util.WalaTestCase;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
|
@ -36,6 +33,7 @@ import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
|||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
import com.ibm.wala.types.MethodReference;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.warnings.WalaException;
|
||||
import com.ibm.wala.util.warnings.Warning;
|
||||
|
@ -210,8 +208,7 @@ public class ReflectionTest extends WalaTestCase {
|
|||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testReflect7() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException,
|
||||
JavaModelException {
|
||||
public void testReflect7() throws Exception {
|
||||
AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA, "Java60RegressionExclusions.txt");
|
||||
ClassHierarchy cha = ClassHierarchy.make(scope);
|
||||
Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha,
|
||||
|
|
|
@ -16,7 +16,6 @@ import java.util.Collections;
|
|||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.core.tests.util.TestConstants;
|
||||
import com.ibm.wala.core.tests.util.WalaTestCase;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
|
@ -30,6 +29,7 @@ import com.ibm.wala.ssa.IR;
|
|||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
import com.ibm.wala.types.MethodReference;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
|
||||
/**
|
||||
* Tests for synthetic methods
|
||||
|
|
|
@ -52,7 +52,6 @@ import com.ibm.wala.demandpa.alg.statemachine.StateMachineFactory;
|
|||
import com.ibm.wala.demandpa.flowgraph.IFlowLabel;
|
||||
import com.ibm.wala.demandpa.util.MemoryAccessMap;
|
||||
import com.ibm.wala.demandpa.util.PABasedMemoryAccessMap;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
|
@ -71,6 +70,7 @@ import com.ibm.wala.ssa.IR;
|
|||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
import com.ibm.wala.ssa.SSAInvokeInstruction;
|
||||
import com.ibm.wala.types.Descriptor;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.intset.IntSet;
|
||||
import com.ibm.wala.util.strings.Atom;
|
||||
|
|
|
@ -48,12 +48,12 @@ import com.ibm.wala.demandpa.alg.refinepolicy.AlwaysRefineFieldsPolicy;
|
|||
import com.ibm.wala.demandpa.alg.refinepolicy.SinglePassRefinementPolicy;
|
||||
import com.ibm.wala.demandpa.alg.statemachine.StateMachineFactory;
|
||||
import com.ibm.wala.demandpa.flowgraph.IFlowLabel;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||
import com.ibm.wala.types.Descriptor;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.strings.Atom;
|
||||
|
||||
public class ContextSensitiveTest extends AbstractPtrTest {
|
||||
|
|
|
@ -42,8 +42,8 @@ import java.io.IOException;
|
|||
import com.ibm.wala.demandpa.alg.IntraProcFilter;
|
||||
import com.ibm.wala.demandpa.alg.statemachine.StateMachineFactory;
|
||||
import com.ibm.wala.demandpa.flowgraph.IFlowLabel;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
|
||||
public class IntraprocTest extends AbstractPtrTest {
|
||||
|
||||
|
|
|
@ -39,8 +39,8 @@ package com.ibm.wala.core.tests.demandpa;
|
|||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
|
||||
public class NoRefinePtrTest extends AbstractPtrTest {
|
||||
|
||||
|
|
|
@ -43,8 +43,8 @@ import com.ibm.wala.demandpa.alg.DemandRefinementPointsTo;
|
|||
import com.ibm.wala.demandpa.alg.refinepolicy.AlwaysRefineCGPolicy;
|
||||
import com.ibm.wala.demandpa.alg.refinepolicy.AlwaysRefineFieldsPolicy;
|
||||
import com.ibm.wala.demandpa.alg.refinepolicy.SinglePassRefinementPolicy;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
|
||||
public class OnTheFlyPtrTest extends AbstractPtrTest {
|
||||
|
||||
|
|
|
@ -43,8 +43,8 @@ import com.ibm.wala.demandpa.alg.DemandRefinementPointsTo;
|
|||
import com.ibm.wala.demandpa.alg.refinepolicy.AlwaysRefineFieldsPolicy;
|
||||
import com.ibm.wala.demandpa.alg.refinepolicy.NeverRefineCGPolicy;
|
||||
import com.ibm.wala.demandpa.alg.refinepolicy.SinglePassRefinementPolicy;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
|
||||
public class RefineFieldsPtrTest extends AbstractPtrTest {
|
||||
|
||||
|
|
|
@ -1,130 +1,130 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 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.core.tests.demandpa;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
|
||||
import com.ibm.wala.demandpa.alg.ContextSensitiveStateMachine;
|
||||
import com.ibm.wala.demandpa.alg.DemandRefinementPointsTo;
|
||||
import com.ibm.wala.demandpa.alg.IDemandPointerAnalysis;
|
||||
import com.ibm.wala.demandpa.alg.refinepolicy.TunedRefinementPolicy;
|
||||
import com.ibm.wala.demandpa.alg.statemachine.StateMachineFactory;
|
||||
import com.ibm.wala.demandpa.flowgraph.IFlowLabel;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||
import com.ibm.wala.types.Descriptor;
|
||||
import com.ibm.wala.util.strings.Atom;
|
||||
|
||||
public class TunedRefinementTest extends AbstractPtrTest {
|
||||
|
||||
public void testArraySet() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
||||
doPointsToSizeTest(TestInfo.SCOPE_FILE, TestInfo.TEST_ARRAY_SET, 1);
|
||||
}
|
||||
|
||||
public void testClone() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
||||
doPointsToSizeTest(TestInfo.SCOPE_FILE, TestInfo.TEST_CLONE, 1);
|
||||
}
|
||||
|
||||
public void testFooId() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
||||
doPointsToSizeTest(TestInfo.SCOPE_FILE, TestInfo.TEST_ID, 1);
|
||||
}
|
||||
|
||||
public void testHashtableEnum() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
||||
// 3 because
|
||||
// can't tell between key, value, and entry enumerators in Hashtable
|
||||
doPointsToSizeTest(TestInfo.SCOPE_FILE, TestInfo.TEST_HASHTABLE_ENUM, 3);
|
||||
}
|
||||
|
||||
// we know this one fails...
|
||||
// public void testOnTheFlyCS() throws ClassHierarchyException {
|
||||
// String mainClass = TestInfo.TEST_ONTHEFLY_CS;
|
||||
// final IDemandPointerAnalysis dmp =
|
||||
// makeDemandPointerAnalysis(TestInfo.SCOPE_FILE, mainClass);
|
||||
// CGNode testMethod =
|
||||
// AbstractPtrTest.findInstanceMethod(dmp.getBaseCallGraph(),
|
||||
// dmp.getClassHierarchy().lookupClass(
|
||||
// TypeReference.findOrCreate(ClassLoaderReference.Application,
|
||||
// "Ltestdata/TestOnTheFlyCS$C2")), Atom
|
||||
// .findOrCreateUnicodeAtom("doSomething"),
|
||||
// Descriptor.findOrCreateUTF8("(Ljava/lang/Object;)V"));
|
||||
// PointerKey keyToQuery = AbstractPtrTest.getParam(testMethod, "testThisVar",
|
||||
// dmp.getHeapModel());
|
||||
// Collection<InstanceKey> pointsTo = dmp.getPointsTo(keyToQuery);
|
||||
// if (debug) {
|
||||
// System.err.println("points-to for " + mainClass + ": " + pointsTo);
|
||||
// }
|
||||
// assertEquals(1, pointsTo.size());
|
||||
// }
|
||||
|
||||
public void testWithinMethodCall() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
||||
String mainClass = TestInfo.TEST_WITHIN_METHOD_CALL;
|
||||
final IDemandPointerAnalysis dmp = makeDemandPointerAnalysis(TestInfo.SCOPE_FILE, mainClass);
|
||||
|
||||
CGNode testMethod = AbstractPtrTest.findStaticMethod(dmp.getBaseCallGraph(), Atom.findOrCreateUnicodeAtom("testMethod"),
|
||||
Descriptor.findOrCreateUTF8("(Ljava/lang/Object;)V"));
|
||||
PointerKey keyToQuery = AbstractPtrTest.getParam(testMethod, "testThisVar", dmp.getHeapModel());
|
||||
Collection<InstanceKey> pointsTo = dmp.getPointsTo(keyToQuery);
|
||||
if (debug) {
|
||||
System.err.println("points-to for " + mainClass + ": " + pointsTo);
|
||||
}
|
||||
assertEquals(1, pointsTo.size());
|
||||
}
|
||||
|
||||
public void testLinkedListIter() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
||||
doPointsToSizeTest(TestInfo.SCOPE_FILE, TestInfo.TEST_LINKEDLIST_ITER, 1);
|
||||
}
|
||||
|
||||
public void testGlobal() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
||||
doPointsToSizeTest(TestInfo.SCOPE_FILE, TestInfo.TEST_GLOBAL, 1);
|
||||
}
|
||||
|
||||
public void testHashSet() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
||||
doPointsToSizeTest(TestInfo.SCOPE_FILE, TestInfo.TEST_HASH_SET, 2, 2, 1);
|
||||
}
|
||||
|
||||
public void testHashMapGet() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
||||
doPointsToSizeTest(TestInfo.SCOPE_FILE, TestInfo.TEST_HASHMAP_GET, 2, 1, 1);
|
||||
}
|
||||
|
||||
public void testMethodRecursion() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
||||
doPointsToSizeTest(TestInfo.SCOPE_FILE, TestInfo.TEST_METHOD_RECURSION, 2);
|
||||
}
|
||||
|
||||
public void testArraySetIter() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
||||
doPointsToSizeTest(TestInfo.SCOPE_FILE, TestInfo.TEST_ARRAY_SET_ITER, 1);
|
||||
}
|
||||
|
||||
public void testArrayList() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
||||
doPointsToSizeTest(TestInfo.SCOPE_FILE, TestInfo.TEST_ARRAY_LIST, 1);
|
||||
}
|
||||
|
||||
public void testLinkedList() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
||||
doPointsToSizeTest(TestInfo.SCOPE_FILE, TestInfo.TEST_LINKED_LIST, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StateMachineFactory<IFlowLabel> getStateMachineFactory() {
|
||||
return new ContextSensitiveStateMachine.Factory();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected DemandRefinementPointsTo makeDemandPointerAnalysis(String scopeFile, String mainClass) throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
||||
DemandRefinementPointsTo dmp = super.makeDemandPointerAnalysis(scopeFile, mainClass);
|
||||
dmp.setRefinementPolicyFactory(new TunedRefinementPolicy.Factory(dmp.getClassHierarchy()));
|
||||
return dmp;
|
||||
}
|
||||
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2008 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.core.tests.demandpa;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
|
||||
import com.ibm.wala.demandpa.alg.ContextSensitiveStateMachine;
|
||||
import com.ibm.wala.demandpa.alg.DemandRefinementPointsTo;
|
||||
import com.ibm.wala.demandpa.alg.IDemandPointerAnalysis;
|
||||
import com.ibm.wala.demandpa.alg.refinepolicy.TunedRefinementPolicy;
|
||||
import com.ibm.wala.demandpa.alg.statemachine.StateMachineFactory;
|
||||
import com.ibm.wala.demandpa.flowgraph.IFlowLabel;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||
import com.ibm.wala.types.Descriptor;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.strings.Atom;
|
||||
|
||||
public class TunedRefinementTest extends AbstractPtrTest {
|
||||
|
||||
public void testArraySet() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
||||
doPointsToSizeTest(TestInfo.SCOPE_FILE, TestInfo.TEST_ARRAY_SET, 1);
|
||||
}
|
||||
|
||||
public void testClone() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
||||
doPointsToSizeTest(TestInfo.SCOPE_FILE, TestInfo.TEST_CLONE, 1);
|
||||
}
|
||||
|
||||
public void testFooId() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
||||
doPointsToSizeTest(TestInfo.SCOPE_FILE, TestInfo.TEST_ID, 1);
|
||||
}
|
||||
|
||||
public void testHashtableEnum() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
||||
// 3 because
|
||||
// can't tell between key, value, and entry enumerators in Hashtable
|
||||
doPointsToSizeTest(TestInfo.SCOPE_FILE, TestInfo.TEST_HASHTABLE_ENUM, 3);
|
||||
}
|
||||
|
||||
// we know this one fails...
|
||||
// public void testOnTheFlyCS() throws ClassHierarchyException {
|
||||
// String mainClass = TestInfo.TEST_ONTHEFLY_CS;
|
||||
// final IDemandPointerAnalysis dmp =
|
||||
// makeDemandPointerAnalysis(TestInfo.SCOPE_FILE, mainClass);
|
||||
// CGNode testMethod =
|
||||
// AbstractPtrTest.findInstanceMethod(dmp.getBaseCallGraph(),
|
||||
// dmp.getClassHierarchy().lookupClass(
|
||||
// TypeReference.findOrCreate(ClassLoaderReference.Application,
|
||||
// "Ltestdata/TestOnTheFlyCS$C2")), Atom
|
||||
// .findOrCreateUnicodeAtom("doSomething"),
|
||||
// Descriptor.findOrCreateUTF8("(Ljava/lang/Object;)V"));
|
||||
// PointerKey keyToQuery = AbstractPtrTest.getParam(testMethod, "testThisVar",
|
||||
// dmp.getHeapModel());
|
||||
// Collection<InstanceKey> pointsTo = dmp.getPointsTo(keyToQuery);
|
||||
// if (debug) {
|
||||
// System.err.println("points-to for " + mainClass + ": " + pointsTo);
|
||||
// }
|
||||
// assertEquals(1, pointsTo.size());
|
||||
// }
|
||||
|
||||
public void testWithinMethodCall() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
||||
String mainClass = TestInfo.TEST_WITHIN_METHOD_CALL;
|
||||
final IDemandPointerAnalysis dmp = makeDemandPointerAnalysis(TestInfo.SCOPE_FILE, mainClass);
|
||||
|
||||
CGNode testMethod = AbstractPtrTest.findStaticMethod(dmp.getBaseCallGraph(), Atom.findOrCreateUnicodeAtom("testMethod"),
|
||||
Descriptor.findOrCreateUTF8("(Ljava/lang/Object;)V"));
|
||||
PointerKey keyToQuery = AbstractPtrTest.getParam(testMethod, "testThisVar", dmp.getHeapModel());
|
||||
Collection<InstanceKey> pointsTo = dmp.getPointsTo(keyToQuery);
|
||||
if (debug) {
|
||||
System.err.println("points-to for " + mainClass + ": " + pointsTo);
|
||||
}
|
||||
assertEquals(1, pointsTo.size());
|
||||
}
|
||||
|
||||
public void testLinkedListIter() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
||||
doPointsToSizeTest(TestInfo.SCOPE_FILE, TestInfo.TEST_LINKEDLIST_ITER, 1);
|
||||
}
|
||||
|
||||
public void testGlobal() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
||||
doPointsToSizeTest(TestInfo.SCOPE_FILE, TestInfo.TEST_GLOBAL, 1);
|
||||
}
|
||||
|
||||
public void testHashSet() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
||||
doPointsToSizeTest(TestInfo.SCOPE_FILE, TestInfo.TEST_HASH_SET, 2, 2, 1);
|
||||
}
|
||||
|
||||
public void testHashMapGet() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
||||
doPointsToSizeTest(TestInfo.SCOPE_FILE, TestInfo.TEST_HASHMAP_GET, 2, 1, 1);
|
||||
}
|
||||
|
||||
public void testMethodRecursion() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
||||
doPointsToSizeTest(TestInfo.SCOPE_FILE, TestInfo.TEST_METHOD_RECURSION, 2);
|
||||
}
|
||||
|
||||
public void testArraySetIter() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
||||
doPointsToSizeTest(TestInfo.SCOPE_FILE, TestInfo.TEST_ARRAY_SET_ITER, 1);
|
||||
}
|
||||
|
||||
public void testArrayList() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
||||
doPointsToSizeTest(TestInfo.SCOPE_FILE, TestInfo.TEST_ARRAY_LIST, 1);
|
||||
}
|
||||
|
||||
public void testLinkedList() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
||||
doPointsToSizeTest(TestInfo.SCOPE_FILE, TestInfo.TEST_LINKED_LIST, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StateMachineFactory<IFlowLabel> getStateMachineFactory() {
|
||||
return new ContextSensitiveStateMachine.Factory();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected DemandRefinementPointsTo makeDemandPointerAnalysis(String scopeFile, String mainClass) throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
||||
DemandRefinementPointsTo dmp = super.makeDemandPointerAnalysis(scopeFile, mainClass);
|
||||
dmp.setRefinementPolicyFactory(new TunedRefinementPolicy.Factory(dmp.getClassHierarchy()));
|
||||
return dmp;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@ import java.util.Iterator;
|
|||
import com.ibm.wala.core.tests.callGraph.CallGraphTestUtil;
|
||||
import com.ibm.wala.core.tests.util.TestConstants;
|
||||
import com.ibm.wala.core.tests.util.WalaTestCase;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
|
@ -30,6 +29,7 @@ import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
|
|||
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.intset.OrdinalSet;
|
||||
|
||||
|
|
|
@ -1,93 +1,93 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 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.core.tests.ptrs;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.ibm.wala.core.tests.callGraph.CallGraphTestUtil;
|
||||
import com.ibm.wala.core.tests.util.TestConstants;
|
||||
import com.ibm.wala.core.tests.util.WalaTestCase;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraphBuilder;
|
||||
import com.ibm.wala.ipa.callgraph.Entrypoint;
|
||||
import com.ibm.wala.ipa.callgraph.impl.Util;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.intset.OrdinalSet;
|
||||
|
||||
public class TypeBasedArrayAliasTest extends WalaTestCase {
|
||||
|
||||
public void testTypeBasedArrayAlias() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
||||
AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA, CallGraphTestUtil.REGRESSION_EXCLUSIONS);
|
||||
ClassHierarchy cha = ClassHierarchy.make(scope);
|
||||
Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util
|
||||
.makeMainEntrypoints(scope, cha, TestConstants.ARRAY_ALIAS_MAIN);
|
||||
AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints);
|
||||
|
||||
// RTA yields a TypeBasedPointerAnalysis
|
||||
CallGraphBuilder builder = Util.makeRTABuilder(options, new AnalysisCache(),cha, scope);
|
||||
CallGraph cg = builder.makeCallGraph(options, null);
|
||||
PointerAnalysis pa = builder.getPointerAnalysis();
|
||||
|
||||
CGNode node = findNode(cg, "testMayAlias1");
|
||||
PointerKey pk1 = pa.getHeapModel().getPointerKeyForLocal(node, 1);
|
||||
PointerKey pk2 = pa.getHeapModel().getPointerKeyForLocal(node, 2);
|
||||
assertTrue(mayAliased(pk1, pk2, pa));
|
||||
|
||||
node = findNode(cg, "testMayAlias2");
|
||||
pk1 = pa.getHeapModel().getPointerKeyForLocal(node, 1);
|
||||
pk2 = pa.getHeapModel().getPointerKeyForLocal(node, 2);
|
||||
assertTrue(mayAliased(pk1, pk2, pa));
|
||||
|
||||
node = findNode(cg, "testMayAlias3");
|
||||
pk1 = pa.getHeapModel().getPointerKeyForLocal(node, 1);
|
||||
pk2 = pa.getHeapModel().getPointerKeyForLocal(node, 2);
|
||||
assertTrue(mayAliased(pk1, pk2, pa));
|
||||
}
|
||||
|
||||
private final static CGNode findNode(CallGraph cg, String methodName) {
|
||||
for (Iterator<? extends CGNode> it = cg.iterator(); it.hasNext(); ) {
|
||||
CGNode n = it.next();
|
||||
if (n.getMethod().getName().toString().equals(methodName)) {
|
||||
return n;
|
||||
}
|
||||
}
|
||||
Assertions.UNREACHABLE("Unexpected: failed to find " + methodName + " node");
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean mayAliased(PointerKey pk1, PointerKey pk2, PointerAnalysis pa) {
|
||||
OrdinalSet<InstanceKey> ptsTo1 = pa.getPointsToSet(pk1);
|
||||
OrdinalSet<InstanceKey> ptsTo2 = pa.getPointsToSet(pk2);
|
||||
boolean foundIntersection = false;
|
||||
outer: for (InstanceKey i : ptsTo1) {
|
||||
for (InstanceKey j : ptsTo2) {
|
||||
if (i.equals(j)) {
|
||||
foundIntersection = true;
|
||||
break outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
return foundIntersection;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2008 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.core.tests.ptrs;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.ibm.wala.core.tests.callGraph.CallGraphTestUtil;
|
||||
import com.ibm.wala.core.tests.util.TestConstants;
|
||||
import com.ibm.wala.core.tests.util.WalaTestCase;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraphBuilder;
|
||||
import com.ibm.wala.ipa.callgraph.Entrypoint;
|
||||
import com.ibm.wala.ipa.callgraph.impl.Util;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.intset.OrdinalSet;
|
||||
|
||||
public class TypeBasedArrayAliasTest extends WalaTestCase {
|
||||
|
||||
public void testTypeBasedArrayAlias() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
||||
AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA, CallGraphTestUtil.REGRESSION_EXCLUSIONS);
|
||||
ClassHierarchy cha = ClassHierarchy.make(scope);
|
||||
Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util
|
||||
.makeMainEntrypoints(scope, cha, TestConstants.ARRAY_ALIAS_MAIN);
|
||||
AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints);
|
||||
|
||||
// RTA yields a TypeBasedPointerAnalysis
|
||||
CallGraphBuilder builder = Util.makeRTABuilder(options, new AnalysisCache(),cha, scope);
|
||||
CallGraph cg = builder.makeCallGraph(options, null);
|
||||
PointerAnalysis pa = builder.getPointerAnalysis();
|
||||
|
||||
CGNode node = findNode(cg, "testMayAlias1");
|
||||
PointerKey pk1 = pa.getHeapModel().getPointerKeyForLocal(node, 1);
|
||||
PointerKey pk2 = pa.getHeapModel().getPointerKeyForLocal(node, 2);
|
||||
assertTrue(mayAliased(pk1, pk2, pa));
|
||||
|
||||
node = findNode(cg, "testMayAlias2");
|
||||
pk1 = pa.getHeapModel().getPointerKeyForLocal(node, 1);
|
||||
pk2 = pa.getHeapModel().getPointerKeyForLocal(node, 2);
|
||||
assertTrue(mayAliased(pk1, pk2, pa));
|
||||
|
||||
node = findNode(cg, "testMayAlias3");
|
||||
pk1 = pa.getHeapModel().getPointerKeyForLocal(node, 1);
|
||||
pk2 = pa.getHeapModel().getPointerKeyForLocal(node, 2);
|
||||
assertTrue(mayAliased(pk1, pk2, pa));
|
||||
}
|
||||
|
||||
private final static CGNode findNode(CallGraph cg, String methodName) {
|
||||
for (Iterator<? extends CGNode> it = cg.iterator(); it.hasNext(); ) {
|
||||
CGNode n = it.next();
|
||||
if (n.getMethod().getName().toString().equals(methodName)) {
|
||||
return n;
|
||||
}
|
||||
}
|
||||
Assertions.UNREACHABLE("Unexpected: failed to find " + methodName + " node");
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean mayAliased(PointerKey pk1, PointerKey pk2, PointerAnalysis pa) {
|
||||
OrdinalSet<InstanceKey> ptsTo1 = pa.getPointsToSet(pk1);
|
||||
OrdinalSet<InstanceKey> ptsTo2 = pa.getPointsToSet(pk2);
|
||||
boolean foundIntersection = false;
|
||||
outer: for (InstanceKey i : ptsTo1) {
|
||||
for (InstanceKey j : ptsTo2) {
|
||||
if (i.equals(j)) {
|
||||
foundIntersection = true;
|
||||
break outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
return foundIntersection;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@ import junit.framework.TestCase;
|
|||
|
||||
import com.ibm.wala.core.tests.callGraph.CallGraphTestUtil;
|
||||
import com.ibm.wala.core.tests.util.TestConstants;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.examples.drivers.PDFSlice;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
|
@ -53,6 +52,7 @@ import com.ibm.wala.ssa.SSANewInstruction;
|
|||
import com.ibm.wala.ssa.SSAPutInstruction;
|
||||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
import com.ibm.wala.types.Descriptor;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.intset.IntSet;
|
||||
import com.ibm.wala.util.strings.Atom;
|
||||
|
|
|
@ -1,150 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* 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.core.tests.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
import java.util.zip.ZipException;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IWorkspaceRoot;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.FileLocator;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
import org.eclipse.core.runtime.Plugin;
|
||||
import org.eclipse.jdt.core.IJavaModel;
|
||||
import org.eclipse.jdt.core.IJavaProject;
|
||||
import org.eclipse.jdt.core.JavaCore;
|
||||
import org.eclipse.ui.dialogs.IOverwriteQuery;
|
||||
import org.eclipse.ui.wizards.datatransfer.ImportOperation;
|
||||
import org.eclipse.ui.wizards.datatransfer.ZipFileStructureProvider;
|
||||
import org.osgi.framework.Bundle;
|
||||
|
||||
public class EclipseTestUtil {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void importZippedProject(Plugin plugin, String zipFileName, IProgressMonitor monitor) {
|
||||
ZipFile zipFile = getZipFile(plugin, zipFileName);
|
||||
ZipFileStructureProvider zp = new ZipFileStructureProvider(zipFile);
|
||||
List children = zp.getChildren(zp.getRoot());
|
||||
Object element = children.get(0);
|
||||
String projectName = zp.getLabel(element);
|
||||
createOpenProject(projectName);
|
||||
importZipfile(zipFile, zp, monitor);
|
||||
}
|
||||
|
||||
public static void createOpenProject(String projectName) {
|
||||
IWorkspaceRoot root = getWorkspace();
|
||||
IProject project = root.getProject(projectName);
|
||||
try {
|
||||
project.create(null);
|
||||
project.open(null);
|
||||
} catch (CoreException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void destroyProject(String projectName) {
|
||||
IWorkspaceRoot root = getWorkspace();
|
||||
IProject project = root.getProject(projectName);
|
||||
try {
|
||||
project.delete(true, null);
|
||||
} catch (CoreException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
protected static void importZipfile(ZipFile sourceZip, ZipFileStructureProvider provider, IProgressMonitor monitor) {
|
||||
IPath containerPath = getWorkspacePath();
|
||||
|
||||
ImportOperation importOp = new ImportOperation(containerPath, provider.getRoot(), provider, new IOverwriteQuery() {
|
||||
public String queryOverwrite(String pathString) {
|
||||
return IOverwriteQuery.ALL;
|
||||
}
|
||||
});
|
||||
|
||||
importOp.setCreateContainerStructure(true);
|
||||
importOp.setOverwriteResources(true);
|
||||
try {
|
||||
importOp.run(monitor);
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
sourceZip.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static File getTestDataFile(Plugin plugin, String filename) {
|
||||
Bundle bundle = plugin.getBundle();
|
||||
IPath path = new Path("testdata").append(filename);
|
||||
|
||||
URL url = FileLocator.find(bundle, path, null);
|
||||
assert url != null;
|
||||
try {
|
||||
URL fileURL = FileLocator.toFileURL(url);
|
||||
File file = new File(fileURL.getPath());
|
||||
return file;
|
||||
} catch (IOException e) {
|
||||
reportException(e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ZipFile getZipFile(Plugin plugin, String testArchive) {
|
||||
File file = getTestDataFile(plugin, testArchive);
|
||||
if (file != null) {
|
||||
try {
|
||||
return new ZipFile(file);
|
||||
} catch (ZipException e) {
|
||||
reportException(e);
|
||||
} catch (IOException e) {
|
||||
reportException(e);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static IWorkspaceRoot getWorkspace() {
|
||||
return ResourcesPlugin.getWorkspace().getRoot();
|
||||
}
|
||||
|
||||
private static IPath getWorkspacePath() {
|
||||
return ResourcesPlugin.getWorkspace().getRoot().getFullPath();
|
||||
}
|
||||
|
||||
private static void reportException(Exception e) {
|
||||
// TODO: add to appropriate error log? Report differently ??
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
public static IJavaProject getNamedProject(String projectName) {
|
||||
IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
|
||||
IJavaModel javaModel = JavaCore.create(workspaceRoot);
|
||||
IJavaProject helloWorldProject = javaModel.getJavaProject(projectName);
|
||||
return helloWorldProject;
|
||||
}
|
||||
|
||||
}
|
|
@ -47,7 +47,6 @@ import com.ibm.wala.demandpa.flowgraph.IFlowLabel;
|
|||
import com.ibm.wala.demandpa.util.CallGraphMapUtil;
|
||||
import com.ibm.wala.demandpa.util.MemoryAccessMap;
|
||||
import com.ibm.wala.demandpa.util.SimpleMemoryAccessMap;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
|
@ -65,6 +64,7 @@ import com.ibm.wala.ipa.cha.ClassHierarchy;
|
|||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||
import com.ibm.wala.ssa.IR;
|
||||
import com.ibm.wala.types.MethodReference;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.config.AnalysisScopeReader;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.intset.OrdinalSet;
|
||||
|
|
|
@ -54,8 +54,6 @@ import com.ibm.wala.demandpa.flowgraph.IFlowLabel;
|
|||
import com.ibm.wala.demandpa.genericutil.Predicate;
|
||||
import com.ibm.wala.demandpa.util.MemoryAccessMap;
|
||||
import com.ibm.wala.demandpa.util.SimpleMemoryAccessMap;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.eclipse.util.ProgressMaster;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
|
@ -79,6 +77,8 @@ import com.ibm.wala.ssa.SSACheckCastInstruction;
|
|||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.ProgressMaster;
|
||||
import com.ibm.wala.util.collections.Pair;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.warnings.WalaException;
|
||||
|
|
|
@ -48,7 +48,6 @@ import com.ibm.wala.demandpa.alg.statemachine.DummyStateMachine;
|
|||
import com.ibm.wala.demandpa.flowgraph.IFlowLabel;
|
||||
import com.ibm.wala.demandpa.util.MemoryAccessMap;
|
||||
import com.ibm.wala.demandpa.util.SimpleMemoryAccessMap;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
|
@ -64,6 +63,7 @@ import com.ibm.wala.ipa.callgraph.propagation.SSAPropagationCallGraphBuilder;
|
|||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||
import com.ibm.wala.ssa.IR;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
|
||||
/**
|
||||
* Driver that tests a pointer analysis results against the results of
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007 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.eclipse.headless;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.eclipse.equinox.app.IApplication;
|
||||
import org.eclipse.equinox.app.IApplicationContext;
|
||||
import org.eclipse.jdt.core.IJavaProject;
|
||||
|
||||
import com.ibm.wala.eclipse.util.EclipseProjectPath;
|
||||
import com.ibm.wala.eclipse.util.JdtUtil;
|
||||
|
||||
/**
|
||||
* A dummy main class that runs WALA in a headless Eclipse platform.
|
||||
*
|
||||
* This is for expository purposes, and tests some WALA eclipse functionality.
|
||||
*
|
||||
* @author sjfink
|
||||
*
|
||||
*/
|
||||
public class Main implements IApplication {
|
||||
|
||||
public Object start(IApplicationContext context) throws Exception {
|
||||
Collection<IJavaProject> jp = JdtUtil.getWorkspaceJavaProjects();
|
||||
for (IJavaProject p : jp) {
|
||||
System.out.println(p);
|
||||
EclipseProjectPath path = EclipseProjectPath.make(p);
|
||||
System.out.println("Path: " + path);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
}
|
||||
}
|
|
@ -1,350 +1,350 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 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.examples.analysis;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
import com.ibm.wala.classLoader.ArrayClass;
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.classLoader.IField;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.classLoader.JarFileModule;
|
||||
import com.ibm.wala.client.AbstractAnalysisEngine;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraphBuilder;
|
||||
import com.ibm.wala.ipa.callgraph.Entrypoint;
|
||||
import com.ibm.wala.ipa.callgraph.impl.Util;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.HeapModel;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.properties.WalaProperties;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.intset.OrdinalSet;
|
||||
import com.ibm.wala.util.warnings.WalaException;
|
||||
|
||||
/**
|
||||
* <P>
|
||||
* A simple thread-level escape analysis: this code computes the set of classes of which some instance may be accessed
|
||||
* by some thread other than the one that created it.
|
||||
* </P>
|
||||
*
|
||||
* <P>
|
||||
* The algorithm is not very bright; it is based on the observation that there are only three ways for an object to pass
|
||||
* from one thread to another.
|
||||
* <UL>
|
||||
* <LI> The object is stored into a static variable.
|
||||
* <LI> The object is stored into an instance field of a Thread
|
||||
* <LI> The object is reachable from a field of another escaping object.
|
||||
* </UL>
|
||||
* </P>
|
||||
*
|
||||
* <P>
|
||||
* This observation is implemented in the obvious way:
|
||||
* <OL>
|
||||
* <LI> All static fields are collected
|
||||
* <LI> All Thread constructor parameters are collected
|
||||
* <LI> The points-to sets of these values represent the base set of escapees.
|
||||
* <LI> All object reachable from fields of these objects are added
|
||||
* <LI> This process continues until a fixpoint is reached
|
||||
* <LI> The abstract objects in the points-to sets are converted to types
|
||||
* <LI> This set of types is returned
|
||||
* </OL>
|
||||
* </P>
|
||||
*
|
||||
* @author Julian Dolby
|
||||
*/
|
||||
public class SimpleThreadEscapeAnalysis extends AbstractAnalysisEngine {
|
||||
|
||||
private final Set<JarFile> applicationJarFiles;
|
||||
|
||||
private final String applicationMainClass;
|
||||
|
||||
/**
|
||||
* The two input parameters define the program to analyze: the jars of .class files and the main class to start from.
|
||||
*/
|
||||
public SimpleThreadEscapeAnalysis(Set<JarFile> applicationJarFiles, String applicationMainClass) {
|
||||
this.applicationJarFiles = applicationJarFiles;
|
||||
this.applicationMainClass = applicationMainClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CallGraphBuilder getCallGraphBuilder(IClassHierarchy cha, AnalysisOptions options, AnalysisCache cache) {
|
||||
return Util.makeZeroCFABuilder(options, cache, cha, scope);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a root path, add it to the set if it is a jar, or traverse it recursively if it is a directory.
|
||||
*/
|
||||
private void collectJars(File f, Set<JarFile> result) throws IOException {
|
||||
if (f.isDirectory()) {
|
||||
File[] files = f.listFiles();
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
collectJars(files[i], result);
|
||||
}
|
||||
} else if (f.getAbsolutePath().endsWith(".jar")) {
|
||||
result.add(new JarFile(f));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect the set of JarFiles that constitute the system libraries of the running JRE.
|
||||
*/
|
||||
private JarFile[] getSystemJars() throws IOException {
|
||||
String javaHomePath = "garbage";
|
||||
Set<JarFile> jarFiles = HashSetFactory.make();
|
||||
|
||||
// first, see if wala.properties has been set up
|
||||
try {
|
||||
Properties p = WalaProperties.loadProperties();
|
||||
javaHomePath = p.getProperty(WalaProperties.J2SE_DIR);
|
||||
} catch (WalaException e) {
|
||||
// no luck.
|
||||
}
|
||||
|
||||
// if not, try assuming the running JRE looks normal
|
||||
File x = new File(javaHomePath);
|
||||
if (!(x.exists() && x.isDirectory())) {
|
||||
javaHomePath = System.getProperty("java.home");
|
||||
|
||||
if (!javaHomePath.endsWith(File.separator)) {
|
||||
javaHomePath = javaHomePath + File.separator;
|
||||
}
|
||||
|
||||
javaHomePath = javaHomePath + "lib";
|
||||
}
|
||||
|
||||
// find jars from chosen JRE lib path
|
||||
collectJars(new File(javaHomePath), jarFiles);
|
||||
|
||||
return jarFiles.toArray(new JarFile[jarFiles.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Take the given set of JarFiles that constitute the program, and return a set of Module files as expected by the
|
||||
* WALA machinery.
|
||||
*/
|
||||
private Set<JarFileModule> getModuleFiles() {
|
||||
Set<JarFileModule> result = HashSetFactory.make();
|
||||
for (Iterator<JarFile> jars = applicationJarFiles.iterator(); jars.hasNext();) {
|
||||
result.add(new JarFileModule(jars.next()));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* The heart of the analysis.
|
||||
* @throws CancelException
|
||||
* @throws IllegalArgumentException
|
||||
*/
|
||||
public Set<IClass> gatherThreadEscapingClasses() throws IOException, ClassHierarchyException, IllegalArgumentException,
|
||||
CancelException {
|
||||
|
||||
//
|
||||
// set the application to analyze
|
||||
//
|
||||
setModuleFiles(getModuleFiles());
|
||||
|
||||
//
|
||||
// set the system jar files to use.
|
||||
// change this if you want to use a specific jre version
|
||||
//
|
||||
setJ2SELibraries(getSystemJars());
|
||||
|
||||
//
|
||||
// the application and libraries are set, now build the scope...
|
||||
//
|
||||
buildAnalysisScope();
|
||||
|
||||
//
|
||||
// ...and the class hierarchy
|
||||
//
|
||||
IClassHierarchy cha = buildClassHierarchy();
|
||||
assert cha != null : "failed to create class hierarchy";
|
||||
setClassHierarchy(cha);
|
||||
|
||||
//
|
||||
// entrypoints are where analysis starts
|
||||
//
|
||||
Iterable<Entrypoint> roots = Util.makeMainEntrypoints(getScope(), cha, applicationMainClass);
|
||||
|
||||
//
|
||||
// analysis options controls aspects of call graph construction
|
||||
//
|
||||
AnalysisOptions options = getDefaultOptions(roots);
|
||||
|
||||
//
|
||||
// build the call graph
|
||||
//
|
||||
buildCallGraph(cha, options, true, null);
|
||||
|
||||
//
|
||||
// extract data for analysis
|
||||
//
|
||||
CallGraph cg = getCallGraph();
|
||||
PointerAnalysis pa = getPointerAnalysis();
|
||||
|
||||
//
|
||||
// collect all places where objects can escape their creating thread:
|
||||
// 1) all static fields
|
||||
// 2) arguments to Thread constructors
|
||||
//
|
||||
Set<PointerKey> escapeAnalysisRoots = HashSetFactory.make();
|
||||
HeapModel heapModel = pa.getHeapModel();
|
||||
|
||||
// 1) static fields
|
||||
for (IClass cls : cha) {
|
||||
Collection<IField> staticFields = cls.getDeclaredStaticFields();
|
||||
for (Iterator<IField> sfs = staticFields.iterator(); sfs.hasNext();) {
|
||||
IField sf = (IField) sfs.next();
|
||||
if (sf.getFieldTypeReference().isReferenceType()) {
|
||||
escapeAnalysisRoots.add(heapModel.getPointerKeyForStaticField(sf));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 2) instance fields of Threads
|
||||
// (we hack this by getting the 'this' parameter of all ctor calls;
|
||||
// this works because the next phase will add all objects transitively
|
||||
// reachable from fields of types in these pointer keys, and all
|
||||
// Thread objects must be constructed somewhere)
|
||||
Collection<IClass> threads = cha.computeSubClasses(TypeReference.JavaLangThread);
|
||||
for (Iterator<IClass> clss = threads.iterator(); clss.hasNext();) {
|
||||
IClass cls = (IClass) clss.next();
|
||||
for (Iterator<IMethod> ms = cls.getDeclaredMethods().iterator(); ms.hasNext();) {
|
||||
IMethod m = (IMethod) ms.next();
|
||||
if (m.isInit()) {
|
||||
Set<CGNode> nodes = cg.getNodes(m.getReference());
|
||||
for (Iterator<CGNode> ns = nodes.iterator(); ns.hasNext();) {
|
||||
CGNode n = (CGNode) ns.next();
|
||||
escapeAnalysisRoots.add(heapModel.getPointerKeyForLocal(n, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// compute escaping types: all types flowing to escaping roots and
|
||||
// all types transitively reachable through their fields.
|
||||
//
|
||||
Set<InstanceKey> escapingInstanceKeys = HashSetFactory.make();
|
||||
|
||||
//
|
||||
// pass 1: get abstract objects (instance keys) for escaping locations
|
||||
//
|
||||
for (Iterator<PointerKey> rts = escapeAnalysisRoots.iterator(); rts.hasNext();) {
|
||||
PointerKey root = rts.next();
|
||||
OrdinalSet<InstanceKey> objects = pa.getPointsToSet(root);
|
||||
for (Iterator<InstanceKey> objs = objects.iterator(); objs.hasNext();) {
|
||||
InstanceKey obj = (InstanceKey) objs.next();
|
||||
escapingInstanceKeys.add(obj);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// passes 2+: get fields of escaping keys, and add pointed-to keys
|
||||
//
|
||||
Set<InstanceKey> newKeys = HashSetFactory.make();
|
||||
do {
|
||||
newKeys.clear();
|
||||
for (Iterator<InstanceKey> keys = escapingInstanceKeys.iterator(); keys.hasNext();) {
|
||||
InstanceKey key = keys.next();
|
||||
IClass type = key.getConcreteType();
|
||||
if (type.isReferenceType()) {
|
||||
if (type.isArrayClass()) {
|
||||
if (((ArrayClass) type).getElementClass() != null) {
|
||||
PointerKey fk = heapModel.getPointerKeyForArrayContents(key);
|
||||
OrdinalSet<InstanceKey> fobjects = pa.getPointsToSet(fk);
|
||||
for (Iterator<InstanceKey> fobjs = fobjects.iterator(); fobjs.hasNext();) {
|
||||
InstanceKey fobj = (InstanceKey) fobjs.next();
|
||||
if (!escapingInstanceKeys.contains(fobj)) {
|
||||
newKeys.add(fobj);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Collection<IField> fields = type.getAllInstanceFields();
|
||||
for (Iterator<IField> fs = fields.iterator(); fs.hasNext();) {
|
||||
IField f = (IField) fs.next();
|
||||
if (f.getFieldTypeReference().isReferenceType()) {
|
||||
PointerKey fk = heapModel.getPointerKeyForInstanceField(key, f);
|
||||
OrdinalSet<InstanceKey> fobjects = pa.getPointsToSet(fk);
|
||||
for (Iterator<InstanceKey> fobjs = fobjects.iterator(); fobjs.hasNext();) {
|
||||
InstanceKey fobj = (InstanceKey) fobjs.next();
|
||||
if (!escapingInstanceKeys.contains(fobj)) {
|
||||
newKeys.add(fobj);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
escapingInstanceKeys.addAll(newKeys);
|
||||
} while (!newKeys.isEmpty());
|
||||
|
||||
//
|
||||
// get set of types from set of instance keys
|
||||
//
|
||||
Set<IClass> escapingTypes = HashSetFactory.make();
|
||||
for (Iterator<InstanceKey> keys = escapingInstanceKeys.iterator(); keys.hasNext();) {
|
||||
InstanceKey key = keys.next();
|
||||
escapingTypes.add(key.getConcreteType());
|
||||
}
|
||||
|
||||
return escapingTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* This main program shows one example use of thread escape analysis: producing a set of fields to be monitored for a
|
||||
* dynamic race detector. The idea is that any field might have a race with two exceptions: final fields do not have
|
||||
* races since there are no writes to them, and volatile fields have atomic read and write semantics provided by the
|
||||
* VM. Hence, this piece of code produces a list of all other fields.
|
||||
* @throws CancelException
|
||||
* @throws IllegalArgumentException
|
||||
*/
|
||||
public static void main(String[] args) throws IOException, ClassHierarchyException, IllegalArgumentException, CancelException {
|
||||
String mainClassName = args[0];
|
||||
|
||||
Set<JarFile> jars = HashSetFactory.make();
|
||||
for (int i = 1; i < args.length; i++) {
|
||||
jars.add(new JarFile(args[i]));
|
||||
}
|
||||
|
||||
Set<IClass> escapingTypes = (new SimpleThreadEscapeAnalysis(jars, mainClassName)).gatherThreadEscapingClasses();
|
||||
|
||||
for (Iterator<IClass> types = escapingTypes.iterator(); types.hasNext();) {
|
||||
IClass cls = types.next();
|
||||
if (!cls.isArrayClass()) {
|
||||
for (Iterator<IField> fs = cls.getAllFields().iterator(); fs.hasNext();) {
|
||||
IField f = (IField) fs.next();
|
||||
if (!f.isVolatile() && !f.isFinal()) {
|
||||
System.err.println(f.getReference());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 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.examples.analysis;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
import com.ibm.wala.classLoader.ArrayClass;
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.classLoader.IField;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.classLoader.JarFileModule;
|
||||
import com.ibm.wala.client.AbstractAnalysisEngine;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraphBuilder;
|
||||
import com.ibm.wala.ipa.callgraph.Entrypoint;
|
||||
import com.ibm.wala.ipa.callgraph.impl.Util;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.HeapModel;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.properties.WalaProperties;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.intset.OrdinalSet;
|
||||
import com.ibm.wala.util.warnings.WalaException;
|
||||
|
||||
/**
|
||||
* <P>
|
||||
* A simple thread-level escape analysis: this code computes the set of classes of which some instance may be accessed
|
||||
* by some thread other than the one that created it.
|
||||
* </P>
|
||||
*
|
||||
* <P>
|
||||
* The algorithm is not very bright; it is based on the observation that there are only three ways for an object to pass
|
||||
* from one thread to another.
|
||||
* <UL>
|
||||
* <LI> The object is stored into a static variable.
|
||||
* <LI> The object is stored into an instance field of a Thread
|
||||
* <LI> The object is reachable from a field of another escaping object.
|
||||
* </UL>
|
||||
* </P>
|
||||
*
|
||||
* <P>
|
||||
* This observation is implemented in the obvious way:
|
||||
* <OL>
|
||||
* <LI> All static fields are collected
|
||||
* <LI> All Thread constructor parameters are collected
|
||||
* <LI> The points-to sets of these values represent the base set of escapees.
|
||||
* <LI> All object reachable from fields of these objects are added
|
||||
* <LI> This process continues until a fixpoint is reached
|
||||
* <LI> The abstract objects in the points-to sets are converted to types
|
||||
* <LI> This set of types is returned
|
||||
* </OL>
|
||||
* </P>
|
||||
*
|
||||
* @author Julian Dolby
|
||||
*/
|
||||
public class SimpleThreadEscapeAnalysis extends AbstractAnalysisEngine {
|
||||
|
||||
private final Set<JarFile> applicationJarFiles;
|
||||
|
||||
private final String applicationMainClass;
|
||||
|
||||
/**
|
||||
* The two input parameters define the program to analyze: the jars of .class files and the main class to start from.
|
||||
*/
|
||||
public SimpleThreadEscapeAnalysis(Set<JarFile> applicationJarFiles, String applicationMainClass) {
|
||||
this.applicationJarFiles = applicationJarFiles;
|
||||
this.applicationMainClass = applicationMainClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CallGraphBuilder getCallGraphBuilder(IClassHierarchy cha, AnalysisOptions options, AnalysisCache cache) {
|
||||
return Util.makeZeroCFABuilder(options, cache, cha, scope);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a root path, add it to the set if it is a jar, or traverse it recursively if it is a directory.
|
||||
*/
|
||||
private void collectJars(File f, Set<JarFile> result) throws IOException {
|
||||
if (f.isDirectory()) {
|
||||
File[] files = f.listFiles();
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
collectJars(files[i], result);
|
||||
}
|
||||
} else if (f.getAbsolutePath().endsWith(".jar")) {
|
||||
result.add(new JarFile(f));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect the set of JarFiles that constitute the system libraries of the running JRE.
|
||||
*/
|
||||
private JarFile[] getSystemJars() throws IOException {
|
||||
String javaHomePath = "garbage";
|
||||
Set<JarFile> jarFiles = HashSetFactory.make();
|
||||
|
||||
// first, see if wala.properties has been set up
|
||||
try {
|
||||
Properties p = WalaProperties.loadProperties();
|
||||
javaHomePath = p.getProperty(WalaProperties.J2SE_DIR);
|
||||
} catch (WalaException e) {
|
||||
// no luck.
|
||||
}
|
||||
|
||||
// if not, try assuming the running JRE looks normal
|
||||
File x = new File(javaHomePath);
|
||||
if (!(x.exists() && x.isDirectory())) {
|
||||
javaHomePath = System.getProperty("java.home");
|
||||
|
||||
if (!javaHomePath.endsWith(File.separator)) {
|
||||
javaHomePath = javaHomePath + File.separator;
|
||||
}
|
||||
|
||||
javaHomePath = javaHomePath + "lib";
|
||||
}
|
||||
|
||||
// find jars from chosen JRE lib path
|
||||
collectJars(new File(javaHomePath), jarFiles);
|
||||
|
||||
return jarFiles.toArray(new JarFile[jarFiles.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Take the given set of JarFiles that constitute the program, and return a set of Module files as expected by the
|
||||
* WALA machinery.
|
||||
*/
|
||||
private Set<JarFileModule> getModuleFiles() {
|
||||
Set<JarFileModule> result = HashSetFactory.make();
|
||||
for (Iterator<JarFile> jars = applicationJarFiles.iterator(); jars.hasNext();) {
|
||||
result.add(new JarFileModule(jars.next()));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* The heart of the analysis.
|
||||
* @throws CancelException
|
||||
* @throws IllegalArgumentException
|
||||
*/
|
||||
public Set<IClass> gatherThreadEscapingClasses() throws IOException, ClassHierarchyException, IllegalArgumentException,
|
||||
CancelException {
|
||||
|
||||
//
|
||||
// set the application to analyze
|
||||
//
|
||||
setModuleFiles(getModuleFiles());
|
||||
|
||||
//
|
||||
// set the system jar files to use.
|
||||
// change this if you want to use a specific jre version
|
||||
//
|
||||
setJ2SELibraries(getSystemJars());
|
||||
|
||||
//
|
||||
// the application and libraries are set, now build the scope...
|
||||
//
|
||||
buildAnalysisScope();
|
||||
|
||||
//
|
||||
// ...and the class hierarchy
|
||||
//
|
||||
IClassHierarchy cha = buildClassHierarchy();
|
||||
assert cha != null : "failed to create class hierarchy";
|
||||
setClassHierarchy(cha);
|
||||
|
||||
//
|
||||
// entrypoints are where analysis starts
|
||||
//
|
||||
Iterable<Entrypoint> roots = Util.makeMainEntrypoints(getScope(), cha, applicationMainClass);
|
||||
|
||||
//
|
||||
// analysis options controls aspects of call graph construction
|
||||
//
|
||||
AnalysisOptions options = getDefaultOptions(roots);
|
||||
|
||||
//
|
||||
// build the call graph
|
||||
//
|
||||
buildCallGraph(cha, options, true, null);
|
||||
|
||||
//
|
||||
// extract data for analysis
|
||||
//
|
||||
CallGraph cg = getCallGraph();
|
||||
PointerAnalysis pa = getPointerAnalysis();
|
||||
|
||||
//
|
||||
// collect all places where objects can escape their creating thread:
|
||||
// 1) all static fields
|
||||
// 2) arguments to Thread constructors
|
||||
//
|
||||
Set<PointerKey> escapeAnalysisRoots = HashSetFactory.make();
|
||||
HeapModel heapModel = pa.getHeapModel();
|
||||
|
||||
// 1) static fields
|
||||
for (IClass cls : cha) {
|
||||
Collection<IField> staticFields = cls.getDeclaredStaticFields();
|
||||
for (Iterator<IField> sfs = staticFields.iterator(); sfs.hasNext();) {
|
||||
IField sf = (IField) sfs.next();
|
||||
if (sf.getFieldTypeReference().isReferenceType()) {
|
||||
escapeAnalysisRoots.add(heapModel.getPointerKeyForStaticField(sf));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 2) instance fields of Threads
|
||||
// (we hack this by getting the 'this' parameter of all ctor calls;
|
||||
// this works because the next phase will add all objects transitively
|
||||
// reachable from fields of types in these pointer keys, and all
|
||||
// Thread objects must be constructed somewhere)
|
||||
Collection<IClass> threads = cha.computeSubClasses(TypeReference.JavaLangThread);
|
||||
for (Iterator<IClass> clss = threads.iterator(); clss.hasNext();) {
|
||||
IClass cls = (IClass) clss.next();
|
||||
for (Iterator<IMethod> ms = cls.getDeclaredMethods().iterator(); ms.hasNext();) {
|
||||
IMethod m = (IMethod) ms.next();
|
||||
if (m.isInit()) {
|
||||
Set<CGNode> nodes = cg.getNodes(m.getReference());
|
||||
for (Iterator<CGNode> ns = nodes.iterator(); ns.hasNext();) {
|
||||
CGNode n = (CGNode) ns.next();
|
||||
escapeAnalysisRoots.add(heapModel.getPointerKeyForLocal(n, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// compute escaping types: all types flowing to escaping roots and
|
||||
// all types transitively reachable through their fields.
|
||||
//
|
||||
Set<InstanceKey> escapingInstanceKeys = HashSetFactory.make();
|
||||
|
||||
//
|
||||
// pass 1: get abstract objects (instance keys) for escaping locations
|
||||
//
|
||||
for (Iterator<PointerKey> rts = escapeAnalysisRoots.iterator(); rts.hasNext();) {
|
||||
PointerKey root = rts.next();
|
||||
OrdinalSet<InstanceKey> objects = pa.getPointsToSet(root);
|
||||
for (Iterator<InstanceKey> objs = objects.iterator(); objs.hasNext();) {
|
||||
InstanceKey obj = (InstanceKey) objs.next();
|
||||
escapingInstanceKeys.add(obj);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// passes 2+: get fields of escaping keys, and add pointed-to keys
|
||||
//
|
||||
Set<InstanceKey> newKeys = HashSetFactory.make();
|
||||
do {
|
||||
newKeys.clear();
|
||||
for (Iterator<InstanceKey> keys = escapingInstanceKeys.iterator(); keys.hasNext();) {
|
||||
InstanceKey key = keys.next();
|
||||
IClass type = key.getConcreteType();
|
||||
if (type.isReferenceType()) {
|
||||
if (type.isArrayClass()) {
|
||||
if (((ArrayClass) type).getElementClass() != null) {
|
||||
PointerKey fk = heapModel.getPointerKeyForArrayContents(key);
|
||||
OrdinalSet<InstanceKey> fobjects = pa.getPointsToSet(fk);
|
||||
for (Iterator<InstanceKey> fobjs = fobjects.iterator(); fobjs.hasNext();) {
|
||||
InstanceKey fobj = (InstanceKey) fobjs.next();
|
||||
if (!escapingInstanceKeys.contains(fobj)) {
|
||||
newKeys.add(fobj);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Collection<IField> fields = type.getAllInstanceFields();
|
||||
for (Iterator<IField> fs = fields.iterator(); fs.hasNext();) {
|
||||
IField f = (IField) fs.next();
|
||||
if (f.getFieldTypeReference().isReferenceType()) {
|
||||
PointerKey fk = heapModel.getPointerKeyForInstanceField(key, f);
|
||||
OrdinalSet<InstanceKey> fobjects = pa.getPointsToSet(fk);
|
||||
for (Iterator<InstanceKey> fobjs = fobjects.iterator(); fobjs.hasNext();) {
|
||||
InstanceKey fobj = (InstanceKey) fobjs.next();
|
||||
if (!escapingInstanceKeys.contains(fobj)) {
|
||||
newKeys.add(fobj);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
escapingInstanceKeys.addAll(newKeys);
|
||||
} while (!newKeys.isEmpty());
|
||||
|
||||
//
|
||||
// get set of types from set of instance keys
|
||||
//
|
||||
Set<IClass> escapingTypes = HashSetFactory.make();
|
||||
for (Iterator<InstanceKey> keys = escapingInstanceKeys.iterator(); keys.hasNext();) {
|
||||
InstanceKey key = keys.next();
|
||||
escapingTypes.add(key.getConcreteType());
|
||||
}
|
||||
|
||||
return escapingTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* This main program shows one example use of thread escape analysis: producing a set of fields to be monitored for a
|
||||
* dynamic race detector. The idea is that any field might have a race with two exceptions: final fields do not have
|
||||
* races since there are no writes to them, and volatile fields have atomic read and write semantics provided by the
|
||||
* VM. Hence, this piece of code produces a list of all other fields.
|
||||
* @throws CancelException
|
||||
* @throws IllegalArgumentException
|
||||
*/
|
||||
public static void main(String[] args) throws IOException, ClassHierarchyException, IllegalArgumentException, CancelException {
|
||||
String mainClassName = args[0];
|
||||
|
||||
Set<JarFile> jars = HashSetFactory.make();
|
||||
for (int i = 1; i < args.length; i++) {
|
||||
jars.add(new JarFile(args[i]));
|
||||
}
|
||||
|
||||
Set<IClass> escapingTypes = (new SimpleThreadEscapeAnalysis(jars, mainClassName)).gatherThreadEscapingClasses();
|
||||
|
||||
for (Iterator<IClass> types = escapingTypes.iterator(); types.hasNext();) {
|
||||
IClass cls = types.next();
|
||||
if (!cls.isArrayClass()) {
|
||||
for (Iterator<IField> fs = cls.getAllFields().iterator(); fs.hasNext();) {
|
||||
IField f = (IField) fs.next();
|
||||
if (!f.isVolatile() && !f.isFinal()) {
|
||||
System.err.println(f.getReference());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,10 +12,11 @@ package com.ibm.wala.examples.drivers;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Properties;
|
||||
|
||||
import com.ibm.wala.core.tests.callGraph.CallGraphTestUtil;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.examples.properties.WalaExamplesProperties;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
|
@ -29,12 +30,15 @@ import com.ibm.wala.ipa.callgraph.propagation.LocalPointerKey;
|
|||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.properties.WalaProperties;
|
||||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.collections.Filter;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.config.AnalysisScopeReader;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.graph.Graph;
|
||||
import com.ibm.wala.util.io.CommandLine;
|
||||
import com.ibm.wala.util.io.FileProvider;
|
||||
import com.ibm.wala.util.io.FileUtil;
|
||||
import com.ibm.wala.util.warnings.WalaException;
|
||||
import com.ibm.wala.viz.DotUtil;
|
||||
import com.ibm.wala.viz.PDFViewUtil;
|
||||
|
@ -45,7 +49,34 @@ import com.ibm.wala.viz.PDFViewUtil;
|
|||
* @author sfink
|
||||
*/
|
||||
public class PDFCallGraph {
|
||||
public static boolean isDirectory(String appJar) {
|
||||
return (new File(appJar).isDirectory());
|
||||
}
|
||||
|
||||
public static String findJarFiles(String[] directories) throws WalaException {
|
||||
Collection<String> result = HashSetFactory.make();
|
||||
for (int i = 0; i < directories.length; i++) {
|
||||
for (Iterator<File> it = FileUtil.listFiles(directories[i], ".*\\.jar", true).iterator(); it.hasNext();) {
|
||||
File f = (File) it.next();
|
||||
result.add(f.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
return composeString(result);
|
||||
}
|
||||
|
||||
private static String composeString(Collection<String> s) {
|
||||
StringBuffer result = new StringBuffer();
|
||||
Iterator<String> it = s.iterator();
|
||||
for (int i = 0; i < s.size() - 1; i++) {
|
||||
result.append(it.next());
|
||||
result.append(';');
|
||||
}
|
||||
if (it.hasNext()) {
|
||||
result.append(it.next());
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
private final static String PDF_FILE = "cg.pdf";
|
||||
|
||||
/**
|
||||
|
@ -136,7 +167,7 @@ public class PDFCallGraph {
|
|||
return g;
|
||||
}
|
||||
|
||||
static Graph<CGNode> pruneForAppLoader(CallGraph g) throws WalaException {
|
||||
public static Graph<CGNode> pruneForAppLoader(CallGraph g) throws WalaException {
|
||||
return PDFTypeHierarchy.pruneGraph(g, new ApplicationLoaderFilter());
|
||||
}
|
||||
|
||||
|
|
|
@ -84,8 +84,8 @@ public class PDFControlDependenceGraph {
|
|||
*/
|
||||
public static Process run(String appJar, String methodSig) throws IOException {
|
||||
try {
|
||||
if (SWTCallGraph.isDirectory(appJar)) {
|
||||
appJar = SWTCallGraph.findJarFiles(new String[] { appJar });
|
||||
if (PDFCallGraph.isDirectory(appJar)) {
|
||||
appJar = PDFCallGraph.findJarFiles(new String[] { appJar });
|
||||
}
|
||||
AnalysisScope scope = AnalysisScopeReader.makeJavaBinaryAnalysisScope(appJar, FileProvider.getFile(CallGraphTestUtil.REGRESSION_EXCLUSIONS));
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@ import java.io.IOException;
|
|||
import java.util.Properties;
|
||||
|
||||
import com.ibm.wala.core.tests.callGraph.CallGraphTestUtil;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.examples.properties.WalaExamplesProperties;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
|
@ -33,6 +32,7 @@ import com.ibm.wala.ipa.slicer.Statement;
|
|||
import com.ibm.wala.ipa.slicer.Slicer.ControlDependenceOptions;
|
||||
import com.ibm.wala.ipa.slicer.Slicer.DataDependenceOptions;
|
||||
import com.ibm.wala.properties.WalaProperties;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.collections.Filter;
|
||||
import com.ibm.wala.util.config.AnalysisScopeReader;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
|
|
@ -17,7 +17,6 @@ import java.util.Properties;
|
|||
|
||||
import com.ibm.wala.core.tests.callGraph.CallGraphTestUtil;
|
||||
import com.ibm.wala.core.tests.slicer.SlicerTest;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.examples.properties.WalaExamplesProperties;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
|
@ -44,6 +43,7 @@ import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
|
|||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
import com.ibm.wala.ssa.SSAInvokeInstruction;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.collections.Filter;
|
||||
import com.ibm.wala.util.config.AnalysisScopeReader;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
|
|
@ -20,13 +20,16 @@ import com.ibm.wala.core.tests.callGraph.CallGraphTestUtil;
|
|||
import com.ibm.wala.examples.properties.WalaExamplesProperties;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.properties.WalaProperties;
|
||||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
import com.ibm.wala.util.collections.CollectionFilter;
|
||||
import com.ibm.wala.util.collections.Filter;
|
||||
import com.ibm.wala.util.config.AnalysisScopeReader;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.graph.Graph;
|
||||
import com.ibm.wala.util.graph.GraphSlicer;
|
||||
import com.ibm.wala.util.graph.impl.SlowSparseNumberedGraph;
|
||||
import com.ibm.wala.util.io.FileProvider;
|
||||
import com.ibm.wala.util.warnings.WalaException;
|
||||
import com.ibm.wala.viz.DotUtil;
|
||||
|
@ -40,6 +43,8 @@ import com.ibm.wala.viz.PDFViewUtil;
|
|||
* @author sfink
|
||||
*/
|
||||
public class PDFTypeHierarchy {
|
||||
// This example takes one command-line argument, so args[1] should be the "-classpath" parameter
|
||||
final static int CLASSPATH_INDEX = 1;
|
||||
|
||||
public final static String DOT_FILE = "temp.dt";
|
||||
|
||||
|
@ -64,16 +69,16 @@ public class PDFTypeHierarchy {
|
|||
|
||||
public static Process run(String[] args) throws IOException {
|
||||
try {
|
||||
SWTTypeHierarchy.validateCommandLine(args);
|
||||
String classpath = args[SWTTypeHierarchy.CLASSPATH_INDEX];
|
||||
validateCommandLine(args);
|
||||
String classpath = args[CLASSPATH_INDEX];
|
||||
AnalysisScope scope = AnalysisScopeReader.makeJavaBinaryAnalysisScope(classpath, FileProvider.getFile(CallGraphTestUtil.REGRESSION_EXCLUSIONS));
|
||||
|
||||
// invoke WALA to build a class hierarchy
|
||||
ClassHierarchy cha = ClassHierarchy.make(scope);
|
||||
|
||||
Graph<IClass> g = SWTTypeHierarchy.typeHierarchy2Graph(cha);
|
||||
Graph<IClass> g = typeHierarchy2Graph(cha);
|
||||
|
||||
g = SWTTypeHierarchy.pruneForAppLoader(g);
|
||||
g = pruneForAppLoader(g);
|
||||
String dotFile = p.getProperty(WalaProperties.OUTPUT_DIR) + File.separatorChar + DOT_FILE;
|
||||
String pdfFile = p.getProperty(WalaProperties.OUTPUT_DIR) + File.separatorChar + PDF_FILE;
|
||||
String dotExe = p.getProperty(WalaExamplesProperties.DOT_EXE);
|
||||
|
@ -92,4 +97,53 @@ public class PDFTypeHierarchy {
|
|||
Collection<T> slice = GraphSlicer.slice(g, f);
|
||||
return GraphSlicer.prune(g, new CollectionFilter<T>(slice));
|
||||
}
|
||||
|
||||
/**
|
||||
* Restrict g to nodes from the Application loader
|
||||
*/
|
||||
public static Graph<IClass> pruneForAppLoader(Graph<IClass> g) throws WalaException {
|
||||
Filter<IClass> f = new Filter<IClass>() {
|
||||
public boolean accepts(IClass c) {
|
||||
return (c.getClassLoader().getReference().equals(ClassLoaderReference.Application));
|
||||
}
|
||||
};
|
||||
return pruneGraph(g, f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that the command-line arguments obey the expected usage.
|
||||
*
|
||||
* Usage: args[0] : "-classpath" args[1] : String, a ";"-delimited class path
|
||||
*
|
||||
* @throws UnsupportedOperationException if command-line is malformed.
|
||||
*/
|
||||
public static void validateCommandLine(String[] args) {
|
||||
if (args.length < 2) {
|
||||
throw new UnsupportedOperationException("must have at least 2 command-line arguments");
|
||||
}
|
||||
if (!args[0].equals("-classpath")) {
|
||||
throw new UnsupportedOperationException("invalid command-line, args[0] should be -classpath, but is " + args[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a view of an {@link IClassHierarchy} as a {@link Graph}, with edges from classes to immediate subtypes
|
||||
*/
|
||||
public static Graph<IClass> typeHierarchy2Graph(IClassHierarchy cha) throws WalaException {
|
||||
Graph<IClass> result = SlowSparseNumberedGraph.make();
|
||||
for (IClass c : cha) {
|
||||
result.addNode(c);
|
||||
}
|
||||
for (IClass c : cha) {
|
||||
for (IClass x : cha.getImmediateSubclasses(c)) {
|
||||
result.addEdge(c, x);
|
||||
}
|
||||
if (c.isInterface()) {
|
||||
for (IClass x : cha.getImplementors(c.getReference())) {
|
||||
result.addEdge(c, x);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -78,8 +78,8 @@ public class PDFWalaIR {
|
|||
*/
|
||||
public static Process run(String appJar, String methodSig) throws IOException {
|
||||
try {
|
||||
if (SWTCallGraph.isDirectory(appJar)) {
|
||||
appJar = SWTCallGraph.findJarFiles(new String[] { appJar });
|
||||
if (PDFCallGraph.isDirectory(appJar)) {
|
||||
appJar = PDFCallGraph.findJarFiles(new String[] { appJar });
|
||||
}
|
||||
AnalysisScope scope = AnalysisScopeReader.makeJavaBinaryAnalysisScope(appJar, FileProvider.getFile(CallGraphTestUtil.REGRESSION_EXCLUSIONS));
|
||||
|
||||
|
@ -138,7 +138,7 @@ public class PDFWalaIR {
|
|||
* @throws UnsupportedOperationException
|
||||
* if command-line is malformed.
|
||||
*/
|
||||
static void validateCommandLine(String[] args) {
|
||||
public static void validateCommandLine(String[] args) {
|
||||
if (args.length != 4) {
|
||||
throw new UnsupportedOperationException("must have at exactly 4 command-line arguments");
|
||||
}
|
||||
|
|
|
@ -1,190 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* 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.examples.drivers;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.eclipse.jface.window.ApplicationWindow;
|
||||
|
||||
import com.ibm.wala.core.tests.callGraph.CallGraphTestUtil;
|
||||
import com.ibm.wala.examples.properties.WalaExamplesProperties;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraphStats;
|
||||
import com.ibm.wala.ipa.callgraph.Entrypoint;
|
||||
import com.ibm.wala.ipa.callgraph.impl.Util;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.properties.WalaProperties;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.config.AnalysisScopeReader;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.graph.GraphIntegrity;
|
||||
import com.ibm.wala.util.graph.InferGraphRoots;
|
||||
import com.ibm.wala.util.io.CommandLine;
|
||||
import com.ibm.wala.util.io.FileProvider;
|
||||
import com.ibm.wala.util.io.FileUtil;
|
||||
import com.ibm.wala.util.warnings.WalaException;
|
||||
import com.ibm.wala.viz.SWTTreeViewer;
|
||||
import com.ibm.wala.viz.ViewIRAction;
|
||||
|
||||
/**
|
||||
*
|
||||
* This application is a WALA client: it invokes an SWT TreeViewer to visualize
|
||||
* a Call Graph
|
||||
*
|
||||
* @author sfink
|
||||
*/
|
||||
public class SWTCallGraph {
|
||||
|
||||
private final static boolean CHECK_GRAPH = false;
|
||||
|
||||
/**
|
||||
* Usage: SWTCallGraph -appJar [jar file name]
|
||||
*
|
||||
* The "jar file name" should be something like
|
||||
* "c:/temp/testdata/java_cup.jar"
|
||||
*
|
||||
* If it's a directory, then we'll try to find all jar files under that
|
||||
* directory.
|
||||
*
|
||||
* @param args
|
||||
* @throws WalaException
|
||||
*/
|
||||
public static void main(String[] args) throws WalaException {
|
||||
Properties p = CommandLine.parse(args);
|
||||
PDFCallGraph.validateCommandLine(p);
|
||||
run(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param p
|
||||
* should contain at least the following properties:
|
||||
* <ul>
|
||||
* <li>appJar should be something like
|
||||
* "c:/temp/testdata/java_cup.jar"
|
||||
* <li>algorithm (optional) can be one of:
|
||||
* <ul>
|
||||
* <li> "ZERO_CFA" (default value)
|
||||
* <li> "RTA"
|
||||
* </ul>
|
||||
* </ul>
|
||||
*
|
||||
* @throws WalaException
|
||||
*/
|
||||
public static ApplicationWindow run(Properties p) throws WalaException {
|
||||
|
||||
try {
|
||||
String appJar = p.getProperty("appJar");
|
||||
if (isDirectory(appJar)) {
|
||||
appJar = SWTCallGraph.findJarFiles(new String[] { appJar });
|
||||
}
|
||||
|
||||
String exclusionFile = p.getProperty("exclusions");
|
||||
|
||||
AnalysisScope scope = AnalysisScopeReader.makeJavaBinaryAnalysisScope(appJar, exclusionFile != null ? new File(exclusionFile)
|
||||
: FileProvider.getFile(CallGraphTestUtil.REGRESSION_EXCLUSIONS));
|
||||
|
||||
ClassHierarchy cha = ClassHierarchy.make(scope);
|
||||
|
||||
Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha);
|
||||
AnalysisOptions options = new AnalysisOptions(scope, entrypoints);
|
||||
|
||||
// //
|
||||
// build the call graph
|
||||
// //
|
||||
com.ibm.wala.ipa.callgraph.CallGraphBuilder builder = Util.makeZeroCFABuilder(options, new AnalysisCache(), cha, scope, null,
|
||||
null);
|
||||
CallGraph cg = builder.makeCallGraph(options,null);
|
||||
|
||||
System.out.println(CallGraphStats.getStats(cg));
|
||||
|
||||
if (CHECK_GRAPH) {
|
||||
GraphIntegrity.check(cg);
|
||||
}
|
||||
|
||||
Properties wp = null;
|
||||
try {
|
||||
wp = WalaProperties.loadProperties();
|
||||
wp.putAll(WalaExamplesProperties.loadProperties());
|
||||
} catch (WalaException e) {
|
||||
e.printStackTrace();
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
String psFile = wp.getProperty(WalaProperties.OUTPUT_DIR) + File.separatorChar + PDFWalaIR.PDF_FILE;
|
||||
String dotFile = wp.getProperty(WalaProperties.OUTPUT_DIR) + File.separatorChar + PDFTypeHierarchy.DOT_FILE;
|
||||
String dotExe = wp.getProperty(WalaExamplesProperties.DOT_EXE);
|
||||
String gvExe = wp.getProperty(WalaExamplesProperties.PDFVIEW_EXE);
|
||||
|
||||
// create and run the viewer
|
||||
final SWTTreeViewer v = new SWTTreeViewer();
|
||||
v.setGraphInput(cg);
|
||||
v.setRootsInput(InferGraphRoots.inferRoots(cg));
|
||||
v.getPopUpActions().add(new ViewIRAction(v, cg, psFile, dotFile, dotExe, gvExe));
|
||||
v.run();
|
||||
return v.getApplicationWindow();
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// private static CallGraphConstructionAlgorithm chooseAlgorithm(Properties p)
|
||||
// throws CapaException {
|
||||
// String alg = p.getProperty("algorithm", "ZERO_CFA");
|
||||
// if (alg.equals("ZERO_CFA")) {
|
||||
// return CallGraphConstructionAlgorithm.ZERO_CFA_LITERAL;
|
||||
// } else if (alg.equals("RTA")) {
|
||||
// return CallGraphConstructionAlgorithm.RTA_LITERAL;
|
||||
// } else if (alg.equals("ZERO_ONE_CFA")) {
|
||||
// return CallGraphConstructionAlgorithm.VANILLA_ZERO_ONE_CFA_LITERAL;
|
||||
// } else {
|
||||
// throw new CapaException("Unsupported algorithm: " + alg);
|
||||
// }
|
||||
// }
|
||||
|
||||
static boolean isDirectory(String appJar) {
|
||||
return (new File(appJar).isDirectory());
|
||||
}
|
||||
|
||||
public static String findJarFiles(String[] directories) throws WalaException {
|
||||
Collection<String> result = HashSetFactory.make();
|
||||
for (int i = 0; i < directories.length; i++) {
|
||||
for (Iterator<File> it = FileUtil.listFiles(directories[i], ".*\\.jar", true).iterator(); it.hasNext();) {
|
||||
File f = (File) it.next();
|
||||
result.add(f.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
return composeString(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param s
|
||||
* Collection<String>
|
||||
*/
|
||||
private static String composeString(Collection<String> s) {
|
||||
StringBuffer result = new StringBuffer();
|
||||
Iterator<String> it = s.iterator();
|
||||
for (int i = 0; i < s.size() - 1; i++) {
|
||||
result.append(it.next());
|
||||
result.append(';');
|
||||
}
|
||||
if (it.hasNext()) {
|
||||
result.append(it.next());
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
}
|
|
@ -1,101 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* 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.examples.drivers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.eclipse.jface.window.ApplicationWindow;
|
||||
|
||||
import com.ibm.wala.analysis.pointers.BasicHeapGraph;
|
||||
import com.ibm.wala.core.tests.callGraph.CallGraphTestUtil;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.Entrypoint;
|
||||
import com.ibm.wala.ipa.callgraph.impl.Util;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.util.config.AnalysisScopeReader;
|
||||
import com.ibm.wala.util.graph.Graph;
|
||||
import com.ibm.wala.util.graph.InferGraphRoots;
|
||||
import com.ibm.wala.util.io.CommandLine;
|
||||
import com.ibm.wala.util.io.FileProvider;
|
||||
import com.ibm.wala.util.warnings.WalaException;
|
||||
import com.ibm.wala.viz.SWTTreeViewer;
|
||||
|
||||
/**
|
||||
*
|
||||
* This application is a WALA client: it invokes an SWT TreeViewer to visualize
|
||||
* a Points-To solution
|
||||
*
|
||||
* @author sfink
|
||||
*/
|
||||
public class SWTPointsTo {
|
||||
|
||||
/**
|
||||
* Usage: SWTPointsTo -appJar [jar file name] The "jar file name" should be
|
||||
* something like "c:/temp/testdata/java_cup.jar"
|
||||
*
|
||||
* @param args
|
||||
* @throws WalaException
|
||||
*/
|
||||
public static void main(String[] args) throws WalaException {
|
||||
Properties p = CommandLine.parse(args);
|
||||
PDFCallGraph.validateCommandLine(p);
|
||||
run(p.getProperty("appJar"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param appJar
|
||||
* should be something like "c:/temp/testdata/java_cup.jar"
|
||||
*/
|
||||
public static ApplicationWindow run(String appJar) {
|
||||
|
||||
try {
|
||||
Graph<Object> g = buildPointsTo(appJar);
|
||||
|
||||
// create and run the viewer
|
||||
final SWTTreeViewer v = new SWTTreeViewer();
|
||||
v.setGraphInput(g);
|
||||
v.setRootsInput(InferGraphRoots.inferRoots(g));
|
||||
v.run();
|
||||
return v.getApplicationWindow();
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Graph<Object> buildPointsTo(String appJar) throws WalaException, IllegalArgumentException, CancelException, IOException {
|
||||
AnalysisScope scope = AnalysisScopeReader.makeJavaBinaryAnalysisScope(appJar, FileProvider.getFile(CallGraphTestUtil.REGRESSION_EXCLUSIONS));
|
||||
|
||||
|
||||
ClassHierarchy cha = ClassHierarchy.make(scope);
|
||||
|
||||
Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha);
|
||||
AnalysisOptions options = new AnalysisOptions(scope, entrypoints);
|
||||
|
||||
// //
|
||||
// build the call graph
|
||||
// //
|
||||
com.ibm.wala.ipa.callgraph.CallGraphBuilder builder = Util.makeVanillaZeroOneCFABuilder(options, new AnalysisCache(),cha, scope, null, null);
|
||||
CallGraph cg = builder.makeCallGraph(options,null);
|
||||
PointerAnalysis pointerAnalysis = builder.getPointerAnalysis();
|
||||
|
||||
System.err.println(pointerAnalysis);
|
||||
|
||||
return new BasicHeapGraph(pointerAnalysis, cg);
|
||||
}
|
||||
}
|
|
@ -1,140 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* 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.examples.drivers;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.eclipse.jface.viewers.TreeViewer;
|
||||
import org.eclipse.jface.window.ApplicationWindow;
|
||||
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.core.tests.callGraph.CallGraphTestUtil;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
import com.ibm.wala.util.collections.CollectionFilter;
|
||||
import com.ibm.wala.util.collections.Filter;
|
||||
import com.ibm.wala.util.config.AnalysisScopeReader;
|
||||
import com.ibm.wala.util.graph.Graph;
|
||||
import com.ibm.wala.util.graph.GraphSlicer;
|
||||
import com.ibm.wala.util.graph.InferGraphRoots;
|
||||
import com.ibm.wala.util.graph.impl.SlowSparseNumberedGraph;
|
||||
import com.ibm.wala.util.io.FileProvider;
|
||||
import com.ibm.wala.util.warnings.WalaException;
|
||||
import com.ibm.wala.viz.SWTTreeViewer;
|
||||
|
||||
/**
|
||||
* This is a simple example WALA application. It's neither efficient nor concise, but is intended to demonstrate some basic
|
||||
* framework concepts.
|
||||
*
|
||||
* This application builds a type hierarchy visualizes it with an SWT {@link TreeViewer}.
|
||||
*/
|
||||
public class SWTTypeHierarchy {
|
||||
// This example takes one command-line argument, so args[1] should be the "-classpath" parameter
|
||||
final static int CLASSPATH_INDEX = 1;
|
||||
|
||||
/**
|
||||
* Usage: SWTTypeHierarchy -classpath [classpath]
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
// check that the command-line is kosher
|
||||
validateCommandLine(args);
|
||||
run(args[CLASSPATH_INDEX]);
|
||||
}
|
||||
|
||||
public static ApplicationWindow run(String classpath) {
|
||||
|
||||
try {
|
||||
AnalysisScope scope = AnalysisScopeReader.makeJavaBinaryAnalysisScope(classpath, FileProvider
|
||||
.getFile(CallGraphTestUtil.REGRESSION_EXCLUSIONS));
|
||||
|
||||
// invoke WALA to build a class hierarchy
|
||||
ClassHierarchy cha = ClassHierarchy.make(scope);
|
||||
|
||||
Graph<IClass> g = typeHierarchy2Graph(cha);
|
||||
g = pruneForAppLoader(g);
|
||||
|
||||
// create and run the viewer
|
||||
final SWTTreeViewer v = new SWTTreeViewer();
|
||||
v.setGraphInput(g);
|
||||
Collection<IClass> roots = InferGraphRoots.inferRoots(g);
|
||||
if (roots.size() < 1) {
|
||||
System.err.println("PANIC: roots.size()=" + roots.size());
|
||||
System.exit(-1);
|
||||
}
|
||||
v.setRootsInput(roots);
|
||||
v.run();
|
||||
return v.getApplicationWindow();
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a view of an {@link IClassHierarchy} as a {@link Graph}, with edges from classes to immediate subtypes
|
||||
*/
|
||||
public static Graph<IClass> typeHierarchy2Graph(IClassHierarchy cha) throws WalaException {
|
||||
Graph<IClass> result = SlowSparseNumberedGraph.make();
|
||||
for (IClass c : cha) {
|
||||
result.addNode(c);
|
||||
}
|
||||
for (IClass c : cha) {
|
||||
for (IClass x : cha.getImmediateSubclasses(c)) {
|
||||
result.addEdge(c, x);
|
||||
}
|
||||
if (c.isInterface()) {
|
||||
for (IClass x : cha.getImplementors(c.getReference())) {
|
||||
result.addEdge(c, x);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restrict g to nodes from the Application loader
|
||||
*/
|
||||
static Graph<IClass> pruneForAppLoader(Graph<IClass> g) throws WalaException {
|
||||
Filter<IClass> f = new Filter<IClass>() {
|
||||
public boolean accepts(IClass c) {
|
||||
return (c.getClassLoader().getReference().equals(ClassLoaderReference.Application));
|
||||
}
|
||||
};
|
||||
return pruneGraph(g, f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove from a graph g any nodes that are not accepted by a {@link Filter}
|
||||
*/
|
||||
public static <T> Graph<T> pruneGraph(Graph<T> g, Filter<T> f) throws WalaException {
|
||||
Collection<T> slice = GraphSlicer.slice(g, f);
|
||||
return GraphSlicer.prune(g, new CollectionFilter<T>(slice));
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that the command-line arguments obey the expected usage.
|
||||
*
|
||||
* Usage: args[0] : "-classpath" args[1] : String, a ";"-delimited class path
|
||||
*
|
||||
* @throws UnsupportedOperationException if command-line is malformed.
|
||||
*/
|
||||
static void validateCommandLine(String[] args) {
|
||||
if (args.length < 2) {
|
||||
throw new UnsupportedOperationException("must have at least 2 command-line arguments");
|
||||
}
|
||||
if (!args[0].equals("-classpath")) {
|
||||
throw new UnsupportedOperationException("invalid command-line, args[0] should be -classpath, but is " + args[0]);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,12 +7,9 @@ Bundle-Version: 1.1.3.qualifier
|
|||
Bundle-Activator: com.ibm.wala.core.plugin.CorePlugin
|
||||
Bundle-Vendor: %providerName
|
||||
Bundle-Localization: plugin
|
||||
Require-Bundle: com.ibm.wala.shrike;visibility:=reexport,
|
||||
org.eclipse.core.resources;visibility:=reexport,
|
||||
org.eclipse.jdt.core;visibility:=reexport,
|
||||
org.eclipse.ui;visibility:=reexport,
|
||||
org.eclipse.core.runtime;visibility:=reexport,
|
||||
org.eclipse.pde.ui
|
||||
Require-Bundle: com.ibm.wala.shrike,
|
||||
org.eclipse.core.runtime,
|
||||
org.eclipse.core.resources;resolution:=optional
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Export-Package: .,
|
||||
com.ibm.wala.analysis.pointers,
|
||||
|
@ -34,8 +31,6 @@ Export-Package: .,
|
|||
com.ibm.wala.demandpa.genericutil,
|
||||
com.ibm.wala.demandpa.util,
|
||||
com.ibm.wala.dynamic,
|
||||
com.ibm.wala.eclipse,
|
||||
com.ibm.wala.eclipse.util,
|
||||
com.ibm.wala.escape,
|
||||
com.ibm.wala.fixedpoint.impl,
|
||||
com.ibm.wala.fixpoint,
|
||||
|
|
|
@ -19,8 +19,6 @@ import com.ibm.wala.dataflow.graph.BasicFramework;
|
|||
import com.ibm.wala.dataflow.graph.DataflowSolver;
|
||||
import com.ibm.wala.dataflow.graph.IKilldallFramework;
|
||||
import com.ibm.wala.dataflow.graph.ITransferFunctionProvider;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.eclipse.util.CancelRuntimeException;
|
||||
import com.ibm.wala.fixedpoint.impl.AbstractStatement;
|
||||
import com.ibm.wala.fixedpoint.impl.AbstractVariable;
|
||||
import com.ibm.wala.fixedpoint.impl.UnaryOperator;
|
||||
|
@ -54,6 +52,8 @@ import com.ibm.wala.shrikeBT.ThrowInstruction;
|
|||
import com.ibm.wala.shrikeBT.Util;
|
||||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.CancelRuntimeException;
|
||||
import com.ibm.wala.util.shrike.ShrikeUtil;
|
||||
|
||||
/**
|
||||
|
|
|
@ -19,8 +19,6 @@ import com.ibm.wala.classLoader.IClass;
|
|||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.classLoader.Language;
|
||||
import com.ibm.wala.dataflow.ssa.SSAInference;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.eclipse.util.CancelRuntimeException;
|
||||
import com.ibm.wala.fixedpoint.impl.AbstractOperator;
|
||||
import com.ibm.wala.fixedpoint.impl.NullaryOperator;
|
||||
import com.ibm.wala.fixpoint.FixedPointConstants;
|
||||
|
@ -52,6 +50,8 @@ import com.ibm.wala.ssa.SSAUnaryOpInstruction;
|
|||
import com.ibm.wala.ssa.SymbolTable;
|
||||
import com.ibm.wala.ssa.SSACFG.ExceptionHandlerBasicBlock;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.CancelRuntimeException;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007 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.classLoader;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IWorkspace;
|
||||
import org.eclipse.core.resources.IWorkspaceRoot;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
|
||||
import com.ibm.wala.eclipse.util.EclipseProjectPath;
|
||||
|
||||
public class EclipseSourceDirectoryTreeModule extends SourceDirectoryTreeModule {
|
||||
|
||||
private final IPath rootIPath;
|
||||
|
||||
public EclipseSourceDirectoryTreeModule(IPath root) {
|
||||
super(EclipseProjectPath.makeAbsolute(root).toFile());
|
||||
this.rootIPath = root;
|
||||
}
|
||||
|
||||
public EclipseSourceDirectoryTreeModule(IPath root, String fileExt) {
|
||||
super(EclipseProjectPath.makeAbsolute(root).toFile(), fileExt);
|
||||
this.rootIPath = root;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FileModule makeFile(File file) {
|
||||
IPath p = rootIPath.append(file.getPath().substring(root.getPath().length()));
|
||||
IWorkspace ws = ResourcesPlugin.getWorkspace();
|
||||
IWorkspaceRoot root = ws.getRoot();
|
||||
IFile ifile = root.getFile(p);
|
||||
assert ifile.exists();
|
||||
return EclipseSourceFileModule.createEclipseSourceFileModule(ifile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "EclipseSourceDirectoryTreeModule:" + rootIPath;
|
||||
}
|
||||
|
||||
}
|
|
@ -23,7 +23,6 @@ import com.ibm.wala.classLoader.ClassLoaderFactory;
|
|||
import com.ibm.wala.classLoader.ClassLoaderFactoryImpl;
|
||||
import com.ibm.wala.classLoader.JarFileModule;
|
||||
import com.ibm.wala.classLoader.Module;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
|
@ -37,6 +36,7 @@ import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
|||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.ssa.DefaultIRFactory;
|
||||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.config.AnalysisScopeReader;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.io.FileProvider;
|
||||
|
|
|
@ -10,15 +10,52 @@
|
|||
*******************************************************************************/
|
||||
package com.ibm.wala.core.plugin;
|
||||
|
||||
import org.eclipse.core.runtime.Plugin;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.core.runtime.Plugin;
|
||||
|
||||
|
||||
/**
|
||||
* The main plugin class to be used in the desktop.
|
||||
*/
|
||||
public class CorePlugin extends Plugin {
|
||||
|
||||
public static final boolean IS_ECLIPSE_RUNNING;
|
||||
static
|
||||
{
|
||||
boolean result = false;
|
||||
try
|
||||
{
|
||||
result = Platform.isRunning();
|
||||
}
|
||||
catch (Throwable exception)
|
||||
{
|
||||
// Assume that we aren't running.
|
||||
}
|
||||
IS_ECLIPSE_RUNNING = result;
|
||||
}
|
||||
|
||||
public static final boolean IS_RESOURCES_BUNDLE_AVAILABLE;
|
||||
static
|
||||
{
|
||||
boolean result = false;
|
||||
if (IS_ECLIPSE_RUNNING)
|
||||
{
|
||||
try
|
||||
{
|
||||
Bundle resourcesBundle = Platform.getBundle("org.eclipse.core.resources");
|
||||
result = resourcesBundle != null && (resourcesBundle.getState() & (Bundle.ACTIVE | Bundle.STARTING | Bundle.RESOLVED)) != 0;
|
||||
}
|
||||
catch (Throwable exception)
|
||||
{
|
||||
// Assume that it's not available.
|
||||
}
|
||||
}
|
||||
IS_RESOURCES_BUNDLE_AVAILABLE = result;
|
||||
}
|
||||
|
||||
// The shared instance.
|
||||
private static CorePlugin plugin;
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
package com.ibm.wala.dataflow.IFDS;
|
||||
|
||||
import com.ibm.wala.dataflow.IFDS.TabulationSolver.Result;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
|
||||
/**
|
||||
* A {@link CancelException} thrown during tabulation; holds a pointer to a partial {@link Result}. Use with care, this can hold on
|
||||
|
|
|
@ -23,9 +23,9 @@ import java.util.Map.Entry;
|
|||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
|
||||
import com.ibm.wala.cfg.IBasicBlock;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.eclipse.util.CancelRuntimeException;
|
||||
import com.ibm.wala.eclipse.util.MonitorUtil;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.CancelRuntimeException;
|
||||
import com.ibm.wala.util.MonitorUtil;
|
||||
import com.ibm.wala.util.collections.HashMapFactory;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.collections.Heap;
|
||||
|
|
|
@ -1,212 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* 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.eclipse;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.runtime.jobs.Job;
|
||||
import org.eclipse.jdt.core.IJavaElement;
|
||||
import org.eclipse.jdt.core.IJavaProject;
|
||||
import org.eclipse.jface.action.IAction;
|
||||
import org.eclipse.jface.operation.IRunnableWithProgress;
|
||||
import org.eclipse.jface.viewers.ISelection;
|
||||
import org.eclipse.jface.viewers.IStructuredSelection;
|
||||
import org.eclipse.ui.IObjectActionDelegate;
|
||||
import org.eclipse.ui.IWorkbenchPart;
|
||||
import org.eclipse.ui.PlatformUI;
|
||||
import org.eclipse.ui.progress.IProgressService;
|
||||
|
||||
import com.ibm.wala.classLoader.Module;
|
||||
import com.ibm.wala.eclipse.util.EclipseProjectPath;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
/**
|
||||
* An Eclipse action that analyzes a Java selection
|
||||
*/
|
||||
public abstract class AbstractJavaAnalysisAction implements IObjectActionDelegate, IRunnableWithProgress {
|
||||
|
||||
/**
|
||||
* The current {@link ISelection} highlighted in the Eclipse workspace
|
||||
*/
|
||||
private ISelection currentSelection;
|
||||
|
||||
public AbstractJavaAnalysisAction() {
|
||||
super();
|
||||
}
|
||||
|
||||
/*
|
||||
* @see IObjectActionDelegate#setActivePart(IAction, IWorkbenchPart)
|
||||
*/
|
||||
public void setActivePart(IAction action, IWorkbenchPart targetPart) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute an analysis scope for the current selection
|
||||
*/
|
||||
public static AnalysisScope computeScope(IStructuredSelection selection) throws IOException {
|
||||
return computeScope(selection, false, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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?
|
||||
*/
|
||||
public static AnalysisScope computeScope(final IStructuredSelection selection, final boolean includeSource,
|
||||
final boolean includeClassFiles) throws IOException {
|
||||
if (selection == null) {
|
||||
throw new IllegalArgumentException("null selection");
|
||||
}
|
||||
final Collection<EclipseProjectPath> projectPaths = new LinkedList<EclipseProjectPath>();
|
||||
Job job = new Job("Compute project paths") {
|
||||
|
||||
@Override
|
||||
protected IStatus run(IProgressMonitor monitor) {
|
||||
for (Iterator it = selection.iterator(); it.hasNext();) {
|
||||
Object object = it.next();
|
||||
if (object instanceof IJavaElement) {
|
||||
IJavaElement e = (IJavaElement) object;
|
||||
IJavaProject jp = e.getJavaProject();
|
||||
try {
|
||||
projectPaths.add(EclipseProjectPath.make(jp, includeSource, includeClassFiles));
|
||||
} catch (CoreException e1) {
|
||||
e1.printStackTrace();
|
||||
// skip and continue
|
||||
} catch (IOException e2) {
|
||||
e2.printStackTrace();
|
||||
return new Status(IStatus.ERROR, "", "", e2);
|
||||
}
|
||||
} else {
|
||||
Assertions.UNREACHABLE(object.getClass());
|
||||
}
|
||||
}
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
|
||||
};
|
||||
// lock the whole workspace
|
||||
job.setRule(ResourcesPlugin.getWorkspace().getRoot());
|
||||
job.schedule();
|
||||
try {
|
||||
job.join();
|
||||
IStatus result = job.getResult();
|
||||
if (result.getSeverity() == IStatus.ERROR) {
|
||||
Throwable exception = result.getException();
|
||||
if (exception instanceof IOException) {
|
||||
throw (IOException)exception;
|
||||
} else if (exception instanceof RuntimeException) {
|
||||
throw (RuntimeException)exception;
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
assert false;
|
||||
}
|
||||
AnalysisScope scope = mergeProjectPaths(projectPaths);
|
||||
return scope;
|
||||
}
|
||||
|
||||
/**
|
||||
* compute the java projects represented by the current selection
|
||||
*/
|
||||
protected Collection<IJavaProject> computeJavaProjects() {
|
||||
IStructuredSelection selection = (IStructuredSelection) currentSelection;
|
||||
Collection<IJavaProject> projects = HashSetFactory.make();
|
||||
for (Iterator it = selection.iterator(); it.hasNext();) {
|
||||
Object object = it.next();
|
||||
if (object instanceof IJavaElement) {
|
||||
IJavaElement e = (IJavaElement) object;
|
||||
IJavaProject jp = e.getJavaProject();
|
||||
projects.add(jp);
|
||||
} else {
|
||||
Assertions.UNREACHABLE(object.getClass());
|
||||
}
|
||||
}
|
||||
return projects;
|
||||
}
|
||||
|
||||
/**
|
||||
* create an analysis scope as the union of a bunch of EclipseProjectPath
|
||||
*/
|
||||
private static AnalysisScope mergeProjectPaths(Collection<EclipseProjectPath> projectPaths) throws IOException {
|
||||
AnalysisScope scope = AnalysisScope.createJavaAnalysisScope();
|
||||
|
||||
Collection<Module> seen = HashSetFactory.make();
|
||||
// to avoid duplicates, we first add all application modules, then extension
|
||||
// modules, then primordial
|
||||
buildScope(ClassLoaderReference.Application, projectPaths, scope, seen);
|
||||
buildScope(ClassLoaderReference.Extension, projectPaths, scope, seen);
|
||||
buildScope(ClassLoaderReference.Primordial, projectPaths, scope, seen);
|
||||
return scope;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enhance an {@link AnalysisScope} to include in a particular loader, elements from a set of Eclipse projects
|
||||
* @param loader the class loader in which new {@link Module}s will live
|
||||
* @param projectPaths Eclipse project paths to add to the analysis scope
|
||||
* @param scope the {@link AnalysisScope} under construction. This will be mutated.
|
||||
* @param seen set of {@link Module}s which have already been seen, and should not be added to the analysis scope
|
||||
*/
|
||||
private static void buildScope(ClassLoaderReference loader, Collection<EclipseProjectPath> projectPaths, AnalysisScope scope,
|
||||
Collection<Module> seen) throws IOException {
|
||||
for (EclipseProjectPath path : projectPaths) {
|
||||
AnalysisScope pScope = path.toAnalysisScope((File) null);
|
||||
for (Module m : pScope.getModules(loader)) {
|
||||
if (!seen.contains(m)) {
|
||||
seen.add(m);
|
||||
scope.addToScope(loader, m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @see IActionDelegate#run(IAction)
|
||||
*/
|
||||
public void run(IAction action) {
|
||||
IProgressService progressService = PlatformUI.getWorkbench().getProgressService();
|
||||
try {
|
||||
progressService.busyCursorWhile(this);
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* @see IActionDelegate#selectionChanged(IAction, ISelection)
|
||||
*/
|
||||
public void selectionChanged(IAction action, ISelection selection) {
|
||||
currentSelection = selection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The current {@link ISelection} highlighted in the Eclipse workspace
|
||||
*/
|
||||
public ISelection getCurrentSelection() {
|
||||
return currentSelection;
|
||||
}
|
||||
}
|
|
@ -1,408 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007 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.eclipse.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.zip.ZipException;
|
||||
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.resources.IWorkspace;
|
||||
import org.eclipse.core.resources.IWorkspaceRoot;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.jdt.core.IClasspathContainer;
|
||||
import org.eclipse.jdt.core.IClasspathEntry;
|
||||
import org.eclipse.jdt.core.IJavaProject;
|
||||
import org.eclipse.jdt.core.JavaCore;
|
||||
import org.eclipse.jdt.core.JavaModelException;
|
||||
import org.eclipse.osgi.service.resolver.BundleDescription;
|
||||
import org.eclipse.pde.core.plugin.IPluginModelBase;
|
||||
import org.eclipse.pde.internal.core.ClasspathUtilCore;
|
||||
import org.eclipse.pde.internal.core.PDECore;
|
||||
import org.eclipse.pde.internal.core.PDEStateHelper;
|
||||
|
||||
import com.ibm.wala.classLoader.BinaryDirectoryTreeModule;
|
||||
import com.ibm.wala.classLoader.EclipseSourceDirectoryTreeModule;
|
||||
import com.ibm.wala.classLoader.JarFileModule;
|
||||
import com.ibm.wala.classLoader.Module;
|
||||
import com.ibm.wala.client.AbstractAnalysisEngine;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.collections.MapUtil;
|
||||
import com.ibm.wala.util.config.AnalysisScopeReader;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
/**
|
||||
* Representation of an analysis scope from an Eclipse project.
|
||||
*
|
||||
* 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>System libraries are in the primordial loader.
|
||||
* <li>Source modules go in a special Source loader.
|
||||
* </ul>
|
||||
*/
|
||||
@SuppressWarnings("restriction")
|
||||
public class EclipseProjectPath {
|
||||
|
||||
/**
|
||||
* Eclipse projects are modelled with 3 loaders, as described above.
|
||||
*/
|
||||
public enum Loader {
|
||||
APPLICATION(ClassLoaderReference.Application), EXTENSION(ClassLoaderReference.Extension), PRIMORDIAL(
|
||||
ClassLoaderReference.Primordial);
|
||||
|
||||
private ClassLoaderReference ref;
|
||||
|
||||
Loader(ClassLoaderReference ref) {
|
||||
this.ref = ref;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The project whose path this object represents
|
||||
*/
|
||||
private final IJavaProject project;
|
||||
|
||||
/**
|
||||
* names of OSGi bundles already processed.
|
||||
*/
|
||||
private final Set<String> bundlesProcessed = HashSetFactory.make();
|
||||
|
||||
// SJF: Intentionally do not use HashMapFactory, since the Loader keys in the following must use
|
||||
// identityHashCode. TODO: fix this source of non-determinism?
|
||||
private final Map<Loader, List<Module>> modules = new HashMap<Loader, List<Module>>();
|
||||
|
||||
/**
|
||||
* Classpath entries that have already been resolved and added to the scope.
|
||||
*/
|
||||
private final Collection<IClasspathEntry> alreadyResolved = HashSetFactory.make();
|
||||
|
||||
/**
|
||||
* Should the analysis scope include source files
|
||||
*/
|
||||
private final boolean includeSource;
|
||||
|
||||
/**
|
||||
* 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,
|
||||
CoreException {
|
||||
if (project == null) {
|
||||
throw new IllegalArgumentException("null project");
|
||||
}
|
||||
this.includeSource = includeSource;
|
||||
this.includeClassFiles = includeClassFiles;
|
||||
this.project = project;
|
||||
assert project != null;
|
||||
for (Loader loader : Loader.values()) {
|
||||
MapUtil.findOrCreateList(modules, loader);
|
||||
}
|
||||
resolveProjectClasspathEntries(includeSource);
|
||||
if (isPluginProject(project)) {
|
||||
resolvePluginClassPath(project.getProject(), includeSource);
|
||||
}
|
||||
}
|
||||
|
||||
public static EclipseProjectPath make(IJavaProject project) throws IOException, CoreException {
|
||||
return make(project, false, true);
|
||||
}
|
||||
|
||||
public static EclipseProjectPath make(IJavaProject project, boolean includeSource, boolean includeClassFiles) throws IOException,
|
||||
CoreException {
|
||||
return new EclipseProjectPath(project, includeSource, includeClassFiles);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
IClasspathEntry e = JavaCore.getResolvedClasspathEntry(entry);
|
||||
if (alreadyResolved.contains(e)) {
|
||||
return;
|
||||
} else {
|
||||
alreadyResolved.add(e);
|
||||
}
|
||||
|
||||
if (e.getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
|
||||
IClasspathContainer cont = JavaCore.getClasspathContainer(entry.getPath(), project);
|
||||
IClasspathEntry[] entries = cont.getClasspathEntries();
|
||||
resolveClasspathEntries(entries, cont.getKind() == IClasspathContainer.K_APPLICATION ? loader : Loader.PRIMORDIAL,
|
||||
includeSource);
|
||||
} else if (e.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
|
||||
File file = makeAbsolute(e.getPath()).toFile();
|
||||
JarFile j;
|
||||
try {
|
||||
j = new JarFile(file);
|
||||
} catch (ZipException z) {
|
||||
// a corrupted file. ignore it.
|
||||
return;
|
||||
} catch (FileNotFoundException z) {
|
||||
// should ignore directories as well..
|
||||
return;
|
||||
}
|
||||
if (isPrimordialJarFile(j)) {
|
||||
List<Module> s = MapUtil.findOrCreateList(modules, loader);
|
||||
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) {
|
||||
s.add(new EclipseSourceDirectoryTreeModule(e.getPath()));
|
||||
}
|
||||
if (e.getOutputLocation() != null) {
|
||||
File output = makeAbsolute(e.getOutputLocation()).toFile();
|
||||
s = MapUtil.findOrCreateList(modules, loader);
|
||||
s.add(new BinaryDirectoryTreeModule(output));
|
||||
}
|
||||
} else if (e.getEntryKind() == IClasspathEntry.CPE_PROJECT) {
|
||||
IPath projectPath = makeAbsolute(e.getPath());
|
||||
IWorkspace ws = ResourcesPlugin.getWorkspace();
|
||||
IWorkspaceRoot root = ws.getRoot();
|
||||
IProject project = (IProject) root.getContainerForLocation(projectPath);
|
||||
try {
|
||||
if (project.hasNature(JavaCore.NATURE_ID)) {
|
||||
IJavaProject javaProject = JavaCore.create(project);
|
||||
if (isPluginProject(javaProject)) {
|
||||
resolvePluginClassPath(javaProject.getProject(), includeSource);
|
||||
}
|
||||
resolveClasspathEntries(javaProject.getRawClasspath(), loader, includeSource);
|
||||
File output = makeAbsolute(javaProject.getOutputLocation()).toFile();
|
||||
List<Module> s = MapUtil.findOrCreateList(modules, loader);
|
||||
s.add(new BinaryDirectoryTreeModule(output));
|
||||
}
|
||||
} catch (CoreException e1) {
|
||||
e1.printStackTrace();
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("unexpected entry " + e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* traverse the bundle description for an Eclipse project and populate the analysis scope accordingly
|
||||
*/
|
||||
private void resolvePluginClassPath(IProject p, boolean includeSource) throws CoreException, IOException {
|
||||
IPluginModelBase model = findModel(p);
|
||||
if (!model.isInSync() || model.isDisposed()) {
|
||||
model.load();
|
||||
}
|
||||
BundleDescription bd = model.getBundleDescription();
|
||||
|
||||
if (bd == null) {
|
||||
// temporary debugging code; remove once we figure out what the heck is going on here --MS
|
||||
System.err.println("model.isDisposed(): " + model.isDisposed());
|
||||
System.err.println("model.isInSync(): " + model.isInSync());
|
||||
System.err.println("model.isEnabled(): " + model.isEnabled());
|
||||
System.err.println("model.isLoaded(): " + model.isLoaded());
|
||||
System.err.println("model.isValid(): " + model.isValid());
|
||||
}
|
||||
for (int i = 0; i < 3 && bd == null; i++) {
|
||||
// Uh oh. bd is null. Go to sleep, cross your fingers, and try again.
|
||||
// This is horrible. We can't figure out the race condition yet which causes this to happen.
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
} catch (InterruptedException e) {
|
||||
// whatever.
|
||||
}
|
||||
bd = findModel(p).getBundleDescription();
|
||||
}
|
||||
|
||||
if (bd == null) {
|
||||
throw new IllegalStateException("bundle description was null for " + p);
|
||||
}
|
||||
resolveBundleDescriptionClassPath(bd, Loader.APPLICATION, includeSource);
|
||||
}
|
||||
|
||||
/**
|
||||
* traverse a bundle description and populate the analysis scope accordingly
|
||||
*/
|
||||
private void resolveBundleDescriptionClassPath(BundleDescription bd, Loader loader, boolean includeSource) throws CoreException,
|
||||
IOException {
|
||||
assert bd != null;
|
||||
if (alreadyProcessed(bd)) {
|
||||
return;
|
||||
}
|
||||
bundlesProcessed.add(bd.getName());
|
||||
|
||||
// handle the classpath entries for bd
|
||||
ArrayList l = new ArrayList();
|
||||
ClasspathUtilCore.addLibraries(findModel(bd), l);
|
||||
IClasspathEntry[] entries = new IClasspathEntry[l.size()];
|
||||
int i = 0;
|
||||
for (Object o : l) {
|
||||
IClasspathEntry e = (IClasspathEntry) o;
|
||||
entries[i++] = e;
|
||||
}
|
||||
resolveClasspathEntries(entries, loader, includeSource);
|
||||
|
||||
// recurse to handle dependencies. put these in the Extension loader
|
||||
for (BundleDescription b : PDEStateHelper.getImportedBundles(bd)) {
|
||||
resolveBundleDescriptionClassPath(b, Loader.EXTENSION, includeSource);
|
||||
}
|
||||
for (BundleDescription b : bd.getResolvedRequires()) {
|
||||
resolveBundleDescriptionClassPath(b, Loader.EXTENSION, includeSource);
|
||||
}
|
||||
for (BundleDescription b : bd.getFragments()) {
|
||||
resolveBundleDescriptionClassPath(b, Loader.EXTENSION, includeSource);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* have we already processed a particular bundle description?
|
||||
*/
|
||||
private boolean alreadyProcessed(BundleDescription bd) {
|
||||
return bundlesProcessed.contains(bd.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Is javaProject a plugin project?
|
||||
*/
|
||||
private boolean isPluginProject(IJavaProject javaProject) {
|
||||
IPluginModelBase model = findModel(javaProject.getProject());
|
||||
if (model == null) {
|
||||
return false;
|
||||
}
|
||||
if (model.getPluginBase().getId() == null) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the given jar file should be handled by the Primordial loader. If false, other provisions should be made to add
|
||||
* the jar file to the appropriate component of the AnalysisScope. Subclasses can override this method.
|
||||
*/
|
||||
protected boolean isPrimordialJarFile(JarFile j) {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void resolveClasspathEntries(IClasspathEntry[] entries, Loader loader, boolean includeSource)
|
||||
throws JavaModelException, IOException {
|
||||
for (int i = 0; i < entries.length; i++) {
|
||||
resolveClasspathEntry(entries[i], loader, includeSource);
|
||||
}
|
||||
}
|
||||
|
||||
public static IPath makeAbsolute(IPath p) {
|
||||
IPath absolutePath = p;
|
||||
if (p.toFile().exists()) {
|
||||
return p;
|
||||
}
|
||||
|
||||
IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(p);
|
||||
if (resource != null && resource.exists()) {
|
||||
absolutePath = resource.getLocation();
|
||||
}
|
||||
return absolutePath;
|
||||
}
|
||||
|
||||
private void resolveProjectClasspathEntries(boolean includeSource) throws JavaModelException, IOException {
|
||||
resolveClasspathEntries(project.getRawClasspath(), Loader.EXTENSION, includeSource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert this path to a WALA analysis scope
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public AnalysisScope toAnalysisScope(ClassLoader classLoader, File exclusionsFile) throws IOException {
|
||||
AnalysisScope scope = AnalysisScopeReader.readJavaScope(AbstractAnalysisEngine.SYNTHETIC_J2SE_MODEL, exclusionsFile,
|
||||
classLoader);
|
||||
return toAnalysisScope(scope);
|
||||
}
|
||||
|
||||
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)) {
|
||||
scope.addToScope(loader.ref, m);
|
||||
}
|
||||
}
|
||||
return scope;
|
||||
} catch (JavaModelException e) {
|
||||
e.printStackTrace();
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public AnalysisScope toAnalysisScope(final File exclusionsFile) throws IOException {
|
||||
return toAnalysisScope(getClass().getClassLoader(), exclusionsFile);
|
||||
}
|
||||
|
||||
public AnalysisScope toAnalysisScope() throws IOException {
|
||||
return toAnalysisScope(getClass().getClassLoader(), null);
|
||||
}
|
||||
|
||||
public Collection<Module> getModules(Loader loader, boolean binary) {
|
||||
return Collections.unmodifiableCollection(modules.get(loader));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
try {
|
||||
return toAnalysisScope((File) null).toString();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return "Error in toString()";
|
||||
}
|
||||
}
|
||||
|
||||
private IPluginModelBase findModel(IProject p) {
|
||||
// PluginRegistry is specific to Eclipse 3.3+. Use PDECore for compatibility with 3.2
|
||||
// return PluginRegistry.findModel(p);
|
||||
return PDECore.getDefault().getModelManager().findModel(p);
|
||||
}
|
||||
|
||||
private IPluginModelBase findModel(BundleDescription bd) {
|
||||
// PluginRegistry is specific to Eclipse 3.3+. Use PDECore for compatibility with 3.2
|
||||
// return PluginRegistry.findModel(bd);
|
||||
return PDECore.getDefault().getModelManager().findModel(bd);
|
||||
}
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007 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.eclipse.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IWorkspaceRoot;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.jdt.core.IJavaProject;
|
||||
import org.eclipse.jdt.core.JavaCore;
|
||||
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.io.CommandLine;
|
||||
|
||||
public class HeadlessUtil {
|
||||
|
||||
/**
|
||||
* create a Properties object representing the properties set by the command
|
||||
* line args. if args[i] is "-foo" and args[i+1] is "bar", then the result
|
||||
* will define a property with key "foo" and value "bar"
|
||||
*/
|
||||
public static Properties parseCommandLine(String[] cmdLine) {
|
||||
if (cmdLine == null) {
|
||||
throw new IllegalArgumentException("null cmdLine");
|
||||
}
|
||||
if (cmdLine.length == 0) {
|
||||
throw new IllegalArgumentException("cmdLine must have at least one parameter");
|
||||
}
|
||||
Properties p = null;
|
||||
assert cmdLine[0].equals("-pdelaunch");
|
||||
String[] x = new String[cmdLine.length - 1];
|
||||
System.arraycopy(cmdLine, 1, x, 0, x.length);
|
||||
try {
|
||||
p = CommandLine.parse(x);
|
||||
} catch (IllegalArgumentException e) {
|
||||
e.printStackTrace();
|
||||
System.err.println("Length " + x.length);
|
||||
for (String s : x) {
|
||||
System.err.println(s);
|
||||
}
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* compute the analysis scope for a project in the current workspace
|
||||
* @throws IOException
|
||||
* @throws CoreException
|
||||
*/
|
||||
public static AnalysisScope computeScope(String projectName) throws IOException, CoreException {
|
||||
if (projectName == null) {
|
||||
throw new IllegalArgumentException("null projectName");
|
||||
}
|
||||
IJavaProject jp = getProjectFromWorkspace(projectName);
|
||||
EclipseProjectPath path = EclipseProjectPath.make(jp);
|
||||
return path.toAnalysisScope((File)null);
|
||||
}
|
||||
|
||||
private static IJavaProject getProjectFromWorkspace(String projectName) {
|
||||
IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
|
||||
IPath workspaceRootPath = workspaceRoot.getLocation();
|
||||
System.out.println("workspace: " + workspaceRootPath.toOSString());
|
||||
|
||||
for (IProject p : workspaceRoot.getProjects()) {
|
||||
try {
|
||||
if (p.hasNature(JavaCore.NATURE_ID)) {
|
||||
IJavaProject jp = JavaCore.create(p);
|
||||
if (jp != null && jp.getElementName().equals(projectName)) {
|
||||
return jp;
|
||||
}
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
// do nothing and continue
|
||||
}
|
||||
}
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,568 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* 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.eclipse.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.resources.IWorkspaceRoot;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.jdt.core.ICompilationUnit;
|
||||
import org.eclipse.jdt.core.IJavaElement;
|
||||
import org.eclipse.jdt.core.IJavaModel;
|
||||
import org.eclipse.jdt.core.IJavaProject;
|
||||
import org.eclipse.jdt.core.IMethod;
|
||||
import org.eclipse.jdt.core.IPackageDeclaration;
|
||||
import org.eclipse.jdt.core.IType;
|
||||
import org.eclipse.jdt.core.ITypeParameter;
|
||||
import org.eclipse.jdt.core.JavaCore;
|
||||
import org.eclipse.jdt.core.JavaModelException;
|
||||
import org.eclipse.jdt.core.Signature;
|
||||
import org.eclipse.jdt.core.search.IJavaSearchConstants;
|
||||
import org.eclipse.jdt.core.search.IJavaSearchScope;
|
||||
import org.eclipse.jdt.core.search.SearchEngine;
|
||||
import org.eclipse.jdt.core.search.SearchMatch;
|
||||
import org.eclipse.jdt.core.search.SearchParticipant;
|
||||
import org.eclipse.jdt.core.search.SearchPattern;
|
||||
import org.eclipse.jdt.core.search.SearchRequestor;
|
||||
import org.eclipse.jface.viewers.StructuredSelection;
|
||||
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
|
||||
/**
|
||||
* Convenience methods to get information from JDT {@link IJavaElement} model.
|
||||
*/
|
||||
public class JdtUtil {
|
||||
|
||||
public static String getFilePath(IJavaElement javaElt) {
|
||||
if (javaElt == null) {
|
||||
throw new IllegalArgumentException("javaElt is null");
|
||||
}
|
||||
try {
|
||||
IPath p = javaElt.getPath();
|
||||
if (p == null) {
|
||||
throw new IllegalArgumentException("javaElt has null path");
|
||||
}
|
||||
String filePath = p.toString();
|
||||
return filePath;
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException("malformed javaElt: " + javaElt, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getPackageName(ICompilationUnit cu) {
|
||||
if (cu == null) {
|
||||
throw new IllegalArgumentException("cu is null");
|
||||
}
|
||||
try {
|
||||
IPackageDeclaration[] pkgDecl = cu.getPackageDeclarations();
|
||||
|
||||
// TODO: handle default package?
|
||||
if (pkgDecl != null && pkgDecl.length > 0) {
|
||||
String packageName = pkgDecl[0].getElementName();
|
||||
return packageName;
|
||||
}
|
||||
} catch (JavaModelException e) {
|
||||
|
||||
}
|
||||
return "";
|
||||
|
||||
}
|
||||
|
||||
public static String getFullyQualifiedClassName(IType type) {
|
||||
if (type == null) {
|
||||
throw new IllegalArgumentException("type is null");
|
||||
}
|
||||
ICompilationUnit cu = (ICompilationUnit) type.getParent();
|
||||
String packageName = getPackageName(cu);
|
||||
String className = type.getElementName();
|
||||
String fullyQName = packageName + "." + className;
|
||||
return fullyQName;
|
||||
}
|
||||
|
||||
public static String getClassName(IType type) {
|
||||
if (type == null) {
|
||||
throw new IllegalArgumentException("type is null");
|
||||
}
|
||||
String className = type.getElementName();
|
||||
return className;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a unique string representing the specified Java element across projects in the workspace. The returned string can be
|
||||
* used as a handle to create JavaElement by 'JavaCore.create(String)'
|
||||
*
|
||||
* For example, suppose we have the method 'fooPackage.barPackage.FooClass.fooMethod(int)' which is in the 'FooProject' and source
|
||||
* folder 'src' the handle would be '=FooProject/src<fooPackage.barPackage{FooClass.java[FooClass~fooMethod~I'
|
||||
*
|
||||
* @param javaElt
|
||||
* @throws IllegalArgumentException if javaElt is null
|
||||
*/
|
||||
public static String getJdtHandleString(IJavaElement javaElt) {
|
||||
if (javaElt == null) {
|
||||
throw new IllegalArgumentException("javaElt is null");
|
||||
}
|
||||
return javaElt.getHandleIdentifier();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static IJavaElement createJavaElementFromJdtHandle(String jdtHandle) {
|
||||
return JavaCore.create(jdtHandle);
|
||||
}
|
||||
|
||||
public static IType[] getClasses(ICompilationUnit cu) {
|
||||
if (cu == null) {
|
||||
throw new IllegalArgumentException("cu is null");
|
||||
}
|
||||
try {
|
||||
return cu.getAllTypes();
|
||||
} catch (JavaModelException e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static IJavaProject getProject(IJavaElement javaElt) {
|
||||
if (javaElt == null) {
|
||||
throw new IllegalArgumentException("javaElt is null");
|
||||
}
|
||||
IJavaProject javaProject = javaElt.getJavaProject();
|
||||
return javaProject;
|
||||
}
|
||||
|
||||
public static String getProjectName(IJavaProject javaProject) {
|
||||
if (javaProject == null) {
|
||||
throw new IllegalArgumentException("javaProject is null");
|
||||
}
|
||||
return javaProject.getElementName();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param typeSignature Some of the type signatures examples are "QString;" (String) and "I" (int) The type signatures may be
|
||||
* either unresolved (for source types) or resolved (for binary types), and either basic (for basic types) or rich (for
|
||||
* parameterized types). See {@link Signature} for details.
|
||||
*/
|
||||
public static String getHumanReadableType(String typeSignature) {
|
||||
String simpleName = Signature.getSignatureSimpleName(typeSignature);
|
||||
return simpleName;
|
||||
}
|
||||
|
||||
public static IJavaProject getJavaProject(IFile appJar) {
|
||||
if (appJar == null) {
|
||||
throw new IllegalArgumentException("appJar is null");
|
||||
}
|
||||
String projectName = appJar.getProject().getName();
|
||||
return getJavaProject(projectName);
|
||||
}
|
||||
|
||||
public static IJavaProject getJavaProject(String projectName) {
|
||||
if (projectName == null) {
|
||||
throw new IllegalArgumentException("null projectName");
|
||||
}
|
||||
IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
|
||||
IJavaModel javaModel = JavaCore.create(workspaceRoot);
|
||||
IJavaProject javaProject = javaModel.getJavaProject(projectName);
|
||||
return javaProject;
|
||||
}
|
||||
|
||||
/**
|
||||
* compute the java projects in the active workspace
|
||||
*/
|
||||
public static Collection<IJavaProject> getWorkspaceJavaProjects() {
|
||||
Collection<IJavaProject> result = HashSetFactory.make();
|
||||
IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
|
||||
|
||||
for (IProject p : workspaceRoot.getProjects()) {
|
||||
try {
|
||||
if (p.hasNature(JavaCore.NATURE_ID)) {
|
||||
IJavaProject jp = JavaCore.create(p);
|
||||
if (jp != null) {
|
||||
result.add(jp);
|
||||
}
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the {@link IType} in the workspace corresponding to a class name.
|
||||
*
|
||||
* @return null if not found
|
||||
* @throws IllegalArgumentException if projects == null
|
||||
*/
|
||||
public static IType findJavaClassInProjects(String fullyQualifiedName, Collection<IJavaProject> projects)
|
||||
throws IllegalArgumentException {
|
||||
if (projects == null) {
|
||||
throw new IllegalArgumentException("projects == null");
|
||||
}
|
||||
for (IJavaProject project : projects) {
|
||||
try {
|
||||
IType t = project.findType(fullyQualifiedName);
|
||||
if (t != null) {
|
||||
return t;
|
||||
}
|
||||
} catch (JavaModelException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
System.err.println("failed to find " + fullyQualifiedName);
|
||||
return null;
|
||||
// IJavaElement[] arr = new IJavaElement[projects.size()];
|
||||
// projects.toArray(arr);
|
||||
// IJavaSearchScope scope = SearchEngine.createJavaSearchScope(arr, false);
|
||||
//
|
||||
// return searchForJavaClass(className, scope);
|
||||
}
|
||||
|
||||
public static IType findJavaClassInResources(String className, Collection<IResource> resources) {
|
||||
if (resources == null) {
|
||||
throw new IllegalArgumentException("null resources");
|
||||
}
|
||||
Collection<IJavaProject> projects = HashSetFactory.make();
|
||||
for (IResource r : resources) {
|
||||
projects.add(JavaCore.create(r).getJavaProject());
|
||||
}
|
||||
return findJavaClassInProjects(className, projects);
|
||||
}
|
||||
|
||||
// private static IType searchForJavaClass(String className, IJavaSearchScope scope) {
|
||||
// SearchPattern p = SearchPattern.createPattern(className, IJavaSearchConstants.CLASS_AND_INTERFACE,
|
||||
// IJavaSearchConstants.DECLARATIONS, SearchPattern.R_EXACT_MATCH);
|
||||
// SearchEngine engine = new SearchEngine();
|
||||
// final Collection<IJavaElement> kludge = HashSetFactory.make();
|
||||
// SearchRequestor requestor = new SearchRequestor() {
|
||||
//
|
||||
// @Override
|
||||
// public void acceptSearchMatch(SearchMatch match) throws CoreException {
|
||||
// kludge.add((IJavaElement) match.getElement());
|
||||
// }
|
||||
//
|
||||
// };
|
||||
// try {
|
||||
// engine.search(p, new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant() }, scope, requestor, null);
|
||||
// } catch (CoreException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// if (kludge.size() == 1) {
|
||||
// System.err.println("Found " + className);
|
||||
// return (IType) kludge.iterator().next();
|
||||
// } else {
|
||||
// System.err.println("Failed to find " + className + " " + kludge.size());
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* Find the IMethod in the workspace corresponding to a method selector.
|
||||
*
|
||||
* TODO: this is way too slow. figure out something better.
|
||||
*
|
||||
* @return null if not found
|
||||
*/
|
||||
public static IMethod findJavaMethodInProjects(String klass, String selector, Collection<IJavaProject> projects) {
|
||||
|
||||
if (klass == null) {
|
||||
throw new IllegalArgumentException("null klass");
|
||||
}
|
||||
if (projects == null) {
|
||||
throw new IllegalArgumentException("null projects");
|
||||
}
|
||||
IType type = null;
|
||||
try {
|
||||
type = findJavaClassInProjects(klass, projects);
|
||||
} catch (Throwable t) {
|
||||
return null;
|
||||
}
|
||||
if (type == null) {
|
||||
return null;
|
||||
}
|
||||
String name = parseForName(selector, type);
|
||||
String[] paramTypes = parseForParameterTypes(selector);
|
||||
IMethod m = type.getMethod(name, paramTypes);
|
||||
IMethod[] methods = type.findMethods(m);
|
||||
if (methods != null && methods.length == 1) {
|
||||
return methods[0];
|
||||
} else {
|
||||
// methods is null. probably got screwed by generics.
|
||||
// i spent 5 hours trying to figure out how to fix this correctly
|
||||
// and failed. implementing a miserable hack instead.
|
||||
// Need to consult a guru to figure out how to do this.
|
||||
try {
|
||||
List<IMethod> matches = new ArrayList<IMethod>();
|
||||
Collection<String> typeParameterNames = getTypeParameterNames(type);
|
||||
METHODS: for (IMethod x : type.getMethods()) {
|
||||
if (x.getElementName().equals(name)) {
|
||||
if (x.getParameterTypes().length == paramTypes.length) {
|
||||
for (int i = 0; i < x.getParameterTypes().length; i++) {
|
||||
String s1 = Signature.getTypeErasure(Signature.getSignatureSimpleName(x.getParameterTypes()[i]));
|
||||
String s2 = Signature.getTypeErasure(Signature.getSignatureSimpleName(paramTypes[i]));
|
||||
if (typeParameterNames.contains(s1)) {
|
||||
// s1 is a type parameter to the class. optimistically assume
|
||||
// the types match.
|
||||
} else {
|
||||
if (!s1.equals(s2)) {
|
||||
// no match
|
||||
continue METHODS;
|
||||
}
|
||||
}
|
||||
}
|
||||
matches.add(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (matches.size() == 1) {
|
||||
return matches.get(0);
|
||||
} else {
|
||||
System.err.println("findJavaMethodInWorkspace FAILED TO MATCH " + m);
|
||||
return null;
|
||||
}
|
||||
} catch (JavaModelException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Collection<String> getTypeParameterNames(IType type) throws IllegalArgumentException, JavaModelException {
|
||||
if (type == null) {
|
||||
throw new IllegalArgumentException("type == null");
|
||||
}
|
||||
ITypeParameter[] tp = type.getTypeParameters();
|
||||
Collection<String> typeParameterNames = HashSetFactory.make(tp.length);
|
||||
for (ITypeParameter p : tp) {
|
||||
typeParameterNames.add(p.getElementName());
|
||||
}
|
||||
return typeParameterNames;
|
||||
}
|
||||
|
||||
public static String parseForName(String selector, IType type) {
|
||||
if (selector == null) {
|
||||
throw new IllegalArgumentException("selector is null");
|
||||
}
|
||||
try {
|
||||
String result = selector.substring(0, selector.indexOf('('));
|
||||
if (result.equals("<init>")) {
|
||||
return type.getElementName();
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
} catch (StringIndexOutOfBoundsException e) {
|
||||
throw new IllegalArgumentException("invalid selector: " + selector);
|
||||
}
|
||||
}
|
||||
|
||||
public static final String[] parseForParameterTypes(String selector) throws IllegalArgumentException {
|
||||
|
||||
try {
|
||||
if (selector == null) {
|
||||
throw new IllegalArgumentException("selector is null");
|
||||
}
|
||||
String d = selector.substring(selector.indexOf('('));
|
||||
if (d.length() <= 2) {
|
||||
throw new IllegalArgumentException("invalid descriptor: " + d);
|
||||
|
||||
}
|
||||
if (d.charAt(0) != '(') {
|
||||
throw new IllegalArgumentException("invalid descriptor: " + d);
|
||||
}
|
||||
|
||||
ArrayList<String> sigs = new ArrayList<String>(10);
|
||||
|
||||
int i = 1;
|
||||
while (true) {
|
||||
switch (d.charAt(i++)) {
|
||||
case TypeReference.VoidTypeCode:
|
||||
sigs.add(TypeReference.VoidName.toString());
|
||||
continue;
|
||||
case TypeReference.BooleanTypeCode:
|
||||
sigs.add(TypeReference.BooleanName.toString());
|
||||
continue;
|
||||
case TypeReference.ByteTypeCode:
|
||||
sigs.add(TypeReference.ByteName.toString());
|
||||
continue;
|
||||
case TypeReference.ShortTypeCode:
|
||||
sigs.add(TypeReference.ShortName.toString());
|
||||
continue;
|
||||
case TypeReference.IntTypeCode:
|
||||
sigs.add(TypeReference.IntName.toString());
|
||||
continue;
|
||||
case TypeReference.LongTypeCode:
|
||||
sigs.add(TypeReference.LongName.toString());
|
||||
continue;
|
||||
case TypeReference.FloatTypeCode:
|
||||
sigs.add(TypeReference.FloatName.toString());
|
||||
continue;
|
||||
case TypeReference.DoubleTypeCode:
|
||||
sigs.add(TypeReference.DoubleName.toString());
|
||||
continue;
|
||||
case TypeReference.CharTypeCode:
|
||||
sigs.add(TypeReference.CharName.toString());
|
||||
continue;
|
||||
case TypeReference.ArrayTypeCode: {
|
||||
int off = i - 1;
|
||||
while (d.charAt(i) == TypeReference.ArrayTypeCode) {
|
||||
++i;
|
||||
}
|
||||
if (d.charAt(i++) == TypeReference.ClassTypeCode) {
|
||||
while (d.charAt(i++) != ';')
|
||||
;
|
||||
sigs.add(d.substring(off, i).replaceAll("/", "."));
|
||||
} else {
|
||||
sigs.add(d.substring(off, i));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
case (byte) ')': // end of parameter list
|
||||
return toArray(sigs);
|
||||
default: {
|
||||
// a class
|
||||
int off = i - 1;
|
||||
char c;
|
||||
do {
|
||||
c = d.charAt(i++);
|
||||
} while (c != ',' && c != ')');
|
||||
sigs.add("L" + d.substring(off, i - 1) + ";");
|
||||
|
||||
if (c == ')') {
|
||||
return toArray(sigs);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (StringIndexOutOfBoundsException e) {
|
||||
throw new IllegalArgumentException("error parsing selector " + selector);
|
||||
}
|
||||
}
|
||||
|
||||
private static String[] toArray(ArrayList<String> sigs) {
|
||||
int size = sigs.size();
|
||||
if (size == 0) {
|
||||
return new String[0];
|
||||
}
|
||||
Iterator<String> it = sigs.iterator();
|
||||
String[] result = new String[size];
|
||||
for (int j = 0; j < size; j++) {
|
||||
result[j] = it.next();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the IMethod in the workspace corresponding to a method signature.
|
||||
*
|
||||
* This doesn't work for elements declared in inner classes. It's possible this is a 3.2 bug fixed in 3.3
|
||||
*
|
||||
* @return null if not found
|
||||
*/
|
||||
@Deprecated
|
||||
public static IMethod findJavaMethodInWorkspaceBrokenForInnerClasses(String methodSig) {
|
||||
// dammit ... this doesn't work for inner classes.
|
||||
|
||||
System.err.println("Search for " + methodSig);
|
||||
SearchPattern p = SearchPattern.createPattern(methodSig, IJavaSearchConstants.METHOD, IJavaSearchConstants.DECLARATIONS,
|
||||
SearchPattern.R_EXACT_MATCH);
|
||||
IJavaSearchScope scope = SearchEngine.createWorkspaceScope();
|
||||
SearchEngine engine = new SearchEngine();
|
||||
final Collection<IJavaElement> kludge = HashSetFactory.make();
|
||||
SearchRequestor requestor = new SearchRequestor() {
|
||||
|
||||
@Override
|
||||
public void acceptSearchMatch(SearchMatch match) throws CoreException {
|
||||
kludge.add((IJavaElement) match.getElement());
|
||||
}
|
||||
|
||||
};
|
||||
try {
|
||||
engine.search(p, new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant() }, scope, requestor, null);
|
||||
} catch (CoreException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (kludge.size() == 1) {
|
||||
return (IMethod) kludge.iterator().next();
|
||||
} else {
|
||||
System.err.println("RETURNED " + kludge.size() + " " + kludge);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the search engine to find all methods in a java element
|
||||
*/
|
||||
public static Collection<IMethod> findMethods(IJavaElement elt) {
|
||||
|
||||
if (elt instanceof ICompilationUnit) {
|
||||
Collection<IMethod> result = HashSetFactory.make();
|
||||
for (IType type : getClasses((ICompilationUnit) elt)) {
|
||||
try {
|
||||
for (IMethod m : type.getMethods()) {
|
||||
result.add(m);
|
||||
}
|
||||
} catch (JavaModelException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
final Collection<IMethod> result = HashSetFactory.make();
|
||||
SearchPattern p = SearchPattern.createPattern("*", IJavaSearchConstants.METHOD, IJavaSearchConstants.DECLARATIONS,
|
||||
SearchPattern.R_PATTERN_MATCH);
|
||||
SearchPattern p2 = SearchPattern.createPattern("*", IJavaSearchConstants.CONSTRUCTOR, IJavaSearchConstants.DECLARATIONS,
|
||||
SearchPattern.R_PATTERN_MATCH);
|
||||
IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaElement[] { elt }, IJavaSearchScope.SOURCES);
|
||||
SearchEngine engine = new SearchEngine();
|
||||
SearchRequestor requestor = new SearchRequestor() {
|
||||
@Override
|
||||
public void acceptSearchMatch(SearchMatch match) throws CoreException {
|
||||
if (match.getElement() instanceof IMethod) {
|
||||
result.add((IMethod) match.getElement());
|
||||
}
|
||||
}
|
||||
};
|
||||
try {
|
||||
engine.search(p, new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant() }, scope, requestor, null);
|
||||
engine.search(p2, new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant() }, scope, requestor, null);
|
||||
} catch (CoreException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get a {@link StructuredSelection} corresponding to the named projects
|
||||
*/
|
||||
public static StructuredSelection getStructuredSelectionForProjectNames(Collection<String> projectNames) {
|
||||
if (projectNames == null) {
|
||||
throw new IllegalArgumentException("null projectNames");
|
||||
}
|
||||
Object[] projects = new Object[projectNames.size()];
|
||||
int i = 0;
|
||||
for (String projectName : projectNames) {
|
||||
projects[i++] = getJavaProject(projectName);
|
||||
}
|
||||
StructuredSelection selection = new StructuredSelection(projects);
|
||||
return selection;
|
||||
}
|
||||
|
||||
}
|
|
@ -15,12 +15,12 @@ import java.util.LinkedList;
|
|||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.eclipse.util.MonitorUtil;
|
||||
import com.ibm.wala.fixpoint.FixedPointConstants;
|
||||
import com.ibm.wala.fixpoint.IFixedPointSolver;
|
||||
import com.ibm.wala.fixpoint.IFixedPointStatement;
|
||||
import com.ibm.wala.fixpoint.IVariable;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.MonitorUtil;
|
||||
import com.ibm.wala.util.debug.VerboseAction;
|
||||
|
||||
/**
|
||||
|
|
|
@ -12,7 +12,7 @@ package com.ibm.wala.fixpoint;
|
|||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
|
||||
/**
|
||||
* Solves a set of constraints
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
*******************************************************************************/
|
||||
package com.ibm.wala.ipa.callgraph;
|
||||
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
|
||||
/**
|
||||
* An exception to throw when call graph construction is canceled. This exception allows clients to retrieve the partially-built
|
||||
|
|
|
@ -18,7 +18,6 @@ import java.util.Set;
|
|||
|
||||
import com.ibm.wala.classLoader.CallSiteReference;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.Context;
|
||||
|
@ -26,6 +25,7 @@ import com.ibm.wala.ipa.callgraph.propagation.SSAContextInterpreter;
|
|||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.shrikeBT.IInvokeInstruction;
|
||||
import com.ibm.wala.types.MethodReference;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.collections.HashMapFactory;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.collections.NonNullSingletonIterator;
|
||||
|
|
|
@ -19,7 +19,6 @@ import com.ibm.wala.cfg.ControlFlowGraph;
|
|||
import com.ibm.wala.classLoader.CallSiteReference;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.classLoader.NewSiteReference;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
|
@ -30,6 +29,7 @@ import com.ibm.wala.ssa.DefUse;
|
|||
import com.ibm.wala.ssa.IR;
|
||||
import com.ibm.wala.ssa.ISSABasicBlock;
|
||||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.collections.EmptyIterator;
|
||||
import com.ibm.wala.util.collections.Filter;
|
||||
import com.ibm.wala.util.collections.FilterIterator;
|
||||
|
|
|
@ -12,7 +12,7 @@ package com.ibm.wala.ipa.callgraph.propagation;
|
|||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -12,7 +12,7 @@ package com.ibm.wala.ipa.callgraph.propagation;
|
|||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
|
||||
/**
|
||||
* Basic interface for a pointer analysis solver.
|
||||
|
|
|
@ -17,11 +17,11 @@ import java.util.Iterator;
|
|||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.fixedpoint.impl.AbstractFixedPointSolver;
|
||||
import com.ibm.wala.fixedpoint.impl.AbstractStatement;
|
||||
import com.ibm.wala.fixedpoint.impl.UnaryStatement;
|
||||
import com.ibm.wala.fixpoint.IVariable;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.collections.Iterator2Collection;
|
||||
import com.ibm.wala.util.graph.Graph;
|
||||
|
|
|
@ -24,7 +24,6 @@ import com.ibm.wala.classLoader.IMethod;
|
|||
import com.ibm.wala.classLoader.Language;
|
||||
import com.ibm.wala.classLoader.NewSiteReference;
|
||||
import com.ibm.wala.classLoader.SyntheticClass;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.fixedpoint.impl.UnaryOperator;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
|
@ -41,6 +40,7 @@ import com.ibm.wala.ipa.callgraph.propagation.rta.RTAContextInterpreter;
|
|||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.intset.IntSet;
|
||||
|
|
|
@ -17,7 +17,6 @@ import java.util.Set;
|
|||
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.classLoader.SyntheticMethod;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.rta.RTAContextInterpreter;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
|
@ -30,6 +29,7 @@ import com.ibm.wala.ipa.slicer.Slicer.DataDependenceOptions;
|
|||
import com.ibm.wala.ipa.slicer.Statement.Kind;
|
||||
import com.ibm.wala.ssa.SSACheckCastInstruction;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.collections.Filter;
|
||||
import com.ibm.wala.util.collections.FilterIterator;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
|
|
|
@ -12,7 +12,7 @@ package com.ibm.wala.ipa.callgraph.propagation;
|
|||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
|
||||
/**
|
||||
* standard fixed-point iterative solver for pointer analysis
|
||||
|
|
|
@ -19,7 +19,6 @@ import com.ibm.wala.classLoader.CallSiteReference;
|
|||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.classLoader.NewSiteReference;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.fixedpoint.impl.UnaryOperator;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
|
@ -53,6 +52,7 @@ import com.ibm.wala.types.ClassLoaderReference;
|
|||
import com.ibm.wala.types.FieldReference;
|
||||
import com.ibm.wala.types.MethodReference;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
|
||||
/**
|
||||
|
|
|
@ -34,7 +34,6 @@ import com.ibm.wala.util.intset.BitVector;
|
|||
import com.ibm.wala.util.intset.BitVectorIntSet;
|
||||
import com.ibm.wala.util.intset.IntSet;
|
||||
import com.ibm.wala.util.intset.MutableIntSet;
|
||||
import com.ibm.wala.viz.IFDSExplorer;
|
||||
|
||||
/**
|
||||
* Interprocedural control-flow graph, constructed lazily.
|
||||
|
|
|
@ -18,8 +18,6 @@ import java.util.Set;
|
|||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.classLoader.IField;
|
||||
import com.ibm.wala.dataflow.graph.BitVectorSolver;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.eclipse.util.CancelRuntimeException;
|
||||
import com.ibm.wala.fixpoint.BitVectorVariable;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
|
@ -35,6 +33,8 @@ import com.ibm.wala.ssa.SSAGetInstruction;
|
|||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
import com.ibm.wala.ssa.SSANewInstruction;
|
||||
import com.ibm.wala.ssa.SSAPutInstruction;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.CancelRuntimeException;
|
||||
import com.ibm.wala.util.collections.HashMapFactory;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.graph.impl.GraphInverter;
|
||||
|
|
|
@ -24,8 +24,6 @@ import com.ibm.wala.dataflow.graph.BitVectorSolver;
|
|||
import com.ibm.wala.dataflow.graph.BitVectorUnion;
|
||||
import com.ibm.wala.dataflow.graph.BitVectorUnionVector;
|
||||
import com.ibm.wala.dataflow.graph.ITransferFunctionProvider;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.eclipse.util.CancelRuntimeException;
|
||||
import com.ibm.wala.fixedpoint.impl.UnaryOperator;
|
||||
import com.ibm.wala.fixpoint.BitVectorVariable;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
|
@ -44,6 +42,8 @@ import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
|
|||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
import com.ibm.wala.ssa.analysis.ExplodedControlFlowGraph;
|
||||
import com.ibm.wala.ssa.analysis.IExplodedBasicBlock;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.CancelRuntimeException;
|
||||
import com.ibm.wala.util.collections.Filter;
|
||||
import com.ibm.wala.util.collections.FilterIterator;
|
||||
import com.ibm.wala.util.collections.HashMapFactory;
|
||||
|
|
|
@ -23,10 +23,10 @@ import com.ibm.wala.dataflow.IFDS.PathEdge;
|
|||
import com.ibm.wala.dataflow.IFDS.TabulationDomain;
|
||||
import com.ibm.wala.dataflow.IFDS.TabulationResult;
|
||||
import com.ibm.wala.dataflow.IFDS.UnorderedDomain;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
|
||||
import com.ibm.wala.ipa.modref.ModRef;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
|
||||
/**
|
||||
|
|
|
@ -15,8 +15,6 @@ import java.util.Iterator;
|
|||
import java.util.Map;
|
||||
|
||||
import com.ibm.wala.cfg.ControlFlowGraph;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.eclipse.util.CancelRuntimeException;
|
||||
import com.ibm.wala.fixedpoint.impl.DefaultFixedPointSolver;
|
||||
import com.ibm.wala.fixpoint.BooleanVariable;
|
||||
import com.ibm.wala.fixpoint.UnaryOr;
|
||||
|
@ -25,6 +23,8 @@ import com.ibm.wala.ssa.IR;
|
|||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
import com.ibm.wala.ssa.SSAPhiInstruction;
|
||||
import com.ibm.wala.ssa.SSACFG.BasicBlock;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.CancelRuntimeException;
|
||||
import com.ibm.wala.util.collections.HashMapFactory;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.ibm.wala.eclipse.util;
|
||||
package com.ibm.wala.util;
|
||||
|
||||
/**
|
||||
* An exception for when work is canceled in eclipse. This version forces every API that uses it to declare it. Use
|
|
@ -8,7 +8,7 @@
|
|||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.ibm.wala.eclipse.util;
|
||||
package com.ibm.wala.util;
|
||||
|
||||
/**
|
||||
* An exception for when work is canceled in eclipse. This is identical to {@link CancelException}, but this one extends
|
|
@ -8,7 +8,7 @@
|
|||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.ibm.wala.eclipse.util;
|
||||
package com.ibm.wala.util;
|
||||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.SubProgressMonitor;
|
|
@ -8,7 +8,7 @@
|
|||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.ibm.wala.eclipse.util;
|
||||
package com.ibm.wala.util;
|
||||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
|
|
@ -22,9 +22,9 @@ import com.ibm.wala.dataflow.graph.BitVectorUnion;
|
|||
import com.ibm.wala.dataflow.graph.BitVectorUnionConstant;
|
||||
import com.ibm.wala.dataflow.graph.DataflowSolver;
|
||||
import com.ibm.wala.dataflow.graph.ITransferFunctionProvider;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.fixedpoint.impl.UnaryOperator;
|
||||
import com.ibm.wala.fixpoint.BitVectorVariable;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.collections.Filter;
|
||||
import com.ibm.wala.util.collections.FilterIterator;
|
||||
import com.ibm.wala.util.collections.Iterator2Collection;
|
||||
|
|
|
@ -13,6 +13,7 @@ package com.ibm.wala.util.io;// 5724-D15
|
|||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.JarURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
|
@ -22,11 +23,8 @@ import java.util.jar.JarEntry;
|
|||
import java.util.jar.JarFile;
|
||||
import java.util.zip.ZipException;
|
||||
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IWorkspace;
|
||||
import org.eclipse.core.resources.IWorkspaceRoot;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.core.runtime.FileLocator;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
import org.eclipse.core.runtime.Plugin;
|
||||
|
||||
|
@ -40,6 +38,41 @@ import com.ibm.wala.util.debug.Assertions;
|
|||
* This class provides files that are packaged with this plug-in
|
||||
*/
|
||||
public class FileProvider {
|
||||
|
||||
/**
|
||||
* This class uses reflection to access classes and methods that are only available when Eclipse is
|
||||
* running as an IDE environment. The choice to use reflection is related to builds: with this design
|
||||
* the build doesn't need to provide IDE bundles during compilation and hence can spot invalid uses of
|
||||
* such classes through this bundle.
|
||||
*
|
||||
* Because of this class, this bundle must OPTIONALY require 'org.eclipse.core.resources'.
|
||||
*/
|
||||
private static final class EclipseUtil {
|
||||
private static Object workspaceRoot = null;
|
||||
private static Method workspaceRoot_getFile = null;
|
||||
|
||||
public static Module getJarFileModule(String fileName, ClassLoader loader) {
|
||||
// Using reflection to enable this code to be built without the org.eclipse.core.resources bundle
|
||||
//
|
||||
try {
|
||||
if (workspaceRoot_getFile == null) {
|
||||
Class<?> cls = Class.forName("org.eclipse.core.resources.ResourcesPlugin");
|
||||
Method getWorkspaceMethod = cls.getDeclaredMethod("getWorkspace");
|
||||
Object workspace = getWorkspaceMethod.invoke(null);
|
||||
Method getRoot = workspace.getClass().getDeclaredMethod("getRoot");
|
||||
workspaceRoot = getRoot.invoke(workspace);
|
||||
workspaceRoot_getFile = workspaceRoot.getClass().getMethod("getFile", IPath.class);
|
||||
}
|
||||
|
||||
IPath path = new Path(fileName);
|
||||
if (workspaceRoot_getFile.invoke(workspaceRoot, path) != null) {
|
||||
return new JarFileModule(new JarFile(fileName, false));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private final static int DEBUG_LEVEL = 0;
|
||||
|
||||
|
@ -47,17 +80,6 @@ public class FileProvider {
|
|||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null if there's a problem
|
||||
*/
|
||||
public static IWorkspace getWorkspace() {
|
||||
try {
|
||||
return ResourcesPlugin.getWorkspace();
|
||||
} catch (Throwable t) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fileName
|
||||
* @return the jar file packaged with this plug-in of the given name, or null if not found.
|
||||
|
@ -69,21 +91,13 @@ public class FileProvider {
|
|||
public static Module getJarFileModule(String fileName, ClassLoader loader) throws IOException {
|
||||
if (CorePlugin.getDefault() == null) {
|
||||
return getJarFileFromClassLoader(fileName, loader);
|
||||
} else {
|
||||
// try to load the path as a full path
|
||||
try {
|
||||
IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
|
||||
IFile file = workspaceRoot.getFile(new Path(fileName));
|
||||
if (file != null) {
|
||||
return new JarFileModule(new JarFile(fileName, false));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} else if (CorePlugin.IS_RESOURCES_BUNDLE_AVAILABLE){
|
||||
Module module = EclipseUtil.getJarFileModule(fileName, loader);
|
||||
if (module != null) {
|
||||
return module;
|
||||
}
|
||||
|
||||
// otherwise load from plugin
|
||||
return getFromPlugin(CorePlugin.getDefault(), fileName);
|
||||
}
|
||||
|
||||
return getFromPlugin(CorePlugin.getDefault(), fileName);
|
||||
}
|
||||
|
||||
public static URL getResource(String fileName) throws IOException {
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* 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.viz;
|
||||
|
||||
import org.eclipse.jface.window.ApplicationWindow;
|
||||
|
||||
/**
|
||||
* abstract base class for launching a JFace application
|
||||
*
|
||||
* TODO: unify with other launchers?
|
||||
*/
|
||||
public abstract class AbstractJFaceRunner {
|
||||
|
||||
protected ApplicationWindow applicationWindow = null;
|
||||
|
||||
protected boolean blockInput = false;
|
||||
|
||||
protected AbstractJFaceRunner() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ApplicationWindow getApplicationWindow() {
|
||||
return applicationWindow;
|
||||
}
|
||||
|
||||
public void setApplicationWindow(ApplicationWindow newApplicationWindow) {
|
||||
applicationWindow = newApplicationWindow;
|
||||
}
|
||||
|
||||
public boolean isBlockInput() {
|
||||
return blockInput;
|
||||
}
|
||||
|
||||
public void setBlockInput(boolean newBlockInput) {
|
||||
blockInput = newBlockInput;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuffer result = new StringBuffer(super.toString());
|
||||
result.append(" (applicationWindow: ");
|
||||
result.append(applicationWindow);
|
||||
result.append(", blockInput: ");
|
||||
result.append(blockInput);
|
||||
result.append(')');
|
||||
return result.toString();
|
||||
}
|
||||
}
|
|
@ -1,124 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* 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.viz;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.Properties;
|
||||
|
||||
import com.ibm.wala.dataflow.IFDS.TabulationResult;
|
||||
import com.ibm.wala.properties.WalaProperties;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.graph.Graph;
|
||||
import com.ibm.wala.util.graph.InferGraphRoots;
|
||||
import com.ibm.wala.util.warnings.WalaException;
|
||||
|
||||
/**
|
||||
* Explore the result of an IFDS problem with an SWT viewer and ghostview.
|
||||
*/
|
||||
public class IFDSExplorer {
|
||||
|
||||
/**
|
||||
* absolute path name to invoke dot
|
||||
*/
|
||||
protected static String dotExe = null;
|
||||
|
||||
/**
|
||||
* Absolute path name to invoke viewer
|
||||
*/
|
||||
protected static String viewerExe = null;
|
||||
|
||||
private static final boolean PRINT_DOMAIN = true;
|
||||
|
||||
public static void setDotExe(String newDotExe) {
|
||||
dotExe = newDotExe;
|
||||
}
|
||||
|
||||
public static void setGvExe(String newGvExe) {
|
||||
viewerExe = newGvExe;
|
||||
}
|
||||
|
||||
public static <T, P, F> void viewIFDS(TabulationResult<T, P, F> r, Collection<? extends P> roots) throws WalaException {
|
||||
viewIFDS(r, roots, null);
|
||||
}
|
||||
|
||||
public static <T, P, F> void viewIFDS(TabulationResult<T, P, F> r, Collection<? extends P> roots, NodeDecorator labels)
|
||||
throws WalaException {
|
||||
Properties p = null;
|
||||
try {
|
||||
p = WalaProperties.loadProperties();
|
||||
} catch (WalaException e) {
|
||||
e.printStackTrace();
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
String scratch = p.getProperty(WalaProperties.OUTPUT_DIR);
|
||||
viewIFDS(r, roots, labels, scratch);
|
||||
}
|
||||
|
||||
public static <T, P, F> void viewIFDS(TabulationResult<T, P, F> r, Collection<? extends P> roots, NodeDecorator labels,
|
||||
String scratchDirectory) throws WalaException {
|
||||
if (r == null) {
|
||||
throw new IllegalArgumentException("r is null");
|
||||
}
|
||||
assert dotExe != null;
|
||||
|
||||
// dump the domain to stderr
|
||||
if (PRINT_DOMAIN) {
|
||||
System.err.println("Domain:\n" + r.getProblem().getDomain().toString());
|
||||
}
|
||||
|
||||
String irFileName = null;
|
||||
switch (DotUtil.getOutputType()) {
|
||||
case PDF:
|
||||
irFileName = "ir.pdf";
|
||||
break;
|
||||
case PS:
|
||||
irFileName = "ir.ps";
|
||||
break;
|
||||
case SVG:
|
||||
irFileName = "ir.svg";
|
||||
break;
|
||||
}
|
||||
String outputFile = scratchDirectory + File.separatorChar + irFileName;
|
||||
String dotFile = scratchDirectory + File.separatorChar + "ir.dt";
|
||||
|
||||
final SWTTreeViewer v = new SWTTreeViewer();
|
||||
Graph<? extends P> g = r.getProblem().getSupergraph().getProcedureGraph();
|
||||
v.setGraphInput(g);
|
||||
v.setBlockInput(true);
|
||||
v.setRootsInput(roots);
|
||||
ViewIFDSLocalAction<T, P, F> action = (labels == null ? new ViewIFDSLocalAction<T, P, F>(v, r, outputFile, dotFile, dotExe,
|
||||
viewerExe) : new ViewIFDSLocalAction<T, P, F>(v, r, outputFile, dotFile, dotExe, viewerExe, labels));
|
||||
v.getPopUpActions().add(action);
|
||||
v.run();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls {@link #viewIFDS(TabulationResult)} with roots computed by {@link InferGraphRoots}.
|
||||
*/
|
||||
public static <T, P, F> void viewIFDS(TabulationResult<T, P, F> r) throws WalaException {
|
||||
if (r == null) {
|
||||
throw new IllegalArgumentException("null r");
|
||||
}
|
||||
Collection<? extends P> roots = InferGraphRoots.inferRoots(r.getProblem().getSupergraph().getProcedureGraph());
|
||||
viewIFDS(r, roots);
|
||||
}
|
||||
|
||||
public static String getDotExe() {
|
||||
return dotExe;
|
||||
}
|
||||
|
||||
public static String getGvExe() {
|
||||
return viewerExe;
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue