dst

package module
v0.27.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 9, 2022 License: BSD-3-Clause, MIT Imports: 8 Imported by: 204

README

Build Status Documentation codecov stability-stable Sourcegraph

Decorated Syntax Tree

The dst package enables manipulation of a Go syntax tree with high fidelity. Decorations (e.g. comments and line spacing) remain attached to the correct nodes as the tree is modified.

Where does go/ast break?

The go/ast package wasn't created with source manipulation as an intended use-case. Comments are stored by their byte offset instead of attached to nodes, so re-arranging nodes breaks the output. See this Go issue for more information.

Consider this example where we want to reverse the order of the two statements. As you can see the comments don't remain attached to the correct nodes:

code := `package a

func main(){
	var a int    // foo
	var b string // bar
}
`
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, "", code, parser.ParseComments)
if err != nil {
	panic(err)
}

list := f.Decls[0].(*ast.FuncDecl).Body.List
list[0], list[1] = list[1], list[0]

if err := format.Node(os.Stdout, fset, f); err != nil {
	panic(err)
}

//Output:
//package a
//
//func main() {
//	// foo
//	var b string
//	var a int
//	// bar
//}

Here's the same example using dst:

code := `package a

func main(){
	var a int    // foo
	var b string // bar
}
`
f, err := decorator.Parse(code)
if err != nil {
	panic(err)
}

list := f.Decls[0].(*dst.FuncDecl).Body.List
list[0], list[1] = list[1], list[0]

if err := decorator.Print(f); err != nil {
	panic(err)
}

//Output:
//package a
//
//func main() {
//	var b string // bar
//	var a int    // foo
//}

Usage

Parsing a source file to dst and printing the results after modification can be accomplished with several Parse and Print convenience functions in the decorator package.

For more fine-grained control you can use Decorator to convert from ast to dst, and Restorer to convert back again.

Comments

Comments are added at decoration attachment points. See here for a full list of these points, along with demonstration code of where they are rendered in the output.

The decoration attachment points have convenience functions Append, Prepend, Replace, Clear and All to accomplish common tasks. Use the full text of your comment including the // or /**/ markers. When adding a line comment, a newline is automatically rendered.

code := `package main

func main() {
	println("Hello World!")
}`
f, err := decorator.Parse(code)
if err != nil {
	panic(err)
}

call := f.Decls[0].(*dst.FuncDecl).Body.List[0].(*dst.ExprStmt).X.(*dst.CallExpr)

call.Decs.Start.Append("// you can add comments at the start...")
call.Decs.Fun.Append("/* ...in the middle... */")
call.Decs.End.Append("// or at the end.")

if err := decorator.Print(f); err != nil {
	panic(err)
}

//Output:
//package main
//
//func main() {
//	// you can add comments at the start...
//	println /* ...in the middle... */ ("Hello World!") // or at the end.
//}
Spacing

The Before property marks the node as having a line space (new line or empty line) before the node. These spaces are rendered before any decorations attached to the Start decoration point. The After property is similar but rendered after the node (and after any End decorations).

code := `package main

func main() {
	println(a, b, c)
}`
f, err := decorator.Parse(code)
if err != nil {
	panic(err)
}

call := f.Decls[0].(*dst.FuncDecl).Body.List[0].(*dst.ExprStmt).X.(*dst.CallExpr)

call.Decs.Before = dst.EmptyLine
call.Decs.After = dst.EmptyLine

for _, v := range call.Args {
	v := v.(*dst.Ident)
	v.Decs.Before = dst.NewLine
	v.Decs.After = dst.NewLine
}

if err := decorator.Print(f); err != nil {
	panic(err)
}

//Output:
//package main
//
//func main() {
//
//	println(
//		a,
//		b,
//		c,
//	)
//
//}
Decorations

The common decoration properties (Start, End, Before and After) occur on all nodes, and can be accessed with the Decorations() method on the Node interface:

code := `package main

func main() {
	var i int
	i++
	println(i)
}`
f, err := decorator.Parse(code)
if err != nil {
	panic(err)
}

list := f.Decls[0].(*dst.FuncDecl).Body.List

list[0].Decorations().Before = dst.EmptyLine
list[0].Decorations().End.Append("// the Decorations method allows access to the common")
list[1].Decorations().End.Append("// decoration properties (Before, Start, End and After)")
list[2].Decorations().End.Append("// for all nodes.")
list[2].Decorations().After = dst.EmptyLine

if err := decorator.Print(f); err != nil {
	panic(err)
}

//Output:
//package main
//
//func main() {
//
//	var i int  // the Decorations method allows access to the common
//	i++        // decoration properties (Before, Start, End and After)
//	println(i) // for all nodes.
//
//}
dstutil.Decorations

While debugging, it is often useful to have a list of all decorations attached to a node. The dstutil package provides a helper function Decorations which returns a list of the attachment points and all decorations for any node:

code := `package main

// main comment
// is multi line
func main() {

	if true {

		// foo
		println( /* foo inline */ "foo")
	} else if false {
		println /* bar inline */ ("bar")

		// bar after

	} else {
		// empty block
	}
}`

f, err := decorator.Parse(code)
if err != nil {
	panic(err)
}

dst.Inspect(f, func(node dst.Node) bool {
	if node == nil {
		return false
	}
	before, after, points := dstutil.Decorations(node)
	var info string
	if before != dst.None {
		info += fmt.Sprintf("- Before: %s\n", before)
	}
	for _, point := range points {
		if len(point.Decs) == 0 {
			continue
		}
		info += fmt.Sprintf("- %s: [", point.Name)
		for i, dec := range point.Decs {
			if i > 0 {
				info += ", "
			}
			info += fmt.Sprintf("%q", dec)
		}
		info += "]\n"
	}
	if after != dst.None {
		info += fmt.Sprintf("- After: %s\n", after)
	}
	if info != "" {
		fmt.Printf("%T\n%s\n", node, info)
	}
	return true
})

//Output:
//*dst.FuncDecl
//- Before: NewLine
//- Start: ["// main comment", "// is multi line"]
//
//*dst.IfStmt
//- Before: NewLine
//- After: NewLine
//
//*dst.ExprStmt
//- Before: NewLine
//- Start: ["// foo"]
//- After: NewLine
//
//*dst.CallExpr
//- Lparen: ["/* foo inline */"]
//
//*dst.ExprStmt
//- Before: NewLine
//- End: ["\n", "\n", "// bar after"]
//- After: NewLine
//
//*dst.CallExpr
//- Fun: ["/* bar inline */"]
//
//*dst.BlockStmt
//- Lbrace: ["\n", "// empty block"]
Newlines

The Before and After properties cover the majority of cases, but occasionally a newline needs to be rendered inside a node. Simply add a \n decoration to accomplish this.

Clone

Re-using an existing node elsewhere in the tree will panic when the tree is restored to ast. Instead, use the Clone function to make a deep copy of the node before re-use:

code := `package main

var i /* a */ int`

f, err := decorator.Parse(code)
if err != nil {
	panic(err)
}

cloned := dst.Clone(f.Decls[0]).(*dst.GenDecl)

cloned.Decs.Before = dst.NewLine
cloned.Specs[0].(*dst.ValueSpec).Names[0].Name = "j"
cloned.Specs[0].(*dst.ValueSpec).Names[0].Decs.End.Replace("/* b */")

f.Decls = append(f.Decls, cloned)

if err := decorator.Print(f); err != nil {
	panic(err)
}

//Output:
//package main
//
//var i /* a */ int
//var j /* b */ int
Apply

The dstutil package is a fork of golang.org/x/tools/go/ast/astutil, and provides the Apply function with similar semantics.

Imports

The decorator can automatically manage the import block, which is a non-trivial task.

Use NewDecoratorWithImports and NewRestorerWithImports to create an import aware decorator / restorer.

During decoration, remote identifiers are normalised - *ast.SelectorExpr nodes that represent qualified identifiers are replaced with *dst.Ident nodes with the Path field set to the path of the imported package.

