Documentation
¶
Overview ¶
package lf stands for internal parts of "Lost Fields"
Index ¶
- func IsPossibleConverter(fn *ast.FuncDecl, pass *analysis.Pass) bool
- func PrettyPrint(w io.Writer, filename string, fn *ast.FuncDecl, pass *analysis.Pass, ...)
- func Run(pass *analysis.Pass) (any, error)
- type CollectingType
- type ContainerType
- type ConverterType
- type ConverterValidationResult
- type UsageCollector
- type UsageLookup
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func IsPossibleConverter ¶
IsPossibleConverter checks whether fn (a function declaration) qualifies as a potential converter function based on these rules:
- At least one input and one output candidate exist.
- Candidate is the argument who fits the candidate type (struct or pointer to struct).
- For at least one candidate pair (input, output) with the same container type, the names of the candidate types share a common substring (ignoring case).
TODO: it can't be the same type e.g. HandleRewrites(sectionRewrites) (string, SectionRewrite, erro)
func PrettyPrint ¶
func PrettyPrint( w io.Writer, filename string, fn *ast.FuncDecl, pass *analysis.Pass, message string, converterType string, )
PrettyPrint writes a linter message in a Rust-like style to the given writer. It extracts the source line from the file (using filename and pos.Line), shortens it to a maximum width (80 characters) while preserving the significant ranges, adjusts the caret position, and prints the formatted diagnostic. TODO: make a struct-base method (so we do not send `pass` via arg, etc)
Types ¶
type CollectingType ¶
type CollectingType int
CollectingType means which type of node we can "collect" via usageCollector.
const ( RecordUnknown CollectingType = iota RecordMethods RecordFields )
type ContainerType ¶
type ContainerType string
ContainerType represents the "container" kind for a candidate type.
const ( ContainerNone ContainerType = "none" // plain struct ContainerPointer ContainerType = "pointer" // pointer to struct ContainerSlice ContainerType = "slice" // slice or array ContainerMap ContainerType = "map" // map (using its value type) )
type ConverterType ¶
type ConverterType string
ConverterType indicates the type of converter function.
const ( ConverterTypeNormal ConverterType = "converter" ConverterTypeDelegating ConverterType = "delegating converter" ConverterTypeAggregating ConverterType = "aggregating converter" )
type ConverterValidationResult ¶
type ConverterValidationResult struct {
// Valid is true if every exported field (or getter methods) in
// both input/output models were used.
Valid bool
// ConverterType indicates what type of converter this is
ConverterType ConverterType
// MissingInputFields contains the names of exported fields in the input candidate
// that were not used.
MissingInputFields []string
// MissingOutputFields contains the names of exported fields in the output candidate
// that were not used.
MissingOutputFields []string
}
ConverterValidationResult holds the details of a converter function validation.
func NewFailedConverterValidationResult ¶
func NewFailedConverterValidationResult(in, out []string) *ConverterValidationResult
func NewOKConverterValidationResult ¶
func NewOKConverterValidationResult() *ConverterValidationResult
func ValidateConverter ¶
ValidateConverter checks that the converter function fn uses every field of the candidate input model (by reading) and every field of the candidate output model (by writing).
For input, we assume the candidate comes from the first parameter and that it has a name. For output, we first try to use a named result; if none, we look for a composite literal.
type UsageCollector ¶
type UsageCollector struct {
// contains filtered or unexported fields
}
UsageCollector is a generic AST visitor that collects selector usage for a given variable. rType(RecordingType) stands for the type of things we record: fields or methods.
func NewUsageCollector ¶
func NewUsageCollector(varName string, rType CollectingType) *UsageCollector
func (*UsageCollector) Visit ¶
func (v *UsageCollector) Visit(container ast.Node) ast.Visitor
Visit collects used items (of nodeType) in a given container node.
func (*UsageCollector) Walk ¶
func (v *UsageCollector) Walk(container ast.Node) UsageLookup
type UsageLookup ¶
type UsageLookup map[string]struct{}
UsageLookup is a map storing name of fields/methods that were used.
func CollectCompositeLitKeys ¶
func CollectCompositeLitKeys(n ast.Node, candidateName string) UsageLookup
CollectCompositeLitKeys scans for composite literals of type matching the given candidate, and returns a set of keys (field names) that appear in the literal. (We assume keys are simple identifiers; more complex cases can be added as needed.)
func CollectOutputFields ¶
func CollectOutputFields(fn *ast.FuncDecl, outVar, candidateName string) UsageLookup
CollectOutputFields inspects fn.Body looking for all field names that are "set" on the output value of the converter. It does two things:
(a) If outVar is non-empty, it collects direct field accesses on that variable.
(b) It also scans assignment and return statements to find composite literals
(or their address-of forms) whose type (or underlying type) matches candidateName,
then collects the keys (i.e. field names) provided in the literal.
CollectOutputFields inspects fn.Body and returns a set of field names that are used in constructing the output value of the converter. It does two things:
(a) If outVar is non-empty or can be determined from a local declaration, it collects direct
field accesses on that variable (e.g. out.ID = ...).
(b) It scans assignment and return statements for composite literals that initialize a value
of type candidateName (e.g. out = &Category{ Type: ... }).
func CollectUsedFields ¶
func CollectUsedFields(n ast.Node, varName string) UsageLookup
CollectUsedFields walks the AST rooted at n and returns a set (UsageLookup) of field names that are directly accessed on varName (ignoring any method calls).
func CollectUsedMethods ¶
func CollectUsedMethods(n ast.Node, varName string) UsageLookup
CollectUsedMethods walks the AST rooted at n and returns a set (UsageLookup) of method names that are called on varName.
func (UsageLookup) LookUp ¶
func (ul UsageLookup) LookUp(v string) bool