// Generated by Lisette bindgen
// Source: go/ast (Go stdlib)
// Go: 1.25.5
// Lisette: 0.1.11

import "go:go/token"
import "go:io"
import "go:iter"
import "go:reflect"

pub enum ObjKind: int {
  Bad = 0,
  Con = 2,
  Fun = 5,
  Lbl = 6,
  Pkg = 1,
  Typ = 3,
  Var = 4,
}

pub const Bad: ObjKind = 0

pub const Con: ObjKind = 2

pub const Fun: ObjKind = 5

pub const Lbl: ObjKind = 6

pub const Pkg: ObjKind = 1

pub const Typ: ObjKind = 3

pub const Var: ObjKind = 4

/// FileExports trims the AST for a Go source file in place such that
/// only exported nodes remain: all top-level identifiers which are not exported
/// and their associated information (such as type, initial value, or function
/// body) are removed. Non-exported fields and methods of exported types are
/// stripped. The [File.Comments] list is not changed.
/// 
/// FileExports reports whether there are exported declarations.
pub fn FileExports(src: Ref<File>) -> bool

/// FilterDecl trims the AST for a Go declaration in place by removing
/// all names (including struct field and interface method names, but
/// not from parameter lists) that don't pass through the filter f.
/// 
/// FilterDecl reports whether there are any declared names left after
/// filtering.
pub fn FilterDecl(decl: Decl, f: Filter) -> bool

/// FilterFile trims the AST for a Go file in place by removing all
/// names from top-level declarations (including struct field and
/// interface method names, but not from parameter lists) that don't
/// pass through the filter f. If the declaration is empty afterwards,
/// the declaration is removed from the AST. Import declarations are
/// always removed. The [File.Comments] list is not changed.
/// 
/// FilterFile reports whether there are any top-level declarations
/// left after filtering.
pub fn FilterFile(src: Ref<File>, f: Filter) -> bool

/// FilterPackage trims the AST for a Go package in place by removing
/// all names from top-level declarations (including struct field and
/// interface method names, but not from parameter lists) that don't
/// pass through the filter f. If the declaration is empty afterwards,
/// the declaration is removed from the AST. The pkg.Files list is not
/// changed, so that file names and top-level package comments don't get
/// lost.
/// 
/// FilterPackage reports whether there are any top-level declarations
/// left after filtering.
/// 
/// Deprecated: use the type checker [go/types] instead of [Package];
/// see [Object]. Alternatively, use [FilterFile].
pub fn FilterPackage(pkg: Ref<Package>, f: Filter) -> bool

/// 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.
pub fn Fprint(
  w: io.Writer,
  fset: Ref<token.FileSet>,
  x: Unknown,
  f: FieldFilter,
) -> Result<(), error>

/// 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).
/// 
/// In many cases it may be more convenient to use [Preorder], which
/// returns an iterator over the sqeuence of nodes, or [PreorderStack],
/// which (like [Inspect]) provides control over descent into subtrees,
/// but additionally reports the stack of enclosing nodes.
pub fn Inspect(node: Node, f: fn(Node) -> bool)

/// IsExported reports whether name starts with an upper-case letter.
pub fn IsExported(name: string) -> bool

/// IsGenerated reports whether the file was generated by a program,
/// not handwritten, by detecting the special comment described
/// at https://go.dev/s/generatedcode.
/// 
/// The syntax tree must have been parsed with the [parser.ParseComments] flag.
/// Example:
/// 
/// 	f, err := parser.ParseFile(fset, filename, src, parser.ParseComments|parser.PackageClauseOnly)
/// 	if err != nil { ... }
/// 	gen := ast.IsGenerated(f)
pub fn IsGenerated(file: Ref<File>) -> bool

pub fn MergePackageFiles(pkg: Ref<Package>, mode: MergeMode) -> Ref<File>

pub fn NewCommentMap(
  fset: Ref<token.FileSet>,
  node: Node,
  comments: Slice<Ref<CommentGroup>>,
) -> CommentMap

pub fn NewIdent(name: string) -> Ref<Ident>

pub fn NewObj(kind: ObjKind, name: string) -> Ref<Object>

pub fn NewPackage(
  fset: Ref<token.FileSet>,
  files: Map<string, Ref<File>>,
  importer: Importer,
  universe: Ref<Scope>,
) -> Result<Ref<Package>, error>

pub fn NewScope(outer: Ref<Scope>) -> Ref<Scope>

/// NotNilFilter is a [FieldFilter] that returns true for field values
/// that are not nil; it returns false otherwise.
pub fn NotNilFilter(_: string, v: reflect.Value) -> bool

