x1 := T2{T2inner{2, 3}, 17};
check2ndField(x1, uintptr(unsafe.Pointer(&x1.f)) - uintptr(unsafe.Pointer(&x1)), t);
}
+
+type Nillable interface {
+ IsNil() bool
+}
+
+func Nil(a interface{}, t *testing.T) {
+ n := NewValue(a).(Nillable);
+ if !n.IsNil() {
+ t.Errorf("%v should be nil", a)
+ }
+}
+
+func NotNil(a interface{}, t *testing.T) {
+ n := NewValue(a).(Nillable);
+ if n.IsNil() {
+ t.Errorf("value of type %v should not be nil", NewValue(a).Type().String())
+ }
+}
+
+func TestIsNil(t *testing.T) {
+ // These do not implement IsNil
+ doNotNil := []string{"int", "float32", "struct { a int }"};
+ // These do implement IsNil
+ doNil := []string{"*int", "interface{}", "map[string]int", "func() bool", "chan int", "[]string"};
+ for i, ts := range doNotNil {
+ ty := reflect.ParseTypeString("", ts);
+ v := reflect.NewInitValue(ty);
+ if nilable, ok := v.(Nillable); ok {
+ t.Errorf("%s is nilable; should not be", ts)
+ }
+ }
+
+ for i, ts := range doNil {
+ ty := reflect.ParseTypeString("", ts);
+ v := reflect.NewInitValue(ty);
+ if nilable, ok := v.(Nillable); !ok {
+ t.Errorf("%s is not nilable; should be", ts)
+ }
+ }
+ // Check the implementations
+ var pi *int;
+ Nil(pi, t);
+ pi = new(int);
+ NotNil(pi, t);
+
+ var si []int;
+ Nil(si, t);
+ si = make([]int, 10);
+ NotNil(si, t);
+
+ // TODO: map and chan don't work yet
+
+ var ii interface {};
+ Nil(ii, t);
+ ii = pi;
+ NotNil(ii, t);
+
+ var fi func(t *testing.T);
+ Nil(fi, t);
+ fi = TestIsNil;
+ NotNil(fi, t);
+}
Sub() Value; // The Value pointed to.
Get() Addr; // Get the address stored in the pointer.
SetSub(Value); // Set the the pointed-to Value.
+ IsNil() bool;
}
type ptrValueStruct struct {
*(*Addr)(v.addr) = subv.Addr();
}
+func (v *ptrValueStruct) IsNil() bool {
+ return uintptr(*(*Addr)(v.addr)) == 0
+}
+
func ptrCreator(typ Type, addr Addr) Value {
return &ptrValueStruct{ commonValue{PtrKind, typ, addr} };
}
Elem(i int) Value; // The Value of the i'th element.
SetLen(len int); // Set the length; slice only.
Set(src ArrayValue); // Set the underlying Value; slice only for src and dest both.
- CopyFrom(src ArrayValue, n int) // Copy the elements from src; lengths must match.
+ CopyFrom(src ArrayValue, n int); // Copy the elements from src; lengths must match.
+ IsNil() bool;
}
func copyArray(dst ArrayValue, src ArrayValue, n int);
copyArray(v, src, n);
}
+func (v *sliceValueStruct) IsNil() bool {
+ return uintptr(v.slice.data) == 0
+}
+
type arrayValueStruct struct {
commonValue;
elemtype Type;
copyArray(v, src, n);
}
+func (v *arrayValueStruct) IsNil() bool {
+ return false
+}
+
func arrayCreator(typ Type, addr Addr) Value {
arraytype := typ.(ArrayType);
if arraytype.IsSlice() {
Value;
Len() int; // The number of elements; currently always returns 0.
Elem(key Value) Value; // The value indexed by key; unimplemented.
+ IsNil() bool;
}
type mapValueStruct struct {
return 0 // TODO: probably want this to be dynamic
}
+func (v *mapValueStruct) IsNil() bool {
+ return false // TODO: implement this properly
+}
+
func (v *mapValueStruct) Elem(key Value) Value {
panic("map value element");
return nil
// Its implementation is incomplete.
type ChanValue interface {
Value;
+ IsNil() bool;
}
type chanValueStruct struct {
commonValue
}
+func (v *chanValueStruct) IsNil() bool {
+ return false // TODO: implement this properly
+}
+
func chanCreator(typ Type, addr Addr) Value {
return &chanValueStruct{ commonValue{ChanKind, typ, addr} }
}
Value;
Get() interface {}; // Get the underlying interface{} value.
Value() Value;
+ IsNil() bool;
}
type interfaceValueStruct struct {
return NewValue(i);
}
+func (v *interfaceValueStruct) IsNil() bool {
+ return *(*interface{})(v.addr) == nil
+}
+
func interfaceCreator(typ Type, addr Addr) Value {
return &interfaceValueStruct{ commonValue{InterfaceKind, typ, addr} }
}
type FuncValue interface {
Value;
Get() Addr; // The address of the function.
+ IsNil() bool;
}
type funcValueStruct struct {
return *(*Addr)(v.addr)
}
+func (v *funcValueStruct) IsNil() bool {
+ return *(*Addr)(v.addr) == nil
+}
+
func funcCreator(typ Type, addr Addr) Value {
return &funcValueStruct{ commonValue{FuncKind, typ, addr} }
}