fix: correct scoping of method declaration (#175)

This commit is contained in:
Marc Vertes
2019-05-01 16:40:21 +02:00
committed by Ludovic Fernandez
parent 16690838e3
commit 5cdcf61e0e
4 changed files with 36 additions and 21 deletions

View File

@@ -1,13 +1,17 @@
package main
type T int
const BlockSize = 8
func (t T) foo() { println("foo", t) }
type Cipher struct{}
func (c *Cipher) BlockSize() int { return BlockSize }
func main() {
var t T = 2
t.foo()
println(BlockSize)
s := Cipher{}
println(s.BlockSize())
}
// Output:
// foo 2
// 8
// 8

View File

@@ -1,15 +1,17 @@
package main
func BlockSize() string { return "func" }
type Cipher struct{}
func (c *Cipher) BlockSize() string { return "method" }
func main() {
o := &Coord{3, 4}
println(o.dist())
}
func (c *Coord) dist() int { return c.x*c.x + c.y*c.y }
type Coord struct {
x, y int
println(BlockSize())
s := Cipher{}
println(s.BlockSize())
}
// Output:
// 25
// func
// method

View File

@@ -776,14 +776,16 @@ func (interp *Interpreter) Cfg(root *Node) ([]*Node, error) {
scope = scope.pop()
case FuncDecl:
n.start = n.child[3].start
n.types = scope.types
scope = scope.pop()
funcName := n.child[1].ident
n.start = n.child[3].start
interp.scope[pkgName].sym[funcName].index = -1 // to force value to n.val
interp.scope[pkgName].sym[funcName].typ = n.typ
interp.scope[pkgName].sym[funcName].kind = Func
interp.scope[pkgName].sym[funcName].node = n
if !isMethod(n) {
funcName := n.child[1].ident
interp.scope[pkgName].sym[funcName].index = -1 // to force value to n.val
interp.scope[pkgName].sym[funcName].typ = n.typ
interp.scope[pkgName].sym[funcName].kind = Func
interp.scope[pkgName].sym[funcName].node = n
}
case FuncLit:
n.types = scope.types
@@ -1348,6 +1350,7 @@ func (n *Node) lastChild() *Node { return n.child[len(n.child)-1] }
func isKey(n *Node) bool {
return n.anc.kind == File ||
(n.anc.kind == SelectorExpr && n.anc.child[0] != n) ||
(n.anc.kind == FuncDecl && isMethod(n.anc)) ||
(n.anc.kind == KeyValueExpr && n.anc.child[0] == n)
}
@@ -1371,6 +1374,10 @@ func isNewDefine(n *Node, scope *Scope) bool {
return false
}
func isMethod(n *Node) bool {
return len(n.child[0].child) > 0 // receiver defined
}
func isMapEntry(n *Node) bool {
return n.action == GetIndex && n.child[0].typ.cat == MapT
}

View File

@@ -68,7 +68,9 @@ func (interp *Interpreter) Gta(root *Node, rpath string) error {
if n.typ, err = nodeType(interp, scope, n.child[2]); err != nil {
return false
}
scope.sym[n.child[1].ident] = &Symbol{kind: Func, typ: n.typ, node: n, index: -1}
if !isMethod(n) {
scope.sym[n.child[1].ident] = &Symbol{kind: Func, typ: n.typ, node: n, index: -1}
}
if len(n.child[0].child) > 0 {
// function is a method, add it to the related type
var receiverType *Type