mirror of
https://github.com/golang/go
synced 2024-11-17 15:54:39 -07:00
go/types: add commentMap and test
This adds the (adjusted) syntax.CommentMap function and corresponding test to the types_test package so that we can use it for collecting ERROR comments in the next CL. For #51006. Change-Id: I63ce96e7394c28c02d5a292250586cc49c1f6e19 Reviewed-on: https://go-review.googlesource.com/c/go/+/456125 Reviewed-by: Robert Findley <rfindley@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Robert Griesemer <gri@google.com> Auto-Submit: Robert Griesemer <gri@google.com> Run-TryBot: Robert Griesemer <gri@google.com>
This commit is contained in:
parent
1e00516583
commit
526b8956c2
103
src/go/types/commentMap_test.go
Normal file
103
src/go/types/commentMap_test.go
Normal file
@ -0,0 +1,103 @@
|
||||
// Copyright 2022 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package types_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/scanner"
|
||||
"go/token"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type comment struct {
|
||||
line, col int // comment position
|
||||
text string // comment text, excluding "//", "/*", or "*/"
|
||||
}
|
||||
|
||||
// commentMap collects all comments in the given src with comment text
|
||||
// that matches the supplied regular expression rx and returns them as
|
||||
// []comment lists in a map indexed by line number. The comment text is
|
||||
// the comment with any comment markers ("//", "/*", or "*/") stripped.
|
||||
// The position for each comment is the position of the token immediately
|
||||
// preceding the comment, with all comments that are on the same line
|
||||
// collected in a slice, in source order. If there is no preceding token
|
||||
// (the matching comment appears at the beginning of the file), then the
|
||||
// recorded position is unknown (line, col = 0, 0).
|
||||
// If there are no matching comments, the result is nil.
|
||||
func commentMap(src []byte, rx *regexp.Regexp) (res map[int][]comment) {
|
||||
fset := token.NewFileSet()
|
||||
file := fset.AddFile("", -1, len(src))
|
||||
|
||||
var s scanner.Scanner
|
||||
s.Init(file, src, nil, scanner.ScanComments)
|
||||
var prev token.Pos // position of last non-comment, non-semicolon token
|
||||
|
||||
for {
|
||||
pos, tok, lit := s.Scan()
|
||||
switch tok {
|
||||
case token.EOF:
|
||||
return
|
||||
case token.COMMENT:
|
||||
if lit[1] == '*' {
|
||||
lit = lit[:len(lit)-2] // strip trailing */
|
||||
}
|
||||
lit = lit[2:] // strip leading // or /*
|
||||
if rx.MatchString(lit) {
|
||||
p := fset.Position(prev)
|
||||
err := comment{p.Line, p.Column, lit}
|
||||
if res == nil {
|
||||
res = make(map[int][]comment)
|
||||
}
|
||||
res[p.Line] = append(res[p.Line], err)
|
||||
}
|
||||
case token.SEMICOLON:
|
||||
// ignore automatically inserted semicolon
|
||||
if lit == "\n" {
|
||||
continue
|
||||
}
|
||||
fallthrough
|
||||
default:
|
||||
prev = pos
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommentMap(t *testing.T) {
|
||||
const src = `/* ERROR "0:0" */ /* ERROR "0:0" */ // ERROR "0:0"
|
||||
// ERROR "0:0"
|
||||
x /* ERROR "3:1" */ // ignore automatically inserted semicolon here
|
||||
/* ERROR "3:1" */ // position of x on previous line
|
||||
x /* ERROR "5:4" */ ; // do not ignore this semicolon
|
||||
/* ERROR "5:24" */ // position of ; on previous line
|
||||
package /* ERROR "7:2" */ // indented with tab
|
||||
import /* ERROR "8:9" */ // indented with blanks
|
||||
`
|
||||
m := commentMap([]byte(src), regexp.MustCompile("^ ERROR "))
|
||||
found := 0 // number of errors found
|
||||
for line, errlist := range m {
|
||||
for _, err := range errlist {
|
||||
if err.line != line {
|
||||
t.Errorf("%v: got map line %d; want %d", err, err.line, line)
|
||||
continue
|
||||
}
|
||||
// err.line == line
|
||||
|
||||
got := strings.TrimSpace(err.text[len(" ERROR "):])
|
||||
want := fmt.Sprintf(`"%d:%d"`, line, err.col)
|
||||
if got != want {
|
||||
t.Errorf("%v: got msg %q; want %q", err, got, want)
|
||||
continue
|
||||
}
|
||||
found++
|
||||
}
|
||||
}
|
||||
|
||||
want := strings.Count(src, " ERROR ")
|
||||
if found != want {
|
||||
t.Errorf("commentMap got %d errors; want %d", found, want)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user