...

Source file src/go/ast/example_test.go

Documentation: go/ast

		 1  // Copyright 2012 The Go Authors. All rights reserved.
		 2  // Use of this source code is governed by a BSD-style
		 3  // license that can be found in the LICENSE file.
		 4  
		 5  package ast_test
		 6  
		 7  import (
		 8  	"bytes"
		 9  	"fmt"
		10  	"go/ast"
		11  	"go/format"
		12  	"go/parser"
		13  	"go/token"
		14  )
		15  
		16  // This example demonstrates how to inspect the AST of a Go program.
		17  func ExampleInspect() {
		18  	// src is the input for which we want to inspect the AST.
		19  	src := `
		20  package p
		21  const c = 1.0
		22  var X = f(3.14)*2 + c
		23  `
		24  
		25  	// Create the AST by parsing src.
		26  	fset := token.NewFileSet() // positions are relative to fset
		27  	f, err := parser.ParseFile(fset, "src.go", src, 0)
		28  	if err != nil {
		29  		panic(err)
		30  	}
		31  
		32  	// Inspect the AST and print all identifiers and literals.
		33  	ast.Inspect(f, func(n ast.Node) bool {
		34  		var s string
		35  		switch x := n.(type) {
		36  		case *ast.BasicLit:
		37  			s = x.Value
		38  		case *ast.Ident:
		39  			s = x.Name
		40  		}
		41  		if s != "" {
		42  			fmt.Printf("%s:\t%s\n", fset.Position(n.Pos()), s)
		43  		}
		44  		return true
		45  	})
		46  
		47  	// Output:
		48  	// src.go:2:9:	p
		49  	// src.go:3:7:	c
		50  	// src.go:3:11:	1.0
		51  	// src.go:4:5:	X
		52  	// src.go:4:9:	f
		53  	// src.go:4:11:	3.14
		54  	// src.go:4:17:	2
		55  	// src.go:4:21:	c
		56  }
		57  
		58  // This example shows what an AST looks like when printed for debugging.
		59  func ExamplePrint() {
		60  	// src is the input for which we want to print the AST.
		61  	src := `
		62  package main
		63  func main() {
		64  	println("Hello, World!")
		65  }
		66  `
		67  
		68  	// Create the AST by parsing src.
		69  	fset := token.NewFileSet() // positions are relative to fset
		70  	f, err := parser.ParseFile(fset, "", src, 0)
		71  	if err != nil {
		72  		panic(err)
		73  	}
		74  
		75  	// Print the AST.
		76  	ast.Print(fset, f)
		77  
		78  	// Output:
		79  	//			0	*ast.File {
		80  	//			1	.	Package: 2:1
		81  	//			2	.	Name: *ast.Ident {
		82  	//			3	.	.	NamePos: 2:9
		83  	//			4	.	.	Name: "main"
		84  	//			5	.	}
		85  	//			6	.	Decls: []ast.Decl (len = 1) {
		86  	//			7	.	.	0: *ast.FuncDecl {
		87  	//			8	.	.	.	Name: *ast.Ident {
		88  	//			9	.	.	.	.	NamePos: 3:6
		89  	//		 10	.	.	.	.	Name: "main"
		90  	//		 11	.	.	.	.	Obj: *ast.Object {
		91  	//		 12	.	.	.	.	.	Kind: func
		92  	//		 13	.	.	.	.	.	Name: "main"
		93  	//		 14	.	.	.	.	.	Decl: *(obj @ 7)
		94  	//		 15	.	.	.	.	}
		95  	//		 16	.	.	.	}
		96  	//		 17	.	.	.	Type: *ast.FuncType {
		97  	//		 18	.	.	.	.	Func: 3:1
		98  	//		 19	.	.	.	.	Params: *ast.FieldList {
		99  	//		 20	.	.	.	.	.	Opening: 3:10
	 100  	//		 21	.	.	.	.	.	Closing: 3:11
	 101  	//		 22	.	.	.	.	}
	 102  	//		 23	.	.	.	}
	 103  	//		 24	.	.	.	Body: *ast.BlockStmt {
	 104  	//		 25	.	.	.	.	Lbrace: 3:13
	 105  	//		 26	.	.	.	.	List: []ast.Stmt (len = 1) {
	 106  	//		 27	.	.	.	.	.	0: *ast.ExprStmt {
	 107  	//		 28	.	.	.	.	.	.	X: *ast.CallExpr {
	 108  	//		 29	.	.	.	.	.	.	.	Fun: *ast.Ident {
	 109  	//		 30	.	.	.	.	.	.	.	.	NamePos: 4:2
	 110  	//		 31	.	.	.	.	.	.	.	.	Name: "println"
	 111  	//		 32	.	.	.	.	.	.	.	}
	 112  	//		 33	.	.	.	.	.	.	.	Lparen: 4:9
	 113  	//		 34	.	.	.	.	.	.	.	Args: []ast.Expr (len = 1) {
	 114  	//		 35	.	.	.	.	.	.	.	.	0: *ast.BasicLit {
	 115  	//		 36	.	.	.	.	.	.	.	.	.	ValuePos: 4:10
	 116  	//		 37	.	.	.	.	.	.	.	.	.	Kind: STRING
	 117  	//		 38	.	.	.	.	.	.	.	.	.	Value: "\"Hello, World!\""
	 118  	//		 39	.	.	.	.	.	.	.	.	}
	 119  	//		 40	.	.	.	.	.	.	.	}
	 120  	//		 41	.	.	.	.	.	.	.	Ellipsis: -
	 121  	//		 42	.	.	.	.	.	.	.	Rparen: 4:25
	 122  	//		 43	.	.	.	.	.	.	}
	 123  	//		 44	.	.	.	.	.	}
	 124  	//		 45	.	.	.	.	}
	 125  	//		 46	.	.	.	.	Rbrace: 5:1
	 126  	//		 47	.	.	.	}
	 127  	//		 48	.	.	}
	 128  	//		 49	.	}
	 129  	//		 50	.	Scope: *ast.Scope {
	 130  	//		 51	.	.	Objects: map[string]*ast.Object (len = 1) {
	 131  	//		 52	.	.	.	"main": *(obj @ 11)
	 132  	//		 53	.	.	}
	 133  	//		 54	.	}
	 134  	//		 55	.	Unresolved: []*ast.Ident (len = 1) {
	 135  	//		 56	.	.	0: *(obj @ 29)
	 136  	//		 57	.	}
	 137  	//		 58	}
	 138  }
	 139  
	 140  // This example illustrates how to remove a variable declaration
	 141  // in a Go program while maintaining correct comment association
	 142  // using an ast.CommentMap.
	 143  func ExampleCommentMap() {
	 144  	// src is the input for which we create the AST that we
	 145  	// are going to manipulate.
	 146  	src := `
	 147  // This is the package comment.
	 148  package main
	 149  
	 150  // This comment is associated with the hello constant.
	 151  const hello = "Hello, World!" // line comment 1
	 152  
	 153  // This comment is associated with the foo variable.
	 154  var foo = hello // line comment 2
	 155  
	 156  // This comment is associated with the main function.
	 157  func main() {
	 158  	fmt.Println(hello) // line comment 3
	 159  }
	 160  `
	 161  
	 162  	// Create the AST by parsing src.
	 163  	fset := token.NewFileSet() // positions are relative to fset
	 164  	f, err := parser.ParseFile(fset, "src.go", src, parser.ParseComments)
	 165  	if err != nil {
	 166  		panic(err)
	 167  	}
	 168  
	 169  	// Create an ast.CommentMap from the ast.File's comments.
	 170  	// This helps keeping the association between comments
	 171  	// and AST nodes.
	 172  	cmap := ast.NewCommentMap(fset, f, f.Comments)
	 173  
	 174  	// Remove the first variable declaration from the list of declarations.
	 175  	for i, decl := range f.Decls {
	 176  		if gen, ok := decl.(*ast.GenDecl); ok && gen.Tok == token.VAR {
	 177  			copy(f.Decls[i:], f.Decls[i+1:])
	 178  			f.Decls = f.Decls[:len(f.Decls)-1]
	 179  			break
	 180  		}
	 181  	}
	 182  
	 183  	// Use the comment map to filter comments that don't belong anymore
	 184  	// (the comments associated with the variable declaration), and create
	 185  	// the new comments list.
	 186  	f.Comments = cmap.Filter(f).Comments()
	 187  
	 188  	// Print the modified AST.
	 189  	var buf bytes.Buffer
	 190  	if err := format.Node(&buf, fset, f); err != nil {
	 191  		panic(err)
	 192  	}
	 193  	fmt.Printf("%s", buf.Bytes())
	 194  
	 195  	// Output:
	 196  	// // This is the package comment.
	 197  	// package main
	 198  	//
	 199  	// // This comment is associated with the hello constant.
	 200  	// const hello = "Hello, World!" // line comment 1
	 201  	//
	 202  	// // This comment is associated with the main function.
	 203  	// func main() {
	 204  	// 	fmt.Println(hello) // line comment 3
	 205  	// }
	 206  }
	 207  

View as plain text