Documentation
¶
Overview ¶
Package goexprshape classifies where a gsx value sits within the Go expression it was substituted into, at a GoWithElements decl's embedding point (e.g. an assignment RHS vs. a call argument). Shared by internal/printer (decides whether to visually wrap a value in decorative parens) and internal/codegen (decides whether to strip a decorative paren before splicing the value's lowered form into the generated .x.go — see each package's own doc for why the two decisions are independent).
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func StripLeadingParen ¶
StripLeadingParen drops a decorative ")" — and any whitespace before it — from the start of src, when src (after trimming leading whitespace) starts with exactly one ")". Used on the GoText immediately after a ParenWrap-classified element/fragment; see StripTrailingParen.
func StripTrailingParen ¶
StripTrailingParen drops a decorative "(" — and any whitespace after it — from the end of src, when src (after trimming trailing whitespace) ends in exactly one "(". Used on the GoText immediately before a ParenWrap-classified element/fragment, by both internal/printer (rebuilding fresh output — so an already-wrapped value isn't wrapped a second time) and internal/codegen (stripping the decorative paren before splicing the value's lowered closure, so it can never trip Go's automatic semicolon insertion).
Types ¶
type Hole ¶
type Hole struct {
Start, End int
}
Hole is one placeholder's byte range [Start, End) within the src passed to Classify — Start..End is the placeholder identifier itself, exclusive of any surrounding whitespace.
func Sanitize ¶
Sanitize returns src with every bracket-adjacent newline touching a hole collapsed to a single space, plus each hole's range within the returned string (same order as holes; the placeholder text itself is never altered, only the whitespace around it).
A hole alone on its own line directly inside a bracket — `(\nHOLE\n)`, the shape gsx fmt's own decorative-paren output takes — makes Go's automatic semicolon insertion place a semicolon after the placeholder identifier, so the source no longer parses. Every consumer that hands the substituted source to go/parser or go/format must sanitize it first, or that consumer silently fails on any file gsx fmt has already formatted once. Classify does this internally; internal/printer calls it directly, because go/format needs the same treatment for the same reason.
Sanitize is idempotent: its output has no newline left adjacent to a hole's brackets, so re-running it is a no-op.
type Result ¶
type Result struct {
// Shape is the position's kind, independent of whether it currently has a
// decorative paren around it — this answers "would wrapping this value in
// (...) be safe," not "is it wrapped right now."
Shape Shape
// Wrapped reports whether the value, AS GIVEN in src, is actually sitting
// inside a real *ast.ParenExpr — i.e. whether there is a decorative paren
// immediately around THIS hole to strip. A GoText run immediately after a
// ParenWrap-shaped hole is NOT necessarily wrapping it: e.g. a `var (…)`
// group's own closing paren can immediately follow an unwrapped value with
// no relation to it at all. Only Wrapped, never Shape alone, licenses
// stripping — see StripLeadingParen/StripTrailingParen.
Wrapped bool
}
Result is one hole's classification.
func Classify ¶
Classify reports, for each hole in order, its Result within src — a syntactically-complete Go source (the caller's responsibility to complete, e.g. with a synthetic package clause) in which each gsx value has been replaced by a placeholder identifier occupying its Hole range. A hole whose position isn't found among the recognized shapes (including when src fails to parse) keeps the zero value (Shape: Plain, Wrapped: false).
Before parsing, the whitespace run immediately touching each hole is collapsed to a single space when it sits directly inside an open bracket: before the hole, when the nearest non-whitespace byte is "(", "[", or "{"; after the hole, when it is ")", "]", or "}". src is real, author-written GoText concatenated around one-rune placeholders, and on a re-parse of gsx fmt's OWN previous output (or any multi-line bare composite-literal element, with no decorative paren involved at all) a placeholder can land alone on its own line directly inside a bracket — exactly the shape that trips Go's automatic semicolon insertion right after the placeholder, breaking the parse this function depends on, regardless of whether that bracket turns out to be decorative or load-bearing call/list syntax.
This is deliberately narrower than "collapse any newline touching the hole": a hole followed by a newline that is NOT bracket-adjacent is a real statement separator (e.g. `n := HOLE` immediately followed by a new top-level statement on the next line) that Go's own automatic semicolon insertion requires to parse at all — collapsing it would break the parse this function depends on in the other direction.
type Shape ¶
type Shape int
Shape classifies a gsx value's position in the surrounding Go expression.
const ( // Plain covers a call argument, a keyless composite-literal element, an // unrecognized position, or a substituted source that failed to parse. Plain Shape = iota // ParenWrap is an assignment RHS, a return operand, or a keyed // composite-literal field's value — a "prefix: value" shape safe to // visually wrap in (...) without changing its meaning. ParenWrap )