@@ -26,9 +26,9 @@ func (lint Scopelint) Run(ctx context.Context, lintCtx *linter.Context) ([]resul
26
26
for _ , f := range lintCtx .ASTCache .GetAllValidFiles () {
27
27
n := Node {
28
28
fset : f .Fset ,
29
- dangerObjects : map [* ast.Object ]struct {} {},
30
- unsafeObjects : map [* ast.Object ]struct {} {},
31
- skipFuncs : map [* ast.FuncLit ]struct {} {},
29
+ DangerObjects : map [* ast.Object ]int {},
30
+ UnsafeObjects : map [* ast.Object ]int {},
31
+ SkipFuncs : map [* ast.FuncLit ]int {},
32
32
issues : & res ,
33
33
}
34
34
ast .Walk (& n , f .F )
@@ -37,14 +37,14 @@ func (lint Scopelint) Run(ctx context.Context, lintCtx *linter.Context) ([]resul
37
37
return res , nil
38
38
}
39
39
40
- // The code below is copy-pasted from https://github.com/kyoh86/scopelint
40
+ // The code below is copy-pasted from https://github.com/kyoh86/scopelint 92cbe2cc9276abda0e309f52cc9e309d407f174e
41
41
42
42
// Node represents a Node being linted.
43
43
type Node struct {
44
44
fset * token.FileSet
45
- dangerObjects map [* ast.Object ]struct {}
46
- unsafeObjects map [* ast.Object ]struct {}
47
- skipFuncs map [* ast.FuncLit ]struct {}
45
+ DangerObjects map [* ast.Object ]int
46
+ UnsafeObjects map [* ast.Object ]int
47
+ SkipFuncs map [* ast.FuncLit ]int
48
48
issues * []result.Issue
49
49
}
50
50
@@ -60,7 +60,7 @@ func (f *Node) Visit(node ast.Node) ast.Visitor {
60
60
for _ , lh := range init .Lhs {
61
61
switch tlh := lh .(type ) {
62
62
case * ast.Ident :
63
- f .unsafeObjects [tlh .Obj ] = struct {}{}
63
+ f .UnsafeObjects [tlh .Obj ] = 0
64
64
}
65
65
}
66
66
}
@@ -69,25 +69,25 @@ func (f *Node) Visit(node ast.Node) ast.Visitor {
69
69
// Memory variables declarated in range statement
70
70
switch k := typedNode .Key .(type ) {
71
71
case * ast.Ident :
72
- f .unsafeObjects [k .Obj ] = struct {}{}
72
+ f .UnsafeObjects [k .Obj ] = 0
73
73
}
74
74
switch v := typedNode .Value .(type ) {
75
75
case * ast.Ident :
76
- f .unsafeObjects [v .Obj ] = struct {}{}
76
+ f .UnsafeObjects [v .Obj ] = 0
77
77
}
78
78
79
79
case * ast.UnaryExpr :
80
80
if typedNode .Op == token .AND {
81
81
switch ident := typedNode .X .(type ) {
82
82
case * ast.Ident :
83
- if _ , unsafe := f .unsafeObjects [ident .Obj ]; unsafe {
83
+ if _ , unsafe := f .UnsafeObjects [ident .Obj ]; unsafe {
84
84
f .errorf (ident , "Using a reference for the variable on range scope %s" , formatCode (ident .Name , nil ))
85
85
}
86
86
}
87
87
}
88
88
89
89
case * ast.Ident :
90
- if _ , obj := f .dangerObjects [typedNode .Obj ]; obj {
90
+ if _ , obj := f .DangerObjects [typedNode .Obj ]; obj {
91
91
// It is the naked variable in scope of range statement.
92
92
f .errorf (node , "Using the variable on range scope %s in function literal" , formatCode (typedNode .Name , nil ))
93
93
break
@@ -97,26 +97,43 @@ func (f *Node) Visit(node ast.Node) ast.Visitor {
97
97
// Ignore func literals that'll be called immediately.
98
98
switch funcLit := typedNode .Fun .(type ) {
99
99
case * ast.FuncLit :
100
- f .skipFuncs [funcLit ] = struct {}{}
100
+ f .SkipFuncs [funcLit ] = 0
101
101
}
102
102
103
103
case * ast.FuncLit :
104
- if _ , skip := f .skipFuncs [typedNode ]; ! skip {
105
- dangers := map [* ast.Object ]struct {} {}
106
- for d := range f .dangerObjects {
107
- dangers [d ] = struct {}{}
104
+ if _ , skip := f .SkipFuncs [typedNode ]; ! skip {
105
+ dangers := map [* ast.Object ]int {}
106
+ for d := range f .DangerObjects {
107
+ dangers [d ] = 0
108
108
}
109
- for u := range f .unsafeObjects {
110
- dangers [u ] = struct {}{}
109
+ for u := range f .UnsafeObjects {
110
+ dangers [u ] = 0
111
+ f .UnsafeObjects [u ]++
111
112
}
112
113
return & Node {
113
114
fset : f .fset ,
114
- dangerObjects : dangers ,
115
- unsafeObjects : f .unsafeObjects ,
116
- skipFuncs : f .skipFuncs ,
115
+ DangerObjects : dangers ,
116
+ UnsafeObjects : f .UnsafeObjects ,
117
+ SkipFuncs : f .SkipFuncs ,
117
118
issues : f .issues ,
118
119
}
119
120
}
121
+
122
+ case * ast.ReturnStmt :
123
+ unsafe := map [* ast.Object ]int {}
124
+ for u := range f .UnsafeObjects {
125
+ if f .UnsafeObjects [u ] == 0 {
126
+ continue
127
+ }
128
+ unsafe [u ] = f .UnsafeObjects [u ]
129
+ }
130
+ return & Node {
131
+ fset : f .fset ,
132
+ DangerObjects : f .DangerObjects ,
133
+ UnsafeObjects : unsafe ,
134
+ SkipFuncs : f .SkipFuncs ,
135
+ issues : f .issues ,
136
+ }
120
137
}
121
138
return f
122
139
}
0 commit comments