linedirective

package
v0.5.18 Latest Latest
Warning

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

Go to latest
Published: Aug 20, 2026 License: Apache-2.0 Imports: 4 Imported by: 0

Documentation

Overview

Package linedirective builds the Go //line comments that map generated template code back to the template that produced it.

A directive maps the line that follows it and keeps mapping every later line until another directive replaces it, so a mapped span has to be closed as well as opened. Closing it means naming the generated file and the physical line the reader is actually on — a number no emitter knows, because go/format has not run yet and may still move the line. Emitters therefore write Restore as a placeholder and Resolve fills the number in once the bytes are final. A placeholder occupies exactly one line and is replaced by exactly one line, so the numbering Resolve computes stays correct as it goes.

See .knowledge rule:line-directive-emission for the mechanics this encodes.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Directive

func Directive(path string, line int) string

Directive returns a directive mapping the following line to path and line.

It carries no column. A column-carrying form costs either an arithmetic compensation for the space go/format normalizes after an inline directive or an invalid column of zero at the left margin, and requirement:template-source-positions asks for path and line only.

func Finalize

func Finalize(source []byte) []byte

Finalize is the whole post-format pass over emitted directives: it pins every mapped line and fills in each restore's line number, leaving only the file name for Rename. It is what a caller runs when it knows the bytes are final and the name is not.

func IsDirective

func IsDirective(line string) bool

IsDirective reports whether line is a directive this package emitted or a hand-written one. It exists so indentation helpers can leave such a line at the left margin, where the compiler requires a // directive to start.

func Path

func Path(filename string) string

Path returns the path a directive should state for a template source: the absolute one.

The Go toolchain shortens an absolute path against the working directory before printing it, so one string reads correctly from anywhere — as store/users.tb.sql from the module root and ./users.tb.sql from inside the package — and go build and go vet agree on it. A relative path does not survive both: go build prints it verbatim, terse and unclickable from the module root, while go vet resolves it a second time against the directory of the file holding the directive and reports it doubled.

The cost is that generated bytes stop being machine independent. See requirement:template-source-positions for what that does and does not reach.

func Pin

func Pin(source []byte) []byte

Pin repeats the directive in force before every line of a mapped span, so a diagnostic reports the template line the code came from rather than that line plus the code's offset inside the span.

A directive maps the line after it exactly, the line after that as line+1, and so on. One template node emits several Go lines, so without this only the first of them is right and the rest walk forward through template lines they did not come from. A declaration mapped as a whole function walks furthest: past its neighbours and off the end of a short file.

It runs after the last formatting pass, because a line it inserts would otherwise be a line go/format could still move, and before ResolveLines, because inserting lines moves every line a restore names.

func Rename

func Rename(source []byte, file string) []byte

Rename replaces the synthetic restore file name with the name the source is actually written as. It is a no-op on source holding none, so it is safe to call on any generated output.

func Resolve

func Resolve(source []byte, file string) []byte

Resolve is Finalize followed by Rename, for a caller that already knows the name its output is written as.

func ResolveLines

func ResolveLines(source []byte) []byte

ResolveLines fills in the line number of every placeholder restore, leaving the synthetic file name in place for Rename to replace.

It must run after the last formatting pass. Running it earlier would let go/format move a line the numbers already describe.

Line and name are separate steps because they are known at different moments: the line is known as soon as the bytes are final, and the name only when whoever writes the artifact chooses it. Splitting them lets an emitter fix what it knows without guessing what it does not.

func Restore

func Restore() string

Restore returns the placeholder that ends a mapped span. Resolve replaces it with a directive naming the generated file and the line after it.

Types

This section is empty.

Jump to

Keyboard shortcuts

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