/// PackageExports trims the AST for a Go package in place such that
/// only exported nodes remain. The pkg.Files list is not changed, so that
/// file names and top-level package comments don't get lost.
/// 
/// PackageExports reports whether there are exported declarations;
/// it returns false otherwise.
/// 
/// Deprecated: use the type checker [go/types] instead of [Package];
/// see [Object]. Alternatively, use [FileExports].
pub fn PackageExports(pkg: Ref<Package>) -> bool

/// Preorder returns an iterator over all the nodes of the syntax tree
/// beneath (and including) the specified root, in depth-first
/// preorder.
/// 
/// For greater control over the traversal of each subtree, use
/// [Inspect] or [PreorderStack].
pub fn Preorder(root: Node) -> iter.Seq<Node>

/// PreorderStack traverses the tree rooted at root,
/// calling f before visiting each node.
/// 
/// Each call to f provides the current node and traversal stack,
/// consisting of the original value of stack appended with all nodes
/// from root to n, excluding n itself. (This design allows calls
/// to PreorderStack to be nested without double counting.)
/// 
/// If f returns false, the traversal skips over that subtree. Unlike
/// [Inspect], no second call to f is made after visiting node n.
/// (In practice, the second call is nearly always used only to pop the
/// stack, and it is surprisingly tricky to do this correctly.)
pub fn PreorderStack(
  root: Node,
  stack: Slice<Node>,
  f: fn(Node, Slice<Node>) -> bool,
)

/// Print prints x to standard output, skipping nil fields.
/// Print(fset, x) is the same as Fprint(os.Stdout, fset, x, NotNilFilter).
pub fn Print(fset: Ref<token.FileSet>, x: Unknown) -> Result<(), error>

/// SortImports sorts runs of consecutive import lines in import blocks in f.
/// It also removes duplicate imports when it is possible to do so without data loss.
pub fn SortImports(fset: Ref<token.FileSet>, f: Ref<File>)

pub fn Unparen(e: Expr) -> Expr

/// 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).
pub fn Walk(v: Visitor, node: Node)

/// An ArrayType node represents an array or slice type.
pub struct ArrayType {
  pub Lbrack: token.Pos,
  pub Len: Option<Expr>,
  pub Elt: Option<Expr>,
}

/// An AssignStmt node represents an assignment or
/// a short variable declaration.
pub struct AssignStmt {
  pub Lhs: Slice<Option<Expr>>,
  pub TokPos: token.Pos,
  pub Tok: token.Token,
  pub Rhs: Slice<Option<Expr>>,
}

/// A BadDecl node is a placeholder for a declaration containing
/// syntax errors for which a correct declaration node cannot be
/// created.
pub struct BadDecl {
  pub From: token.Pos,
  pub To: token.Pos,
}

/// A BadExpr node is a placeholder for an expression containing
/// syntax errors for which a correct expression node cannot be
/// created.
pub struct BadExpr {
  pub From: token.Pos,
  pub To: token.Pos,
}

/// A BadStmt node is a placeholder for statements containing
/// syntax errors for which no correct statement nodes can be
/// created.
pub struct BadStmt {
  pub From: token.Pos,
  pub To: token.Pos,
}

/// A BasicLit node represents a literal of basic type.
/// 
/// Note that for the CHAR and STRING kinds, the literal is stored
/// with its quotes. For example, for a double-quoted STRING, the
/// first and the last rune in the Value field will be ". The
/// [strconv.Unquote] and [strconv.UnquoteChar] functions can be
/// used to unquote STRING and CHAR values, respectively.
/// 
/// For raw string literals (Kind == token.STRING && Value[0] == '`'),
/// the Value field contains the string text without carriage returns (\r) that
/// may have been present in the source. Because the end position is
/// computed using len(Value), the position reported by [BasicLit.End] does not match the
/// true source end position for raw string literals containing carriage returns.
pub struct BasicLit {
  pub ValuePos: token.Pos,
  pub Kind: token.Token,
  pub Value: string,
}

/// A BinaryExpr node represents a binary expression.
pub struct BinaryExpr {
  pub X: Option<Expr>,
  pub OpPos: token.Pos,
  pub Op: token.Token,
  pub Y: Option<Expr>,
}

/// A BlockStmt node represents a braced statement list.
pub struct BlockStmt {
  pub Lbrace: token.Pos,
  pub List: Slice<Option<Stmt>>,
  pub Rbrace: token.Pos,
}

