/******************************************************************************* * Copyright (c) 2010 Thiago Tonelli Bartolomei. * 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: * Thiago Tonelli Bartolomei - initial API and implementation ******************************************************************************/ package ca.uwaterloo.gsd.fsml.javaMappingInterpreter.analysis; import java.util.Collection; import java.util.List; import org.eclipse.jdt.core.IMember; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.ITypeRoot; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.dom.Expression; /** * A Hierarchical Call Graph Manager implements data structures and methods to keep track * of call graphs related only to types of the same hierarchy. When a type is added to the * manager, its whole hierarchy will be analyzed with respect to the method declarations and * the possible call sequences they entail. * * Note that although this manager deals with call graphs and is able to find the exact method * that will be called in a given context (i.e., it understands polymorphism), it does NOT deal * with control flow. This means that if there is a path in a method declaration that calls another * method in the hierarchy, the declaring method is assumed to call that method in any path. * * @author Thiago Tonelli Bartolomei <ttonelli@gsd.uwaterloo.ca> */ public interface IHierarchicalCallGraphManager { /** * Adds the compilation unit indicated by this type root to the manager. * * The Type Root can be an ICompilationUnit or an IClassFile. In any case, this method * will analyze the inheritance hierarchy of the class regarding the methods that are * inherited, overridden, etc. A certain hierarchy will be analyzed only once and the * results will be cached (until a clear() is called in the manager). * * @param root the compilation unit to be added */ public void addCompilationUnit(ITypeRoot root); /** * Gets the method that really is going to be executed at runtime if the target method * is called in this context type. * * This method will check if the target method was overridden somewhere in the hierarchy * of the context. If the method was not overridden, target itself will be returned. * Otherwise, the method that is available to objects of the context type will be returned. * * The target method must be a method in the hierarchy of the context. * * @param context the context type (the type of the object receiving the call) * @param target the method that is being called (can be retrieved from the method binding) * @return the available method, i.e., the method that will be actually executed at runtime * (can be target itself) or null if the method could not be found. */ public IMethod getExecutingMethod(IType context, IMethod target); /** * Return the list of methods available in this type, i.e., the methods * declared in this type plus the ones it inherits from super types. * * Note that if you just want to check if a certain method is available in the * type, you should use isMethodAvailable, which is much more efficient. * * This method will process the compilation unit of the type if necessary. * * @param type the source type * @return the list of available methods * @throws JavaModelException if cannot list the methods of this type */ public List<IMethod> getAvailableMethods(IType type) throws JavaModelException; /** * Checks if the given method is available in the given type, i.e., if it is between * the methods declared or inherited by the type. * * @param type the source type * @param method the method to search for * @return true, if the method is between the available methods, false otherwise. * @throws JavaModelException */ public boolean isMethodAvailable(IType type, IMethod method) throws JavaModelException; /** * Checks if there is a path in the call graph between this caller and this callee. * * This method will use the caller's declaring type as context * * @param caller the method calling * @param callee the method being called * @return true if there is a possibility for callee being called from caller, false otherwise */ public boolean calls(IMethod caller, IMethod callee); /** * Checks if there is a path in the call graph between this caller and this callee, having this * type as a context. * * @param context the context type * @param caller the method calling * @param callee the method being called * @return true if there is a possibility for callee being called from caller, false otherwise */ public boolean calls(IType context, IMethod caller, IMethod callee); /** * Checks if there is a path in the call graph between any method in this context and the callee * * @param context the context type * @param callee the method being called * @return true if there is a possibility for callee being called from caller, false otherwise */ public boolean calls(IType context, IMethod callee); /** * Checks if there is a path in the call graph between this caller and this callee. * * If the caller is an IType, we search for all methods in the type (and inherited). If it * is an IMethod, we search only for a connection between this method and the callee. * * @param caller the method or type calling * @param callee the method being called * @return true if there is a possibility for callee being called from caller, false otherwise */ public boolean calls(IMember caller, IMethod callee); /** * Finds the possible implementations of this method (which was found on this type) on the hierarchy * of this type. * * If the method is an actual implementation of itself (i.e., if it is not abstract or * inside an interface), then it will also be returned in the list. * * @param type * @param method * @return */ public List<IMethod> findImplementations(IType type, IMethod method); /** * Called before starting the analysis, so that the manager has a chance to initialize */ public void init(); /** * Clears all cached information in this manager */ public void finish(); /** * Michal: related to the experimental 'callGraph' search scope * This method should be called before the analysis starts to set the methods for which method calls will be recorded. * @param targetMethods */ public void setTargetMethods(Collection<IMethod> targetMethods); /** * Michal: related to the experimental 'callGraph' search scope * @param targetMethod * @return method invocations of the given target method reachable in the call graph. */ public List<Expression> getCalls(IMethod targetIMethod, IType contextIType); }