engine

package
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Apr 3, 2024 License: MIT Imports: 16 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Sprint

func Sprint(x any) string

Sprint is used primarily for debugging and prints a readable representation of the provided value.

Types

type Change

type Change struct {
	Name string
	Meta *Meta

	Comments []string
	// contains filtered or unexported fields
}

Change is a single Change in a program.

func (*Change) Match

func (c *Change) Match(f *ast.File) (d data.Data, ok bool)

Match matches this change in the given Go AST and returns captured match information it a data.Data object.

func (*Change) Replace

func (c *Change) Replace(d data.Data, cl Changelog) (*ast.File, error)

Replace generates a replacement File based on previously captured match data.

type Changelog

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

Changelog records the ranges of positions changed over the course of successive patches.

func NewChangelog

func NewChangelog() Changelog

NewChangelog builds a new, empty Changelog

func (Changelog) Changed

func (c Changelog) Changed(start, end token.Pos)

Changed records the portion of code altered in this match to the Changelog.

func (Changelog) ChangedIntervals

func (c Changelog) ChangedIntervals() []Interval

ChangedIntervals returns the sum of the Intervals recorded to the Changelog.

func (Changelog) Unchanged

func (c Changelog) Unchanged(start, end token.Pos)

Unchanged records the portion of unaltered code to the Changelog.

type FileMatcher

type FileMatcher struct {
	// Matches the package name, if any.
	Package string

	// Imports in the file.
	Imports ImportsMatcher

	// Matches nodes in the file.
	NodeMatcher Matcher
}

FileMatcher matches Go files.

func (FileMatcher) Match

func (m FileMatcher) Match(file *ast.File, d data.Data) (data.Data, bool)

Match matches against the file, recording information about all matches found in it.

type FileReplacer

type FileReplacer struct {
	Fset *token.FileSet

	// Package name to change to, if any.
	Package string

	// Imports in the file.
	Imports ImportsReplacer

	// Replaces matched nodes in the file.
	NodeReplacer Replacer
}

FileReplacer replaces an ast.File.

func (FileReplacer) Replace

func (r FileReplacer) Replace(d data.Data, cl Changelog) (*ast.File, error)

Replace replaces a file using the provided Match data.

type ForDotsMatcher

type ForDotsMatcher struct {
	Dots token.Pos
	Body Matcher
}

ForDotsMatcher represents a "for ..." stmt, matching both, for and range statements.

func (ForDotsMatcher) Match

func (m ForDotsMatcher) Match(got reflect.Value, d data.Data, r Region) (data.Data, bool)

Match matches either a for statement or a range statement.

type ForDotsReplacer

type ForDotsReplacer struct {
	Dots token.Pos
	Body Replacer
	// contains filtered or unexported fields
}

ForDotsReplacer replaces a "for ...".

func (ForDotsReplacer) Replace

func (r ForDotsReplacer) Replace(d data.Data, cl Changelog, pos token.Pos) (reflect.Value, error)

Replace rebuilds a For or Range statement from the originally captured fields.

type GenericNodeMatcher

type GenericNodeMatcher struct {
	Matcher // underlying matcher
}

GenericNodeMatcher is the top-level matcher for ast.Node objects.

func (GenericNodeMatcher) Match

func (m GenericNodeMatcher) Match(got reflect.Value, d data.Data, r Region) (data.Data, bool)

Match matches an ast.Node.

type ImportMatcher

type ImportMatcher struct {
	NameS         string  // TODO: better naming
	Name          Matcher // named import, if any
	NameIsMetavar bool    // records wehther the named import was a metavariable

	Path string // import path as a string
}

ImportMatcher matches a single import.

func (ImportMatcher) Match

func (m ImportMatcher) Match(file *ast.File, d data.Data) (_ data.Data, ok bool)

Match matches an import in a file. If the matcher was built with a named import where the name is a metavariable, then this will match both, named and unnamed imports and record that information in the patch data.

type ImportReplacer

