summaryrefslogtreecommitdiff
path: root/src/main/java/org/javacs/Ptr.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/javacs/Ptr.java')
-rw-r--r--src/main/java/org/javacs/Ptr.java99
1 files changed, 99 insertions, 0 deletions
diff --git a/src/main/java/org/javacs/Ptr.java b/src/main/java/org/javacs/Ptr.java
new file mode 100644
index 0000000..71520a3
--- /dev/null
+++ b/src/main/java/org/javacs/Ptr.java
@@ -0,0 +1,99 @@
+package org.javacs;
+
+import com.sun.source.tree.ClassTree;
+import com.sun.source.tree.MethodTree;
+import com.sun.source.tree.VariableTree;
+import com.sun.source.util.TreePath;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.StringJoiner;
+import java.util.logging.Logger;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+
+/** Ptr is a serialized TreePath, suitable for storing in Index and remember across compiler invocations */
+public class Ptr {
+ private final String path;
+
+ public Ptr(TreePath path) {
+ var packageName = path.getCompilationUnit().getPackageName();
+ var rev = new ArrayList<CharSequence>();
+ while (path != null) {
+ var part = path.getLeaf();
+ if (part instanceof ClassTree) {
+ var cls = (ClassTree) part;
+ rev.add(cls.getSimpleName());
+ } else if (part instanceof MethodTree) {
+ var method = (MethodTree) part;
+ // TODO overloads
+ rev.add(method.getName());
+ } else if (part instanceof VariableTree) {
+ var variable = (VariableTree) part;
+ rev.add(variable.getName());
+ }
+ path = path.getParentPath();
+ }
+ if (packageName != null) rev.add(packageName.toString());
+ var name = reverseAndJoin(rev, ".");
+ if (!name.matches("(\\w+\\.)*(\\w+|<init>)")) LOG.warning(String.format("`%s` doesn't look like a name", name));
+ this.path = name;
+ }
+
+ public Ptr(Element e) {
+ var rev = new ArrayList<CharSequence>();
+ while (e != null) {
+ if (e instanceof PackageElement) {
+ var pkg = (PackageElement) e;
+ if (!pkg.isUnnamed()) rev.add(pkg.getQualifiedName());
+ } else if (e instanceof TypeElement) {
+ var type = (TypeElement) e;
+ rev.add(type.getSimpleName());
+ } else if (e instanceof ExecutableElement) {
+ var method = (ExecutableElement) e;
+ // TODO overloads
+ rev.add(method.getSimpleName());
+ } else if (e instanceof VariableElement) {
+ var field = (VariableElement) e;
+ rev.add(field.getSimpleName());
+ }
+ e = e.getEnclosingElement();
+ }
+ var name = reverseAndJoin(rev, ".");
+ if (!name.matches("(\\w+\\.)*(\\w+|<init>)")) LOG.warning(String.format("`%s` doesn't look like a name", name));
+ this.path = name;
+ }
+
+ private static String reverseAndJoin(List<CharSequence> parts, String sep) {
+ var join = new StringJoiner(sep);
+ for (var i = parts.size() - 1; i >= 0; i--) {
+ join.add(parts.get(i));
+ }
+ return join.toString();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof Ptr)) return false;
+ var that = (Ptr) other;
+ return this.path.equals(that.path);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(path);
+ }
+
+ public boolean inPackage(String packageName) {
+ return path.startsWith(packageName);
+ }
+
+ public boolean inClass(String qualifiedName) {
+ return path.startsWith(qualifiedName);
+ }
+
+ private static final Logger LOG = Logger.getLogger("main");
+}