blob: 354ea9dbd07325ec7fb9c68c3cb852e94d8ca487 [file] [log] [blame]
Marcel van Lohuizen96507262019-02-08 17:48:17 +01001// Copyright 2019 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package reflectlite
6
7import (
8 "unsafe"
9)
10
11// Field returns the i'th field of the struct v.
12// It panics if v's Kind is not Struct or i is out of range.
13func Field(v Value, i int) Value {
14 if v.kind() != Struct {
15 panic(&ValueError{"reflect.Value.Field", v.kind()})
16 }
17 tt := (*structType)(unsafe.Pointer(v.typ))
18 if uint(i) >= uint(len(tt.fields)) {
19 panic("reflect: Field index out of range")
20 }
21 field := &tt.fields[i]
22 typ := field.typ
23
24 // Inherit permission bits from v, but clear flagEmbedRO.
25 fl := v.flag&(flagStickyRO|flagIndir|flagAddr) | flag(typ.Kind())
26 // Using an unexported field forces flagRO.
27 if !field.name.isExported() {
28 if field.embedded() {
29 fl |= flagEmbedRO
30 } else {
31 fl |= flagStickyRO
32 }
33 }
34 // Either flagIndir is set and v.ptr points at struct,
35 // or flagIndir is not set and v.ptr is the actual struct data.
36 // In the former case, we want v.ptr + offset.
37 // In the latter case, we must have field.offset = 0,
38 // so v.ptr + field.offset is still the correct address.
39 ptr := add(v.ptr, field.offset(), "same as non-reflect &v.field")
40 return Value{typ, ptr, fl}
41}
42
43func TField(typ Type, i int) Type {
44 t := typ.(*rtype)
45 if t.Kind() != Struct {
46 panic("reflect: Field of non-struct type")
47 }
48 tt := (*structType)(unsafe.Pointer(t))
49
50 return StructFieldType(tt, i)
51}
52
53// Field returns the i'th struct field.
54func StructFieldType(t *structType, i int) Type {
55 if i < 0 || i >= len(t.fields) {
56 panic("reflect: Field index out of bounds")
57 }
58 p := &t.fields[i]
59 return toType(p.typ)
60}
61
62// Zero returns a Value representing the zero value for the specified type.
63// The result is different from the zero value of the Value struct,
64// which represents no value at all.
65// For example, Zero(TypeOf(42)) returns a Value with Kind Int and value 0.
66// The returned value is neither addressable nor settable.
67func Zero(typ Type) Value {
68 if typ == nil {
69 panic("reflect: Zero(nil)")
70 }
71 t := typ.(*rtype)
72 fl := flag(t.Kind())
73 if ifaceIndir(t) {
74 return Value{t, unsafe_New(t), fl | flagIndir}
75 }
76 return Value{t, nil, fl}
77}
78
79// ToInterface returns v's current value as an interface{}.
80// It is equivalent to:
81// var i interface{} = (v's underlying value)
82// It panics if the Value was obtained by accessing
83// unexported struct fields.
84func ToInterface(v Value) (i interface{}) {
85 return valueInterface(v)
86}
87
88type EmbedWithUnexpMeth struct{}
89
90func (EmbedWithUnexpMeth) f() {}
91
92type pinUnexpMeth interface {
93 f()
94}
95
96var pinUnexpMethI = pinUnexpMeth(EmbedWithUnexpMeth{})
97
98func FirstMethodNameBytes(t Type) *byte {
99 _ = pinUnexpMethI
100
101 ut := t.uncommon()
102 if ut == nil {
103 panic("type has no methods")
104 }
105 m := ut.methods()[0]
106 mname := t.(*rtype).nameOff(m.name)
107 if *mname.data(0, "name flag field")&(1<<2) == 0 {
108 panic("method name does not have pkgPath *string")
109 }
110 return mname.bytes
111}
112
113type Buffer struct {
114 buf []byte
115}