diff options
author | Rob Pike <r@golang.org> | 2008-11-05 08:17:01 -0800 |
---|---|---|
committer | Rob Pike <r@golang.org> | 2008-11-05 08:17:01 -0800 |
commit | 945927fae51c931691be47a2415ddc0061e66463 (patch) | |
tree | f7b7935ba85ebd18722671cd221d1db2696ea910 | |
parent | ae7fb0d662b80be982de11939c8243313d63cd85 (diff) | |
download | golang-945927fae51c931691be47a2415ddc0061e66463.tar.gz |
fix bugs parsing functions in reflect library.
parsed interfaces wrong.
could not handle a function with a single type as a return value.
R=rsc
DELTA=34 (20 added, 2 deleted, 12 changed)
OCL=18511
CL=18520
-rw-r--r-- | src/lib/reflect/test.go | 12 | ||||
-rw-r--r-- | src/lib/reflect/type.go | 32 |
2 files changed, 31 insertions, 13 deletions
diff --git a/src/lib/reflect/test.go b/src/lib/reflect/test.go index 54fd5ac4d..13be64cc0 100644 --- a/src/lib/reflect/test.go +++ b/src/lib/reflect/test.go @@ -88,7 +88,6 @@ export type empty interface {} export type T struct { a int; b float64; c string; d *int } func main() { -//NOTE: INTERFACES PARSE INCORRECTLY: parser's Fields() stops at '(' var s string; var t reflect.Type; @@ -224,13 +223,18 @@ func main() { name, typ, tag, offset = st.Field(1); assert(typ.String(), "float32"); - //TODO! this is bad - can't put a method in an interface! - t = reflect.ParseTypeString("", "interface {a int}"); - assert(t.String(), "interface {a int}"); + t = reflect.ParseTypeString("", "interface {a() *int}"); + assert(t.String(), "interface {a() *int}"); t = reflect.ParseTypeString("", "*(a int8, b int32)"); assert(t.String(), "*(a int8, b int32)"); + t = reflect.ParseTypeString("", "*(a int8, b int32) float"); + assert(t.String(), "*(a int8, b int32) float"); + + t = reflect.ParseTypeString("", "*(a int8, b int32) (a float, b float)"); + assert(t.String(), "*(a int8, b int32) (a float, b float)"); + t = reflect.ParseTypeString("", "[32]int32"); assert(t.String(), "[32]int32"); at = t.(reflect.ArrayType); diff --git a/src/lib/reflect/type.go b/src/lib/reflect/type.go index 64405765b..09ecbc067 100644 --- a/src/lib/reflect/type.go +++ b/src/lib/reflect/type.go @@ -671,10 +671,10 @@ func (p *Parser) Chan(name string, tokstart, dir int) *StubType { } // Parse array of fields for struct, interface, and func arguments -func (p *Parser) Fields(sep string) *[]Field { +func (p *Parser) Fields(sep, term string) *[]Field { a := new([]Field, 10); nf := 0; - for p.token != "" && !special(p.token[0]) { + for p.token != "" && p.token != term { if nf == len(a) { a1 := new([]Field, 2*nf); for i := 0; i < nf; i++ { @@ -698,8 +698,16 @@ func (p *Parser) Fields(sep string) *[]Field { return a[0:nf]; } +// A single type packaged as a field for a function return +func (p *Parser) OneField() *[]Field { + a := new([]Field, 1); + a[0].name = ""; + a[0].typ = p.Type(""); + return a; +} + func (p *Parser) Struct(name string, tokstart int) *StubType { - f := p.Fields(";"); + f := p.Fields(";", "}"); if p.token != "}" { return MissingStub; } @@ -709,7 +717,7 @@ func (p *Parser) Struct(name string, tokstart int) *StubType { } func (p *Parser) Interface(name string, tokstart int) *StubType { - f := p.Fields(";"); + f := p.Fields(";", "}"); if p.token != "}" { return MissingStub; } @@ -720,18 +728,24 @@ func (p *Parser) Interface(name string, tokstart int) *StubType { func (p *Parser) Func(name string, tokstart int) *StubType { // may be 1 or 2 parenthesized lists - f1 := NewStructTypeStruct("", "", p.Fields(",")); + f1 := NewStructTypeStruct("", "", p.Fields(",", ")")); if p.token != ")" { return MissingStub; } end := p.index; p.Next(); if p.token != "(" { - // 1 list: the in parameters only - return NewStubType(name, NewFuncTypeStruct(name, p.str[tokstart:end], f1, nil)); + // 1 list: the in parameters are a list. Is there a single out parameter? + if p.token == "" || p.token == "}" || p.token == "," || p.token == ";" { + return NewStubType(name, NewFuncTypeStruct(name, p.str[tokstart:end], f1, nil)); + } + // A single out parameter. + f2 := NewStructTypeStruct("", "", p.OneField()); + return NewStubType(name, NewFuncTypeStruct(name, p.str[tokstart:end], f1, f2)); + } else { + p.Next(); } - p.Next(); - f2 := NewStructTypeStruct("", "", p.Fields(",")); + f2 := NewStructTypeStruct("", "", p.Fields(",", ")")); if p.token != ")" { return MissingStub; } |