Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,23 @@ This conversion only applies to structs defined in the same file. External struc

### Functions

**Function signatures** are always collapsed to a single line:

```go
// Before — multi-line signature
func Process(
ctx context.Context,
input Input,
) (Output, error) {

// After — single line
func Process(ctx context.Context, input Input) (Output, error) {
```

This applies to function definitions, methods, function types, and interface methods.

---

**Standalone functions sorting:**
1. Exported first, then unexported
2. Within each group: by architectural layer (high-level first)
Expand Down
1 change: 1 addition & 0 deletions pkg/formatter/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ func FormatFile(filePath string, opts Options) error {
return nil
}

collapseFuncSignatures(f)
originalFieldOrder := collectOriginalFieldOrder(f)
convertPositionalToKeyed(f, originalFieldOrder)
reorderStructFields(f)
Expand Down
55 changes: 55 additions & 0 deletions pkg/formatter/spacing.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,58 @@ func normalizeSpacing(f *dst.File) {
return true
})
}

func collapseFuncSignatures(f *dst.File) {
dst.Inspect(f, func(n dst.Node) bool {
switch node := n.(type) {
case *dst.FuncDecl:
if node.Type != nil {
collapseFuncType(node.Type)
}
case *dst.FuncLit:
if node.Type != nil {
collapseFuncType(node.Type)
}
case *dst.TypeSpec:
if ft, ok := node.Type.(*dst.FuncType); ok {
collapseFuncType(ft)
}
case *dst.InterfaceType:
if node.Methods != nil {
for _, method := range node.Methods.List {
if ft, ok := method.Type.(*dst.FuncType); ok {
collapseFuncType(ft)
}
}
}
}

return true
})
}

func collapseFuncType(ft *dst.FuncType) {
if ft.Params != nil {
collapseFieldList(ft.Params)
}
if ft.Results != nil {
collapseFieldList(ft.Results)
}
}

func collapseFieldList(fl *dst.FieldList) {
// Remove newlines from opening paren
fl.Decs.Opening = nil

for i, field := range fl.List {
// First field: no newline before
if i == 0 {
field.Decs.Before = dst.None
} else {
// Subsequent fields: space only (comma handled automatically)
field.Decs.Before = dst.None
}
// No newline after any field
field.Decs.After = dst.None
}
}
30 changes: 30 additions & 0 deletions pkg/formatter/testdata/expected.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package main

import (
"context"
"fmt"
"net/http"
"os"
"strings"
)
Expand Down Expand Up @@ -66,6 +68,9 @@ type StatusCode MyString

type Priority int

// Test: function type should collapse
type MultiLineHandler func(w http.ResponseWriter, r *http.Request)

type Reader interface {
Read(p []byte) (n int, err error)
}
Expand All @@ -78,6 +83,11 @@ type Closer interface {
Close() error
}

// Test: interface method should collapse
type MultiLineInterface interface {
Process(ctx context.Context, input Input) (Output, error)
}

type ReadWriter interface {
Read(p []byte) (n int, err error)
Write(p []byte) (n int, err error)
Expand Down Expand Up @@ -118,6 +128,11 @@ func (s *Server) PublicMethod() {}

func (s *Server) handleRequest() {}

// Test: multi-line method signature should collapse
func (s *Server) multiLineMethod(ctx context.Context, input string) (string, error) {
return input, nil
}

// Test: method declared before its type
func (s *Server) privateMethod() {
return
Expand Down Expand Up @@ -227,6 +242,11 @@ type WithEmbedded struct {
Extra string
}

// Types for interface test
type Input struct{}

type Output struct{}

func HelperUpper() {}

func ProcessDataPublic(data string) string {
Expand Down Expand Up @@ -360,6 +380,16 @@ func helperLower() {
fmt.Println("helper")
}

// Test: multi-line func signature should collapse to single line
func multiLineFunc(a int, b string, c bool) error {
return nil
}

// Test: multi-line return values should collapse
func multiLineReturns() (result string, err error) {
return "", nil
}

func processData(data string) string {
return strings.ToUpper(data)
}
Expand Down
45 changes: 45 additions & 0 deletions pkg/formatter/testdata/input.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package main

import (
"context"
"fmt"
"net/http"
"os"
"strings"
)
Expand Down Expand Up @@ -338,3 +340,46 @@ func createKeyed() *PositionalTest {
func createEmpty() *PositionalTest {
return &PositionalTest{}
}

// Test: multi-line func signature should collapse to single line
func multiLineFunc(
a int,
b string,
c bool,
) error {
return nil
}

// Test: multi-line method signature should collapse
func (s *Server) multiLineMethod(
ctx context.Context,
input string,
) (string, error) {
return input, nil
}

// Test: multi-line return values should collapse
func multiLineReturns() (
result string,
err error,
) {
return "", nil
}

// Test: function type should collapse
type MultiLineHandler func(
w http.ResponseWriter,
r *http.Request,
)

// Test: interface method should collapse
type MultiLineInterface interface {
Process(
ctx context.Context,
input Input,
) (Output, error)
}

// Types for interface test
type Input struct{}
type Output struct{}