|
6 | 6 | "go/types" |
7 | 7 | "regexp" |
8 | 8 | "strings" |
| 9 | + "sync" |
9 | 10 |
|
10 | 11 | "github.com/golangci/plugin-module-register/register" |
11 | 12 | "golang.org/x/tools/go/analysis" |
@@ -65,6 +66,8 @@ type PluginStructWrite struct { |
65 | 66 | mutationProtected map[string]struct{} |
66 | 67 | // Regex of constructor function names, where mutation is allowed. |
67 | 68 | constructorRegex *regexp.Regexp |
| 69 | + |
| 70 | + mu sync.RWMutex |
68 | 71 | } |
69 | 72 |
|
70 | 73 | // New creates a new instance of the PluginStructWrite plugin. |
@@ -143,7 +146,7 @@ func (p *PluginStructWrite) gatherMutationProtectedTypes(pass *analysis.Pass) { |
143 | 146 | typeObj := pass.TypesInfo.Defs[typeSpec.Name] |
144 | 147 | if named, ok := typeObj.Type().(*types.Named); ok { |
145 | 148 | fullyQualified := named.String() |
146 | | - p.mutationProtected[fullyQualified] = struct{}{} |
| 149 | + p.setMutationProtected(fullyQualified) |
147 | 150 | } |
148 | 151 | break |
149 | 152 | } |
@@ -242,10 +245,19 @@ func (p *PluginStructWrite) handleCompositeLit(lit *ast.CompositeLit, pass *anal |
242 | 245 |
|
243 | 246 | // isMutationProtected checks whether a fully qualified type is configured to be mutation-protected. |
244 | 247 | func (p *PluginStructWrite) isMutationProtected(fullyQualifiedTypeName string) bool { |
| 248 | + p.mu.RLock() |
| 249 | + defer p.mu.RUnlock() |
245 | 250 | _, ok := p.mutationProtected[fullyQualifiedTypeName] |
246 | 251 | return ok |
247 | 252 | } |
248 | 253 |
|
| 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 | + |
249 | 261 | // containsTrackedStruct checks whether the field accessed via selector expression belongs to a tracked struct, |
250 | 262 | // either directly or via embedding. |
251 | 263 | func (p *PluginStructWrite) containsTrackedStruct(selExpr *ast.SelectorExpr, pass *analysis.Pass) (*types.Named, bool) { |
|
0 commit comments