/// A BranchStmt node represents a break, continue, goto,
/// or fallthrough statement.
pub struct BranchStmt {
  pub TokPos: token.Pos,
  pub Tok: token.Token,
  pub Label: Option<Ref<Ident>>,
}

/// A CallExpr node represents an expression followed by an argument list.
pub struct CallExpr {
  pub Fun: Option<Expr>,
  pub Lparen: token.Pos,
  pub Args: Slice<Option<Expr>>,
  pub Ellipsis: token.Pos,
  pub Rparen: token.Pos,
}

/// A CaseClause represents a case of an expression or type switch statement.
pub struct CaseClause {
  pub Case: token.Pos,
  pub List: Slice<Option<Expr>>,
  pub Colon: token.Pos,
  pub Body: Slice<Option<Stmt>>,
}

/// The direction of a channel type is indicated by a bit
/// mask including one or both of the following constants.
pub struct ChanDir(int)

/// A ChanType node represents a channel type.
pub struct ChanType {
  pub Begin: token.Pos,
  pub Arrow: token.Pos,
  pub Dir: ChanDir,
  pub Value: Option<Expr>,
}

/// A CommClause node represents a case of a select statement.
pub struct CommClause {
  pub Case: token.Pos,
  pub Comm: Option<Stmt>,
  pub Colon: token.Pos,
  pub Body: Slice<Option<Stmt>>,
}

/// A Comment node represents a single //-style or /*-style comment.
/// 
/// The Text field contains the comment text without carriage returns (\r) that
/// may have been present in the source. Because a comment's end position is
/// computed using len(Text), the position reported by [Comment.End] does not match the
/// true source end position for comments containing carriage returns.
pub struct Comment {
  pub Slash: token.Pos,
  pub Text: string,
}

/// A CommentGroup represents a sequence of comments
/// with no other tokens and no empty lines between.
pub struct CommentGroup {
  pub List: Slice<Option<Ref<Comment>>>,
}

/// A CommentMap maps an AST node to a list of comment groups
/// associated with it. See [NewCommentMap] for a description of
/// the association.
pub struct CommentMap(Map<Node, Slice<Ref<CommentGroup>>>)

/// A CompositeLit node represents a composite literal.
pub struct CompositeLit {
  pub Type: Option<Expr>,
  pub Lbrace: token.Pos,
  pub Elts: Slice<Option<Expr>>,
  pub Rbrace: token.Pos,
  pub Incomplete: bool,
}

/// All declaration nodes implement the Decl interface.
pub interface Decl {
  fn End() -> token.Pos
  fn Pos() -> token.Pos
}

/// A DeclStmt node represents a declaration in a statement list.
pub struct DeclStmt {
  pub Decl: Option<Decl>,
}

/// A DeferStmt node represents a defer statement.
pub struct DeferStmt {
  pub Defer: token.Pos,
  pub Call: Option<Ref<CallExpr>>,
}

/// An Ellipsis node stands for the "..." type in a
/// parameter list or the "..." length in an array type.
pub struct Ellipsis {
  pub Ellipsis: token.Pos,
  pub Elt: Option<Expr>,
}

/// An EmptyStmt node represents an empty statement.
/// The "position" of the empty statement is the position
/// of the immediately following (explicit or implicit) semicolon.
pub struct EmptyStmt {
  pub Semicolon: token.Pos,
  pub Implicit: bool,
}

/// All expression nodes implement the Expr interface.
pub interface Expr {
  fn End() -> token.Pos
  fn Pos() -> token.Pos
}

/// An ExprStmt node represents a (stand-alone) expression
/// in a statement list.
pub struct ExprStmt {
  pub X: Option<Expr>,
}

/// 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.
pub struct Field {
  pub Doc: Option<Ref<CommentGroup>>,
  pub Names: Slice<Option<Ref<Ident>>>,
  pub Type: Option<Expr>,
  pub Tag: Option<Ref<BasicLit>>,
  pub Comment: Option<Ref<CommentGroup>>,
}

/// A FieldFilter may be provided to [Fprint] to control the output.
pub type FieldFilter = fn(string, reflect.Value) -> bool

/// A FieldList represents a list of Fields, enclosed by parentheses,
/// curly braces, or square brackets.
pub struct FieldList {
  pub Opening: token.Pos,
  pub List: Slice<Option<Ref<Field>>>,
  pub Closing: token.Pos,
}

