Skip to content

Commit 10cd673

Browse files
committed
fix #302: fix concurrent astcache access
1 parent dba3907 commit 10cd673

File tree

4 files changed

+39
-28
lines changed

4 files changed

+39
-28
lines changed

pkg/lint/astcache/astcache.go

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"go/parser"
66
"go/token"
77
"path/filepath"
8-
"strings"
98
"time"
109

1110
"golang.org/x/tools/go/packages"
@@ -33,37 +32,30 @@ func NewCache(log logutils.Log) *Cache {
3332
}
3433
}
3534

36-
func (c Cache) Get(filename string) *File {
37-
return c.m[filepath.Clean(filename)]
38-
}
39-
40-
func (c Cache) keys() []string {
35+
func (c Cache) ParsedFilenames() []string {
4136
var keys []string
4237
for k := range c.m {
4338
keys = append(keys, k)
4439
}
4540
return keys
4641
}
4742

48-
func (c Cache) GetOrParse(filename string, fset *token.FileSet) *File {
49-
if !filepath.IsAbs(filename) {
50-
absFilename, err := filepath.Abs(filename)
51-
if err != nil {
52-
c.log.Warnf("Can't abs-ify filename %s: %s", filename, err)
53-
} else {
54-
filename = absFilename
55-
}
43+
func (c Cache) normalizeFilename(filename string) string {
44+
if filepath.IsAbs(filename) {
45+
return filepath.Clean(filename)
5646
}
5747

58-
f := c.m[filename]
59-
if f != nil {
60-
return f
48+
absFilename, err := filepath.Abs(filename)
49+
if err != nil {
50+
c.log.Warnf("Can't abs-ify filename %s: %s", filename, err)
51+
return filename
6152
}
6253

63-
c.log.Infof("Parse AST for file %s on demand, existing files are %s",
64-
filename, strings.Join(c.keys(), ","))
65-
c.parseFile(filename, fset)
66-
return c.m[filename]
54+
return absFilename
55+
}
56+
57+
func (c Cache) Get(filename string) *File {
58+
return c.m[c.normalizeFilename(filename)]
6759
}
6860

6961
func (c Cache) GetAllValidFiles() []*File {
@@ -81,6 +73,18 @@ func (c *Cache) prepareValidFiles() {
8173
c.s = files
8274
}
8375

76+
func LoadFromFilenames(log logutils.Log, filenames ...string) *Cache {
77+
c := NewCache(log)
78+
79+
fset := token.NewFileSet()
80+
for _, filename := range filenames {
81+
c.parseFile(filename, fset)
82+
}
83+
84+
c.prepareValidFiles()
85+
return c
86+
}
87+
8488
func LoadFromPackages(pkgs []*packages.Package, log logutils.Log) (*Cache, error) {
8589
c := NewCache(log)
8690

@@ -127,6 +131,8 @@ func (c *Cache) parseFile(filePath string, fset *token.FileSet) {
127131
fset = token.NewFileSet()
128132
}
129133

134+
filePath = c.normalizeFilename(filePath)
135+
130136
// comments needed by e.g. golint
131137
f, err := parser.ParseFile(fset, filePath, nil, parser.ParseComments)
132138
c.m[filePath] = &File{

pkg/result/processors/autogenerated_exclude.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,9 @@ func (p *AutogeneratedExclude) getOrCreateFileSummary(i *result.Issue) (*ageFile
9292
return nil, fmt.Errorf("no file path for issue")
9393
}
9494

95-
f := p.astCache.GetOrParse(i.FilePath(), nil)
96-
if f.Err != nil {
97-
return nil, fmt.Errorf("can't parse file %s: %s", i.FilePath(), f.Err)
95+
f := p.astCache.Get(i.FilePath())
96+
if f == nil || f.Err != nil {
97+
return nil, fmt.Errorf("can't parse file %s: %v", i.FilePath(), f)
9898
}
9999

100100
autogenDebugf("file %q: astcache file is %+v", i.FilePath(), *f)

pkg/result/processors/nolint.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,9 @@ func (p *Nolint) getOrCreateFileData(i *result.Issue) (*fileData, error) {
8787
return nil, fmt.Errorf("no file path for issue")
8888
}
8989

90-
file := p.astCache.GetOrParse(i.FilePath(), nil)
91-
if file.Err != nil {
92-
return nil, fmt.Errorf("can't parse file %s: %s", i.FilePath(), file.Err)
90+
file := p.astCache.Get(i.FilePath())
91+
if file == nil || file.Err != nil {
92+
return nil, fmt.Errorf("can't parse file %s: %v, astcache is %v", i.FilePath(), file, p.astCache.ParsedFilenames())
9393
}
9494

9595
fd.ignoredRanges = p.buildIgnoredRangesForFile(file.F, file.Fset, i.FilePath())

pkg/result/processors/nolint_test.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,12 @@ func newNolint2FileIssue(line int) result.Issue {
3131
}
3232

3333
func newTestNolintProcessor(log logutils.Log) *Nolint {
34-
return NewNolint(astcache.NewCache(log), log)
34+
cache := astcache.LoadFromFilenames(log,
35+
filepath.Join("testdata", "nolint.go"),
36+
filepath.Join("testdata", "nolint2.go"),
37+
filepath.Join("testdata", "nolint_bad_names.go"),
38+
)
39+
return NewNolint(cache, log)
3540
}
3641

3742
func getOkLogger(ctrl *gomock.Controller) *logutils.MockLog {

0 commit comments

Comments
 (0)