Repository: kythe/kythe
Pull request #5611 (2023-05-01 18:35:40)

feat(java_indexer): mark this/super ctor calls as direct


Patch:
diff --git a/kythe/java/com/google/devtools/kythe/analyzers/java/JavaNode.java b/kythe/java/com/google/devtools/kythe/analyzers/java/JavaNode.java
index 526f6001d..5ffcda7bb 100644
--- a/kythe/java/com/google/devtools/kythe/analyzers/java/JavaNode.java
+++ b/kythe/java/com/google/devtools/kythe/analyzers/java/JavaNode.java
@@ -19,6 +19,7 @@ package com.google.devtools.kythe.analyzers.java;
 import com.google.common.collect.ImmutableList;
 import com.google.devtools.kythe.analyzers.base.EntrySet;
 import com.google.devtools.kythe.proto.Storage.VName;
+import com.sun.tools.javac.code.Symbol;
 import java.util.List;
 import java.util.Optional;
 
@@ -28,6 +29,7 @@ class JavaNode {
   // (i.e. types and abstractions)
   private final VName vName;
   private JavaNode type;
+  private Symbol sym;
 
   private ImmutableList<VName> classConstructors = ImmutableList.of();
   private Optional<VName> classInit = Optional.empty();
@@ -71,6 +73,15 @@ class JavaNode {
     return type;
   }
 
+  JavaNode setSymbol(Symbol sym) {
+    this.sym = sym;
+    return this;
+  }
+
+  Symbol getSymbol() {
+    return sym;
+  }
+
   JavaNode setClassConstructors(List<VName> constructors) {
     this.classConstructors = ImmutableList.copyOf(constructors);
     return this;
diff --git a/kythe/java/com/google/devtools/kythe/analyzers/java/KytheTreeScanner.java b/kythe/java/com/google/devtools/kythe/analyzers/java/KytheTreeScanner.java
index ef146ec73..5211a04db 100644
--- a/kythe/java/com/google/devtools/kythe/analyzers/java/KytheTreeScanner.java
+++ b/kythe/java/com/google/devtools/kythe/analyzers/java/KytheTreeScanner.java
@@ -906,7 +906,12 @@ public class KytheTreeScanner extends JCTreeScanner<JavaNode, TreeContext> {
       return emitDiagnostic(ctx, "error analyzing method", null, null);
     }
 
-    emitAnchor(ctx, EdgeKind.REF_CALL, method.getVName());
+    emitAnchor(
+        ctx,
+        Optional.ofNullable(method.getSymbol()).map(Symbol::isConstructor).orElse(false)
+            ? EdgeKind.REF_CALL_DIRECT
+            : EdgeKind.REF_CALL,
+        method.getVName());
     return method;
   }
 
@@ -1199,7 +1204,8 @@ public class KytheTreeScanner extends JCTreeScanner<JavaNode, TreeContext> {
   /** Returns the {@link JavaNode} associated with a {@link Symbol} or {@code null}. */
   private @Nullable JavaNode getJavaNode(Symbol sym) {
     if (sym.getKind() == ElementKind.PACKAGE) {
-      return new JavaNode(entrySets.newPackageNodeAndEmit((PackageSymbol) sym).getVName());
+      return new JavaNode(entrySets.newPackageNodeAndEmit((PackageSymbol) sym).getVName())
+          .setSymbol(sym);
     }
 
     VName jvmNode = getJvmNode(sym);
@@ -1207,7 +1213,10 @@ public class KytheTreeScanner extends JCTreeScanner<JavaNode, TreeContext> {
     JavaNode node =
         signatureGenerator
             .getSignature(sym)
-            .map(sig -> new JavaNode(entrySets.getNode(signatureGenerator, sym, sig, null)))
+            .map(
+                sig ->
+                    new JavaNode(entrySets.getNode(signatureGenerator, sym, sig, null))
+                        .setSymbol(sym))
             .orElse(null);
     if (node != null && jvmNode != null) {
       entrySets.emitEdge(node.getVName(), EdgeKind.NAMED, jvmNode);
@@ -1400,7 +1409,8 @@ public class KytheTreeScanner extends JCTreeScanner<JavaNode, TreeContext> {
       // This usually indicates a problem with the compilation's bootclasspath.
       return emitDiagnostic(null, "failed to resolve " + sym, null, null);
     }
-    return new JavaNode(entrySets.getNode(signatureGenerator, sym, signature.get(), null, null));
+    return new JavaNode(entrySets.getNode(signatureGenerator, sym, signature.get(), null, null))
+        .setSymbol(sym);
   }
 
   private void emitMetadata(Span span, VName node) {


Test patch:
diff --git a/kythe/javatests/com/google/devtools/kythe/analyzers/java/testdata/pkg/Classes.java b/kythe/javatests/com/google/devtools/kythe/analyzers/java/testdata/pkg/Classes.java
index e1d228720..5cf328ba5 100644
--- a/kythe/javatests/com/google/devtools/kythe/analyzers/java/testdata/pkg/Classes.java
+++ b/kythe/javatests/com/google/devtools/kythe/analyzers/java/testdata/pkg/Classes.java
@@ -20,12 +20,22 @@ public class Classes {
 
   //- @Subclass defines/binding SubclassOne
   private static class Subclass extends Classes {
-    //- ImplicitSuperCall ref/call DefaultCtor
+    //- ImplicitSuperCall ref/call/direct DefaultCtor
     //- ImplicitSuperCall.loc/start @^"{}"
     //- ImplicitSuperCall.loc/end @^"{}"
     //- ImplicitSuperCall childof SubclassCtor
     //- @Subclass defines/binding SubclassCtor
     Subclass() {}
+
+    Subclass(String s) {
+      //- @"this()" ref/call/direct SubclassCtor
+      this();
+    }
+
+    Subclass(int i) {
+      //- @"super()" ref/call/direct DefaultCtor
+      super();
+    }
   }
 
   //- @Subclass2 defines/binding SubclassTwo
@@ -42,7 +52,7 @@ public class Classes {
     //- ImplicitSubclassTwoCtor.node/kind function
     //- ImplicitSubclassTwoCtor.subkind constructor
     //- ImplicitSubclassTwoCtor childof SubclassTwo
-    //- ExtraImplicitSuperCall ref/call DefaultCtor
+    //- ExtraImplicitSuperCall ref/call/direct DefaultCtor
     //- ExtraImplicitSuperCall childof ImplicitSubclassTwoCtor
   }
 
@@ -77,7 +87,6 @@ public class Classes {
     //- @LocalClass defines/binding LC
     //- LC childof LF
     class LocalClass {}
-    ;
   }
 
   //- ClassInit.node/kind function
@@ -88,7 +97,6 @@ public class Classes {
     //- @LocalClassInStaticInitializer defines/binding LCISI
     //- LCISI childof ClassInit
     class LocalClassInStaticInitializer {}
-    ;
   }
 }