Commit a8f6e38b authored by Rob Pike's avatar Rob Pike

implement IsNil() bool for those types that can be nil. most of them, anyway.

R=rsc
DELTA=97  (96 added, 0 deleted, 1 changed)
OCL=28596
CL=28702
parent c6da3e5a
......@@ -507,3 +507,65 @@ func TestAlignment(t *testing.T) {
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);
}
......@@ -501,6 +501,7 @@ type PtrValue interface {
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 {
......@@ -525,6 +526,10 @@ func (v *ptrValueStruct) SetSub(subv Value) {
*(*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} };
}
......@@ -541,7 +546,8 @@ type ArrayValue interface {
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);
......@@ -606,6 +612,10 @@ func (v *sliceValueStruct) CopyFrom(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;
......@@ -643,6 +653,10 @@ func (v *arrayValueStruct) CopyFrom(src ArrayValue, n int) {
copyArray(v, src, n);
}
func (v *arrayValueStruct) IsNil() bool {
return false
}
func arrayCreator(typ Type, addr Addr) Value {
arraytype := typ.(ArrayType);
if arraytype.IsSlice() {
......@@ -673,6 +687,7 @@ type MapValue interface {
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 {
......@@ -687,6 +702,10 @@ func (v *mapValueStruct) Len() int {
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
......@@ -698,12 +717,17 @@ func (v *mapValueStruct) Elem(key Value) Value {
// 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} }
}
......@@ -750,6 +774,7 @@ type InterfaceValue interface {
Value;
Get() interface {}; // Get the underlying interface{} value.
Value() Value;
IsNil() bool;
}
type interfaceValueStruct struct {
......@@ -768,6 +793,10 @@ func (v *interfaceValueStruct) Value() Value {
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} }
}
......@@ -780,6 +809,7 @@ func interfaceCreator(typ Type, addr Addr) Value {
type FuncValue interface {
Value;
Get() Addr; // The address of the function.
IsNil() bool;
}
type funcValueStruct struct {
......@@ -790,6 +820,10 @@ func (v *funcValueStruct) Get() Addr {
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} }
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment