nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: kythe/kythe
Pull request #4161 (2019-10-24 18:00:49)

chore: Record kzip size in KzipInfo


Patch:
diff --git a/kythe/go/platform/kzip/info/info.go b/kythe/go/platform/kzip/info/info.go
index 548823b92..1da4de869 100644
--- a/kythe/go/platform/kzip/info/info.go
+++ b/kythe/go/platform/kzip/info/info.go
@@ -32,10 +32,15 @@ import (
 // stats.
 const unspecifiedCorpus = "__UNSPECIFIED_CORPUS__"
 
-// KzipInfo scans a kzip and counts contained files and units, giving a breakdown by corpus and language.
-func KzipInfo(f kzip.File, scanOpts ...kzip.ScanOption) (*apb.KzipInfo, error) {
+// KzipInfo scans the kzip in f and counts contained files and units, giving a breakdown by corpus
+// and language. It also records the size (in bytes) of the kzip specified by fileSize in the
+// returned KzipInfo.
+func KzipInfo(f kzip.File, fileSize int64, scanOpts ...kzip.ScanOption) (*apb.KzipInfo, error) {
 	// Get file and unit counts broken down by corpus, language.
-	kzipInfo := &apb.KzipInfo{Corpora: make(map[string]*apb.KzipInfo_CorpusInfo)}
+	kzipInfo := &apb.KzipInfo{
+		Corpora: make(map[string]*apb.KzipInfo_CorpusInfo),
+		Size:    fileSize,
+	}
 
 	err := kzip.Scan(f, func(rd *kzip.Reader, u *kzip.Unit) error {
 		srcs := stringset.New(u.Proto.SourceFile...)
@@ -141,6 +146,7 @@ func MergeKzipInfo(infos []*apb.KzipInfo) *apb.KzipInfo {
 				c.Count += sources.GetCount()
 			}
 		}
+		kzipInfo.Size += i.Size
 	}
 	return kzipInfo
 }
diff --git a/kythe/go/platform/tools/kzip/infocmd/infocmd.go b/kythe/go/platform/tools/kzip/infocmd/infocmd.go
index c094be5eb..68d7e3b44 100644
--- a/kythe/go/platform/tools/kzip/infocmd/infocmd.go
+++ b/kythe/go/platform/tools/kzip/infocmd/infocmd.go
@@ -73,7 +73,11 @@ func (c *infoCommand) Execute(ctx context.Context, fs *flag.FlagSet, _ ...interf
 		return c.Fail("Invalid --write_format. Can be 'json' or 'proto'.")
 	}
 
-	kzipInfo, err := info.KzipInfo(f, kzip.ReadConcurrency(c.readConcurrency))
+	s, err := os.Stat(c.input)
+	if err != nil {
+		return c.Fail("Couldn't stat kzip file: %v", err)
+	}
+	kzipInfo, err := info.KzipInfo(f, s.Size(), kzip.ReadConcurrency(c.readConcurrency))
 	if err != nil {
 		return c.Fail("Scanning kzip: %v", err)
 	}


Test patch:
diff --git a/kythe/go/platform/kzip/info/info_test.go b/kythe/go/platform/kzip/info/info_test.go
index 386f6b4da..b789b0398 100644
--- a/kythe/go/platform/kzip/info/info_test.go
+++ b/kythe/go/platform/kzip/info/info_test.go
@@ -46,6 +46,7 @@ func TestMergeKzipInfo(t *testing.T) {
 					},
 				},
 			},
+			Size: 10,
 		},
 		{
 			Corpora: map[string]*apb.KzipInfo_CorpusInfo{
@@ -96,6 +97,7 @@ func TestMergeKzipInfo(t *testing.T) {
 					},
 				},
 			},
+			Size: 30,
 		},
 	}
 
@@ -153,6 +155,7 @@ func TestMergeKzipInfo(t *testing.T) {
 				},
 			},
 		},