type ImportReplacer struct {
	Name          Replacer // named import, if any
	NameS         string
	NameIsMetavar bool

	Path string // import path as a string
	Fset *token.FileSet
}

ImportReplacer replaces imports in a file.

func (ImportReplacer) Replace

func (r ImportReplacer) Replace(d data.Data, cl Changelog, f *ast.File) (string, error)

Replace adds a single import. Returns the name of the import that was added.

type ImportsMatcher

type ImportsMatcher struct {
	Imports []ImportMatcher
}

ImportsMatcher matches multiple imports in a Go file.

func (ImportsMatcher) Match

func (m ImportsMatcher) Match(file *ast.File, d data.Data) (_ data.Data, ok bool)

Match matches a block of imports in a file.

type ImportsReplacer

type ImportsReplacer struct {
	Imports []ImportReplacer
	Fset    *token.FileSet
}

ImportsReplacer replaces a block of imports.

func (ImportsReplacer) Cleanup

func (r ImportsReplacer) Cleanup(d data.Data, f *ast.File, newNames []string) error

Cleanup cleans up unused imports. newNames is a list of names of imports that were added by the plus sections.

func (ImportsReplacer) Replace

func (r ImportsReplacer) Replace(d data.Data, cl Changelog, f *ast.File) ([]string, error)

Replace adds zero or more imports t a file.

Returns a list of the names of the imports that were added, if known.

type InterfaceMatcher

type InterfaceMatcher struct {
	Matcher // underlying matcher
}

InterfaceMatcher matches an interface value.

func (InterfaceMatcher) Match

func (m InterfaceMatcher) Match(got reflect.Value, d data.Data, r Region) (data.Data, bool)

Match matches non-nil interface nalues.

type InterfaceReplacer

type InterfaceReplacer struct {
	Replacer // underlying replacer

	Type reflect.Type // type of the interface
}

InterfaceReplacer replaces an interface value.

func (InterfaceReplacer) Replace

func (r InterfaceReplacer) Replace(d data.Data, cl Changelog, pos token.Pos) (reflect.Value, error)

Replace replaces an interface value.

type Interval

type Interval struct {
	Start, End token.Pos
}

Interval represents a consecutive set of positions in the source file.

type Matcher

type Matcher interface {
	// Match is called with the a value from the AST being compared with the
	// match data captured so far.
	//
	// Match reports whether the match succeeded and if so, returns the
	// original or a different Data object containing additional match data.
	Match(reflect.Value, data.Data, Region) (_ data.Data, ok bool)
}

Matcher matches values in a Go AST. It is built from the "-" portion of a patch.

type Meta

type Meta struct {
	// Variables defined in this Meta section and their types.
	Vars map[string]MetavarType
}

Meta is the compiled representaton of a Meta section.

func (*Meta) LookupVar

func (m *Meta) LookupVar(name string) MetavarType

LookupVar returns the type of the given metavariable or zero value if it wasn't found.

type MetavarMatcher

type MetavarMatcher struct {
	Fset *token.FileSet

	// Name of the metavariable.
	Name string

	// Reports whether the provided type matches the metavariable declaration.
	TypeMatches func(reflect.Type) bool
}

MetavarMatcher is compiled from a metavarible occurring in the minus section of the patch.

@@
var x expression
@@
-foo(x, x)

The first time a metavariable occurs in the patch, it matches and captures a value of the requested type. For any consecutive appearances of the metavariable, the previously captured value is expected to match.

For example, the patch above will match any expression for the first "x" and the second occurrence will require the previously captured expression to match.

func (MetavarMatcher) Match

func (m MetavarMatcher) Match(got reflect.Value, d data.Data, r Region) (data.Data, bool)

Match matches a metavariable from the patch in the AST.

type MetavarReplacer

type MetavarReplacer struct {
	Name string
}

MetavarReplacer is compiled from a metavarible occurring in the plus section of the patch.

@@
var x expression
@@
-foo(x)
+bar(x)

