dsl

package
v0.0.0-...-af88cc4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 7, 2026 License: MIT Imports: 18 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ApplyEdits

func ApplyEdits(src []byte, edits []Edit) ([]byte, error)

ApplyEdits applies a set of non-overlapping edits to src and returns the modified source.

Edits may be provided unsorted; they are applied in increasing Start order.

func ApplySingleEdit

func ApplySingleEdit(src []byte, start, end int,
	replace []byte) ([]byte, error)

ApplySingleEdit is a convenience wrapper around ApplyEdits for the common single-span replacement case.

func ArithmeticOps

func ArithmeticOps() []string

ArithmeticOps returns the list of arithmetic operators.

func ComparisonOps

func ComparisonOps() []string

ComparisonOps returns the list of comparison operators.

func LogPrintfCanonicalPatterns

func LogPrintfCanonicalPatterns() []string

LogPrintfCanonicalPatterns returns the canonical "pkg.Func" patterns that are always recognized as log/printf-style calls.

func LogPrintfSelectorNames

func LogPrintfSelectorNames() []string

LogPrintfSelectorNames returns the selector/ident names that are recognized as printf-style calls when suffix-only matching is enabled.

func LogicalOps

func LogicalOps() []string

LogicalOps returns the list of logical operators.

func NonFStringLogNames

func NonFStringLogNames() []string

NonFStringLogNames returns the selector/ident names that are recognized as message-only string calls when IncludeNonFStringCalls is enabled.

func VisualLen

func VisualLen(s string, tabStop int) int

VisualLen calculates the visual width of a string with tab expansion.

Types

type Action

type Action interface {
	Execute(caps Captures, ctx *Context) ([]byte, bool)
}

Action performs the formatting transformation.

type AndCond

type AndCond struct {
	Conds []Condition
}

AndCond combines conditions with AND.

func (*AndCond) Eval

func (c *AndCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for AndCond.

type AnyLineWidthCond

type AnyLineWidthCond struct {
	Target string
	Op     string
	Value  int // If 0, uses ctx.ColumnLimit
}

AnyLineWidthCond checks if ANY line of a node exceeds a threshold. This is useful for multiline nodes like function signatures where one line might be short but another line exceeds the limit.

func (*AnyLineWidthCond) Eval

func (c *AnyLineWidthCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for AnyLineWidthCond.

type AnyLineWidthFuncLitSignatureCond

type AnyLineWidthFuncLitSignatureCond struct {
	Target string
	Op     string
	Value  int // If 0, uses ctx.ColumnLimit
}

AnyLineWidthFuncLitSignatureCond checks if ANY line of a function literal signature exceeds a threshold (defaults to ctx.ColumnLimit).

The signature span is limited to `func`..`{` (exclusive of the body).

func (*AnyLineWidthFuncLitSignatureCond) Eval

type AnyOf

type AnyOf struct {
	Patterns []Pattern
}

AnyOf matches if any of the sub-patterns match.

func (*AnyOf) Match

func (a *AnyOf) Match(n ast.Node, fset *token.FileSet) (Captures, bool)

Match implements Pattern for AnyOf.

type BlankLineOptions

type BlankLineOptions struct {
	// ExtraIfErrReturn inserts a blank line before:
	//
	// if err != nil { return ... }
	//
	// This is intentionally opt-in because it is opinionated and may
	// interact with users' desired grouping/spacing style.
	ExtraIfErrReturn bool
}

type BlankLinesBatchAction

type BlankLinesBatchAction struct {
	Options BlankLineOptions
}

BlankLinesBatchAction inserts all blank lines required by the blank-line DSL policy in a single deterministic rewrite.

The default DSL engine applies at most one transforming rule per iteration for determinism, which makes per-node blank-line rules expensive for files with many cases/returns/methods. This action keeps the logic in the DSL while avoiding hundreds of iterations.

func (*BlankLinesBatchAction) Execute

func (a *BlankLinesBatchAction) Execute(caps Captures, ctx *Context) ([]byte,
	bool)

type BreakAfterAction

type BreakAfterAction struct {
	Target string
}

BreakAfterAction inserts a line break after a node.

func (*BreakAfterAction) Execute

func (a *BreakAfterAction) Execute(caps Captures, ctx *Context) ([]byte, bool)

Execute implements Action for BreakAfterAction.

type BreakArithmeticChainLayoutAction

type BreakArithmeticChainLayoutAction struct {
	Target string
}

BreakArithmeticChainLayoutAction breaks long arithmetic chains for a single operator (e.g. `a + b + c + d`) using the layout engine.

This is intentionally conservative: it will not rewrite mixed-op trees such as `a + b - c`, because those often carry intent and are more error-prone to restructure without a full layout/precedence engine.

func (*BreakArithmeticChainLayoutAction) Execute

func (a *BreakArithmeticChainLayoutAction) Execute(caps Captures,
	ctx *Context) ([]byte, bool)

Execute implements Action for BreakArithmeticChainLayoutAction.

type BreakAtOpAction

type BreakAtOpAction struct {
	Target     string
	BreakAfter bool // true = break after op (Go style), false = break before
}

BreakAtOpAction breaks a binary expression at the best operator position. It finds the rightmost operator that keeps the first part under the column limit. Prefers logical operators (&&, ||) over comparison/arithmetic when possible.

func (*BreakAtOpAction) Execute

func (a *BreakAtOpAction) Execute(caps Captures, ctx *Context) ([]byte, bool)

Execute implements Action for BreakAtOpAction.

func (*BreakAtOpAction) ExecuteEdits

func (a *BreakAtOpAction) ExecuteEdits(caps Captures, ctx *Context) ([]Edit,
	bool, error)

ExecuteEdits implements EditAction for BreakAtOpAction.

type BreakBeforeAction

type BreakBeforeAction struct {
	Target string
}

BreakBeforeAction inserts a line break before a node.

func (*BreakBeforeAction) Execute

func (a *BreakBeforeAction) Execute(caps Captures, ctx *Context) ([]byte,
	bool)

Execute implements Action for BreakBeforeAction.

type BreakBinaryExprLayoutAction

type BreakBinaryExprLayoutAction struct {
	Target          string
	LogicalStyle    string // "legacy"|"layout"
	ArithmeticStyle string // "legacy"|"layout"
}

BreakBinaryExprLayoutAction tries to break a binary expression using the layout engine, based on configured style toggles.

This provides a single entry point for contexts that capture a BinaryExpr (e.g. `for` conditions or `return` statements) without duplicating operator- specific rule logic.

func (*BreakBinaryExprLayoutAction) Execute

func (a *BreakBinaryExprLayoutAction) Execute(caps Captures, ctx *Context) (
	[]byte, bool)

Execute implements Action for BreakBinaryExprLayoutAction.

type BreakCallArgsLayoutAction

type BreakCallArgsLayoutAction struct {
	Target string

	// Grouping optionally controls how the call argument list is grouped.
	//
	// Supported values:
	// - "" (default): one argument per line (forced break)
	// - "pairs": group args as (a, b) pairs when possible
	Grouping string
}

BreakCallArgsLayoutAction formats a call expression by breaking its arguments across lines using the layout engine (with a gofmt-like tab indent).

This is intended as an opt-in style that can fall back to existing packed/ legacy formatters when it cannot safely operate (e.g. comments, multiline args).

func (*BreakCallArgsLayoutAction) Execute

func (a *BreakCallArgsLayoutAction) Execute(caps Captures, ctx *Context) (
	[]byte, bool)

Execute implements Action for BreakCallArgsLayoutAction.

type BreakCaseClauseAction

type BreakCaseClauseAction struct {
	Target string
}

BreakCaseClauseAction breaks a long case clause at comma boundaries.

func (*BreakCaseClauseAction) Execute

func (a *BreakCaseClauseAction) Execute(caps Captures, ctx *Context) ([]byte,
	bool)

Execute implements Action for BreakCaseClauseAction.

func (*BreakCaseClauseAction) ExecuteEdits

func (a *BreakCaseClauseAction) ExecuteEdits(caps Captures, ctx *Context) (
	[]Edit, bool, error)

ExecuteEdits implements EditAction for BreakCaseClauseAction.

type BreakCaseClauseLayoutAction

type BreakCaseClauseLayoutAction struct {
	Target string
}

BreakCaseClauseLayoutAction formats a long case clause list (`case A, B, C:`) using the layout engine. It breaks after commas using the standard continuation indentation (`indent + "\t"`).

func (*BreakCaseClauseLayoutAction) Execute

func (a *BreakCaseClauseLayoutAction) Execute(caps Captures, ctx *Context) (
	[]byte, bool)

Execute implements Action for BreakCaseClauseLayoutAction.

type BreakFuncLitSignatureAction

type BreakFuncLitSignatureAction struct {
	Target     string
	FormatFunc SignatureFormatFunc
}

BreakFuncLitSignatureAction formats function literals (closures) by extracting the literal signature from `func` to `{` and reformatting it.

Unlike BreakFuncSignatureAction, this does not insert blank lines after the opening brace; function literals should remain compact.

func (*BreakFuncLitSignatureAction) Execute

func (a *BreakFuncLitSignatureAction) Execute(caps Captures, ctx *Context) (
	[]byte, bool)

Execute implements Action for BreakFuncLitSignatureAction.

type BreakFuncSignatureAction

type BreakFuncSignatureAction struct {
	Target     string
	FormatFunc SignatureFormatFunc
}

BreakFuncSignatureAction breaks a long function signature using left-flow packing. It extracts the entire signature line and reformats it.

func (*BreakFuncSignatureAction) Execute

func (a *BreakFuncSignatureAction) Execute(caps Captures, ctx *Context) ([]byte,
	bool)

Execute implements Action for BreakFuncSignatureAction.

type BreakInterfaceMethodAction

type BreakInterfaceMethodAction struct {
	Target     string
	FormatFunc SignatureFormatFunc
}

BreakInterfaceMethodAction formats a long interface method declaration.

func (*BreakInterfaceMethodAction) Execute

func (a *BreakInterfaceMethodAction) Execute(caps Captures, ctx *Context) (
	[]byte, bool)

Execute implements Action for BreakInterfaceMethodAction.

type BreakLogicalChainLayoutAction

type BreakLogicalChainLayoutAction struct {
	Target string
}

BreakLogicalChainLayoutAction breaks long &&/|| chains using the layout engine. It prefers breaking after each operator (Go style) and uses the standard continuation indent (newline + indent + one tab).

This action is intended for opt-in "modern" formatting; legacy/parity rules should generally use BreakAtOpAction to match historical behavior.

func (*BreakLogicalChainLayoutAction) Execute

func (a *BreakLogicalChainLayoutAction) Execute(caps Captures, ctx *Context) (
	[]byte, bool)

Execute implements Action for BreakLogicalChainLayoutAction.

type BreakMethodChainAction

type BreakMethodChainAction struct {
	Target string
}

BreakMethodChainAction breaks a method chain with one call per line. The dot is placed at the end of each line (trailing dot style).

func (*BreakMethodChainAction) Execute

func (a *BreakMethodChainAction) Execute(caps Captures, ctx *Context) ([]byte,
	bool)

Execute implements Action for BreakMethodChainAction.

type BreakMethodChainLayoutAction

type BreakMethodChainLayoutAction struct {
	Target string
}

BreakMethodChainLayoutAction breaks method call chains such as:

client.WithTimeout(30*time.Second).WithRetry(3).Execute(ctx, req)

It breaks after dots (to avoid semicolon insertion) and indents continuation lines with the standard continuation indent (`indent + "\t"`).

This action is intentionally conservative: - skips chains with inline comments (AST printing would drop them) - skips chains with multiline argument expressions - handles only selector-based calls (skips generic instantiation / index fun)

func (*BreakMethodChainLayoutAction) Execute

func (a *BreakMethodChainLayoutAction) Execute(caps Captures, ctx *Context) (
	[]byte, bool)

Execute implements Action for BreakMethodChainLayoutAction.

type BreakReturnValuesAction

type BreakReturnValuesAction struct {
	Target string
}

BreakReturnValuesAction breaks long return values to a new line.

func (*BreakReturnValuesAction) Execute

func (a *BreakReturnValuesAction) Execute(caps Captures, ctx *Context) ([]byte,
	bool)

Execute implements Action for BreakReturnValuesAction.

type BreakSelectorChainLayoutAction

type BreakSelectorChainLayoutAction struct {
	Target string
}

BreakSelectorChainLayoutAction breaks long selector chains such as `pkg.subpkg.Symbol.Field` using the layout engine.

It breaks after dots using a soft line break so that flat rendering produces `a.b.c` (no illegal spaces), while broken rendering produces:

a. b. c

func (*BreakSelectorChainLayoutAction) Execute

func (a *BreakSelectorChainLayoutAction) Execute(caps Captures, ctx *Context) (
	[]byte, bool)

Execute implements Action for BreakSelectorChainLayoutAction.

type CallArgsPolicy

type CallArgsPolicy int

CallArgsPolicy controls whether the expression stage may edit expressions that are contained within call argument expressions.

const (
	// CallArgsPolicyOff forbids edits inside call argument expressions.
	CallArgsPolicyOff CallArgsPolicy = iota

	// CallArgsPolicyAuto allows edits inside call argument expressions only
	// when the enclosing call is known to be ignored by later
	// call-formatting stages.
	CallArgsPolicyAuto

	// CallArgsPolicyForce always allows edits inside call argument
	// expressions.
	CallArgsPolicyForce
)

type Captures

type Captures map[string]ast.Node

Captures holds captured nodes from pattern matching.

type CaseHasBodyCond

type CaseHasBodyCond struct {
	Target string
}

CaseHasBodyCond checks if a case clause has a non-empty body.

func (*CaseHasBodyCond) Eval

func (c *CaseHasBodyCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for CaseHasBodyCond.

type CollapsedWidthCond

type CollapsedWidthCond struct {
	Target string
	Op     string
	Value  int
}

CollapsedWidthCond checks if a node, when collapsed to a single line (whitespace normalized), would exceed a threshold. This is useful for multiline nodes where the first line might be short but the total content is long.

func (*CollapsedWidthCond) Eval

func (c *CollapsedWidthCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for CollapsedWidthCond.

type Condition

type Condition interface {
	Eval(caps Captures, ctx *Context) bool
}

Condition evaluates whether a rule should apply.

type Context

type Context struct {
	Fset        *token.FileSet
	Source      []byte
	ColumnLimit int
	TabStop     int
	// Parseable reports whether ctx.Source parsed without syntax errors
	// when the engine built this Context for the current iteration.
	//
	// The DSL engine uses this to decide whether to enforce parseability
	// checks on candidate rewrites: when the input is already syntactically
	// invalid, we still want to allow whitespace/layout rewrites to run (to
	// support legacy fixtures that are intentionally unparseable).
	Parseable bool

	// ForbiddenSpans holds the union of spans that this engine instance
	// should not rewrite. It is populated by the outer pipeline when
	// ownership boundaries are enabled.
	ForbiddenSpans llast.OffsetSpanSet

	// LastAppliedRule records the most recent transforming rule that
	// applied. This is used for optional tracing.
	LastAppliedRule string

	// LastAppliedRulePriority is the priority of the last applied rule.
	LastAppliedRulePriority int

	// LastAppliedNodeType is a short node type label (e.g.
	// "*ast.CallExpr").
	LastAppliedNodeType string

	// LastAppliedNodeStart/End are byte offsets into Source for the node
	// that triggered the last applied rule.
	LastAppliedNodeStart int
	LastAppliedNodeEnd   int
	// contains filtered or unexported fields
}

Context provides formatting context to conditions and actions.

func NewContext

func NewContext(fset *token.FileSet, source []byte, columnLimit,
	tabStop int) *Context

NewContext creates a new formatting context.

func (*Context) IndentAt

func (ctx *Context) IndentAt(n ast.Node) string

IndentAt returns the indentation string at node n.

func (*Context) IsAtomic

func (ctx *Context) IsAtomic(n ast.Node) bool

IsAtomic checks if a node is marked as atomic.

func (*Context) IsChildOfCallExpr

func (ctx *Context) IsChildOfCallExpr(n ast.Node) bool

IsChildOfCallExpr checks if node n is a direct child (argument) of a CallExpr.

func (*Context) LineWidth

func (ctx *Context) LineWidth(n ast.Node) int

LineWidth returns the visual width of the line containing node n.

func (*Context) MarkAtomic

func (ctx *Context) MarkAtomic(n ast.Node)

MarkAtomic marks a node as atomic (should not be broken).

func (*Context) NodeSource

func (ctx *Context) NodeSource(n ast.Node) []byte

NodeSource returns the source code for a node.

func (*Context) NodeWidth

func (ctx *Context) NodeWidth(n ast.Node) int

NodeWidth returns the visual width of a node rendered as single line.

func (*Context) Parent

func (ctx *Context) Parent(n ast.Node) ast.Node

Parent returns the parent node of n, or nil if not found.

func (*Context) SetParentMap

func (ctx *Context) SetParentMap(m map[ast.Node]ast.Node)

SetParentMap sets the parent map for the context.

type DefaultRuleOptions

type DefaultRuleOptions struct {
	LeftFlowFormat        LeftFlowFormatFunc
	PackedMultiLineFormat PackedMultiLineFormatFunc
	FuncSignatureFormat   SignatureFormatFunc
	InterfaceMethodFormat SignatureFormatFunc
}

DefaultRuleOptions controls which legacy formatter functions are used by the default DSL rule set. Callers in other packages (e.g. formatter) can inject existing implementations without creating import cycles.

type Edit

type Edit struct {
	Start   int
	End     int
	Replace []byte
}

Edit represents a single source edit in byte offsets: replace src[Start:End] with Replace. Insertions have Start == End.

type EditAction

type EditAction interface {
	ExecuteEdits(caps Captures, ctx *Context) ([]Edit, bool, error)
}

EditAction is an optional interface for actions that can express changes as a list of validated byte-range edits rather than returning a whole rewritten file. The engine will apply these edits to ctx.Source.

type EditBuilder

type EditBuilder struct {
	// contains filtered or unexported fields
}

EditBuilder accumulates source edits and applies them in one validated pass. It is a small convenience layer over ApplyEdits.

func (*EditBuilder) Apply

func (b *EditBuilder) Apply(src []byte) ([]byte, bool, error)

Apply applies the accumulated edits to src, returning the new source and a boolean indicating whether any effective change was made.

func (*EditBuilder) Delete

func (b *EditBuilder) Delete(start, end int)

Delete removes src[start:end].

func (*EditBuilder) Insert

func (b *EditBuilder) Insert(pos int, content []byte)

Insert inserts content at pos.

func (*EditBuilder) Replace

func (b *EditBuilder) Replace(start, end int, replace []byte)

Replace replaces src[start:end] with replace.

type Engine

type Engine struct {
	Rules             []Rule
	ColumnLimit       int
	TabStop           int
	MaxIterations     int
	Trace             bool // Enable trace logging
	TraceReasons      bool // Include "why fired/didn't fire" reasons in trace output
	NodeOrder         NodeOrder
	AutoMaxIterations bool // Derive MaxIterations from the AST when true
	DetectCycles      bool // Stop if the engine repeats a previous output

	// ForbiddenSpans holds the union of spans that this engine instance
	// should not rewrite (e.g. spans owned by later pipeline stages).
	ForbiddenSpans llast.OffsetSpanSet

	// Budget provides optional guardrails against pathological rule
	// behavior (e.g. exponential growth, accidental whole-file rewrites).
	Budget RewriteBudget

	// StageName is an optional label (e.g. "expressions",
	// "multiline-calls") that will be included in trace output for easier
	// debugging.
	StageName string
}

Engine executes formatting rules.

func NewEngine

func NewEngine(rules []Rule) *Engine

NewEngine creates a rule engine with default settings.

func (*Engine) Format

func (e *Engine) Format(src []byte) ([]byte, error)

Format applies rules to source code.

func (*Engine) FormatFile

func (e *Engine) FormatFile(src []byte) []byte

FormatFile is a convenience method that reads, formats, and returns source.

type ExpandCompositeLitAction

type ExpandCompositeLitAction struct {
	Target string
}

ExpandCompositeLitAction expands a composite literal into a multiline form when it appears on an overflowing line, or when nested inside a multiline composite literal.

func (*ExpandCompositeLitAction) Execute

func (a *ExpandCompositeLitAction) Execute(caps Captures, ctx *Context) ([]byte,
	bool)

Execute implements Action for ExpandCompositeLitAction.

type ExpandFuncLitBodyAction

type ExpandFuncLitBodyAction struct {
	Target string
}

ExpandFuncLitBodyAction expands a single-line function literal body into a multi-line block with one statement per line.

func (*ExpandFuncLitBodyAction) Execute

func (a *ExpandFuncLitBodyAction) Execute(caps Captures, ctx *Context) ([]byte,
	bool)

Execute implements Action for ExpandFuncLitBodyAction.

type ExprEditSafeCond

type ExprEditSafeCond struct {
	Target string

	// CallArgsPolicy controls whether edits inside call argument
	// expressions are allowed.
	CallArgsPolicy CallArgsPolicy

	// CallArgsAllowlist is used when CallArgsPolicy == CallArgsPolicyAuto.
	// When set, edits are allowed only when the enclosing call's function
	// name matches an entry.
	CallArgsAllowlist []string
}

ExprEditSafeCond is a conservative guard intended for the expression stage: it allows edits only when we are unlikely to interfere with other formatters (calls, composite literals, func literals) and when inline comments would not be lost.

func (*ExprEditSafeCond) Eval

func (c *ExprEditSafeCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for ExprEditSafeCond.

type FalseCond

type FalseCond struct{}

FalseCond always returns false (never applies).

func (FalseCond) Eval

func (c FalseCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for FalseCond.

type FieldMatch

type FieldMatch struct {
	Capture    string   // Variable name to capture (without $)
	SubPattern Pattern  // Nested pattern to match
	Literal    string   // Literal value to match (for operators, identifiers)
	OneOf      []string // Match any of these literal values
}

FieldMatch specifies how to match a field.

type HasAnyCommentCond

type HasAnyCommentCond struct {
	Target string
}

HasAnyCommentCond checks whether the target node's source includes any comment token (line or block) outside of string literals. This is used to conservatively avoid AST-based rewrites that would drop comments inside spans.

func (*HasAnyCommentCond) Eval

func (c *HasAnyCommentCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for HasAnyCommentCond.

type HasCallExprCond

type HasCallExprCond struct {
	Target string
}

HasCallExprCond checks if a node contains a function call.

func (*HasCallExprCond) Eval

func (c *HasCallExprCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for HasCallExprCond.

type HasLineCommentCond

type HasLineCommentCond struct {
	Target string
}

HasLineCommentCond checks whether the target node's source includes an inline line comment ("//") outside of string literals.

func (*HasLineCommentCond) Eval

func (c *HasLineCommentCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for HasLineCommentCond.

type HasMultilineCaseHeaderCond

type HasMultilineCaseHeaderCond struct {
	Target string
}

HasMultilineCaseHeaderCond checks if a `case A, B, ...:` clause spans multiple source lines before the `:`.

func (*HasMultilineCaseHeaderCond) Eval

func (c *HasMultilineCaseHeaderCond) Eval(caps Captures, ctx *Context) bool

type HasMultilineForHeaderCond

type HasMultilineForHeaderCond struct {
	Target string
}

HasMultilineForHeaderCond checks if a `for` statement header spans multiple source lines before the opening `{`.

func (*HasMultilineForHeaderCond) Eval

func (c *HasMultilineForHeaderCond) Eval(caps Captures, ctx *Context) bool

type HasMultilineFuncLitSignatureCond

type HasMultilineFuncLitSignatureCond struct {
	Target string
}

HasMultilineFuncLitSignatureCond checks if a function literal signature spans multiple lines (i.e. there is a newline between `func` and the opening brace).

func (*HasMultilineFuncLitSignatureCond) Eval

type HasMultilineFuncSignatureCond

type HasMultilineFuncSignatureCond struct {
	Target string
}

HasMultilineFuncSignatureCond checks if a function declaration signature spans multiple lines (i.e. there is a newline between `func` and the opening brace).

This is intentionally signature-specific: checking the entire FuncDecl node text would always see newlines in the function body.

func (*HasMultilineFuncSignatureCond) Eval

func (c *HasMultilineFuncSignatureCond) Eval(caps Captures, ctx *Context) bool

type HasMultilineIfHeaderCond

type HasMultilineIfHeaderCond struct {
	Target string
}

HasMultilineIfHeaderCond checks if an `if` statement header spans multiple source lines before the opening `{`.

func (*HasMultilineIfHeaderCond) Eval

func (c *HasMultilineIfHeaderCond) Eval(caps Captures, ctx *Context) bool

type HasMultilineInterfaceMethodCond

type HasMultilineInterfaceMethodCond struct {
	Target string
}

HasMultilineInterfaceMethodCond checks if an interface method signature spans multiple lines (i.e. there is a newline inside the method field text).

This is used by the "next" profile to reflow already-multiline interface methods even when no line exceeds the column limit, enabling collapse of short manually-split return lists.

func (*HasMultilineInterfaceMethodCond) Eval

type HasMultipleMethodsCond

type HasMultipleMethodsCond struct {
	Target string
}

HasMultipleMethodsCond checks if an interface has multiple methods.

func (*HasMultipleMethodsCond) Eval

func (c *HasMultipleMethodsCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for HasMultipleMethodsCond.

type HasNestedMultilineTypeCond

type HasNestedMultilineTypeCond struct {
	Target string
}

HasNestedMultilineTypeCond checks if a FuncDecl has parameters containing func types with multiline nested content (like multiline structs). This is useful to trigger formatting for readability even when no line exceeds the column limit.

func (*HasNestedMultilineTypeCond) Eval

func (c *HasNestedMultilineTypeCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for HasNestedMultilineTypeCond.

type HasPrecedingInterfaceFieldCond

type HasPrecedingInterfaceFieldCond struct {
	Target string
}

HasPrecedingInterfaceFieldCond checks if a field in an interface has a preceding sibling field.

func (*HasPrecedingInterfaceFieldCond) Eval

Eval implements Condition for HasPrecedingInterfaceFieldCond.

type HasPrecedingSiblingCond

type HasPrecedingSiblingCond struct {
	Target string
}

HasPrecedingSiblingCond checks if a case clause has a preceding sibling case. Used to determine if blank line is needed before a case.

func (*HasPrecedingSiblingCond) Eval

func (c *HasPrecedingSiblingCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for HasPrecedingSiblingCond.

type HasType

type HasType struct {
	Types []string
}

HasType matches nodes of specific types without field constraints.

func (*HasType) Match

func (h *HasType) Match(n ast.Node, fset *token.FileSet) (Captures, bool)

Match implements Pattern for HasType.

type InsertBlankAfterAction

type InsertBlankAfterAction struct {
	Target string
}

InsertBlankAfterAction inserts a blank line after a node if not already present.

func (*InsertBlankAfterAction) Execute

func (a *InsertBlankAfterAction) Execute(caps Captures, ctx *Context) ([]byte,
	bool)

Execute implements Action for InsertBlankAfterAction.

type InsertBlankBeforeAction

type InsertBlankBeforeAction struct {
	Target string
}

InsertBlankBeforeAction inserts a blank line before a node if not already present.

func (*InsertBlankBeforeAction) Execute

func (a *InsertBlankBeforeAction) Execute(caps Captures, ctx *Context) ([]byte,
	bool)

Execute implements Action for InsertBlankBeforeAction.

type InsertBlankBeforeFirstStmtInBlockAction

type InsertBlankBeforeFirstStmtInBlockAction struct {
	Target string
}

InsertBlankBeforeFirstStmtInBlockAction inserts a blank line between the opening delimiter of a block-like construct and its first body statement.

This is used for the "next" profile to improve readability when a control statement header is already multiline (e.g. long `if` conditions, long `case` lists).

func (*InsertBlankBeforeFirstStmtInBlockAction) Execute

type IsAfterBlockOpenCond

type IsAfterBlockOpenCond struct {
	Target string
}

IsAfterBlockOpenCond checks if a node is immediately after a block opening brace. This is used to avoid adding blank lines right after { or case:.

func (*IsAfterBlockOpenCond) Eval

func (c *IsAfterBlockOpenCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for IsAfterBlockOpenCond.

type IsAncestorTypeCond

type IsAncestorTypeCond struct {
	Target string
	Type   string
}

IsAncestorTypeCond checks if the target node has an ancestor that matches a given AST node type name.

func (*IsAncestorTypeCond) Eval

func (c *IsAncestorTypeCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for IsAncestorTypeCond.

type IsArithmeticOpCond

type IsArithmeticOpCond struct {
	Target string
}

IsArithmeticOpCond checks if a binary expression uses an arithmetic operator.

func (*IsArithmeticOpCond) Eval

func (c *IsArithmeticOpCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for IsArithmeticOpCond.

type IsBinaryExprCond

type IsBinaryExprCond struct {
	Target string
}

IsBinaryExprCond checks if a node is a binary expression.

func (*IsBinaryExprCond) Eval

func (c *IsBinaryExprCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for IsBinaryExprCond.

type IsCallArgCond

type IsCallArgCond struct {
	Target string
}

IsCallArgCond checks if the target node is a direct argument of a CallExpr. This uses proper parent tracking from the AST traversal.

func (*IsCallArgCond) Eval

func (c *IsCallArgCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for IsCallArgCond.

type IsCallExprCond

type IsCallExprCond struct {
	Target string
}

IsCallExprCond checks if a node is a function call.

func (*IsCallExprCond) Eval

func (c *IsCallExprCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for IsCallExprCond.

type IsCallFuncContainsAnyCond

type IsCallFuncContainsAnyCond struct {
	Target string
	Names  []string
}

IsCallFuncContainsAnyCond checks whether the target node is a CallExpr whose callee name contains any of the provided substrings. This matches legacy multiline-exclude semantics (strings.Contains).

func (*IsCallFuncContainsAnyCond) Eval

func (c *IsCallFuncContainsAnyCond) Eval(caps Captures, ctx *Context) bool

type IsCallFuncInListCond

type IsCallFuncInListCond struct {
	Target string
	Names  []string
}

IsCallFuncInListCond checks whether the target node is a CallExpr whose callee name matches one of the provided names (e.g. "foo", "pkg.Foo"). If the target is not a CallExpr, it returns false.

func (*IsCallFuncInListCond) Eval

func (c *IsCallFuncInListCond) Eval(caps Captures, ctx *Context) bool

type IsChainedCallReceiverCond

type IsChainedCallReceiverCond struct {
	Target string
}

IsChainedCallReceiverCond checks whether a CallExpr is used as the receiver of another call in a method-chain-like expression, i.e. it appears as:

<call>().Method(...)

This is useful to prevent “double ownership” where both the receiver call and the full method chain are rewritten independently, causing oscillation.

func (*IsChainedCallReceiverCond) Eval

func (c *IsChainedCallReceiverCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for IsChainedCallReceiverCond.

type IsComparisonOpCond

type IsComparisonOpCond struct {
	Target string
}

IsComparisonOpCond checks if a binary expression uses a comparison operator.

func (*IsComparisonOpCond) Eval

func (c *IsComparisonOpCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for IsComparisonOpCond.

type IsFinalReturnCond

type IsFinalReturnCond struct {
	Target string
}

IsFinalReturnCond checks if a return statement is the final statement in its function body (not in a nested block like if/for). Returns true if: 1. It's the last statement in the function body 2. There's more than one statement before it

func (*IsFinalReturnCond) Eval

func (c *IsFinalReturnCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for IsFinalReturnCond.

type IsIfErrReturnNeedingBlankCond

type IsIfErrReturnNeedingBlankCond struct {
	Target string
}

IsIfErrReturnNeedingBlankCond checks if an `if err != nil { return ... }` statement should be preceded by a blank line for readability.

This is intentionally opt-in and should only be enabled under explicit profiles (e.g. "next").

func (*IsIfErrReturnNeedingBlankCond) Eval

func (c *IsIfErrReturnNeedingBlankCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for IsIfErrReturnNeedingBlankCond.

type IsInAssignRHSCond

type IsInAssignRHSCond struct {
	Target string
}

IsInAssignRHSCond checks whether the target node is a direct RHS expression in an assignment statement (AssignStmt).

func (*IsInAssignRHSCond) Eval

func (c *IsInAssignRHSCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for IsInAssignRHSCond.

type IsInCallArgsCond

type IsInCallArgsCond struct {
	Target string
}

IsInCallArgsCond checks whether the target node is contained within an argument expression of any enclosing CallExpr. This rejects not only direct call arguments, but also nested subexpressions inside an argument.

func (*IsInCallArgsCond) Eval

func (c *IsInCallArgsCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for IsInCallArgsCond.

type IsInInterfaceCond

type IsInInterfaceCond struct {
	Target string
}

IsInInterfaceCond checks if a node is inside an interface type declaration.

func (*IsInInterfaceCond) Eval

func (c *IsInInterfaceCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for IsInInterfaceCond.

type IsInReturnResultsCond

type IsInReturnResultsCond struct {
	Target string
}

IsInReturnResultsCond checks whether the target node is a direct result expression in a return statement.

func (*IsInReturnResultsCond) Eval

func (c *IsInReturnResultsCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for IsInReturnResultsCond.

type IsInterfaceMethodCond

type IsInterfaceMethodCond struct {
	Target string
}

IsInterfaceMethodCond checks if a field is a method in an interface.

func (*IsInterfaceMethodCond) Eval

func (c *IsInterfaceMethodCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for IsInterfaceMethodCond.

type IsLogOrPrintfCallCond

type IsLogOrPrintfCallCond struct {
	Target string

	// MatchAnySelectorPrefix enables suffix-only matching for selector
	// calls.
	//
	// When false (default), this condition matches only the canonical
	// patterns: "log.Infof", "fmt.Sprintf", etc.
	//
	// When true, any selector expression whose Sel is one of the known
	// log/printf function names is matched, regardless of the selector
	// prefix (e.g. "myLogger.Infof", "rpcLog.Errorf"). This is
	// intentionally opt-in because some repos include custom loggers that
	// should not be rewritten.
	MatchAnySelectorPrefix bool

	// SelectorNames overrides the set of recognized printf-style selector
	// names for suffix-only matching (e.g. "Infof", "Errorf").
	//
	// When empty, a built-in default set is used.
	//
	// This does not affect canonical exact matches (e.g. "fmt.Errorf"),
	// which remain matched regardless of SelectorNames.
	SelectorNames []string

	// SelectorPrefixes restricts selector-prefix matching for log/printf
	// calls. This supports allowlist-style targeting of custom loggers.
	//
	// When empty (default), selector-prefix matching behavior is controlled
	// only by MatchAnySelectorPrefix.
	//
	// When non-empty, a selector expression is treated as a log/printf call
	// only if its receiver expression string (e.g. "rpcSLog", "zap.S()",
	// "zap.L().Sugar()") has one of these prefixes.
	//
	// Canonical patterns (e.g. "fmt.Errorf") remain matched regardless of
	// SelectorPrefixes.
	SelectorPrefixes []string

	// IncludeNonFStringCalls enables matching a small subset of non-`*f`
	// log calls (e.g. `logger.Error("...")`) when the first argument is a
	// string. This is intended for "next" where string-call formatting is
	// more broadly useful.
	IncludeNonFStringCalls bool
}

IsLogOrPrintfCallCond checks if a call expression is a log or printf-style call.

func (*IsLogOrPrintfCallCond) Eval

func (c *IsLogOrPrintfCallCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for IsLogOrPrintfCallCond.

type IsLogicalOpCond

type IsLogicalOpCond struct {
	Target string
}

IsLogicalOpCond checks if a binary expression uses a logical operator.

func (*IsLogicalOpCond) Eval

func (c *IsLogicalOpCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for IsLogicalOpCond.

type IsMethodChainCond

type IsMethodChainCond struct {
	Target   string
	MinCalls int // Minimum number of calls to consider it a chain (default 2)
}

IsMethodChainCond checks if a call expression is part of a method chain with at least minCalls chained method calls.

func (*IsMethodChainCond) Eval

func (c *IsMethodChainCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for IsMethodChainCond.

type IsNonFLogCallCond

type IsNonFLogCallCond struct {
	Target string
}

IsNonFLogCallCond checks if a call expression is a non-printf-style logging call such as `log.Info(...)`.

This is used to keep the generic multiline-call formatter from rewriting these calls. The log/printf formatter intentionally targets only the `*f` variants, and some repos rely on the non-`f` variants being left alone.

func (*IsNonFLogCallCond) Eval

func (c *IsNonFLogCallCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for IsNonFLogCallCond.

type IsOutermostBinaryExprCond

type IsOutermostBinaryExprCond struct {
	Target string
}

IsOutermostBinaryExprCond checks if this binary expression is not a child of another binary expression with the same operator type. This prevents matching inner nodes in chains like "a && b && c".

func (*IsOutermostBinaryExprCond) Eval

func (c *IsOutermostBinaryExprCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for IsOutermostBinaryExprCond.

type IsParentTypeCond

type IsParentTypeCond struct {
	Target string
	Type   string
}

IsParentTypeCond checks if the target node's direct parent matches a given AST node type name (e.g. "CallExpr", "AssignStmt").

func (*IsParentTypeCond) Eval

func (c *IsParentTypeCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for IsParentTypeCond.

type IsParseableCond

type IsParseableCond struct {
	// Want indicates the desired parseability:
	// - Want == true => condition passes only if the source parses
	// - Want == false => condition passes only if the source does not parse
	Want bool
}

IsParseableCond checks whether the current ctx.Source parses as a Go file. This is primarily intended to gate file-scoped legacy fallback rules so they only run on parse failures.

func (*IsParseableCond) Eval

func (c *IsParseableCond) Eval(_ Captures, ctx *Context) bool

type IsReturnNeedingBlankCond

type IsReturnNeedingBlankCond struct {
	Target string
}

IsReturnNeedingBlankCond checks if a return statement needs a blank line before it. This is true if: 1. It's not immediately after a block open ({ or case:) 2. It's not already preceded by a blank line

func (*IsReturnNeedingBlankCond) Eval

func (c *IsReturnNeedingBlankCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for IsReturnNeedingBlankCond.

type IsSimpleLiteralCond

type IsSimpleLiteralCond struct {
	Target string
}

IsSimpleLiteralCond checks if a node is a simple literal (number, bool, nil).

func (*IsSimpleLiteralCond) Eval

func (c *IsSimpleLiteralCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for IsSimpleLiteralCond.

type IsStringConcatCond

type IsStringConcatCond struct {
	Target string
}

IsStringConcatCond checks if a binary expression involves string concatenation. String concatenation uses + but should be handled differently than arithmetic.

func (*IsStringConcatCond) Eval

func (c *IsStringConcatCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for IsStringConcatCond.

type KeepTogetherAction

type KeepTogetherAction struct {
	Target string
}

KeepTogetherAction marks a node as atomic (won't be broken by other rules).

func (*KeepTogetherAction) Execute

func (a *KeepTogetherAction) Execute(caps Captures, ctx *Context) ([]byte,
	bool)

Execute implements Action for KeepTogetherAction.

type LeftFlowCallAction

type LeftFlowCallAction struct {
	Target string

	// FormatFunc is an optional function that formats the call using legacy
	// logic. If nil, a simplified fallback is used.
	FormatFunc func(call []byte, wsIndent string, baseLen int, colLimit, tabStop int) string
}

LeftFlowCallAction formats log/printf calls using left-flow packing with string splitting. This action delegates to the legacy formatter to ensure identical output behavior.

func (*LeftFlowCallAction) Execute

func (a *LeftFlowCallAction) Execute(caps Captures, ctx *Context) ([]byte,
	bool)

Execute implements Action for LeftFlowCallAction.

type LeftFlowFormatFunc

type LeftFlowFormatFunc func(call []byte, wsIndent string, baseLen int, colLimit, tabStop int) string

LeftFlowFormatFunc is the signature for the left-flow call formatting function. This allows injecting the legacy formatter implementation to avoid circular imports.

type LegacyBlankLinesFormatAction

type LegacyBlankLinesFormatAction struct {
	FormatFunc LegacyBlankLinesFormatFunc
}

LegacyBlankLinesFormatAction delegates blank line formatting to an injected legacy formatter implementation.

func (*LegacyBlankLinesFormatAction) Execute

func (a *LegacyBlankLinesFormatAction) Execute(_ Captures, ctx *Context) (
	[]byte, bool)

Execute implements Action for LegacyBlankLinesFormatAction.

type LegacyBlankLinesFormatFunc

type LegacyBlankLinesFormatFunc func(src []byte) ([]byte, bool)

LegacyBlankLinesFormatFunc formats blank lines in src and reports whether it changed anything.

type LegacyCommentFormatAction

type LegacyCommentFormatAction struct {
	MoveInlineAbove bool
	FormatFunc      LegacyCommentFormatFunc
}

LegacyCommentFormatAction delegates comment formatting to an injected legacy formatter implementation.

func (*LegacyCommentFormatAction) Execute

func (a *LegacyCommentFormatAction) Execute(_ Captures, ctx *Context) ([]byte,
	bool)

Execute implements Action for LegacyCommentFormatAction.

type LegacyCommentFormatFunc

type LegacyCommentFormatFunc func(src []byte, colLimit, tabStop int, moveInlineAbove bool) ([]byte, bool)

LegacyCommentFormatFunc formats comments in src and reports whether it changed anything.

type LegacyCompactCallFormatAction

type LegacyCompactCallFormatAction struct {
	FormatFunc LegacyCompactCallFormatFunc
}

LegacyCompactCallFormatAction delegates compact-call formatting to an injected legacy formatter implementation.

func (*LegacyCompactCallFormatAction) Execute

func (a *LegacyCompactCallFormatAction) Execute(_ Captures, ctx *Context) (
	[]byte, bool)

Execute implements Action for LegacyCompactCallFormatAction.

type LegacyCompactCallFormatFunc

type LegacyCompactCallFormatFunc func(src []byte, colLimit, tabStop int) ([]byte, bool)

LegacyCompactCallFormatFunc formats compact call targets (and optionally fallback non-targets) in src and reports whether it changed anything.

type LegacyFuncSigFormatAction

type LegacyFuncSigFormatAction struct {
	FormatFunc LegacyFuncSigFormatFunc
}

LegacyFuncSigFormatAction delegates function signature formatting to an injected legacy formatter implementation.

func (*LegacyFuncSigFormatAction) Execute

func (a *LegacyFuncSigFormatAction) Execute(_ Captures, ctx *Context) ([]byte,
	bool)

Execute implements Action for LegacyFuncSigFormatAction.

type LegacyFuncSigFormatFunc

type LegacyFuncSigFormatFunc func(src []byte, colLimit, tabStop int) ([]byte, bool)

LegacyFuncSigFormatFunc formats function signatures in src and reports whether it changed anything.

type LegacyMultiLineScanAction

type LegacyMultiLineScanAction struct {
	Excludes []string
	ScanFunc LegacyMultiLineScanFunc
}

LegacyMultiLineScanAction delegates multiline-call detection + rewriting to a scan-based implementation, matching the legacy formatter's behavior (including its lexical detection quirks).

func (*LegacyMultiLineScanAction) Execute

func (a *LegacyMultiLineScanAction) Execute(_ Captures, ctx *Context) ([]byte,
	bool)

Execute implements Action for LegacyMultiLineScanAction.

type LegacyMultiLineScanFunc

type LegacyMultiLineScanFunc func(src []byte, colLimit, tabStop int, excludes []string) ([]byte, bool)

LegacyMultiLineScanFunc applies a single legacy multiline-call formatting pass to src and reports whether it changed anything.

This intentionally mirrors the legacy MultiLineCallFormatter behavior of making at most one change per pass and repeating up to a fixed iteration cap.

type LegacyOnePerLineCallAction

type LegacyOnePerLineCallAction struct {
	Target string

	// FormatFunc is an optional function that formats the call using legacy
	// logic. If nil, a simplified fallback is used.
	FormatFunc func(call []byte, wsIndent string, colLimit, tabStop int) string
}

LegacyOnePerLineCallAction formats generic function calls using the legacy MultiLineCallFormatter style (one argument per line). Unlike AST-based call actions, this action preserves comments inside argument lists because it only rearranges the existing source bytes.

func (*LegacyOnePerLineCallAction) Execute

func (a *LegacyOnePerLineCallAction) Execute(caps Captures, ctx *Context) (
	[]byte, bool)

Execute implements Action for LegacyOnePerLineCallAction.

type LineWidthCond

type LineWidthCond struct {
	Target string // Capture name (without $) or "node" for matched node
	Op     string // ">", "<", ">=", "<=", "=="
	Value  int    // If 0, uses ctx.ColumnLimit
}

LineWidthCond checks if a node's line width exceeds a threshold.

func (*LineWidthCond) Eval

func (c *LineWidthCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for LineWidthCond.

type LogPrintfOptions

type LogPrintfOptions struct {
	// MatchAnySelectorPrefix enables suffix-only matching for selector
	// calls. See IsLogOrPrintfCallCond.MatchAnySelectorPrefix for details.
	MatchAnySelectorPrefix bool

	// SelectorNames overrides the set of recognized printf-style selector
	// names for suffix-only matching. See
	// IsLogOrPrintfCallCond.SelectorNames.
	SelectorNames []string

	// SelectorPrefixes restricts selector-prefix matching for log/printf
	// calls (allowlist). See IsLogOrPrintfCallCond.SelectorPrefixes.
	SelectorPrefixes []string

	// IncludeNonFStringCalls enables matching a small subset of non-`*f`
	// log calls (e.g. `logger.Error("...")`) when the first argument is a
	// string.
	//
	// This is intended for the "next" profile only; it expands the set of
	// targeted string calls beyond the printf-style patterns.
	IncludeNonFStringCalls bool
}

LogPrintfOptions configures LogPrintfRulesWithOptions behavior.

type LongExprOptions

type LongExprOptions struct {
	// AllowCallArgs forces breaking long logical chains inside call
	// arguments. This can interact with call-formatting stages, so it is
	// disabled by default.
	AllowCallArgs bool

	// CallArgsPolicy controls call-argument editing for the expression
	// stage. When set to CallArgsPolicyAuto, CallArgsAllowlist is used.
	CallArgsPolicy CallArgsPolicy

	// CallArgsAllowlist is used when CallArgsPolicy == CallArgsPolicyAuto.
	// Typically, this should be a list of call names excluded from later
	// call-formatting stages.
	CallArgsAllowlist []string

	// LogicalChainStyle controls how long &&/|| chains are broken.
	// Supported: "legacy" (BreakAtOpAction) and "layout" (layout engine).
	// Empty defaults to "legacy".
	LogicalChainStyle string

	// ArithmeticChainStyle controls how long arithmetic chains are broken.
	// Supported: "legacy" (BreakAtOpAction) and "layout" (layout engine).
	// Empty defaults to "legacy".
	ArithmeticChainStyle string

	// CaseClauseStyle controls how long `case A, B, C:` lists are broken.
	// Supported: "legacy" (single-break BreakCaseClauseAction) and "layout"
	// (layout engine, may break multiple times). Empty defaults to
	// "legacy".
	CaseClauseStyle string

	// SelectorChainStyle controls formatting of long selector chains.
	// Supported: "legacy" (disabled) and "layout" (layout engine). Empty
	// defaults to "legacy".
	SelectorChainStyle string
}

LongExprOptions configures LongExprRules behavior.

type MaxSpanLineWidthCond

type MaxSpanLineWidthCond struct {
	Target string
	Op     string
	Value  int // If 0, uses ctx.ColumnLimit
}

MaxSpanLineWidthCond checks the maximum visual width of any line spanned by a node's source range (including continuation lines for multiline constructs).

This is useful for cases where:

  • the node starts on a short line (so LineWidthCond is a false negative), and
  • collapsing whitespace produces a short estimate (so CollapsedWidthCond is a false negative), but
  • an indented continuation line still exceeds the column limit.

func (*MaxSpanLineWidthCond) Eval

func (c *MaxSpanLineWidthCond) Eval(caps Captures, ctx *Context) bool

type MultiLineCallOptions

type MultiLineCallOptions struct {
	// Excludes is a list of function names that should be excluded from
	// multiline call formatting (matches "foo" or "pkg.Foo").
	Excludes []string

	// LogCallSelectorNames configures which selector/ident names should be
	// treated as log/printf-style calls for the purpose of excluding them
	// from generic multiline call formatting. When empty, a built-in
	// default set is used.
	LogCallSelectorNames []string

	// LogCallSelectorPrefixes optionally restricts selector-prefix matching
	// for log/printf call exclusion (allowlist). See
	// IsLogOrPrintfCallCond.SelectorPrefixes.
	LogCallSelectorPrefixes []string

	// MethodChainStyle controls how long method chains are broken.
	// Supported: ""/"legacy" (existing BreakMethodChainAction) and "layout"
	// (layout engine).
	MethodChainStyle string

	// CallArgsStyle controls how long generic call expressions are broken.
	// Supported: ""/"legacy" (existing packed/legacy formatters) and
	// "layout" (layout engine).
	CallArgsStyle string

	// CallArgsGrouping optionally enables an explicit grouping heuristic
	// for call argument lists when CallArgsStyle == "layout".
	//
	// Supported values:
	// - "" (default): one argument per line (forced break)
	// - "pairs": group args as (a, b) pairs when possible
	CallArgsGrouping string

	// DisableBreakBeforeCallOnLongMultiAssignPrefix disables a heuristic in
	// the packed multiline call action that prefers breaking before a call
	// (keeping it single-line) when the only overflow is caused by a long
	// multi-assignment prefix. Some profiles intentionally prefer
	// formatting the call itself as multiline instead.
	DisableBreakBeforeCallOnLongMultiAssignPrefix bool

	// CheckMaxSpanLineWidth enables detection of overlong continuation
	// lines for already-multiline calls. This is useful in styles that want
	// to enforce column limits even when a call's first line and collapsed
	// width appear to fit.
	//
	// This is intentionally opt-in to avoid changing legacy/parity
	// behavior.
	CheckMaxSpanLineWidth bool
}

MultiLineCallOptions configures MultiLineCallRules behavior.

type NoOpAction

type NoOpAction struct{}

NoOpAction does nothing (used for keep_together which just marks nodes).

func (*NoOpAction) Execute

func (a *NoOpAction) Execute(caps Captures, ctx *Context) ([]byte, bool)

Execute implements Action for NoOpAction.

type NodeOrder

type NodeOrder int

NodeOrder controls the order the DSL engine considers nodes when searching for a matching rule.

const (
	// NodeOrderPreorder processes nodes in AST pre-order (current default).
	NodeOrderPreorder NodeOrder = iota

	// NodeOrderSourceOrder processes nodes in ascending source offset
	// order. This more closely matches behavior of the legacy scanner-based
	// formatters which operate left-to-right through the file.
	NodeOrderSourceOrder

	// NodeOrderDeepestFirst processes smaller-span nodes before larger-span
	// nodes. This helps avoid “outer before inner” ordering hazards where
	// an outer rewrite makes decisions based on inner nodes that have not
	// yet been rewritten within the same engine run.
	NodeOrderDeepestFirst
)

type NodePattern

type NodePattern struct {
	Type   string                // "CallExpr", "BinaryExpr", etc.
	Fields map[string]FieldMatch // Field constraints
}

NodePattern matches a specific AST node type with field constraints.

func (*NodePattern) Match

func (p *NodePattern) Match(n ast.Node, fset *token.FileSet) (Captures, bool)

Match implements Pattern for NodePattern.

type NodeWidthCond

type NodeWidthCond struct {
	Target string
	Op     string
	Value  int
}

NodeWidthCond checks if a node's total width exceeds a threshold.

func (*NodeWidthCond) Eval

func (c *NodeWidthCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for NodeWidthCond.

type NotCond

type NotCond struct {
	Cond Condition
}

NotCond negates a condition.

func (*NotCond) Eval

func (c *NotCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for NotCond.

type OnePerLineMultiLineCallAction

type OnePerLineMultiLineCallAction struct {
	Target string
}

OnePerLineMultiLineCallAction formats a call as a multiline call with one argument per line. This matches the legacy MultiLineCallFormatter style more closely than PackedMultiLineCallAction (which packs args when possible).

func (*OnePerLineMultiLineCallAction) Execute

func (a *OnePerLineMultiLineCallAction) Execute(caps Captures, ctx *Context) (
	[]byte, bool)

Execute implements Action for OnePerLineMultiLineCallAction.

type OpIsCond

type OpIsCond struct {
	Target    string
	Operators []string // List of operators to match
}

OpIsCond checks if a binary/unary expression has a specific operator.

func (*OpIsCond) Eval

func (c *OpIsCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for OpIsCond.

type OrCond

type OrCond struct {
	Conds []Condition
}

OrCond combines conditions with OR.

func (*OrCond) Eval

func (c *OrCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for OrCond.

type PackedMultiLineCallAction

type PackedMultiLineCallAction struct {
	Target string

	// FormatFunc is an optional function that formats the call using legacy
	// logic. If nil, a simplified fallback is used.
	FormatFunc func(call []byte, wsIndent string, colLimit, tabStop int) string

	// DisableBreakBeforeCallOnLongMultiAssignPrefix disables a readability
	// heuristic that prefers breaking before a call (keeping it
	// single-line) when the only overflow is caused by a long
	// multi-assignment prefix.
	//
	// Some modes (e.g. "next") intentionally prefer preserving the
	// assignment shape by formatting the call itself as multiline rather
	// than detaching the call from the assignment with a newline.
	DisableBreakBeforeCallOnLongMultiAssignPrefix bool

	// OnlyIfSingleLine restricts this action to calls that are currently
	// rendered on a single line in the source span. This is useful as a
	// fallback when a layout-based formatter "owns" the multiline shape and
	// we only want the packed formatter to run when the call is still a
	// long single-line expression.
	OnlyIfSingleLine bool
}

PackedMultiLineCallAction formats generic function calls using packed multi-line style when they exceed the column limit. This action delegates to the legacy formatter to ensure identical output behavior.

func (*PackedMultiLineCallAction) Execute

func (a *PackedMultiLineCallAction) Execute(caps Captures, ctx *Context) (
	[]byte, bool)

Execute implements Action for PackedMultiLineCallAction.

type PackedMultiLineFormatFunc

type PackedMultiLineFormatFunc func(call []byte, wsIndent string, colLimit, tabStop int) string

PackedMultiLineFormatFunc is the signature for the packed multiline formatter. Unlike LeftFlowFormatFunc, it doesn't need baseLen since it always puts opening paren on its own line.

type Pattern

type Pattern interface {
	Match(n ast.Node, fset *token.FileSet) (Captures, bool)
}

Pattern matches against Go AST nodes.

type ReflowCallAction

type ReflowCallAction struct {
	Target   string
	Strategy ReflowStrategy
}

ReflowCallAction reformats a function call.

func (*ReflowCallAction) Execute

func (a *ReflowCallAction) Execute(caps Captures, ctx *Context) ([]byte, bool)

Execute implements Action for ReflowCallAction.

type ReflowNestedCallsAction

type ReflowNestedCallsAction struct {
	Target   string
	Strategy ReflowStrategy
}

ReflowNestedCallsAction finds and reflows function calls within an expression.

func (*ReflowNestedCallsAction) Execute

func (a *ReflowNestedCallsAction) Execute(caps Captures, ctx *Context) ([]byte,
	bool)

Execute implements Action for ReflowNestedCallsAction.

type ReflowStrategy

type ReflowStrategy string

ReflowStrategy defines how to reformat a function call.

const (
	// StrategyOnePerLine puts each argument on its own line.
	StrategyOnePerLine ReflowStrategy = "one-per-line"
	// StrategyLeftPack packs arguments greedily from left.
	StrategyLeftPack ReflowStrategy = "left-pack"
	// StrategyAdaptive uses one-per-line if any arg is multiline, else
	// left-pack.
	StrategyAdaptive ReflowStrategy = "adaptive"
)

type ReflowStringConcatAction

type ReflowStringConcatAction struct {
	Target string
}

ReflowStringConcatAction rewrites a long string concatenation expression into a multi-line concatenation with stable indentation.

func (*ReflowStringConcatAction) Execute

func (a *ReflowStringConcatAction) Execute(caps Captures, ctx *Context) ([]byte,
	bool)

Execute implements Action for ReflowStringConcatAction.

func (*ReflowStringConcatAction) ExecuteEdits

func (a *ReflowStringConcatAction) ExecuteEdits(caps Captures, ctx *Context) (
	[]Edit, bool, error)

ExecuteEdits implements EditAction for ReflowStringConcatAction.

type RewriteBudget

type RewriteBudget struct {
	// MaxOutputBytes rejects a rewrite if the candidate output exceeds this
	// absolute size.
	MaxOutputBytes int

	// MaxBytesIncrease rejects a rewrite if the candidate output grows more
	// than this many bytes beyond the initial input size for the engine
	// run.
	MaxBytesIncrease int
}

RewriteBudget describes optional safety limits for the DSL engine. Zero values mean "no limit".

type Rule

type Rule struct {
	Name     string
	Pattern  Pattern
	When     Condition
	Priority int
	Action   Action
}

Rule represents a formatting rule.

func BlankLineRules

func BlankLineRules() []Rule

BlankLineRules returns rules for inserting blank lines. These are separate from expression formatting rules.

func BlankLineRulesWithOptions

func BlankLineRulesWithOptions(opts BlankLineOptions) []Rule

func DefaultRules

func DefaultRules(formatFunc ...LeftFlowFormatFunc) []Rule

DefaultRules returns the standard formatting rules, including blank line rules. The optional formatFunc parameter allows injecting the legacy formatter for left-flow call formatting.

func DefaultRulesWithOptions

func DefaultRulesWithOptions(opts DefaultRuleOptions) []Rule

DefaultRulesWithOptions returns the default rule set used by the DSL engine. It is intended to reproduce the legacy pipeline behavior via injected formatter functions where available.

func ExpandCompositeLitRules

func ExpandCompositeLitRules() []Rule

ExpandCompositeLitRules returns DSL rules that expand composite literals into a multiline form when needed.

func ExpandFuncLitBodyRules

func ExpandFuncLitBodyRules() []Rule

ExpandFuncLitBodyRules returns DSL rules that expand single-line function literals into multi-line blocks.

func ExpressionRules

func ExpressionRules() []Rule

ExpressionRules returns rules for expression formatting (logical chains, etc). Use this for isolated testing of expression breaking.

func LegacyBlankLinesFallbackRules

func LegacyBlankLinesFallbackRules(
	formatFunc LegacyBlankLinesFormatFunc) []Rule

LegacyBlankLinesFallbackRules delegates blank line formatting to a legacy formatter, but at a low priority intended only as a fallback (e.g. when the source cannot be parsed, or as a last resort after native DSL rules).

func LegacyBlankLinesRules

func LegacyBlankLinesRules(formatFunc LegacyBlankLinesFormatFunc) []Rule

LegacyBlankLinesRules delegates blank line formatting to a legacy formatter.

func LegacyCommentRules

func LegacyCommentRules(formatFunc LegacyCommentFormatFunc,
	moveInlineAbove bool) []Rule

LegacyCommentRules delegates comment formatting to a legacy formatter.

func LegacyCompactCallRules

func LegacyCompactCallRules(formatFunc LegacyCompactCallFormatFunc) []Rule

LegacyCompactCallRules delegates the compact-call stage to a legacy formatter. This exists to preserve parity with the legacy pipeline while running under the DSL engine.

func LegacyFuncSigFallbackRules

func LegacyFuncSigFallbackRules(formatFunc LegacyFuncSigFormatFunc) []Rule

LegacyFuncSigFallbackRules delegates function signature formatting to a legacy formatter, but at a low priority intended only as a fallback (e.g. when the source cannot be parsed).

func LegacyFuncSigRules

func LegacyFuncSigRules(formatFunc LegacyFuncSigFormatFunc) []Rule

LegacyFuncSigRules delegates function signature formatting to a legacy formatter.

func LegacyMultiLineCallRules

func LegacyMultiLineCallRules(formatFunc ...PackedMultiLineFormatFunc) []Rule

LegacyMultiLineCallRules returns a rule set intended to match the legacy MultiLineCallFormatter behavior more closely (one argument per line, no method-chain breaking).

func LegacyMultiLineCallRulesWithOptions

func LegacyMultiLineCallRulesWithOptions(opts MultiLineCallOptions,
	formatFunc ...PackedMultiLineFormatFunc) []Rule

LegacyMultiLineCallRulesWithOptions returns LegacyMultiLineCallRules with explicit options.

func LegacyMultiLineScanRules

func LegacyMultiLineScanRules(scanFunc LegacyMultiLineScanFunc) []Rule

LegacyMultiLineScanRules returns a rule set that delegates to the legacy scan-based multiline call formatter. This is used to preserve exact legacy behavior (including detection quirks) while running in the DSL engine.

func LegacyMultiLineScanRulesWithOptions

func LegacyMultiLineScanRulesWithOptions(opts MultiLineCallOptions,
	scanFunc LegacyMultiLineScanFunc) []Rule

LegacyMultiLineScanRulesWithOptions is the configurable form of LegacyMultiLineScanRules.

func LogPrintfRules

func LogPrintfRules(formatFunc ...LeftFlowFormatFunc) []Rule

LogPrintfRules returns only the log/printf formatting rule. Use this for isolated testing of log call formatting. The optional formatFunc parameter allows injecting the legacy formatter.

func LogPrintfRulesWithOptions

func LogPrintfRulesWithOptions(opts LogPrintfOptions,
	formatFunc ...LeftFlowFormatFunc) []Rule

LogPrintfRulesWithOptions returns only the log/printf formatting rule, with explicit options.

func LongExprRules

func LongExprRules() []Rule

LongExprRules returns a rule set intended to match the legacy long expression formatter behavior: break long boolean/arithmetic chains and case clauses, without reformatting calls or signatures.

func LongExprRulesWithOptions

func LongExprRulesWithOptions(opts LongExprOptions) []Rule

LongExprRulesWithOptions returns LongExprRules with explicit options.

func MethodChainRules

func MethodChainRules() []Rule

MethodChainRules returns rules for method chain formatting. Use this for isolated testing of method chain breaking.

func MultiLineCallRules

func MultiLineCallRules(formatFunc ...PackedMultiLineFormatFunc) []Rule

MultiLineCallRules returns rules for multiline call formatting. Use this for isolated testing of generic call reflow. The optional formatFunc parameter allows injecting the legacy formatter.

func MultiLineCallRulesWithOptions

func MultiLineCallRulesWithOptions(opts MultiLineCallOptions,
	formatFunc ...PackedMultiLineFormatFunc) []Rule

MultiLineCallRulesWithOptions returns MultiLineCallRules with explicit options.

func PackedMultiLineOnlyRules

func PackedMultiLineOnlyRules(formatFunc ...PackedMultiLineFormatFunc) []Rule

PackedMultiLineOnlyRules returns multiline call rules that format only non-method-chain call expressions using packed multiline formatting.

This is a smaller-scope variant of MultiLineCallRules that avoids method-chain breaking (which is a more opinionated behavior change).

func PackedMultiLineOnlyRulesWithOptions

func PackedMultiLineOnlyRulesWithOptions(opts MultiLineCallOptions,
	formatFunc ...PackedMultiLineFormatFunc) []Rule

PackedMultiLineOnlyRulesWithOptions is the configurable form of PackedMultiLineOnlyRules.

func RulesFor

func RulesFor(set RuleSet, opts DefaultRuleOptions) []Rule

RulesFor returns the rule list for a named rule set.

func SignatureRules

func SignatureRules(config ...SignatureConfig) []Rule

SignatureRules returns rules for function signature formatting. Use this for isolated testing of signature breaking. The optional config parameter allows injecting the legacy formatters.

func SplitLongStringLiteralRules

func SplitLongStringLiteralRules(opts SplitLongStringLiteralOptions) []Rule

SplitLongStringLiteralRules returns DSL rules that split long quoted string literals in call-argument position into concatenations.

type RuleSet

type RuleSet string

RuleSet identifies a cohesive bundle of DSL formatting rules.

The goal is to make it explicit when callers want: - legacy-parity behavior (used by golden tests and stable CLI modes), vs. - modern/experimental behavior (opt-in).

const (
	// RuleSetDefault is the default full DSL rule set (signatures, calls,
	// expressions, blank lines). It is intended to reproduce legacy
	// behavior when format functions are injected via DefaultRuleOptions.
	RuleSetDefault RuleSet = "default"

	// RuleSetExpressionOnly is expression-breaking rules intended to run
	// alongside other dedicated rule sets (calls/signatures) without
	// overlap.
	RuleSetExpressionOnly RuleSet = "expression-only"

	// RuleSetExpressionCompat is a conservative expression + signature
	// subset used for tests that expect legacy-like signature wrapping.
	RuleSetExpressionCompat RuleSet = "expression-compat"
)

type SequenceAction

type SequenceAction struct {
	Actions []Action
}

SequenceAction executes actions in sequence until one succeeds.

func (*SequenceAction) Execute

func (a *SequenceAction) Execute(caps Captures, ctx *Context) ([]byte, bool)

Execute implements Action for SequenceAction.

type SignatureConfig

type SignatureConfig struct {
	FuncFormatter   SignatureFormatFunc
	MethodFormatter SignatureFormatFunc
}

SignatureConfig holds optional formatters for signature rules.

type SignatureFormatFunc

type SignatureFormatFunc func(signature, indent string, colLimit, tabStop int) (string, bool)

SignatureFormatFunc is the signature for the function signature formatting function. This allows injecting the legacy formatter implementation to avoid circular imports. Returns the formatted signature and whether a blank line should be added after.

type SplitLongStringLiteralAction

type SplitLongStringLiteralAction struct {
	Target     string
	MinTailLen int
}

SplitLongStringLiteralAction splits a long quoted string literal into a concatenation of multiple quoted literals, adding newlines and indentation.

This is intentionally conservative and currently targets call-argument string literals (to avoid rewriting standalone expressions unexpectedly).

func (*SplitLongStringLiteralAction) Execute

func (a *SplitLongStringLiteralAction) Execute(caps Captures, ctx *Context) (
	[]byte, bool)

Execute implements Action for SplitLongStringLiteralAction.

type SplitLongStringLiteralOptions

type SplitLongStringLiteralOptions struct {
	// MinTailLen avoids creating tiny trailing pieces when splitting at
	// spaces.
	MinTailLen int
}

SplitLongStringLiteralOptions configures string literal splitting.

type TrueCond

type TrueCond struct{}

TrueCond always returns true (no condition / always applies).

func (TrueCond) Eval

func (c TrueCond) Eval(caps Captures, ctx *Context) bool

Eval implements Condition for TrueCond.

type TryElseAction

type TryElseAction struct {
	Try  Action
	Else Action
}

TryElseAction tries the first action, falls back to second if it doesn't help.

func (*TryElseAction) Execute

func (a *TryElseAction) Execute(caps Captures, ctx *Context) ([]byte, bool)

Execute implements Action for TryElseAction.

type Wildcard

type Wildcard struct{}

Wildcard matches any node.

func (Wildcard) Match

func (w Wildcard) Match(n ast.Node, fset *token.FileSet) (Captures, bool)

Match implements Pattern for Wildcard.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL