mirror of
https://github.com/golang/go
synced 2024-11-20 04:54:44 -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 {
|
||||
hash uint32;
|
||||
name *string;
|
||||
PkgPath *string;
|
||||
pkgPath *string;
|
||||
typ *runtime.Type;
|
||||
ifn unsafe.Pointer;
|
||||
tfn unsafe.Pointer;
|
||||
@ -149,12 +149,6 @@ type ArrayType struct {
|
||||
len uintptr;
|
||||
}
|
||||
|
||||
// SliceType represents a slice type.
|
||||
type SliceType struct {
|
||||
commonType;
|
||||
elem *runtime.Type;
|
||||
}
|
||||
|
||||
// ChanDir represents a channel type's direction.
|
||||
type ChanDir int
|
||||
const (
|
||||
@ -205,6 +199,12 @@ type PtrType struct {
|
||||
elem *runtime.Type;
|
||||
}
|
||||
|
||||
// SliceType represents a slice type.
|
||||
type SliceType struct {
|
||||
commonType;
|
||||
elem *runtime.Type;
|
||||
}
|
||||
|
||||
// Struct field
|
||||
type structField struct {
|
||||
name *string;
|
||||
@ -279,83 +279,168 @@ type Type interface {
|
||||
func toType(i interface{}) Type
|
||||
|
||||
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 {
|
||||
return *t.string;
|
||||
}
|
||||
|
||||
func (t *commonType) Size() uintptr {
|
||||
return t.size;
|
||||
}
|
||||
|
||||
func (t *commonType) Align() int {
|
||||
return int(t.align);
|
||||
}
|
||||
|
||||
func (t *commonType) FieldAlign() int {
|
||||
return int(t.fieldAlign);
|
||||
}
|
||||
|
||||
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 {
|
||||
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.
|
||||
func (t *ArrayType) Len() int {
|
||||
return int(t.len);
|
||||
}
|
||||
|
||||
// Elem returns the type of the array's elements.
|
||||
func (t *ArrayType) Elem() Type {
|
||||
return toType(*t.elem);
|
||||
}
|
||||
|
||||
// Dir returns the channel direction.
|
||||
func (t *ChanType) Dir() ChanDir {
|
||||
return ChanDir(t.dir);
|
||||
}
|
||||
|
||||
// Elem returns the channel's element type.
|
||||
func (t *ChanType) Elem() Type {
|
||||
return toType(*t.elem);
|
||||
}
|
||||
|
||||
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.
|
||||
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.
|
||||
func (t *FuncType) NumIn() int {
|
||||
return len(t.in);
|
||||
}
|
||||
|
||||
// Out returns the type of the i'th function output parameter.
|
||||
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.
|
||||
func (t *FuncType) NumOut() int {
|
||||
return len(t.out);
|
||||
}
|
||||
|
||||
// Method returns the i'th interface 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.
|
||||
func (t *InterfaceType) NumMethod() int {
|
||||
return len(t.methods);
|
||||
}
|
||||
|
||||
// Key returns the map key type.
|
||||
func (t *MapType) Key() Type {
|
||||
return toType(*t.key);
|
||||
}
|
||||
|
||||
// Elem returns the map element type.
|
||||
func (t *MapType) Elem() Type {
|
||||
return toType(*t.elem);
|
||||
}
|
||||
|
||||
// Elem returns the pointer element type.
|
||||
func (t *PtrType) Elem() Type {
|
||||
return toType(*t.elem);
|
||||
}
|
||||
|
||||
// Elem returns the type of the slice's elements.
|
||||
func (t *SliceType) Elem() Type {
|
||||
return toType(*t.elem);
|
||||
}
|
||||
|
||||
type StructField struct {
|
||||
@ -369,10 +454,91 @@ type StructField struct {
|
||||
|
||||
// Field returns the i'th struct field.
|
||||
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.
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user