diff options
Diffstat (limited to 'annotation-file-utilities/src/annotator/scanner/MethodCallScanner.java')
-rw-r--r-- | annotation-file-utilities/src/annotator/scanner/MethodCallScanner.java | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/annotation-file-utilities/src/annotator/scanner/MethodCallScanner.java b/annotation-file-utilities/src/annotator/scanner/MethodCallScanner.java new file mode 100644 index 0000000..a104519 --- /dev/null +++ b/annotation-file-utilities/src/annotator/scanner/MethodCallScanner.java @@ -0,0 +1,102 @@ +package annotator.scanner; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.sun.source.tree.MethodInvocationTree; +import com.sun.source.tree.Tree; +import com.sun.source.util.TreePath; + +public class MethodCallScanner extends CommonScanner { + + /** + * Computes the index of the given method invocation amongst all + * method invocation trees inside its method, using 0-based indexing. + * + * @param origpath the path ending in the given method invocation tree + * @param tree the method invocation tree to search for + * @return the index of the given method invocation tree + */ + public static int indexOfMethodCallTree(TreePath origpath, Tree tree) { + TreePath path = findCountingContext(origpath); + if (path == null) { + return -1; + } + + MethodCallScanner mcs = new MethodCallScanner(tree); + mcs.scan(path, null); + return mcs.index; + } + + private int index; + private boolean done; + private final Tree tree; + + /** + * Creates an InstanceOfScanner that will scan the source tree for the + * given node representing the method invocation to find. + * @param tree the given method invocation to search for + */ + private MethodCallScanner(Tree tree) { + this.index = -1; + this.done = false; + this.tree = tree; + } + + @Override + public Void visitMethodInvocation(MethodInvocationTree node, Void p) { + if (!done) { + index++; + } + if (tree == node) { + done = true; + } + return super.visitMethodInvocation(node, p); + } + + // Map from name of a method to a list of bytecode offsets of all + // method invocations in that method. + private static Map<String, List<Integer>> methodNameToMethodCallOffsets = + new HashMap<String, List<Integer>>(); + + /** + * Adds a lambda expression bytecode offset to the current list of + * offsets for methodName. This method must be called with + * monotonically increasing offsets for any one method. + * + * @param methodName the name of the method + * @param offset the offset to add + */ + public static void addMethodCallToMethod(String methodName, Integer offset) { + List<Integer> offsetList = + methodNameToMethodCallOffsets.get(methodName); + if (offsetList == null) { + offsetList = new ArrayList<Integer>(); + methodNameToMethodCallOffsets.put(methodName, offsetList); + } + offsetList.add(offset); + } + + /** + * Returns the index of the given offset within the list of offsets + * for the given method, using 0-based indexing, or returns a negative + * number if the offset is not one of the offsets in the context. + * + * @param methodName the name of the method + * @param offset the offset of the lambda expression + * @return the index of the given offset, or a negative number + * if the offset does not exist inside the context + */ + public static Integer + getMethodCallIndex(String methodName, Integer offset) { + List<Integer> offsetList = + methodNameToMethodCallOffsets.get(methodName); + if (offsetList == null) { + return -1; + } + + return offsetList.indexOf(offset); + } +} |