When adding a qualified identifier node, there is no need to use *dst.SelectorExpr - just add a *dst.Ident and set Path to the imported package path. The restorer will wrap it in a *ast.SelectorExpr where appropriate when converting back to ast, and also update the import block.

To enable import management, the decorator must be able to resolve the imported package for selector expressions and identifiers, and the restorer must be able to resolve the name of a package given it's path. Several implementations for these resolvers are provided, and the best method will depend on the environment. See below for more details.

Load

The Load convenience function uses go/packages to load packages and decorate all loaded ast files, with import management enabled:

// Create a simple module in a temporary directory
dir, err := tempDir(map[string]string{
	"go.mod":	"module root",
	"main.go":	"package main \n\n func main() {}",
})
defer os.RemoveAll(dir)
if err != nil {
	panic(err)
}

// Use the Load convenience function that calls go/packages to load the package. All loaded
// ast files are decorated to dst.
pkgs, err := decorator.Load(&packages.Config{Dir: dir, Mode: packages.LoadSyntax}, "root")
if err != nil {
	panic(err)
}
p := pkgs[0]
f := p.Syntax[0]

// Add a call expression. Note we don't have to use a SelectorExpr - just adding an Ident with
// the imported package path will do. The restorer will add SelectorExpr where appropriate when
// converting back to ast. Note the new Path field on *dst.Ident. Set this to the package path
// of the imported package, and the restorer will automatically add the import to the import
// block.
b := f.Decls[0].(*dst.FuncDecl).Body
b.List = append(b.List, &dst.ExprStmt{
	X: &dst.CallExpr{
		Fun:	&dst.Ident{Path: "fmt", Name: "Println"},
		Args: []dst.Expr{
			&dst.BasicLit{Kind: token.STRING, Value: strconv.Quote("Hello, World!")},
		},
	},
})

// Create a restorer with the import manager enabled, and print the result. As you can see, the
// import block is automatically managed, and the Println ident is converted to a SelectorExpr:
r := decorator.NewRestorerWithImports("root", gopackages.New(dir))
if err := r.Print(p.Syntax[0]); err != nil {
	panic(err)
}

//Output:
//package main
//
//import "fmt"
//
//func main() { fmt.Println("Hello, World!") }
Mappings

The decorator exposes Dst.Nodes and Ast.Nodes which map between ast.Node and dst.Node. This enables systems that refer to ast nodes (such as go/types) to be used:

code := `package main

func main() {
	var i int
	i++
	println(i)
}`

// Parse the code to AST
fset := token.NewFileSet()
astFile, err := parser.ParseFile(fset, "", code, parser.ParseComments)
if err != nil {
	panic(err)
}

// Invoke the type checker using AST as input
typesInfo := types.Info{
	Defs:	make(map[*ast.Ident]types.Object),
	Uses:	make(map[*ast.Ident]types.Object),
}
conf := &types.Config{}
if _, err := conf.Check("", fset, []*ast.File{astFile}, &typesInfo); err != nil {
	panic(err)
}

// Create a new decorator, which will track the mapping between ast and dst nodes
dec := decorator.NewDecorator(fset)

// Decorate the *ast.File to give us a *dst.File
f, err := dec.DecorateFile(astFile)
if err != nil {
	panic(err)
}

// Find the *dst.Ident for the definition of "i"
dstDef := f.Decls[0].(*dst.FuncDecl).Body.List[0].(*dst.DeclStmt).Decl.(*dst.GenDecl).Specs[0].(*dst.ValueSpec).Names[0]

// Find the *ast.Ident using the Ast.Nodes mapping
astDef := dec.Ast.Nodes[dstDef].(*ast.Ident)

// Find the types.Object corresponding to "i"
obj := typesInfo.Defs[astDef]

// Find all the uses of that object
var astUses []*ast.Ident
for id, ob := range typesInfo.Uses {
	if ob != obj {
		continue
	}
	astUses = append(astUses, id)
}

// Find each *dst.Ident in the Dst.Nodes mapping
var dstUses []*dst.Ident
for _, id := range astUses {
	dstUses = append(dstUses, dec.Dst.Nodes[id].(*dst.Ident))
}

// Change the name of the original definition and all uses
dstDef.Name = "foo"
for _, id := range dstUses {
	id.Name = "foo"
}

// Print the DST
if err := decorator.Print(f); err != nil {
	panic(err)
}

//Output:
//package main
//
//func main() {
//	var foo int
//	foo++
//	println(foo)
//}

Resolvers

There are two separate interfaces defined by the resolver package which allow the decorator and restorer to automatically manage the imports block.

The decorator uses a DecoratorResolver which resolves the package path of any *ast.Ident. This is complicated by dot-import syntax (see below).

The restorer uses a RestorerResolver which resolves the name of any package given the path. This is complicated by vendoring and Go modules.

When Resolver is set on Decorator or Restorer, the Path property must be set to the local package path.

Several implementations of both interfaces that are suitable for different environments are provided:

DecoratorResolver
gotypes

The gotypes package provides a DecoratorResolver with full dot-import compatibility. However it requires full export data for all imported packages, so the Uses map from go/types.Info is required. There are several methods of generating go/types.Info. Using golang.org/x/tools/go/packages.Load is recommended for full Go modules compatibility. See the decorator.Load convenience function to automate this.

goast

The goast package provides a simplified DecoratorResolver that only needs to scan a single ast file. This is unable to resolve identifiers from dot-imported packages, so will panic if a dot-import is encountered in the import block. It uses the provided RestorerResolver to resolve the names of all imported packages. If no RestorerResolver is provided, the guess implementation is used.

RestorerResolver
gopackages

The gopackages package provides a RestorerResolver with full compatibility with Go modules. It uses golang.org/x/tools/go/packages to load the package data. This may be very slow, and uses the go command line tool to query package data, so may not be compatible with some environments.

gobuild

The gobuild package provides an alternative RestorerResolver that uses the legacy go/build system to load the imported package data. This may be needed in some circumstances and provides better performance than go/packages. However, this is not Go modules aware.

guess and simple

The guess and simple packages provide simple RestorerResolver implementations that may be useful in certain circumstances, or where performance is critical. simple resolves paths only if they occur in a provided map. guess guesses the package name based on the last part of the path.

Example

Here's an example of supplying resolvers for the decorator and restorer:

code := `package main

	import "fmt"

	func main() {
		fmt.Println("a")
	}`

dec := decorator.NewDecoratorWithImports(token.NewFileSet(), "main", goast.New())

f, err := dec.Parse(code)
if err != nil {
	panic(err)
}

f.Decls[1].(*dst.FuncDecl).Body.List[0].(*dst.ExprStmt).X.(*dst.CallExpr).Args = []dst.Expr{
	&dst.CallExpr{
		Fun: &dst.Ident{Name: "A", Path: "foo.bar/baz"},
	},
}

res := decorator.NewRestorerWithImports("main", guess.New())
if err := res.Print(f); err != nil {
	panic(err)
}

//Output:
//package main
//
//import (
//	"fmt"
//
//	"foo.bar/baz"
//)
//
//func main() {
//	fmt.Println(baz.A())
//}
Alias

To control the alias of imports, use a FileRestorer:

code := `package main

	import "fmt"

	func main() {
		fmt.Println("a")
	}`

dec := decorator.NewDecoratorWithImports(token.NewFileSet(), "main", goast.New())

f, err := dec.Parse(code)
if err != nil {
	panic(err)
}

res := decorator.NewRestorerWithImports("main", guess.New())

fr := res.FileRestorer()
fr.Alias["fmt"] = "fmt1"

if err := fr.Print(f); err != nil {
	panic(err)
}

//Output:
//package main
//
//import fmt1 "fmt"
//
//func main() {
//	fmt1.Println("a")
//}
Details

For more information on exactly how the imports block is managed, read through the test cases.

Dot-imports

Consider this file...

package main

import (
	. "a"
)

func main() {
	B()
	C()
}

B and C could be local identifiers from a different file in this package, or from the imported package a. If only one is from a and it is removed, we should remove the import when we restore to ast. Thus the resolver needs to be able to resolve the package using the full info from go/types.

