package types
import (
"bytes"
"fmt"
"go/ast"
"go/internal/typeparams"
)
func ExprString (x ast .Expr ) string {
var buf bytes .Buffer
WriteExpr (&buf , x )
return buf .String ()
}
func WriteExpr (buf *bytes .Buffer , x ast .Expr ) {
switch x := x .(type ) {
default :
fmt .Fprintf (buf , "(ast: %T)" , x )
case *ast .Ident :
buf .WriteString (x .Name )
case *ast .Ellipsis :
buf .WriteString ("..." )
if x .Elt != nil {
WriteExpr (buf , x .Elt )
}
case *ast .BasicLit :
buf .WriteString (x .Value )
case *ast .FuncLit :
buf .WriteByte ('(' )
WriteExpr (buf , x .Type )
buf .WriteString (" literal)" )
case *ast .CompositeLit :
WriteExpr (buf , x .Type )
buf .WriteByte ('{' )
if len (x .Elts ) > 0 {
buf .WriteString ("…" )
}
buf .WriteByte ('}' )
case *ast .ParenExpr :
buf .WriteByte ('(' )
WriteExpr (buf , x .X )
buf .WriteByte (')' )
case *ast .SelectorExpr :
WriteExpr (buf , x .X )
buf .WriteByte ('.' )
buf .WriteString (x .Sel .Name )
case *ast .IndexExpr , *ast .IndexListExpr :
ix := typeparams .UnpackIndexExpr (x )
WriteExpr (buf , ix .X )
buf .WriteByte ('[' )
writeExprList (buf , ix .Indices )
buf .WriteByte (']' )
case *ast .SliceExpr :
WriteExpr (buf , x .X )
buf .WriteByte ('[' )
if x .Low != nil {
WriteExpr (buf , x .Low )
}
buf .WriteByte (':' )
if x .High != nil {
WriteExpr (buf , x .High )
}
if x .Slice3 {
buf .WriteByte (':' )
if x .Max != nil {
WriteExpr (buf , x .Max )
}
}
buf .WriteByte (']' )
case *ast .TypeAssertExpr :
WriteExpr (buf , x .X )
buf .WriteString (".(" )
WriteExpr (buf , x .Type )
buf .WriteByte (')' )
case *ast .CallExpr :
WriteExpr (buf , x .Fun )
buf .WriteByte ('(' )
writeExprList (buf , x .Args )
if hasDots (x ) {
buf .WriteString ("..." )
}
buf .WriteByte (')' )
case *ast .StarExpr :
buf .WriteByte ('*' )
WriteExpr (buf , x .X )
case *ast .UnaryExpr :
buf .WriteString (x .Op .String ())
WriteExpr (buf , x .X )
case *ast .BinaryExpr :
WriteExpr (buf , x .X )
buf .WriteByte (' ' )
buf .WriteString (x .Op .String ())
buf .WriteByte (' ' )
WriteExpr (buf , x .Y )
case *ast .ArrayType :
buf .WriteByte ('[' )
if x .Len != nil {
WriteExpr (buf , x .Len )
}
buf .WriteByte (']' )
WriteExpr (buf , x .Elt )
case *ast .StructType :
buf .WriteString ("struct{" )
writeFieldList (buf , x .Fields .List , "; " , false )
buf .WriteByte ('}' )
case *ast .FuncType :
buf .WriteString ("func" )
writeSigExpr (buf , x )
case *ast .InterfaceType :
buf .WriteString ("interface{" )
writeFieldList (buf , x .Methods .List , "; " , true )
buf .WriteByte ('}' )
case *ast .MapType :
buf .WriteString ("map[" )
WriteExpr (buf , x .Key )
buf .WriteByte (']' )
WriteExpr (buf , x .Value )
case *ast .ChanType :
var s string
switch x .Dir {
case ast .SEND :
s = "chan<- "
case ast .RECV :
s = "<-chan "
default :
s = "chan "
}
buf .WriteString (s )
WriteExpr (buf , x .Value )
}
}
func writeSigExpr(buf *bytes .Buffer , sig *ast .FuncType ) {
buf .WriteByte ('(' )
writeFieldList (buf , sig .Params .List , ", " , false )
buf .WriteByte (')' )
res := sig .Results
n := res .NumFields ()
if n == 0 {
return
}
buf .WriteByte (' ' )
if n == 1 && len (res .List [0 ].Names ) == 0 {
WriteExpr (buf , res .List [0 ].Type )
return
}
buf .WriteByte ('(' )
writeFieldList (buf , res .List , ", " , false )
buf .WriteByte (')' )
}
func writeFieldList(buf *bytes .Buffer , list []*ast .Field , sep string , iface bool ) {
for i , f := range list {
if i > 0 {
buf .WriteString (sep )
}
writeIdentList (buf , f .Names )
if sig , _ := f .Type .(*ast .FuncType ); sig != nil && iface {
writeSigExpr (buf , sig )
continue
}
if len (f .Names ) > 0 {
buf .WriteByte (' ' )
}
WriteExpr (buf , f .Type )
}
}
func writeIdentList(buf *bytes .Buffer , list []*ast .Ident ) {
for i , x := range list {
if i > 0 {
buf .WriteString (", " )
}
buf .WriteString (x .Name )
}
}
func writeExprList(buf *bytes .Buffer , list []ast .Expr ) {
for i , x := range list {
if i > 0 {
buf .WriteString (", " )
}
WriteExpr (buf , x )
}
}
The pages are generated with Golds v0.7.0-preview . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .