diff --git a/src/main/java/com/ibm/wala/examples/drivers/SourceDirCallGraph.java b/src/main/java/com/ibm/wala/examples/drivers/SourceDirCallGraph.java new file mode 100644 index 0000000..924b17b --- /dev/null +++ b/src/main/java/com/ibm/wala/examples/drivers/SourceDirCallGraph.java @@ -0,0 +1,126 @@ +package com.ibm.wala.examples.drivers; + +import com.ibm.wala.cast.ir.ssa.AstIRFactory; +import com.ibm.wala.cast.java.client.impl.ZeroOneContainerCFABuilderFactory; +import com.ibm.wala.cast.java.ipa.callgraph.JavaSourceAnalysisScope; +import com.ibm.wala.cast.java.translator.jdt.ecj.ECJClassLoaderFactory; +import com.ibm.wala.classLoader.ClassLoaderFactory; +import com.ibm.wala.classLoader.SourceDirectoryTreeModule; +import com.ibm.wala.classLoader.SourceFileModule; +import com.ibm.wala.ipa.callgraph.AnalysisCacheImpl; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +import com.ibm.wala.ipa.callgraph.AnalysisOptions.ReflectionOptions; +import com.ibm.wala.ipa.callgraph.AnalysisScope; +import com.ibm.wala.ipa.callgraph.CallGraph; +import com.ibm.wala.ipa.callgraph.CallGraphBuilder; +import com.ibm.wala.ipa.callgraph.CallGraphBuilderCancelException; +import com.ibm.wala.ipa.callgraph.CallGraphStats; +import com.ibm.wala.ipa.callgraph.Entrypoint; +import com.ibm.wala.ipa.callgraph.IAnalysisCacheView; +import com.ibm.wala.ipa.callgraph.impl.Util; +import com.ibm.wala.ipa.cha.ClassHierarchyException; +import com.ibm.wala.ipa.cha.ClassHierarchyFactory; +import com.ibm.wala.ipa.cha.IClassHierarchy; +import com.ibm.wala.properties.WalaProperties; +import com.ibm.wala.ssa.SymbolTable; +import com.ibm.wala.types.ClassLoaderReference; +import com.ibm.wala.util.io.CommandLine; +import com.ibm.wala.util.warnings.Warnings; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import java.util.Properties; +import java.util.jar.JarFile; + +/** + * Driver that constructs a call graph for an application specified as a directory of source code. + * Example of using the JDT front-end based on ECJ. Useful for getting some code to copy-paste. + */ +public class SourceDirCallGraph { + + @FunctionalInterface + public interface Processor { + public void process(CallGraph CG, CallGraphBuilder> builder, long time); + } + + /** + * Usage: SourceDirCallGraph -sourceDir file_path -mainClass class_name + * + *
If given -mainClass, uses main() method of class_name as entrypoint. Class name should start + * with an 'L'. + * + *
Example args: -sourceDir /tmp/srcTest -mainClass LFoo
+ */
+ public static void main(String[] args)
+ throws ClassHierarchyException, IllegalArgumentException, CallGraphBuilderCancelException,
+ IOException {
+ System.out.println(Arrays.toString(args));
+ new SourceDirCallGraph()
+ .doit(
+ args,
+ (cg, builder, time) -> {
+ System.out.println("done");
+ System.out.println("took " + time + "ms");
+ System.out.println(CallGraphStats.getStats(cg));
+ });
+ }
+
+ protected ClassLoaderFactory getLoaderFactory(AnalysisScope scope) {
+ return new ECJClassLoaderFactory(scope.getExclusions());
+ }
+
+ public void doit(String[] args, Processor processor)
+ throws ClassHierarchyException, IllegalArgumentException, CallGraphBuilderCancelException,
+ IOException {
+ long start = System.currentTimeMillis();
+ Properties p = CommandLine.parse(args);
+ String sourceDir = p.getProperty("sourceDir");
+ String mainClass = p.getProperty("mainClass");
+ AnalysisScope scope = new JavaSourceAnalysisScope();
+ // add standard libraries to scope
+ String[] stdlibs = WalaProperties.getJ2SEJarFiles();
+ for (String stdlib : stdlibs) {
+ scope.addToScope(ClassLoaderReference.Primordial, new JarFile(stdlib));
+ }
+ // add the source directory
+ File root = new File(sourceDir);
+ if (root.isDirectory()) {
+ scope.addToScope(JavaSourceAnalysisScope.SOURCE, new SourceDirectoryTreeModule(root));
+ } else {
+ String srcFileName = sourceDir.substring(sourceDir.lastIndexOf(File.separator) + 1);
+ assert root.exists() : "couldn't find " + sourceDir;
+ scope.addToScope(
+ JavaSourceAnalysisScope.SOURCE, new SourceFileModule(root, srcFileName, null));
+ }
+
+ // build the class hierarchy
+ IClassHierarchy cha = ClassHierarchyFactory.make(scope, getLoaderFactory(scope));
+ System.out.println(cha.getNumberOfClasses() + " classes");
+ System.out.println(Warnings.asString());
+ Warnings.clear();
+ AnalysisOptions options = new AnalysisOptions();
+ Iterable