aboutsummaryrefslogtreecommitdiff
path: root/annotation-file-utilities/src/annotator/scanner/MethodCallScanner.java
diff options
context:
space:
mode:
Diffstat (limited to 'annotation-file-utilities/src/annotator/scanner/MethodCallScanner.java')
-rw-r--r--annotation-file-utilities/src/annotator/scanner/MethodCallScanner.java102
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);
+ }
+}