Status

This package is well tested and used in many projects. The API should be considered stable going forward.

Chat?

Feel free to create an issue or chat in the #dst Gophers Slack channel.

Contributing

For further developing or contributing to dst, check out these notes.

Special thanks

Thanks very much to hawkinsw for taking on the task of adding generics compatibility to dst.

Documentation

Overview

Package dst declares the types used to represent decorated syntax trees for Go packages.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Fprint

func Fprint(w io.Writer, x interface{}, f FieldFilter) error

Fprint prints the (sub-)tree starting at AST node x to w. If fset != nil, position information is interpreted relative to that file set. Otherwise positions are printed as integer values (file set specific offsets).

A non-nil FieldFilter f may be provided to control the output: struct fields for which f(fieldname, fieldvalue) is true are printed; all others are filtered from the output. Unexported struct fields are never printed.

func Inspect

func Inspect(node Node, f func(Node) bool)

Inspect traverses an AST in depth-first order: It starts by calling f(node); node must not be nil. If f returns true, Inspect invokes f recursively for each of the non-nil children of node, followed by a call of f(nil).

Example

This example demonstrates how to inspect the AST of a Go program.

package main

import (
	"fmt"
	"go/token"

	"github.com/dave/dst"
	"github.com/dave/dst/decorator"
)

func main() {
	// src is the input for which we want to inspect the AST.
	src := `
package p
const c = 1.0
var X = f(3.14)*2 + c
`

	// Create the AST by parsing src.
	fset := token.NewFileSet() // positions are relative to fset
	f, err := decorator.ParseFile(fset, "src.go", src, 0)
	if err != nil {
		panic(err)
	}

	// Inspect the AST and print all identifiers and literals.
	dst.Inspect(f, func(n dst.Node) bool {
		var s string
		switch x := n.(type) {
		case *dst.BasicLit:
			s = x.Value
		case *dst.Ident:
			s = x.Name
		}
		if s != "" {
			fmt.Println(s)
		}
		return true
	})

}
Output:

p
c
1.0
X
f
3.14
2
c

func IsExported

func IsExported(name string) bool

IsExported reports whether name starts with an upper-case letter.

func NotNilFilter

func NotNilFilter(_ string, v reflect.Value) bool

NotNilFilter returns true for field values that are not nil; it returns false otherwise.

func Print

func Print(x interface{}) error

Print prints x to standard output, skipping nil fields. Print(fset, x) is the same as Fprint(os.Stdout, fset, x, NotNilFilter).

func Walk

func Walk(v Visitor, node Node)

Walk traverses an AST in depth-first order: It starts by calling v.Visit(node); node must not be nil. If the visitor w returned by v.Visit(node) is not nil, Walk is invoked recursively with visitor w for each of the non-nil children of node, followed by a call of w.Visit(nil).

Types

type ArrayType

type ArrayType struct {
	Len  Expr // Ellipsis node for [...]T array types, nil for slice types
	Elt  Expr // element type
	Decs ArrayTypeDecorations
}

An ArrayType node represents an array or slice type.

func (*ArrayType) Decorations added in v0.6.0

func (n *ArrayType) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type ArrayTypeDecorations

type ArrayTypeDecorations struct {
	NodeDecs
	Lbrack Decorations
	Len    Decorations
}

ArrayTypeDecorations holds decorations for ArrayType:

type R /*Start*/ [ /*Lbrack*/ 1] /*Len*/ int /*End*/

type AssignStmt

type AssignStmt struct {
	Lhs  []Expr
	Tok  token.Token // assignment token, DEFINE
	Rhs  []Expr
	Decs AssignStmtDecorations
}

An AssignStmt node represents an assignment or a short variable declaration.

func (*AssignStmt) Decorations added in v0.6.0

func (n *AssignStmt) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type AssignStmtDecorations

type AssignStmtDecorations struct {
	NodeDecs
	Tok Decorations
}

AssignStmtDecorations holds decorations for AssignStmt:

/*Start*/
i = /*Tok*/ 1 /*End*/

type BadDecl

type BadDecl struct {
	Length int // position range of bad declaration
	Decs   BadDeclDecorations
}

A BadDecl node is a placeholder for a declaration containing syntax errors for which a correct declaration node cannot be created.

func (*BadDecl) Decorations added in v0.6.0

func (n *BadDecl) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type BadDeclDecorations

type BadDeclDecorations struct {
	NodeDecs
}

BadDeclDecorations holds decorations for BadDecl:

type BadExpr

type BadExpr struct {
	Length int // position range of bad expression
	Decs   BadExprDecorations
}

A BadExpr node is a placeholder for an expression containing syntax errors for which a correct expression node cannot be created.

func (*BadExpr) Decorations added in v0.6.0

func (n *BadExpr) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type BadExprDecorations

type BadExprDecorations struct {
	NodeDecs
}

BadExprDecorations holds decorations for BadExpr:

type BadStmt

type BadStmt struct {
	Length int // position range of bad statement
	Decs   BadStmtDecorations
}

A BadStmt node is a placeholder for statements containing syntax errors for which no correct statement nodes can be created.

func (*BadStmt) Decorations added in v0.6.0

func (n *BadStmt) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type BadStmtDecorations

type BadStmtDecorations struct {
	NodeDecs
}

BadStmtDecorations holds decorations for BadStmt:

type BasicLit

type BasicLit struct {
	Kind  token.Token // token.INT, token.FLOAT, token.IMAG, token.CHAR, or token.STRING
	Value string      // literal string; e.g. 42, 0x7f, 3.14, 1e-9, 2.4i, 'a', '\x7f', "foo" or `\m\n\o`
	Decs  BasicLitDecorations
}

A BasicLit node represents a literal of basic type.

func (*BasicLit) Decorations added in v0.6.0

func (n *BasicLit) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type BasicLitDecorations

type BasicLitDecorations struct {
	NodeDecs
}

BasicLitDecorations holds decorations for BasicLit:

type BinaryExpr

type BinaryExpr struct {
	X    Expr        // left operand
	Op   token.Token // operator
	Y    Expr        // right operand
	Decs BinaryExprDecorations
}

A BinaryExpr node represents a binary expression.

func (*BinaryExpr) Decorations added in v0.6.0

func (n *BinaryExpr) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type BinaryExprDecorations

type BinaryExprDecorations struct {
	NodeDecs
	X  Decorations
	Op Decorations
}

BinaryExprDecorations holds decorations for BinaryExpr:

var P = /*Start*/ 1 /*X*/ & /*Op*/ 2 /*End*/

type BlockStmt

type BlockStmt struct {
	List           []Stmt
	RbraceHasNoPos bool // Rbrace may be absent due to syntax error, so we duplicate this in the output for compatibility.
	Decs           BlockStmtDecorations
}

A BlockStmt node represents a braced statement list.

func (*BlockStmt) Decorations added in v0.6.0

func (n *BlockStmt) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type BlockStmtDecorations

type BlockStmtDecorations struct {
	NodeDecs
	Lbrace Decorations
}

BlockStmtDecorations holds decorations for BlockStmt:

if true /*Start*/ { /*Lbrace*/
	i++
} /*End*/

func() /*Start*/ { /*Lbrace*/ i++ } /*End*/ ()

type BranchStmt

type BranchStmt struct {
	Tok   token.Token // keyword token (BREAK, CONTINUE, GOTO, FALLTHROUGH)
	Label *Ident      // label name; or nil
	Decs  BranchStmtDecorations
}

A BranchStmt node represents a break, continue, goto, or fallthrough statement.

func (*BranchStmt) Decorations added in v0.6.0

func (n *BranchStmt) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type BranchStmtDecorations

type BranchStmtDecorations struct {
	NodeDecs
	Tok Decorations
}

BranchStmtDecorations holds decorations for BranchStmt:

/*Start*/
goto /*Tok*/ A /*End*/

type CallExpr

