Skip to content

Commit ae132b4

Browse files
committed
Apply feedback
1 parent 5502674 commit ae132b4

File tree

2 files changed

+40
-12
lines changed

2 files changed

+40
-12
lines changed

v2/comments.go

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ func (s *tagKeyScanner) parseTagKey(tagNames []string) (string, []string, error)
249249
if len(tagNames) > 0 && !slices.Contains(tagNames, tagName) {
250250
return "", nil, nil
251251
}
252-
if s.Peek() != '(' {
252+
if s.PeekSkipSpaces() != '(' {
253253
return tagName, nil, nil
254254
}
255255
s.Scan() // consume the '(' token
@@ -269,10 +269,10 @@ func (s *tagKeyScanner) parseTagKey(tagNames []string) (string, []string, error)
269269
//
270270
// The argument may be a go style identifier, a quoted string ("..."), or a raw string (`...`).
271271
func (s *tagKeyScanner) parseTagArgs() ([]string, error) {
272-
if s.Peek() == ')' {
272+
if s.PeekSkipSpaces() == ')' {
273273
return nil, nil
274274
}
275-
if s.Peek() == '{' || s.Peek() == '[' {
275+
if s.PeekSkipSpaces() == '{' || s.PeekSkipSpaces() == '[' {
276276
value, err := s.scanJSONFlavoredValue()
277277
if err != nil {
278278
return nil, err
@@ -290,6 +290,7 @@ func (s *tagKeyScanner) parseTagArgs() ([]string, error) {
290290
// scanJSONFlavoredValue consumes a single token as a JSON value from the scanner and returns the token text.
291291
// A strict subset of JSON is supported, in particular:
292292
// - Big numbers and numbers with exponents are not supported.
293+
// - JSON is expected to be in a single line. Tabs and newlines are not fully supported.
293294
func (s *tagKeyScanner) scanJSONFlavoredValue() (string, error) {
294295
start, end, err := s.chompJSONFlavoredValue()
295296
if err != nil {
@@ -306,7 +307,7 @@ func (s *tagKeyScanner) scanJSONFlavoredValue() (string, error) {
306307

307308
// chompJSONFlavoredValue consumes valid JSON from the scanner's token stream and returns the start and end positions of the JSON.
308309
func (s *tagKeyScanner) chompJSONFlavoredValue() (int, int, error) {
309-
switch s.Peek() {
310+
switch s.PeekSkipSpaces() {
310311
case '[':
311312
return s.chompJSONFlavoredArray()
312313
case '{':
@@ -338,7 +339,7 @@ func (s *tagKeyScanner) chompJSONFlavoredObject() (int, int, error) {
338339
return 0, 0, s.unexpectedTokenError("JSON array", s.TokenText())
339340
}
340341
startPos := s.Offset
341-
if s.Peek() == '}' {
342+
if s.PeekSkipSpaces() == '}' {
342343
s.Scan() // consume }
343344
return startPos, s.Offset + 1, nil
344345
}
@@ -367,7 +368,7 @@ func (s *tagKeyScanner) chompJSONFlavoredObjectEntries() (int, int, error) {
367368
return 0, 0, err
368369
}
369370

370-
switch s.Peek() {
371+
switch s.PeekSkipSpaces() {
371372
case ',':
372373
s.Scan() // Consume ,
373374
_, entriesEnd, err := s.chompJSONFlavoredObjectEntries()
@@ -387,7 +388,7 @@ func (s *tagKeyScanner) chompJSONFlavoredArray() (int, int, error) {
387388
return 0, 0, s.unexpectedTokenError("JSON array", s.TokenText())
388389
}
389390
startPos := s.Offset
390-
if s.Peek() == ']' {
391+
if s.PeekSkipSpaces() == ']' {
391392
s.Scan() // consume ]
392393
return startPos, s.Offset + 1, nil
393394
}
@@ -407,7 +408,7 @@ func (s *tagKeyScanner) chompJSONFlavoredArrayItems() (int, int, error) {
407408
return 0, 0, err
408409
}
409410

410-
switch s.Peek() {
411+
switch s.PeekSkipSpaces() {
411412
case ',':
412413
s.Scan() // Consume ,
413414
_, itemsEnd, err := s.chompJSONFlavoredArrayItems()
@@ -430,16 +431,24 @@ type tagKeyScanner struct {
430431

431432
func initTagKeyScanner(input string) *tagKeyScanner {
432433
s := tagKeyScanner{input: input, Scanner: &scanner.Scanner{}}
433-
s.Mode = scanner.ScanIdents | scanner.ScanStrings | scanner.ScanRawStrings | scanner.ScanInts | scanner.ScanFloats
434-
s.Whitespace = 0 // disable whitespace scanning
435434
s.Init(strings.NewReader(input))
435+
s.Mode = scanner.ScanIdents | scanner.ScanStrings | scanner.ScanRawStrings | scanner.ScanInts | scanner.ScanFloats
436436

437437
s.Error = func(scanner *scanner.Scanner, msg string) {
438438
s.errs = append(s.errs, fmt.Errorf("error parsing '%s' at %v: %s", input, scanner.Position, msg))
439439
}
440440
return &s
441441
}
442442

443+
func (s *tagKeyScanner) PeekSkipSpaces() rune {
444+
ch := s.Peek()
445+
for ch == ' ' {
446+
s.Next() // Consume the ' '
447+
ch = s.Peek()
448+
}
449+
return ch
450+
}
451+
443452
func (s *tagKeyScanner) unexpectedTokenError(expected string, token string) error {
444453
s.Error(s.Scanner, fmt.Sprintf("expected %s but got (%q)", expected, token))
445454
return errors.Join(s.errs...)

v2/comments_test.go

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"reflect"
2121
"strings"
2222
"testing"
23+
"text/scanner"
2324

2425
"github.com/google/go-cmp/cmp"
2526
)
@@ -372,8 +373,9 @@ func TestParseTagKeyWithTagNames(t *testing.T) {
372373

373374
func TestParseJSON(t *testing.T) {
374375
cases := []struct {
375-
input string
376-
err bool
376+
input string
377+
err bool
378+
incomplete bool
377379
}{
378380
{
379381
input: `[]`,
@@ -411,6 +413,15 @@ func TestParseJSON(t *testing.T) {
411413
{
412414
input: "null",
413415
},
416+
{
417+
input: `{"key":"value" }`,
418+
},
419+
{
420+
input: `[1 ]`,
421+
},
422+
{
423+
input: `[1 ,2]`,
424+
},
414425

415426
// invalid
416427
{
@@ -437,6 +448,9 @@ func TestParseJSON(t *testing.T) {
437448
input: `UNKNOWN`,
438449
err: true,
439450
},
451+
{
452+
input: `1.4e-10`, // parse consumes 1.4, not the full number
453+
},
440454
}
441455

442456
for _, tc := range cases {
@@ -456,6 +470,11 @@ func TestParseJSON(t *testing.T) {
456470
t.Errorf("expected %q got %q", tc.input, out)
457471
}
458472
}
473+
474+
gotIncomplete := s.Scan() != scanner.EOF
475+
if tc.incomplete != gotIncomplete {
476+
t.Errorf("Expected incomplete=%t but got %t", tc.incomplete, gotIncomplete)
477+
}
459478
})
460479
}
461480
}

0 commit comments

Comments
 (0)