summaryrefslogtreecommitdiffstats
path: root/src/internal/reflectlite/export_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/internal/reflectlite/export_test.go')
-rw-r--r--src/internal/reflectlite/export_test.go117
1 files changed, 117 insertions, 0 deletions
diff --git a/src/internal/reflectlite/export_test.go b/src/internal/reflectlite/export_test.go
new file mode 100644
index 0000000..88be6e2
--- /dev/null
+++ b/src/internal/reflectlite/export_test.go
@@ -0,0 +1,117 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package reflectlite
+
+import (
+ "unsafe"
+)
+
+// Field returns the i'th field of the struct v.
+// It panics if v's Kind is not Struct or i is out of range.
+func Field(v Value, i int) Value {
+ if v.kind() != Struct {
+ panic(&ValueError{"reflect.Value.Field", v.kind()})
+ }
+ tt := (*structType)(unsafe.Pointer(v.typ))
+ if uint(i) >= uint(len(tt.Fields)) {
+ panic("reflect: Field index out of range")
+ }
+ field := &tt.Fields[i]
+ typ := field.Typ
+
+ // Inherit permission bits from v, but clear flagEmbedRO.
+ fl := v.flag&(flagStickyRO|flagIndir|flagAddr) | flag(typ.Kind())
+ // Using an unexported field forces flagRO.
+ if !field.Name.IsExported() {
+ if field.Embedded() {
+ fl |= flagEmbedRO
+ } else {
+ fl |= flagStickyRO
+ }
+ }
+ // Either flagIndir is set and v.ptr points at struct,
+ // or flagIndir is not set and v.ptr is the actual struct data.
+ // In the former case, we want v.ptr + offset.
+ // In the latter case, we must have field.offset = 0,
+ // so v.ptr + field.offset is still the correct address.
+ ptr := add(v.ptr, field.Offset, "same as non-reflect &v.field")
+ return Value{typ, ptr, fl}
+}
+
+func TField(typ Type, i int) Type {
+ t := typ.(rtype)
+ if t.Kind() != Struct {
+ panic("reflect: Field of non-struct type")
+ }
+ tt := (*structType)(unsafe.Pointer(t.Type))
+
+ return StructFieldType(tt, i)
+}
+
+// Field returns the i'th struct field.
+func StructFieldType(t *structType, i int) Type {
+ if i < 0 || i >= len(t.Fields) {
+ panic("reflect: Field index out of bounds")
+ }
+ p := &t.Fields[i]
+ return toType(p.Typ)
+}
+
+// Zero returns a Value representing the zero value for the specified type.
+// The result is different from the zero value of the Value struct,
+// which represents no value at all.
+// For example, Zero(TypeOf(42)) returns a Value with Kind Int and value 0.
+// The returned value is neither addressable nor settable.
+func Zero(typ Type) Value {
+ if typ == nil {
+ panic("reflect: Zero(nil)")
+ }
+ t := typ.common()
+ fl := flag(t.Kind())
+ if ifaceIndir(t) {
+ return Value{t, unsafe_New(t), fl | flagIndir}
+ }
+ return Value{t, nil, fl}
+}
+
+// ToInterface returns v's current value as an interface{}.
+// It is equivalent to:
+//
+// var i interface{} = (v's underlying value)
+//
+// It panics if the Value was obtained by accessing
+// unexported struct fields.
+func ToInterface(v Value) (i any) {
+ return valueInterface(v)
+}
+
+type EmbedWithUnexpMeth struct{}
+
+func (EmbedWithUnexpMeth) f() {}
+
+type pinUnexpMeth interface {
+ f()
+}
+
+var pinUnexpMethI = pinUnexpMeth(EmbedWithUnexpMeth{})
+
+func FirstMethodNameBytes(t Type) *byte {
+ _ = pinUnexpMethI
+
+ ut := t.uncommon()
+ if ut == nil {
+ panic("type has no methods")
+ }
+ m := ut.Methods()[0]
+ mname := t.(rtype).nameOff(m.Name)
+ if *mname.DataChecked(0, "name flag field")&(1<<2) == 0 {
+ panic("method name does not have pkgPath *string")
+ }
+ return mname.Bytes
+}
+
+type Buffer struct {
+ buf []byte
+}