mirror of
https://github.com/golang/go
synced 2024-11-26 17:56:55 -07:00
reflect: let StructOf define unexported fields
This was missing from the original StructOf CL because I couldn't think of a use for it. Now I can: even with types used entirely by reflect, unexported fields can be set using UnsafeAddr. Change-Id: I5e7e3d81d16e8817cdd69d85796ce33930ef523b Reviewed-on: https://go-review.googlesource.com/c/go/+/85661 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
739bf6b929
commit
2d1c033259
@ -115,6 +115,19 @@ TODO
|
||||
|
||||
</dl><!-- plugin -->
|
||||
|
||||
<dl id="reflect">
|
||||
|
||||
<dt><a href="/pkg/reflect/">reflect</a></dt>
|
||||
<dd>
|
||||
<p><!-- CL 85661 -->
|
||||
<a href="/pkg/reflect#StructOf"><code>StructOf</code></a> now
|
||||
supports creating struct types with unexported fields, by
|
||||
setting the <code>PkgPath</code> field in
|
||||
a <code>StructField</code> element.
|
||||
</p>
|
||||
|
||||
</dl><!-- reflect -->
|
||||
|
||||
<dl id="runtime"><dt><a href="/pkg/runtime/">runtime</a></dt>
|
||||
<dd>
|
||||
<p><!-- CL 187739 -->
|
||||
|
@ -4733,17 +4733,14 @@ func TestStructOfExportRules(t *testing.T) {
|
||||
mustPanic: true,
|
||||
},
|
||||
{
|
||||
field: StructField{Name: "s2", Type: TypeOf(int(0)), PkgPath: "other/pkg"},
|
||||
mustPanic: true,
|
||||
field: StructField{Name: "s2", Type: TypeOf(int(0)), PkgPath: "other/pkg"},
|
||||
},
|
||||
{
|
||||
field: StructField{Name: "s2", Type: TypeOf(int(0)), PkgPath: "other/pkg"},
|
||||
mustPanic: true,
|
||||
field: StructField{Name: "s2", Type: TypeOf(int(0)), PkgPath: "other/pkg"},
|
||||
},
|
||||
{
|
||||
field: StructField{Name: "S", Type: TypeOf(S1{})},
|
||||
mustPanic: false,
|
||||
exported: true,
|
||||
field: StructField{Name: "S", Type: TypeOf(S1{})},
|
||||
exported: true,
|
||||
},
|
||||
{
|
||||
field: StructField{Name: "S", Type: TypeOf((*S1)(nil))},
|
||||
@ -4774,20 +4771,16 @@ func TestStructOfExportRules(t *testing.T) {
|
||||
mustPanic: true,
|
||||
},
|
||||
{
|
||||
field: StructField{Name: "s", Type: TypeOf(S1{}), PkgPath: "other/pkg"},
|
||||
mustPanic: true, // TODO(sbinet): creating a name with a package path
|
||||
field: StructField{Name: "s", Type: TypeOf(S1{}), PkgPath: "other/pkg"},
|
||||
},
|
||||
{
|
||||
field: StructField{Name: "s", Type: TypeOf((*S1)(nil)), PkgPath: "other/pkg"},
|
||||
mustPanic: true, // TODO(sbinet): creating a name with a package path
|
||||
field: StructField{Name: "s", Type: TypeOf((*S1)(nil)), PkgPath: "other/pkg"},
|
||||
},
|
||||
{
|
||||
field: StructField{Name: "s", Type: TypeOf(s2{}), PkgPath: "other/pkg"},
|
||||
mustPanic: true, // TODO(sbinet): creating a name with a package path
|
||||
field: StructField{Name: "s", Type: TypeOf(s2{}), PkgPath: "other/pkg"},
|
||||
},
|
||||
{
|
||||
field: StructField{Name: "s", Type: TypeOf((*s2)(nil)), PkgPath: "other/pkg"},
|
||||
mustPanic: true, // TODO(sbinet): creating a name with a package path
|
||||
field: StructField{Name: "s", Type: TypeOf((*s2)(nil)), PkgPath: "other/pkg"},
|
||||
},
|
||||
{
|
||||
field: StructField{Name: "", Type: TypeOf(ΦType{})},
|
||||
|
@ -2731,15 +2731,18 @@ func StructOf(fields []StructField) Type {
|
||||
}
|
||||
|
||||
func runtimeStructField(field StructField) structField {
|
||||
if field.PkgPath != "" {
|
||||
panic("reflect.StructOf: StructOf does not allow unexported fields")
|
||||
if field.Anonymous && field.PkgPath != "" {
|
||||
panic("reflect.StructOf: field \"" + field.Name + "\" is anonymous but has PkgPath set")
|
||||
}
|
||||
|
||||
// Best-effort check for misuse.
|
||||
// Since PkgPath is empty, not much harm done if Unicode lowercase slips through.
|
||||
c := field.Name[0]
|
||||
if 'a' <= c && c <= 'z' || c == '_' {
|
||||
panic("reflect.StructOf: field \"" + field.Name + "\" is unexported but missing PkgPath")
|
||||
exported := field.PkgPath == ""
|
||||
if exported {
|
||||
// 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]
|
||||
if 'a' <= c && c <= 'z' || c == '_' {
|
||||
panic("reflect.StructOf: field \"" + field.Name + "\" is unexported but missing PkgPath")
|
||||
}
|
||||
}
|
||||
|
||||
offsetEmbed := uintptr(0)
|
||||
@ -2749,7 +2752,7 @@ func runtimeStructField(field StructField) structField {
|
||||
|
||||
resolveReflectType(field.Type.common()) // install in runtime
|
||||
return structField{
|
||||
name: newName(field.Name, string(field.Tag), true),
|
||||
name: newName(field.Name, string(field.Tag), exported),
|
||||
typ: field.Type.common(),
|
||||
offsetEmbed: offsetEmbed,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user