All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.evosuite.graphs.GraphPool Maven / Gradle / Ivy

/**
 * Copyright (C) 2010-2018 Gordon Fraser, Andrea Arcuri and EvoSuite
 * contributors
 *
 * This file is part of EvoSuite.
 *
 * EvoSuite is free software: you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation, either version 3.0 of the License, or
 * (at your option) any later version.
 *
 * EvoSuite is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with EvoSuite. If not, see .
 */
package org.evosuite.graphs;

import java.util.HashMap;
import java.util.Map;

import org.evosuite.Properties;
import org.evosuite.graphs.ccfg.ClassControlFlowGraph;
import org.evosuite.graphs.ccg.ClassCallGraph;
import org.evosuite.graphs.cdg.ControlDependenceGraph;
import org.evosuite.graphs.cfg.ActualControlFlowGraph;
import org.evosuite.graphs.cfg.RawControlFlowGraph;
import org.evosuite.setup.DependencyAnalysis;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Gives access to all Graphs computed during CUT analysis such as CFGs created
 * by the CFGGenerator and BytcodeAnalyzer in the CFGMethodAdapter
 *
 * For each CUT and each of their methods a Raw- and an ActualControlFlowGraph
 * instance are stored within this pool. Additionally a ControlDependenceGraph
 * is computed and stored for each such method.
 *
 * This pool also offers the possibility to generate the ClassCallGraph and
 * ClassControlFlowGraph for a CUT. They represents the call hierarchy and
 * interaction of different methods within a class.
 *
 * @author Andre Mis
 */
public class GraphPool {

	private static Logger logger = LoggerFactory.getLogger(GraphPool.class);

	private static Map instanceMap = new HashMap();

	private final ClassLoader classLoader;

	/** Private constructor */
	private GraphPool(ClassLoader classLoader) {
		this.classLoader = classLoader;
	}

	public static GraphPool getInstance(ClassLoader classLoader) {
		if (!instanceMap.containsKey(classLoader)) {
			instanceMap.put(classLoader, new GraphPool(classLoader));
		}

		return instanceMap.get(classLoader);
	}

	/**
	 * Complete control flow graph, contains each bytecode instruction, each
	 * label and line number node Think of the direct Known Subclasses of
	 * http://
	 * asm.ow2.org/asm33/javadoc/user/org/objectweb/asm/tree/AbstractInsnNode
	 * .html for a complete list of the nodes in this cfg
	 *
	 * Maps from classNames to methodNames to corresponding RawCFGs
	 */
	private final Map> rawCFGs = new HashMap>();

	/**
	 * Minimized control flow graph. This graph only contains the first and last
	 * node (usually a LABEL and IRETURN), nodes which create branches (all
	 * jumps/switches except GOTO) and nodes which were mutated.
	 *
	 * Maps from classNames to methodNames to corresponding ActualCFGs
	 */
	private final Map> actualCFGs = new HashMap>();

	/**
	 * Control Dependence Graphs for each method.
	 *
	 * Maps from classNames to methodNames to corresponding CDGs
	 */
	private final Map> controlDependencies = new HashMap>();

	/**
	 * Cache of all created CCFGs
	 *
	 * Maps from classNames to computed CCFG of that class
	 */
	private final Map ccfgs = new HashMap();

	// retrieve graphs

