]> Cypherpunks repositories - gostls13.git/commitdiff
embedded interface types in interfaces.
authorRuss Cox <rsc@golang.org>
Tue, 17 Feb 2009 00:36:18 +0000 (16:36 -0800)
committerRuss Cox <rsc@golang.org>
Tue, 17 Feb 2009 00:36:18 +0000 (16:36 -0800)
R=ken
OCL=25072
CL=25072

src/cmd/gc/dcl.c
src/cmd/gc/go.y

index 35d1a8e62b64e7c2e8c9a17486eca52fca921f40..1f053b6114e01880837374ef4dbbabc282e6688c 100644 (file)
@@ -643,7 +643,7 @@ funclit1(Type *type, Node *body)
 Type**
 stotype(Node *n, int et, Type **t)
 {
-       Type *f;
+       Type *f, *t1;
        Iter save;
        String *note;
        int lno;
@@ -666,20 +666,50 @@ loop:
                goto next;
        }
 
-       if(n->op != ODCLFIELD || n->type == T)
+       if(n->op != ODCLFIELD)
                fatal("stotype: oops %N\n", n);
 
+       if(n->type == T) {
+               // assume error already printed
+               goto next;
+       }
+
        switch(n->val.ctype) {
        case CTSTR:
+               if(et != TSTRUCT)
+                       yyerror("interface method cannot have annotation");
                note = n->val.u.sval;
                break;
        default:
-               yyerror("field annotation must be string");
+               if(et != TSTRUCT)
+                       yyerror("interface method cannot have annotation");
+               else
+                       yyerror("field annotation must be string");
        case CTxxx:
                note = nil;
                break;
        }
 
+       if(et == TINTER && n->left == N) {
+               // embedded interface - inline the methods
+               if(n->type->etype != TINTER) {
+                       yyerror("interface contains embedded non-interface %T", t);
+                       goto next;
+               }
+               for(t1=n->type->type; t1!=T; t1=t1->down) {
+                       if(strcmp(t1->sym->package, package) != 0)
+                               yyerror("embedded interface contains unexported method %S", t1->sym);
+                       f = typ(TFIELD);
+                       f->type = t1->type;
+                       f->width = BADWIDTH;
+                       f->nname = newname(t1->sym);
+                       f->sym = t1->sym;
+                       *t = f;
+                       t = &f->down;
+               }
+               goto next;
+       }
+
        f = typ(TFIELD);
        f->type = n->type;
        f->note = note;
index 072db35b682ec2b39265181bbc8dbdaf7fec7c2a..d68576428206041e126d5ba32152a3fe5e77761f 100644 (file)
@@ -57,7 +57,7 @@
 %type  <node>          exprsym3_list_r exprsym3
 %type  <node>          name onew_name new_name new_name_list_r new_field
 %type  <node>          vardcl_list_r vardcl Avardcl Bvardcl
-%type  <node>          interfacedcl_list_r interfacedcl
+%type  <node>          interfacedcl_list_r interfacedcl interfacedcl1
 %type  <node>          structdcl_list_r structdcl embed
 %type  <node>          fnres Afnres Bfnres fnliteral xfndcl fndcl fnbody
 %type  <node>          braced_keyexpr_list keyval_list_r keyval
@@ -1385,8 +1385,8 @@ embed:
                context = nil;
        }
 
-interfacedcl:
-       new_name ',' interfacedcl
+interfacedcl1:
+       new_name ',' interfacedcl1
        {
                $$ = nod(ODCLFIELD, $1, N);
                $$ = nod(OLIST, $$, $3);
@@ -1397,6 +1397,14 @@ interfacedcl:
                $$->type = $2;
        }
 
+interfacedcl:
+       interfacedcl1
+|      latype
+       {
+               $$ = nod(ODCLFIELD, N, N);
+               $$->type = oldtype($1);
+       }
+
 indcl:
        '(' oarg_type_list ')' fnres
        {