From 0a6114ba2cbb97c7fe98cb4ca2aa95227f81e3ac Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Wed, 4 Nov 2009 10:58:54 -0800 Subject: - respect source line breaks in grouped declarations - made ast.Spec nodes implement Node interface - added extra test cases R=rsc http://go/go-review/1016038 --- src/pkg/go/ast/ast.go | 18 +++++++++++ src/pkg/go/printer/nodes.go | 34 +++++++++---------- src/pkg/go/printer/testdata/declarations.go | 42 ++++++++++++++++++++++++ src/pkg/go/printer/testdata/declarations.golden | 43 +++++++++++++++++++++++++ 4 files changed, 120 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/pkg/go/ast/ast.go b/src/pkg/go/ast/ast.go index 4b90f3b74..efe2af459 100644 --- a/src/pkg/go/ast/ast.go +++ b/src/pkg/go/ast/ast.go @@ -596,6 +596,7 @@ func (s *RangeStmt) stmtNode() {} type ( // The Spec type stands for any of *ImportSpec, *ValueSpec, and *TypeSpec. Spec interface { + Node; specNode(); }; @@ -627,6 +628,23 @@ type ( ) +// Pos() implementations for spec nodes. +// +func (s *ImportSpec) Pos() token.Position { + if s.Name != nil { + return s.Name.Pos(); + } + return s.Path[0].Pos(); +} + +func (s *ValueSpec) Pos() token.Position { + return s.Names[0].Pos(); +} +func (s *TypeSpec) Pos() token.Position { + return s.Name.Pos(); +} + + // specNode() ensures that only spec nodes can be // assigned to a Spec. // diff --git a/src/pkg/go/printer/nodes.go b/src/pkg/go/printer/nodes.go index 20bd18b7e..2aa0a5fba 100644 --- a/src/pkg/go/printer/nodes.go +++ b/src/pkg/go/printer/nodes.go @@ -255,8 +255,12 @@ func (p *printer) fieldList(lbrace token.Position, list []*ast.Field, rbrace tok if len(list) == 1 { sep = blank; } + var ml bool; for i, f := range list { - var ml bool; + if i > 0 { + p.linebreak(f.Pos().Line, 1, 2, ignore, ml); + } + ml = false; extraTabs := 0; p.leadComment(f.Doc); if len(f.Names) > 0 { @@ -283,21 +287,23 @@ func (p *printer) fieldList(lbrace token.Position, list []*ast.Field, rbrace tok } p.lineComment(f.Comment); } - if i+1 < len(list) { - p.linebreak(list[i+1].Pos().Line, 1, 2, ignore, ml); - } else if isIncomplete { - p.print(formfeed); - } } if isIncomplete { + if len(list) > 0 { + p.print(formfeed); + } // TODO(gri): this needs to be styled like normal comments p.print("// contains unexported fields"); } } else { // interface + var ml bool; for i, f := range list { - var ml bool; + if i > 0 { + p.linebreak(f.Pos().Line, 1, 2, ignore, ml); + } + ml = false; p.leadComment(f.Doc); if ftyp, isFtyp := f.Type.(*ast.FuncType); isFtyp { // method @@ -309,13 +315,11 @@ func (p *printer) fieldList(lbrace token.Position, list []*ast.Field, rbrace tok } p.print(token.SEMICOLON); p.lineComment(f.Comment); - if i+1 < len(list) { - p.linebreak(list[i+1].Pos().Line, 1, 2, ignore, ml); - } else if isIncomplete { - p.print(formfeed); - } } if isIncomplete { + if len(list) > 0 { + p.print(formfeed); + } // TODO(gri): this needs to be styled like normal comments p.print("// contains unexported methods"); } @@ -941,11 +945,7 @@ func (p *printer) genDecl(d *ast.GenDecl, context declContext, multiLine *bool) var ml bool; for i, s := range d.Specs { if i > 0 { - if ml { - p.print(formfeed); - } else { - p.print(newline); - } + p.linebreak(s.Pos().Line, 1, 2, ignore, ml); } ml = false; p.spec(s, len(d.Specs), inGroup, &ml); diff --git a/src/pkg/go/printer/testdata/declarations.go b/src/pkg/go/printer/testdata/declarations.go index a697ef736..c54a2ce22 100644 --- a/src/pkg/go/printer/testdata/declarations.go +++ b/src/pkg/go/printer/testdata/declarations.go @@ -21,6 +21,7 @@ import ( import ( "io"; aLongRename "io"; + b "io"; c "i" "o"; ) @@ -93,6 +94,47 @@ func _() { } +// don't lose blank lines in grouped declarations +const ( + _ int = 0; + _ float = 1; + + _ string = "foo"; + + _ = iota; + _; + + // a comment + _; + + _; +) + + +type ( + _ int; + _ struct {}; + + _ interface{}; + + // a comment + _ map[string]int; +) + + +var ( + _ int = 0; + _ float = 1; + + _ string = "foo"; + + _ bool; + + // a comment + _ bool; +) + + // don't lose blank lines in this struct type _ struct { String struct { diff --git a/src/pkg/go/printer/testdata/declarations.golden b/src/pkg/go/printer/testdata/declarations.golden index e238b4581..2adf7b5fe 100644 --- a/src/pkg/go/printer/testdata/declarations.golden +++ b/src/pkg/go/printer/testdata/declarations.golden @@ -21,6 +21,7 @@ import ( import ( "io"; aLongRename "io"; + b "io"; c "i" "o"; ) @@ -94,6 +95,47 @@ func _() { } +// don't lose blank lines in grouped declarations +const ( + _ int = 0; + _ float = 1; + + _ string = "foo"; + + _ = iota; + _; + + // a comment + _; + + _; +) + + +type ( + _ int; + _ struct{}; + + _ interface{}; + + // a comment + _ map[string]int; +) + + +var ( + _ int = 0; + _ float = 1; + + _ string = "foo"; + + _ bool; + + // a comment + _ bool; +) + + // don't lose blank lines in this struct type _ struct { String struct { @@ -200,6 +242,7 @@ func _() { _ int; _ float; _ string; + _ int; // comment _ float; // comment _ string; // comment -- cgit v1.2.3