/// 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]).
/// 
/// [#18593]: https://go.dev/issue/18593
/// [#20744]: https://go.dev/issue/20744
pub struct File {
  pub Doc: Option<Ref<CommentGroup>>,
  pub Package: token.Pos,
  pub Name: Option<Ref<Ident>>,
  pub Decls: Slice<Option<Decl>>,
  pub FileStart: token.Pos,
  pub FileEnd: token.Pos,
  pub Scope: Option<Ref<Scope>>,
  pub Imports: Slice<Option<Ref<ImportSpec>>>,
  pub Unresolved: Slice<Option<Ref<Ident>>>,
  pub Comments: Slice<Option<Ref<CommentGroup>>>,
  pub GoVersion: string,
}

pub type Filter = fn(string) -> bool

/// A ForStmt represents a for statement.
pub struct ForStmt {
  pub For: token.Pos,
  pub Init: Option<Stmt>,
  pub Cond: Option<Expr>,
  pub Post: Option<Stmt>,
  pub Body: Option<Ref<BlockStmt>>,
}

/// A FuncDecl node represents a function declaration.
pub struct FuncDecl {
  pub Doc: Option<Ref<CommentGroup>>,
  pub Recv: Option<Ref<FieldList>>,
  pub Name: Option<Ref<Ident>>,
  pub Type: Option<Ref<FuncType>>,
  pub Body: Option<Ref<BlockStmt>>,
}

/// A FuncLit node represents a function literal.
pub struct FuncLit {
  pub Type: Option<Ref<FuncType>>,
  pub Body: Option<Ref<BlockStmt>>,
}

/// A FuncType node represents a function type.
pub struct FuncType {
  pub Func: token.Pos,
  pub TypeParams: Option<Ref<FieldList>>,
  pub Params: Option<Ref<FieldList>>,
  pub Results: Option<Ref<FieldList>>,
}

/// 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
pub struct GenDecl {
  pub Doc: Option<Ref<CommentGroup>>,
  pub TokPos: token.Pos,
  pub Tok: token.Token,
  pub Lparen: token.Pos,
  pub Specs: Slice<Option<Spec>>,
  pub Rparen: token.Pos,
}

/// A GoStmt node represents a go statement.
pub struct GoStmt {
  pub Go: token.Pos,
  pub Call: Option<Ref<CallExpr>>,
}

/// An Ident node represents an identifier.
pub struct Ident {
  pub NamePos: token.Pos,
  pub Name: string,
  pub Obj: Option<Ref<Object>>,
}

/// An IfStmt node represents an if statement.
pub struct IfStmt {
  pub If: token.Pos,
  pub Init: Option<Stmt>,
  pub Cond: Option<Expr>,
  pub Body: Option<Ref<BlockStmt>>,
  pub Else: Option<Stmt>,
}

/// An ImportSpec node represents a single package import.
pub struct ImportSpec {
  pub Doc: Option<Ref<CommentGroup>>,
  pub Name: Option<Ref<Ident>>,
  pub Path: Option<Ref<BasicLit>>,
  pub Comment: Option<Ref<CommentGroup>>,
  pub EndPos: token.Pos,
}

/// 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.
/// 
/// Deprecated: use the type checker [go/types] instead; see [Object].
pub type Importer = fn(Map<string, Ref<Object>>, string) -> Result<Ref<Object>, error>

/// An IncDecStmt node represents an increment or decrement statement.
pub struct IncDecStmt {
  pub X: Option<Expr>,
  pub TokPos: token.Pos,
  pub Tok: token.Token,
}

/// An IndexExpr node represents an expression followed by an index.
pub struct IndexExpr {
  pub X: Option<Expr>,
  pub Lbrack: token.Pos,
  pub Index: Option<Expr>,
  pub Rbrack: token.Pos,
}

/// An IndexListExpr node represents an expression followed by multiple
/// indices.
pub struct IndexListExpr {
  pub X: Option<Expr>,
  pub Lbrack: token.Pos,
  pub Indices: Slice<Option<Expr>>,
  pub Rbrack: token.Pos,
}

/// An InterfaceType node represents an interface type.
pub struct InterfaceType {
  pub Interface: token.Pos,
  pub Methods: Option<Ref<FieldList>>,
  pub Incomplete: bool,
}

/// A KeyValueExpr node represents (key : value) pairs
/// in composite literals.
pub struct KeyValueExpr {
  pub Key: Option<Expr>,
  pub Colon: token.Pos,
  pub Value: Option<Expr>,
}

/// A LabeledStmt node represents a labeled statement.
pub struct LabeledStmt {
  pub Label: Option<Ref<Ident>>,
  pub Colon: token.Pos,
  pub Stmt: Option<Stmt>,
}

/// A MapType node represents a map type.
pub struct MapType {
  pub Map: token.Pos,
  pub Key: Option<Expr>,
  pub Value: Option<Expr>,
}

