...

Package astutil

import "cmd/vendor/golang.org/x/tools/internal/astutil"
Overview
Index
Subdirectories

Overview ▾

Package astutil provides various AST utility functions for gopls.

Index ▾

func CloneNode[T ast.Node](n T) T
func Comments(file *ast.File, start, end token.Pos) iter.Seq[*ast.Comment]
func Deprecation(doc *ast.CommentGroup) string
func DocComment(n ast.Node) *ast.CommentGroup
func EnclosingFile(c inspector.Cursor) *ast.File
func Equal(x, y ast.Node, identical func(x, y *ast.Ident) bool) bool
func EqualSyntax(x, y ast.Expr) bool
func FlatFields(list *ast.FieldList) iter.Seq2[*ast.Ident, *ast.Field]
func Format(fset *token.FileSet, n ast.Node) string
func MaybeParenthesize(parentNode ast.Node, old, new ast.Expr) ast.Expr
func NodeContains(n ast.Node, rng Range) bool
func NodeContainsPos(n ast.Node, pos token.Pos) bool
func OffsetInStringLiteral(lit *ast.BasicLit, pos token.Pos) (int, error)
func PosInStringLiteral(lit *ast.BasicLit, offset int) (token.Pos, error)
func PurgeFuncBodies(src []byte) []byte
func Select(curFile inspector.Cursor, start, end token.Pos) (_enclosing, _start, _end inspector.Cursor, _ error)
func UnpackRecv(rtyp ast.Expr) (ptr bool, rname *ast.Ident, tparams []*ast.Ident)
func UnparenCursor(cur inspector.Cursor) inspector.Cursor
func UnparenEnclosingCursor(cur inspector.Cursor) inspector.Cursor
type Directive
    func Directives(g *ast.CommentGroup) (res []*Directive)
type Range
    func NodeRange(n ast.Node) Range
    func RangeInStringLiteral(lit *ast.BasicLit, start, end int) (Range, error)
    func RangeOf(start, end token.Pos) Range
    func (r Range) Contains(rng Range) bool
    func (r Range) ContainsPos(pos token.Pos) bool
    func (r Range) End() token.Pos
    func (r Range) IsValid() bool
    func (r Range) Pos() token.Pos

Package files

clone.go comment.go cursor.go equal.go fields.go purge.go stringlit.go unpack.go util.go

func CloneNode

func CloneNode[T ast.Node](n T) T

CloneNode returns a deep copy of a Node. It omits pointers to ast.{Scope,Object} variables.

func Comments

func Comments(file *ast.File, start, end token.Pos) iter.Seq[*ast.Comment]

Comments returns an iterator over the comments overlapping the specified interval. Comments are sorted by position in the file, so we can use binary search.

func Deprecation

func Deprecation(doc *ast.CommentGroup) string

Deprecation returns the paragraph of the doc comment that starts with the conventional "Deprecation: " marker, as defined by https://go.dev/wiki/Deprecated, or "" if the documented symbol is not deprecated.

func DocComment

func DocComment(n ast.Node) *ast.CommentGroup

DocComment returns the doc comment for a node, if any.

func EnclosingFile

func EnclosingFile(c inspector.Cursor) *ast.File

EnclosingFile returns the syntax tree for the file enclosing c.

TODO(adonovan): promote this to a method of Cursor.

func Equal

func Equal(x, y ast.Node, identical func(x, y *ast.Ident) bool) bool

Equal reports whether two nodes are structurally equal, ignoring fields of type token.Pos, ast.Object, and ast.Scope, and comments.

The operands x and y may be nil. A nil slice is not equal to an empty slice.

The provided function determines whether two identifiers should be considered identical.

func EqualSyntax

func EqualSyntax(x, y ast.Expr) bool

EqualSyntax reports whether x and y are equal. Identifiers are considered equal if they are spelled the same. Comments are ignored.

func FlatFields

func FlatFields(list *ast.FieldList) iter.Seq2[*ast.Ident, *ast.Field]

FlatFields 'flattens' an ast.FieldList, returning an iterator over each (name, field) combination in the list. For unnamed fields, the identifier is nil.

func Format

func Format(fset *token.FileSet, n ast.Node) string

Format returns a string representation of the node n.

func MaybeParenthesize

func MaybeParenthesize(parentNode ast.Node, old, new ast.Expr) ast.Expr

MaybeParenthesize returns new, possibly wrapped in parens if needed to preserve operator precedence when it replaces old, whose parent is parentNode.

(This would be more naturally written in terms of Cursor, but one of the callers--the inliner--does not have cursors handy.)

func NodeContains

func NodeContains(n ast.Node, rng Range) bool

NodeContains reports whether the Pos/End range of node n encloses the given range.

It is inclusive of both end points, to allow hovering (etc) when the cursor is immediately after a node.

Like NodeRange, it treats the range of an ast.File as the file's complete extent.

Precondition: n must not be nil.

func NodeContainsPos

func NodeContainsPos(n ast.Node, pos token.Pos) bool

NodeContainsPos reports whether the Pos/End range of node n encloses the given pos.

Like NodeRange, it treats the range of an ast.File as the file's complete extent.

func OffsetInStringLiteral

func OffsetInStringLiteral(lit *ast.BasicLit, pos token.Pos) (int, error)