type CallExpr struct {
	Fun      Expr   // function expression
	Args     []Expr // function arguments; or nil
	Ellipsis bool
	Decs     CallExprDecorations
}

A CallExpr node represents an expression followed by an argument list.

func (*CallExpr) Decorations added in v0.6.0

func (n *CallExpr) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type CallExprDecorations

type CallExprDecorations struct {
	NodeDecs
	Fun      Decorations
	Lparen   Decorations
	Ellipsis Decorations
}

CallExprDecorations holds decorations for CallExpr:

var L = /*Start*/ C /*Fun*/ ( /*Lparen*/ 0, []int{}... /*Ellipsis*/) /*End*/

type CaseClause

type CaseClause struct {
	List []Expr // list of expressions or types; nil means default case
	Body []Stmt // statement list; or nil
	Decs CaseClauseDecorations
}

A CaseClause represents a case of an expression or type switch statement.

func (*CaseClause) Decorations added in v0.6.0

func (n *CaseClause) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type CaseClauseDecorations

type CaseClauseDecorations struct {
	NodeDecs
	Case  Decorations
	Colon Decorations
}

CaseClauseDecorations holds decorations for CaseClause:

switch i {
/*Start*/ case /*Case*/ 1: /*Colon*/
	i++ /*End*/
}

type ChanDir

type ChanDir int

The direction of a channel type is indicated by a bit mask including one or both of the following constants.

const (
	SEND ChanDir = 1 << iota
	RECV
)

type ChanType

type ChanType struct {
	Dir   ChanDir // channel direction
	Value Expr    // value type
	Decs  ChanTypeDecorations
}

A ChanType node represents a channel type.

func (*ChanType) Decorations added in v0.6.0

func (n *ChanType) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type ChanTypeDecorations

type ChanTypeDecorations struct {
	NodeDecs
	Begin Decorations
	Arrow Decorations
}

ChanTypeDecorations holds decorations for ChanType:

type W /*Start*/ chan /*Begin*/ int /*End*/

type X /*Start*/ <-chan /*Begin*/ int /*End*/

type Y /*Start*/ chan /*Begin*/ <- /*Arrow*/ int /*End*/

type CommClause

type CommClause struct {
	Comm Stmt   // send or receive statement; nil means default case
	Body []Stmt // statement list; or nil
	Decs CommClauseDecorations
}

A CommClause node represents a case of a select statement.

func (*CommClause) Decorations added in v0.6.0

func (n *CommClause) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type CommClauseDecorations

type CommClauseDecorations struct {
	NodeDecs
	Case  Decorations
	Comm  Decorations
	Colon Decorations
}

CommClauseDecorations holds decorations for CommClause:

select {
/*Start*/ case /*Case*/ a := <-c /*Comm*/ : /*Colon*/
	print(a) /*End*/
}

type CompositeLit

type CompositeLit struct {
	Type       Expr   // literal type; or nil
	Elts       []Expr // list of composite elements; or nil
	Incomplete bool   // true if (source) expressions are missing in the Elts list
	Decs       CompositeLitDecorations
}

A CompositeLit node represents a composite literal.

func (*CompositeLit) Decorations added in v0.6.0

func (n *CompositeLit) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type CompositeLitDecorations

type CompositeLitDecorations struct {
	NodeDecs
	Type   Decorations
	Lbrace Decorations
}

CompositeLitDecorations holds decorations for CompositeLit:

var D = /*Start*/ A /*Type*/ { /*Lbrace*/ A: 0} /*End*/

type Decl

type Decl interface {
	Node
	// contains filtered or unexported methods
}

All declaration nodes implement the Decl interface.

type DeclStmt

type DeclStmt struct {
	Decl Decl // *GenDecl with CONST, TYPE, or VAR token
	Decs DeclStmtDecorations
}

A DeclStmt node represents a declaration in a statement list.

func (*DeclStmt) Decorations added in v0.6.0

func (n *DeclStmt) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type DeclStmtDecorations

type DeclStmtDecorations struct {
	NodeDecs
}

DeclStmtDecorations holds decorations for DeclStmt:

type Decorations

type Decorations []string

Decorations is a slice of strings which are rendered with the node. Decorations can be comments (starting "//" or "/*") or newlines ("\n").

Example
package main

import (
	"fmt"

	"github.com/dave/dst"
	"github.com/dave/dst/decorator"
)

func main() {
	code := `package main

	func main() {
		var a int
		a++
		print(a)
	}`
	f, err := decorator.Parse(code)
	if err != nil {
		panic(err)
	}

	body := f.Decls[0].(*dst.FuncDecl).Body
	for i, stmt := range body.List {
		stmt.Decorations().Before = dst.EmptyLine
		stmt.Decorations().Start.Append(fmt.Sprintf("// foo %d", i))
	}

	call := body.List[2].(*dst.ExprStmt).X.(*dst.CallExpr)
	call.Args = append(call.Args, dst.NewIdent("b"), dst.NewIdent("c"))
	for i, expr := range call.Args {
		expr.Decorations().Before = dst.NewLine
		expr.Decorations().After = dst.NewLine
		expr.Decorations().Start.Append(fmt.Sprintf("/* bar %d */", i))
		expr.Decorations().End.Append(fmt.Sprintf("// baz %d", i))
	}

	if err := decorator.Print(f); err != nil {
		panic(err)
	}

}
Output:

package main

func main() {

	// foo 0
	var a int

	// foo 1
	a++

	// foo 2
	print(
		/* bar 0 */ a, // baz 0
		/* bar 1 */ b, // baz 1
		/* bar 2 */ c, // baz 2
	)
}

func (*Decorations) All added in v0.2.0

func (d *Decorations) All() []string

All returns the decorations as a string slice

func (*Decorations) Append added in v0.6.0

func (d *Decorations) Append(decs ...string)

Append adds one or more decorations to the end of the list.

func (*Decorations) Clear

func (d *Decorations) Clear()

Clear removes all decorations from this item

func (*Decorations) Prepend added in v0.6.0

func (d *Decorations) Prepend(decs ...string)

Prepend adds one or more decorations to the start of the list.

func (*Decorations) Replace

func (d *Decorations) Replace(decs ...string)

Replace replaces all decorations with decs.

type DeferStmt

type DeferStmt struct {
	Call *CallExpr
	Decs DeferStmtDecorations
}

A DeferStmt node represents a defer statement.

func (*DeferStmt) Decorations added in v0.6.0

func (n *DeferStmt) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type DeferStmtDecorations

type DeferStmtDecorations struct {
	NodeDecs
	Defer Decorations
}

DeferStmtDecorations holds decorations for DeferStmt:

/*Start*/
defer /*Defer*/ func() {}() /*End*/

type Ellipsis

type Ellipsis struct {
	Elt  Expr // ellipsis element type (parameter lists only); or nil
	Decs EllipsisDecorations
}

An Ellipsis node stands for the "..." type in a parameter list or the "..." length in an array type.

func (*Ellipsis) Decorations added in v0.6.0

func (n *Ellipsis) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type EllipsisDecorations

type EllipsisDecorations struct {
	NodeDecs
	Ellipsis Decorations
}

EllipsisDecorations holds decorations for Ellipsis:

func B(a /*Start*/ ... /*Ellipsis*/ int /*End*/) {}

type EmptyStmt

type EmptyStmt struct {
	Implicit bool // if set, ";" was omitted in the source
	Decs     EmptyStmtDecorations
}

An EmptyStmt node represents an empty statement. The "position" of the empty statement is the position of the immediately following (explicit or implicit) semicolon.

func (*EmptyStmt) Decorations added in v0.6.0

func (n *EmptyStmt) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type EmptyStmtDecorations

type EmptyStmtDecorations struct {
	NodeDecs
}

EmptyStmtDecorations holds decorations for EmptyStmt:

type Expr

type Expr interface {
	Node
	// contains filtered or unexported methods
}

All expression nodes implement the Expr interface.

type ExprStmt

type ExprStmt struct {
	X    Expr // expression
	Decs ExprStmtDecorations
}

An ExprStmt node represents a (stand-alone) expression in a statement list.