A metavariable cannot be referenced in the plus secton of the patch if it wasn't in the minus section. For example, the following is invalid.

@@
var x expression
@@
-foo()
+foo(x)

Each occurrence of the metavariable in the plus section of the patch is replaced with the value originally captured for it by the Matcher.

func (MetavarReplacer) Replace

func (m MetavarReplacer) Replace(d data.Data, cl Changelog, pos token.Pos) (reflect.Value, error)

Replace reproduces the value of a matched metavariable.

type MetavarType

type MetavarType int

MetavarType defines the different types of metavariables accepted in a '@@' section.

const (
	ExprMetavarType  MetavarType = iota + 1 // expression
	IdentMetavarType                        // identifier
)

Supported metavariable types.

type PosMatcher

type PosMatcher struct {
	Fset *token.FileSet

	// Pos in the patch file.
	Pos token.Pos
}

PosMatcher matches token.Pos fields in an AST.

token.Pos fields are not matched by value, but by validity. A token.Pos in the patch matches a token.Pos in the source file if they're both valid (non-zero) or they're both invalid (zero).

PosMatcher records the matched position from the source file so that it can be reproduced by the PosReplacer later.

func (PosMatcher) Match

func (m PosMatcher) Match(v reflect.Value, d data.Data, _ Region) (data.Data, bool)

Match matches a position in a file.

If the position matches and is valid, this records this match in Data for later retrieval.

type PosReplacer

type PosReplacer struct {
	Fset *token.FileSet
	Pos  token.Pos
}

PosReplacer replaces token.Pos fields.

For valid positions, the replacer will use the previously recorded position for the field, if any. This ensures that whitespace between tokens from the original file are preserved as much as possible.

func (PosReplacer) Replace

func (r PosReplacer) Replace(d data.Data, cl Changelog, pos token.Pos) (reflect.Value, error)

Replace replaces position nodes.

type Program

type Program struct {
	Changes []*Change
}

Program is a collection of compiled changes.

func Compile

func Compile(fset *token.FileSet, p *parse.Program) (*Program, error)

Compile compiles a parsed gopatch Program.

type PtrMatcher

type PtrMatcher struct {
	Matcher // underlying matcher
}

PtrMatcher matches a non-nil pointer in the AST.

func (PtrMatcher) Match

func (m PtrMatcher) Match(got reflect.Value, d data.Data, r Region) (data.Data, bool)

Match matches a non-nil pointer.

type PtrReplacer

type PtrReplacer struct {
	Replacer // underlying replacer

	Type reflect.Type // type of the pointer
}

PtrReplacer replaces a pointer type.

func (PtrReplacer) Replace

func (r PtrReplacer) Replace(d data.Data, cl Changelog, pos token.Pos) (reflect.Value, error)

Replace replaces a pointer type.

type Region

type Region struct{ Pos, End token.Pos }

Region denotes the portion of the code being matched, i.e. the start and end position of the given Node.

type Replacer

type Replacer interface {
	// Replace generates values for a Go AST provided prior match data.
	Replace(d data.Data, cl Changelog, pos token.Pos) (v reflect.Value, err error)
}

Replacer generates portions of the Go AST meant to replace sections matched by a Matcher. A Replacer is built from the "+" portion of a patch.

type SearchMatcher

type SearchMatcher struct {
	Search  Searcher
	Matcher Matcher
}

SearchMatcher runs a Matcher on descendants of an AST, producing SearchResults into Data.

The corresponding replacer applies a Replacer to these matched descendants.

func (SearchMatcher) Match

func (m SearchMatcher) Match(got reflect.Value, d data.Data, _ Region) (data.Data, bool)

Match runs the matcher on the provided ast.Node.

type SearchNode

type SearchNode interface {
	Node() ast.Node
	Parent() ast.Node
	Name() string
	Index() int
}

SearchNode provides access to an AST node, its parent, and its positional information during a traversal.

type SearchReplacer

type SearchReplacer struct {
	Replacer Replacer
}

