-
-
Notifications
You must be signed in to change notification settings - Fork 106
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add visit(node, visitor) to 'yaml' #225
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Okay, fine, I gave it more features. Looked at a number of different AST visitor implementations, ended up taking quite a bit of inspiration from GraphQL, as well as elsewhere. Here's the new API: /**
* Apply a visitor to an AST node or document.
*
* Walks through the tree (depth-first) starting from `node`, calling a
* `visitor` function with three arguments:
* - `key`: For sequence values and map `Pair`, the node's index in the
* collection. Within a `Pair`, `'key'` or `'value'`, correspondingly.
* `null` for the root node.
* - `node`: The current node.
* - `path`: The ancestry of the current node.
*
* The return value of the visitor may be used to control the traversal:
* - `undefined` (default): Do nothing and continue
* - `visit.SKIP`: Do not visit the children of this node, continue with next
* sibling
* - `visit.BREAK`: Terminate traversal completely
* - `visit.REMOVE`: Remove the current node, then continue with the next one
* - `Node`: Replace the current node, then continue by visiting it
* - `number`: While iterating the items of a sequence or map, set the index
* of the next step. This is useful especially if the index of the current
* node has changed.
*
* If `visitor` is a single function, it will be called with all values
* encountered in the tree, including e.g. `null` values. Alternatively,
* separate visitor functions may be defined for each `Map`, `Pair`, `Seq`,
* `Alias` and `Scalar` node.
*/
export declare const visit: visit
export type visitor<T> = (
key: number | 'key' | 'value' | null,
node: T,
path: Node[]
) => void | symbol | number | Node
export interface visit {
(
node: Node | Document,
visitor:
| visitor<any>
| {
Alias?: visitor<Alias>
Map?: visitor<YAMLMap>
Pair?: visitor<Pair>
Scalar?: visitor<Scalar>
Seq?: visitor<YAMLSeq>
}
): void
/** Terminate visit traversal completely */
BREAK: symbol
/** Remove the current node */
REMOVE: symbol
/** Do not visit the children of the current node */
SKIP: symbol
} |
eemeli
changed the title
Add visit(node, visitor) to 'yaml/util'
Add visit(node, visitor) to 'yaml'
Jan 31, 2021
On further thought, it doesn't make sense to hide this behind |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Closes #190, so ping at least @amadare42 and @privatenumber.
This adds the following new export to
'yaml/util'
:To start with, this is pretty minimal and just walks the tree. In other words, it does not provide the node's current path, it does not provide control methods for early exits from the walk, and it does not do anything with the value returned from a visitor function.
I'm quite open to developing this API further, but I'd like to see example use cases or other arguments for more complex features.
EDIT: See next comment for updated API.