1
0
mirror of https://github.com/golang/go synced 2024-11-18 14:24:44 -07:00

go/ast: drop //directive comments from doc.Text

This allows writing

	// F does a thing.
	//go:noinline
	func F()

without the //go:noinline or other directive (such as //line)
ending up looking like extra words in the doc comment.

Fixes #37974.

Change-Id: Ic738d72802cc2fa448f7633915e7126d2f76d8ca
Reviewed-on: https://go-review.googlesource.com/c/go/+/224737
Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
Russ Cox 2020-03-21 08:23:13 -04:00
parent b13ce66d1b
commit 5a550b6951
2 changed files with 70 additions and 6 deletions

View File

@ -87,10 +87,10 @@ func stripTrailingWhitespace(s string) string {
// Text returns the text of the comment.
// Comment markers (//, /*, and */), the first space of a line comment, and
// leading and trailing empty lines are removed. Multiple empty lines are
// reduced to one, and trailing space on lines is trimmed. Unless the result
// is empty, it is newline-terminated.
//
// leading and trailing empty lines are removed.
// Comment directives like "//line" and "//go:noinline" are also removed.
// Multiple empty lines are reduced to one, and trailing space on lines is trimmed.
// Unless the result is empty, it is newline-terminated.
func (g *CommentGroup) Text() string {
if g == nil {
return ""
@ -108,9 +108,18 @@ func (g *CommentGroup) Text() string {
case '/':
//-style comment (no newline at the end)
c = c[2:]
// strip first space - required for Example tests
if len(c) > 0 && c[0] == ' ' {
if len(c) == 0 {
// empty line
break
}
if c[0] == ' ' {
// strip first space - required for Example tests
c = c[1:]
break
}
if isDirective(c) {
// Ignore //go:noinline, //line, and so on.
continue
}
case '*':
/*-style comment */
@ -145,6 +154,32 @@ func (g *CommentGroup) Text() string {
return strings.Join(lines, "\n")
}
// isDirective reports whether c is a comment directive.
func isDirective(c string) bool {
// "//line " is a line directive.
// (The // has been removed.)
if strings.HasPrefix(c, "line ") {
return true
}
// "//[a-z0-9]+:[a-z0-9]"
// (The // has been removed.)
colon := strings.Index(c, ":")
if colon <= 0 || colon+1 >= len(c) {
return false
}
for i := 0; i <= colon+1; i++ {
if i == colon {
continue
}
b := c[i]
if !('a' <= b && b <= 'z' || '0' <= b && b <= '9') {
return false
}
}
return true
}
// ----------------------------------------------------------------------------
// Expressions and types

View File

@ -33,6 +33,9 @@ var comments = []struct {
{[]string{"/* Foo*/", "/*\n*/", "//", "/*\n*/", "// Bar"}, " Foo\n\nBar\n"},
{[]string{"/* Foo*/", "// Bar"}, " Foo\nBar\n"},
{[]string{"/* Foo\n Bar*/"}, " Foo\n Bar\n"},
{[]string{"// foo", "//go:noinline", "// bar", "//:baz"}, "foo\nbar\n:baz\n"},
{[]string{"// foo", "//lint123:ignore", "// bar"}, "foo\nbar\n"},
}
func TestCommentText(t *testing.T) {
@ -48,3 +51,29 @@ func TestCommentText(t *testing.T) {
}
}
}
var isDirectiveTests = []struct {
in string
ok bool
}{
{"abc", false},
{"go:inline", true},
{"Go:inline", false},
{"go:Inline", false},
{":inline", false},
{"lint:ignore", true},
{"lint:1234", true},
{"1234:lint", true},
{"go: inline", false},
{"go:", false},
{"go:*", false},
{"go:x*", true},
}
func TestIsDirective(t *testing.T) {
for _, tt := range isDirectiveTests {
if ok := isDirective(tt.in); ok != tt.ok {
t.Errorf("isDirective(%q) = %v, want %v", tt.in, ok, tt.ok)
}
}
}