const maxNewlines … const debug … const infinity … type whiteSpace … const ignore … const blank … const vtab … const newline … const formfeed … const indent … const unindent … type pmode … const noExtraBlank … const noExtraLinebreak … type commentInfo … type printer … func (p *printer) internalError(msg ...any) { … } // commentsHaveNewline reports whether a list of comments belonging to // an *ast.CommentGroup contains newlines. Because the position information // may only be partially correct, we also have to read the comment text. func (p *printer) commentsHaveNewline(list []*ast.Comment) bool { … } func (p *printer) nextComment() { … } // commentBefore reports whether the current comment group occurs // before the next position in the source code and printing it does // not introduce implicit semicolons. func (p *printer) commentBefore(next token.Position) bool { … } // commentSizeBefore returns the estimated size of the // comments on the same line before the next position. func (p *printer) commentSizeBefore(next token.Position) int { … } // recordLine records the output line number for the next non-whitespace // token in *linePtr. It is used to compute an accurate line number for a // formatted construct, independent of pending (not yet emitted) whitespace // or comments. func (p *printer) recordLine(linePtr *int) { … } // linesFrom returns the number of output lines between the current // output line and the line argument, ignoring any pending (not yet // emitted) whitespace or comments. It is used to compute an accurate // size (in number of lines) for a formatted construct. func (p *printer) linesFrom(line int) int { … } func (p *printer) posFor(pos token.Pos) token.Position { … } func (p *printer) lineFor(pos token.Pos) int { … } // writeLineDirective writes a //line directive if necessary. func (p *printer) writeLineDirective(pos token.Position) { … } // writeIndent writes indentation. func (p *printer) writeIndent() { … } // writeByte writes ch n times to p.output and updates p.pos. // Only used to write formatting (white space) characters. func (p *printer) writeByte(ch byte, n int) { … } // writeString writes the string s to p.output and updates p.pos, p.out, // and p.last. If isLit is set, s is escaped w/ tabwriter.Escape characters // to protect s from being interpreted by the tabwriter. // // Note: writeString is only used to write Go tokens, literals, and // comments, all of which must be written literally. Thus, it is correct // to always set isLit = true. However, setting it explicitly only when // needed (i.e., when we don't know that s contains no tabs or line breaks) // avoids processing extra escape characters and reduces run time of the // printer benchmark by up to 10%. func (p *printer) writeString(pos token.Position, s string, isLit bool) { … } // writeCommentPrefix writes the whitespace before a comment. // If there is any pending whitespace, it consumes as much of // it as is likely to help position the comment nicely. // pos is the comment position, next the position of the item // after all pending comments, prev is the previous comment in // a group of comments (or nil), and tok is the next token. func (p *printer) writeCommentPrefix(pos, next token.Position, prev *ast.Comment, tok token.Token) { … } // Returns true if s contains only white space // (only tabs and blanks can appear in the printer's context). func isBlank(s string) bool { … } // commonPrefix returns the common prefix of a and b. func commonPrefix(a, b string) string { … } // trimRight returns s with trailing whitespace removed. func trimRight(s string) string { … } // stripCommonPrefix removes a common prefix from /*-style comment lines (unless no // comment line is indented, all but the first line have some form of space prefix). // The prefix is computed using heuristics such that is likely that the comment // contents are nicely laid out after re-printing each line using the printer's // current indentation. func stripCommonPrefix(lines []string) { … } func (p *printer) writeComment(comment *ast.Comment) { … } // writeCommentSuffix writes a line break after a comment if indicated // and processes any leftover indentation information. If a line break // is needed, the kind of break (newline vs formfeed) depends on the // pending whitespace. The writeCommentSuffix result indicates if a // newline was written or if a formfeed was dropped from the whitespace // buffer. func (p *printer) writeCommentSuffix(needsLinebreak bool) (wroteNewline, droppedFF bool) { … } // containsLinebreak reports whether the whitespace buffer contains any line breaks. func (p *printer) containsLinebreak() bool { … } // intersperseComments consumes all comments that appear before the next token // tok and prints it together with the buffered whitespace (i.e., the whitespace // that needs to be written before the next token). A heuristic is used to mix // the comments and whitespace. The intersperseComments result indicates if a // newline was written or if a formfeed was dropped from the whitespace buffer. func (p *printer) intersperseComments(next token.Position, tok token.Token) (wroteNewline, droppedFF bool) { … } // writeWhitespace writes the first n whitespace entries. func (p *printer) writeWhitespace(n int) { … } // nlimit limits n to maxNewlines. func nlimit(n int) int { … } func mayCombine(prev token.Token, next byte) (b bool) { … } func (p *printer) setPos(pos token.Pos) { … } // print prints a list of "items" (roughly corresponding to syntactic // tokens, but also including whitespace and formatting information). // It is the only print function that should be called directly from // any of the AST printing functions in nodes.go. // // Whitespace is accumulated until a non-whitespace token appears. Any // comments that need to appear before that token are printed first, // taking into account the amount and structure of any pending white- // space for best comment placement. Then, any leftover whitespace is // printed, followed by the actual token. func (p *printer) print(args ...any) { … } // flush prints any pending comments and whitespace occurring textually // before the position of the next token tok. The flush result indicates // if a newline was written or if a formfeed was dropped from the whitespace // buffer. func (p *printer) flush(next token.Position, tok token.Token) (wroteNewline, droppedFF bool) { … } // getDoc returns the ast.CommentGroup associated with n, if any. func getDoc(n ast.Node) *ast.CommentGroup { … } func getLastComment(n ast.Node) *ast.CommentGroup { … } func (p *printer) printNode(node any) error { … } type trimmer … const inSpace … const inEscape … const inText … func (p *trimmer) resetSpace() { … } var aNewline … func (p *trimmer) Write(data []byte) (n int, err error) { … } type Mode … const RawFormat … const TabIndent … const UseSpaces … const SourcePos … const normalizeNumbers … type Config … var printerPool … func newPrinter(cfg *Config, fset *token.FileSet, nodeSizes map[ast.Node]int) *printer { … } func (p *printer) free() { … } // fprint implements Fprint and takes a nodesSizes map for setting up the printer state. func (cfg *Config) fprint(output io.Writer, fset *token.FileSet, node any, nodeSizes map[ast.Node]int) (err error) { … } type CommentedNode … // Fprint "pretty-prints" an AST node to output for a given configuration cfg. // Position information is interpreted relative to the file set fset. // The node type must be *[ast.File], *[CommentedNode], [][ast.Decl], [][ast.Stmt], // or assignment-compatible to [ast.Expr], [ast.Decl], [ast.Spec], or [ast.Stmt]. func (cfg *Config) Fprint(output io.Writer, fset *token.FileSet, node any) error { … } // Fprint "pretty-prints" an AST node to output. // It calls [Config.Fprint] with default settings. // Note that gofmt uses tabs for indentation but spaces for alignment; // use format.Node (package go/format) for output that matches gofmt. func Fprint(output io.Writer, fset *token.FileSet, node any) error { … }