зеркало из 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 {
|
for _, spec := range decl.Specs {
|
||||||
vspec := spec.(*ast.ValueSpec) // Guaranteed to succeed as this is CONST.
|
vspec := spec.(*ast.ValueSpec) // Guaranteed to succeed as this is CONST.
|
||||||
if vspec.Type == nil && len(vspec.Values) > 0 {
|
if vspec.Type == nil && len(vspec.Values) > 0 {
|
||||||
// "X = 1". With no type but a value, the constant is untyped.
|
// "X = 1". With no type but a value. If the constant is untyped,
|
||||||
// Skip this vspec and reset the remembered type.
|
// skip this vspec and reset the remembered type.
|
||||||
typ = ""
|
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 {
|
if vspec.Type != nil {
|
||||||
// "X T". We have a type. Remember it.
|
// "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)
|
||||||
|
}
|
||||||
|
}
|
Загрузка…
Ссылка в новой задаче