package printer
import (
)
func ( *printer) (, int, whiteSpace, bool) ( int) {
:= nlimit( - .pos.Line)
if < {
=
}
if > 0 {
.print()
if {
.print(formfeed)
--
= 2
}
+=
for ; > 0; -- {
.print(newline)
}
}
return
}
func ( *printer) ( *ast.CommentGroup) {
if == nil || !.useNodeComments {
return
}
if .comments == nil {
.comments = make([]*ast.CommentGroup, 1)
} else if .cindex < len(.comments) {
.flush(.posFor(.List[0].Pos()), token.ILLEGAL)
.comments = .comments[0:1]
.internalError("setComment found pending comments")
}
.comments[0] =
.cindex = 0
if .commentOffset == infinity {
.nextComment()
}
}
type exprListMode uint
const (
commaTerm exprListMode = 1 << iota
noIndent
)
func ( *printer) ( []*ast.Ident, bool) {
:= make([]ast.Expr, len())
for , := range {
[] =
}
var exprListMode
if ! {
= noIndent
}
.exprList(token.NoPos, , 1, , token.NoPos, false)
}
const filteredMsg = "contains filtered or unexported fields"
func ( *printer) ( token.Pos, []ast.Expr, int, exprListMode, token.Pos, bool) {
if len() == 0 {
if {
:= .posFor()
:= .posFor()
if .IsValid() && .Line == .Line {
.print("/* " + filteredMsg + " */")
} else {
.print(newline)
.print(indent, "// "+filteredMsg, unindent, newline)
}
}
return
}
:= .posFor()
:= .posFor()
:= .lineFor([0].Pos())
:= .lineFor([len()-1].End())
if .IsValid() && .Line == && == {
for , := range {
if > 0 {
.print(.Pos(), token.COMMA, blank)
}
.expr0(, )
}
if {
.print(token.COMMA, blank, "/* "+filteredMsg+" */")
}
return
}
:= ignore
if &noIndent == 0 {
= indent
}
:= -1
if .IsValid() && .Line < && .linebreak(, 0, , true) > 0 {
= ignore
= 0
}
:= 0
:= 0.0
:= 0
:= .Line
for , := range {
= .lineFor(.Pos())
:= true
:=
const = 1e6
= .nodeSize(, )
, := .(*ast.KeyValueExpr)
if <= && .IsValid() && .IsValid() {
if {
= .nodeSize(.Key, )
}
} else {
= 0
}
if > 0 && > 0 {
const = 40
if == 0 || <= && <= {
= false
} else {
const = 2.5
:= math.Exp( / float64())
:= float64() /
= * <= 1 || <=
}
}
:= 0 < && <
if > 0 {
if ! {
.print(.Pos())
}
.print(token.COMMA)
:= true
if {
:= .linebreak(, 0, , || +1 < )
if > 0 {
= ignore
=
= false
}
if > 1 {
= 0
= 0
}
}
if {
.print(blank)
}
}
if len() > 1 && && > 0 && {
.expr(.Key)
.print(.Colon, token.COLON, vtab)
.expr(.Value)
} else {
.expr0(, )
}
if > 0 {
+= math.Log(float64())
++
}
=
}
if &commaTerm != 0 && .IsValid() && .pos.Line < .Line {
.print(token.COMMA)
if {
.print(newline)
.print("// " + filteredMsg)
}
if == ignore && &noIndent == 0 {
.print(unindent)
}
.print(formfeed)
return
}
if {
.print(token.COMMA, newline)
.print("// "+filteredMsg, newline)
}
if == ignore && &noIndent == 0 {
.print(unindent)
}
}
type paramMode int
const (
funcParam paramMode = iota
funcTParam
typeTParam
)
func ( *printer) ( *ast.FieldList, paramMode) {
, := token.LPAREN, token.RPAREN
if != funcParam {
, = token.LBRACK, token.RBRACK
}
.print(.Opening, )
if len(.List) > 0 {
:= .lineFor(.Opening)
:= indent
for , := range .List {
:= .lineFor(.Pos())
:= .lineFor(.End())
:= 0 < && <
if > 0 {
if ! {
.print(.Pos())
}
.print(token.COMMA)
}
if && .linebreak(, 0, , true) > 0 {
= ignore
} else if > 0 {
.print(blank)
}
if len(.Names) > 0 {
.identList(.Names, == indent)
.print(blank)
}
.expr(stripParensAlways(.Type))
=
}
if := .lineFor(.Closing); 0 < && < {
.print(token.COMMA)
.linebreak(, 0, ignore, true)
} else if == typeTParam && .NumFields() == 1 {
if , := .List[0].Type.(*ast.StarExpr); != nil && !isTypeLit(.X) {
.print(token.COMMA)
}
}
if == ignore {
.print(unindent)
}
}
.print(.Closing, )
}
func ( ast.Expr) bool {
switch x := .(type) {
case *ast.ArrayType, *ast.StructType, *ast.FuncType, *ast.InterfaceType, *ast.MapType, *ast.ChanType:
return true
case *ast.StarExpr:
return (.X)
case *ast.ParenExpr:
return (.X)
}
return false
}
func ( *printer) ( *ast.FuncType) {
if .TypeParams != nil {
.parameters(.TypeParams, funcTParam)
}
if .Params != nil {
.parameters(.Params, funcParam)
} else {
.print(token.LPAREN, token.RPAREN)
}
:= .Results
:= .NumFields()
if > 0 {
.print(blank)
if == 1 && .List[0].Names == nil {
.expr(stripParensAlways(.List[0].Type))
return
}
.parameters(, funcParam)
}
}
func ( []*ast.Ident, int) ( int) {
for , := range {
if > 0 {
+= len(", ")
}
+= utf8.RuneCountInString(.Name)
if >= {
break
}
}
return
}
func ( *printer) ( []*ast.Field) bool {
if len() != 1 {
return false
}
:= [0]
if .Tag != nil || .Comment != nil {
return false
}
const = 30
:= identListSize(.Names, )
if > 0 {
= 1
}
:= .nodeSize(.Type, )
return + <=
}
func ( *printer) ( string) {
.setComment(&ast.CommentGroup{List: []*ast.Comment{{Slash: token.NoPos, Text: }}})
}
func ( *printer) ( *ast.FieldList, , bool) {
:= .Opening
:= .List
:= .Closing
:= || .commentBefore(.posFor())
:= .IsValid() && .IsValid() && .lineFor() == .lineFor()
if ! && {
if len() == 0 {
.print(, token.LBRACE, , token.RBRACE)
return
} else if .isOneLineFieldList() {
.print(, token.LBRACE, blank)
:= [0]
if {
for , := range .Names {
if > 0 {
.print(token.COMMA, blank)
}
.expr()
}
if len(.Names) > 0 {
.print(blank)
}
.expr(.Type)
} else {
if len(.Names) > 0 {
:= .Names[0]
.expr()
.signature(.Type.(*ast.FuncType))
} else {
.expr(.Type)
}
}
.print(blank, , token.RBRACE)
return
}
}
.print(blank, , token.LBRACE, indent)
if || len() > 0 {
.print(formfeed)
}
if {
:= vtab
if len() == 1 {
= blank
}
var int
for , := range {
if > 0 {
.linebreak(.lineFor(.Pos()), 1, ignore, .linesFrom() > 0)
}
:= 0
.setComment(.Doc)
.recordLine(&)
if len(.Names) > 0 {
.identList(.Names, false)
.print()
.expr(.Type)
= 1
} else {
.expr(.Type)
= 2
}
if .Tag != nil {
if len(.Names) > 0 && == vtab {
.print()
}
.print()
.expr(.Tag)
= 0
}
if .Comment != nil {
for ; > 0; -- {
.print()
}
.setComment(.Comment)
}
}
if {
if len() > 0 {
.print(formfeed)
}
.flush(.posFor(), token.RBRACE)
.setLineComment("// " + filteredMsg)
}
} else {
var int
var *ast.Ident
for , := range {
var *ast.Ident
if len(.Names) > 0 {
= .Names[0]
}
if > 0 {
:= 1
if != nil && == {
= 0
}
.linebreak(.lineFor(.Pos()), , ignore, .linesFrom() > 0)
}
.setComment(.Doc)
.recordLine(&)
if != nil {
.expr()
.signature(.Type.(*ast.FuncType))
= nil
} else {
.expr(.Type)
= nil
}
.setComment(.Comment)
}
if {
if len() > 0 {
.print(formfeed)
}
.flush(.posFor(), token.RBRACE)
.setLineComment("// contains filtered or unexported methods")
}
}
.print(unindent, formfeed, , token.RBRACE)
}
func ( *ast.BinaryExpr) (, bool, int) {
switch .Op.Precedence() {
case 4:
= true
case 5:
= true
}
switch l := .X.(type) {
case *ast.BinaryExpr:
if .Op.Precedence() < .Op.Precedence() {
break
}
, , := ()
= ||
= ||
if < {
=
}
}
switch r := .Y.(type) {
case *ast.BinaryExpr:
if .Op.Precedence() <= .Op.Precedence() {
break
}
, , := ()
= ||
= ||
if < {
=
}
case *ast.StarExpr:
if .Op == token.QUO {
= 5
}
case *ast.UnaryExpr:
switch .Op.String() + .Op.String() {
case "/*", "&&", "&^":
= 5
case "++", "--":
if < 4 {
= 4
}
}
}
return
}
func ( *ast.BinaryExpr, int) int {
, , := walkBinary()
if > 0 {
return + 1
}
if && {
if == 1 {
return 5
}
return 4
}
if == 1 {
return 6
}
return 4
}
func ( ast.Expr, int) int {
, := .(*ast.BinaryExpr)
if ! || != .Op.Precedence() {
return 1
}
return 0
}
func ( int) int {
--
if < 1 {
= 1
}
return
}
func ( *printer) ( *ast.BinaryExpr, , , int) {
:= .Op.Precedence()
if < {
.print(token.LPAREN)
.expr0(, reduceDepth())
.print(token.RPAREN)
return
}
:= <
:= indent
.expr1(.X, , +diffPrec(.X, ))
if {
.print(blank)
}
:= .pos.Line
:= .lineFor(.Y.Pos())
.print(.OpPos, .Op)
if != && > 0 && > 0 {
if .linebreak(, 1, , true) > 0 {
= ignore
= false
}
}
if {
.print(blank)
}
.expr1(.Y, +1, +1)
if == ignore {
.print(unindent)
}
}
func ( ast.Expr) bool {
, := .(*ast.BinaryExpr)
return
}
func ( *printer) ( ast.Expr, , int) {
.print(.Pos())
switch x := .(type) {
case *ast.BadExpr:
.print("BadExpr")
case *ast.Ident:
.print()
case *ast.BinaryExpr:
if < 1 {
.internalError("depth < 1:", )
= 1
}
.binaryExpr(, , cutoff(, ), )
case *ast.KeyValueExpr:
.expr(.Key)
.print(.Colon, token.COLON, blank)
.expr(.Value)
case *ast.StarExpr:
const = token.UnaryPrec
if < {
.print(token.LPAREN)
.print(token.MUL)
.expr(.X)
.print(token.RPAREN)
} else {
.print(token.MUL)
.expr(.X)
}
case *ast.UnaryExpr:
const = token.UnaryPrec
if < {
.print(token.LPAREN)
.expr()
.print(token.RPAREN)
} else {
.print(.Op)
if .Op == token.RANGE {
.print(blank)
}
.(.X, , )
}
case *ast.BasicLit:
if .Config.Mode&normalizeNumbers != 0 {
= normalizedNumber()
}
.print()
case *ast.FuncLit:
.print(.Type.Pos(), token.FUNC)
:= .out.Column - len("func")
.signature(.Type)
.funcBody(.distanceFrom(.Type.Pos(), ), blank, .Body)
case *ast.ParenExpr:
if , := .X.(*ast.ParenExpr); {
.expr0(.X, )
} else {
.print(token.LPAREN)
.expr0(.X, reduceDepth())
.print(.Rparen, token.RPAREN)
}
case *ast.SelectorExpr:
.selectorExpr(, , false)
case *ast.TypeAssertExpr:
.(.X, token.HighestPrec, )
.print(token.PERIOD, .Lparen, token.LPAREN)
if .Type != nil {
.expr(.Type)
} else {
.print(token.TYPE)
}
.print(.Rparen, token.RPAREN)
case *ast.IndexExpr:
.(.X, token.HighestPrec, 1)
.print(.Lbrack, token.LBRACK)
.expr0(.Index, +1)
.print(.Rbrack, token.RBRACK)
case *ast.IndexListExpr:
.(.X, token.HighestPrec, 1)
.print(.Lbrack, token.LBRACK)
.exprList(.Lbrack, .Indices, +1, commaTerm, .Rbrack, false)
.print(.Rbrack, token.RBRACK)
case *ast.SliceExpr:
.(.X, token.HighestPrec, 1)
.print(.Lbrack, token.LBRACK)
:= []ast.Expr{.Low, .High}
if .Max != nil {
= append(, .Max)
}
var bool
if <= 1 {
var int
var bool
for , := range {
if != nil {
++
if isBinary() {
= true
}
}
}
if > 1 && {
= true
}
}
for , := range {
if > 0 {
if [-1] != nil && {
.print(blank)
}
.print(token.COLON)
if != nil && {
.print(blank)
}
}
if != nil {
.expr0(, +1)
}
}
.print(.Rbrack, token.RBRACK)
case *ast.CallExpr:
if len(.Args) > 1 {
++
}
var bool
if , := .Fun.(*ast.FuncType); {
.print(token.LPAREN)
= .possibleSelectorExpr(.Fun, token.HighestPrec, )
.print(token.RPAREN)
} else {
= .possibleSelectorExpr(.Fun, token.HighestPrec, )
}
.print(.Lparen, token.LPAREN)
if .Ellipsis.IsValid() {
.exprList(.Lparen, .Args, , 0, .Ellipsis, false)
.print(.Ellipsis, token.ELLIPSIS)
if .Rparen.IsValid() && .lineFor(.Ellipsis) < .lineFor(.Rparen) {
.print(token.COMMA, formfeed)
}
} else {
.exprList(.Lparen, .Args, , commaTerm, .Rparen, false)
}
.print(.Rparen, token.RPAREN)
if {
.print(unindent)
}
case *ast.CompositeLit:
if .Type != nil {
.(.Type, token.HighestPrec, )
}
.level++
.print(.Lbrace, token.LBRACE)
.exprList(.Lbrace, .Elts, 1, commaTerm, .Rbrace, .Incomplete)
:= noExtraLinebreak
if len(.Elts) > 0 {
|= noExtraBlank
}
.print(indent, unindent, , .Rbrace, token.RBRACE, )
.level--
case *ast.Ellipsis:
.print(token.ELLIPSIS)
if .Elt != nil {
.expr(.Elt)
}
case *ast.ArrayType:
.print(token.LBRACK)
if .Len != nil {
.expr(.Len)
}
.print(token.RBRACK)
.expr(.Elt)
case *ast.StructType:
.print(token.STRUCT)
.fieldList(.Fields, true, .Incomplete)
case *ast.FuncType:
.print(token.FUNC)
.signature()
case *ast.InterfaceType:
.print(token.INTERFACE)
.fieldList(.Methods, false, .Incomplete)
case *ast.MapType:
.print(token.MAP, token.LBRACK)
.expr(.Key)
.print(token.RBRACK)
.expr(.Value)
case *ast.ChanType:
switch .Dir {
case ast.SEND | ast.RECV:
.print(token.CHAN)
case ast.RECV:
.print(token.ARROW, token.CHAN)
case ast.SEND:
.print(token.CHAN, .Arrow, token.ARROW)
}
.print(blank)
.expr(.Value)
default:
panic("unreachable")
}
}
func ( *ast.BasicLit) *ast.BasicLit {
if .Kind != token.INT && .Kind != token.FLOAT && .Kind != token.IMAG {
return
}
if len(.Value) < 2 {
return
}
:= .Value
switch [:2] {
default:
if := strings.LastIndexByte(, 'E'); >= 0 {
= [:] + "e" + [+1:]
break
}
if [len()-1] == 'i' && !strings.ContainsAny(, ".e") {
= strings.TrimLeft(, "0_")
if == "i" {
= "0i"
}
}
case "0X":
= "0x" + [2:]
if := strings.LastIndexByte(, 'P'); >= 0 {
= [:] + "p" + [+1:]
}
case "0x":
:= strings.LastIndexByte(, 'P')
if == -1 {
return
}
= [:] + "p" + [+1:]
case "0O":
= "0o" + [2:]
case "0o":
return
case "0B":
= "0b" + [2:]
case "0b":
return
}
return &ast.BasicLit{ValuePos: .ValuePos, Kind: .Kind, Value: }
}
func ( *printer) ( ast.Expr, , int) bool {
if , := .(*ast.SelectorExpr); {
return .selectorExpr(, , true)
}
.expr1(, , )
return false
}
func ( *printer) ( *ast.SelectorExpr, int, bool) bool {
.expr1(.X, token.HighestPrec, )
.print(token.PERIOD)
if := .lineFor(.Sel.Pos()); .pos.IsValid() && .pos.Line < {
.print(indent, newline, .Sel.Pos(), .Sel)
if ! {
.print(unindent)
}
return true
}
.print(.Sel.Pos(), .Sel)
return false
}
func ( *printer) ( ast.Expr, int) {
.expr1(, token.LowestPrec, )
}
func ( *printer) ( ast.Expr) {
const = 1
.expr1(, token.LowestPrec, )
}
func ( *printer) ( []ast.Stmt, int, bool) {
if > 0 {
.print(indent)
}
var int
:= 0
for , := range {
if , := .(*ast.EmptyStmt); ! {
if len(.output) > 0 {
.linebreak(.lineFor(.Pos()), 1, ignore, == 0 || == 0 || .linesFrom() > 0)
}
.recordLine(&)
.stmt(, && == len()-1)
for := ; ; {
, := .(*ast.LabeledStmt)
if == nil {
break
}
++
= .Stmt
}
++
}
}
if > 0 {
.print(unindent)
}
}
func ( *printer) ( *ast.BlockStmt, int) {
.print(.Lbrace, token.LBRACE)
.stmtList(.List, , true)
.linebreak(.lineFor(.Rbrace), 1, ignore, true)
.print(.Rbrace, token.RBRACE)
}
func ( ast.Expr) bool {
switch t := .(type) {
case *ast.Ident:
return true
case *ast.SelectorExpr:
return (.X)
}
return false
}
func ( ast.Expr) ast.Expr {
if , := .(*ast.ParenExpr); {
ast.Inspect(.X, func( ast.Node) bool {
switch x := .(type) {
case *ast.ParenExpr:
return false
case *ast.CompositeLit:
if isTypeName(.Type) {
= false
}
return false
}
return true
})
if {
return (.X)
}
}
return
}
func ( ast.Expr) ast.Expr {
if , := .(*ast.ParenExpr); {
return (.X)
}
return
}
func ( *printer) ( bool, ast.Stmt, ast.Expr, ast.Stmt) {
.print(blank)
:= false
if == nil && == nil {
if != nil {
.expr(stripParens())
= true
}
} else {
if != nil {
.stmt(, false)
}
.print(token.SEMICOLON, blank)
if != nil {
.expr(stripParens())
= true
}
if {
.print(token.SEMICOLON, blank)
= false
if != nil {
.stmt(, false)
= true
}
}
}
if {
.print(blank)
}
}
func ( *printer) ( []ast.Expr) bool {
if len() >= 2 {
var = .lineFor([0].Pos())
var = .lineFor([len()-1].End())
if 0 < && < {
:= 0
:=
for , := range {
:= .lineFor(.Pos())
:= .lineFor(.End())
if < {
return true
}
if < {
++
}
=
}
return > 1
}
}
return false
}
func ( *printer) ( ast.Stmt, bool) {
.print(.Pos())
switch s := .(type) {
case *ast.BadStmt:
.print("BadStmt")
case *ast.DeclStmt:
.decl(.Decl)
case *ast.EmptyStmt:
case *ast.LabeledStmt:
.print(unindent)
.expr(.Label)
.print(.Colon, token.COLON, indent)
if , := .Stmt.(*ast.EmptyStmt); {
if ! {
.print(newline, .Pos(), token.SEMICOLON)
break
}
} else {
.linebreak(.lineFor(.Stmt.Pos()), 1, ignore, true)
}
.(.Stmt, )
case *ast.ExprStmt:
const = 1
.expr0(.X, )
case *ast.SendStmt:
const = 1
.expr0(.Chan, )
.print(blank, .Arrow, token.ARROW, blank)
.expr0(.Value, )
case *ast.IncDecStmt:
const = 1
.expr0(.X, +1)
.print(.TokPos, .Tok)
case *ast.AssignStmt:
var = 1
if len(.Lhs) > 1 && len(.Rhs) > 1 {
++
}
.exprList(.Pos(), .Lhs, , 0, .TokPos, false)
.print(blank, .TokPos, .Tok, blank)
.exprList(.TokPos, .Rhs, , 0, token.NoPos, false)
case *ast.GoStmt:
.print(token.GO, blank)
.expr(.Call)
case *ast.DeferStmt:
.print(token.DEFER, blank)
.expr(.Call)
case *ast.ReturnStmt:
.print(token.RETURN)
if .Results != nil {
.print(blank)
if .indentList(.Results) {
.print(indent)
.exprList(token.NoPos, .Results, 1, noIndent, token.NoPos, false)
.print(unindent)
} else {
.exprList(token.NoPos, .Results, 1, 0, token.NoPos, false)
}
}
case *ast.BranchStmt:
.print(.Tok)
if .Label != nil {
.print(blank)
.expr(.Label)
}
case *ast.BlockStmt:
.block(, 1)
case *ast.IfStmt:
.print(token.IF)
.controlClause(false, .Init, .Cond, nil)
.block(.Body, 1)
if .Else != nil {
.print(blank, token.ELSE, blank)
switch .Else.(type) {
case *ast.BlockStmt, *ast.IfStmt:
.(.Else, )
default:
.print(token.LBRACE, indent, formfeed)
.(.Else, true)
.print(unindent, formfeed, token.RBRACE)
}
}
case *ast.CaseClause:
if .List != nil {
.print(token.CASE, blank)
.exprList(.Pos(), .List, 1, 0, .Colon, false)
} else {
.print(token.DEFAULT)
}
.print(.Colon, token.COLON)
.stmtList(.Body, 1, )
case *ast.SwitchStmt:
.print(token.SWITCH)
.controlClause(false, .Init, .Tag, nil)
.block(.Body, 0)
case *ast.TypeSwitchStmt:
.print(token.SWITCH)
if .Init != nil {
.print(blank)
.(.Init, false)
.print(token.SEMICOLON)
}
.print(blank)
.(.Assign, false)
.print(blank)
.block(.Body, 0)
case *ast.CommClause:
if .Comm != nil {
.print(token.CASE, blank)
.(.Comm, false)
} else {
.print(token.DEFAULT)
}
.print(.Colon, token.COLON)
.stmtList(.Body, 1, )
case *ast.SelectStmt:
.print(token.SELECT, blank)
:= .Body
if len(.List) == 0 && !.commentBefore(.posFor(.Rbrace)) {
.print(.Lbrace, token.LBRACE, .Rbrace, token.RBRACE)
} else {
.block(, 0)
}
case *ast.ForStmt:
.print(token.FOR)
.controlClause(true, .Init, .Cond, .Post)
.block(.Body, 1)
case *ast.RangeStmt:
.print(token.FOR, blank)
if .Key != nil {
.expr(.Key)
if .Value != nil {
.print(.Value.Pos(), token.COMMA, blank)
.expr(.Value)
}
.print(blank, .TokPos, .Tok, blank)
}
.print(token.RANGE, blank)
.expr(stripParens(.X))
.print(blank)
.block(.Body, 1)
default:
panic("unreachable")
}
}
func ( []ast.Spec) []bool {
:= make([]bool, len())
:= func(, int, bool) {
if {
for ; < ; ++ {
[] = true
}
}
}
:= -1
var bool
for , := range {
:= .(*ast.ValueSpec)
if .Values != nil {
if < 0 {
=
= false
}
} else {
if >= 0 {
(, , )
= -1
}
}
if .Type != nil {
= true
}
}
if >= 0 {
(, len(), )
}
return
}
func ( *printer) ( *ast.ValueSpec, bool) {
.setComment(.Doc)
.identList(.Names, false)
:= 3
if .Type != nil || {
.print(vtab)
--
}
if .Type != nil {
.expr(.Type)
}
if .Values != nil {
.print(vtab, token.ASSIGN, blank)
.exprList(token.NoPos, .Values, 1, 0, token.NoPos, false)
--
}
if .Comment != nil {
for ; > 0; -- {
.print(vtab)
}
.setComment(.Comment)
}
}
func ( *ast.BasicLit) *ast.BasicLit {
if .Kind != token.STRING {
return
}
, := strconv.Unquote(.Value)
if != nil {
return
}
if == "" {
return
}
const = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD"
for , := range {
if !unicode.IsGraphic() || unicode.IsSpace() || strings.ContainsRune(, ) {
return
}
}
= strconv.Quote()
if == .Value {
return
}
return &ast.BasicLit{ValuePos: .ValuePos, Kind: token.STRING, Value: }
}
func ( *printer) ( ast.Spec, int, bool) {
switch s := .(type) {
case *ast.ImportSpec:
.setComment(.Doc)
if .Name != nil {
.expr(.Name)
.print(blank)
}
.expr(sanitizeImportPath(.Path))
.setComment(.Comment)
.print(.EndPos)
case *ast.ValueSpec:
if != 1 {
.internalError("expected n = 1; got", )
}
.setComment(.Doc)
.identList(.Names, )
if .Type != nil {
.print(blank)
.expr(.Type)
}
if .Values != nil {
.print(blank, token.ASSIGN, blank)
.exprList(token.NoPos, .Values, 1, 0, token.NoPos, false)
}
.setComment(.Comment)
case *ast.TypeSpec:
.setComment(.Doc)
.expr(.Name)
if .TypeParams != nil {
.parameters(.TypeParams, typeTParam)
}
if == 1 {
.print(blank)
} else {
.print(vtab)
}
if .Assign.IsValid() {
.print(token.ASSIGN, blank)
}
.expr(.Type)
.setComment(.Comment)
default:
panic("unreachable")
}
}
func ( *printer) ( *ast.GenDecl) {
.setComment(.Doc)
.print(.Pos(), .Tok, blank)
if .Lparen.IsValid() || len(.Specs) > 1 {
.print(.Lparen, token.LPAREN)
if := len(.Specs); > 0 {
.print(indent, formfeed)
if > 1 && (.Tok == token.CONST || .Tok == token.VAR) {
:= keepTypeColumn(.Specs)
var int
for , := range .Specs {
if > 0 {
.linebreak(.lineFor(.Pos()), 1, ignore, .linesFrom() > 0)
}
.recordLine(&)
.valueSpec(.(*ast.ValueSpec), [])
}
} else {
var int
for , := range .Specs {
if > 0 {
.linebreak(.lineFor(.Pos()), 1, ignore, .linesFrom() > 0)
}
.recordLine(&)
.spec(, , false)
}
}
.print(unindent, formfeed)
}
.print(.Rparen, token.RPAREN)
} else if len(.Specs) > 0 {
.spec(.Specs[0], 1, true)
}
}
func ( *printer) ( ast.Node, int) ( int) {
if , := .nodeSizes[]; {
return
}
= + 1
.nodeSizes[] =
:= Config{Mode: RawFormat}
var bytes.Buffer
if := .fprint(&, .fset, , .nodeSizes); != nil {
return
}
if .Len() <= {
for , := range .Bytes() {
if < ' ' {
return
}
}
= .Len()
.nodeSizes[] =
}
return
}
func ( *printer) ( ast.Node) int {
if := .Pos(); .IsValid() {
if := .End(); .IsValid() {
return .lineFor() - .lineFor() + 1
}
}
return infinity
}
func ( *printer) ( *ast.BlockStmt, int) int {
:= .Pos()
:= .Rbrace
if .IsValid() && .IsValid() && .lineFor() != .lineFor() {
return + 1
}
if len(.List) > 5 {
return + 1
}
:= .commentSizeBefore(.posFor())
for , := range .List {
if > {
break
}
if > 0 {
+= 2
}
+= .nodeSize(, )
}
return
}
func ( *printer) ( int, whiteSpace, *ast.BlockStmt) {
if == nil {
return
}
defer func( int) {
.level =
}(.level)
.level = 0
const = 100
if +.bodySize(, ) <= {
.print(, .Lbrace, token.LBRACE)
if len(.List) > 0 {
.print(blank)
for , := range .List {
if > 0 {
.print(token.SEMICOLON, blank)
}
.stmt(, == len(.List)-1)
}
.print(blank)
}
.print(noExtraLinebreak, .Rbrace, token.RBRACE, noExtraLinebreak)
return
}
if != ignore {
.print(blank)
}
.block(, 1)
}
func ( *printer) ( token.Pos, int) int {
if .IsValid() && .pos.IsValid() && .posFor().Line == .pos.Line {
return .out.Column -
}
return infinity
}
func ( *printer) ( *ast.FuncDecl) {
.setComment(.Doc)
.print(.Pos(), token.FUNC, blank)
:= .out.Column - len("func ")
if .Recv != nil {
.parameters(.Recv, funcParam)
.print(blank)
}
.expr(.Name)
.signature(.Type)
.funcBody(.distanceFrom(.Pos(), ), vtab, .Body)
}
func ( *printer) ( ast.Decl) {
switch d := .(type) {
case *ast.BadDecl:
.print(.Pos(), "BadDecl")
case *ast.GenDecl:
.genDecl()
case *ast.FuncDecl:
.funcDecl()
default:
panic("unreachable")
}
}
func ( ast.Decl) ( token.Token) {
= token.ILLEGAL
switch d := .(type) {
case *ast.GenDecl:
= .Tok
case *ast.FuncDecl:
= token.FUNC
}
return
}
func ( *printer) ( []ast.Decl) {
:= token.ILLEGAL
for , := range {
:=
= declToken()
if len(.output) > 0 {
:= 1
if != || getDoc() != nil {
= 2
}
.linebreak(.lineFor(.Pos()), , ignore, == token.FUNC && .numLines() > 1)
}
.decl()
}
}
func ( *printer) ( *ast.File) {
.setComment(.Doc)
.print(.Pos(), token.PACKAGE, blank)
.expr(.Name)
.declList(.Decls)
.print(newline)
}