-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfix.go
More file actions
112 lines (98 loc) · 2.49 KB
/
fix.go
File metadata and controls
112 lines (98 loc) · 2.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package lint
import (
"fmt"
"sort"
"sync"
)
// FixableRule is implemented by rules that support auto-fix.
type FixableRule interface {
FixMeta() FixMeta
Fix(ctx *FixContext) error
}
// FixMeta describes a fixer's identity.
type FixMeta struct {
RuleName string
Description string
}
// FixContext provides everything a fixer needs.
type FixContext struct {
Config *Config
Analyzer *CodebaseAnalyzer
Options Options
DryRun bool
mu sync.Mutex
results []FixResult
}
// FixResult records a single file fix.
type FixResult struct {
File string
RuleName string
}
// RecordFix records that a file was fixed by a rule.
func (c *FixContext) RecordFix(file, rule string) {
c.mu.Lock()
defer c.mu.Unlock()
c.results = append(c.results, FixResult{File: file, RuleName: rule})
}
// Results returns all recorded fix results.
func (c *FixContext) Results() []FixResult {
c.mu.Lock()
defer c.mu.Unlock()
out := make([]FixResult, len(c.results))
copy(out, c.results)
return out
}
// --- Fixer Registry ---
var (
fixersMu sync.RWMutex
fixers = make(map[string]FixableRule)
)
// RegisterFixer adds a fixer to the global registry. Typically called in init().
func RegisterFixer(f FixableRule) {
fixersMu.Lock()
defer fixersMu.Unlock()
name := f.FixMeta().RuleName
if _, exists := fixers[name]; exists {
panic(fmt.Sprintf("cht-go-lint: fixer %q already registered", name))
}
fixers[name] = f
}
// GetFixer returns a fixer by rule name, or nil if not found.
func GetFixer(name string) FixableRule {
fixersMu.RLock()
defer fixersMu.RUnlock()
return fixers[name]
}
// AllFixers returns all registered fixers sorted by rule name.
func AllFixers() []FixableRule {
fixersMu.RLock()
defer fixersMu.RUnlock()
result := make([]FixableRule, 0, len(fixers))
for _, f := range fixers {
result = append(result, f)
}
sort.Slice(result, func(i, j int) bool {
return result[i].FixMeta().RuleName < result[j].FixMeta().RuleName
})
return result
}
// RunFixers executes all enabled fixers and returns fix results.
func RunFixers(cfg *Config, analyzer *CodebaseAnalyzer, dryRun bool) []FixResult {
ctx := &FixContext{
Config: cfg,
Analyzer: analyzer,
DryRun: dryRun,
}
for _, fixer := range AllFixers() {
name := fixer.FixMeta().RuleName
if cfg.EffectiveSeverity(name, "") == Off {
continue
}
if rule := Get(name); rule != nil && !tierSatisfied(rule.Meta().Tier, cfg) {
continue
}
ctx.Options = NewOptions(cfg.RuleOptions(name))
_ = fixer.Fix(ctx)
}
return ctx.Results()
}