Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(664)

Delta Between Two Patch Sets: src/pkg/reflect/type.go

Issue 4281055: code review 4281055: reflect: new Type and Value definitions (Closed)
Left Patch Set: diff -r 82050f8e7881 https://go.googlecode.com/hg/ Created 12 years, 12 months ago
Right Patch Set: diff -r ce9962e29e4b https://go.googlecode.com/hg Created 12 years, 11 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « src/pkg/reflect/tostring_test.go ('k') | src/pkg/reflect/value.go » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 // Copyright 2009 The Go Authors. All rights reserved. 1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 // The reflect package implements run-time reflection, allowing a program to 5 // The reflect package implements run-time reflection, allowing a program to
6 // manipulate objects with arbitrary types. The typical use is to take a 6 // manipulate objects with arbitrary types. The typical use is to take a
7 // value with static type interface{} and extract its dynamic type 7 // value with static type interface{} and extract its dynamic type
8 // information by calling Typeof, which returns a Type. 8 // information by calling Typeof, which returns a Type.
9 // 9 //
10 // A call to NewValue returns a Value representing the run-time data. 10 // A call to NewValue returns a Value representing the run-time data.
11 // MakeZero takes a Type and returns a Value representing a zero value 11 // Zero takes a Type and returns a Value representing a zero value
12 // for that type. 12 // for that type.
13 package reflect 13 package reflect
14 14
15 import ( 15 import (
16 "runtime" 16 "runtime"
17 "strconv" 17 "strconv"
18 "sync" 18 "sync"
19 "unsafe" 19 "unsafe"
20 ) 20 )
21 21
22 /*
23 We want to be able to call methods on Type and to compare types for equality.
r 2011/04/02 18:45:33 i think this comment can go. at least it needs rep
24 Thus Type must be either an opaque type or an interface.
25 If we make it an interface then existing code changes less.
26 If we make Type an opaque type then that could allow overwriting
27 type data using copying. It also means saying *Type everywhere
28 but plain Value (not *Value), which is a bit strange. Let's use
29 the interface for better protection and to lose the *.
30
31
32 */
33
34 // Type is the representation of a Go type. 22 // Type is the representation of a Go type.
r 2011/04/02 18:45:33 might be good to have helper methods or functions
35 // 23 //
36 // Not all methods apply to all kinds of types. Restrictions, 24 // Not all methods apply to all kinds of types. Restrictions,
37 // if any, are noted in the documentation for each method. 25 // if any, are noted in the documentation for each method.
38 // Use the Kind method to find out the kind of type before 26 // Use the Kind method to find out the kind of type before
39 // calling kind-specific methods. Calling a method 27 // calling kind-specific methods. Calling a method
40 // inappropriate to the kind of type causes a run time panic. 28 // inappropriate to the kind of type causes a run-time panic.
r 2011/04/02 18:45:33 s/run time/run-time/ (adjective)
41 type Type interface { 29 type Type interface {
42 // Methods applicable to all types. 30 // Methods applicable to all types.
43 31
44 » // Align returns the alignment of a value of this type 32 » // Align returns the alignment in bytes of a value of
45 » // when allocated in memory. 33 » // this type when allocated in memory.
r 2011/04/02 18:45:33 what units?
46 Align() int 34 Align() int
47 35
48 » // FieldAlign returns the alignment of a value of this type 36 » // FieldAlign returns the alignment in bytes of a value of
49 » // when used as a field in a struct. 37 » // this type when used as a field in a struct.
r 2011/04/02 18:45:33 what units?
50 FieldAlign() int 38 FieldAlign() int
51 39
52 // Method returns the i'th method in the type's method set. 40 // Method returns the i'th method in the type's method set.
r 2011/04/02 18:45:33 what happens if i is out of range? obviously, it p
41 // It panics if i is not in the range [0, NumMethod()).
53 // 42 //
54 // For a non-interface type T or *T, the returned Method's Type and Func 43 // For a non-interface type T or *T, the returned Method's Type and Func
55 // fields describe a function whose first argument is the receiver. 44 // fields describe a function whose first argument is the receiver.
56 // 45 //
57 // For an interface type, the returned Method's Type field gives the 46 // For an interface type, the returned Method's Type field gives the
58 // method signature, without a receiver, and the Func field is nil. 47 // method signature, without a receiver, and the Func field is nil.
59 Method(int) Method 48 Method(int) Method
60 49
61 // NumMethods returns the number of methods in the type's method set. 50 // NumMethods returns the number of methods in the type's method set.
62 NumMethod() int 51 NumMethod() int
63 52
64 // Name returns the type's name within its package. 53 // Name returns the type's name within its package.
r 2011/04/02 18:45:33 really? i thought it returned pkg.NameOfType
65 // It returns an empty string for unnamed types. 54 // It returns an empty string for unnamed types.
66 Name() string 55 Name() string
67 56
68 // PkgPath returns the type's package path. 57 // PkgPath returns the type's package path.
69 // The package path is a full package import path like "container/vector ". 58 // The package path is a full package import path like "container/vector ".
70 // PkgPath returns an empty string for unnamed types. 59 // PkgPath returns an empty string for unnamed types.
71 PkgPath() string 60 PkgPath() string
72 61
73 // Size returns the number of bytes needed to store 62 // Size returns the number of bytes needed to store
74 // a value of the given type; it is analogous to unsafe.Sizeof. 63 // a value of the given type; it is analogous to unsafe.Sizeof.
75 Size() uintptr 64 Size() uintptr
76 65
77 // String returns a string representation of the type. 66 // String returns a string representation of the type.
78 // The string representation may use shortened package names 67 // The string representation may use shortened package names
79 // (e.g., vector instead of "container/vector") and is not 68 // (e.g., vector instead of "container/vector") and is not
80 // guaranteed to be unique among types. To test for equality, 69 // guaranteed to be unique among types. To test for equality,
81 // compare the Types directly. 70 // compare the Types directly.
82 String() string 71 String() string
83 72
84 // Kind returns the specific kind of this type. 73 // Kind returns the specific kind of this type.
85 Kind() Kind 74 Kind() Kind
86 75
87 // Methods applicable only to some types, depending on Kind. 76 // Methods applicable only to some types, depending on Kind.
88 // The methods allowed for each kind are: 77 // The methods allowed for each kind are:
89 // 78 //
90 // Int*, Uint*, Float*, Complex*: Bits 79 // Int*, Uint*, Float*, Complex*: Bits
91 // Array: Elem, Len 80 // Array: Elem, Len
92 // Chan: ChanDir, Elem 81 // Chan: ChanDir, Elem
93 » //» Func: In, NumIn, Out, NumOut, DotDotDot. 82 » //» Func: In, NumIn, Out, NumOut, IsVariadic.
94 // Map: Key, Elem 83 // Map: Key, Elem
95 // Ptr: Elem 84 // Ptr: Elem
96 // Slice: Elem 85 // Slice: Elem
97 // Struct: Field, FieldByIndex, FieldByName, FieldByNameFunc, NumFi eld 86 // Struct: Field, FieldByIndex, FieldByName, FieldByNameFunc, NumFi eld
98 87
99 // Bits returns the size of the type in bits. 88 // Bits returns the size of the type in bits.
100 // It panics if the type's Kind is not one of the 89 // It panics if the type's Kind is not one of the
101 » // sized or unsized Int, Uint, Float, or Complex knids. 90 » // sized or unsized Int, Uint, Float, or Complex kinds.
102 Bits() int 91 Bits() int
103 92
104 // ChanDir returns a channel type's direction. 93 // ChanDir returns a channel type's direction.
105 // It panics if the type's Kind is not Chan. 94 // It panics if the type's Kind is not Chan.
106 ChanDir() ChanDir 95 ChanDir() ChanDir
107 96
108 » // DotDotDot returns true if a function type's final input parameter 97 » // IsVariadic returns true if a function type's final input parameter
109 // is a "..." parameter. If so, t.In(t.NumIn() - 1) returns the paramet er's 98 // is a "..." parameter. If so, t.In(t.NumIn() - 1) returns the paramet er's
110 » // underlying static type []T. 99 » // implicit actual type []T.
111 // 100 //
112 // For concreteness, if t represents func(x int, y ... float), then 101 // For concreteness, if t represents func(x int, y ... float), then
113 // 102 //
114 // t.NumIn() == 2 103 // t.NumIn() == 2
115 // t.In(0) is the reflect.Type for "int" 104 // t.In(0) is the reflect.Type for "int"
116 // t.In(1) is the reflect.Type for "[]float" 105 // t.In(1) is the reflect.Type for "[]float"
117 » //» t.DotDotDot() == true 106 » //» t.IsVariadic() == true
118 // 107 //
119 » // DotDotDot panics if the type's Kind is not Func. 108 » // IsVariadic panics if the type's Kind is not Func.
120 » DotDotDot() bool 109 » IsVariadic() bool
r 2011/04/02 18:45:33 wrong name for a boolean method. HasDotDotDot is
121 110
122 // Elem returns a type's element type. 111 // Elem returns a type's element type.
niemeyer 2011/04/04 13:52:35 s/element type/element Type/ ?
rsc 2011/04/05 16:29:45 I intentionally left type lower case in most place
123 // It panics if the type's Kind is not Array, Chan, Map, Ptr, or Slice. 112 // It panics if the type's Kind is not Array, Chan, Map, Ptr, or Slice.
124 Elem() Type 113 Elem() Type
125 114
126 // Field returns a struct type's i'th field. 115 // Field returns a struct type's i'th field.
r 2011/04/02 18:45:33 what if i is out of range?
127 // It panics if the type's Kind is not Struct. 116 // It panics if the type's Kind is not Struct.
117 // It panics if i is not in the range [0, NumField()).
128 Field(i int) StructField 118 Field(i int) StructField
129 119
130 // FieldByIndex returns the nested field corresponding 120 // FieldByIndex returns the nested field corresponding
131 // to the index sequence. It is equivalent to calling Field 121 // to the index sequence. It is equivalent to calling Field
132 // successively for each index i. 122 // successively for each index i.
133 // It panics if the type's Kind is not Struct. 123 // It panics if the type's Kind is not Struct.
134 FieldByIndex(index []int) StructField 124 FieldByIndex(index []int) StructField
135 125
136 // FieldByName returns the struct field with the given name 126 // FieldByName returns the struct field with the given name
137 // and a boolean indicating if the field was found. 127 // and a boolean indicating if the field was found.
138 FieldByName(name string) (StructField, bool) 128 FieldByName(name string) (StructField, bool)
139 129
140 // FieldByNameFunc returns the first struct field with a name 130 // FieldByNameFunc returns the first struct field with a name
141 // that satisfies the match function and a boolean indicating if 131 // that satisfies the match function and a boolean indicating if
142 // the field was found. 132 // the field was found.
143 FieldByNameFunc(match func(string) bool) (StructField, bool) 133 FieldByNameFunc(match func(string) bool) (StructField, bool)
144 134
145 // In returns the type of a function type's i'th input parameter. 135 // In returns the type of a function type's i'th input parameter.
146 // It panics if the type's Kind is not Func. 136 // It panics if the type's Kind is not Func.
r 2011/04/02 18:45:33 here and for Out: what if i is out of range?
137 // It panics if i is not in the range [0, NumIn()).
147 In(i int) Type 138 In(i int) Type
148 139
149 // Key returns a map type's key type. 140 // Key returns a map type's key type.
150 // It panics if the type's Kind is not Map. 141 // It panics if the type's Kind is not Map.
151 Key() Type 142 Key() Type
niemeyer 2011/04/04 13:52:35 Should this be called MapKey, or MapKeys be rename
rsc 2011/04/05 16:29:45 I don't think so. SliceType still uses Elem() to
152 143
153 // Len returns an array type's length. 144 // Len returns an array type's length.
154 // It panics if the type's Kind is not Array. 145 // It panics if the type's Kind is not Array.
155 Len() int 146 Len() int
156 147
157 // NumField returns a struct type's field count. 148 // NumField returns a struct type's field count.
158 // It panics if the type's Kind is not Struct. 149 // It panics if the type's Kind is not Struct.
159 NumField() int 150 NumField() int
160 151
161 // NumIn returns a function type's input parameter count. 152 // NumIn returns a function type's input parameter count.
162 // It panics if the type's Kind is not Func. 153 // It panics if the type's Kind is not Func.
163 NumIn() int 154 NumIn() int
164 155
165 // NumOut returns a function type's output parameter count. 156 // NumOut returns a function type's output parameter count.
166 // It panics if the type's Kind is not Func. 157 // It panics if the type's Kind is not Func.
167 NumOut() int 158 NumOut() int
168 159
169 // Out returns the type of a function type's i'th output parameter. 160 // Out returns the type of a function type's i'th output parameter.
170 // It panics if the type's Kind is not Func. 161 // It panics if the type's Kind is not Func.
162 // It panics if i is not in the range [0, NumOut()).
171 Out(i int) Type 163 Out(i int) Type
172 164
173 uncommon() *uncommonType 165 uncommon() *uncommonType
174 } 166 }
175 167
176 // A Kind represents the specific kind of type that a Type represents. 168 // A Kind represents the specific kind of type that a Type represents.
177 // The zero Kind is not a valid kind. 169 // The zero Kind is not a valid kind.
178 type Kind uint8 170 type Kind uint8
179 171
180 const ( 172 const (
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 } 475 }
484 476
485 func (t *commonType) ChanDir() ChanDir { 477 func (t *commonType) ChanDir() ChanDir {
486 if t.Kind() != Chan { 478 if t.Kind() != Chan {
487 panic("reflect: ChanDir of non-chan type") 479 panic("reflect: ChanDir of non-chan type")
488 } 480 }
489 tt := (*chanType)(unsafe.Pointer(t)) 481 tt := (*chanType)(unsafe.Pointer(t))
490 return ChanDir(tt.dir) 482 return ChanDir(tt.dir)
491 } 483 }
492 484
493 func (t *commonType) DotDotDot() bool { 485 func (t *commonType) IsVariadic() bool {
494 if t.Kind() != Func { 486 if t.Kind() != Func {
495 » » panic("reflect: DotDotDot of non-func type") 487 » » panic("reflect: IsVariadic of non-func type")
496 } 488 }
497 tt := (*funcType)(unsafe.Pointer(t)) 489 tt := (*funcType)(unsafe.Pointer(t))
498 return tt.dotdotdot 490 return tt.dotdotdot
499 } 491 }
500 492
501 func (t *commonType) Elem() Type { 493 func (t *commonType) Elem() Type {
502 switch t.Kind() { 494 switch t.Kind() {
503 case Array: 495 case Array:
504 tt := (*arrayType)(unsafe.Pointer(t)) 496 tt := (*arrayType)(unsafe.Pointer(t))
505 return toType(tt.elem) 497 return toType(tt.elem)
506 case Chan: 498 case Chan:
507 tt := (*chanType)(unsafe.Pointer(t)) 499 tt := (*chanType)(unsafe.Pointer(t))
508 return toType(tt.elem) 500 return toType(tt.elem)
509 case Map: 501 case Map:
510 tt := (*mapType)(unsafe.Pointer(t)) 502 tt := (*mapType)(unsafe.Pointer(t))
511 return toType(tt.elem) 503 return toType(tt.elem)
512 case Ptr: 504 case Ptr:
513 tt := (*ptrType)(unsafe.Pointer(t)) 505 tt := (*ptrType)(unsafe.Pointer(t))
514 return toType(tt.elem) 506 return toType(tt.elem)
515 case Slice: 507 case Slice:
516 tt := (*sliceType)(unsafe.Pointer(t)) 508 tt := (*sliceType)(unsafe.Pointer(t))
517 return toType(tt.elem) 509 return toType(tt.elem)
518 } 510 }
519 panic("reflect; Elem of invalid type") 511 panic("reflect; Elem of invalid type")
520 } 512 }
521 513
522 func (t *commonType) Field(i int) StructField { 514 func (t *commonType) Field(i int) StructField {
523 if t.Kind() != Struct { 515 if t.Kind() != Struct {
524 panic("reflect: Field of non-struct type") 516 panic("reflect: Field of non-struct type")
niemeyer 2011/04/04 13:52:35 It would be helpful to have a TypeError analogous
rsc 2011/04/05 16:29:45 Sure, I will add that in a separate CL.
525 } 517 }
526 tt := (*structType)(unsafe.Pointer(t)) 518 tt := (*structType)(unsafe.Pointer(t))
527 return tt.Field(i) 519 return tt.Field(i)
528 } 520 }
529 521
530 func (t *commonType) FieldByIndex(index []int) StructField { 522 func (t *commonType) FieldByIndex(index []int) StructField {
531 if t.Kind() != Struct { 523 if t.Kind() != Struct {
532 panic("reflect: FieldByIndex of non-struct type") 524 panic("reflect: FieldByIndex of non-struct type")
533 } 525 }
534 tt := (*structType)(unsafe.Pointer(t)) 526 tt := (*structType)(unsafe.Pointer(t))
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 668
677 // TODO(gri): Should there be an error/bool indicator if the index 669 // TODO(gri): Should there be an error/bool indicator if the index
678 // is wrong for FieldByIndex? 670 // is wrong for FieldByIndex?
679 671
680 // FieldByIndex returns the nested field corresponding to index. 672 // FieldByIndex returns the nested field corresponding to index.
681 func (t *structType) FieldByIndex(index []int) (f StructField) { 673 func (t *structType) FieldByIndex(index []int) (f StructField) {
682 f.Type = Type(t.toType()) 674 f.Type = Type(t.toType())
683 for i, x := range index { 675 for i, x := range index {
684 if i > 0 { 676 if i > 0 {
685 ft := f.Type 677 ft := f.Type
686 » » » if ft.Kind() == Ptr { 678 » » » if ft.Kind() == Ptr && ft.Elem().Kind() == Struct {
687 ft = ft.Elem() 679 ft = ft.Elem()
688 }
689 if ft.Kind() != Struct {
690 return StructField{}
niemeyer 2011/04/04 13:52:35 Should we take the chance to make this panic rathe
rsc 2011/04/05 16:29:45 Done.
691 } 680 }
692 f.Type = ft 681 f.Type = ft
693 } 682 }
694 f = f.Type.Field(x) 683 f = f.Type.Field(x)
695 } 684 }
696 return 685 return
697 } 686 }
698 687
699 const inf = 1 << 30 // infinity - no struct has that many nesting levels 688 const inf = 1 << 30 // infinity - no struct has that many nesting levels
700 689
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
866 p.hash = ct.hash*16777619 ^ '*' 855 p.hash = ct.hash*16777619 ^ '*'
867 856
868 p.uncommonType = nil 857 p.uncommonType = nil
869 p.ptrToThis = nil 858 p.ptrToThis = nil
870 p.elem = (*runtime.Type)(unsafe.Pointer(uintptr(unsafe.Pointer(ct)) - ui ntptr(unsafe.Offsetof(rt.ptrType)))) 859 p.elem = (*runtime.Type)(unsafe.Pointer(uintptr(unsafe.Pointer(ct)) - ui ntptr(unsafe.Offsetof(rt.ptrType))))
871 860
872 ptrMap.m[ct] = p 861 ptrMap.m[ct] = p
873 ptrMap.Unlock() 862 ptrMap.Unlock()
874 return p.commonType.toType() 863 return p.commonType.toType()
875 } 864 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b