fix #302: fix concurrent astcache access
This commit is contained in:
parent
dba3907ff3
commit
255a39bcb1
@ -5,7 +5,6 @@ import (
|
|||||||
"go/parser"
|
"go/parser"
|
||||||
"go/token"
|
"go/token"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"golang.org/x/tools/go/packages"
|
"golang.org/x/tools/go/packages"
|
||||||
@ -33,11 +32,7 @@ func NewCache(log logutils.Log) *Cache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c Cache) Get(filename string) *File {
|
func (c Cache) ParsedFilenames() []string {
|
||||||
return c.m[filepath.Clean(filename)]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c Cache) keys() []string {
|
|
||||||
var keys []string
|
var keys []string
|
||||||
for k := range c.m {
|
for k := range c.m {
|
||||||
keys = append(keys, k)
|
keys = append(keys, k)
|
||||||
@ -45,25 +40,22 @@ func (c Cache) keys() []string {
|
|||||||
return keys
|
return keys
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c Cache) GetOrParse(filename string, fset *token.FileSet) *File {
|
func (c Cache) normalizeFilename(filename string) string {
|
||||||
if !filepath.IsAbs(filename) {
|
if filepath.IsAbs(filename) {
|
||||||
absFilename, err := filepath.Abs(filename)
|
return filepath.Clean(filename)
|
||||||
if err != nil {
|
|
||||||
c.log.Warnf("Can't abs-ify filename %s: %s", filename, err)
|
|
||||||
} else {
|
|
||||||
filename = absFilename
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
f := c.m[filename]
|
absFilename, err := filepath.Abs(filename)
|
||||||
if f != nil {
|
if err != nil {
|
||||||
return f
|
c.log.Warnf("Can't abs-ify filename %s: %s", filename, err)
|
||||||
|
return filename
|
||||||
}
|
}
|
||||||
|
|
||||||
c.log.Infof("Parse AST for file %s on demand, existing files are %s",
|
return absFilename
|
||||||
filename, strings.Join(c.keys(), ","))
|
}
|
||||||
c.parseFile(filename, fset)
|
|
||||||
return c.m[filename]
|
func (c Cache) Get(filename string) *File {
|
||||||
|
return c.m[c.normalizeFilename(filename)]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c Cache) GetAllValidFiles() []*File {
|
func (c Cache) GetAllValidFiles() []*File {
|
||||||
@ -81,6 +73,18 @@ func (c *Cache) prepareValidFiles() {
|
|||||||
c.s = files
|
c.s = files
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func LoadFromFilenames(log logutils.Log, filenames ...string) *Cache {
|
||||||
|
c := NewCache(log)
|
||||||
|
|
||||||
|
fset := token.NewFileSet()
|
||||||
|
for _, filename := range filenames {
|
||||||
|
c.parseFile(filename, fset)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.prepareValidFiles()
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
func LoadFromPackages(pkgs []*packages.Package, log logutils.Log) (*Cache, error) {
|
func LoadFromPackages(pkgs []*packages.Package, log logutils.Log) (*Cache, error) {
|
||||||
c := NewCache(log)
|
c := NewCache(log)
|
||||||
|
|
||||||
@ -127,6 +131,8 @@ func (c *Cache) parseFile(filePath string, fset *token.FileSet) {
|
|||||||
fset = token.NewFileSet()
|
fset = token.NewFileSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
filePath = c.normalizeFilename(filePath)
|
||||||
|
|
||||||
// comments needed by e.g. golint
|
// comments needed by e.g. golint
|
||||||
f, err := parser.ParseFile(fset, filePath, nil, parser.ParseComments)
|
f, err := parser.ParseFile(fset, filePath, nil, parser.ParseComments)
|
||||||
c.m[filePath] = &File{
|
c.m[filePath] = &File{
|
||||||
|
@ -92,9 +92,9 @@ func (p *AutogeneratedExclude) getOrCreateFileSummary(i *result.Issue) (*ageFile
|
|||||||
return nil, fmt.Errorf("no file path for issue")
|
return nil, fmt.Errorf("no file path for issue")
|
||||||
}
|
}
|
||||||
|
|
||||||
f := p.astCache.GetOrParse(i.FilePath(), nil)
|
f := p.astCache.Get(i.FilePath())
|
||||||
if f.Err != nil {
|
if f == nil || f.Err != nil {
|
||||||
return nil, fmt.Errorf("can't parse file %s: %s", i.FilePath(), f.Err)
|
return nil, fmt.Errorf("can't parse file %s: %v", i.FilePath(), f)
|
||||||
}
|
}
|
||||||
|
|
||||||
autogenDebugf("file %q: astcache file is %+v", i.FilePath(), *f)
|
autogenDebugf("file %q: astcache file is %+v", i.FilePath(), *f)
|
||||||
|
@ -87,9 +87,9 @@ func (p *Nolint) getOrCreateFileData(i *result.Issue) (*fileData, error) {
|
|||||||
return nil, fmt.Errorf("no file path for issue")
|
return nil, fmt.Errorf("no file path for issue")
|
||||||
}
|
}
|
||||||
|
|
||||||
file := p.astCache.GetOrParse(i.FilePath(), nil)
|
file := p.astCache.Get(i.FilePath())
|
||||||
if file.Err != nil {
|
if file == nil || file.Err != nil {
|
||||||
return nil, fmt.Errorf("can't parse file %s: %s", i.FilePath(), file.Err)
|
return nil, fmt.Errorf("can't parse file %s: %v, astcache is %v", i.FilePath(), file, p.astCache.ParsedFilenames())
|
||||||
}
|
}
|
||||||
|
|
||||||
fd.ignoredRanges = p.buildIgnoredRangesForFile(file.F, file.Fset, i.FilePath())
|
fd.ignoredRanges = p.buildIgnoredRangesForFile(file.F, file.Fset, i.FilePath())
|
||||||
|
@ -31,7 +31,12 @@ func newNolint2FileIssue(line int) result.Issue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func newTestNolintProcessor(log logutils.Log) *Nolint {
|
func newTestNolintProcessor(log logutils.Log) *Nolint {
|
||||||
return NewNolint(astcache.NewCache(log), log)
|
cache := astcache.LoadFromFilenames(log,
|
||||||
|
filepath.Join("testdata", "nolint.go"),
|
||||||
|
filepath.Join("testdata", "nolint2.go"),
|
||||||
|
filepath.Join("testdata", "nolint_bad_names.go"),
|
||||||
|
)
|
||||||
|
return NewNolint(cache, log)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getOkLogger(ctrl *gomock.Controller) *logutils.MockLog {
|
func getOkLogger(ctrl *gomock.Controller) *logutils.MockLog {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user