/// The MergeMode flags control the behavior of [MergePackageFiles].
/// 
/// Deprecated: use the type checker [go/types] instead of [Package];
/// see [Object].
pub struct MergeMode(uint)

/// All node types implement the Node interface.
pub interface Node {
  fn End() -> token.Pos
  fn Pos() -> token.Pos
}

/// 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
/// 
/// Deprecated: The relationship between Idents and Objects cannot be
/// correctly computed without type information. For example, the
/// expression T{K: 0} may denote a struct, map, slice, or array
/// literal, depending on the type of T. If T is a struct, then K
/// refers to a field of T, whereas for the other types it refers to a
/// value in the environment.
/// 
/// New programs should set the [parser.SkipObjectResolution] parser
/// flag to disable syntactic object resolution (which also saves CPU
/// and memory), and instead use the type checker [go/types] if object
/// resolution is desired. See the Defs, Uses, and Implicits fields of
/// the [types.Info] struct for details.
pub struct Object {
  pub Kind: ObjKind,
  pub Name: string,
  pub Decl: Unknown,
  pub Data: Unknown,
  pub Type: Unknown,
}

/// A Package node represents a set of source files
/// collectively building a Go package.
/// 
/// Deprecated: use the type checker [go/types] instead; see [Object].
pub struct Package {
  pub Name: string,
  pub Scope: Option<Ref<Scope>>,
  pub Imports: Map<string, Option<Ref<Object>>>,
  pub Files: Map<string, Option<Ref<File>>>,
}

/// A ParenExpr node represents a parenthesized expression.
pub struct ParenExpr {
  pub Lparen: token.Pos,
  pub X: Option<Expr>,
  pub Rparen: token.Pos,
}

/// A RangeStmt represents a for statement with a range clause.
pub struct RangeStmt {
  pub For: token.Pos,
  pub Key: Option<Expr>,
  pub Value: Option<Expr>,
  pub TokPos: token.Pos,
  pub Tok: token.Token,
  pub Range: token.Pos,
  pub X: Option<Expr>,
  pub Body: Option<Ref<BlockStmt>>,
}

/// A ReturnStmt node represents a return statement.
pub struct ReturnStmt {
  pub Return: token.Pos,
  pub Results: Slice<Option<Expr>>,
}

/// A Scope maintains the set of named language entities declared
/// in the scope and a link to the immediately surrounding (outer)
/// scope.
/// 
/// Deprecated: use the type checker [go/types] instead; see [Object].
pub struct Scope {
  pub Outer: Option<Ref<Scope>>,
  pub Objects: Map<string, Option<Ref<Object>>>,
}

/// A SelectStmt node represents a select statement.
pub struct SelectStmt {
  pub Select: token.Pos,
  pub Body: Option<Ref<BlockStmt>>,
}

/// A SelectorExpr node represents an expression followed by a selector.
pub struct SelectorExpr {
  pub X: Option<Expr>,
  pub Sel: Option<Ref<Ident>>,
}

/// A SendStmt node represents a send statement.
pub struct SendStmt {
  pub Chan: Option<Expr>,
  pub Arrow: token.Pos,
  pub Value: Option<Expr>,
}

/// A SliceExpr node represents an expression followed by slice indices.
pub struct SliceExpr {
  pub X: Option<Expr>,
  pub Lbrack: token.Pos,
  pub Low: Option<Expr>,
  pub High: Option<Expr>,
  pub Max: Option<Expr>,
  pub Slice3: bool,
  pub Rbrack: token.Pos,
}

/// The Spec type stands for any of *ImportSpec, *ValueSpec, and *TypeSpec.
pub interface Spec {
  fn End() -> token.Pos
  fn Pos() -> token.Pos
}

/// A StarExpr node represents an expression of the form "*" Expression.
/// Semantically it could be a unary "*" expression, or a pointer type.
pub struct StarExpr {
  pub Star: token.Pos,
  pub X: Option<Expr>,
}

/// All statement nodes implement the Stmt interface.
pub interface Stmt {
  fn End() -> token.Pos
  fn Pos() -> token.Pos
}

/// A StructType node represents a struct type.
pub struct StructType {
  pub Struct: token.Pos,
  pub Fields: Option<Ref<FieldList>>,
  pub Incomplete: bool,
}

/// A SwitchStmt node represents an expression switch statement.
pub struct SwitchStmt {
  pub Switch: token.Pos,
  pub Init: Option<Stmt>,
  pub Tag: Option<Expr>,
  pub Body: Option<Ref<BlockStmt>>,
}