	/**
	 * 

* getRawCFG *

* * @param className * a {@link java.lang.String} object. * @param methodName * a {@link java.lang.String} object. * @return a {@link org.evosuite.graphs.cfg.RawControlFlowGraph} object. */ public RawControlFlowGraph getRawCFG(String className, String methodName) { if (rawCFGs.get(className) == null) { logger.warn("Class unknown: " + className); logger.warn(rawCFGs.keySet().toString()); return null; } return rawCFGs.get(className).get(methodName); } /** *

* Getter for the field rawCFGs. *

* * @param className * a {@link java.lang.String} object. * @return a {@link java.util.Map} object. */ public Map getRawCFGs(String className) { if (rawCFGs.get(className) == null) { logger.warn("Class unknown: " + className); logger.warn(rawCFGs.keySet().toString()); return null; } return rawCFGs.get(className); } /** *

* getActualCFG *

* * @param className * a {@link java.lang.String} object. * @param methodName * a {@link java.lang.String} object. * @return a {@link org.evosuite.graphs.cfg.ActualControlFlowGraph} object. */ public ActualControlFlowGraph getActualCFG(String className, String methodName) { if (actualCFGs.get(className) == null) return null; return actualCFGs.get(className).get(methodName); } /** *

* getCDG *

* * @param className * a {@link java.lang.String} object. * @param methodName * a {@link java.lang.String} object. * @return a {@link org.evosuite.graphs.cdg.ControlDependenceGraph} object. */ public ControlDependenceGraph getCDG(String className, String methodName) { if (controlDependencies.get(className) == null) return null; return controlDependencies.get(className).get(methodName); } // register graphs /** *

* registerRawCFG *

* * @param cfg * a {@link org.evosuite.graphs.cfg.RawControlFlowGraph} object. */ public void registerRawCFG(RawControlFlowGraph cfg) { String className = cfg.getClassName(); String methodName = cfg.getMethodName(); if (className == null || methodName == null) throw new IllegalStateException( "expect class and method name of CFGs to be set before entering the GraphPool"); if (!rawCFGs.containsKey(className)) { rawCFGs.put(className, new HashMap()); } Map methods = rawCFGs.get(className); logger.debug("Added complete CFG for class " + className + " and method " + methodName); methods.put(methodName, cfg); if (Properties.WRITE_CFG) cfg.toDot(); } /** *

* registerActualCFG *

* * @param cfg * a {@link org.evosuite.graphs.cfg.ActualControlFlowGraph} * object. */ public void registerActualCFG(ActualControlFlowGraph cfg) { String className = cfg.getClassName(); String methodName = cfg.getMethodName(); if (className == null || methodName == null) throw new IllegalStateException( "expect class and method name of CFGs to be set before entering the GraphPool"); if (!actualCFGs.containsKey(className)) { actualCFGs.put(className, new HashMap()); // diameters.put(className, new HashMap()); } Map methods = actualCFGs.get(className); logger.debug("Added CFG for class " + className + " and method " + methodName); cfg.finalise(); methods.put(methodName, cfg); if (Properties.WRITE_CFG) cfg.toDot(); if (DependencyAnalysis.shouldInstrument(cfg.getClassName(), cfg.getMethodName())) { createAndRegisterControlDependence(cfg); } } private void createAndRegisterControlDependence(ActualControlFlowGraph cfg) { ControlDependenceGraph cd = new ControlDependenceGraph(cfg); String className = cd.getClassName(); String methodName = cd.getMethodName(); if (className == null || methodName == null) throw new IllegalStateException( "expect class and method name of CFGs to be set before entering the GraphPool"); if (!controlDependencies.containsKey(className)) controlDependencies.put(className, new HashMap()); Map cds = controlDependencies.get(className); cds.put(methodName, cd); if (Properties.WRITE_CFG) cd.toDot(); } public void registerControlDependence(ControlDependenceGraph cd){ String className = cd.getClassName(); String methodName = cd.getMethodName(); if (className == null || methodName == null){ throw new IllegalStateException( "expect class and method name of CFGs to be set before entering the GraphPool"); } if (!controlDependencies.containsKey(className)){ controlDependencies.put(className, new HashMap()); } controlDependencies.get(className).put(methodName,cd); } /** * Ensures this GraphPool knows the CCFG for the given class and then * returns it. * * @param className * the name of the class of the CCFG as a * {@link java.lang.String} * @return The cached CCFG of type * {@link org.evosuite.graphs.ccfg.ClassControlFlowGraph} */ public ClassControlFlowGraph getCCFG(String className) { if (!ccfgs.containsKey(className)) { ccfgs.put(className, computeCCFG(className)); } return ccfgs.get(className); } public boolean canMakeCCFGForClass(String className) { // if(!rawCFGs.containsKey(className)) // LoggingUtils.getEvoLogger().info("unable to create CCFG for "+className); return rawCFGs.containsKey(className); } /** * Computes the CCFG for the given class * * If no CFG is known for the given class, an IllegalArgumentException is * thrown * * @param className * a {@link java.lang.String} object. * @return a {@link org.evosuite.graphs.ccfg.ClassControlFlowGraph} object. */ private ClassControlFlowGraph computeCCFG(String className) { if (rawCFGs.get(className) == null) throw new IllegalArgumentException( "can't compute CCFG, don't know CFGs for class " + className); ClassCallGraph ccg = new ClassCallGraph(classLoader, className); if (Properties.WRITE_CFG) ccg.toDot(); ClassControlFlowGraph ccfg = new ClassControlFlowGraph(ccg); if (Properties.WRITE_CFG) ccfg.toDot(); return ccfg; } /** *

* clear *

*/ public void clear() { rawCFGs.clear(); actualCFGs.clear(); controlDependencies.clear(); } /** *

* clear *

* * @param className * a {@link java.lang.String} object. */ public void clear(String className) { rawCFGs.remove(className); actualCFGs.remove(className); controlDependencies.remove(className); } /** *

* clear *

* * @param className * a {@link java.lang.String} object. * @param methodName * a {@link java.lang.String} object. */ public void clear(String className, String methodName) { if (rawCFGs.containsKey(className)) rawCFGs.get(className).remove(methodName); if (actualCFGs.containsKey(className)) actualCFGs.get(className).remove(methodName); if (controlDependencies.containsKey(className)) controlDependencies.get(className).remove(methodName); } public static void clearAll(String className) { for (GraphPool pool : instanceMap.values()) { pool.clear(className); } } public static void clearAll(String className, String methodName) { for (GraphPool pool : instanceMap.values()) { pool.clear(className, methodName); } } public static void clearAll() { instanceMap.clear(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy