Commit 2e1bb4a4 authored by Russ Cox's avatar Russ Cox

add method test & fix method name bugs

R=ken,r
DELTA=86  (72 added, 9 deleted, 5 changed)
OCL=16488
CL=16488
parent 7766b12e
...@@ -176,22 +176,15 @@ methodname(Node *n, Type *t) ...@@ -176,22 +176,15 @@ methodname(Node *n, Type *t)
Sym *s; Sym *s;
char buf[NSYMB]; char buf[NSYMB];
// caller has already called ismethod to obtain t
if(t == T) if(t == T)
goto bad; goto bad;
s = t->sym;
// method receiver must be typename or *typename
s = S;
if(t->sym != S)
s = t->sym;
if(isptr[t->etype])
t = t->type;
if(t->sym != S)
s = t->sym;
if(s == S) if(s == S)
goto bad; goto bad;
snprint(buf, sizeof(buf), "%s_%s", s->name, n->sym->name); snprint(buf, sizeof(buf), "%s_%s", s->name, n->sym->name);
return newname(pkglookup(buf, t->sym->opackage)); return newname(pkglookup(buf, s->opackage));
bad: bad:
yyerror("illegal <this> type: %T", t); yyerror("illegal <this> type: %T", t);
......
...@@ -1113,9 +1113,15 @@ fndcl: ...@@ -1113,9 +1113,15 @@ fndcl:
} }
| '(' oarg_type_list ')' new_name '(' oarg_type_list ')' fnres | '(' oarg_type_list ')' new_name '(' oarg_type_list ')' fnres
{ {
Type *t;
b0stack = dclstack; // mark base for fn literals b0stack = dclstack; // mark base for fn literals
$$ = nod(ODCLFUNC, N, N); $$ = nod(ODCLFUNC, N, N);
$$->nname = methodname($4, $2->type); t = ismethod($2->type);
if(t != T)
$$->nname = methodname($4, t);
else
$$->nname = $4;
$$->type = functype($2, $6, $8); $$->type = functype($2, $6, $8);
funchdr($$); funchdr($$);
......
...@@ -1230,7 +1230,7 @@ recv: ...@@ -1230,7 +1230,7 @@ recv:
r = list(a, r); r = list(a, r);
goto out; goto out;
recv2: recv2:
walktype(c->right, Erv); // chan walktype(c->right, Erv); // chan
t = fixchan(c->right->type); t = fixchan(c->right->type);
...@@ -1399,6 +1399,7 @@ lookdot(Node *n, Type *f) ...@@ -1399,6 +1399,7 @@ lookdot(Node *n, Type *f)
for(; f!=T; f=f->down) { for(; f!=T; f=f->down) {
if(f->sym == S) if(f->sym == S)
continue; continue;
// if(strcmp(f->sym->name, s->name) != 0)
if(f->sym != s) if(f->sym != s)
continue; continue;
if(r != T) { if(r != T) {
...@@ -1430,6 +1431,7 @@ walkdot(Node *n) ...@@ -1430,6 +1431,7 @@ walkdot(Node *n)
if(t == T) if(t == T)
return; return;
// as a structure field or pointer to structure field
if(isptr[t->etype]) { if(isptr[t->etype]) {
t = t->type; t = t->type;
if(t == T) if(t == T)
...@@ -1437,7 +1439,6 @@ walkdot(Node *n) ...@@ -1437,7 +1439,6 @@ walkdot(Node *n)
n->op = ODOTPTR; n->op = ODOTPTR;
} }
// as a structure field
if(t->etype == TSTRUCT || t->etype == TINTER) { if(t->etype == TSTRUCT || t->etype == TINTER) {
f = lookdot(n->right, t->type); f = lookdot(n->right, t->type);
if(f != T) { if(f != T) {
...@@ -1450,9 +1451,13 @@ walkdot(Node *n) ...@@ -1450,9 +1451,13 @@ walkdot(Node *n)
} }
} }
f = lookdot(n->right, t->method); // as a method
f = T;
t = ismethod(n->left->type);
if(t != T)
f = lookdot(n->right, t->method);
if(f == T) { if(f == T) {
yyerror("undefined DOT %S", n->right->sym); yyerror("undefined DOT %S on %T", n->right->sym, n->left->type);
return; return;
} }
...@@ -1883,7 +1888,7 @@ fixchan(Type *tm) ...@@ -1883,7 +1888,7 @@ fixchan(Type *tm)
{ {
Type *t; Type *t;
if(tm == T) if(tm == T)
goto bad; goto bad;
t = tm->type; t = tm->type;
if(t == T) if(t == T)
...@@ -2298,7 +2303,7 @@ fixarray(Type *tm) ...@@ -2298,7 +2303,7 @@ fixarray(Type *tm)
bad: bad:
yyerror("not an array: %lT", tm); yyerror("not an array: %lT", tm);
return T; return T;
} }
Node* Node*
......
// $G $D/$F.go && $L $F.$A && ./$A.out
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
type S string
type S1 string
type I int
type I1 int
type P *int
type P1 *int
type T struct { x int }
type T1 T
func (s S) val() int { return 1 }
func (s *S1) val() int { return 2 }
func (i I) val() int { return 3 }
func (i *I1) val() int { return 4 }
func (p P) val() int { return 5 }
func (p *P1) val() int { return 6 }
//func (t T) val() int { return 7 }
func (t *T1) val() int { return 8 }
type Val interface {
val() int
}
func val(v Val) int {
return v.val()
}
func main() {
var s S;
var ps *S1;
var i I;
var pi *I1;
var p P;
var pp *P1;
var t T;
var pt *T1
if s.val() != 1 { panicln("s.val:", s.val()) }
if ps.val() != 2 { panicln("ps.val:", ps.val()) }
if i.val() != 3 { panicln("i.val:", i.val()) }
if pi.val() != 4 { panicln("pi.val:", pi.val()) }
if p.val() != 5 { panicln("p.val:", p.val()) }
if pp.val() != 6 { panicln("pp.val:", pp.val()) }
// if t.val() != 7 { panicln("t.val:", t.val()) }
if pt.val() != 8 { panicln("pt.val:", pt.val()) }
if val(s) != 1 { panicln("s.val:", val(s)) }
if val(ps) != 2 { panicln("ps.val:", val(ps)) }
if val(i) != 3 { panicln("i.val:", val(i)) }
if val(pi) != 4 { panicln("pi.val:", val(pi)) }
if val(p) != 5 { panicln("p.val:", val(p)) }
if val(pp) != 6 { panicln("pp.val:", val(pp)) }
// if val(t) != 7 { panicln("t.val:", val(t)) }
if val(pt) != 8 { panicln("pt.val:", val(pt)) }
}
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