/// A TypeAssertExpr node represents an expression followed by a
/// type assertion.
pub struct TypeAssertExpr {
  pub X: Option<Expr>,
  pub Lparen: token.Pos,
  pub Type: Option<Expr>,
  pub Rparen: token.Pos,
}

/// A TypeSpec node represents a type declaration (TypeSpec production).
pub struct TypeSpec {
  pub Doc: Option<Ref<CommentGroup>>,
  pub Name: Option<Ref<Ident>>,
  pub TypeParams: Option<Ref<FieldList>>,
  pub Assign: token.Pos,
  pub Type: Option<Expr>,
  pub Comment: Option<Ref<CommentGroup>>,
}

/// A TypeSwitchStmt node represents a type switch statement.
pub struct TypeSwitchStmt {
  pub Switch: token.Pos,
  pub Init: Option<Stmt>,
  pub Assign: Option<Stmt>,
  pub Body: Option<Ref<BlockStmt>>,
}

/// A UnaryExpr node represents a unary expression.
/// Unary "*" expressions are represented via StarExpr nodes.
pub struct UnaryExpr {
  pub OpPos: token.Pos,
  pub Op: token.Token,
  pub X: Option<Expr>,
}

/// A ValueSpec node represents a constant or variable declaration
/// (ConstSpec or VarSpec production).
pub struct ValueSpec {
  pub Doc: Option<Ref<CommentGroup>>,
  pub Names: Slice<Option<Ref<Ident>>>,
  pub Type: Option<Expr>,
  pub Values: Slice<Option<Expr>>,
  pub Comment: Option<Ref<CommentGroup>>,
}

/// 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).
pub interface Visitor {
  fn Visit(node: Node) -> Visitor
}

const FilterFuncDuplicates: MergeMode = 1

const FilterImportDuplicates: MergeMode = 4

const FilterUnassociatedComments: MergeMode = 2

const RECV: ChanDir = 2

const SEND: ChanDir = 1

impl ArrayType {
  fn End(self: Ref<ArrayType>) -> token.Pos

  fn Pos(self: Ref<ArrayType>) -> token.Pos
}

impl AssignStmt {
  fn End(self: Ref<AssignStmt>) -> token.Pos

  fn Pos(self: Ref<AssignStmt>) -> token.Pos
}

impl BadDecl {
  fn End(self: Ref<BadDecl>) -> token.Pos

  fn Pos(self: Ref<BadDecl>) -> token.Pos
}

impl BadExpr {
  fn End(self: Ref<BadExpr>) -> token.Pos

  fn Pos(self: Ref<BadExpr>) -> token.Pos
}

impl BadStmt {
  fn End(self: Ref<BadStmt>) -> token.Pos

  fn Pos(self: Ref<BadStmt>) -> token.Pos
}

impl BasicLit {
  fn End(self: Ref<BasicLit>) -> token.Pos

  fn Pos(self: Ref<BasicLit>) -> token.Pos
}

impl BinaryExpr {
  fn End(self: Ref<BinaryExpr>) -> token.Pos

  fn Pos(self: Ref<BinaryExpr>) -> token.Pos
}

impl BlockStmt {
  fn End(self: Ref<BlockStmt>) -> token.Pos

  fn Pos(self: Ref<BlockStmt>) -> token.Pos
}

impl BranchStmt {
  fn End(self: Ref<BranchStmt>) -> token.Pos

  fn Pos(self: Ref<BranchStmt>) -> token.Pos
}

impl CallExpr {
  fn End(self: Ref<CallExpr>) -> token.Pos

  fn Pos(self: Ref<CallExpr>) -> token.Pos
}

impl CaseClause {
  fn End(self: Ref<CaseClause>) -> token.Pos

  fn Pos(self: Ref<CaseClause>) -> token.Pos
}

impl ChanType {
  fn End(self: Ref<ChanType>) -> token.Pos

  fn Pos(self: Ref<ChanType>) -> token.Pos
}

impl CommClause {
  fn End(self: Ref<CommClause>) -> token.Pos

  fn Pos(self: Ref<CommClause>) -> token.Pos
}

impl Comment {
  fn End(self: Ref<Comment>) -> token.Pos

  fn Pos(self: Ref<Comment>) -> token.Pos
}

impl CommentGroup {
  fn End(self: Ref<CommentGroup>) -> token.Pos

  fn Pos(self: Ref<CommentGroup>) -> token.Pos

