]> Cypherpunks repositories - gostls13.git/commitdiff
fix bugs parsing functions in reflect library.
authorRob Pike <r@golang.org>
Wed, 5 Nov 2008 16:17:01 +0000 (08:17 -0800)
committerRob Pike <r@golang.org>
Wed, 5 Nov 2008 16:17:01 +0000 (08:17 -0800)
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

src/lib/reflect/test.go
src/lib/reflect/type.go

index 54fd5ac4d68b5224a4dce5fa7d87fac2fa1d9ce6..13be64cc0835168e4bea0d219b838eff3183ece6 100644 (file)
@@ -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);
index 64405765b57fb8ffab4a53bf71eacbcd1c2125b3..09ecbc0675e4a8d677e7ed1edbf87a68c39d6e12 100644 (file)
@@ -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;
        }