Description
astextract converts a given go file to its ast representation.
This is useful for easliy writing typesafe go generate tools, which don't concatenate strings for generating code.
The output of astextract is 100% valid go, so it can be used in go code directly without any modifications.
All zero/null value struct fields are ommited for a more compact ast representation.
Absolute Position info is stripped, because positions change if you add any dynamic content to the ast.
I already wrote binclude a tool for resource embedding with the help of astextraxt, and added string obfuscation to garble.
astextract alternatives and similar packages
Based on the "Go Generate Tools" category.
Alternatively, view astextract alternatives based on common mentions on social networks and blogs.
-
re2dfa
Transform regular expressions into finite state machines and output Go source code. This repository has migrated to https://gitlab.com/opennota/re2dfa
WorkOS - The modern identity platform for B2B SaaS
Do you think we are missing an alternative of astextract or a related project?
Popular Comparisons
README
astextract
astextract converts a given go file to its ast representation.
This is useful for easliy writing typesafe go generate
tools, which don't concatenate strings for generating code.
The output of astextract is 100% valid go, so it can be used in go code directly without any modifications.
All zero/null value struct fields are ommited for a more compact ast representation.
Absolute Position info is stripped, because positions change if you add any dynamic content to the ast.
I already wrote binclude a tool for resource embedding with the help of astextraxt, and added string obfuscation to garble.
Web app
astextract be used as a Web app: https://lu4p.github.io/astextract/
The Web app was created using the amazing go-app package.
Install
GO111MODULE=on go get -u github.com/lu4p/astextract/cmd/astextract
Usage
astextract [flags] file
See astextract -h
for up to date usage information.
Example
main.go:
package main
func main() {
println("Hello, World!")
}
Command: astextract main.go
Output:
&ast.File {
Package: 1,
Name: &ast.Ident {
Name: "main",
},
Decls: []ast.Decl {
&ast.FuncDecl {
Name: &ast.Ident {
Name: "main",
},
Type: &ast.FuncType {
Params: &ast.FieldList {},
},
Body: &ast.BlockStmt {
List: []ast.Stmt {
&ast.ExprStmt {
X: &ast.CallExpr {
Fun: &ast.Ident {
Name: "println",
},
Args: []ast.Expr {
&ast.BasicLit {
Kind: token.STRING,
Value: "\"Hello, World!\"",
},
},
},
},
},
},
},
},
}
How to convert go/ast back to go
Example taken from binclude generateFile()
bincludeFile := &ast.File{
Doc: &ast.CommentGroup{
List: []*ast.Comment{
{
Slash: 1,
Text: "// Code generated by binclude; DO NOT EDIT.",
},
},
},
Package: 45,
Name: pkgName,
Decls: []ast.Decl{
&ast.GenDecl{
Tok: token.IMPORT,
Specs: imports,
},
&ast.GenDecl{
Tok: token.VAR,
Specs: astVars,
},
},
}
f, err := os.OpenFile("binclude.go", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
if err != nil {
return err
}
defer f.Close()
err = printer.Fprint(f, fset, bincludeFile)
if err != nil {
return err
}
astextract -out=filename main.go
generates a go file containing the ast of main.go
and an example on how to generate go code from the ast.
Alternatives
- go2ast: only converts a single line and doesn't support top level definitions.
- go/ast Print: prints a representation which is unsuitable for usage in code generation
From the go/ast documentation:
This example shows what an AST looks like when printed for debugging. Code:
// src is the input for which we want to print the AST.
src := `
package main
func main() {
println("Hello, World!")
}
`
// Create the AST by parsing src.
fset := token.NewFileSet() // positions are relative to fset
f, err := parser.ParseFile(fset, "", src, 0)
if err != nil {
panic(err)
}
// Print the AST.
ast.Print(fset, f)
Output:
0 *ast.File {
1 . Package: 2:1
2 . Name: *ast.Ident {
3 . . NamePos: 2:9
4 . . Name: "main"
5 . }
6 . Decls: []ast.Decl (len = 1) {
7 . . 0: *ast.FuncDecl {
8 . . . Name: *ast.Ident {
9 . . . . NamePos: 3:6
10 . . . . Name: "main"
11 . . . . Obj: *ast.Object {
12 . . . . . Kind: func
13 . . . . . Name: "main"
14 . . . . . Decl: *(obj @ 7)
15 . . . . }
16 . . . }
17 . . . Type: *ast.FuncType {
18 . . . . Func: 3:1
19 . . . . Params: *ast.FieldList {
20 . . . . . Opening: 3:10
21 . . . . . Closing: 3:11
22 . . . . }
23 . . . }
24 . . . Body: *ast.BlockStmt {
25 . . . . Lbrace: 3:13
26 . . . . List: []ast.Stmt (len = 1) {
27 . . . . . 0: *ast.ExprStmt {
28 . . . . . . X: *ast.CallExpr {
29 . . . . . . . Fun: *ast.Ident {
30 . . . . . . . . NamePos: 4:2
31 . . . . . . . . Name: "println"
32 . . . . . . . }
33 . . . . . . . Lparen: 4:9
34 . . . . . . . Args: []ast.Expr (len = 1) {
35 . . . . . . . . 0: *ast.BasicLit {
36 . . . . . . . . . ValuePos: 4:10
37 . . . . . . . . . Kind: STRING
38 . . . . . . . . . Value: "\"Hello, World!\""
39 . . . . . . . . }
40 . . . . . . . }
41 . . . . . . . Ellipsis: -
42 . . . . . . . Rparen: 4:25
43 . . . . . . }
44 . . . . . }
45 . . . . }
46 . . . . Rbrace: 5:1
47 . . . }
48 . . }
49 . }
50 . Scope: *ast.Scope {
51 . . Objects: map[string]*ast.Object (len = 1) {
52 . . . "main": *(obj @ 11)
53 . . }
54 . }
55 . Unresolved: []*ast.Ident (len = 1) {
56 . . 0: *(obj @ 29)
57 . }
58 }