Skip to content

Commit 524efca

Browse files
daenneyantonmedv
authored andcommitted
Make WithContext work for methods on env struct (#602)
This makes the WithContext patcher work when passing in a struct for an env that has methods that take a context. This is a bit fiddly because we can't quite detect the difference of function vs. method on a struct, so we have to check both the first and the second param. Since it's highly unusual to pass the context as anything other than the first parameter, this should work out just fine in practice. Fixes #600.
1 parent 55dc4e8 commit 524efca

File tree

2 files changed

+35
-4
lines changed

2 files changed

+35
-4
lines changed

patcher/with_context.go

+11-4
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,18 @@ func (w WithContext) Visit(node *ast.Node) {
2222
if fn.Kind() != reflect.Func {
2323
return
2424
}
25-
if fn.NumIn() == 0 {
26-
return
27-
}
28-
if fn.In(0).String() != "context.Context" {
25+
switch fn.NumIn() {
26+
case 0:
2927
return
28+
case 1:
29+
if fn.In(0).String() != "context.Context" {
30+
return
31+
}
32+
default:
33+
if fn.In(0).String() != "context.Context" &&
34+
fn.In(1).String() != "context.Context" {
35+
return
36+
}
3037
}
3138
ast.Patch(node, &ast.CallNode{
3239
Callee: call.Callee,

patcher/with_context_test.go

+24
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,30 @@ func TestWithContext_with_env_Function(t *testing.T) {
6262
require.Equal(t, 42, output)
6363
}
6464

65+
type testEnvContext struct {
66+
Context context.Context `expr:"ctx"`
67+
}
68+
69+
func (testEnvContext) Fn(ctx context.Context, a int) int {
70+
return ctx.Value("value").(int) + a
71+
}
72+
73+
func TestWithContext_env_struct(t *testing.T) {
74+
withContext := patcher.WithContext{Name: "ctx"}
75+
76+
program, err := expr.Compile(`Fn(40)`, expr.Env(testEnvContext{}), expr.Patch(withContext))
77+
require.NoError(t, err)
78+
79+
ctx := context.WithValue(context.Background(), "value", 2)
80+
env := testEnvContext{
81+
Context: ctx,
82+
}
83+
84+
output, err := expr.Run(program, env)
85+
require.NoError(t, err)
86+
require.Equal(t, 42, output)
87+
}
88+
6589
type TestFoo struct {
6690
contextValue int
6791
}

0 commit comments

Comments
 (0)