Commit f399af31 authored by Joe Tsai's avatar Joe Tsai Committed by Joe Tsai

go/doc: replace unexported values with underscore if necessary

When a var or const declaration contains a mixture of exported and unexported
identifiers, replace the unexported identifiers with underscore.
Otherwise, the LHS and the RHS may mismatch or the declaration may mismatch
with an iota from above.

Fixes #22426

Change-Id: Icd5fb81b4ece647232a9f7d05cb140227091e9cb
Reviewed-on: https://go-review.googlesource.com/94877
Run-TryBot: Joe Tsai <thebrokentoaster@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarRobert Griesemer <gri@golang.org>
parent ed6c6c9c
......@@ -25,6 +25,21 @@ func filterIdentList(list []*ast.Ident) []*ast.Ident {
return list[0:j]
}
var underscore = ast.NewIdent("_")
// updateIdentList replaces all unexported identifiers with underscore
// and reports whether at least one exported name exists.
func updateIdentList(list []*ast.Ident) (hasExported bool) {
for i, x := range list {
if ast.IsExported(x.Name) {
hasExported = true
} else {
list[i] = underscore
}
}
return hasExported
}
// hasExportedName reports whether list contains any exported names.
//
func hasExportedName(list []*ast.Ident) bool {
......@@ -156,10 +171,23 @@ func (r *reader) filterSpec(spec ast.Spec) bool {
// always keep imports so we can collect them
return true
case *ast.ValueSpec:
s.Names = filterIdentList(s.Names)
if len(s.Names) > 0 {
r.filterType(nil, s.Type)
return true
if len(s.Values) > 0 || s.Type == nil && len(s.Values) == 0 {
// If there are values declared on RHS, just replace the unexported
// identifiers on the LHS with underscore, so that it matches
// the sequence of expression on the RHS.
//
// Similarly, if there are no type and values, then this expression
// must be following an iota expression, where order matters.
if updateIdentList(s.Names) {
r.filterType(nil, s.Type)
return true
}
} else {
s.Names = filterIdentList(s.Names)
if len(s.Names) > 0 {
r.filterType(nil, s.Type)
return true
}
}
case *ast.TypeSpec:
if name := s.Name.Name; ast.IsExported(name) {
......
// The package g is a go/doc test for mixed exported/unexported ...
PACKAGE g
IMPORTPATH
testdata/g
FILENAMES
testdata/g.go
CONSTANTS
//
const (
A, _ = iota, iota
_, D
E, _
G, H
)
VARIABLES
//
var (
_, C2, _ = 1, 2, 3
C4, _, C6 = 4, 5, 6
_, C8, _ = 7, 8, 9
)
//
var (
_, X = f()
)
// The package g is a go/doc test for mixed exported/unexported ...
PACKAGE g
IMPORTPATH
testdata/g
FILENAMES
testdata/g.go
CONSTANTS
//
const (
A, b = iota, iota
c, D
E, f
G, H
)
VARIABLES
//
var (
c1, C2, c3 = 1, 2, 3
C4, c5, C6 = 4, 5, 6
c7, C8, c9 = 7, 8, 9
xx, yy, zz = 0, 0, 0 // all unexported and hidden
)
//
var (
x, X = f()
y, z = f()
)
// The package g is a go/doc test for mixed exported/unexported ...
PACKAGE g
IMPORTPATH
testdata/g
FILENAMES
testdata/g.go
CONSTANTS
//
const (
A, _ = iota, iota
_, D
E, _
G, H
)
VARIABLES
//
var (
_, C2, _ = 1, 2, 3
C4, _, C6 = 4, 5, 6
_, C8, _ = 7, 8, 9
)
//
var (
_, X = f()
)
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// The package g is a go/doc test for mixed exported/unexported values.
package g
const (
A, b = iota, iota
c, D
E, f
G, H
)
var (
c1, C2, c3 = 1, 2, 3
C4, c5, C6 = 4, 5, 6
c7, C8, c9 = 7, 8, 9
xx, yy, zz = 0, 0, 0 // all unexported and hidden
)
var (
x, X = f()
y, z = f()
)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment