Repository: kythe/kythe
Pull request #4740 (2020-11-10 21:54:44)

fix(java_indexer): blame callsites under static fields on the clinit


Patch:
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 a2987f616..79568e2db 100644
--- a/kythe/java/com/google/devtools/kythe/analyzers/java/KytheTreeScanner.java
+++ b/kythe/java/com/google/devtools/kythe/analyzers/java/KytheTreeScanner.java
@@ -698,7 +698,6 @@ public class KytheTreeScanner extends JCTreeScanner<JavaNode, TreeContext> {
                 .build());
       }
     }
-    scan(varDef.getInitializer(), ctx);
 
     VName varNode =
         entrySets.getNode(
@@ -727,7 +726,12 @@ public class KytheTreeScanner extends JCTreeScanner<JavaNode, TreeContext> {
 
     if (varDef.getModifiers().getFlags().contains(Modifier.STATIC)) {
       entrySets.getEmitter().emitFact(varNode, "/kythe/tag/static", "");
+
+      if (varDef.sym.getKind().isField() && owner.getNode().getClassInit().isPresent()) {
+        ctx.setNode(new JavaNode(owner.getNode().getClassInit().get()));
+      }
     }
+    scan(varDef.getInitializer(), ctx);
 
     JavaNode typeNode = scan(varDef.getType(), ctx);
     if (typeNode != null) {
diff --git a/kythe/java/com/google/devtools/kythe/analyzers/java/TreeContext.java b/kythe/java/com/google/devtools/kythe/analyzers/java/TreeContext.java
index b36315566..607915acb 100644
--- a/kythe/java/com/google/devtools/kythe/analyzers/java/TreeContext.java
+++ b/kythe/java/com/google/devtools/kythe/analyzers/java/TreeContext.java
@@ -24,6 +24,7 @@ import com.sun.tools.javac.tree.JCTree.JCBlock;
 import com.sun.tools.javac.tree.JCTree.JCClassDecl;
 import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
 import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
+import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -98,6 +99,8 @@ class TreeContext {
     while (parent != null
         && !(parent.getTree() instanceof JCMethodDecl
             || parent.getTree() instanceof JCClassDecl
+            || (parent.getTree() instanceof JCVariableDecl // static fields
+                && parent.getNode() != null)
             || parent.getTree() instanceof JCBlock)) {
       parent = parent.up();
     }


Test patch:
diff --git a/kythe/javatests/com/google/devtools/kythe/analyzers/java/testdata/pkg/Callgraph.java b/kythe/javatests/com/google/devtools/kythe/analyzers/java/testdata/pkg/Callgraph.java
index cf35a2529..04e2c4047 100644
--- a/kythe/javatests/com/google/devtools/kythe/analyzers/java/testdata/pkg/Callgraph.java
+++ b/kythe/javatests/com/google/devtools/kythe/analyzers/java/testdata/pkg/Callgraph.java
@@ -11,14 +11,22 @@ public class Callgraph {
   //- ClassInit childof Class
   //- !{ ClassInit.subkind "constructor" }
 
+  //- NonStaticGCall.loc/start @^"g()"
+  //- NonStaticGCall.loc/end @$"g()"
+  //- NonStaticGCall ref/call G
+  //- NonStaticGCall childof ECtor
+  //- NonStaticGCall childof SCtor
+  //- !{ NonStaticGCall childof Class }
+  //- !{ NonStaticGCall childof ClassInit }
+  final int ZERO = g();
+
   //- StaticGCall.loc/start @^"g()"
   //- StaticGCall.loc/end @$"g()"
   //- StaticGCall ref/call G
-  //- StaticGCall childof ECtor
-  //- StaticGCall childof SCtor
-  //- !{ StaticGCall childof Class }
-  //- !{ StaticGCall childof ClassInit }
-  final int ZERO = g();
+  //- StaticGCall childof ClassInit
+  //- !{ StaticGCall childof ECtor }
+  //- !{ StaticGCall childof SCtor }
+  static final int ZERO_TWO = g();
 
   static {
     //- StaticBlockGCall.loc/start @^"g()"