使用go/ast包

huangapple go评论82阅读模式
英文:

Using the go/ast package

问题

我正在尝试在Go中进行一些元编程,并且我正在尝试使用go/ast包。

以下是创建AST的代码片段:

// 创建AST
fooFn := &ast.FuncDecl{
    Name: &ast.Ident{Name: "foofn"},
    Body: &ast.BlockStmt{
        List: []ast.Stmt{&ast.ExprStmt{
            X: &ast.CallExpr{
                Fun: &ast.Ident{Name: "println"},
                Args: []ast.Expr{
                    &ast.BasicLit{Kind: token.INT, Value: "42"},
                },
            },
        }},
    },
}

f := &ast.File{
    Name:  &ast.Ident{Name: "foopackage"},
    Decls: []ast.Decl{fooFn},
    Scope: &ast.Scope{
        Objects: map[string]*ast.Object{
            "Foo": &ast.Object{
                Kind: ast.Fun,
                Name: "Foo",
                Decl: fooFn,
            },
        },
    },
}

完整代码请参见此处:http://play.golang.org/p/zTJdnqVx__,它应该输出以下内容:

panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0xffffffff addr=0x0 pc=0x773ae]

goroutine 16 [running]:
runtime.panic(0x18b5a0, 0x24c8af)
    /tmp/sandbox/go/src/pkg/runtime/panic.c:279 +0x120
go/ast.(*FuncType).Pos(0x0, 0x1c827eb4, 0xfefd02b8, 0x10422360)
    /tmp/sandbox/go/src/pkg/go/ast/ast.go:446 +0x2e
go/ast.(*FuncDecl).Pos(0x10422360, 0x10422360, 0x47, 0xfeee1cb0)
    /tmp/sandbox/go/src/pkg/go/ast/ast.go:933 +0x40
go/printer.(*printer).declList(0x10402840, 0x1040e108, 0x1, 0x1)
    /tmp/sandbox/go/src/pkg/go/printer/nodes.go:1587 +0x180
go/printer.(*printer).file(0x10402840, 0x10442080)
    /tmp/sandbox/go/src/pkg/go/printer/nodes.go:1597 +0x1e0
go/printer.(*printer).printNode(0x10402840, 0x184ba0, 0x10442080, 0x104223c0, 0x0, 0x0)
    /tmp/sandbox/go/src/pkg/go/printer/printer.go:1087 +0xa40
go/printer.(*Config).fprint(0xfeee1e90, 0xfefd02d8, 0x10426180, 0x104181b0, 0x184ba0, 0x10442080, 0x104223c0, 0xfefd02d8, 0x0, 0x0)
    /tmp/sandbox/go/src/pkg/go/printer/printer.go:1226 +0xc0
go/printer.(*Config).Fprint(0xfeee1e90, 0xfefd02d8, 0x10426180, 0x104181b0, 0x184ba0, 0x10442080, 0x0, 0x0)
    /tmp/sandbox/go/src/pkg/go/printer/printer.go:1284 +0xa0
main.main()
    /tmpfs/gosandbox-eb231fa6_4e4e43ec_79a6f993_ce4170ce_07ee185b/prog.go:46 +0x8c0

编辑:这是一个工作版本,其中设置了FuncDelc.Type并删除了Scope(因为我只需要源代码缓冲区):http://play.golang.org/p/B0Xp61rSce

英文:

I'm attempting to do some metaprogramming in Go and I'm trying to use the go/ast package.

Here's the snippet which is creating the AST:

// Create an AST
fooFn := &ast.FuncDecl{
	Name: &ast.Ident{Name: "foofn"},
	Body: &ast.BlockStmt{
		List: []ast.Stmt{&ast.ExprStmt{
			X: &ast.CallExpr{
				Fun: &ast.Ident{Name: "println"},
				Args: []ast.Expr{
					&ast.BasicLit{Kind: token.INT, Value: "42"},
				},
			},
		}},
	},
}

f := &ast.File{
	Name:  &ast.Ident{Name: "foopackage"},
	Decls: []ast.Decl{fooFn},
	Scope: &ast.Scope{
		Objects: map[string]*ast.Object{
			"Foo": &ast.Object{
				Kind: ast.Fun,
				Name: "Foo",
				Decl: fooFn,
			},
		},
	},
}

See the full code here http://play.golang.org/p/zTJdnqVx__ which should produce this output:

panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0xffffffff addr=0x0 pc=0x773ae]

goroutine 16 [running]:
runtime.panic(0x18b5a0, 0x24c8af)
    /tmp/sandbox/go/src/pkg/runtime/panic.c:279 +0x120
go/ast.(*FuncType).Pos(0x0, 0x1c827eb4, 0xfefd02b8, 0x10422360)
    /tmp/sandbox/go/src/pkg/go/ast/ast.go:446 +0x2e
go/ast.(*FuncDecl).Pos(0x10422360, 0x10422360, 0x47, 0xfeee1cb0)
    /tmp/sandbox/go/src/pkg/go/ast/ast.go:933 +0x40
go/printer.(*printer).declList(0x10402840, 0x1040e108, 0x1, 0x1)
    /tmp/sandbox/go/src/pkg/go/printer/nodes.go:1587 +0x180
go/printer.(*printer).file(0x10402840, 0x10442080)
    /tmp/sandbox/go/src/pkg/go/printer/nodes.go:1597 +0x1e0
go/printer.(*printer).printNode(0x10402840, 0x184ba0, 0x10442080, 0x104223c0, 0x0, 0x0)
    /tmp/sandbox/go/src/pkg/go/printer/printer.go:1087 +0xa40
go/printer.(*Config).fprint(0xfeee1e90, 0xfefd02d8, 0x10426180, 0x104181b0, 0x184ba0, 0x10442080, 0x104223c0, 0xfefd02d8, 0x0, 0x0)
    /tmp/sandbox/go/src/pkg/go/printer/printer.go:1226 +0xc0
go/printer.(*Config).Fprint(0xfeee1e90, 0xfefd02d8, 0x10426180, 0x104181b0, 0x184ba0, 0x10442080, 0x0, 0x0)
    /tmp/sandbox/go/src/pkg/go/printer/printer.go:1284 +0xa0
main.main()
    /tmpfs/gosandbox-eb231fa6_4e4e43ec_79a6f993_ce4170ce_07ee185b/prog.go:46 +0x8c0

Edit: here is the working version with FuncDelc.Type set and Scope removed (since I'm only after the source code buffer):

http://play.golang.org/p/B0Xp61rSce

答案1

得分: 4

看起来你可能需要将 ast.FuncType 提供给你的 ast.FuncDecl。错误似乎是由于在 (nil) FuncTypeFunc 属性上调用了 IsValid() 导致的。

英文:

It looks like you may need to provide an ast.FuncType to your ast.FuncDecl. The error appears to be a result of calling IsValid() on the Func property of your (nil) FuncType.

huangapple
  • 本文由 发表于 2014年8月12日 19:27:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/25263094.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定