+		Size: 40,
 	}
 	wantTotal := apb.KzipInfo_CorpusInfo{
 		LanguageCompilationUnits: map[string]*apb.KzipInfo_CorpusInfo_CompilationUnits{
Repository: kythe/kythe
Pull request #4196 (2019-11-07 23:06:48)

fix(kzip info): trim extra spaces from error message
this works around the fact that log("%v", proto) is inconsistent about spacing in open source go vs google3


Patch:
diff --git a/kythe/go/platform/kzip/info/info.go b/kythe/go/platform/kzip/info/info.go
index 82b1351f5..a46428272 100644
--- a/kythe/go/platform/kzip/info/info.go
+++ b/kythe/go/platform/kzip/info/info.go
@@ -20,6 +20,7 @@ package info // import "kythe.io/kythe/go/platform/kzip/info"
 import (
 	"fmt"
 	"log"
+	"strings"
 
 	"bitbucket.org/creachadair/stringset"
 
@@ -52,7 +53,8 @@ func KzipInfo(f kzip.File, fileSize int64, scanOpts ...kzip.ScanOption) (*apb.Kz
 		for _, ri := range u.Proto.RequiredInput {
 			riCorpus := requiredInputCorpus(u, ri)
 			if riCorpus == "" {
-				msg := fmt.Sprintf("unable to determine corpus for required_input %q in CU %v", ri.Info.Path, u.Proto.GetVName())
+				// Trim spaces to work around the fact that log("%v", proto) is inconsistent about trailing spaces in google3 vs open-source go.
+				msg := strings.TrimSpace(fmt.Sprintf("unable to determine corpus for required_input %q in CU %v", ri.Info.Path, u.Proto.GetVName()))
 				kzipInfo.CriticalKzipErrors = append(kzipInfo.CriticalKzipErrors, msg)
 				return nil
 			}


Test patch:
diff --git a/kythe/go/platform/kzip/info/info_test.go b/kythe/go/platform/kzip/info/info_test.go
index 106d12dbd..20042e067 100644
--- a/kythe/go/platform/kzip/info/info_test.go
+++ b/kythe/go/platform/kzip/info/info_test.go
@@ -212,7 +212,7 @@ var infoTests = []struct {
 			},
 		},
 		&apb.KzipInfo{
-			CriticalKzipErrors: []string{"unable to determine corpus for required_input \"file1.py\" in CU language:\"python\" "},
+			CriticalKzipErrors: []string{"unable to determine corpus for required_input \"file1.py\" in CU language:\"python\""},
 		},
 	},
 }
Repository: kythe/kythe
Pull request #4201 (2019-11-11 18:43:13)

feat(serving): return known generators in DecorationsReply
Plumbing logic for #4177


Patch:
diff --git a/kythe/go/serving/xrefs/BUILD b/kythe/go/serving/xrefs/BUILD
index 1a3ffe264..7d77fe835 100644
--- a/kythe/go/serving/xrefs/BUILD
+++ b/kythe/go/serving/xrefs/BUILD
@@ -45,6 +45,7 @@ go_test(
     visibility = ["//visibility:private"],
     deps = [
         "//kythe/go/test/testutil",
+        "//kythe/go/util/compare",
         "@org_golang_x_text//encoding:go_default_library",
         "@org_golang_x_text//encoding/unicode:go_default_library",
         "@org_golang_x_text//transform:go_default_library",
diff --git a/kythe/go/serving/xrefs/xrefs.go b/kythe/go/serving/xrefs/xrefs.go
index 5b6566515..9d0e9a353 100644
--- a/kythe/go/serving/xrefs/xrefs.go
+++ b/kythe/go/serving/xrefs/xrefs.go
@@ -244,7 +244,10 @@ func (t *Table) Decorations(ctx context.Context, req *xpb.DecorationsRequest) (*
 		return nil, err
 	}
 
-	reply := &xpb.DecorationsReply{Location: loc}
+	reply := &xpb.DecorationsReply{
+		Location:    loc,
+		GeneratedBy: decor.GeneratedBy,
+	}
 
 	if req.SourceText {
 		reply.Encoding = decor.File.Encoding


Test patch:
diff --git a/kythe/go/serving/xrefs/xrefs_test.go b/kythe/go/serving/xrefs/xrefs_test.go
index 509bf4e1e..7414cf740 100644
--- a/kythe/go/serving/xrefs/xrefs_test.go
+++ b/kythe/go/serving/xrefs/xrefs_test.go
@@ -25,6 +25,7 @@ import (
 	"kythe.io/kythe/go/services/xrefs"
 	"kythe.io/kythe/go/storage/table"
 	"kythe.io/kythe/go/test/testutil"
+	"kythe.io/kythe/go/util/compare"
 	"kythe.io/kythe/go/util/kytheuri"
 	"kythe.io/kythe/go/util/span"
 
@@ -276,6 +277,14 @@ var (
 					},
 				},
 			},
+			{
+				File: &srvpb.File{
+					Ticket:   "kythe://corpus?path=/some/proto.proto?root=generated",
+					Text:     []byte("// Generated by /some/proto.proto"),
+					Encoding: "utf-8",
+				},
+				GeneratedBy: []string{"kythe://corpus?path=/some/proto.proto"},
+			},
 		},
 
 		RefSets: []*srvpb.PagedCrossReferences{{
@@ -879,6 +888,23 @@ func TestDecorationsSourceText(t *testing.T) {
 	}
 }
 
+func TestDecorationsGeneratedBy(t *testing.T) {
+	st := tbl.Construct(t)
+	reply, err := st.Decorations(ctx, &xpb.DecorationsRequest{
+		Location: &xpb.Location{Ticket: "kythe://corpus?path=/some/proto.proto?root=generated"},
+	})
+	testutil.FatalOnErrT(t, "DecorationsRequest error: %v", err)
+
+	expected := &xpb.DecorationsReply{
+		Location:    &xpb.Location{Ticket: "kythe://corpus?path=/some/proto.proto?root=generated"},
+		GeneratedBy: []string{"kythe://corpus?path=/some/proto.proto"},
+	}
+
+	if diff := compare.ProtoDiff(expected, reply); diff != "" {
+		t.Fatalf("Unexpected diff (- expected; + found):\n%s", diff)
+	}
+}
+
 func TestDecorationsDiagnostics(t *testing.T) {
 	d := tbl.Decorations[1]
Repository: kythe/kythe
Pull request #4375 (2020-02-15 23:17:51)

fix(vfs): use correct FileInfo in globWalker


Patch:
diff --git a/kythe/go/platform/vfs/vfs.go b/kythe/go/platform/vfs/vfs.go
index 201096018..6afca34be 100644
--- a/kythe/go/platform/vfs/vfs.go
+++ b/kythe/go/platform/vfs/vfs.go
@@ -323,7 +323,7 @@ func (gw *globWalker) walk(ctx context.Context, path string, info os.FileInfo, w
 			if err := walkFn(name, fileInfo, err); err != nil && err != filepath.SkipDir {
 				return err
 			}
-		} else if err := gw.walk(ctx, name, info, walkFn); err != nil {
+		} else if err := gw.walk(ctx, name, fileInfo, walkFn); err != nil {
 			if !fileInfo.IsDir() || err != filepath.SkipDir {
 				return err
 			}


Test patch:
diff --git a/kythe/go/platform/vfs/vfs_test.go b/kythe/go/platform/vfs/vfs_test.go
index a714c1160..23f48f9fd 100644
--- a/kythe/go/platform/vfs/vfs_test.go
+++ b/kythe/go/platform/vfs/vfs_test.go
@@ -26,6 +26,11 @@ import (
 
 const testDataDir = "testdata"
 
+type walkResult struct {
+	Path string
+	Info string
+}
+
 func TestGlobWalker(t *testing.T) {
 	byglob, err := collectFiles(&globWalker{LocalFS{}}, testutil.TestFilePath(t, testDataDir))
 	testutil.FatalOnErrT(t, "unable to collect files from glob", err)
@@ -34,13 +39,13 @@ func TestGlobWalker(t *testing.T) {
 	testutil.FatalOnErrT(t, "local and glob walks differ", testutil.DeepEqual(bylocal, byglob))
 }
 
-func collectFiles(walk Walker, root string) ([]string, error) {
-	var files []string
-	return files, walk.Walk(context.Background(), root, func(path string, info os.FileInfo, err error) error {
+func collectFiles(walk Walker, root string) ([]walkResult, error) {
+	var results []walkResult
+	return results, walk.Walk(context.Background(), root, func(path string, info os.FileInfo, err error) error {
 		if err != nil {
 			return err
 		}
-		files = append(files, path)
+		results = append(results, walkResult{path, info.Name()})
 		return nil
 	})
 }
Repository: kythe/kythe
Pull request #4738 (2020-11-10 20:00:52)

fix(java_indexer): special-case builtin Array class lookup


Patch:
diff --git a/kythe/java/com/google/devtools/kythe/analyzers/java/JavaEntrySets.java b/kythe/java/com/google/devtools/kythe/analyzers/java/JavaEntrySets.java
index 3093e498f..b711389f8 100644
--- a/kythe/java/com/google/devtools/kythe/analyzers/java/JavaEntrySets.java
+++ b/kythe/java/com/google/devtools/kythe/analyzers/java/JavaEntrySets.java
@@ -57,6 +57,8 @@ import org.checkerframework.checker.nullness.qual.Nullable;
 public class JavaEntrySets extends KytheEntrySets {
   private static final FluentLogger logger = FluentLogger.forEnclosingClass();
 
+  private static final String ARRAY_BUILTIN_CLASS = "Array";
+
   private final Map<Symbol, VName> symbolNodes = new HashMap<>();
   private final Set<Symbol> symbolsDocumented = new HashSet<>();
   private final Map<Symbol, Integer> symbolHashes = new HashMap<>();
@@ -353,6 +355,8 @@ public class JavaEntrySets extends KytheEntrySets {
   private VName lookupVName(@Nullable ClassSymbol cls) {
     if (cls == null) {
       return null;
+    } else if (cls.getQualifiedName().toString().equals(ARRAY_BUILTIN_CLASS)) {
+      return newBuiltinAndEmit("array").getVName();
     }
     VName clsVName = lookupVName(getDigest(cls.classfile));
     return clsVName != null ? clsVName : lookupVName(getDigest(cls.sourcefile));


Test patch:
diff --git a/kythe/javatests/com/google/devtools/kythe/analyzers/java/testdata/pkg/SpecialMembers.java b/kythe/javatests/com/google/devtools/kythe/analyzers/java/testdata/pkg/SpecialMembers.java
index 9b6d33f09..fde60d798 100644
--- a/kythe/javatests/com/google/devtools/kythe/analyzers/java/testdata/pkg/SpecialMembers.java
+++ b/kythe/javatests/com/google/devtools/kythe/analyzers/java/testdata/pkg/SpecialMembers.java
@@ -2,16 +2,20 @@ package pkg;
 
 public final class SpecialMembers {
   public static void main(String[] args) {
-    // TODO(schroederc): handle special members better than not crashing
-
     //- @length ref Length
-    //- Length.node/kind diagnostic
+    //- Length.node/kind variable
     System.err.println(args.length);
 
     //- @clone ref Clone
-    //- Clone.node/kind diagnostic
+    //- Clone.node/kind function
     String[] arrayClone = args.clone();
 
+    int[] intArray = new int[]{1, 2, 3};
+    //- @clone ref Clone
+    intArray.clone();
+    //- @length ref Length
+    System.err.println(intArray.length);
+
     //- @getClass ref GetClass
     //- GetClass.node/kind function
     Class<?> arrayClass = args.getClass();
Repository: kythe/kythe
Pull request #4739 (2020-11-10 21:30:39)

fix(java_indexer): add zero-length definition for cinit


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 a0a8ca5a1..a2987f616 100644
--- a/kythe/java/com/google/devtools/kythe/analyzers/java/KytheTreeScanner.java
+++ b/kythe/java/com/google/devtools/kythe/analyzers/java/KytheTreeScanner.java
@@ -446,8 +446,20 @@ public class KytheTreeScanner extends JCTreeScanner<JavaNode, TreeContext> {
     node.setClassConstructors(constructors);
 
     // TODO(schroeder): flesh out cinit w/ MarkedSource
-    node.setClassInit(entrySets.newClassInitAndEmit(classNode).getVName());
-    entrySets.emitEdge(node.getClassInit().get(), EdgeKind.CHILDOF, classNode);
+    VName classInit = entrySets.newClassInitAndEmit(classNode).getVName();
+    node.setClassInit(classInit);
+    entrySets.emitEdge(classInit, EdgeKind.CHILDOF, classNode);
+    if (classIdent != null) {
+      // Emit implicit zero-length definition for the class static initializer.
+      emitAnchor(
+          entrySets.newAnchorAndEmit(
+              filePositions,
+              new Span(classIdent.getStart(), classIdent.getStart()),
+              ctx.getSnippet()),
+          EdgeKind.DEFINES,
+          classInit,
+          ImmutableList.of(classNode));
+    }
 
     for (JCTree member : classDef.getMembers()) {
       if (member instanceof JCMethodDecl) {


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 706af42a9..cf35a2529 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
@@ -1,6 +1,9 @@
 package pkg;
 
 //- @Callgraph defines/binding Class
+//- ClassInitDef.loc/start @^"Callgraph"
+//- ClassInitDef.loc/end @^"Callgraph"
+//- ClassInitDef defines ClassInit
 public class Callgraph {
 
   // Implicit static class initializer
Repository: kythe/kythe
Pull request #5608 (2023-04-28 22:45:34)

feat(go_indexer): render context namespaces recursively in RenderQualifiedName.
This is an export of an internal change.



Patch:
diff --git a/kythe/go/util/markedsource/markedsource.go b/kythe/go/util/markedsource/markedsource.go
index 520a97250..492be1f2e 100644
--- a/kythe/go/util/markedsource/markedsource.go
+++ b/kythe/go/util/markedsource/markedsource.go
@@ -147,8 +147,10 @@ func RenderQualifiedName(ms *cpb.MarkedSource) *cpb.SymbolInfo {
 		}
 		var quals []string
 		for _, kid := range ctx.Child {
-			if kid.Kind == cpb.MarkedSource_IDENTIFIER && kid.PreText != "" {
-				quals = append(quals, kid.PreText)
+			if kid.Kind == cpb.MarkedSource_IDENTIFIER || kid.Kind == cpb.MarkedSource_BOX {
+				if namespace := Render(kid); namespace != "" {
+					quals = append(quals, namespace)
+				}
 			}
 		}
 		if pkg := strings.Join(quals, delim); pkg != "" {
@@ -160,11 +162,14 @@ func RenderQualifiedName(ms *cpb.MarkedSource) *cpb.SymbolInfo {
 }
 
 // firstMatching returns the first node in a breadth-first traversal of the
-// children of ms for which f reports true, or nil.
+// children of ms, or ms itself, for which f reports true, or nil.
 func firstMatching(ms *cpb.MarkedSource, f func(*cpb.MarkedSource) bool) *cpb.MarkedSource {
-	if ms == nil || len(ms.Child) == 0 {
+	if ms == nil {
 		return nil
 	}
+	if f(ms) {
+		return ms
+	}
 	for _, kid := range ms.Child {
 		if f(kid) {
 			return kid


Test patch:
diff --git a/kythe/go/util/markedsource/markedsource_test.go b/kythe/go/util/markedsource/markedsource_test.go
index 4ca5258b5..113a13e5c 100644
--- a/kythe/go/util/markedsource/markedsource_test.go
+++ b/kythe/go/util/markedsource/markedsource_test.go
@@ -253,6 +253,14 @@ func TestQName(t *testing.T) {
 		// Verify that the default separator is correctly used.
 		{input: `child { kind: CONTEXT child { kind: IDENTIFIER pre_text: "a" } child { kind: IDENTIFIER pre_text: "b" } } child { kind: IDENTIFIER pre_text: "-tail" }`,
 			want: &cpb.SymbolInfo{BaseName: "-tail", QualifiedName: "a.b-tail"}},
+
+		// Verify that template names in context can be correctly rendered.
+		{input: `child { kind: CONTEXT child { kind: IDENTIFIER pre_text: "a" } child { child { kind: IDENTIFIER pre_text: "b" } child: { pre_text: "<" child: { pre_text: "c" } post_text: ">"} } post_child_text: "::" } child { kind: IDENTIFIER pre_text: "d" }`,
+			want: &cpb.SymbolInfo{BaseName: "d", QualifiedName: "a::b<c>::d"}},
+
+		// Verify that a standalone identifier can work.
+		{input: `kind: IDENTIFIER pre_text: "hello"`,
+			want: &cpb.SymbolInfo{BaseName: "hello", QualifiedName: ""}},
 	}
 
 	for _, test := range tests {
Repository: kythe/kythe
Pull request #5631 (2023-05-12 19:54:19)

feat(typescript_indexer): handle type nodes when emitting ref/id from object bindings
This fixes indexing of dynamic imports where imported symbols such as classes and enums use TSNamespace.TYPE in their vnames. 


Patch:
diff --git a/kythe/typescript/indexer.ts b/kythe/typescript/indexer.ts
index cf2cda134..9dc2b2642 100644
--- a/kythe/typescript/indexer.ts
+++ b/kythe/typescript/indexer.ts
@@ -2061,7 +2061,12 @@ class Visitor {
     if (propName == null) return;
     const propertyOnType = type.getProperty(propName);
     if (propertyOnType == null) return;
-    const vname = this.host.getSymbolName(propertyOnType, TSNamespace.VALUE);
+    const propFlags = propertyOnType.flags;
+    const isType = (propFlags &
+                    (ts.SymbolFlags.Class | ts.SymbolFlags.Interface |
+                     ts.SymbolFlags.RegularEnum | ts.SymbolFlags.TypeAlias)) > 0;
+    const vname = this.host.getSymbolName(
+        propertyOnType, isType ? TSNamespace.TYPE : TSNamespace.VALUE);
     if (vname == null) return;
     const anchor = this.newAnchor(prop);
     this.emitEdge(anchor, EdgeKind.REF_ID, vname);


Test patch:
diff --git a/kythe/typescript/testdata/dynamic_import_group/import.ts b/kythe/typescript/testdata/dynamic_import_group/import.ts
index 7c0ef2acd..57cdc9bc3 100644
--- a/kythe/typescript/testdata/dynamic_import_group/import.ts
+++ b/kythe/typescript/testdata/dynamic_import_group/import.ts
@@ -1,6 +1,7 @@
 
 function regularFunction() {
     //- @"'./module'" ref/imports Mod
+    //- @StuffDoer ref/id StuffDoer
     import('./module').then(({StuffDoer}) => {
         new StuffDoer().doStuff();
     })
@@ -13,8 +14,17 @@ function regularFunction() {
 }
 
 async function asyncFunction() {
+    const {
+        //- @StuffDoer ref/id StuffDoer
+        StuffDoer,
+        //- @CONSTANT ref/id Constant
+        CONSTANT,
+        //- @doStuff ref/id DoStuff
+        doStuff,
+        //- @Enum ref/id Enum
+        Enum,
     //- @"'./module'" ref/imports Mod
-    const {StuffDoer} = await import('./module');
+    } = await import('./module');
     new StuffDoer().doStuff();
 }
 
diff --git a/kythe/typescript/testdata/dynamic_import_group/module.ts b/kythe/typescript/testdata/dynamic_import_group/module.ts
index d8692fa92..980190c48 100644
--- a/kythe/typescript/testdata/dynamic_import_group/module.ts
+++ b/kythe/typescript/testdata/dynamic_import_group/module.ts
@@ -1,5 +1,16 @@
 //- Mod=vname("module", _, _, "testdata/dynamic_import_group/module", _).node/kind record
 
+//- @StuffDoer defines/binding StuffDoer
+//- StuffDoer.node/kind record
 export class StuffDoer {
     doStuff() {}
-}
\ No newline at end of file
+}
+
+//- @CONSTANT defines/binding Constant
+export const CONSTANT = 1;
+
+//- @doStuff defines/binding DoStuff
+export function doStuff() {}
+
+//- @Enum defines/binding Enum
+export enum Enum {}
\ No newline at end of file
Repository: kythe/kythe
Pull request #5673 (2023-05-31 15:55:14)

fix(go): avoid formatting protos via %v for non-debug uses

schroederc: You can also use `%s` to use the standard proto String representation.

Patch:
diff --git a/kythe/go/platform/kzip/info/info.go b/kythe/go/platform/kzip/info/info.go
index 00adcd3ce..ea05dfe66 100644
--- a/kythe/go/platform/kzip/info/info.go
+++ b/kythe/go/platform/kzip/info/info.go
@@ -69,6 +69,10 @@ func NewAccumulator(fileSize int64) *Accumulator {
 	}
 }
 
+func cuString(u *kzip.Unit) string {
+	return fmt.Sprintf("corpus: %q root: %q language: %q", u.Proto.GetVName().GetCorpus(), u.Proto.GetVName().GetRoot(), u.Proto.GetVName().GetLanguage())
+}
+
 // Accumulate should be called for each unit in the kzip so its counts can be
 // recorded.
 func (a *Accumulator) Accumulate(u *kzip.Unit) {
@@ -80,7 +84,7 @@ func (a *Accumulator) Accumulate(u *kzip.Unit) {
 
 	cuLang := u.Proto.GetVName().GetLanguage()
 	if cuLang == "" {
-		msg := fmt.Sprintf("CU does not specify a language %v", u.Proto.GetVName())
+		msg := fmt.Sprintf("CU(%s) does not specify a language", cuString(u))
 		a.KzipInfo.CriticalKzipErrors = append(a.KzipInfo.CriticalKzipErrors, msg)
 		return
 	}
@@ -103,7 +107,7 @@ func (a *Accumulator) Accumulate(u *kzip.Unit) {
 		riCorpus := requiredInputCorpus(u, ri)
 		if riCorpus == "" {
 			// Trim spaces to work around the fact that log("%v", proto) is inconsistent about trailing spaces in google3 vs open-source go.
-			msg := strings.TrimSpace(fmt.Sprintf("unable to determine corpus for required_input %q in CU %v", ri.Info.Path, u.Proto.GetVName()))
+			msg := strings.TrimSpace(fmt.Sprintf("unable to determine corpus for required_input %q in CU(%s)", ri.Info.Path, cuString(u)))
 			a.KzipInfo.CriticalKzipErrors = append(a.KzipInfo.CriticalKzipErrors, msg)
 			return
 		}
@@ -121,7 +125,7 @@ func (a *Accumulator) Accumulate(u *kzip.Unit) {
 	}
 	srcsWithoutRI := srcs.Diff(srcsWithRI)
 	for path := range srcsWithoutRI {
-		msg := fmt.Sprintf("source %q in CU %v doesn't have a required_input entry", path, u.Proto.GetVName())
+		msg := fmt.Sprintf("source %q in CU(%s) doesn't have a required_input entry", path, cuString(u))
 		a.KzipInfo.CriticalKzipErrors = append(a.KzipInfo.CriticalKzipErrors, msg)
 	}
 	if srcCorpora.Len() != 1 {


Test patch:
diff --git a/kythe/go/platform/kzip/info/info_test.go b/kythe/go/platform/kzip/info/info_test.go
index e7dc1c365..a592799da 100644
--- a/kythe/go/platform/kzip/info/info_test.go
+++ b/kythe/go/platform/kzip/info/info_test.go
@@ -295,7 +295,7 @@ var infoTests = []struct {
 					},
 				},
 			},
-			CriticalKzipErrors: []string{"unable to determine corpus for required_input \"file1.py\" in CU language:\"python\""},
+			CriticalKzipErrors: []string{`unable to determine corpus for required_input "file1.py" in CU(corpus: "" root: "" language: "python")`},
 		},
 	},