mirror of
https://github.com/golang/go
synced 2024-11-20 05:54:43 -07:00
new reflect type.go implementation
R=r DELTA=179 (172 added, 6 deleted, 1 changed) OCL=31215 CL=31220
This commit is contained in:
parent
769919c4ee
commit
a7b4e9f03e
@ -39,7 +39,7 @@ type commonType struct {
|
|||||||
type method struct {
|
type method struct {
|
||||||
hash uint32;
|
hash uint32;
|
||||||
name *string;
|
name *string;
|
||||||
PkgPath *string;
|
pkgPath *string;
|
||||||
typ *runtime.Type;
|
typ *runtime.Type;
|
||||||
ifn unsafe.Pointer;
|
ifn unsafe.Pointer;
|
||||||
tfn unsafe.Pointer;
|
tfn unsafe.Pointer;
|
||||||
@ -149,12 +149,6 @@ type ArrayType struct {
|
|||||||
len uintptr;
|
len uintptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SliceType represents a slice type.
|
|
||||||
type SliceType struct {
|
|
||||||
commonType;
|
|
||||||
elem *runtime.Type;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ChanDir represents a channel type's direction.
|
// ChanDir represents a channel type's direction.
|
||||||
type ChanDir int
|
type ChanDir int
|
||||||
const (
|
const (
|
||||||
@ -205,6 +199,12 @@ type PtrType struct {
|
|||||||
elem *runtime.Type;
|
elem *runtime.Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SliceType represents a slice type.
|
||||||
|
type SliceType struct {
|
||||||
|
commonType;
|
||||||
|
elem *runtime.Type;
|
||||||
|
}
|
||||||
|
|
||||||
// Struct field
|
// Struct field
|
||||||
type structField struct {
|
type structField struct {
|
||||||
name *string;
|
name *string;
|
||||||
@ -279,83 +279,168 @@ type Type interface {
|
|||||||
func toType(i interface{}) Type
|
func toType(i interface{}) Type
|
||||||
|
|
||||||
func (t *uncommonType) Name() (pkgPath string, name string) {
|
func (t *uncommonType) Name() (pkgPath string, name string) {
|
||||||
|
if t == nil {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if t.pkgPath != nil {
|
||||||
|
pkgPath = *t.pkgPath;
|
||||||
|
}
|
||||||
|
if t.name != nil {
|
||||||
|
name = *t.name;
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *commonType) String() string {
|
func (t *commonType) String() string {
|
||||||
|
return *t.string;
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *commonType) Size() uintptr {
|
func (t *commonType) Size() uintptr {
|
||||||
|
return t.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *commonType) Align() int {
|
func (t *commonType) Align() int {
|
||||||
|
return int(t.align);
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *commonType) FieldAlign() int {
|
func (t *commonType) FieldAlign() int {
|
||||||
|
return int(t.fieldAlign);
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *uncommonType) Method(i int) (m Method) {
|
func (t *uncommonType) Method(i int) (m Method) {
|
||||||
|
if t == nil || i < 0 || i >= len(t.methods) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
p := &t.methods[i];
|
||||||
|
if p.name != nil {
|
||||||
|
m.Name = *p.name;
|
||||||
|
}
|
||||||
|
if p.pkgPath != nil {
|
||||||
|
m.PkgPath = *p.pkgPath;
|
||||||
|
}
|
||||||
|
m.Type = toType(*p.typ).(*FuncType);
|
||||||
|
fn := p.tfn;
|
||||||
|
m.Func = newFuncValue(m.Type, addr(&fn));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *uncommonType) NumMethod() int {
|
func (t *uncommonType) NumMethod() int {
|
||||||
|
if t == nil {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return len(t.methods);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(rsc): 6g supplies these, but they are not
|
||||||
|
// as efficient as they could be: they have commonType
|
||||||
|
// as the receiver instead of *commonType.
|
||||||
|
func (t *commonType) NumMethod() int {
|
||||||
|
return t.uncommonType.NumMethod();
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *commonType) Method(i int) (m Method) {
|
||||||
|
return t.uncommonType.Method(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *commonType) Name() (pkgPath string, name string) {
|
||||||
|
return t.uncommonType.Name();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Len returns the number of elements in the array.
|
// Len returns the number of elements in the array.
|
||||||
func (t *ArrayType) Len() int {
|
func (t *ArrayType) Len() int {
|
||||||
|
return int(t.len);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Elem returns the type of the array's elements.
|
// Elem returns the type of the array's elements.
|
||||||
func (t *ArrayType) Elem() Type {
|
func (t *ArrayType) Elem() Type {
|
||||||
|
return toType(*t.elem);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dir returns the channel direction.
|
// Dir returns the channel direction.
|
||||||
func (t *ChanType) Dir() ChanDir {
|
func (t *ChanType) Dir() ChanDir {
|
||||||
|
return ChanDir(t.dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Elem returns the channel's element type.
|
// Elem returns the channel's element type.
|
||||||
func (t *ChanType) Elem() Type {
|
func (t *ChanType) Elem() Type {
|
||||||
|
return toType(*t.elem);
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d ChanDir) String() string {
|
func (d ChanDir) String() string {
|
||||||
|
switch d {
|
||||||
|
case SendDir:
|
||||||
|
return "chan<-";
|
||||||
|
case RecvDir:
|
||||||
|
return "<-chan";
|
||||||
|
case BothDir:
|
||||||
|
return "chan";
|
||||||
|
}
|
||||||
|
return "ChanDir" + strconv.Itoa(int(d));
|
||||||
}
|
}
|
||||||
|
|
||||||
// In returns the type of the i'th function input parameter.
|
// In returns the type of the i'th function input parameter.
|
||||||
func (t *FuncType) In(i int) Type {
|
func (t *FuncType) In(i int) Type {
|
||||||
|
if i < 0 || i >= len(t.in) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
return toType(*t.in[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// NumIn returns the number of input parameters.
|
// NumIn returns the number of input parameters.
|
||||||
func (t *FuncType) NumIn() int {
|
func (t *FuncType) NumIn() int {
|
||||||
|
return len(t.in);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Out returns the type of the i'th function output parameter.
|
// Out returns the type of the i'th function output parameter.
|
||||||
func (t *FuncType) Out(i int) Type {
|
func (t *FuncType) Out(i int) Type {
|
||||||
|
if i < 0 || i >= len(t.out) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
return toType(*t.out[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// NumOut returns the number of function output parameters.
|
// NumOut returns the number of function output parameters.
|
||||||
func (t *FuncType) NumOut() int {
|
func (t *FuncType) NumOut() int {
|
||||||
|
return len(t.out);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method returns the i'th interface method.
|
// Method returns the i'th interface method.
|
||||||
func (t *InterfaceType) Method(i int) (m Method) {
|
func (t *InterfaceType) Method(i int) (m Method) {
|
||||||
|
if i < 0 || i >= len(t.methods) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
p := t.methods[i];
|
||||||
|
m.Name = *p.name;
|
||||||
|
if p.pkgPath != nil {
|
||||||
|
m.PkgPath = *p.pkgPath;
|
||||||
|
}
|
||||||
|
m.Type = toType(*p.typ).(*FuncType);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NumMethod returns the number of interface methods.
|
// NumMethod returns the number of interface methods.
|
||||||
func (t *InterfaceType) NumMethod() int {
|
func (t *InterfaceType) NumMethod() int {
|
||||||
|
return len(t.methods);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Key returns the map key type.
|
// Key returns the map key type.
|
||||||
func (t *MapType) Key() Type {
|
func (t *MapType) Key() Type {
|
||||||
|
return toType(*t.key);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Elem returns the map element type.
|
// Elem returns the map element type.
|
||||||
func (t *MapType) Elem() Type {
|
func (t *MapType) Elem() Type {
|
||||||
|
return toType(*t.elem);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Elem returns the pointer element type.
|
// Elem returns the pointer element type.
|
||||||
func (t *PtrType) Elem() Type {
|
func (t *PtrType) Elem() Type {
|
||||||
|
return toType(*t.elem);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Elem returns the type of the slice's elements.
|
// Elem returns the type of the slice's elements.
|
||||||
func (t *SliceType) Elem() Type {
|
func (t *SliceType) Elem() Type {
|
||||||
|
return toType(*t.elem);
|
||||||
}
|
}
|
||||||
|
|
||||||
type StructField struct {
|
type StructField struct {
|
||||||
@ -369,10 +454,91 @@ type StructField struct {
|
|||||||
|
|
||||||
// Field returns the i'th struct field.
|
// Field returns the i'th struct field.
|
||||||
func (t *StructType) Field(i int) (f StructField) {
|
func (t *StructType) Field(i int) (f StructField) {
|
||||||
|
if i < 0 || i >= len(t.fields) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
p := t.fields[i];
|
||||||
|
f.Type = toType(*p.typ);
|
||||||
|
if p.name != nil {
|
||||||
|
f.Name = *p.name;
|
||||||
|
} else {
|
||||||
|
nam, pkg := f.Type.Name();
|
||||||
|
f.Name = nam;
|
||||||
|
f.Anonymous = true;
|
||||||
|
}
|
||||||
|
if p.pkgPath != nil {
|
||||||
|
f.PkgPath = *p.pkgPath;
|
||||||
|
}
|
||||||
|
if p.tag != nil {
|
||||||
|
f.Tag = *p.tag;
|
||||||
|
}
|
||||||
|
f.Offset = p.offset;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NumField returns the number of struct fields.
|
// NumField returns the number of struct fields.
|
||||||
func (t *StructType) NumField() int {
|
func (t *StructType) NumField() int {
|
||||||
|
return len(t.fields);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert runtime type to reflect type.
|
||||||
|
// Same memory layouts, different method sets.
|
||||||
|
func toType(i interface{}) Type {
|
||||||
|
switch v := i.(type) {
|
||||||
|
case *runtime.BoolType:
|
||||||
|
return (*BoolType)(unsafe.Pointer(v));
|
||||||
|
case *runtime.DotDotDotType:
|
||||||
|
return (*DotDotDotType)(unsafe.Pointer(v));
|
||||||
|
case *runtime.FloatType:
|
||||||
|
return (*FloatType)(unsafe.Pointer(v));
|
||||||
|
case *runtime.Float32Type:
|
||||||
|
return (*Float32Type)(unsafe.Pointer(v));
|
||||||
|
case *runtime.Float64Type:
|
||||||
|
return (*Float64Type)(unsafe.Pointer(v));
|
||||||
|
case *runtime.IntType:
|
||||||
|
return (*IntType)(unsafe.Pointer(v));
|
||||||
|
case *runtime.Int8Type:
|
||||||
|
return (*Int8Type)(unsafe.Pointer(v));
|
||||||
|
case *runtime.Int16Type:
|
||||||
|
return (*Int16Type)(unsafe.Pointer(v));
|
||||||
|
case *runtime.Int32Type:
|
||||||
|
return (*Int32Type)(unsafe.Pointer(v));
|
||||||
|
case *runtime.Int64Type:
|
||||||
|
return (*Int64Type)(unsafe.Pointer(v));
|
||||||
|
case *runtime.StringType:
|
||||||
|
return (*StringType)(unsafe.Pointer(v));
|
||||||
|
case *runtime.UintType:
|
||||||
|
return (*UintType)(unsafe.Pointer(v));
|
||||||
|
case *runtime.Uint8Type:
|
||||||
|
return (*Uint8Type)(unsafe.Pointer(v));
|
||||||
|
case *runtime.Uint16Type:
|
||||||
|
return (*Uint16Type)(unsafe.Pointer(v));
|
||||||
|
case *runtime.Uint32Type:
|
||||||
|
return (*Uint32Type)(unsafe.Pointer(v));
|
||||||
|
case *runtime.Uint64Type:
|
||||||
|
return (*Uint64Type)(unsafe.Pointer(v));
|
||||||
|
case *runtime.UintptrType:
|
||||||
|
return (*UintptrType)(unsafe.Pointer(v));
|
||||||
|
case *runtime.UnsafePointerType:
|
||||||
|
return (*UnsafePointerType)(unsafe.Pointer(v));
|
||||||
|
case *runtime.ArrayType:
|
||||||
|
return (*ArrayType)(unsafe.Pointer(v));
|
||||||
|
case *runtime.ChanType:
|
||||||
|
return (*ChanType)(unsafe.Pointer(v));
|
||||||
|
case *runtime.FuncType:
|
||||||
|
return (*FuncType)(unsafe.Pointer(v));
|
||||||
|
case *runtime.InterfaceType:
|
||||||
|
return (*InterfaceType)(unsafe.Pointer(v));
|
||||||
|
case *runtime.MapType:
|
||||||
|
return (*MapType)(unsafe.Pointer(v));
|
||||||
|
case *runtime.PtrType:
|
||||||
|
return (*PtrType)(unsafe.Pointer(v));
|
||||||
|
case *runtime.SliceType:
|
||||||
|
return (*SliceType)(unsafe.Pointer(v));
|
||||||
|
case *runtime.StructType:
|
||||||
|
return (*StructType)(unsafe.Pointer(v));
|
||||||
|
}
|
||||||
|
panicln("toType", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ArrayOrSliceType is the common interface implemented
|
// ArrayOrSliceType is the common interface implemented
|
||||||
|
Loading…
Reference in New Issue
Block a user