Skip to content

Commit c82f5f7

Browse files
committed
allow passing optional parameters to the function without getter.
1 parent d5e1bf5 commit c82f5f7

File tree

3 files changed

+81
-7
lines changed

3 files changed

+81
-7
lines changed

processor.go

Lines changed: 55 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -77,17 +77,65 @@ func (c *processor) process(n ast.Node) (*Result, error) {
7777
}
7878
}
7979

80-
f, ok := x.Fun.(*ast.SelectorExpr)
81-
if !ok {
82-
return &Result{}, nil
83-
}
80+
switch fun := x.Fun.(type) {
81+
case *ast.Ident:
82+
// Allow passing optional parameters to the function without getter.
8483

85-
if !isProtoMessage(c.info, f.X) {
84+
if len(x.Args) == 0 {
85+
return &Result{}, nil
86+
}
87+
88+
if fun.Obj == nil || fun.Obj.Kind != ast.Fun {
89+
return &Result{}, nil
90+
}
91+
92+
decl, ok := fun.Obj.Decl.(*ast.FuncDecl)
93+
if !ok || decl.Type == nil || decl.Type.Params == nil {
94+
return &Result{}, nil
95+
}
96+
97+
paramTypes := make([]ast.Expr, 0, len(x.Args))
98+
for _, p := range decl.Type.Params.List {
99+
count := max(len(p.Names), 1)
100+
for range count {
101+
paramTypes = append(paramTypes, p.Type)
102+
}
103+
}
104+
105+
for i, arg := range x.Args {
106+
a, ok := arg.(*ast.SelectorExpr)
107+
if !ok {
108+
continue
109+
}
110+
111+
_, isParamPointer := paramTypes[i].(*ast.StarExpr)
112+
if !isParamPointer {
113+
return &Result{}, nil
114+
}
115+
116+
if !isProtoMessage(c.info, a.X) {
117+
continue
118+
}
119+
120+
hasPointer, ok := getterResultHasPointer(c.info, a.X, a.Sel.Name)
121+
if !ok || hasPointer {
122+
continue
123+
}
124+
125+
c.filter.AddPos(a.Sel.Pos())
126+
}
127+
128+
case *ast.SelectorExpr:
129+
if !isProtoMessage(c.info, fun.X) {
130+
return &Result{}, nil
131+
}
132+
133+
c.processInner(x)
134+
135+
default:
86136
return &Result{}, nil
87137
}
88138

89-
c.processInner(x)
90-
91139
case *ast.SelectorExpr:
92140
if !isProtoMessage(c.info, x.X) {
93141
// If the selector is not on a proto message, skip it.

testdata/test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@ func testInvalid(t *proto.Test) {
119119
_ = structWithPtrField{
120120
OptBool: t.Embedded.OptBool, // want `avoid direct access to proto field t\.Embedded\.OptBool, use t\.GetEmbedded\(\)\.OptBool instead`
121121
}
122+
123+
optionalArgsFunc(t.Embedded.OptBool) // want `avoid direct access to proto field t\.Embedded\.OptBool, use t\.GetEmbedded\(\)\.OptBool instead`
124+
optionalArgs2Func(t.OptBool, t.Embedded.OptBool) // want `avoid direct access to proto field t\.Embedded\.OptBool, use t\.GetEmbedded\(\)\.OptBool instead`
125+
messageArgsFunc(t.Embedded) // want `avoid direct access to proto field t\.Embedded, use t\.GetEmbedded\(\) instead`
122126
}
123127

124128
func testValid(t *proto.Test) {
@@ -219,9 +223,18 @@ func testValid(t *proto.Test) {
219223
_ = structWithPtrField{
220224
OptBool: t.GetEmbedded().OptBool,
221225
}
226+
227+
optionalArgsFunc(t.GetEmbedded().OptBool)
228+
optionalArgs2Func(t.OptBool, t.GetEmbedded().OptBool)
229+
messageArgsFunc(t.GetEmbedded())
222230
}
223231

224232
// stubs
225233
func slicesIndexFunc[S ~[]E, E any](s S, f func(E) bool) int {
226234
return 0
227235
}
236+
237+
func optionalArgsFunc(*bool) {}
238+
func optionalArgs2Func(a, b *bool) {}
239+
240+
func messageArgsFunc(*proto.Embedded) {}

testdata/test.go.golden

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,10 @@ func testInvalid(t *proto.Test) {
120120
_ = structWithPtrField{
121121
OptBool: t.GetEmbedded().OptBool, // want `avoid direct access to proto field t\.Embedded\.OptBool, use t\.GetEmbedded\(\)\.OptBool instead`
122122
}
123+
124+
optionalArgsFunc(t.GetEmbedded().OptBool) // want `avoid direct access to proto field t\.Embedded\.OptBool, use t\.GetEmbedded\(\)\.OptBool instead`
125+
optionalArgs2Func(t.OptBool, t.GetEmbedded().OptBool) // want `avoid direct access to proto field t\.Embedded\.OptBool, use t\.GetEmbedded\(\)\.OptBool instead`
126+
messageArgsFunc(t.GetEmbedded()) // want `avoid direct access to proto field t\.Embedded, use t\.GetEmbedded\(\) instead`
123127
}
124128

125129
func testValid(t *proto.Test) {
@@ -220,9 +224,18 @@ func testValid(t *proto.Test) {
220224
_ = structWithPtrField{
221225
OptBool: t.GetEmbedded().OptBool,
222226
}
227+
228+
optionalArgsFunc(t.GetEmbedded().OptBool)
229+
optionalArgs2Func(t.OptBool, t.GetEmbedded().OptBool)
230+
messageArgsFunc(t.GetEmbedded())
223231
}
224232

225233
// stubs
226234
func slicesIndexFunc[S ~[]E, E any](s S, f func(E) bool) int {
227235
return 0
228236
}
237+
238+
func optionalArgsFunc(*bool) {}
239+
func optionalArgs2Func(a, b *bool) {}
240+
241+
func messageArgsFunc(*proto.Embedded) {}

0 commit comments

Comments
 (0)