Commit ac09eb4f authored by Rob Pike's avatar Rob Pike

handle the nil interface better in reflect and print

R=rsc
DELTA=25  (19 added, 0 deleted, 6 changed)
OCL=20985
CL=20985
parent 793a6eff
...@@ -307,10 +307,13 @@ func parsenum(s string, start, end int) (n int, got bool, newi int) { ...@@ -307,10 +307,13 @@ func parsenum(s string, start, end int) (n int, got bool, newi int) {
} }
func (p *P) printField(field reflect.Value) (was_string bool) { func (p *P) printField(field reflect.Value) (was_string bool) {
if stringer, ok := field.Interface().(String); ok { inter := field.Interface();
if inter != nil {
if stringer, ok := inter.(String); ok {
p.addstr(stringer.String()); p.addstr(stringer.String());
return false; // this value is not a string return false; // this value is not a string
} }
}
s := ""; s := "";
switch field.Kind() { switch field.Kind() {
case reflect.BoolKind: case reflect.BoolKind:
...@@ -363,6 +366,14 @@ func (p *P) printField(field reflect.Value) (was_string bool) { ...@@ -363,6 +366,14 @@ func (p *P) printField(field reflect.Value) (was_string bool) {
p.add('{'); p.add('{');
p.doprint(field, true, false); p.doprint(field, true, false);
p.add('}'); p.add('}');
case reflect.InterfaceKind:
inter := field.(reflect.InterfaceValue).Get();
if inter == nil {
s = "<nil>"
} else {
// should never happen since a non-nil interface always has a type
s = "<non-nil interface>";
}
default: default:
s = "?" + field.Type().String() + "?"; s = "?" + field.Type().String() + "?";
} }
...@@ -421,8 +432,9 @@ func (p *P) doprintf(format string, v reflect.StructValue) { ...@@ -421,8 +432,9 @@ func (p *P) doprintf(format string, v reflect.StructValue) {
} }
field := getField(v, fieldnum); field := getField(v, fieldnum);
fieldnum++; fieldnum++;
if c != 'T' { // don't want thing to describe itself if we're asking for its type inter := field.Interface();
if formatter, ok := field.Interface().(Format); ok { if inter != nil && c != 'T' { // don't want thing to describe itself if we're asking for its type
if formatter, ok := inter.(Format); ok {
formatter.Format(p, c); formatter.Format(p, c);
continue; continue;
} }
......
...@@ -340,6 +340,8 @@ func (t *InterfaceTypeStruct) Len() int { ...@@ -340,6 +340,8 @@ func (t *InterfaceTypeStruct) Len() int {
return len(t.field) return len(t.field)
} }
var NilInterface = NewInterfaceTypeStruct("nil", "", new([]Field, 0));
// -- Func // -- Func
export type FuncType interface { export type FuncType interface {
...@@ -834,6 +836,10 @@ func (p *Parser) Type(name string) *StubType { ...@@ -834,6 +836,10 @@ func (p *Parser) Type(name string) *StubType {
} }
export func ParseTypeString(name, typestring string) Type { export func ParseTypeString(name, typestring string) Type {
if typestring == "" {
// If the typestring is empty, it represents (the type of) a nil interface value
return NilInterface
}
p := new(Parser); p := new(Parser);
p.str = typestring; p.str = typestring;
p.Next(); p.Next();
......
...@@ -59,6 +59,7 @@ type Creator *(typ Type, addr Addr) Value ...@@ -59,6 +59,7 @@ type Creator *(typ Type, addr Addr) Value
export type MissingValue interface { export type MissingValue interface {
Kind() int; Kind() int;
Type() Type; Type() Type;
Addr() Addr;
} }
type MissingValueStruct struct { type MissingValueStruct struct {
...@@ -66,7 +67,7 @@ type MissingValueStruct struct { ...@@ -66,7 +67,7 @@ type MissingValueStruct struct {
} }
func MissingCreator(typ Type, addr Addr) Value { func MissingCreator(typ Type, addr Addr) Value {
return &MissingValueStruct{ Common{IntKind, typ, addr} } return &MissingValueStruct{ Common{MissingKind, typ, addr} }
} }
// -- Int // -- Int
......
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