SearchReplacer replaces nodes found by a SearchMatcher.

func (SearchReplacer) Replace

func (r SearchReplacer) Replace(d data.Data, cl Changelog, pos token.Pos) (reflect.Value, error)

Replace replaces nodes found by a SearchMatcher.

type SearchResult

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

SearchResult contains information about search results found by a SearchMatcher.

type Searcher

type Searcher func(SearchNode, Matcher, data.Data) *SearchResult

Searcher inspects the given Node using the given Matcher and returns a non-nil SearchResult if it matched.

type SliceDotsMatcher

type SliceDotsMatcher struct {

	// List of contiguous sections to match against.
	Sections [][]Matcher // inv: len > 0

	// Positions at which dots were found.
	Dots []token.Pos // inv: len(dots) = len(sections) - 1
}

SliceDotsMatcher implements support for "..." in portions of the AST where slices of values are expected.

func (SliceDotsMatcher) Match

func (m SliceDotsMatcher) Match(got reflect.Value, d data.Data, r Region) (data.Data, bool)

Match matches

type SliceDotsReplacer

type SliceDotsReplacer struct {
	Type     reflect.Type
	Sections [][]Replacer // inv: len > 0

	// Positions at which dots were found.
	Dots []token.Pos // inv: len(dots) = len(sections) - 1
	// contains filtered or unexported fields
}

SliceDotsReplacer replaces target nodes and reproduces the values captured by "..." in places which the AST expects a slice.

func (SliceDotsReplacer) Replace

func (r SliceDotsReplacer) Replace(d data.Data, cl Changelog, pos token.Pos) (reflect.Value, error)

Replace replaces target Nodes in slices where elements may have been elided in the patch.

type SliceMatcher

type SliceMatcher struct {
	// Matchers for individual fields of the slice.
	Items []Matcher
}

SliceMatcher matches a slice of values exactly.

This matcher does not support eliding values with "...".

func (SliceMatcher) Match

func (m SliceMatcher) Match(got reflect.Value, d data.Data, r Region) (data.Data, bool)

Match mathces a slice of values.

type SliceReplacer

type SliceReplacer struct {
	Type reflect.Type // type of slice

	// Replacers for individual items in the slice.
	Items []Replacer
}

SliceReplacer replaces a slice of values.

This replacer does not support generating values elided with "...".

func (SliceReplacer) Replace

func (r SliceReplacer) Replace(d data.Data, cl Changelog, pos token.Pos) (reflect.Value, error)

Replace replaces a slice.

type StructMatcher

type StructMatcher struct {
	Type reflect.Type // type of the struct

	// Matchers for individual fields of the struct.
	Fields []Matcher
}

StructMatcher matches a struct.

func (StructMatcher) Match

func (m StructMatcher) Match(got reflect.Value, d data.Data, r Region) (data.Data, bool)

Match matches a struct.

type StructReplacer

type StructReplacer struct {
	Type reflect.Type // type of the struct

	// Replacers for individual fields of the struct.
	Fields []Replacer
}

StructReplacer replaces a struct.

func (StructReplacer) Replace

func (r StructReplacer) Replace(d data.Data, cl Changelog, pos token.Pos) (reflect.Value, error)

Replace replaces a struct value.

type ValueMatcher

type ValueMatcher struct {
	Type  reflect.Type // underlying type
	Value any          // value to match
}

ValueMatcher matches a value as-is.

func (ValueMatcher) Match

func (m ValueMatcher) Match(got reflect.Value, d data.Data, _ Region) (data.Data, bool)

Match matches a value as-is.

type ValueReplacer

type ValueReplacer struct{ Value reflect.Value }

ValueReplacer replace a value as-is.

func (ValueReplacer) Replace

Replace replaces a value as-is.

type ZeroReplacer

type ZeroReplacer struct{ Type reflect.Type }

ZeroReplacer replaces with a zero value.

func (ZeroReplacer) Replace

Replace replaces with a zero value.

Jump to

Keyboard shortcuts

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