  /// Text returns the text of the comment.
  /// Comment markers (//, /*, and */), the first space of a line comment, and
  /// leading and trailing empty lines are removed.
  /// Comment directives like "//line" and "//go:noinline" are also removed.
  /// Multiple empty lines are reduced to one, and trailing space on lines is trimmed.
  /// Unless the result is empty, it is newline-terminated.
  fn Text(self: Ref<CommentGroup>) -> string
}

impl CommentMap {
  /// Comments returns the list of comment groups in the comment map.
  /// The result is sorted in source order.
  fn Comments(self) -> Slice<Ref<CommentGroup>>

  /// Filter returns a new comment map consisting of only those
  /// entries of cmap for which a corresponding node exists in
  /// the AST specified by node.
  fn Filter(self, node: Node) -> CommentMap

  fn String(self) -> string

  /// Update replaces an old node in the comment map with the new node
  /// and returns the new node. Comments that were associated with the
  /// old node are associated with the new node.
  fn Update(self, old: Node, new: Node) -> Node
}

impl CompositeLit {
  fn End(self: Ref<CompositeLit>) -> token.Pos

  fn Pos(self: Ref<CompositeLit>) -> token.Pos
}

impl DeclStmt {
  fn End(self: Ref<DeclStmt>) -> token.Pos

  fn Pos(self: Ref<DeclStmt>) -> token.Pos
}

impl DeferStmt {
  fn End(self: Ref<DeferStmt>) -> token.Pos

  fn Pos(self: Ref<DeferStmt>) -> token.Pos
}

impl Ellipsis {
  fn End(self: Ref<Ellipsis>) -> token.Pos

  fn Pos(self: Ref<Ellipsis>) -> token.Pos
}

impl EmptyStmt {
  fn End(self: Ref<EmptyStmt>) -> token.Pos

  fn Pos(self: Ref<EmptyStmt>) -> token.Pos
}

impl ExprStmt {
  fn End(self: Ref<ExprStmt>) -> token.Pos

  fn Pos(self: Ref<ExprStmt>) -> token.Pos
}

impl Field {
  fn End(self: Ref<Field>) -> token.Pos

  fn Pos(self: Ref<Field>) -> token.Pos
}

impl FieldList {
  fn End(self: Ref<FieldList>) -> token.Pos

  /// NumFields returns the number of parameters or struct fields represented by a [FieldList].
  fn NumFields(self: Ref<FieldList>) -> int

  fn Pos(self: Ref<FieldList>) -> token.Pos
}

impl File {
  /// End returns the end of the last declaration in the file.
  /// It may be invalid, for example in an empty file.
  /// 
  /// (Use FileEnd for the end of the entire file. It is always valid.)
  fn End(self: Ref<File>) -> token.Pos

  /// Pos returns the position of the package declaration.
  /// It may be invalid, for example in an empty file.
  /// 
  /// (Use FileStart for the start of the entire file. It is always valid.)
  fn Pos(self: Ref<File>) -> token.Pos
}

impl ForStmt {
  fn End(self: Ref<ForStmt>) -> token.Pos

  fn Pos(self: Ref<ForStmt>) -> token.Pos
}

impl FuncDecl {
  fn End(self: Ref<FuncDecl>) -> token.Pos

  fn Pos(self: Ref<FuncDecl>) -> token.Pos
}

impl FuncLit {
  fn End(self: Ref<FuncLit>) -> token.Pos

  fn Pos(self: Ref<FuncLit>) -> token.Pos
}

impl FuncType {
  fn End(self: Ref<FuncType>) -> token.Pos

  fn Pos(self: Ref<FuncType>) -> token.Pos
}

impl GenDecl {
  fn End(self: Ref<GenDecl>) -> token.Pos

  fn Pos(self: Ref<GenDecl>) -> token.Pos
}

impl GoStmt {
  fn End(self: Ref<GoStmt>) -> token.Pos

  fn Pos(self: Ref<GoStmt>) -> token.Pos
}

impl Ident {
  fn End(self: Ref<Ident>) -> token.Pos

  /// IsExported reports whether id starts with an upper-case letter.
  fn IsExported(self: Ref<Ident>) -> bool

  fn Pos(self: Ref<Ident>) -> token.Pos

  fn String(self: Ref<Ident>) -> string
}

impl IfStmt {
  fn End(self: Ref<IfStmt>) -> token.Pos

  fn Pos(self: Ref<IfStmt>) -> token.Pos
}

impl ImportSpec {
  fn End(self: Ref<ImportSpec>) -> token.Pos

  fn Pos(self: Ref<ImportSpec>) -> token.Pos
}

impl IncDecStmt {
  fn End(self: Ref<IncDecStmt>) -> token.Pos

