From 7356d5f88875523b62c873d04211212bcf03553b Mon Sep 17 00:00:00 2001 From: Martin Tournoij Date: Thu, 25 Nov 2021 04:07:11 +0100 Subject: [PATCH] Few staticcheck fixes --- cmd/toml-test-decoder/main.go | 2 +- encode.go | 44 +++++++++++++++++++++-------------- encode_test.go | 20 ++++++++-------- error_test.go | 3 --- internal/tag/rm.go | 2 +- internal/toml-test/json.go | 10 -------- internal/toml-test/runner.go | 2 +- parse.go | 22 ++++++++---------- type_fields.go | 4 ++-- 9 files changed, 52 insertions(+), 57 deletions(-) diff --git a/cmd/toml-test-decoder/main.go b/cmd/toml-test-decoder/main.go index 344047f1..0823bbf8 100644 --- a/cmd/toml-test-decoder/main.go +++ b/cmd/toml-test-decoder/main.go @@ -31,7 +31,7 @@ func main() { } var decoded interface{} - if _, err := toml.DecodeReader(os.Stdin, &decoded); err != nil { + if _, err := toml.NewDecoder(os.Stdin).Decode(&decoded); err != nil { log.Fatalf("Error decoding TOML: %s", err) } diff --git a/encode.go b/encode.go index 0804c653..9e5126f5 100644 --- a/encode.go +++ b/encode.go @@ -21,7 +21,6 @@ type tomlEncodeError struct{ error } var ( errArrayNilElement = errors.New("toml: cannot encode array with nil element") errNonString = errors.New("toml: cannot encode a map with non-string key type") - errAnonNonStruct = errors.New("toml: cannot encode an anonymous field that is not a struct") errNoKey = errors.New("toml: top-level values must be Go maps or structs") errAnything = errors.New("") // used in testing ) @@ -521,30 +520,41 @@ func tomlTypeOfGo(rv reflect.Value) tomlType { case reflect.Map: return tomlHash case reflect.Struct: - switch rv.Interface().(type) { - case time.Time: + if _, ok := rv.Interface().(time.Time); ok { return tomlDatetime - case encoding.TextMarshaler: + } + if isMarshaler(rv) { return tomlString - default: - // Someone used a pointer receiver: we can make it work for pointer - // values. - if rv.CanAddr() { - _, ok := rv.Addr().Interface().(encoding.TextMarshaler) - if ok { - return tomlString - } - } - return tomlHash } + return tomlHash default: - _, ok := rv.Interface().(encoding.TextMarshaler) - if ok { + if isMarshaler(rv) { return tomlString } + encPanic(errors.New("unsupported type: " + rv.Kind().String())) - panic("") // Need *some* return value + panic("unreachable") + } +} + +func isMarshaler(rv reflect.Value) bool { + switch rv.Interface().(type) { + case encoding.TextMarshaler: + return true + case Marshaler: + return true + } + + // Someone used a pointer receiver: we can make it work for pointer values. + if rv.CanAddr() { + if _, ok := rv.Addr().Interface().(encoding.TextMarshaler); ok { + return true + } + if _, ok := rv.Addr().Interface().(Marshaler); ok { + return true + } } + return false } // tomlArrayType returns the element type of a TOML array. The type returned diff --git a/encode_test.go b/encode_test.go index 65aa10a0..f12cd9c7 100644 --- a/encode_test.go +++ b/encode_test.go @@ -408,22 +408,22 @@ func TestEncodeTOMLMarshaler(t *testing.T) { x := struct { Name string Labels map[string]string - Sound sound - Sound2 *sound - Food food - Food2 *food - Complex cplx - Fun fun + Sound sound2 + Sound2 *sound2 + Food food2 + Food2 *food2 + Complex cplx2 + Fun fun2 }{ Name: "Goblok", - Sound: sound{"miauw"}, - Sound2: &sound{"miauw"}, + Sound: sound2{"miauw"}, + Sound2: &sound2{"miauw"}, Labels: map[string]string{ "type": "cat", "color": "black", }, - Food: food{[]string{"chicken", "fish"}}, - Food2: &food{[]string{"chicken", "fish"}}, + Food: food2{[]string{"chicken", "fish"}}, + Food2: &food2{[]string{"chicken", "fish"}}, Complex: complex(42, 666), Fun: func() { panic("x") }, } diff --git a/error_test.go b/error_test.go index 913be858..75401583 100644 --- a/error_test.go +++ b/error_test.go @@ -95,9 +95,6 @@ func TestParseError(t *testing.T) { if !strings.HasSuffix(path, ".toml") { return nil } - if f.Name() != "datetime-no-secs.toml" { - //continue - } if f.Name() == "string-multiline-escape-space.toml" || f.Name() == "bad-utf8-at-end.toml" { return nil diff --git a/internal/tag/rm.go b/internal/tag/rm.go index a8903fd1..2647e64f 100644 --- a/internal/tag/rm.go +++ b/internal/tag/rm.go @@ -102,7 +102,7 @@ func untag(typed map[string]interface{}) (interface{}, error) { func parseTime(v, format string, l *time.Location) (time.Time, error) { t, err := time.Parse(format, v) if err != nil { - return time.Time{}, fmt.Errorf("Could not parse %q as a datetime: %w", v, err) + return time.Time{}, fmt.Errorf("could not parse %q as a datetime: %w", v, err) } if l != nil { t = t.In(l) diff --git a/internal/toml-test/json.go b/internal/toml-test/json.go index 127b50e9..a5fa2830 100644 --- a/internal/toml-test/json.go +++ b/internal/toml-test/json.go @@ -218,16 +218,6 @@ func (r Test) cmpAsDatetimes(kind, want, have string) Test { return r } -func (r Test) cmpAsDatetimesLocal(want, have string) Test { - if datetimeRepl.Replace(want) != datetimeRepl.Replace(have) { - return r.fail("Values for key '%s' don't match:\n"+ - " Expected: %v\n"+ - " Your encoder: %v", - r.Key, want, have) - } - return r -} - func (r Test) kjoin(key string) Test { if len(r.Key) == 0 { r.Key = key diff --git a/internal/toml-test/runner.go b/internal/toml-test/runner.go index 7d074056..410df235 100644 --- a/internal/toml-test/runner.go +++ b/internal/toml-test/runner.go @@ -367,7 +367,7 @@ func (t *Test) ReadWantTOML(fsys fs.FS) (v interface{}, err error) { } _, err = toml.Decode(t.Want, &v) if err != nil { - return nil, fmt.Errorf("Could not decode TOML file %q:\n %s", path, err) + return nil, fmt.Errorf("could not decode TOML file %q:\n %s", path, err) } return v, nil } diff --git a/parse.go b/parse.go index bf02aaec..f9e13e5f 100644 --- a/parse.go +++ b/parse.go @@ -11,15 +11,15 @@ import ( ) type parser struct { - mapping map[string]interface{} - types map[string]tomlType - lx *lexer - - ordered []Key // List of keys in the order that they appear in the TOML data. - context Key // Full key for the current hash in scope. - currentKey string // Base key name for everything except hashes. - pos Position // Position - implicits map[string]struct{} // Record implied keys (e.g. 'key.group.names'). + lx *lexer + context Key // Full key for the current hash in scope. + currentKey string // Base key name for everything except hashes. + pos Position // Current position in the TOML file. + + ordered []Key // List of keys in the order that they appear in the TOML data. + mapping map[string]interface{} // Map keyname → key value. + types map[string]tomlType // Map keyname → TOML type. + implicits map[string]struct{} // Record implicit keys (e.g. "key.group.names"). } func parse(data string) (p *parser, err error) { @@ -597,9 +597,7 @@ func (p *parser) setValue(key string, value interface{}) { // current context (which is either a table or an array of tables). func (p *parser) setType(key string, typ tomlType) { keyContext := make(Key, 0, len(p.context)+1) - for _, k := range p.context { - keyContext = append(keyContext, k) - } + keyContext = append(keyContext, p.context...) if len(key) > 0 { // allow type setting for hashes keyContext = append(keyContext, key) } diff --git a/type_fields.go b/type_fields.go index 608997c2..254ca82e 100644 --- a/type_fields.go +++ b/type_fields.go @@ -70,8 +70,8 @@ func typeFields(t reflect.Type) []field { next := []field{{typ: t}} // Count of queued names for current level and the next. - count := map[reflect.Type]int{} - nextCount := map[reflect.Type]int{} + var count map[reflect.Type]int + var nextCount map[reflect.Type]int // Types already visited at an earlier level. visited := map[reflect.Type]bool{}