Merge pull request #30 from dmarkham/use-constant-names

Use constant names, Help the compiler detect value changes
This commit is contained in:
Dan Markham 2020-02-23 23:11:09 -08:00 committed by GitHub
commit d46c853929
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 606 additions and 287 deletions

View File

@ -61,7 +61,7 @@ func (g *Generator) buildBasicExtras(runs [][]Value, typeName string, runsThresh
g.Printf("\nvar _%sValues = []%s{", typeName, typeName) g.Printf("\nvar _%sValues = []%s{", typeName, typeName)
for _, values := range runs { for _, values := range runs {
for _, value := range values { for _, value := range values {
g.Printf("\t%s, ", value.str) g.Printf("\t%s, ", value.originalName)
} }
} }
g.Printf("}\n\n") g.Printf("}\n\n")
@ -98,8 +98,8 @@ func (g *Generator) printValueMap(runs [][]Value, typeName string, runsThreshold
} }
for _, value := range values { for _, value := range values {
g.Printf("\t_%sName%s[%d:%d]: %s,\n", typeName, runID, n, n+len(value.name), &value) g.Printf("\t_%sName%s[%d:%d]: %s,\n", typeName, runID, n, n+len(value.name), value.originalName)
g.Printf("\t_%sLowerName%s[%d:%d]: %s,\n", typeName, runID, n, n+len(value.name), &value) g.Printf("\t_%sLowerName%s[%d:%d]: %s,\n", typeName, runID, n, n+len(value.name), value.originalName)
n += len(value.name) n += len(value.name)
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -445,6 +445,7 @@ func (g *Generator) generate(typeName string, includeJSON, includeYAML, includeS
default: default:
g.buildMap(runs, typeName) g.buildMap(runs, typeName)
} }
g.buildNoOpOrderChangeDetect(runs, typeName)
g.buildBasicExtras(runs, typeName, runsThreshold) g.buildBasicExtras(runs, typeName, runsThreshold)
if includeJSON { if includeJSON {
@ -508,7 +509,8 @@ func (g *Generator) format() []byte {
// Value represents a declared constant. // Value represents a declared constant.
type Value struct { type Value struct {
name string // The name of the constant after transformation (i.e. camel case => snake case) originalName string // The name of the constant before transformation
name string // The name of the constant after transformation (i.e. camel case => snake case)
// The value is stored as a bit pattern alone. The boolean tells us // The value is stored as a bit pattern alone. The boolean tells us
// whether to interpret it as an int64 or a uint64; the only place // whether to interpret it as an int64 or a uint64; the only place
// this matters is when sorting. // this matters is when sorting.
@ -602,10 +604,11 @@ func (f *File) genDecl(node ast.Node) bool {
u64 = uint64(i64) u64 = uint64(i64)
} }
v := Value{ v := Value{
name: n.Name, originalName: n.Name,
value: u64, name: n.Name,
signed: info&types.IsUnsigned == 0, value: u64,
str: value.String(), signed: info&types.IsUnsigned == 0,
str: value.String(),
} }
if c := vspec.Comment; f.lineComment && c != nil && len(c.List) == 1 { if c := vspec.Comment; f.lineComment && c != nil && len(c.List) == 1 {
v.name = strings.TrimSpace(c.Text()) v.name = strings.TrimSpace(c.Text())
@ -817,6 +820,24 @@ func (g *Generator) buildMap(runs [][]Value, typeName string) {
g.Printf(stringMap, typeName) g.Printf(stringMap, typeName)
} }
// buildNoOpOrderChangeDetect try to let the compiler and the user know if the order/value of the ENUMS have changed.
func (g *Generator) buildNoOpOrderChangeDetect(runs [][]Value, typeName string) {
g.Printf("\n")
g.Printf(`
// An "invalid array index" compiler error signifies that the constant values have changed.
// Re-run the stringer command to generate them again.
`)
g.Printf("func _%sNoOp (){ ", typeName)
g.Printf("\n var x [1]struct{}\n")
for _, values := range runs {
for _, value := range values {
g.Printf("\t_ = x[%s-(%s)]\n", value.originalName, value.str)
}
}
g.Printf("}\n\n")
}
// Argument to format is the type name. // Argument to format is the type name.
const stringMap = `func (i %[1]s) String() string { const stringMap = `func (i %[1]s) String() string {
if str, ok := _%[1]sMap[i]; ok { if str, ok := _%[1]sMap[i]; ok {

View File

@ -54,7 +54,7 @@ Outer:
for n, test := range splitTests { for n, test := range splitTests {
values := make([]Value, len(test.input)) values := make([]Value, len(test.input))
for i, v := range test.input { for i, v := range test.input {
values[i] = Value{"", v, test.signed, fmt.Sprint(v)} values[i] = Value{"", "", v, test.signed, fmt.Sprint(v)}
} }
runs := splitIntoRuns(values) runs := splitIntoRuns(values)
if len(runs) != len(test.output) { if len(runs) != len(test.output) {