diff --git a/rewrite-go/rewrite/pkg/parser/go_parser.go b/rewrite-go/rewrite/pkg/parser/go_parser.go index 64941227fa..ab3c782c5a 100644 --- a/rewrite-go/rewrite/pkg/parser/go_parser.go +++ b/rewrite-go/rewrite/pkg/parser/go_parser.go @@ -669,9 +669,15 @@ func (ctx *parseContext) mapFieldListAsParams(fl *ast.FieldList) tree.Container[ if len(field.Names) == 0 { // Unnamed parameter: just a type expression (e.g., `int` in `func(int)`) typeExpr := ctx.mapTypeExpr(field.Type) + var varargs *tree.Space + if u, ok := typeExpr.(*tree.Unary); ok && u.Operator.Element == tree.Spread { + varargs = &u.Prefix + typeExpr = u.Operand + } vd := &tree.VariableDeclarations{ ID: uuid.New(), TypeExpr: typeExpr, + Varargs: varargs, Variables: []tree.RightPadded[*tree.VariableDeclarator]{ {Element: &tree.VariableDeclarator{ID: uuid.New(), Name: &tree.Identifier{ID: uuid.New()}}}, }, @@ -706,9 +712,15 @@ func (ctx *parseContext) mapFieldListAsParams(fl *ast.FieldList) tree.Container[ } typeExpr := ctx.mapTypeExpr(field.Type) + var varargs *tree.Space + if u, ok := typeExpr.(*tree.Unary); ok && u.Operator.Element == tree.Spread { + varargs = &u.Prefix + typeExpr = u.Operand + } vd := &tree.VariableDeclarations{ ID: uuid.New(), TypeExpr: typeExpr, + Varargs: varargs, Variables: vars, } diff --git a/rewrite-go/rewrite/pkg/printer/go_printer.go b/rewrite-go/rewrite/pkg/printer/go_printer.go index d5ef8f328a..7b6081c345 100644 --- a/rewrite-go/rewrite/pkg/printer/go_printer.go +++ b/rewrite-go/rewrite/pkg/printer/go_printer.go @@ -323,7 +323,11 @@ func (p *GoPrinter) VisitVariableDeclarations(vd *tree.VariableDeclarations, par out.Append(",") } } - // Then type expression + // Then varargs + type expression + if vd.Varargs != nil { + p.visitSpace(*vd.Varargs, out) + out.Append("...") + } if vd.TypeExpr != nil { p.Visit(vd.TypeExpr, out) } diff --git a/rewrite-go/rewrite/pkg/rpc/java_receiver.go b/rewrite-go/rewrite/pkg/rpc/java_receiver.go index ebcafda8f4..668cd44192 100644 --- a/rewrite-go/rewrite/pkg/rpc/java_receiver.go +++ b/rewrite-go/rewrite/pkg/rpc/java_receiver.go @@ -356,7 +356,15 @@ func (r *JavaReceiver) receiveVariableDeclarations(vd *tree.VariableDeclarations vd.TypeExpr = result.(tree.Expression) } // varargs - q.Receive(nil, nil) + var currentVarargs any + if vd.Varargs != nil { + currentVarargs = *vd.Varargs + } + varargsResult := q.Receive(currentVarargs, func(v any) any { return receiveSpace(v.(tree.Space), q) }) + if varargsResult != nil { + sp := varargsResult.(tree.Space) + vd.Varargs = &sp + } // variables beforeVars := make([]any, len(vd.Variables)) for i, v := range vd.Variables { diff --git a/rewrite-go/rewrite/pkg/rpc/java_sender.go b/rewrite-go/rewrite/pkg/rpc/java_sender.go index 80b3c08c60..391de64331 100644 --- a/rewrite-go/rewrite/pkg/rpc/java_sender.go +++ b/rewrite-go/rewrite/pkg/rpc/java_sender.go @@ -473,8 +473,14 @@ func (s *JavaSender) sendVariableDeclarations(vd *tree.VariableDeclarations, q * // typeExpression q.GetAndSend(vd, func(v any) any { return v.(*tree.VariableDeclarations).TypeExpr }, func(v any) { s.parent.Visit(v, q) }) - // varargs (nil for Go) - q.GetAndSend(vd, func(_ any) any { return nil }, nil) + // varargs + q.GetAndSend(vd, func(v any) any { + va := v.(*tree.VariableDeclarations).Varargs + if va != nil { + return *va + } + return nil + }, func(v any) { sendSpace(v.(tree.Space), q) }) // variables (list of right-padded NamedVariable) q.GetAndSendList(vd, func(v any) []any { diff --git a/rewrite-go/rewrite/pkg/tree/j.go b/rewrite-go/rewrite/pkg/tree/j.go index 5b5757a1d7..1356e2ac68 100644 --- a/rewrite-go/rewrite/pkg/tree/j.go +++ b/rewrite-go/rewrite/pkg/tree/j.go @@ -1076,6 +1076,7 @@ type VariableDeclarations struct { Prefix Space Markers Markers TypeExpr Expression // the declared type (nil if inferred) + Varargs *Space // non-nil for variadic params (`...T`); holds prefix of `...` Variables []RightPadded[*VariableDeclarator] // the declared variables Specs *Container[Statement] // non-nil for grouped `var ( ... )`; Before = space before `(` } diff --git a/rewrite-go/src/integTest/java/org/openrewrite/golang/rpc/GolangParserIntegTest.java b/rewrite-go/src/integTest/java/org/openrewrite/golang/rpc/GolangParserIntegTest.java index 2daf4ca29b..d448015338 100644 --- a/rewrite-go/src/integTest/java/org/openrewrite/golang/rpc/GolangParserIntegTest.java +++ b/rewrite-go/src/integTest/java/org/openrewrite/golang/rpc/GolangParserIntegTest.java @@ -451,4 +451,18 @@ void literalWithNonPrimitiveType() { ) ); } + + @Test + void variadicParameter() { + rewriteRun( + go( + """ + package main + + func foo(args ...string) { + } + """ + ) + ); + } }