OffsetInStringLiteral returns the byte offset within the logical (unquoted) string corresponding to the specified source position.

func PosInStringLiteral

func PosInStringLiteral(lit *ast.BasicLit, offset int) (token.Pos, error)

PosInStringLiteral returns the position within a string literal corresponding to the specified byte offset within the logical string that it denotes.

func PurgeFuncBodies

func PurgeFuncBodies(src []byte) []byte

PurgeFuncBodies returns a copy of src in which the contents of each outermost {...} region have been deleted, except for struct and interface type bodies and the bodies of length-elided array literals ([...]T), whose element count is part of the type. It includes function bodies, function-literal bodies, and the bodies of slice, map, and explicitly-sized array composite literals (whose contents don't affect the type of the enclosing declaration). This reduces the amount of work required to parse the top-level declarations.

PurgeFuncBodies does not preserve newlines or position information. Also, if the input is invalid, parsing the output of PurgeFuncBodies may result in a different tree due to its effects on parser error recovery.

func Select

func Select(curFile inspector.Cursor, start, end token.Pos) (_enclosing, _start, _end inspector.Cursor, _ error)

Select returns the syntax nodes identified by a user's text selection. It returns three nodes: the innermost node that wholly encloses the selection; and the first and last nodes that are wholly enclosed by the selection.

For example, given this selection:

{ f(); g(); /* comment */ }
  ~~~~~~~~~~~

Select returns the enclosing BlockStmt, the f() CallExpr, and the g() CallExpr.

If the selection does not wholly enclose any nodes, Select returns an error and invalid start/end nodes, but it may return a valid enclosing node.

Callers that require exactly one syntax tree (e.g. just f() or just g()) should check that the returned start and end nodes are identical.

This function is intended to be called early in the handling of a user's request, since it is tolerant of sloppy selection including extraneous whitespace and comments. Use it in new code instead of PathEnclosingInterval. When the exact extent of a node is known, use [Cursor.FindByPos] instead.

TODO(hxjiang): Consider refactoring the function signature. It is currently confusing that an error is returned even when a valid enclosing node is successfully found. Consider grouping all cursors into one struct.

func UnpackRecv

func UnpackRecv(rtyp ast.Expr) (ptr bool, rname *ast.Ident, tparams []*ast.Ident)

UnpackRecv unpacks a receiver type expression, reporting whether it is a pointer receiver, along with the type name identifier and any receiver type parameter identifiers.

Copied (with modifications) from go/types.

func UnparenCursor

func UnparenCursor(cur inspector.Cursor) inspector.Cursor

UnparenCursor returns the cursor for an expression with any enclosing parentheses removed, similar to ast.Unparen. It is often prudent to call this before switching on the type of cur.Node().

See also UnparenEnclosingCursor.

func UnparenEnclosingCursor

func UnparenEnclosingCursor(cur inspector.Cursor) inspector.Cursor

UnparenEnclosingCursor returns the first element of the [Cursor.Enclosing] sequence that is not itself enclosed in parens. It is often prudent to call this before switching on cur.ParentEdge().

See also UnparenCursor.

type Directive

A directive is a comment line with special meaning to the Go toolchain or another tool. It has the form:

//tool:name args

The "tool:" portion is missing for the three directives named line, extern, and export.

See https://go.dev/doc/comment#Syntax for details of Go comment syntax and https://pkg.go.dev/cmd/compile#hdr-Compiler_Directives for details of directives used by the Go compiler.

type Directive struct {
    Pos  token.Pos // of preceding "//"
    Tool string
    Name string
    Args string // may contain internal spaces
}

func Directives

func Directives(g *ast.CommentGroup) (res []*Directive)

Directives returns the directives within the comment.

type Range

Range is a Pos interval. It implements [analysis.Range] and ast.Node.

type Range struct{ Start, EndPos token.Pos }

func NodeRange

func NodeRange(n ast.Node) Range

NodeRange returns the extent of node n as a Range.

For unfortunate historical reasons, the Pos/End extent of an ast.File runs from the start of its package declaration---excluding copyright comments, build tags, and package documentation---to the end of its last declaration, excluding any trailing comments. So, as a special case, if n is an ast.File, NodeContains uses n.FileStart <= pos && pos <= n.FileEnd to report whether the position lies anywhere within the file.

func RangeInStringLiteral

func RangeInStringLiteral(lit *ast.BasicLit, start, end int) (Range, error)

RangeInStringLiteral calculates the positional range within a string literal corresponding to the specified start and end byte offsets within the logical string.

func RangeOf

func RangeOf(start, end token.Pos) Range

RangeOf constructs a Range.

RangeOf exists to pacify the "unkeyed literal" (composites) vet check. It would be nice if there were a way for a type to add itself to the allowlist.

func (Range) Contains

func (r Range) Contains(rng Range) bool

Contains reports whether the range (inclusive of both end points) includes the specified range.

func (Range) ContainsPos

func (r Range) ContainsPos(pos token.Pos) bool

ContainsPos reports whether the range (inclusive of both end points) includes the specified position.

func (Range) End

func (r Range) End() token.Pos

func (Range) IsValid

func (r Range) IsValid() bool

IsValid reports whether the range is valid.

func (Range) Pos

func (r Range) Pos() token.Pos

Subdirectories

Name Synopsis
..