func (*ExprStmt) Decorations added in v0.6.0

func (n *ExprStmt) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type ExprStmtDecorations

type ExprStmtDecorations struct {
	NodeDecs
}

ExprStmtDecorations holds decorations for ExprStmt:

type Field

type Field struct {
	Names []*Ident  // field/method/(type) parameter names; or nil
	Type  Expr      // field/method/parameter type; or nil
	Tag   *BasicLit // field tag; or nil
	Decs  FieldDecorations
}

A Field represents a Field declaration list in a struct type, a method list in an interface type, or a parameter/result declaration in a signature. Field.Names is nil for unnamed parameters (parameter lists which only contain types) and embedded struct fields. In the latter case, the field name is the type name.

func (*Field) Decorations added in v0.6.0

func (n *Field) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type FieldDecorations

type FieldDecorations struct {
	NodeDecs
	Type Decorations
}

FieldDecorations holds decorations for Field:

type A struct {
	/*Start*/ A int /*Type*/ `a:"a"` /*End*/
}

type FieldFilter

type FieldFilter func(name string, value reflect.Value) bool

A FieldFilter may be provided to Fprint to control the output.

type FieldList

type FieldList struct {
	Opening bool
	List    []*Field // field list; or nil
	Closing bool
	Decs    FieldListDecorations
}

A FieldList represents a list of Fields, enclosed by parentheses, curly braces, or square brackets.

func (*FieldList) Decorations added in v0.6.0

func (n *FieldList) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

func (*FieldList) NumFields

func (f *FieldList) NumFields() int

NumFields returns the number of parameters or struct fields represented by a FieldList.

type FieldListDecorations

type FieldListDecorations struct {
	NodeDecs
	Opening Decorations
}

FieldListDecorations holds decorations for FieldList:

type A1 struct /*Start*/ { /*Opening*/
	a, b int
	c    string
} /*End*/

type File

type File struct {
	Name       *Ident        // package name
	Decls      []Decl        // top-level declarations; or nil
	Scope      *Scope        // package scope (this file only)
	Imports    []*ImportSpec // imports in this file
	Unresolved []*Ident      // unresolved identifiers in this file
	Decs       FileDecorations
}

A File node represents a Go source file.

The Comments list contains all comments in the source file in order of appearance, including the comments that are pointed to from other nodes via Doc and Comment fields.

For correct printing of source code containing comments (using packages go/format and go/printer), special care must be taken to update comments when a File's syntax tree is modified: For printing, comments are interspersed between tokens based on their position. If syntax tree nodes are removed or moved, relevant comments in their vicinity must also be removed (from the File.Comments list) or moved accordingly (by updating their positions). A CommentMap may be used to facilitate some of these operations.

Whether and how a comment is associated with a node depends on the interpretation of the syntax tree by the manipulating program: Except for Doc and Comment comments directly associated with nodes, the remaining comments are "free-floating" (see also issues #18593, #20744).

func (*File) Decorations added in v0.6.0

func (n *File) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type FileDecorations

type FileDecorations struct {
	NodeDecs
	Package Decorations
	Name    Decorations
}

FileDecorations holds decorations for File:

/*Start*/ package /*Package*/ data /*Name*/

type ForStmt

type ForStmt struct {
	Init Stmt // initialization statement; or nil
	Cond Expr // condition; or nil
	Post Stmt // post iteration statement; or nil
	Body *BlockStmt
	Decs ForStmtDecorations
}

A ForStmt represents a for statement.

func (*ForStmt) Decorations added in v0.6.0

func (n *ForStmt) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type ForStmtDecorations

type ForStmtDecorations struct {
	NodeDecs
	For  Decorations
	Init Decorations
	Cond Decorations
	Post Decorations
}

ForStmtDecorations holds decorations for ForStmt:

/*Start*/
for /*For*/ {
	i++
} /*End*/

/*Start*/
for /*For*/ i < 1 /*Cond*/ {
	i++
} /*End*/

/*Start*/
for /*For*/ i = 0; /*Init*/ i < 10; /*Cond*/ i++ /*Post*/ {
	i++
} /*End*/

type FuncDecl

type FuncDecl struct {
	Recv *FieldList // receiver (methods); or nil (functions)
	Name *Ident     // function/method name
	Type *FuncType  // function signature: type and value parameters, results, and position of "func" keyword
	Body *BlockStmt // function body; or nil for external (non-Go) function
	Decs FuncDeclDecorations
}

A FuncDecl node represents a function declaration.

func (*FuncDecl) Decorations added in v0.6.0

func (n *FuncDecl) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type FuncDeclDecorations

type FuncDeclDecorations struct {
	NodeDecs
	Func       Decorations
	Recv       Decorations
	Name       Decorations
	TypeParams Decorations
	Params     Decorations
	Results    Decorations
}

FuncDeclDecorations holds decorations for FuncDecl:

/*Start*/
func /*Func*/ d /*Name*/ (d, e int) /*Params*/ {
	return
} /*End*/

/*Start*/
func /*Func*/ TP /*Name*/ [P any] /*TypeParams*/ (a int) /*Params*/ (b P) /*Results*/ {
	return b
} /*End*/

/*Start*/
func /*Func*/ (a *A) /*Recv*/ e /*Name*/ (d, e int) /*Params*/ {
	return
} /*End*/

/*Start*/
func /*Func*/ (a *A) /*Recv*/ f /*Name*/ (d, e int) /*Params*/ (f, g int) /*Results*/ {
	return
} /*End*/

type FuncLit

type FuncLit struct {
	Type *FuncType  // function type
	Body *BlockStmt // function body
	Decs FuncLitDecorations
}

A FuncLit node represents a function literal.

func (*FuncLit) Decorations added in v0.6.0

func (n *FuncLit) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type FuncLitDecorations

type FuncLitDecorations struct {
	NodeDecs
	Type Decorations
}

FuncLitDecorations holds decorations for FuncLit:

var C = /*Start*/ func(a int, b ...int) (c int) /*Type*/ { return 0 } /*End*/

type FuncType

type FuncType struct {
	Func       bool
	TypeParams *FieldList // type parameters; or nil
	Params     *FieldList // (incoming) parameters; non-nil
	Results    *FieldList // (outgoing) results; or nil
	Decs       FuncTypeDecorations
}

A FuncType node represents a function type.

func (*FuncType) Decorations added in v0.6.0

func (n *FuncType) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type FuncTypeDecorations

type FuncTypeDecorations struct {
	NodeDecs
	Func       Decorations
	TypeParams Decorations
	Params     Decorations
}

FuncTypeDecorations holds decorations for FuncType:

type T /*Start*/ func /*Func*/ (a int) /*Params*/ (b int) /*End*/

type GenDecl

type GenDecl struct {
	Tok    token.Token // IMPORT, CONST, TYPE, or VAR
	Lparen bool
	Specs  []Spec
	Rparen bool
	Decs   GenDeclDecorations
}

A GenDecl node (generic declaration node) represents an import, constant, type or variable declaration. A valid Lparen position (Lparen.IsValid()) indicates a parenthesized declaration.

Relationship between Tok value and Specs element type:

token.IMPORT  *ImportSpec
token.CONST   *ValueSpec
token.TYPE    *TypeSpec
token.VAR     *ValueSpec

func (*GenDecl) Decorations added in v0.6.0

func (n *GenDecl) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type GenDeclDecorations

type GenDeclDecorations struct {
	NodeDecs
	Tok    Decorations
	Lparen Decorations
}

GenDeclDecorations holds decorations for GenDecl:

/*Start*/
const /*Tok*/ ( /*Lparen*/
	a, b = 1, 2
	c    = 3
) /*End*/

/*Start*/
const /*Tok*/ d = 1 /*End*/

type GoStmt

type GoStmt struct {
	Call *CallExpr
	Decs GoStmtDecorations
}

A GoStmt node represents a go statement.

func (*GoStmt) Decorations added in v0.6.0

func (n *GoStmt) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type GoStmtDecorations

type GoStmtDecorations struct {
	NodeDecs
	Go Decorations
}

GoStmtDecorations holds decorations for GoStmt:

/*Start*/
go /*Go*/ func() {}() /*End*/

type Ident

type Ident struct {
	Name string  // identifier name
	Obj  *Object // denoted object; or nil
	Path string  // path of the imported package, if this identifier is not local
	Decs IdentDecorations
}

An Ident node represents an identifier.

func NewIdent

func NewIdent(name string) *Ident

NewIdent creates a new Ident without position. Useful for ASTs generated by code other than the Go parser.

func (*Ident) Decorations added in v0.6.0

func (n *Ident) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

func (*Ident) IsExported

func (id *Ident) IsExported() bool

IsExported reports whether id starts with an upper-case letter.

func (*Ident) String

func (id *Ident) String() string

type IdentDecorations

type IdentDecorations struct {
	NodeDecs
	X Decorations
}

IdentDecorations holds decorations for Ident:

/*Start*/
i /*End*/ ++

/*Start*/
fmt. /*X*/ Print /*End*/ ()

type IfStmt

type IfStmt struct {
	Init Stmt // initialization statement; or nil
	Cond Expr // condition
	Body *BlockStmt
	Else Stmt // else branch; or nil
	Decs IfStmtDecorations
}

An IfStmt node represents an if statement.

func (*IfStmt) Decorations added in v0.6.0

func (n *IfStmt) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type IfStmtDecorations

type IfStmtDecorations struct {
	NodeDecs
	If   Decorations
	Init Decorations
	Cond Decorations
	Else Decorations
}

IfStmtDecorations holds decorations for IfStmt:

/*Start*/
if /*If*/ a := b; /*Init*/ a /*Cond*/ {
	i++
} else /*Else*/ {
	i++
} /*End*/

type ImportSpec

type ImportSpec struct {
	Name *Ident    // local package name (including "."); or nil
	Path *BasicLit // import path
	Decs ImportSpecDecorations
}

An ImportSpec node represents a single package import.

func (*ImportSpec) Decorations added in v0.6.0

func (n *ImportSpec) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type ImportSpecDecorations

type ImportSpecDecorations struct {
	NodeDecs
	Name Decorations
}

ImportSpecDecorations holds decorations for ImportSpec:

import (
	/*Start*/ fmt /*Name*/ "fmt" /*End*/
)

type Importer

type Importer func(imports map[string]*Object, path string) (pkg *Object, err error)

An Importer resolves import paths to package Objects. The imports map records the packages already imported, indexed by package id (canonical import path). An Importer must determine the canonical import path and check the map to see if it is already present in the imports map. If so, the Importer can return the map entry. Otherwise, the Importer should load the package data for the given path into a new *Object (pkg), record pkg in the imports map, and then return pkg.

type IncDecStmt

type IncDecStmt struct {
	X    Expr
	Tok  token.Token // INC or DEC
	Decs IncDecStmtDecorations
}

An IncDecStmt node represents an increment or decrement statement.

func (*IncDecStmt) Decorations added in v0.6.0

func (n *IncDecStmt) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type IncDecStmtDecorations

type IncDecStmtDecorations struct {
	NodeDecs
	X Decorations
}

IncDecStmtDecorations holds decorations for IncDecStmt:

/*Start*/
i /*X*/ ++ /*End*/

type IndexExpr

type IndexExpr struct {
	X     Expr // expression
	Index Expr // index expression
	Decs  IndexExprDecorations
}

An IndexExpr node represents an expression followed by an index.

func (*IndexExpr) Decorations added in v0.6.0

func (n *IndexExpr) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type IndexExprDecorations

type IndexExprDecorations struct {
	NodeDecs
	X      Decorations
	Lbrack Decorations
	Index  Decorations
}

IndexExprDecorations holds decorations for IndexExpr:

var G = /*Start*/ []int{0} /*X*/ [ /*Lbrack*/ 0 /*Index*/] /*End*/

type IndexListExpr added in v0.27.0

type IndexListExpr struct {
	X       Expr // expression
	Indices []Expr
	Decs    IndexListExprDecorations
}

An IndexListExpr node represents an expression followed by multiple indices.

func (*IndexListExpr) Decorations added in v0.27.0

func (n *IndexListExpr) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type IndexListExprDecorations added in v0.27.0

type IndexListExprDecorations struct {
	NodeDecs
	X       Decorations
	Lbrack  Decorations
	Indices Decorations
}

IndexListExprDecorations holds decorations for IndexListExpr:

var T4 /*Start*/ T3 /*X*/ [ /*Lbrack*/ int, string /*Indices*/] /*End*/

type InterfaceType

type InterfaceType struct {
	Methods    *FieldList // list of embedded interfaces, methods, or types
	Incomplete bool       // true if (source) methods or types are missing in the Methods list
	Decs       InterfaceTypeDecorations
}

An InterfaceType node represents an interface type.

func (*InterfaceType) Decorations added in v0.6.0

func (n *InterfaceType) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type InterfaceTypeDecorations

type InterfaceTypeDecorations struct {
	NodeDecs
	Interface Decorations
}

InterfaceTypeDecorations holds decorations for InterfaceType:

type U /*Start*/ interface /*Interface*/ {
	A()
} /*End*/

type KeyValueExpr

type KeyValueExpr struct {
	Key   Expr
	Value Expr
	Decs  KeyValueExprDecorations
}

A KeyValueExpr node represents (key : value) pairs in composite literals.

func (*KeyValueExpr) Decorations added in v0.6.0

func (n *KeyValueExpr) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type KeyValueExprDecorations

type KeyValueExprDecorations struct {
	NodeDecs
	Key   Decorations
	Colon Decorations
}

KeyValueExprDecorations holds decorations for KeyValueExpr:

var Q = map[string]string{
	/*Start*/ "a" /*Key*/ : /*Colon*/ "a", /*End*/
}

type LabeledStmt

type LabeledStmt struct {
	Label *Ident
	Stmt  Stmt
	Decs  LabeledStmtDecorations
}

A LabeledStmt node represents a labeled statement.

func (*LabeledStmt) Decorations added in v0.6.0

func (n *LabeledStmt) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type LabeledStmtDecorations

type LabeledStmtDecorations struct {
	NodeDecs
	Label Decorations
	Colon Decorations
}

LabeledStmtDecorations holds decorations for LabeledStmt:

/*Start*/
A /*Label*/ : /*Colon*/
	print("Stmt") /*End*/

type MapType

type MapType struct {
	Key   Expr
	Value Expr
	Decs  MapTypeDecorations
}

A MapType node represents a map type.

func (*MapType) Decorations added in v0.6.0

func (n *MapType) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type MapTypeDecorations

type MapTypeDecorations struct {
	NodeDecs
	Map Decorations
	Key Decorations
}

MapTypeDecorations holds decorations for MapType:

type V /*Start*/ map[ /*Map*/ int] /*Key*/ int /*End*/

type Node

type Node interface {
	// Decorations returns the common Node decorations (Before, After, Start, End). This returns nil for Package nodes.
	Decorations() *NodeDecs
}

Node is satisfied by all nodes types.

func Clone added in v0.7.0

func Clone(n Node) Node

Clone returns a deep copy of the node, ready to be re-used elsewhere in the tree.

Example
package main

import (
	"github.com/dave/dst"
	"github.com/dave/dst/decorator"
)

func main() {
	code := `package main

	var i /* a */ int`

	f, err := decorator.Parse(code)
	if err != nil {
		panic(err)
	}

	cloned := dst.Clone(f.Decls[0]).(*dst.GenDecl)

	cloned.Decs.Before = dst.NewLine
	cloned.Specs[0].(*dst.ValueSpec).Names[0].Name = "j"
	cloned.Specs[0].(*dst.ValueSpec).Names[0].Decs.End.Replace("/* b */")

	f.Decls = append(f.Decls, cloned)

	if err := decorator.Print(f); err != nil {
		panic(err)
	}

}
Output:

package main

var i /* a */ int
var j /* b */ int

type NodeDecs added in v0.6.0

type NodeDecs struct {
	Before SpaceType
	Start  Decorations
	End    Decorations
	After  SpaceType
}

NodeDecs holds the decorations that are common to all nodes (except Package).

type ObjKind

type ObjKind int

ObjKind describes what an object represents.

const (
	Bad ObjKind = iota // for error handling
	Pkg                // package
	Con                // constant
	Typ                // type
	Var                // variable
	Fun                // function or method
	Lbl                // label
)

The list of possible Object kinds.

func (ObjKind) String

func (kind ObjKind) String() string

type Object

type Object struct {
	Kind ObjKind
	Name string      // declared name
	Decl interface{} // corresponding Field, XxxSpec, FuncDecl, LabeledStmt, AssignStmt, Scope; or nil
	Data interface{} // object-specific data; or nil
	Type interface{} // placeholder for type information; may be nil
}

An Object describes a named language entity such as a package, constant, type, variable, function (incl. methods), or label.

The Data fields contains object-specific data:

Kind    Data type         Data value
Pkg     *Scope            package scope
Con     int               iota for the respective declaration

func CloneObject added in v0.7.0

func CloneObject(o *Object) *Object

CloneObject returns nil: After cloning a node, it should not be attached to the same object / scope.

func NewObj

func NewObj(kind ObjKind, name string) *Object

NewObj creates a new object of a given kind and name.

type Package

type Package struct {
	Name    string             // package name
	Scope   *Scope             // package scope across all files
	Imports map[string]*Object // map of package id -> package object
	Files   map[string]*File   // Go source files by filename
}

A Package node represents a set of source files collectively building a Go package.

func NewPackage

func NewPackage(fset *token.FileSet, files map[string]*File, importer Importer, universe *Scope) (*Package, error)

NewPackage creates a new Package node from a set of File nodes. It resolves unresolved identifiers across files and updates each file's Unresolved list accordingly. If a non-nil importer and universe scope are provided, they are used to resolve identifiers not declared in any of the package files. Any remaining unresolved identifiers are reported as undeclared. If the files belong to different packages, one package name is selected and files with different package names are reported and then ignored. The result is a package node and a scanner.ErrorList if there were errors.

func (*Package) Decorations added in v0.6.0

func (n *Package) Decorations() *NodeDecs

Decorations is nil for Package nodes.

type PackageDecorations added in v0.1.0

type PackageDecorations struct {
	NodeDecs
}

PackageDecorations holds decorations for Package:

type ParenExpr

type ParenExpr struct {
	X    Expr // parenthesized expression
	Decs ParenExprDecorations
}

A ParenExpr node represents a parenthesized expression.

func (*ParenExpr) Decorations added in v0.6.0

func (n *ParenExpr) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type ParenExprDecorations

type ParenExprDecorations struct {
	NodeDecs
	Lparen Decorations
	X      Decorations
}

ParenExprDecorations holds decorations for ParenExpr:

var E = /*Start*/ ( /*Lparen*/ 1 + 1 /*X*/) /*End*/ / 2

type RangeStmt

type RangeStmt struct {
	Key, Value Expr        // Key, Value may be nil
	Tok        token.Token // ILLEGAL if Key == nil, ASSIGN, DEFINE
	X          Expr        // value to range over
	Body       *BlockStmt
	Decs       RangeStmtDecorations
}

A RangeStmt represents a for statement with a range clause.

func (*RangeStmt) Decorations added in v0.6.0

func (n *RangeStmt) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type RangeStmtDecorations

type RangeStmtDecorations struct {
	NodeDecs
	For   Decorations
	Key   Decorations
	Value Decorations
	Range Decorations
	X     Decorations
}

RangeStmtDecorations holds decorations for RangeStmt:

/*Start*/
for range /*Range*/ a /*X*/ {
} /*End*/

/*Start*/
for /*For*/ k /*Key*/ := range /*Range*/ a /*X*/ {
	print(k)
} /*End*/

/*Start*/
for /*For*/ k /*Key*/, v /*Value*/ := range /*Range*/ a /*X*/ {
	print(k, v)
} /*End*/

type ReturnStmt

type ReturnStmt struct {
	Results []Expr // result expressions; or nil
	Decs    ReturnStmtDecorations
}

A ReturnStmt node represents a return statement.

func (*ReturnStmt) Decorations added in v0.6.0

func (n *ReturnStmt) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type ReturnStmtDecorations

type ReturnStmtDecorations struct {
	NodeDecs
	Return Decorations
}

ReturnStmtDecorations holds decorations for ReturnStmt:

func() int {
	/*Start*/ return /*Return*/ 1 /*End*/
}()

type Scope

type Scope struct {
	Outer   *Scope
	Objects map[string]*Object
}

A Scope maintains the set of named language entities declared in the scope and a link to the immediately surrounding (outer) scope.

func CloneScope added in v0.7.0

func CloneScope(s *Scope) *Scope

CloneScope returns nil: After cloning a node, it should not be attached to the same object / scope.

func NewScope

func NewScope(outer *Scope) *Scope

NewScope creates a new scope nested in the outer scope.

func (*Scope) Insert

func (s *Scope) Insert(obj *Object) (alt *Object)

Insert attempts to insert a named object obj into the scope s. If the scope already contains an object alt with the same name, Insert leaves the scope unchanged and returns alt. Otherwise it inserts obj and returns nil.

func (*Scope) Lookup

func (s *Scope) Lookup(name string) *Object

Lookup returns the object with the given name if it is found in scope s, otherwise it returns nil. Outer scopes are ignored.

func (*Scope) String

func (s *Scope) String() string

Debugging support

type SelectStmt

type SelectStmt struct {
	Body *BlockStmt // CommClauses only
	Decs SelectStmtDecorations
}

A SelectStmt node represents a select statement.

func (*SelectStmt) Decorations added in v0.6.0

func (n *SelectStmt) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type SelectStmtDecorations

type SelectStmtDecorations struct {
	NodeDecs
	Select Decorations
}

SelectStmtDecorations holds decorations for SelectStmt:

/*Start*/
select /*Select*/ {
} /*End*/

type SelectorExpr

type SelectorExpr struct {
	X    Expr   // expression
	Sel  *Ident // field selector
	Decs SelectorExprDecorations
}

A SelectorExpr node represents an expression followed by a selector.

func (*SelectorExpr) Decorations added in v0.6.0

func (n *SelectorExpr) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type SelectorExprDecorations

type SelectorExprDecorations struct {
	NodeDecs
	X Decorations
}

SelectorExprDecorations holds decorations for SelectorExpr:

var F = /*Start*/ tt. /*X*/ F /*End*/ ()

type SendStmt

type SendStmt struct {
	Chan  Expr
	Value Expr
	Decs  SendStmtDecorations
}

A SendStmt node represents a send statement.

func (*SendStmt) Decorations added in v0.6.0

func (n *SendStmt) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type SendStmtDecorations

type SendStmtDecorations struct {
	NodeDecs
	Chan  Decorations
	Arrow Decorations
}

SendStmtDecorations holds decorations for SendStmt:

/*Start*/
c /*Chan*/ <- /*Arrow*/ 0 /*End*/

type SliceExpr

type SliceExpr struct {
	X      Expr // expression
	Low    Expr // begin of slice range; or nil
	High   Expr // end of slice range; or nil
	Max    Expr // maximum capacity of slice; or nil
	Slice3 bool // true if 3-index slice (2 colons present)
	Decs   SliceExprDecorations
}

An SliceExpr node represents an expression followed by slice indices.

func (*SliceExpr) Decorations added in v0.6.0

func (n *SliceExpr) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type SliceExprDecorations

type SliceExprDecorations struct {
	NodeDecs
	X      Decorations
	Lbrack Decorations
	Low    Decorations
	High   Decorations
	Max    Decorations
}

SliceExprDecorations holds decorations for SliceExpr:

var H = /*Start*/ []int{0, 1, 2} /*X*/ [ /*Lbrack*/ 1: /*Low*/ 2: /*High*/ 3 /*Max*/] /*End*/

var H1 = /*Start*/ []int{0, 1, 2} /*X*/ [ /*Lbrack*/ 1: /*Low*/ 2 /*High*/] /*End*/

var H2 = /*Start*/ []int{0} /*X*/ [: /*Low*/] /*End*/

var H3 = /*Start*/ []int{0} /*X*/ [ /*Lbrack*/ 1: /*Low*/] /*End*/

var H4 = /*Start*/ []int{0, 1, 2} /*X*/ [: /*Low*/ 2 /*High*/] /*End*/

var H5 = /*Start*/ []int{0, 1, 2} /*X*/ [: /*Low*/ 2: /*High*/ 3 /*Max*/] /*End*/

type SpaceType added in v0.1.0

type SpaceType int

SpaceType represents the line spacing before or after a node. When the start of one node is adjacent to the end of another node, the SpaceType values are not additive (e.g. two NewLines will render a NewLine and not an EmptyLine).

const (
	None      SpaceType = 0 // None means no extra spacing.
	NewLine   SpaceType = 1 // NewLine is a single "\n"
	EmptyLine SpaceType = 2 // EmptyLine is a double "\n"
)

func (SpaceType) String added in v0.7.0

func (s SpaceType) String() string

String returns a human readable representation of the space type

type Spec

type Spec interface {
	Node
	// contains filtered or unexported methods
}

The Spec type stands for any of *ImportSpec, *ValueSpec, and *TypeSpec.

type StarExpr

type StarExpr struct {
	X    Expr // operand
	Decs StarExprDecorations
}

A StarExpr node represents an expression of the form "*" Expression. Semantically it could be a unary "*" expression, or a pointer type.

func (*StarExpr) Decorations added in v0.6.0

func (n *StarExpr) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type StarExprDecorations

type StarExprDecorations struct {
	NodeDecs
	Star Decorations
}

StarExprDecorations holds decorations for StarExpr:

var N = /*Start*/ * /*Star*/ p /*End*/

type Stmt

type Stmt interface {
	Node
	// contains filtered or unexported methods
}

All statement nodes implement the Stmt interface.

type StructType

type StructType struct {
	Fields     *FieldList // list of field declarations
	Incomplete bool       // true if (source) fields are missing in the Fields list
	Decs       StructTypeDecorations
}

A StructType node represents a struct type.

func (*StructType) Decorations added in v0.6.0

func (n *StructType) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type StructTypeDecorations

type StructTypeDecorations struct {
	NodeDecs
	Struct Decorations
}

StructTypeDecorations holds decorations for StructType:

type S /*Start*/ struct /*Struct*/ {
	A int
} /*End*/

type SwitchStmt

type SwitchStmt struct {
	Init Stmt       // initialization statement; or nil
	Tag  Expr       // tag expression; or nil
	Body *BlockStmt // CaseClauses only
	Decs SwitchStmtDecorations
}

A SwitchStmt node represents an expression switch statement.

func (*SwitchStmt) Decorations added in v0.6.0

func (n *SwitchStmt) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type SwitchStmtDecorations

type SwitchStmtDecorations struct {
	NodeDecs
	Switch Decorations
	Init   Decorations
	Tag    Decorations
}

SwitchStmtDecorations holds decorations for SwitchStmt:

/*Start*/
switch /*Switch*/ i /*Tag*/ {
} /*End*/

/*Start*/
switch /*Switch*/ a := i; /*Init*/ a /*Tag*/ {
} /*End*/

type TypeAssertExpr

type TypeAssertExpr struct {
	X    Expr // expression
	Type Expr // asserted type; nil means type switch X.(type)
	Decs TypeAssertExprDecorations
}

A TypeAssertExpr node represents an expression followed by a type assertion.

func (*TypeAssertExpr) Decorations added in v0.6.0

func (n *TypeAssertExpr) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type TypeAssertExprDecorations

type TypeAssertExprDecorations struct {
	NodeDecs
	X      Decorations
	Lparen Decorations
	Type   Decorations
}

TypeAssertExprDecorations holds decorations for TypeAssertExpr:

var J = /*Start*/ f. /*X*/ ( /*Lparen*/ int /*Type*/) /*End*/

type TypeSpec

type TypeSpec struct {
	Name       *Ident     // type name
	TypeParams *FieldList // type parameters; or nil
	Assign     bool       // position of '=', if any
	Type       Expr       // *Ident, *ParenExpr, *SelectorExpr, *StarExpr, or any of the *XxxTypes
	Decs       TypeSpecDecorations
}

A TypeSpec node represents a type declaration (TypeSpec production).

func (*TypeSpec) Decorations added in v0.6.0

func (n *TypeSpec) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type TypeSpecDecorations

type TypeSpecDecorations struct {
	NodeDecs
	Name       Decorations
	TypeParams Decorations
}

TypeSpecDecorations holds decorations for TypeSpec:

type (
	/*Start*/ T1 /*Name*/ []int /*End*/
)

type (
	/*Start*/ T2 = /*Name*/ T1 /*End*/
)

type (
	/*Start*/ T3 /*Name*/ [P any, Q any] /*TypeParams*/ []P /*End*/
)

type TypeSwitchStmt

type TypeSwitchStmt struct {
	Init   Stmt       // initialization statement; or nil
	Assign Stmt       // x := y.(type) or y.(type)
	Body   *BlockStmt // CaseClauses only
	Decs   TypeSwitchStmtDecorations
}

A TypeSwitchStmt node represents a type switch statement.

func (*TypeSwitchStmt) Decorations added in v0.6.0

func (n *TypeSwitchStmt) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type TypeSwitchStmtDecorations

type TypeSwitchStmtDecorations struct {
	NodeDecs
	Switch Decorations
	Init   Decorations
	Assign Decorations
}

TypeSwitchStmtDecorations holds decorations for TypeSwitchStmt:

/*Start*/
switch /*Switch*/ f.(type) /*Assign*/ {
} /*End*/

/*Start*/
switch /*Switch*/ g := f.(type) /*Assign*/ {
case int:
	print(g)
} /*End*/

/*Start*/
switch /*Switch*/ g := f; /*Init*/ g := g.(type) /*Assign*/ {
case int:
	print(g)
} /*End*/

type UnaryExpr

type UnaryExpr struct {
	Op   token.Token // operator
	X    Expr        // operand
	Decs UnaryExprDecorations
}

A UnaryExpr node represents a unary expression. Unary "*" expressions are represented via StarExpr nodes.

func (*UnaryExpr) Decorations added in v0.6.0

func (n *UnaryExpr) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type UnaryExprDecorations

type UnaryExprDecorations struct {
	NodeDecs
	Op Decorations
}

UnaryExprDecorations holds decorations for UnaryExpr:

var O = /*Start*/ ^ /*Op*/ 1 /*End*/

type ValueSpec

type ValueSpec struct {
	Names  []*Ident // value names (len(Names) > 0)
	Type   Expr     // value type; or nil
	Values []Expr   // initial values; or nil
	Decs   ValueSpecDecorations
}

A ValueSpec node represents a constant or variable declaration (ConstSpec or VarSpec production).

func (*ValueSpec) Decorations added in v0.6.0

func (n *ValueSpec) Decorations() *NodeDecs

Decorations returns the decorations that are common to all nodes (Before, Start, End, After).

type ValueSpecDecorations

type ValueSpecDecorations struct {
	NodeDecs
	Assign Decorations
}

ValueSpecDecorations holds decorations for ValueSpec:

var (
	/*Start*/ j = /*Assign*/ 1 /*End*/
)

var (
	/*Start*/ k, l = /*Assign*/ 1, 2 /*End*/
)

var (
	/*Start*/ m, n int = /*Assign*/ 1, 2 /*End*/
)

type Visitor

type Visitor interface {
	Visit(node Node) (w Visitor)
}

A Visitor's Visit method is invoked for each node encountered by Walk. If the result visitor w is not nil, Walk visits each of the children of node with the visitor w, followed by a call of w.Visit(nil).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL