-
-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor to move implementation to
lib/
- Loading branch information
Showing
7 changed files
with
182 additions
and
117 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
.DS_Store | ||
index.d.ts | ||
lib/index.d.ts | ||
test.d.ts | ||
*.log | ||
coverage/ | ||
|
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,54 +1,2 @@ | ||
import type {Node, Parent} from 'unist' | ||
import type {Test} from 'unist-util-is' | ||
import type { | ||
VisitorResult, | ||
Matches, | ||
InclusiveDescendant | ||
} from 'unist-util-visit-parents/complex-types.js' | ||
|
||
/** | ||
* Called when a node (matching test, if given) is found. | ||
* Visitors are free to transform node. | ||
* They can also transform the parent of node (the last of ancestors). | ||
* Replacing node itself, if `SKIP` is not returned, still causes its descendants to be visited. | ||
* If adding or removing previous siblings (or next siblings, in case of reverse) of node, | ||
* visitor should return a new index (number) to specify the sibling to traverse after node is traversed. | ||
* Adding or removing next siblings of node (or previous siblings, in case of reverse) | ||
* is handled as expected without needing to return a new index. | ||
* Removing the children property of an ancestor still results in them being traversed. | ||
*/ | ||
export type Visitor< | ||
Visited extends Node = Node, | ||
Ancestor extends Parent = Parent | ||
> = ( | ||
node: Visited, | ||
index: Visited extends Node ? number | null : never, | ||
parent: Ancestor extends Node ? Ancestor | null : Ancestor | ||
) => VisitorResult | ||
|
||
type ParentsOf< | ||
Ancestor extends Node, | ||
Child extends Node | ||
> = Ancestor extends Parent | ||
? Child extends Ancestor['children'][number] | ||
? Ancestor | ||
: never | ||
: never | ||
|
||
type BuildVisitorFromMatch< | ||
Visited extends Node, | ||
Ancestor extends Parent | ||
> = Visitor<Visited, ParentsOf<Ancestor, Visited>> | ||
|
||
type BuildVisitorFromDescendants< | ||
Descendant extends Node, | ||
Check extends Test | ||
> = BuildVisitorFromMatch< | ||
Matches<Descendant, Check>, | ||
Extract<Descendant, Parent> | ||
> | ||
|
||
export type BuildVisitor< | ||
Tree extends Node = Node, | ||
Check extends Test = string | ||
> = BuildVisitorFromDescendants<InclusiveDescendant<Tree>, Check> | ||
// To do: next major: remove this file. | ||
export type {Visitor, BuildVisitor} from './index.js' |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
export type {Test} from 'unist-util-is' | ||
export type { | ||
Action, | ||
ActionTuple, | ||
Index, | ||
VisitorResult | ||
} from 'unist-util-visit-parents' | ||
export {CONTINUE, EXIT, SKIP} from 'unist-util-visit-parents' | ||
export type {Visitor, BuildVisitor} from './lib/index.js' | ||
export {visit} from './lib/index.js' |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,61 +1,3 @@ | ||
/** | ||
* @typedef {import('unist').Node} Node | ||
* @typedef {import('unist').Parent} Parent | ||
* @typedef {import('unist-util-is').Test} Test | ||
* @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult | ||
* @typedef {import('./complex-types.js').Visitor} Visitor | ||
*/ | ||
|
||
import {visitParents} from 'unist-util-visit-parents' | ||
|
||
/** | ||
* Visit children of tree which pass test. | ||
* | ||
* @param tree | ||
* Tree to walk | ||
* @param [test] | ||
* `unist-util-is`-compatible test | ||
* @param visitor | ||
* Function called for nodes that pass `test`. | ||
* @param reverse | ||
* Traverse in reverse preorder (NRL) instead of preorder (NLR) (default). | ||
*/ | ||
export const visit = | ||
/** | ||
* @type {( | ||
* (<Tree extends Node, Check extends Test>(tree: Tree, test: Check, visitor: import('./complex-types.js').BuildVisitor<Tree, Check>, reverse?: boolean) => void) & | ||
* (<Tree extends Node>(tree: Tree, visitor: import('./complex-types.js').BuildVisitor<Tree>, reverse?: boolean) => void) | ||
* )} | ||
*/ | ||
( | ||
/** | ||
* @param {Node} tree | ||
* @param {Test} test | ||
* @param {import('./complex-types.js').Visitor} visitor | ||
* @param {boolean} [reverse] | ||
*/ | ||
function (tree, test, visitor, reverse) { | ||
if (typeof test === 'function' && typeof visitor !== 'function') { | ||
reverse = visitor | ||
visitor = test | ||
test = null | ||
} | ||
|
||
visitParents(tree, test, overload, reverse) | ||
|
||
/** | ||
* @param {Node} node | ||
* @param {Array<Parent>} parents | ||
*/ | ||
function overload(node, parents) { | ||
const parent = parents[parents.length - 1] | ||
return visitor( | ||
node, | ||
parent ? parent.children.indexOf(node) : null, | ||
parent | ||
) | ||
} | ||
} | ||
) | ||
|
||
// Note: types exported from `index.d.ts` | ||
export {CONTINUE, EXIT, SKIP} from 'unist-util-visit-parents' | ||
export {visit} from './lib/index.js' |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
/** | ||
* @typedef {import('unist').Node} Node | ||
* @typedef {import('unist').Parent} Parent | ||
* @typedef {import('unist-util-is').Test} Test | ||
* @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult | ||
*/ | ||
|
||
/** | ||
* Check if `Child` can be a child of `Ancestor`. | ||
* | ||
* Returns the ancestor when `Child` can be a child of `Ancestor`, or returns | ||
* `never`. | ||
* | ||
* @template {Node} Ancestor | ||
* Node type. | ||
* @template {Node} Child | ||
* Node type. | ||
* @typedef {( | ||
* Ancestor extends Parent | ||
* ? Child extends Ancestor['children'][number] | ||
* ? Ancestor | ||
* : never | ||
* : never | ||
* )} ParentsOf | ||
*/ | ||
|
||
/** | ||
* @template {Node} [Visited=Node] | ||
* Visited node type. | ||
* @template {Parent} [Ancestor=Parent] | ||
* Ancestor type. | ||
* @callback Visitor | ||
* Handle a node (matching `test`, if given). | ||
* | ||
* Visitors are free to transform `node`. | ||
* They can also transform `parent`. | ||
* | ||
* Replacing `node` itself, if `SKIP` is not returned, still causes its | ||
* descendants to be walked (which is a bug). | ||
* | ||
* When adding or removing previous siblings of `node` (or next siblings, in | ||
* case of reverse), the `Visitor` should return a new `Index` to specify the | ||
* sibling to traverse after `node` is traversed. | ||
* Adding or removing next siblings of `node` (or previous siblings, in case | ||
* of reverse) is handled as expected without needing to return a new `Index`. | ||
* | ||
* Removing the children property of `parent` still results in them being | ||
* traversed. | ||
* @param {Visited} node | ||
* Found node. | ||
* @param {Visited extends Node ? number | null : never} index | ||
* Index of `node` in `parent`. | ||
* @param {Ancestor extends Node ? Ancestor | null : never} parent | ||
* Parent of `node`. | ||
* @returns {VisitorResult} | ||
* What to do next. | ||
* | ||
* An `Index` is treated as a tuple of `[CONTINUE, Index]`. | ||
* An `Action` is treated as a tuple of `[Action]`. | ||
* | ||
* Passing a tuple back only makes sense if the `Action` is `SKIP`. | ||
* When the `Action` is `EXIT`, that action can be returned. | ||
* When the `Action` is `CONTINUE`, `Index` can be returned. | ||
*/ | ||
|
||
/** | ||
* Build a typed `Visitor` function from a node and all possible parents. | ||
* | ||
* It will infer which values are passed as `node` and which as `parent`. | ||
* | ||
* @template {Node} Visited | ||
* Node type. | ||
* @template {Parent} Ancestor | ||
* Parent type. | ||
* @typedef {Visitor<Visited, ParentsOf<Ancestor, Visited>>} BuildVisitorFromMatch | ||
*/ | ||
|
||
/** | ||
* Build a typed `Visitor` function from a list of descendants and a test. | ||
* | ||
* It will infer which values are passed as `node` and which as `parent`. | ||
* | ||
* @template {Node} Descendant | ||
* Node type. | ||
* @template {Test} Check | ||
* Test type. | ||
* @typedef {( | ||
* BuildVisitorFromMatch< | ||
* import('unist-util-visit-parents/complex-types.js').Matches<Descendant, Check>, | ||
* Extract<Descendant, Parent> | ||
* > | ||
* )} BuildVisitorFromDescendants | ||
*/ | ||
|
||
/** | ||
* Build a typed `Visitor` function from a tree and a test. | ||
* | ||
* It will infer which values are passed as `node` and which as `parent`. | ||
* | ||
* @template {Node} [Tree=Node] | ||
* Node type. | ||
* @template {Test} [Check=string] | ||
* Test type. | ||
* @typedef {( | ||
* BuildVisitorFromDescendants< | ||
* import('unist-util-visit-parents/complex-types.js').InclusiveDescendant<Tree>, | ||
* Check | ||
* > | ||
* )} BuildVisitor | ||
*/ | ||
|
||
import {visitParents} from 'unist-util-visit-parents' | ||
|
||
/** | ||
* Visit children of tree which pass test. | ||
* | ||
* @param tree | ||
* Tree to walk | ||
* @param [test] | ||
* `unist-util-is`-compatible test | ||
* @param visitor | ||
* Function called for nodes that pass `test`. | ||
* @param reverse | ||
* Traverse in reverse preorder (NRL) instead of preorder (NLR) (default). | ||
*/ | ||
export const visit = | ||
/** | ||
* @type {( | ||
* (<Tree extends Node, Check extends Test>(tree: Tree, test: Check, visitor: BuildVisitor<Tree, Check>, reverse?: boolean) => void) & | ||
* (<Tree extends Node>(tree: Tree, visitor: BuildVisitor<Tree>, reverse?: boolean) => void) | ||
* )} | ||
*/ | ||
( | ||
/** | ||
* @param {Node} tree | ||
* @param {Test} test | ||
* @param {Visitor} visitor | ||
* @param {boolean} [reverse] | ||
*/ | ||
function (tree, test, visitor, reverse) { | ||
if (typeof test === 'function' && typeof visitor !== 'function') { | ||
reverse = visitor | ||
visitor = test | ||
test = null | ||
} | ||
|
||
visitParents(tree, test, overload, reverse) | ||
|
||
/** | ||
* @param {Node} node | ||
* @param {Array<Parent>} parents | ||
*/ | ||
function overload(node, parents) { | ||
const parent = parents[parents.length - 1] | ||
return visitor( | ||
node, | ||
parent ? parent.children.indexOf(node) : null, | ||
parent | ||
) | ||
} | ||
} | ||
) | ||
|
||
export {CONTINUE, EXIT, SKIP} from 'unist-util-visit-parents' |
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
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