mirror of
https://github.com/golang/go
synced 2024-11-21 19:04:44 -07:00
go/ast: streamline representation of field lists
- always include position information about opening/closing parens/braces - replace uses of []*ast.Field with *ast.FieldList Fixes #473. R=rsc CC=golang-dev https://golang.org/cl/223043
This commit is contained in:
parent
78961ed961
commit
ef0be41e20
@ -164,6 +164,10 @@ func walk(x interface{}, p *Prog, context string) {
|
|||||||
// These are ordered and grouped to match ../../pkg/go/ast/ast.go
|
// These are ordered and grouped to match ../../pkg/go/ast/ast.go
|
||||||
case *ast.Field:
|
case *ast.Field:
|
||||||
walk(&n.Type, p, "type")
|
walk(&n.Type, p, "type")
|
||||||
|
case *ast.FieldList:
|
||||||
|
for _, f := range n.List {
|
||||||
|
walk(f, p, context)
|
||||||
|
}
|
||||||
case *ast.BadExpr:
|
case *ast.BadExpr:
|
||||||
case *ast.Ident:
|
case *ast.Ident:
|
||||||
case *ast.Ellipsis:
|
case *ast.Ellipsis:
|
||||||
@ -211,7 +215,9 @@ func walk(x interface{}, p *Prog, context string) {
|
|||||||
walk(n.Fields, p, "field")
|
walk(n.Fields, p, "field")
|
||||||
case *ast.FuncType:
|
case *ast.FuncType:
|
||||||
walk(n.Params, p, "field")
|
walk(n.Params, p, "field")
|
||||||
walk(n.Results, p, "field")
|
if n.Results != nil {
|
||||||
|
walk(n.Results, p, "field")
|
||||||
|
}
|
||||||
case *ast.InterfaceType:
|
case *ast.InterfaceType:
|
||||||
walk(n.Methods, p, "field")
|
walk(n.Methods, p, "field")
|
||||||
case *ast.MapType:
|
case *ast.MapType:
|
||||||
@ -313,10 +319,6 @@ func walk(x interface{}, p *Prog, context string) {
|
|||||||
for i := range n {
|
for i := range n {
|
||||||
walk(&n[i], p, context)
|
walk(&n[i], p, context)
|
||||||
}
|
}
|
||||||
case []*ast.Field:
|
|
||||||
for _, f := range n {
|
|
||||||
walk(f, p, context)
|
|
||||||
}
|
|
||||||
case []ast.Stmt:
|
case []ast.Stmt:
|
||||||
for _, s := range n {
|
for _, s := range n {
|
||||||
walk(s, p, context)
|
walk(s, p, context)
|
||||||
|
@ -703,8 +703,8 @@ func (c *typeConv) FuncType(dtype *dwarf.FuncType) *FuncType {
|
|||||||
Params: p,
|
Params: p,
|
||||||
Result: r,
|
Result: r,
|
||||||
Go: &ast.FuncType{
|
Go: &ast.FuncType{
|
||||||
Params: gp,
|
Params: &ast.FieldList{List: gp},
|
||||||
Results: gr,
|
Results: &ast.FieldList{List: gr},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -796,6 +796,6 @@ func (c *typeConv) Struct(dt *dwarf.StructType) (expr *ast.StructType, csyntax s
|
|||||||
fatal("struct size calculation error")
|
fatal("struct size calculation error")
|
||||||
}
|
}
|
||||||
csyntax += "}"
|
csyntax += "}"
|
||||||
expr = &ast.StructType{Fields: fld}
|
expr = &ast.StructType{Fields: &ast.FieldList{List: fld}}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -86,43 +86,33 @@ func (a *typeCompiler) compileArrayType(x *ast.ArrayType, allowRec bool) Type {
|
|||||||
return NewArrayType(l, elem)
|
return NewArrayType(l, elem)
|
||||||
}
|
}
|
||||||
|
|
||||||
func countFields(fs []*ast.Field) int {
|
func (a *typeCompiler) compileFields(fields *ast.FieldList, allowRec bool) ([]Type, []*ast.Ident, []token.Position, bool) {
|
||||||
n := 0
|
n := fields.NumFields()
|
||||||
for _, f := range fs {
|
|
||||||
if f.Names == nil {
|
|
||||||
n++
|
|
||||||
} else {
|
|
||||||
n += len(f.Names)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *typeCompiler) compileFields(fs []*ast.Field, allowRec bool) ([]Type, []*ast.Ident, []token.Position, bool) {
|
|
||||||
n := countFields(fs)
|
|
||||||
ts := make([]Type, n)
|
ts := make([]Type, n)
|
||||||
ns := make([]*ast.Ident, n)
|
ns := make([]*ast.Ident, n)
|
||||||
ps := make([]token.Position, n)
|
ps := make([]token.Position, n)
|
||||||
|
|
||||||
bad := false
|
bad := false
|
||||||
i := 0
|
|
||||||
for _, f := range fs {
|
if fields != nil {
|
||||||
t := a.compileType(f.Type, allowRec)
|
i := 0
|
||||||
if t == nil {
|
for _, f := range fields.List {
|
||||||
bad = true
|
t := a.compileType(f.Type, allowRec)
|
||||||
}
|
if t == nil {
|
||||||
if f.Names == nil {
|
bad = true
|
||||||
ns[i] = nil
|
}
|
||||||
ts[i] = t
|
if f.Names == nil {
|
||||||
ps[i] = f.Type.Pos()
|
ns[i] = nil
|
||||||
i++
|
ts[i] = t
|
||||||
continue
|
ps[i] = f.Type.Pos()
|
||||||
}
|
i++
|
||||||
for _, n := range f.Names {
|
continue
|
||||||
ns[i] = n
|
}
|
||||||
ts[i] = t
|
for _, n := range f.Names {
|
||||||
ps[i] = n.Pos()
|
ns[i] = n
|
||||||
i++
|
ts[i] = t
|
||||||
|
ps[i] = n.Pos()
|
||||||
|
i++
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,6 +102,30 @@ func (f *Field) Pos() token.Position {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// A FieldList represents a list of Fields, enclosed by parentheses or braces.
|
||||||
|
type FieldList struct {
|
||||||
|
Opening token.Position // position of opening parenthesis/brace
|
||||||
|
List []*Field // field list
|
||||||
|
Closing token.Position // position of closing parenthesis/brace
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// NumFields returns the number of (named and anonymous fields) in a FieldList.
|
||||||
|
func (f *FieldList) NumFields() int {
|
||||||
|
n := 0
|
||||||
|
if f != nil {
|
||||||
|
for _, g := range f.List {
|
||||||
|
m := len(g.Names)
|
||||||
|
if m == 0 {
|
||||||
|
m = 1 // anonymous field
|
||||||
|
}
|
||||||
|
n += m
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// An expression is represented by a tree consisting of one
|
// An expression is represented by a tree consisting of one
|
||||||
// or more of the following concrete expression nodes.
|
// or more of the following concrete expression nodes.
|
||||||
//
|
//
|
||||||
@ -253,29 +277,25 @@ type (
|
|||||||
|
|
||||||
// A StructType node represents a struct type.
|
// A StructType node represents a struct type.
|
||||||
StructType struct {
|
StructType struct {
|
||||||
token.Position // position of "struct" keyword
|
token.Position // position of "struct" keyword
|
||||||
Lbrace token.Position // position of "{"
|
Fields *FieldList // list of field declarations
|
||||||
Fields []*Field // list of field declarations
|
Incomplete bool // true if (source) fields are missing in the Fields list
|
||||||
Rbrace token.Position // position of "}"
|
|
||||||
Incomplete bool // true if (source) fields are missing in the Fields list
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pointer types are represented via StarExpr nodes.
|
// Pointer types are represented via StarExpr nodes.
|
||||||
|
|
||||||
// A FuncType node represents a function type.
|
// A FuncType node represents a function type.
|
||||||
FuncType struct {
|
FuncType struct {
|
||||||
token.Position // position of "func" keyword
|
token.Position // position of "func" keyword
|
||||||
Params []*Field // (incoming) parameters
|
Params *FieldList // (incoming) parameters
|
||||||
Results []*Field // (outgoing) results
|
Results *FieldList // (outgoing) results
|
||||||
}
|
}
|
||||||
|
|
||||||
// An InterfaceType node represents an interface type.
|
// An InterfaceType node represents an interface type.
|
||||||
InterfaceType struct {
|
InterfaceType struct {
|
||||||
token.Position // position of "interface" keyword
|
token.Position // position of "interface" keyword
|
||||||
Lbrace token.Position // position of "{"
|
Methods *FieldList // list of methods
|
||||||
Methods []*Field // list of methods
|
Incomplete bool // true if (source) methods are missing in the Methods list
|
||||||
Rbrace token.Position // position of "}"
|
|
||||||
Incomplete bool // true if (source) methods are missing in the Methods list
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// A MapType node represents a map type.
|
// A MapType node represents a map type.
|
||||||
@ -669,7 +689,7 @@ type (
|
|||||||
// A FuncDecl node represents a function declaration.
|
// A FuncDecl node represents a function declaration.
|
||||||
FuncDecl struct {
|
FuncDecl struct {
|
||||||
Doc *CommentGroup // associated documentation; or nil
|
Doc *CommentGroup // associated documentation; or nil
|
||||||
Recv *Field // receiver (methods); or nil (functions)
|
Recv *FieldList // receiver (methods); or nil (functions)
|
||||||
Name *Ident // function/method name
|
Name *Ident // function/method name
|
||||||
Type *FuncType // position of Func keyword, parameters and results
|
Type *FuncType // position of Func keyword, parameters and results
|
||||||
Body *BlockStmt // function body; or nil (forward declaration)
|
Body *BlockStmt // function body; or nil (forward declaration)
|
||||||
|
@ -36,7 +36,11 @@ func isExportedType(typ Expr) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func filterFieldList(list []*Field, incomplete *bool) []*Field {
|
func filterFieldList(fields *FieldList, incomplete *bool) {
|
||||||
|
if fields == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
list := fields.List
|
||||||
j := 0
|
j := 0
|
||||||
for _, f := range list {
|
for _, f := range list {
|
||||||
exported := false
|
exported := false
|
||||||
@ -65,12 +69,15 @@ func filterFieldList(list []*Field, incomplete *bool) []*Field {
|
|||||||
if j < len(list) {
|
if j < len(list) {
|
||||||
*incomplete = true
|
*incomplete = true
|
||||||
}
|
}
|
||||||
return list[0:j]
|
fields.List = list[0:j]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func filterParamList(list []*Field) {
|
func filterParamList(fields *FieldList) {
|
||||||
for _, f := range list {
|
if fields == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, f := range fields.List {
|
||||||
filterType(f.Type)
|
filterType(f.Type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -83,12 +90,12 @@ func filterType(typ Expr) {
|
|||||||
case *ArrayType:
|
case *ArrayType:
|
||||||
filterType(t.Elt)
|
filterType(t.Elt)
|
||||||
case *StructType:
|
case *StructType:
|
||||||
t.Fields = filterFieldList(t.Fields, &t.Incomplete)
|
filterFieldList(t.Fields, &t.Incomplete)
|
||||||
case *FuncType:
|
case *FuncType:
|
||||||
filterParamList(t.Params)
|
filterParamList(t.Params)
|
||||||
filterParamList(t.Results)
|
filterParamList(t.Results)
|
||||||
case *InterfaceType:
|
case *InterfaceType:
|
||||||
t.Methods = filterFieldList(t.Methods, &t.Incomplete)
|
filterFieldList(t.Methods, &t.Incomplete)
|
||||||
case *MapType:
|
case *MapType:
|
||||||
filterType(t.Key)
|
filterType(t.Key)
|
||||||
filterType(t.Value)
|
filterType(t.Value)
|
||||||
|
@ -72,6 +72,11 @@ func Walk(v Visitor, node interface{}) {
|
|||||||
Walk(v, n.Tag)
|
Walk(v, n.Tag)
|
||||||
walkCommentGroup(v, n.Comment)
|
walkCommentGroup(v, n.Comment)
|
||||||
|
|
||||||
|
case *FieldList:
|
||||||
|
for _, f := range n.List {
|
||||||
|
Walk(v, f)
|
||||||
|
}
|
||||||
|
|
||||||
// Expressions
|
// Expressions
|
||||||
case *BadExpr, *Ident, *Ellipsis, *BasicLit:
|
case *BadExpr, *Ident, *Ellipsis, *BasicLit:
|
||||||
// nothing to do
|
// nothing to do
|
||||||
@ -134,7 +139,9 @@ func Walk(v Visitor, node interface{}) {
|
|||||||
|
|
||||||
case *FuncType:
|
case *FuncType:
|
||||||
Walk(v, n.Params)
|
Walk(v, n.Params)
|
||||||
Walk(v, n.Results)
|
if n.Results != nil {
|
||||||
|
Walk(v, n.Results)
|
||||||
|
}
|
||||||
|
|
||||||
case *InterfaceType:
|
case *InterfaceType:
|
||||||
Walk(v, n.Methods)
|
Walk(v, n.Methods)
|
||||||
@ -287,11 +294,6 @@ func Walk(v Visitor, node interface{}) {
|
|||||||
Walk(v, f)
|
Walk(v, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
case []*Field:
|
|
||||||
for _, x := range n {
|
|
||||||
Walk(v, x)
|
|
||||||
}
|
|
||||||
|
|
||||||
case []*Ident:
|
case []*Ident:
|
||||||
for _, x := range n {
|
for _, x := range n {
|
||||||
Walk(v, x)
|
Walk(v, x)
|
||||||
|
@ -153,7 +153,7 @@ func (doc *docReader) addFunc(fun *ast.FuncDecl) {
|
|||||||
// determine if it should be associated with a type
|
// determine if it should be associated with a type
|
||||||
if fun.Recv != nil {
|
if fun.Recv != nil {
|
||||||
// method
|
// method
|
||||||
typ := doc.lookupTypeDoc(baseTypeName(fun.Recv.Type))
|
typ := doc.lookupTypeDoc(baseTypeName(fun.Recv.List[0].Type))
|
||||||
if typ != nil {
|
if typ != nil {
|
||||||
// exported receiver type
|
// exported receiver type
|
||||||
typ.methods[name] = fun
|
typ.methods[name] = fun
|
||||||
@ -168,8 +168,8 @@ func (doc *docReader) addFunc(fun *ast.FuncDecl) {
|
|||||||
|
|
||||||
// perhaps a factory function
|
// perhaps a factory function
|
||||||
// determine result type, if any
|
// determine result type, if any
|
||||||
if len(fun.Type.Results) >= 1 {
|
if fun.Type.Results.NumFields() >= 1 {
|
||||||
res := fun.Type.Results[0]
|
res := fun.Type.Results.List[0]
|
||||||
if len(res.Names) <= 1 {
|
if len(res.Names) <= 1 {
|
||||||
// exactly one (named or anonymous) result associated
|
// exactly one (named or anonymous) result associated
|
||||||
// with the first type in result signature (there may
|
// with the first type in result signature (there may
|
||||||
@ -398,7 +398,7 @@ func makeFuncDocs(m map[string]*ast.FuncDecl) []*FuncDoc {
|
|||||||
doc.Doc = CommentText(f.Doc)
|
doc.Doc = CommentText(f.Doc)
|
||||||
f.Doc = nil // doc consumed - remove from ast.FuncDecl node
|
f.Doc = nil // doc consumed - remove from ast.FuncDecl node
|
||||||
if f.Recv != nil {
|
if f.Recv != nil {
|
||||||
doc.Recv = f.Recv.Type
|
doc.Recv = f.Recv.List[0].Type
|
||||||
}
|
}
|
||||||
doc.Name = f.Name.Name()
|
doc.Name = f.Name.Name()
|
||||||
doc.Decl = f
|
doc.Decl = f
|
||||||
|
@ -572,7 +572,7 @@ func (p *parser) parseStructType() *ast.StructType {
|
|||||||
// TODO(gri) The struct scope shouldn't get lost.
|
// TODO(gri) The struct scope shouldn't get lost.
|
||||||
p.declFieldList(ast.NewScope(nil), fields)
|
p.declFieldList(ast.NewScope(nil), fields)
|
||||||
|
|
||||||
return &ast.StructType{pos, lbrace, fields, rbrace, false}
|
return &ast.StructType{pos, &ast.FieldList{lbrace, fields, rbrace}, false}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -679,44 +679,44 @@ func (p *parser) parseParameterList(ellipsisOk bool) []*ast.Field {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (p *parser) parseParameters(scope *ast.Scope, ellipsisOk bool) []*ast.Field {
|
func (p *parser) parseParameters(scope *ast.Scope, ellipsisOk bool) *ast.FieldList {
|
||||||
if p.trace {
|
if p.trace {
|
||||||
defer un(trace(p, "Parameters"))
|
defer un(trace(p, "Parameters"))
|
||||||
}
|
}
|
||||||
|
|
||||||
var params []*ast.Field
|
var params []*ast.Field
|
||||||
p.expect(token.LPAREN)
|
lparen := p.expect(token.LPAREN)
|
||||||
if p.tok != token.RPAREN {
|
if p.tok != token.RPAREN {
|
||||||
params = p.parseParameterList(ellipsisOk)
|
params = p.parseParameterList(ellipsisOk)
|
||||||
p.declFieldList(scope, params)
|
p.declFieldList(scope, params)
|
||||||
}
|
}
|
||||||
p.expect(token.RPAREN)
|
rparen := p.expect(token.RPAREN)
|
||||||
|
|
||||||
return params
|
return &ast.FieldList{lparen, params, rparen}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (p *parser) parseResult(scope *ast.Scope) []*ast.Field {
|
func (p *parser) parseResult(scope *ast.Scope) *ast.FieldList {
|
||||||
if p.trace {
|
if p.trace {
|
||||||
defer un(trace(p, "Result"))
|
defer un(trace(p, "Result"))
|
||||||
}
|
}
|
||||||
|
|
||||||
var results []*ast.Field
|
|
||||||
if p.tok == token.LPAREN {
|
if p.tok == token.LPAREN {
|
||||||
results = p.parseParameters(scope, false)
|
return p.parseParameters(scope, false)
|
||||||
} else {
|
|
||||||
typ := p.tryType()
|
|
||||||
if typ != nil {
|
|
||||||
results = make([]*ast.Field, 1)
|
|
||||||
results[0] = &ast.Field{Type: typ}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return results
|
typ := p.tryType()
|
||||||
|
if typ != nil {
|
||||||
|
list := make([]*ast.Field, 1)
|
||||||
|
list[0] = &ast.Field{Type: typ}
|
||||||
|
return &ast.FieldList{List: list}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (p *parser) parseSignature(scope *ast.Scope) (params []*ast.Field, results []*ast.Field) {
|
func (p *parser) parseSignature(scope *ast.Scope) (params, results *ast.FieldList) {
|
||||||
if p.trace {
|
if p.trace {
|
||||||
defer un(trace(p, "Signature"))
|
defer un(trace(p, "Signature"))
|
||||||
}
|
}
|
||||||
@ -787,7 +787,7 @@ func (p *parser) parseInterfaceType() *ast.InterfaceType {
|
|||||||
// TODO(gri) The interface scope shouldn't get lost.
|
// TODO(gri) The interface scope shouldn't get lost.
|
||||||
p.declFieldList(ast.NewScope(nil), methods)
|
p.declFieldList(ast.NewScope(nil), methods)
|
||||||
|
|
||||||
return &ast.InterfaceType{pos, lbrace, methods, rbrace, false}
|
return &ast.InterfaceType{pos, &ast.FieldList{lbrace, methods, rbrace}, false}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1942,7 +1942,7 @@ func (p *parser) parseGenDecl(keyword token.Token, f parseSpecFunction) *ast.Gen
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (p *parser) parseReceiver(scope *ast.Scope) *ast.Field {
|
func (p *parser) parseReceiver(scope *ast.Scope) *ast.FieldList {
|
||||||
if p.trace {
|
if p.trace {
|
||||||
defer un(trace(p, "Receiver"))
|
defer un(trace(p, "Receiver"))
|
||||||
}
|
}
|
||||||
@ -1951,12 +1951,12 @@ func (p *parser) parseReceiver(scope *ast.Scope) *ast.Field {
|
|||||||
par := p.parseParameters(scope, false)
|
par := p.parseParameters(scope, false)
|
||||||
|
|
||||||
// must have exactly one receiver
|
// must have exactly one receiver
|
||||||
if len(par) != 1 || len(par) == 1 && len(par[0].Names) > 1 {
|
if par.NumFields() != 1 {
|
||||||
p.errorExpected(pos, "exactly one receiver")
|
p.errorExpected(pos, "exactly one receiver")
|
||||||
return &ast.Field{Type: &ast.BadExpr{noPos}}
|
par.List = []*ast.Field{&ast.Field{Type: &ast.BadExpr{noPos}}}
|
||||||
}
|
}
|
||||||
|
|
||||||
recv := par[0]
|
recv := par.List[0]
|
||||||
|
|
||||||
// recv type must be TypeName or *TypeName
|
// recv type must be TypeName or *TypeName
|
||||||
base := recv.Type
|
base := recv.Type
|
||||||
@ -1967,7 +1967,7 @@ func (p *parser) parseReceiver(scope *ast.Scope) *ast.Field {
|
|||||||
p.errorExpected(base.Pos(), "type name")
|
p.errorExpected(base.Pos(), "type name")
|
||||||
}
|
}
|
||||||
|
|
||||||
return recv
|
return par
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1980,7 +1980,7 @@ func (p *parser) parseFuncDecl() *ast.FuncDecl {
|
|||||||
pos := p.expect(token.FUNC)
|
pos := p.expect(token.FUNC)
|
||||||
scope := ast.NewScope(p.funcScope)
|
scope := ast.NewScope(p.funcScope)
|
||||||
|
|
||||||
var recv *ast.Field
|
var recv *ast.FieldList
|
||||||
if p.tok == token.LPAREN {
|
if p.tok == token.LPAREN {
|
||||||
recv = p.parseReceiver(scope)
|
recv = p.parseReceiver(scope)
|
||||||
}
|
}
|
||||||
|
@ -218,10 +218,10 @@ func (p *printer) exprList(prev token.Position, list []ast.Expr, depth int, mode
|
|||||||
|
|
||||||
|
|
||||||
// Sets multiLine to true if the the parameter list spans multiple lines.
|
// Sets multiLine to true if the the parameter list spans multiple lines.
|
||||||
func (p *printer) parameters(list []*ast.Field, multiLine *bool) {
|
func (p *printer) parameters(fields *ast.FieldList, multiLine *bool) {
|
||||||
p.print(token.LPAREN)
|
p.print(fields.Opening, token.LPAREN)
|
||||||
if len(list) > 0 {
|
if len(fields.List) > 0 {
|
||||||
for i, par := range list {
|
for i, par := range fields.List {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
p.print(token.COMMA, blank)
|
p.print(token.COMMA, blank)
|
||||||
}
|
}
|
||||||
@ -232,18 +232,19 @@ func (p *printer) parameters(list []*ast.Field, multiLine *bool) {
|
|||||||
p.expr(par.Type, multiLine)
|
p.expr(par.Type, multiLine)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p.print(token.RPAREN)
|
p.print(fields.Closing, token.RPAREN)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Sets multiLine to true if the signature spans multiple lines.
|
// Sets multiLine to true if the signature spans multiple lines.
|
||||||
func (p *printer) signature(params, result []*ast.Field, multiLine *bool) {
|
func (p *printer) signature(params, result *ast.FieldList, multiLine *bool) {
|
||||||
p.parameters(params, multiLine)
|
p.parameters(params, multiLine)
|
||||||
if result != nil {
|
n := result.NumFields()
|
||||||
|
if n > 0 {
|
||||||
p.print(blank)
|
p.print(blank)
|
||||||
if len(result) == 1 && result[0].Names == nil {
|
if n == 1 && result.List[0].Names == nil {
|
||||||
// single anonymous result; no ()'s
|
// single anonymous result; no ()'s
|
||||||
p.expr(result[0].Type, multiLine)
|
p.expr(result.List[0].Type, multiLine)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
p.parameters(result, multiLine)
|
p.parameters(result, multiLine)
|
||||||
@ -289,7 +290,11 @@ func (p *printer) setLineComment(text string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (p *printer) fieldList(lbrace token.Position, list []*ast.Field, rbrace token.Position, isIncomplete bool, ctxt exprContext) {
|
func (p *printer) fieldList(fields *ast.FieldList, isIncomplete bool, ctxt exprContext) {
|
||||||
|
lbrace := fields.Opening
|
||||||
|
list := fields.List
|
||||||
|
rbrace := fields.Closing
|
||||||
|
|
||||||
if !isIncomplete && !p.commentBefore(rbrace) {
|
if !isIncomplete && !p.commentBefore(rbrace) {
|
||||||
// possibly a one-line struct/interface
|
// possibly a one-line struct/interface
|
||||||
if len(list) == 0 {
|
if len(list) == 0 {
|
||||||
@ -711,7 +716,7 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, ctxt exprContext, multi
|
|||||||
|
|
||||||
case *ast.StructType:
|
case *ast.StructType:
|
||||||
p.print(token.STRUCT)
|
p.print(token.STRUCT)
|
||||||
p.fieldList(x.Lbrace, x.Fields, x.Rbrace, x.Incomplete, ctxt|structType)
|
p.fieldList(x.Fields, x.Incomplete, ctxt|structType)
|
||||||
|
|
||||||
case *ast.FuncType:
|
case *ast.FuncType:
|
||||||
p.print(token.FUNC)
|
p.print(token.FUNC)
|
||||||
@ -719,7 +724,7 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, ctxt exprContext, multi
|
|||||||
|
|
||||||
case *ast.InterfaceType:
|
case *ast.InterfaceType:
|
||||||
p.print(token.INTERFACE)
|
p.print(token.INTERFACE)
|
||||||
p.fieldList(x.Lbrace, x.Methods, x.Rbrace, x.Incomplete, ctxt)
|
p.fieldList(x.Methods, x.Incomplete, ctxt)
|
||||||
|
|
||||||
case *ast.MapType:
|
case *ast.MapType:
|
||||||
p.print(token.MAP, token.LBRACK)
|
p.print(token.MAP, token.LBRACK)
|
||||||
@ -1209,15 +1214,9 @@ func distance(from, to token.Position) int {
|
|||||||
func (p *printer) funcDecl(d *ast.FuncDecl, multiLine *bool) {
|
func (p *printer) funcDecl(d *ast.FuncDecl, multiLine *bool) {
|
||||||
p.setComment(d.Doc)
|
p.setComment(d.Doc)
|
||||||
p.print(d.Pos(), token.FUNC, blank)
|
p.print(d.Pos(), token.FUNC, blank)
|
||||||
if recv := d.Recv; recv != nil {
|
if d.Recv != nil {
|
||||||
// method: print receiver
|
p.parameters(d.Recv, multiLine) // method: print receiver
|
||||||
p.print(token.LPAREN)
|
p.print(blank)
|
||||||
if len(recv.Names) > 0 {
|
|
||||||
p.expr(recv.Names[0], multiLine)
|
|
||||||
p.print(blank)
|
|
||||||
}
|
|
||||||
p.expr(recv.Type, multiLine)
|
|
||||||
p.print(token.RPAREN, blank)
|
|
||||||
}
|
}
|
||||||
p.expr(d.Name, multiLine)
|
p.expr(d.Name, multiLine)
|
||||||
p.signature(d.Type.Params, d.Type.Results, multiLine)
|
p.signature(d.Type.Params, d.Type.Results, multiLine)
|
||||||
|
8
src/pkg/go/printer/testdata/comments.golden
vendored
8
src/pkg/go/printer/testdata/comments.golden
vendored
@ -381,6 +381,14 @@ func _() {
|
|||||||
// Some interesting interspersed comments
|
// Some interesting interspersed comments
|
||||||
func _( /* this */ x /* is */ /* an */ int) {}
|
func _( /* this */ x /* is */ /* an */ int) {}
|
||||||
|
|
||||||
|
func _( /* no params */ ) {}
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
f( /* no args */ )
|
||||||
|
}
|
||||||
|
|
||||||
|
func ( /* comment1 */ T /* comment2 */ ) _() {}
|
||||||
|
|
||||||
|
|
||||||
// Line comments with tabs
|
// Line comments with tabs
|
||||||
func _() {
|
func _() {
|
||||||
|
8
src/pkg/go/printer/testdata/comments.input
vendored
8
src/pkg/go/printer/testdata/comments.input
vendored
@ -382,6 +382,14 @@ func _() {
|
|||||||
func _(/* this */x/* is *//* an */ int) {
|
func _(/* this */x/* is *//* an */ int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func _(/* no params */) {}
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
f(/* no args */)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (/* comment1 */ T /* comment2 */) _() {}
|
||||||
|
|
||||||
|
|
||||||
// Line comments with tabs
|
// Line comments with tabs
|
||||||
func _() {
|
func _() {
|
||||||
|
Loading…
Reference in New Issue
Block a user