From 6872a8e1c9904af5f6c23e42e01b027c8cd1c813 Mon Sep 17 00:00:00 2001 From: Joe Tsai Date: Fri, 22 Sep 2017 15:44:09 -0700 Subject: [PATCH] encoding/json: cleanup detection of unexported embedded fields CL 60410 fixes the compiler such that reflect.StructField.PkgPath is non-empty if and only if the field is unexported. Given that property, we can cleanup the logic in the json encoder to avoid parsing the field name to detect export properties. Updates #21122 Change-Id: Ic01b9c4ca76386774846b742b0c1b9b948f53e7c Reviewed-on: https://go-review.googlesource.com/65550 Run-TryBot: Joe Tsai TryBot-Result: Gobot Gobot Reviewed-by: Matthew Dempsky --- src/encoding/json/encode.go | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/src/encoding/json/encode.go b/src/encoding/json/encode.go index 9a2f841335..d1dda9796a 100644 --- a/src/encoding/json/encode.go +++ b/src/encoding/json/encode.go @@ -1091,21 +1091,19 @@ func typeFields(t reflect.Type) []field { // Scan f.typ for fields to include. for i := 0; i < f.typ.NumField(); i++ { sf := f.typ.Field(i) + isUnexported := sf.PkgPath != "" if sf.Anonymous { t := sf.Type if t.Kind() == reflect.Ptr { t = t.Elem() } - // If embedded, StructField.PkgPath is not a reliable - // indicator of whether the field is exported. - // See https://golang.org/issue/21122 - if !isExported(t.Name()) && t.Kind() != reflect.Struct { + if isUnexported && t.Kind() != reflect.Struct { // Ignore embedded fields of unexported non-struct types. - // Do not ignore embedded fields of unexported struct types - // since they may have exported fields. continue } - } else if sf.PkgPath != "" { + // Do not ignore embedded fields of unexported struct types + // since they may have exported fields. + } else if isUnexported { // Ignore unexported non-embedded fields. continue } @@ -1224,12 +1222,6 @@ func typeFields(t reflect.Type) []field { return fields } -// isExported reports whether the identifier is exported. -func isExported(id string) bool { - r, _ := utf8.DecodeRuneInString(id) - return unicode.IsUpper(r) -} - // dominantField looks through the fields, all of which are known to // have the same name, to find the single field that dominates the // others using Go's embedding rules, modified by the presence of