go/analysis/analysistest: fix nil pointer dereference when sorting facts

Without this change, we can't use `ExportPackageFact` function with analysistest package.

PackageFacts are keyed by nil and analysistest.check crashed while sorting, due to a nil object dereference.

Change-Id: Ic94c71acc9c74012bf150e1d72e937da8dfdff75
GitHub-Last-Rev: 51c91008a6756e66c630bfeabc9b8da08c12bfdd
GitHub-Pull-Request: golang/tools#163
Reviewed-on: https://go-review.googlesource.com/c/tools/+/196758
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
Reviewed-by: Alan Donovan <adonovan@google.com>
diff --git a/go/analysis/analysistest/analysistest.go b/go/analysis/analysistest/analysistest.go
index 0d323dc..fc06c32 100644
--- a/go/analysis/analysistest/analysistest.go
+++ b/go/analysis/analysistest/analysistest.go
@@ -277,6 +277,11 @@
 		objects = append(objects, obj)
 	}
 	sort.Slice(objects, func(i, j int) bool {
+		// Package facts compare less than object facts.
+		ip, jp := objects[i] == nil, objects[j] == nil // whether i, j is a package fact
+		if ip != jp {
+			return ip && !jp
+		}
 		return objects[i].Pos() < objects[j].Pos()
 	})
 	for _, obj := range objects {
diff --git a/go/analysis/analysistest/analysistest_test.go b/go/analysis/analysistest/analysistest_test.go
index 2b08542..c16e507 100644
--- a/go/analysis/analysistest/analysistest_test.go
+++ b/go/analysis/analysistest/analysistest_test.go
@@ -33,7 +33,7 @@
 	// which (by default) reports calls to functions named 'println'.
 	findcall.Analyzer.Flags.Set("name", "println")
 
-	filemap := map[string]string{"a/b.go": `package main
+	filemap := map[string]string{"a/b.go": `package main // want package:"found"
 
 func main() {
 	// The expectation is ill-formed:
diff --git a/go/analysis/passes/findcall/findcall.go b/go/analysis/passes/findcall/findcall.go
index 2a4e3a4..cd31ab4 100644
--- a/go/analysis/passes/findcall/findcall.go
+++ b/go/analysis/passes/findcall/findcall.go
@@ -5,7 +5,10 @@
 // The findcall package defines an Analyzer that serves as a trivial
 // example and test of the Analysis API. It reports a diagnostic for
 // every call to a function or method of the name specified by its
-// -name flag.
+// -name flag. It also exports a fact for each declaration that
+// matches the name, plus a package-level fact if the package contained
+// one or more such declarations.
+
 package findcall
 
 import (
@@ -69,6 +72,10 @@
 		}
 	}
 
+	if len(pass.AllObjectFacts()) > 0 {
+		pass.ExportPackageFact(new(foundFact))
+	}
+
 	return nil, nil
 }
 
diff --git a/go/analysis/passes/findcall/findcall_test.go b/go/analysis/passes/findcall/findcall_test.go
index e5292df..7710d52 100644
--- a/go/analysis/passes/findcall/findcall_test.go
+++ b/go/analysis/passes/findcall/findcall_test.go
@@ -29,12 +29,14 @@
 		{
 			desc:    "SimpleTest",
 			pkgpath: "main",
-			files: map[string]string{"main/main.go": `package main
+			files: map[string]string{"main/main.go": `package main // want package:"found"
 
 func main() {
 	println("hello") // want "call of println"
 	print("goodbye") // not a call of println
-}`,
+}
+
+func println(s string) {} // want println:"found"`,
 			},
 		},
 	} {
diff --git a/go/analysis/passes/findcall/testdata/src/a/a.go b/go/analysis/passes/findcall/testdata/src/a/a.go
index f2c2053..d9321cc 100644
--- a/go/analysis/passes/findcall/testdata/src/a/a.go
+++ b/go/analysis/passes/findcall/testdata/src/a/a.go
@@ -1,6 +1,8 @@
-package main
+package main // want package:"found"
 
 func main() {
 	println("hi") // want "call of println"
 	print("hi")   // not a call of println
 }
+
+func println(s string) {} // want println:"found"