lf

package
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Oct 31, 2025 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

package lf stands for internal parts of "Lost Fields"

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsPossibleConverter

func IsPossibleConverter(fn *ast.FuncDecl, pass *analysis.Pass) bool

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)

func Run

func Run(pass *analysis.Pass) (any, error)

Run function used in analysis.Analyzer.

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

func ValidateConverter(fn *ast.FuncDecl, pass *analysis.Pass) (*ConverterValidationResult, error)

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

Jump to

Keyboard shortcuts

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