index []int
pkgPath string
embedded bool
+ exported bool
}
checkPkgPath := func(name string, s []pkgpathTest) {
if got, want := f.Anonymous, test.embedded; got != want {
t.Errorf("%s: Field(%d).Anonymous = %v, want %v", name, test.index, got, want)
}
+ if got, want := f.IsExported(), test.exported; got != want {
+ t.Errorf("%s: Field(%d).IsExported = %v, want %v", name, test.index, got, want)
+ }
}
}
checkPkgPath("testStruct", []pkgpathTest{
- {[]int{0}, "", false}, // Exported
- {[]int{1}, "reflect_test", false}, // unexported
- {[]int{2}, "", true}, // OtherPkgFields
- {[]int{2, 0}, "", false}, // OtherExported
- {[]int{2, 1}, "reflect", false}, // otherUnexported
- {[]int{3}, "reflect_test", true}, // int
- {[]int{4}, "reflect_test", true}, // *x
+ {[]int{0}, "", false, true}, // Exported
+ {[]int{1}, "reflect_test", false, false}, // unexported
+ {[]int{2}, "", true, true}, // OtherPkgFields
+ {[]int{2, 0}, "", false, true}, // OtherExported
+ {[]int{2, 1}, "reflect", false, false}, // otherUnexported
+ {[]int{3}, "reflect_test", true, false}, // int
+ {[]int{4}, "reflect_test", true, false}, // *x
})
type localOtherPkgFields OtherPkgFields
typ = TypeOf(localOtherPkgFields{})
checkPkgPath("localOtherPkgFields", []pkgpathTest{
- {[]int{0}, "", false}, // OtherExported
- {[]int{1}, "reflect", false}, // otherUnexported
+ {[]int{0}, "", false, true}, // OtherExported
+ {[]int{1}, "reflect", false, false}, // otherUnexported
})
}
+func TestMethodPkgPath(t *testing.T) {
+ type I interface {
+ x()
+ X()
+ }
+ typ := TypeOf((*interface {
+ I
+ y()
+ Y()
+ })(nil)).Elem()
+
+ tests := []struct {
+ name string
+ pkgPath string
+ exported bool
+ }{
+ {"X", "", true},
+ {"Y", "", true},
+ {"x", "reflect_test", false},
+ {"y", "reflect_test", false},
+ }
+
+ for _, test := range tests {
+ m, _ := typ.MethodByName(test.name)
+ if got, want := m.PkgPath, test.pkgPath; got != want {
+ t.Errorf("MethodByName(%q).PkgPath = %q, want %q", test.name, got, want)
+ }
+ if got, want := m.IsExported(), test.exported; got != want {
+ t.Errorf("MethodByName(%q).IsExported = %v, want %v", test.name, got, want)
+ }
+ }
+}
+
func TestVariadicType(t *testing.T) {
// Test example from Type documentation.
var f func(x int, y ...float64)
// Method represents a single method.
type Method struct {
// Name is the method name.
+ Name string
+
// PkgPath is the package path that qualifies a lower case (unexported)
// method name. It is empty for upper case (exported) method names.
// The combination of PkgPath and Name uniquely identifies a method
// in a method set.
// See https://golang.org/ref/spec#Uniqueness_of_identifiers
- Name string
PkgPath string
Type Type // method type
Index int // index for Type.Method
}
+// IsExported reports whether the method is exported.
+func (m Method) IsExported() bool {
+ return m.PkgPath == ""
+}
+
const (
kindDirectIface = 1 << 5
kindGCProg = 1 << 6 // Type.gc points to GC program
type StructField struct {
// Name is the field name.
Name string
+
// PkgPath is the package path that qualifies a lower case (unexported)
// field name. It is empty for upper case (exported) field names.
// See https://golang.org/ref/spec#Uniqueness_of_identifiers
Anonymous bool // is an embedded field
}
+// IsExported reports whether the field is exported.
+func (f StructField) IsExported() bool {
+ return f.PkgPath == ""
+}
+
// A StructTag is the tag string in a struct field.
//
// By convention, tag strings are a concatenation of
panic("reflect.StructOf: field \"" + field.Name + "\" is anonymous but has PkgPath set")
}
- exported := field.PkgPath == ""
- if exported {
+ if field.IsExported() {
// Best-effort check for misuse.
// Since this field will be treated as exported, not much harm done if Unicode lowercase slips through.
c := field.Name[0]
resolveReflectType(field.Type.common()) // install in runtime
f := structField{
- name: newName(field.Name, string(field.Tag), exported),
+ name: newName(field.Name, string(field.Tag), field.IsExported()),
typ: field.Type.common(),
offsetEmbed: offsetEmbed,
}