visitors

package
v0.0.0-...-f1bff1d Latest Latest
Warning

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

Go to latest
Published: Apr 29, 2024 License: Apache-2.0 Imports: 2 Imported by: 1

Documentation

Overview

This package defines a generic VisitorManager interface, which is implemented in various sub-packages, like http_rest_spec_visitor for traversing REST specs.

The go_ast subpackage is the infrastructure that implements the visitor traversal. It takes a VisitorManager and applies it to a Go data structure, calling VisitorManager.Visit on each subterm in the data structure.

See http_rest_spec_visitor/http_rest_spec_visitor_test.go for an example of using a REST spec visitor.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ArrayElementEdge

type ArrayElementEdge struct {
	ElementIndex int
}

A context-path edge indicating that an element of an array is being visited.

func NewArrayElementEdge

func NewArrayElementEdge(elementIndex int) *ArrayElementEdge

func (*ArrayElementEdge) String

func (e *ArrayElementEdge) String() string

type Cont

type Cont int

An enum to indicate how a visitor's traversal should continue.

const (
	// Indicates that the visitor should continue with normal traversal.
	Continue Cont = iota

	// Indicates that the visitor should end its traversal, but perform 'leave'
	// operations as the traversal stack is unwound back to the root node.
	Stop

	// Indicates that the visitor should stop its traversal immediately. No
	// 'leave' operations will be performed as the traversal stack is unwound
	// back to the root node.
	Abort

	// Indicates that the visitor should not visit the children of the current
	// node.
	SkipChildren
)

type Context

type Context interface {
	// Returns a new Context in which the path is appended to indicate a
	// traversal into the given field of the given struct.
	EnterStruct(structNode interface{}, fieldName string) Context

	// Returns a new Context in which the path is appended to indicate a
	// traversal into the given element of the given array.
	EnterArray(arrayNode interface{}, elementIndex int) Context

	// Returns a new Context in which the path is appended to indicate a
	// traversal into the value at the given key of the given map.
	EnterMapValue(mapNode, mapKey interface{}) Context

	// Returns the path through the structure being traversed.
	GetPath() ContextPath

	// Returns the parent context from which this context was derived. Returns
	// nil if this is the root context.
	GetOuter() Context
}

func NewContext

func NewContext() Context

type ContextPath

type ContextPath []ContextPathElement

Represents a path through a data structure.

func (ContextPath) GetLast

func (c ContextPath) GetLast() ContextPathElement

func (ContextPath) GetNthLast

func (c ContextPath) GetNthLast(n int) *ContextPathElement

Returns the `n`-th last element in the path, or nil if there is no such element.

func (ContextPath) IsEmpty

func (c ContextPath) IsEmpty() bool

type ContextPathEdge

type ContextPathEdge interface {
	String() string
	// contains filtered or unexported methods
}

Represents an edge in the path from the root node to the node being visited.

type ContextPathElement

type ContextPathElement struct {
	AncestorNode interface{}
	OutEdge      ContextPathEdge
}

Represents an ancestor node and an outgoing edge from that node.

type LeftOrRight

type LeftOrRight bool
const (
	LeftSide  LeftOrRight = true
	RightSide LeftOrRight = false
)

type MapValueEdge

type MapValueEdge struct {
	MapKey interface{}
}

A context-path edge indicating that a value of a map is being visited.

func NewMapValueEdge

func NewMapValueEdge(mapKey interface{}) *MapValueEdge

func (*MapValueEdge) String

func (e *MapValueEdge) String() string

type PairContext

type PairContext interface {
	// Returns a new PairContext in which the paths are appended to indicate a
	// traversal into the given fields of the given structs.
	EnterStructs(leftStruct interface{}, leftFieldName string, rightStruct interface{}, rightFieldName string) PairContext

	// Returns a new PairContext in which the path on one side is appended to
	// indicate a traversal into the given field of the given struct.
	EnterStruct(leftOrRight LeftOrRight, structNode interface{}, fieldName string) PairContext

	// Returns a new PairContext in which the paths are appended to indicate a
	// traversal into the given elements of the given arrays.
	EnterArrays(leftArray interface{}, leftIndex int, rightArray interface{}, rightIndex int) PairContext

	// Returns a new PairContext in which the path on one side is appended to
	// indicate a traversal into the given element of the given array.
	EnterArray(leftOrRight LeftOrRight, arrayNode interface{}, elementIndex int) PairContext

	// Returns a new PairContext in which the paths are appended to indicate a
	// traversal into the values at the given keys of the given maps.
	EnterMapValues(leftMap, leftKey, rightMap, rightKey interface{}) PairContext

	// Returns a new PairContext in which the path on one side is appended to
	// indicate a traversal into the value at the given key of the given map.
	EnterMapValue(leftOrRight LeftOrRight, mapNode, mapKey interface{}) PairContext

	// Returns the paths through the structures being traversed.
	// See Context.GetPath().
	GetPaths() (ContextPath, ContextPath)
}

