Skip to content

Commit

Permalink
feat: add comment formatter and unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
hirasawayuki committed Oct 20, 2024
1 parent 629aeea commit f2b2019
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 13 deletions.
49 changes: 36 additions & 13 deletions private/buf/buflsp/symbol.go
Original file line number Diff line number Diff line change
Expand Up @@ -498,24 +498,12 @@ func (s *symbol) FormatDocs(ctx context.Context) string {
var printed bool
for _, comments := range allComments {
for i := 0; i < comments.Len(); i++ {
comment := comments.Index(i).RawText()

// The compiler does not currently provide comments without their
// delimited removed, so we have to do this ourselves.
if strings.HasPrefix(comment, "//") {
// NOTE: We do not trim the space here, because indentation is
// significant for Markdown code fences, and if every line
// starts with a space, Markdown will trim it for us, even off
// of code blocks.
comment = strings.TrimPrefix(comment, "//")
} else {
comment = strings.TrimSuffix(strings.TrimPrefix(comment, "/*"), "*/")
}

comment := formatComment(comments.Index(i).RawText())
if comment != "" {
printed = true
}

// No need to process Markdown in comment; this Just Works!
fmt.Fprintln(&tooltip, comment)
}
Expand All @@ -528,6 +516,41 @@ func (s *symbol) FormatDocs(ctx context.Context) string {
return tooltip.String()
}

// formatComment takes a raw comment string and formats it by removing comment
// delimiters and unnecessary whitespace. It handles both single-line (//) and
// multi-line (/* */) comments.
func formatComment(comment string) string {
comment = strings.TrimSpace(comment)

if strings.HasPrefix(comment, "//") {
// NOTE: We do not trim the space here, because indentation is
// significant for Markdown code fences, and if every line
// starts with a space, Markdown will trim it for us, even off
// of code blocks.
return strings.TrimPrefix(comment, "//")
}

if strings.HasPrefix(comment, "/*") && strings.HasSuffix(comment, "*/") {
comment = strings.Trim(comment, "/*")
// single-line
if !strings.Contains(comment, "\n") {
return strings.TrimSpace(comment)
}

lines := strings.Split(strings.TrimSpace(comment), "\n")
for i, line := range lines {
line = strings.TrimSpace(line)
line = strings.TrimLeft(line, "*")
line = strings.TrimPrefix(line, " ")
lines[i] = line
}

return strings.Join(lines, "\n")
}

return comment
}

// symbolWalker is an AST walker that generates the symbol table for a file in IndexSymbols().
type symbolWalker struct {
file *file
Expand Down
63 changes: 63 additions & 0 deletions private/buf/buflsp/symbol_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package buflsp

import (
"testing"

"github.com/stretchr/testify/assert"
)

func Test_formatComment(t *testing.T) {
t.Parallel()

tests := []struct {
name string
input string
expected string
}{
{
name: "Single-line comment",
input: "// This is a single-line comment",
expected: " This is a single-line comment",
},
{
name: "Multi-line comment",
input: "/*\n * This is a\n * multi-line comment\n */",
expected: "This is a\nmulti-line comment",
},
{
name: "Multi-line comment with mixed indentation",
input: "/*\n * First line\n * - Second line\n * - Third line\n */",
expected: "First line\n- Second line\n - Third line",
},
{
name: "Multi-line comment with multi-asterisks",
input: "/*** This is a\n *** multi-line comment\n *** with multi-asterisks ***/",
expected: "This is a\nmulti-line comment\nwith multi-asterisks",
},
{
name: "Multi-line comment without asterisks",
input: "/* This is a\n multi-line comment\n without asterisks */",
expected: "This is a\nmulti-line comment\nwithout asterisks",
},
{
name: "Single-line multi-line comment",
input: "/* Single-line multi-line comment */",
expected: "Single-line multi-line comment",
},
{
name: "Empty comment",
input: "/**/",
expected: "",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
result := formatComment(tt.input)
if result != tt.expected {
assert.Equal(t, tt.input, result)
}
})
}
}

0 comments on commit f2b2019

Please sign in to comment.