Skip to content

Commit 29678cf

Browse files
authored
fix(emit-format): handle chained method call in formatCallExpr (#181)
## Summary - Fix panic when processing chained method calls (e.g., `ctx.Caller().String()`) in emit format rule - Add `formatEmitExpr` helper to safely handle various `ast.Expr` types ## Problem The `formatCallExpr` function assumed `SelectorExpr.X` is always `*ast.Ident`, causing a panic when encountering chained method calls like `obj.Method().AnotherMethod()` where `X` is `*ast.CallExpr`. ## Changes - Replace unsafe type assertion with `formatEmitExpr` helper that handles `*ast.Ident`, `*ast.CallExpr`, and `*ast.SelectorExpr` - Add test case for chained method calls
1 parent 314ead1 commit 29678cf

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

internal/lints/format_emit.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ func formatArg(arg ast.Expr) string {
117117
func formatCallExpr(call *ast.CallExpr) string {
118118
var sb strings.Builder
119119
if sel, ok := call.Fun.(*ast.SelectorExpr); ok {
120-
sb.WriteString(sel.X.(*ast.Ident).Name)
120+
sb.WriteString(formatEmitExpr(sel.X))
121121
sb.WriteString(".")
122122
sb.WriteString(sel.Sel.Name)
123123
} else if ident, ok := call.Fun.(*ast.Ident); ok {
@@ -133,3 +133,16 @@ func formatCallExpr(call *ast.CallExpr) string {
133133
sb.WriteString(")")
134134
return sb.String()
135135
}
136+
137+
func formatEmitExpr(expr ast.Expr) string {
138+
switch v := expr.(type) {
139+
case *ast.Ident:
140+
return v.Name
141+
case *ast.CallExpr:
142+
return formatCallExpr(v)
143+
case *ast.SelectorExpr:
144+
return formatEmitExpr(v.X) + "." + v.Sel.Name
145+
default:
146+
return "..."
147+
}
148+
}

internal/lints/lint_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,17 @@ func TestFormatEmitCall(t *testing.T) {
320320
"from", sender.Address(),
321321
"to", recipient.Address(),
322322
"amount", token.Format(amount),
323+
)`,
324+
},
325+
{
326+
name: "Emit call with chained method calls",
327+
input: `chain.Emit("UpdateConfig", "callerAddr", ctx.Caller().String(), "callerPath", ctx.Path(), "newVal", conv.FormatInt(newVal, 10), "prevVal", conv.FormatInt(prevVal, 10))`,
328+
expected: `chain.Emit(
329+
"UpdateConfig",
330+
"callerAddr", ctx.Caller().String(),
331+
"callerPath", ctx.Path(),
332+
"newVal", conv.FormatInt(newVal, 10),
333+
"prevVal", conv.FormatInt(prevVal, 10),
323334
)`,
324335
},
325336
}

0 commit comments

Comments
 (0)