5
5
"go/types"
6
6
"strconv"
7
7
"strings"
8
+ "sync"
8
9
9
10
"github.com/gostaticanalysis/analysisutil"
10
11
"golang.org/x/tools/go/analysis"
@@ -13,16 +14,25 @@ import (
13
14
"golang.org/x/tools/go/ssa"
14
15
)
15
16
16
- func NewAnalyzer () * analysis.Analyzer {
17
- return & analysis.Analyzer {
17
+ type Configuration struct {
18
+ DisableFact bool
19
+ }
20
+
21
+ func NewAnalyzer (cfg Configuration ) * analysis.Analyzer {
22
+ analyzer := & analysis.Analyzer {
18
23
Name : "contextcheck" ,
19
24
Doc : "check the function whether use a non-inherited context" ,
20
- Run : NewRun (nil ),
25
+ Run : NewRun (nil , cfg . DisableFact ),
21
26
Requires : []* analysis.Analyzer {
22
27
buildssa .Analyzer ,
23
28
},
24
- FactTypes : []analysis.Fact {(* ctxFact )(nil )},
25
29
}
30
+
31
+ if ! cfg .DisableFact {
32
+ analyzer .FactTypes = append (analyzer .FactTypes , (* ctxFact )(nil ))
33
+ }
34
+
35
+ return analyzer
26
36
}
27
37
28
38
const (
@@ -48,6 +58,11 @@ const (
48
58
EntryWithHttpHandler // is http handler
49
59
)
50
60
61
+ var (
62
+ pkgFactMap = make (map [* types.Package ]ctxFact )
63
+ pkgFactMu sync.RWMutex
64
+ )
65
+
51
66
type resInfo struct {
52
67
Valid bool
53
68
Funcs []string
@@ -68,9 +83,10 @@ type runner struct {
68
83
httpReqTyps []types.Type
69
84
70
85
currentFact ctxFact
86
+ disableFact bool
71
87
}
72
88
73
- func NewRun (pkgs []* packages.Package ) func (pass * analysis.Pass ) (interface {}, error ) {
89
+ func NewRun (pkgs []* packages.Package , disableFact bool ) func (pass * analysis.Pass ) (interface {}, error ) {
74
90
m := make (map [string ]bool )
75
91
for _ , pkg := range pkgs {
76
92
m [strings .Split (pkg .PkgPath , "/" )[0 ]] = true
@@ -81,7 +97,8 @@ func NewRun(pkgs []*packages.Package) func(pass *analysis.Pass) (interface{}, er
81
97
return nil , nil
82
98
}
83
99
84
- new (runner ).run (pass )
100
+ r := & runner {disableFact : disableFact }
101
+ r .run (pass )
85
102
return nil , nil
86
103
}
87
104
}
@@ -132,7 +149,11 @@ func (r *runner) run(pass *analysis.Pass) {
132
149
}
133
150
134
151
if len (r .currentFact ) > 0 {
135
- pass .ExportPackageFact (& r .currentFact )
152
+ if r .disableFact {
153
+ setPkgFact (pass .Pkg , r .currentFact )
154
+ } else {
155
+ pass .ExportPackageFact (& r .currentFact )
156
+ }
136
157
}
137
158
}
138
159
@@ -664,7 +685,13 @@ func (r *runner) getValue(key string, f *ssa.Function) (res resInfo, ok bool) {
664
685
}
665
686
666
687
var fact ctxFact
667
- if r .pass .ImportPackageFact (f .Pkg .Pkg , & fact ) {
688
+ var got bool
689
+ if r .disableFact {
690
+ fact , got = getPkgFact (f .Pkg .Pkg )
691
+ } else {
692
+ got = r .pass .ImportPackageFact (f .Pkg .Pkg , & fact )
693
+ }
694
+ if got {
668
695
res , ok = fact [key ]
669
696
}
670
697
return
@@ -677,6 +704,21 @@ func (r *runner) setFact(key string, valid bool, funcs ...string) {
677
704
}
678
705
}
679
706
707
+ // setPkgFact save fact to mem
708
+ func setPkgFact (pkg * types.Package , fact ctxFact ) {
709
+ pkgFactMu .Lock ()
710
+ pkgFactMap [pkg ] = fact
711
+ pkgFactMu .Unlock ()
712
+ }
713
+
714
+ // getPkgFact get fact from mem
715
+ func getPkgFact (pkg * types.Package ) (fact ctxFact , ok bool ) {
716
+ pkgFactMu .RLock ()
717
+ fact , ok = pkgFactMap [pkg ]
718
+ pkgFactMu .RUnlock ()
719
+ return
720
+ }
721
+
680
722
func reverse (arr1 []string ) (arr2 []string ) {
681
723
l := len (arr1 )
682
724
if l == 0 {
0 commit comments