  fn Pos(self: Ref<IncDecStmt>) -> token.Pos
}

impl IndexExpr {
  fn End(self: Ref<IndexExpr>) -> token.Pos

  fn Pos(self: Ref<IndexExpr>) -> token.Pos
}

impl IndexListExpr {
  fn End(self: Ref<IndexListExpr>) -> token.Pos

  fn Pos(self: Ref<IndexListExpr>) -> token.Pos
}

impl InterfaceType {
  fn End(self: Ref<InterfaceType>) -> token.Pos

  fn Pos(self: Ref<InterfaceType>) -> token.Pos
}

impl KeyValueExpr {
  fn End(self: Ref<KeyValueExpr>) -> token.Pos

  fn Pos(self: Ref<KeyValueExpr>) -> token.Pos
}

impl LabeledStmt {
  fn End(self: Ref<LabeledStmt>) -> token.Pos

  fn Pos(self: Ref<LabeledStmt>) -> token.Pos
}

impl MapType {
  fn End(self: Ref<MapType>) -> token.Pos

  fn Pos(self: Ref<MapType>) -> token.Pos
}

impl ObjKind {
  fn String(self) -> string
}

impl Object {
  /// Pos computes the source position of the declaration of an object name.
  /// The result may be an invalid position if it cannot be computed
  /// (obj.Decl may be nil or not correct).
  fn Pos(self: Ref<Object>) -> token.Pos
}

impl Package {
  fn End(self: Ref<Package>) -> token.Pos

  fn Pos(self: Ref<Package>) -> token.Pos
}

impl ParenExpr {
  fn End(self: Ref<ParenExpr>) -> token.Pos

  fn Pos(self: Ref<ParenExpr>) -> token.Pos
}

impl RangeStmt {
  fn End(self: Ref<RangeStmt>) -> token.Pos

  fn Pos(self: Ref<RangeStmt>) -> token.Pos
}

impl ReturnStmt {
  fn End(self: Ref<ReturnStmt>) -> token.Pos

  fn Pos(self: Ref<ReturnStmt>) -> token.Pos
}

impl Scope {
  /// 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.
  fn Insert(self: Ref<Scope>, obj: Ref<Object>) -> Option<Ref<Object>>

  /// Lookup returns the object with the given name if it is
  /// found in scope s, otherwise it returns nil. Outer scopes
  /// are ignored.
  fn Lookup(self: Ref<Scope>, name: string) -> Option<Ref<Object>>

  /// Debugging support
  fn String(self: Ref<Scope>) -> string
}

impl SelectStmt {
  fn End(self: Ref<SelectStmt>) -> token.Pos

  fn Pos(self: Ref<SelectStmt>) -> token.Pos
}

impl SelectorExpr {
  fn End(self: Ref<SelectorExpr>) -> token.Pos

  fn Pos(self: Ref<SelectorExpr>) -> token.Pos
}

impl SendStmt {
  fn End(self: Ref<SendStmt>) -> token.Pos

  fn Pos(self: Ref<SendStmt>) -> token.Pos
}

impl SliceExpr {
  fn End(self: Ref<SliceExpr>) -> token.Pos

  fn Pos(self: Ref<SliceExpr>) -> token.Pos
}

impl StarExpr {
  fn End(self: Ref<StarExpr>) -> token.Pos

  fn Pos(self: Ref<StarExpr>) -> token.Pos
}

impl StructType {
  fn End(self: Ref<StructType>) -> token.Pos

  fn Pos(self: Ref<StructType>) -> token.Pos
}

impl SwitchStmt {
  fn End(self: Ref<SwitchStmt>) -> token.Pos

  fn Pos(self: Ref<SwitchStmt>) -> token.Pos
}

impl TypeAssertExpr {
  fn End(self: Ref<TypeAssertExpr>) -> token.Pos

  fn Pos(self: Ref<TypeAssertExpr>) -> token.Pos
}

impl TypeSpec {
  fn End(self: Ref<TypeSpec>) -> token.Pos

  fn Pos(self: Ref<TypeSpec>) -> token.Pos
}

impl TypeSwitchStmt {
  fn End(self: Ref<TypeSwitchStmt>) -> token.Pos

  fn Pos(self: Ref<TypeSwitchStmt>) -> token.Pos
}

impl UnaryExpr {
  fn End(self: Ref<UnaryExpr>) -> token.Pos

  fn Pos(self: Ref<UnaryExpr>) -> token.Pos
}

impl ValueSpec {
  fn End(self: Ref<ValueSpec>) -> token.Pos

  fn Pos(self: Ref<ValueSpec>) -> token.Pos
}
