Skip to content

Commit 840e1e4

Browse files
committed
fix concurrent update in StructWrite linter
1 parent c9e019f commit 840e1e4

File tree

1 file changed

+13
-1
lines changed

1 file changed

+13
-1
lines changed

tools/structwrite/structwrite.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"go/types"
77
"regexp"
88
"strings"
9+
"sync"
910

1011
"github.com/golangci/plugin-module-register/register"
1112
"golang.org/x/tools/go/analysis"
@@ -65,6 +66,8 @@ type PluginStructWrite struct {
6566
mutationProtected map[string]struct{}
6667
// Regex of constructor function names, where mutation is allowed.
6768
constructorRegex *regexp.Regexp
69+
70+
mu sync.RWMutex
6871
}
6972

7073
// New creates a new instance of the PluginStructWrite plugin.
@@ -143,7 +146,7 @@ func (p *PluginStructWrite) gatherMutationProtectedTypes(pass *analysis.Pass) {
143146
typeObj := pass.TypesInfo.Defs[typeSpec.Name]
144147
if named, ok := typeObj.Type().(*types.Named); ok {
145148
fullyQualified := named.String()
146-
p.mutationProtected[fullyQualified] = struct{}{}
149+
p.setMutationProtected(fullyQualified)
147150
}
148151
break
149152
}
@@ -242,10 +245,19 @@ func (p *PluginStructWrite) handleCompositeLit(lit *ast.CompositeLit, pass *anal
242245

243246
// isMutationProtected checks whether a fully qualified type is configured to be mutation-protected.
244247
func (p *PluginStructWrite) isMutationProtected(fullyQualifiedTypeName string) bool {
248+
p.mu.RLock()
249+
defer p.mu.RUnlock()
245250
_, ok := p.mutationProtected[fullyQualifiedTypeName]
246251
return ok
247252
}
248253

254+
// setMutationProtected sets a fully qualified type as mutation-protected.
255+
func (p *PluginStructWrite) setMutationProtected(fullyQualifiedTypeName string) {
256+
p.mu.Lock()
257+
defer p.mu.Unlock()
258+
p.mutationProtected[fullyQualifiedTypeName] = struct{}{}
259+
}
260+
249261
// containsTrackedStruct checks whether the field accessed via selector expression belongs to a tracked struct,
250262
// either directly or via embedding.
251263
func (p *PluginStructWrite) containsTrackedStruct(selExpr *ast.SelectorExpr, pass *analysis.Pass) (*types.Named, bool) {

0 commit comments

Comments
 (0)