fix: correct scoping of method declaration (#175)
This commit is contained in:
committed by
Ludovic Fernandez
parent
16690838e3
commit
5cdcf61e0e
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user