func NewPairContext

func NewPairContext() PairContext

type PairVisitorManager

type PairVisitorManager interface {
	// Creates an empty context.
	Context() PairContext

	// Returns the visitor implementation.
	Visitor() interface{}

	// Provides functionality for entering a pair of nodes, before visiting the
	// nodes' children.
	EnterNodes(c PairContext, visitor interface{}, leftNode, rightNode interface{}) Cont

	// Visits the nodes' children with the given context.
	VisitChildren(c PairContext, vm PairVisitorManager, leftNode, rightNode interface{}) Cont

	// Provides functionality for leaving a pair of nodes, after visiting the
	// nodes' children.
	//
	// The given cont can be Continue, Stop, or SkipChildren, indicating the
	// state of the traversal before leaving the node. Most implementations will
	// want to return this value unchanged: for convenience, if SkipChildren is
	// returned, the visitor framework will interpret this as Continue.
	LeaveNodes(c PairContext, visitor interface{}, leftNode, rightNode interface{}, cont Cont) Cont

	ExtendContext(c PairContext, leftNode, rightNode interface{})
}

A version of VisitorManager that traverses a pair of nodes in tandem.

func NewPairVisitorManager

func NewPairVisitorManager(
	c PairContext,
	v interface{},
	enter func(c PairContext, visitor interface{}, left, right interface{}) Cont,
	visitChildren func(c PairContext, vm PairVisitorManager, left, right interface{}) Cont,
	leave func(c PairContext, visitor interface{}, left, right interface{}, cont Cont) Cont,
	extendContext func(c PairContext, left, right interface{}),
) PairVisitorManager

type StructFieldEdge

type StructFieldEdge struct {
	FieldName string
}

A context-path edge indicating that a field of a struct is being visited.

func NewStructFieldEdge

func NewStructFieldEdge(fieldName string) *StructFieldEdge

func (*StructFieldEdge) String

func (e *StructFieldEdge) String() string

type VisitorManager

type VisitorManager interface {
	Context() Context
	Visitor() interface{}

	// Provides functionality for entering a node, before visiting the node's
	// children.
	EnterNode(c Context, visitor interface{}, node interface{}) Cont

	// Visits a node's children with the given context.
	VisitChildren(c Context, vm VisitorManager, node interface{}) Cont

	// Provides functionality for leaving a node, after visiting the node's
	// children.
	//
	// The given cont can be Continue, Stop, or SkipChildren, indicating the
	// state of the traversal before leaving the node. Most implementations will
	// want to return this value unchanged: for convenience, if SkipChildren is
	// returned, the visitor framework will interpret this as Continue.
	LeaveNode(c Context, visitor interface{}, node interface{}, cont Cont) Cont

	// Augments the given context with information from the given node.
	ExtendContext(c Context, visitor interface{}, term interface{})
}

A visitor is made up of a context (which may extend the Context defined above), an arbitrary visitor object, and an Apply function that takes the context, the visitor object, and a term to visit. It returns the context passed in (possibly with modifications) as well as a value indicating how to continue the traversal.

Typically, the Apply method will use the context and the term to figure out which method of the visitor object to call, and then call it with the context and the term.

Factoring out the dispatch logic into Apply means the logic for figuring out which visitor method to call is implemented once for a given data structure, and custom visitors for that data structure can simply override the methods on the vistor object they care about. See http_rest_spec_visitor for an example.

ExtendContext creates a new context for a given term without visiting the term. This makes it possible to create the correct context for children when applying a postorder traversal.

func NewVisitorManager

func NewVisitorManager(
	c Context,
	v interface{},
	enter func(c Context, visitor interface{}, term interface{}) Cont,
	visitChildren func(c Context, vm VisitorManager, term interface{}) Cont,
	leave func(c Context, visitor interface{}, term interface{}, cont Cont) Cont,
	extendContext func(c Context, term interface{}),
) VisitorManager

Directories

Path Synopsis
Package go_ast implements a depth-first traversal of a go data structure, applying the vm to each node.
Package go_ast implements a depth-first traversal of a go data structure, applying the vm to each node.

Jump to

Keyboard shortcuts

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