зеркало из https://github.com/golang/tools.git
cmd/stringer: accept simple type conversion expressions in constant ValueSpec
This permits constants of the form `const X = T(A)` to add `X` to the stringer output for type `T`. While those constants can be rewritten as `const X T = T(A)`, that becomes tedious and visually noisy when `T` is a long name. It is quite easy to address this easy and common case, while not attempting to solve this with full generality. Fixes #11581. Change-Id: Ifb8e43515f05493de190e02577260d94dd851581 Reviewed-on: https://go-review.googlesource.com/c/146577 Run-TryBot: David Symonds <dsymonds@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rob Pike <r@golang.org>
This commit is contained in:
Родитель
3a10b9bf0a
Коммит
45ff765b48
|
@ -428,10 +428,24 @@ func (f *File) genDecl(node ast.Node) bool {
|
|||
for _, spec := range decl.Specs {
|
||||
vspec := spec.(*ast.ValueSpec) // Guaranteed to succeed as this is CONST.
|
||||
if vspec.Type == nil && len(vspec.Values) > 0 {
|
||||
// "X = 1". With no type but a value, the constant is untyped.
|
||||
// Skip this vspec and reset the remembered type.
|
||||
// "X = 1". With no type but a value. If the constant is untyped,
|
||||
// skip this vspec and reset the remembered type.
|
||||
typ = ""
|
||||
continue
|
||||
|
||||
// If this is a simple type conversion, remember the type.
|
||||
// We don't mind if this is actually a call; a qualified call won't
|
||||
// be matched (that will be SelectorExpr, not Ident), and only unusual
|
||||
// situations will result in a function call that appears to be
|
||||
// a type conversion.
|
||||
ce, ok := vspec.Values[0].(*ast.CallExpr)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
id, ok := ce.Fun.(*ast.Ident)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
typ = id.Name
|
||||
}
|
||||
if vspec.Type != nil {
|
||||
// "X T". We have a type. Remember it.
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
// 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.
|
||||
|
||||
// Check that constants defined as a conversion are accepted.
|
||||
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
type Other int // Imagine this is in another package.
|
||||
|
||||
const (
|
||||
alpha Other = iota
|
||||
beta
|
||||
gamma
|
||||
delta
|
||||
)
|
||||
|
||||
type Conv int
|
||||
|
||||
const (
|
||||
Alpha = Conv(alpha)
|
||||
Beta = Conv(beta)
|
||||
Gamma = Conv(gamma)
|
||||
Delta = Conv(delta)
|
||||
)
|
||||
|
||||
func main() {
|
||||
ck(Alpha, "Alpha")
|
||||
ck(Beta, "Beta")
|
||||
ck(Gamma, "Gamma")
|
||||
ck(Delta, "Delta")
|
||||
ck(42, "Conv(42)")
|
||||
}
|
||||
|
||||
func ck(c Conv, str string) {
|
||||
if fmt.Sprint(c) != str {
|
||||
panic("conv.go: " + str)
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче