package soot.poc;

import java.util.List;

import soot.Body;
import soot.Scene;
import soot.SootClass;
import soot.SootMethod;
import soot.Unit;
import soot.poc.inter.Definition;
import soot.poc.reachingdef.ReachingDefinitions;
import soot.poc.reachingdef.SimpleReachingDefinitions;
import soot.toolkits.graph.ExceptionalUnitGraph;
import soot.toolkits.graph.UnitGraph;

public class RunDefsAtExitAnalysis
{
	public static void main(String[] _args) {
		_args = new String[] {"br.ufpe.cin.soot.poc.testers.SimpleClass"};
		
		if (_args.length == 0) {
			System.out.println("Usage: java RunDefsAtExitAnalysis class_to_analyse");
			System.exit(0);
		}
		
		SootClass sClass = Scene.v().loadClassAndSupport(_args[0]);		
		sClass.setApplicationClass();
		
		List<SootMethod> methods = sClass.getMethods();
		for (SootMethod method : methods)
		{
			Body body = method.retrieveActiveBody();

			System.out.println("=======================================");			
			System.out.println("Method: " + method.getName());
			
			UnitGraph graph = new ExceptionalUnitGraph(body);
			ReachingDefinitions analysis = new SimpleReachingDefinitions(graph);
			
			for (Unit unit: graph.getTails())
			{
				List<Definition> out = analysis.getReachingDefinitionsAfter(unit);

				System.out.print("Defs@Exit {");
				String sep = "";
				for (Definition definition: out) {
					System.out.print(sep + definition.toString());
					sep = ", ";
				}
				System.out.println("}");
			}
		}
	}
}
