Skip to content

Commit eaa5f03

Browse files
committed
Support all leading comment types in StripMarginComments()
The previous version only supported leading block comments, and leading whole-line line comments were not split.
1 parent 16ad9e8 commit eaa5f03

File tree

2 files changed

+83
-12
lines changed

2 files changed

+83
-12
lines changed

comments.go

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,16 @@ func isNonSpace(r rune) bool {
3636
return !unicode.IsSpace(r)
3737
}
3838

39+
func hasLineCommentPrefix(text string) bool {
40+
if strings.HasPrefix(text, "#") {
41+
return true
42+
}
43+
if strings.HasPrefix(text, "--") {
44+
return len(text) == 2 || unicode.IsSpace(rune(text[2]))
45+
}
46+
return false
47+
}
48+
3949
// leadingCommentEnd returns the first index after all leading comments, or
4050
// 0 if there are no leading comments.
4151
func leadingCommentEnd(text string) (end int) {
@@ -51,19 +61,35 @@ func leadingCommentEnd(text string) (end int) {
5161
pos += nextVisibleOffset
5262
remainingText := text[pos:]
5363

54-
// Found visible characters. Look for '/*' at the beginning
55-
// and '*/' somewhere after that.
56-
if len(remainingText) < 4 || remainingText[:2] != "/*" {
57-
break
64+
// Found visible characters. Look for comment prefixes.
65+
if strings.HasPrefix(remainingText, "/*") {
66+
commentLength := 4 + strings.Index(remainingText[2:], "*/")
67+
if commentLength < 4 {
68+
// Missing end comment :/
69+
break
70+
}
71+
hasComment = true
72+
pos += commentLength
73+
continue
5874
}
59-
commentLength := 4 + strings.Index(remainingText[2:], "*/")
60-
if commentLength < 4 {
61-
// Missing end comment :/
62-
break
75+
76+
if hasLineCommentPrefix(remainingText) {
77+
lineEnd := strings.IndexAny(remainingText, "\r\n")
78+
hasComment = true
79+
if lineEnd < 0 {
80+
// Single-line comment runs to end of input.
81+
pos = len(text)
82+
continue
83+
}
84+
pos += lineEnd + 1
85+
// Handle CRLF as a single line terminator.
86+
if remainingText[lineEnd] == '\r' && lineEnd+1 < len(remainingText) && remainingText[lineEnd+1] == '\n' {
87+
pos++
88+
}
89+
continue
6390
}
6491

65-
hasComment = true
66-
pos += commentLength
92+
break
6793
}
6894

6995
if hasComment {
@@ -85,7 +111,7 @@ func trailingCommentStart(text string) (start int) {
85111
break
86112
}
87113
reducedLen = nextReducedLen
88-
if reducedLen < 4 || text[reducedLen-2:reducedLen] != "*/" {
114+
if reducedLen < 2 || text[reducedLen-2:reducedLen] != "*/" {
89115
// Try single-line trailing comments (MySQL supports both '-- ' and '#').
90116
lineStart := reducedLen - 1
91117
for lineStart >= 0 && text[lineStart] != '\n' && text[lineStart] != '\r' {
@@ -210,7 +236,7 @@ type CommentDirectives map[string]interface{}
210236
// ExtractCommentDirectives parses the comment list for any execution directives
211237
// of the form:
212238
//
213-
// /*vt+ OPTION_ONE=1 OPTION_TWO OPTION_THREE=abcd */
239+
// /*vt+ OPTION_ONE=1 OPTION_TWO OPTION_THREE=abcd */
214240
//
215241
// It returns the map of the directive values or nil if there aren't any.
216242
func ExtractCommentDirectives(comments Comments) CommentDirectives {

comments_test.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,51 @@ func TestSplitComments(t *testing.T) {
129129
outSQL: "",
130130
outLeadingComments: "",
131131
outTrailingComments: "# only hash comment",
132+
}, {
133+
input: "-- lead one\nselect 1",
134+
outSQL: "select 1",
135+
outLeadingComments: "-- lead one\n",
136+
outTrailingComments: "",
137+
}, {
138+
input: "--\nselect 1",
139+
outSQL: "select 1",
140+
outLeadingComments: "--\n",
141+
outTrailingComments: "",
142+
}, {
143+
input: "# lead one\nselect 1",
144+
outSQL: "select 1",
145+
outLeadingComments: "# lead one\n",
146+
outTrailingComments: "",
147+
}, {
148+
input: "#\nselect 1",
149+
outSQL: "select 1",
150+
outLeadingComments: "#\n",
151+
outTrailingComments: "",
152+
}, {
153+
input: "-- lead one\r\n# lead two\r\nselect 1",
154+
outSQL: "select 1",
155+
outLeadingComments: "-- lead one\r\n# lead two\r\n",
156+
outTrailingComments: "",
157+
}, {
158+
input: "/**/\nselect 1",
159+
outSQL: "select 1",
160+
outLeadingComments: "/**/\n",
161+
outTrailingComments: "",
162+
}, {
163+
input: "/* lead block */\n-- lead one\n# lead two\nselect 1",
164+
outSQL: "select 1",
165+
outLeadingComments: "/* lead block */\n-- lead one\n# lead two\n",
166+
outTrailingComments: "",
167+
}, {
168+
input: "/*/\nselect 1",
169+
outSQL: "/*/\nselect 1",
170+
outLeadingComments: "",
171+
outTrailingComments: "",
172+
}, {
173+
input: "--not_a_comment\nselect 1",
174+
outSQL: "--not_a_comment\nselect 1",
175+
outLeadingComments: "",
176+
outTrailingComments: "",
132177
}}
133178
for _, testCase := range testCases {
134179
gotSQL, gotComments := SplitMarginComments(testCase.input)

0 commit comments

Comments
 (0)