go/analysis: validate: report duplicates among analyzers (roots)

Duplicate root analyzers caused duplicate flag registration and other problems.

Change-Id: Id0c2761529c57ed1f9a63b669e62401ebf035cc2
Reviewed-on: https://go-review.googlesource.com/c/141159
Reviewed-by: Michael Matloob <matloob@golang.org>
diff --git a/go/analysis/validate.go b/go/analysis/validate.go
index dd9d25b..6e6cf49 100644
--- a/go/analysis/validate.go
+++ b/go/analysis/validate.go
@@ -20,14 +20,20 @@
 	factTypes := make(map[reflect.Type]*Analyzer)
 
 	// Traverse the Requires graph, depth first.
-	color := make(map[*Analyzer]uint8) // 0=white 1=grey 2=black
+	const (
+		white = iota
+		grey
+		black
+		finished
+	)
+	color := make(map[*Analyzer]uint8)
 	var visit func(a *Analyzer) error
 	visit = func(a *Analyzer) error {
 		if a == nil {
 			return fmt.Errorf("nil *Analyzer")
 		}
-		if color[a] == 0 { // white
-			color[a] = 1 // grey
+		if color[a] == white {
+			color[a] = grey
 
 			// names
 			if !validIdent(a.Name) {
@@ -64,7 +70,7 @@
 					return fmt.Errorf("%s.Requires[%d]: %v", a.Name, i, err)
 				}
 			}
-			color[a] = 2 // black
+			color[a] = black
 		}
 
 		return nil
@@ -75,6 +81,16 @@
 		}
 	}
 
+	// Reject duplicates among analyzers.
+	// Precondition:  color[a] == black.
+	// Postcondition: color[a] == finished.
+	for _, a := range analyzers {
+		if color[a] == finished {
+			return fmt.Errorf("duplicate analyzer: %s", a.Name)
+		}
+		color[a] = finished
+	}
+
 	return nil
 }