/****************************************************************************** * Copyright (c) 2009 - 2015 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.memsat.frontEnd; import java.io.File; import java.io.FilenameFilter; import java.io.IOException; import java.util.List; import java.util.jar.JarFile; import java.util.zip.ZipException; import org.eclipse.core.runtime.CoreException; import com.ibm.wala.cast.java.client.JavaSourceAnalysisEngine; import com.ibm.wala.classLoader.JarFileModule; import com.ibm.wala.classLoader.SourceDirectoryTreeModule; import com.ibm.wala.ipa.callgraph.AnalysisScope; import com.ibm.wala.memsat.Options; import com.ibm.wala.memsat.frontEnd.core.WalaInformationImpl; import com.ibm.wala.memsat.frontEnd.engine.MiniaturAnalysisEngine; import com.ibm.wala.memsat.frontEnd.engine.MiniaturECJJavaAnalysisEngine; import com.ibm.wala.memsat.frontEnd.engine.MiniaturJDTJavaAnalysisEngine; import com.ibm.wala.types.MethodReference; import com.ibm.wala.util.collections.Iterator2Collection; import com.ibm.wala.util.graph.Graph; /** * Computes and analyzes the call graph for a given * {@linkplain AnalysisScope analysis scope} and a set of * {@linkplain MethodReference methods}, using the wala library. * * @see WalaInformation * * @author Emina Torlak */ public final class WalaEngine { /** * The engine cannot be instantiated from the outside. */ private WalaEngine() {} private static void doJavaLibDir(JavaSourceAnalysisEngine engine, String libDir) throws IOException { if (new File(libDir).exists()) { File[] libJarFiles = new File(libDir).listFiles( new FilenameFilter() { public boolean accept(File dir, String name) { return name.endsWith(".jar"); } }); for(int i = 0; i < libJarFiles.length; i++) { try { JarFileModule m = new JarFileModule(new JarFile(libJarFiles[i])); engine.addSystemModule(m); } catch (ZipException e) { System.err.println("trouble with " + libJarFiles[i]); } } } } private static void setExclusions(MiniaturAnalysisEngine engine, List<File> relativeNames) { final String exclusions = System.getProperty("com.ibm.wala.memsat.exclusions") ; if (exclusions != null) { engine.setExclusionsFile(exclusions); } if (exclusions == null) { for(File relativeName : relativeNames) { String testSourceDirName = System.getProperty("user.dir") + File.separator + relativeName.getPath(); File appExclusionsFile = new File(testSourceDirName + "_exclusions.xml"); if (appExclusionsFile.exists()) { engine.setExclusionsFile(appExclusionsFile.getAbsolutePath()); } } } } private static void setPolyglotJavaEngineScope(JavaSourceAnalysisEngine engine, List<File> relativeNames) { try { String home = System.getProperty("java.home"); doJavaLibDir(engine, home + File.separator + "lib"); doJavaLibDir(engine, home + "/../Classes"); for(File relativeName : relativeNames) { engine.addSourceModule(new SourceDirectoryTreeModule(relativeName)); String testSourceDirName = System.getProperty("user.dir") + File.separator + relativeName.getPath(); File appLibsDir = new File(testSourceDirName + "Libs"); if (appLibsDir.exists() && appLibsDir.isDirectory()) { File[] appJarFiles = appLibsDir.listFiles( new FilenameFilter() { public boolean accept(File dir, String name) { return name.endsWith(".jar"); } }); for(int i = 0; i < appJarFiles.length; i++) { engine.addCompiledModule( new JarFileModule(new JarFile(appJarFiles[i]))); } } } } catch (IOException e) { assert false : e.toString(); } } /** * Returns the {@linkplain WalaInformation result} of * analyzing the given methods in the specified source directory * @requires all of the given method references are in the specified directory * @return { wInfo: WalaInformation | wInfo.methods = methods } */ public static WalaInformation analyze(Graph<MethodReference> methods, List<File> sourceDirs, Options options) throws com.ibm.wala.util.CancelException, java.io.IOException { MiniaturAnalysisEngine engine = null; if (options.getEclipseProjectName() == null) { MiniaturECJJavaAnalysisEngine e = new MiniaturECJJavaAnalysisEngine( options.loopUnrollDepth(), Iterator2Collection.toList(methods.iterator())); setPolyglotJavaEngineScope(e, sourceDirs); engine = e; } else { try { engine = new MiniaturJDTJavaAnalysisEngine( options.getEclipseProjectName(), options.loopUnrollDepth(), Iterator2Collection.toList(methods.iterator())); } catch (IllegalArgumentException e) { assert false : e; } catch (CoreException e) { assert false : e; } } setExclusions(engine, sourceDirs); return new WalaInformationImpl(options, engine, methods); } }