Add support for -linecomment

This commit is contained in:
Álvaro 2019-05-25 17:02:36 +01:00
parent 0f1dc27ec9
commit 642f2c0436
3 changed files with 124 additions and 16 deletions

View File

@ -34,28 +34,32 @@ var golden = []Golden{
} }
var goldenJSON = []Golden{ var goldenJSON = []Golden{
{"prime", primeJsonIn, primeJsonOut}, {"prime with JSON", primeJsonIn, primeJsonOut},
} }
var goldenText = []Golden{ var goldenText = []Golden{
{"prime", primeTextIn, primeTextOut}, {"prime with Text", primeTextIn, primeTextOut},
} }
var goldenYAML = []Golden{ var goldenYAML = []Golden{
{"prime", primeYamlIn, primeYamlOut}, {"prime with YAML", primeYamlIn, primeYamlOut},
} }
var goldenSQL = []Golden{ var goldenSQL = []Golden{
{"prime", primeSqlIn, primeSqlOut}, {"prime with SQL", primeSqlIn, primeSqlOut},
} }
var goldenJSONAndSQL = []Golden{ var goldenJSONAndSQL = []Golden{
{"prime", primeJsonAndSqlIn, primeJsonAndSqlOut}, {"prime with JSONAndSQL", primeJsonAndSqlIn, primeJsonAndSqlOut},
} }
var goldenPrefix = []Golden{ var goldenPrefix = []Golden{
{"prefix", prefixIn, dayOut}, {"prefix", prefixIn, dayOut},
} }
var goldenWithLineComments = []Golden{
{"primer with line Comments", primeWithLineCommentIn, primeWithLineCommentOut},
}
// Each example starts with "type XXX [u]int", with a single space separating them. // Each example starts with "type XXX [u]int", with a single space separating them.
// Simple test: enumeration of type int starting at 0. // Simple test: enumeration of type int starting at 0.
@ -1025,6 +1029,90 @@ const (
) )
` `
const primeWithLineCommentIn = `type Prime int
const (
p2 Prime = 2
p3 Prime = 3
p5 Prime = 5
p7 Prime = 7
p77 Prime = 7 // Duplicate; note that p77 doesn't appear below.
p11 Prime = 11
p13 Prime = 13
p17 Prime = 17
p19 Prime = 19
p23 Prime = 23
p29 Prime = 29
p37 Prime = 31
p41 Prime = 41
p43 Prime = 43
)
`
const primeWithLineCommentOut = `
const _PrimeName = "p2p3GoodPrimep7p11p13p17p19p23p29p37TwinPrime41Twin prime 43"
var _PrimeMap = map[Prime]string{
2: _PrimeName[0:2],
3: _PrimeName[2:4],
5: _PrimeName[4:13],
7: _PrimeName[13:15],
11: _PrimeName[15:18],
13: _PrimeName[18:21],
17: _PrimeName[21:24],
19: _PrimeName[24:27],
23: _PrimeName[27:30],
29: _PrimeName[30:33],
31: _PrimeName[33:36],
41: _PrimeName[36:47],
43: _PrimeName[47:60],
}
func (i Prime) String() string {
if str, ok := _PrimeMap[i]; ok {
return str
}
return fmt.Sprintf("Prime(%d)", i)
}
var _PrimeValues = []Prime{2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 41, 43}
var _PrimeNameToValueMap = map[string]Prime{
_PrimeName[0:2]: 2,
_PrimeName[2:4]: 3,
_PrimeName[4:13]: 5,
_PrimeName[13:15]: 7,
_PrimeName[15:18]: 11,
_PrimeName[18:21]: 13,
_PrimeName[21:24]: 17,
_PrimeName[24:27]: 19,
_PrimeName[27:30]: 23,
_PrimeName[30:33]: 29,
_PrimeName[33:36]: 31,
_PrimeName[36:47]: 41,
_PrimeName[47:60]: 43,
}
// PrimeString retrieves an enum value from the enum constants string name.
// Throws an error if the param is not part of the enum.
func PrimeString(s string) (Prime, error) {
if val, ok := _PrimeNameToValueMap[s]; ok {
return val, nil
}
return 0, fmt.Errorf("%s does not belong to Prime values", s)
}
// PrimeValues returns all values of the enum
func PrimeValues() []Prime {
return _PrimeValues
}
// IsAPrime returns "true" if the value is listed in the enum definition. "false" otherwise
func (i Prime) IsAPrime() bool {
_, ok := _PrimeMap[i]
return ok
}
`
func TestGolden(t *testing.T) { func TestGolden(t *testing.T) {
for _, test := range golden { for _, test := range golden {
runGoldenTest(t, test, false, false, false, false, "") runGoldenTest(t, test, false, false, false, false, "")
@ -1076,7 +1164,7 @@ func runGoldenTest(t *testing.T, test Golden, generateJSON, generateYAML, genera
if len(tokens) != 3 { if len(tokens) != 3 {
t.Fatalf("%s: need type declaration on first line", test.name) t.Fatalf("%s: need type declaration on first line", test.name)
} }
g.generate(tokens[1], generateJSON, generateYAML, generateSQL, generateText, "noop", prefix) g.generate(tokens[1], generateJSON, generateYAML, generateSQL, generateText, "noop", prefix, false)
got := string(g.format()) got := string(g.format())
if got != test.output { if got != test.output {
t.Errorf("%s: got\n====\n%s====\nexpected\n====%s", test.name, got, test.output) t.Errorf("%s: got\n====\n%s====\nexpected\n====%s", test.name, got, test.output)

View File

@ -51,6 +51,7 @@ var (
output = flag.String("output", "", "output file name; default srcdir/<type>_string.go") output = flag.String("output", "", "output file name; default srcdir/<type>_string.go")
transformMethod = flag.String("transform", "noop", "enum item name transformation method. Default: noop") transformMethod = flag.String("transform", "noop", "enum item name transformation method. Default: noop")
trimPrefix = flag.String("trimprefix", "", "transform each item name by removing a prefix. Default: \"\"") trimPrefix = flag.String("trimprefix", "", "transform each item name by removing a prefix. Default: \"\"")
lineComment = flag.Bool("linecomment", false, "use line comment text as printed text when present")
) )
var comments arrayFlags var comments arrayFlags
@ -120,7 +121,7 @@ func main() {
// Run generate for each type. // Run generate for each type.
for _, typeName := range types { for _, typeName := range types {
g.generate(typeName, *json, *yaml, *sql, *text, *transformMethod, *trimPrefix) g.generate(typeName, *json, *yaml, *sql, *text, *transformMethod, *trimPrefix, *lineComment)
} }
// Format the output. // Format the output.
@ -331,8 +332,16 @@ func (g *Generator) trimValueNames(values []Value, prefix string) {
} }
} }
func (g *Generator) replaceValuesWithLineComment(values []Value) {
for i, val := range values {
if val.comment != "" {
values[i].name = val.comment
}
}
}
// generate produces the String method for the named type. // generate produces the String method for the named type.
func (g *Generator) generate(typeName string, includeJSON, includeYAML, includeSQL, includeText bool, transformMethod string, trimPrefix string) { func (g *Generator) generate(typeName string, includeJSON, includeYAML, includeSQL, includeText bool, transformMethod string, trimPrefix string, lineComment bool) {
values := make([]Value, 0, 100) values := make([]Value, 0, 100)
for _, file := range g.pkg.files { for _, file := range g.pkg.files {
// Set the state for this run of the walker. // Set the state for this run of the walker.
@ -352,6 +361,10 @@ func (g *Generator) generate(typeName string, includeJSON, includeYAML, includeS
g.transformValueNames(values, transformMethod) g.transformValueNames(values, transformMethod)
if lineComment {
g.replaceValuesWithLineComment(values)
}
runs := splitIntoRuns(values) runs := splitIntoRuns(values)
// The decision of which pattern to use depends on the number of // The decision of which pattern to use depends on the number of
// runs in the numbers. If there's only one, it's easy. For more than // runs in the numbers. If there's only one, it's easy. For more than
@ -446,6 +459,7 @@ type Value struct {
value uint64 // Will be converted to int64 when needed. value uint64 // Will be converted to int64 when needed.
signed bool // Whether the constant is a signed type. signed bool // Whether the constant is a signed type.
str string // The string representation given by the "go/exact" package. str string // The string representation given by the "go/exact" package.
comment string // The comment on the right of the constant
} }
func (v *Value) String() string { func (v *Value) String() string {
@ -530,11 +544,17 @@ func (f *File) genDecl(node ast.Node) bool {
if !isInt { if !isInt {
u64 = uint64(i64) u64 = uint64(i64)
} }
comment := ""
if c := vspec.Comment; c != nil && len(c.List) == 1 {
comment = strings.TrimSpace(c.Text())
}
v := Value{ v := Value{
name: name.Name, name: name.Name,
value: u64, value: u64,
signed: info&types.IsUnsigned == 0, signed: info&types.IsUnsigned == 0,
str: value.String(), str: value.String(),
comment: comment,
} }
f.values = append(f.values, v) f.values = append(f.values, v)
} }

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) {