]> Cypherpunks repositories - gostls13.git/commitdiff
go/parser: include more comments in a struct or interface
authorAgniva De Sarker <agnivade@yahoo.co.in>
Mon, 4 Feb 2019 07:31:11 +0000 (13:01 +0530)
committerRobert Griesemer <gri@golang.org>
Wed, 6 Mar 2019 06:05:15 +0000 (06:05 +0000)
While parsing inside a struct or an interface, skipping over empty lines
too to collect the next group of comments. We do not need to skip
over more than 1 empty line since gofmt already removes multiple
empty consecutive lines.

Fixes #10858

Change-Id: I0c97b65b5fc44e225e5dc7871ace24f43419ce08
Reviewed-on: https://go-review.googlesource.com/c/go/+/161177
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
src/go/doc/testdata/issue10858.0.golden [new file with mode: 0644]
src/go/doc/testdata/issue10858.1.golden [new file with mode: 0644]
src/go/doc/testdata/issue10858.2.golden [new file with mode: 0644]
src/go/doc/testdata/issue10858.go [new file with mode: 0644]
src/go/parser/parser.go

diff --git a/src/go/doc/testdata/issue10858.0.golden b/src/go/doc/testdata/issue10858.0.golden
new file mode 100644 (file)
index 0000000..51f8f1e
--- /dev/null
@@ -0,0 +1,79 @@
+// 
+PACKAGE issue10858
+
+IMPORTPATH
+       testdata/issue10858
+
+IMPORTS
+       unsafe
+
+FILENAMES
+       testdata/issue10858.go
+
+CONSTANTS
+       // First line  Second line 
+       const (
+       
+               // C1 comment
+               C1      int     = 1 << 0
+       
+               C2      int     = 1 << 1
+       
+               // C3 comment
+               //
+               // with a line gap
+               C3      int     = 1 << 2
+       )
+
+
+TYPES
+       // StructTag is a comment  with 2 connecting lines 
+       type StructTag string   // adjacent comment
+
+       // Get returns the value associated with key in the tag string. 
+       func (tag StructTag) Get(key string) string
+
+       // First line  Second line 
+       type Type interface {
+               // Should be present
+       
+               // Align returns the alignment in bytes of a value of
+               // this type when allocated in memory.
+               Align() int
+       
+               // FieldAlign returns the alignment in bytes of a value of
+               // this type when used as a field in a struct.
+               FieldAlign() int        // adjacent comment
+       
+               //      Ptr: Elem
+               //      Slice: Elem
+       
+               // Bits returns the size of the type in bits.
+       
+               //
+               // It panics if the type's Kind is not one of the
+               // sized or unsized Int, Uint, Float, or Complex kinds.
+               Bits() int
+       }
+
+       // NewType is a comment  ending with this line. 
+       func NewType() Type
+
+       // TypeAlg is a copy of runtime.typeAlg 
+       type TypeAlg struct {
+               // function for hashing objects of this type
+               //
+               //
+               // (ptr to object, seed) -> hash
+               Hash    func(unsafe.Pointer, uintptr) uintptr
+       
+               // include
+               // include
+       
+               // include
+       
+               // function for comparing objects of this type
+               // (ptr to object A, ptr to object B) -> ==?
+               Equal   func(unsafe.Pointer, unsafe.Pointer) bool
+       }
+
diff --git a/src/go/doc/testdata/issue10858.1.golden b/src/go/doc/testdata/issue10858.1.golden
new file mode 100644 (file)
index 0000000..51f8f1e
--- /dev/null
@@ -0,0 +1,79 @@
+// 
+PACKAGE issue10858
+
+IMPORTPATH
+       testdata/issue10858
+
+IMPORTS
+       unsafe
+
+FILENAMES
+       testdata/issue10858.go
+
+CONSTANTS
+       // First line  Second line 
+       const (
+       
+               // C1 comment
+               C1      int     = 1 << 0
+       
+               C2      int     = 1 << 1
+       
+               // C3 comment
+               //
+               // with a line gap
+               C3      int     = 1 << 2
+       )
+
+
+TYPES
+       // StructTag is a comment  with 2 connecting lines 
+       type StructTag string   // adjacent comment
+
+       // Get returns the value associated with key in the tag string. 
+       func (tag StructTag) Get(key string) string
+
+       // First line  Second line 
+       type Type interface {
+               // Should be present
+       
+               // Align returns the alignment in bytes of a value of
+               // this type when allocated in memory.
+               Align() int
+       
+               // FieldAlign returns the alignment in bytes of a value of
+               // this type when used as a field in a struct.
+               FieldAlign() int        // adjacent comment
+       
+               //      Ptr: Elem
+               //      Slice: Elem
+       
+               // Bits returns the size of the type in bits.
+       
+               //
+               // It panics if the type's Kind is not one of the
+               // sized or unsized Int, Uint, Float, or Complex kinds.
+               Bits() int
+       }
+
+       // NewType is a comment  ending with this line. 
+       func NewType() Type
+
+       // TypeAlg is a copy of runtime.typeAlg 
+       type TypeAlg struct {
+               // function for hashing objects of this type
+               //
+               //
+               // (ptr to object, seed) -> hash
+               Hash    func(unsafe.Pointer, uintptr) uintptr
+       
+               // include
+               // include
+       
+               // include
+       
+               // function for comparing objects of this type
+               // (ptr to object A, ptr to object B) -> ==?
+               Equal   func(unsafe.Pointer, unsafe.Pointer) bool
+       }
+
diff --git a/src/go/doc/testdata/issue10858.2.golden b/src/go/doc/testdata/issue10858.2.golden
new file mode 100644 (file)
index 0000000..51f8f1e
--- /dev/null
@@ -0,0 +1,79 @@
+// 
+PACKAGE issue10858
+
+IMPORTPATH
+       testdata/issue10858
+
+IMPORTS
+       unsafe
+
+FILENAMES
+       testdata/issue10858.go
+
+CONSTANTS
+       // First line  Second line 
+       const (
+       
+               // C1 comment
+               C1      int     = 1 << 0
+       
+               C2      int     = 1 << 1
+       
+               // C3 comment
+               //
+               // with a line gap
+               C3      int     = 1 << 2
+       )
+
+
+TYPES
+       // StructTag is a comment  with 2 connecting lines 
+       type StructTag string   // adjacent comment
+
+       // Get returns the value associated with key in the tag string. 
+       func (tag StructTag) Get(key string) string
+
+       // First line  Second line 
+       type Type interface {
+               // Should be present
+       
+               // Align returns the alignment in bytes of a value of
+               // this type when allocated in memory.
+               Align() int
+       
+               // FieldAlign returns the alignment in bytes of a value of
+               // this type when used as a field in a struct.
+               FieldAlign() int        // adjacent comment
+       
+               //      Ptr: Elem
+               //      Slice: Elem
+       
+               // Bits returns the size of the type in bits.
+       
+               //
+               // It panics if the type's Kind is not one of the
+               // sized or unsized Int, Uint, Float, or Complex kinds.
+               Bits() int
+       }
+
+       // NewType is a comment  ending with this line. 
+       func NewType() Type
+
+       // TypeAlg is a copy of runtime.typeAlg 
+       type TypeAlg struct {
+               // function for hashing objects of this type
+               //
+               //
+               // (ptr to object, seed) -> hash
+               Hash    func(unsafe.Pointer, uintptr) uintptr
+       
+               // include
+               // include
+       
+               // include
+       
+               // function for comparing objects of this type
+               // (ptr to object A, ptr to object B) -> ==?
+               Equal   func(unsafe.Pointer, unsafe.Pointer) bool
+       }
+
diff --git a/src/go/doc/testdata/issue10858.go b/src/go/doc/testdata/issue10858.go
new file mode 100644 (file)
index 0000000..aebea50
--- /dev/null
@@ -0,0 +1,102 @@
+package issue10858
+
+import "unsafe"
+
+// Should be ignored
+
+// First line
+//
+// Second line
+type Type interface {
+       // Should be present
+
+       // Align returns the alignment in bytes of a value of
+       // this type when allocated in memory.
+       Align() int
+
+       // FieldAlign returns the alignment in bytes of a value of
+       // this type when used as a field in a struct.
+       FieldAlign() int // adjacent comment
+
+       //      Ptr: Elem
+       //      Slice: Elem
+
+       // Bits returns the size of the type in bits.
+
+       //
+       // It panics if the type's Kind is not one of the
+       // sized or unsized Int, Uint, Float, or Complex kinds.
+       Bits() int
+
+       // Should be ignored
+}
+
+// Should be ignored
+
+// NewType is a comment
+//
+// ending with this line.
+func NewType() Type {}
+
+// Ignore
+
+// First line
+//
+// Second line
+const (
+       // Should be ignored
+
+       // C1 comment
+       C1 int = 1 << 0
+
+       // Should
+       //
+       // be ignored
+
+       C2 int = 1 << 1
+
+       // C3 comment
+       //
+       // with a line gap
+       C3 int = 1 << 2
+
+       // Should be ignored
+)
+
+// Should be ignored
+
+// Should be ignored
+
+// TypeAlg is a
+// copy of runtime.typeAlg
+type TypeAlg struct {
+       // function for hashing objects of this type
+       //
+       //
+       // (ptr to object, seed) -> hash
+       Hash func(unsafe.Pointer, uintptr) uintptr
+
+       // include
+       // include
+
+       // include
+
+       // function for comparing objects of this type
+       // (ptr to object A, ptr to object B) -> ==?
+       Equal func(unsafe.Pointer, unsafe.Pointer) bool
+       // Should be ignored
+}
+
+// Should be ignored
+
+// StructTag is a comment
+//
+//
+// with 2 connecting lines
+type StructTag string // adjacent comment
+
+// Should be ignored
+
+// Get returns the value associated with key in the tag string.
+func (tag StructTag) Get(key string) string {
+}
index ba16b652246f11bcae4c99e21ca29420fb830f53..9294bb6b3ef690f78b60f681dfd781c6d2448097 100644 (file)
@@ -63,6 +63,7 @@ type parser struct {
        topScope   *ast.Scope        // top-most scope; may be pkgScope
        unresolved []*ast.Ident      // unresolved identifiers
        imports    []*ast.ImportSpec // list of imports
+       inStruct   bool              // if set, parser is parsing a struct or interface (for comment collection)
 
        // Label scopes
        // (maintained by open/close LabelScope)
@@ -337,7 +338,15 @@ func (p *parser) next() {
                // consume successor comments, if any
                endline = -1
                for p.tok == token.COMMENT {
-                       comment, endline = p.consumeCommentGroup(1)
+                       n := 1
+                       // When inside a struct (or interface), we don't want to lose comments
+                       // separated from individual field (or method) documentation by empty
+                       // lines. Allow for some white space in this case and collect those
+                       // comments as a group. See issue #10858 for details.
+                       if p.inStruct {
+                               n = 2
+                       }
+                       comment, endline = p.consumeCommentGroup(n)
                }
 
                if endline+1 == p.file.Line(p.pos) {
@@ -748,6 +757,7 @@ func (p *parser) parseStructType() *ast.StructType {
        }
 
        pos := p.expect(token.STRUCT)
+       p.inStruct = true
        lbrace := p.expect(token.LBRACE)
        scope := ast.NewScope(nil) // struct scope
        var list []*ast.Field
@@ -758,6 +768,7 @@ func (p *parser) parseStructType() *ast.StructType {
                list = append(list, p.parseFieldDecl(scope))
        }
        rbrace := p.expect(token.RBRACE)
+       p.inStruct = false
 
        return &ast.StructType{
                Struct: pos,
@@ -959,6 +970,7 @@ func (p *parser) parseInterfaceType() *ast.InterfaceType {
        }
 
        pos := p.expect(token.INTERFACE)
+       p.inStruct = true
        lbrace := p.expect(token.LBRACE)
        scope := ast.NewScope(nil) // interface scope
        var list []*ast.Field
@@ -966,6 +978,7 @@ func (p *parser) parseInterfaceType() *ast.InterfaceType {
                list = append(list, p.parseMethodSpec(scope))
        }
        rbrace := p.expect(token.RBRACE)
+       p.inStruct = false
 
        return &ast.InterfaceType{
                Interface: pos,