Skip to content

Commit b334ae7

Browse files
committed
refactor: use descriptable String() methods instead of Fingerprint()
1 parent 1379460 commit b334ae7

4 files changed

Lines changed: 76 additions & 105 deletions

File tree

filter.go

Lines changed: 16 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package pkgdmp
22

33
import (
4-
"hash/fnv"
4+
"fmt"
55
"regexp"
66
"sort"
77
"strings"
@@ -95,13 +95,10 @@ type SymbolFilter interface {
9595
// the filter's logic and configuration.
9696
Include(Symbol) bool
9797

98-
// Fingerprint should return a 64-bit FNV-1a hash of the filter and its
99-
// configuration.
98+
// String should return a string representation of the filter.
10099
//
101-
// This method is intended for testing purposes.
102-
//
103-
// See: https://pkg.go.dev/hash/fnv
104-
Fingerprint() uint64
100+
// This method is mainly intended for testing purposes.
101+
String() string
105102
}
106103

107104
// FilterUnexported creates a filter that determines whether to include or
@@ -122,12 +119,8 @@ func (f *filterUnexported) Include(s Symbol) bool {
122119
return f.action == Include || s.IsExported()
123120
}
124121

125-
func (f *filterUnexported) Fingerprint() uint64 {
126-
h := fnv.New64a()
127-
h.Write([]byte("filterUnexported"))
128-
h.Sum([]byte(f.action.String()))
129-
130-
return h.Sum64()
122+
func (f *filterUnexported) String() string {
123+
return fmt.Sprintf("filterUnexported(action=%s)", f.action)
131124
}
132125

133126
// FilterSymbolTypes creates a filter function that determines whether to
@@ -164,11 +157,7 @@ func (f *filterSymbolTypes) Include(s Symbol) bool {
164157
return !ok
165158
}
166159

167-
func (f *filterSymbolTypes) Fingerprint() uint64 {
168-
h := fnv.New64a()
169-
h.Write([]byte("filterSymbolTypes"))
170-
h.Write([]byte(f.action.String()))
171-
160+
func (f *filterSymbolTypes) String() string {
172161
sts := make([]string, 0, len(f.stMap))
173162

174163
for st := range f.stMap {
@@ -177,28 +166,26 @@ func (f *filterSymbolTypes) Fingerprint() uint64 {
177166

178167
sort.Strings(sts)
179168

180-
h.Sum([]byte(strings.Join(sts, "")))
181-
182-
return h.Sum64()
169+
return fmt.Sprintf("filterSymbolTypes(action=%s,symbolTypes=%s)", f.action, strings.Join(sts, ","))
183170
}
184171

185172
// FilterSymbolTypes creates a filter function that determines whether to
186173
// include or exclude symbols with matching idents.
187174
func FilterMatchingIdents(action FilterAction, p *regexp.Regexp) SymbolFilter {
188-
return &filterMatchingIdents{action: action, p: p}
175+
return &filterMatchingIdents{action: action, pattern: p}
189176
}
190177

191178
type filterMatchingIdents struct {
192-
p *regexp.Regexp
193-
action FilterAction
179+
pattern *regexp.Regexp
180+
action FilterAction
194181
}
195182

196183
func (f *filterMatchingIdents) Include(s Symbol) bool {
197184
if isUnfilterable(s) {
198185
return true
199186
}
200187

201-
match := f.p.MatchString(s.Ident())
188+
match := f.pattern.MatchString(s.Ident())
202189

203190
if f.action == Include {
204191
return match
@@ -207,14 +194,8 @@ func (f *filterMatchingIdents) Include(s Symbol) bool {
207194
return !match
208195
}
209196

210-
func (f *filterMatchingIdents) Fingerprint() uint64 {
211-
h := fnv.New64a()
212-
213-
h.Write([]byte("filterMatchingIdents"))
214-
h.Write([]byte(f.action.String()))
215-
h.Sum([]byte(f.p.String()))
216-
217-
return h.Sum64()
197+
func (f *filterMatchingIdents) String() string {
198+
return fmt.Sprintf("filterMatchingIdents(action=%s,pattern=%s)", f.action, f.pattern)
218199
}
219200

220201
// FilterPackages creates a filter function that determines whether to include
@@ -248,12 +229,7 @@ func (f *filterPackages) Include(s Symbol) bool {
248229
return !ok
249230
}
250231

251-
func (f *filterPackages) Fingerprint() uint64 {
252-
h := fnv.New64a()
253-
254-
h.Write([]byte("filterPackages"))
255-
h.Write([]byte(f.action.String()))
256-
232+
func (f *filterPackages) String() string {
257233
names := make([]string, 0, len(f.pkgMap))
258234

259235
for n := range f.pkgMap {
@@ -262,9 +238,7 @@ func (f *filterPackages) Fingerprint() uint64 {
262238

263239
sort.Strings(names)
264240

265-
h.Sum([]byte(strings.Join(names, "")))
266-
267-
return h.Sum64()
241+
return fmt.Sprintf("filterPackages(action=%s,names=%s)", f.action, strings.Join(names, ","))
268242
}
269243

270244
func isUnfilterable(s Symbol) bool {

internal/cli/flags.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -360,17 +360,20 @@ func usage() {
360360

361361
func strToSymbolTypes(list string) ([]pkgdmp.SymbolType, error) {
362362
ss := strings.Split(list, ",")
363-
res := make([]pkgdmp.SymbolType, len(ss))
363+
res := make([]pkgdmp.SymbolType, 0, len(ss))
364364

365-
for i, s := range ss {
365+
for _, s := range ss {
366366
s = strings.TrimSpace(strings.ToLower(s))
367+
if s == "" {
368+
continue
369+
}
367370

368371
st, ok := symbolTypeMap[s]
369372
if !ok {
370373
return nil, fmt.Errorf("unsupported symbol type string: %q", s)
371374
}
372375

373-
res[i] = st
376+
res = append(res, st)
374377
}
375378

376379
return res, nil

internal/cli/flags_test.go

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -80,25 +80,35 @@ func TestParseFlags(t *testing.T) {
8080

8181
func TestParserOptsFromCfg(t *testing.T) {
8282
tt := []struct {
83-
name string
84-
cfg *cli.Config
85-
wantOptFingerprints []uint64
86-
wantErrRegexp *regexp.Regexp
83+
name string
84+
cfg *cli.Config
85+
wantOpts []string
86+
wantErrRegexp *regexp.Regexp
8787
}{
8888
{
89-
name: "default config",
90-
cfg: &cli.Config{},
91-
wantOptFingerprints: []uint64{2070688686324183492},
89+
name: "default config",
90+
cfg: &cli.Config{},
91+
wantOpts: []string{
92+
"symbolFilters(filters=filterUnexported(action=Exclude))",
93+
},
9294
},
9395
{
94-
name: "full docs and exclude interfaces",
95-
cfg: &cli.Config{FullDocs: true, Exclude: "interface"},
96-
wantOptFingerprints: []uint64{14695981039346656037, 4573527031645899146},
96+
name: "full docs and exclude interfaces",
97+
cfg: &cli.Config{FullDocs: true, Exclude: "interface"},
98+
wantOpts: []string{
99+
"fullDocs",
100+
"symbolFilters(filters=filterUnexported(action=Exclude),filterSymbolTypes(action=Exclude,symbolTypes=SymbolInterfaceType))",
101+
},
97102
},
98103
{
99-
name: "match and exclude patterns",
100-
cfg: &cli.Config{Matching: `^FooBa(r|z)`, ExcludeMatching: `(Hello|Hi)World`},
101-
wantOptFingerprints: []uint64{14104148152248147676},
104+
name: "match and exclude patterns",
105+
cfg: &cli.Config{Matching: `^FooBa(r|z)`, ExcludeMatching: `(Hello|Hi)World`},
106+
wantOpts: []string{
107+
"symbolFilters(filters=" +
108+
"filterUnexported(action=Exclude)," +
109+
"filterMatchingIdents(action=Include,pattern=^FooBa(r|z))," +
110+
"filterMatchingIdents(action=Exclude,pattern=(Hello|Hi)World))",
111+
},
102112
},
103113
{
104114
name: "invalid match regexp",
@@ -116,20 +126,20 @@ func TestParserOptsFromCfg(t *testing.T) {
116126
t.Run(tc.name, func(t *testing.T) {
117127
opts, err := cli.ParserOptsFromCfg(tc.cfg)
118128

119-
if fpLen := len(tc.wantOptFingerprints); fpLen != 0 {
129+
if wOptsLen := len(tc.wantOpts); wOptsLen != 0 {
120130
optsLen := len(opts)
121131

122-
if optsLen != fpLen {
123-
t.Fatalf("expected option length to be %d, but got %d", fpLen, optsLen)
132+
if optsLen != wOptsLen {
133+
t.Fatalf("expected option length to be %d, but got %d", wOptsLen, optsLen)
124134
}
125135

126136
for i, opt := range opts {
127-
wantFp := tc.wantOptFingerprints[i]
128-
actualFp := opt.Fingerprint()
137+
wantOpt := tc.wantOpts[i]
138+
actualOpt := opt.String()
129139

130-
if actualFp != wantFp {
131-
t.Fatalf("expected option at index %d to have fingerprint %d, but has %d",
132-
i, wantFp, actualFp,
140+
if actualOpt != wantOpt {
141+
t.Fatalf("expected option at index %d to be:\n\n%s\n\nbut is:\n\n%s\n\n",
142+
i, wantOpt, actualOpt,
133143
)
134144
}
135145
}

parse.go

Lines changed: 23 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"go/ast"
66
"go/doc"
77
"go/token"
8-
"hash/fnv"
98
"strings"
109
)
1110

@@ -19,13 +18,10 @@ var typeNames = map[token.Token]string{
1918

2019
// ParserOption configures a [Parser].
2120
type ParserOption interface {
22-
// Fingerprint should return a 64-bit FNV-1a hash of the option and its
23-
// configuration.
21+
// String should return a string representation of the option.
2422
//
25-
// This method is intended for testing purposes.
26-
//
27-
// See: https://pkg.go.dev/hash/fnv
28-
Fingerprint() uint64
23+
// This method is mainly intended for testing purposes.
24+
String() string
2925

3026
apply(*Parser) error
3127
}
@@ -361,64 +357,52 @@ func WithFullDocs() ParserOption {
361357

362358
type fullDocs struct{}
363359

360+
func (*fullDocs) String() string {
361+
return "fullDocs"
362+
}
363+
364364
func (*fullDocs) apply(p *Parser) error {
365365
p.fullDocs = true
366366
return nil
367367
}
368368

369-
func (*fullDocs) Fingerprint() uint64 {
370-
h := fnv.New64a()
371-
372-
h.Sum([]byte("fullDocs"))
373-
374-
return h.Sum64()
375-
}
376-
377369
// WithNoDocs configures a [Parser] to not include any doc comments for symbols.
378370
func WithNoDocs() ParserOption {
379371
return &noDocs{}
380372
}
381373

382374
type noDocs struct{}
383375

376+
func (*noDocs) String() string {
377+
return "noDocs"
378+
}
379+
384380
func (*noDocs) apply(p *Parser) error {
385381
p.noDocs = true
386382
return nil
387383
}
388384

389-
func (*noDocs) Fingerprint() uint64 {
390-
h := fnv.New64a()
391-
392-
h.Sum([]byte("noDocs"))
393-
394-
return h.Sum64()
395-
}
396-
397385
// WithSymbolFilters configures a [Parser] to filter package symbols with
398386
// provided filter functions.
399387
func WithSymbolFilters(filters ...SymbolFilter) ParserOption {
400-
return &symbolFilters{f: filters}
388+
return &symbolFilters{filters: filters}
401389
}
402390

403391
type symbolFilters struct {
404-
f []SymbolFilter
405-
}
406-
407-
func (sf *symbolFilters) apply(p *Parser) error {
408-
p.filters = sf.f
409-
return nil
392+
filters []SymbolFilter
410393
}
411394

412-
func (sf *symbolFilters) Fingerprint() uint64 {
413-
h := fnv.New64a()
414-
415-
h.Sum([]byte("symbolFilters"))
395+
func (sf *symbolFilters) String() string {
396+
filters := make([]string, 0, len(sf.filters))
416397

417-
sum := h.Sum64()
418-
419-
for _, f := range sf.f {
420-
sum += f.Fingerprint()
398+
for _, f := range sf.filters {
399+
filters = append(filters, f.String())
421400
}
422401

423-
return sum
402+
return fmt.Sprintf("symbolFilters(filters=%s)", strings.Join(filters, ","))
403+
}
404+
405+
func (sf *symbolFilters) apply(p *Parser) error {
406+
p.filters = sf.filters
407+
return nil
424408
}

0 commit comments

Comments
 (0)