Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit fedb9c8

Browse files
perf(lexer): improve efficiency
Signed-off-by: Lexus Drumgold <unicornware@flexdevelopment.llc>
1 parent b64cb0d commit fedb9c8

File tree

21 files changed

+952
-540
lines changed

21 files changed

+952
-540
lines changed

‎.dprint.jsonc‎

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"!**/typings/**/dist/",
77
"**/*.patch",
88
"**/*.snap",
9+
"**/*.ts.txt",
910
"**/*config.*.timestamp*",
1011
"**/.temp/",
1112
"**/.vercel/",
@@ -81,9 +82,9 @@
8182
},
8283
"newLineKind": "lf",
8384
"plugins": [
84-
"https://plugins.dprint.dev/typescript-0.88.10.wasm",
85-
"https://plugins.dprint.dev/json-0.19.1.wasm",
86-
"https://plugins.dprint.dev/markdown-0.16.3.wasm",
85+
"https://plugins.dprint.dev/typescript-0.90.5.wasm",
86+
"https://plugins.dprint.dev/json-0.19.2.wasm",
87+
"https://plugins.dprint.dev/markdown-0.17.0.wasm",
8788
"https://plugins.dprint.dev/exec-0.4.4.json@c207bf9b9a4ee1f0ecb75c594f774924baf62e8e53a2ce9d873816a408cecbf7"
8889
],
8990
"typescript": {
@@ -98,7 +99,7 @@
9899
"constructorType.spaceAfterNewKeyword": true,
99100
"doWhileStatement.spaceAfterWhileKeyword": true,
100101
"enumDeclaration.memberSpacing": "maintain",
101-
"exportDeclaration.forceMultiLine": false,
102+
"exportDeclaration.forceMultiLine": "never",
102103
"exportDeclaration.forceSingleLine": false,
103104
"exportDeclaration.sortNamedExports": "maintain",
104105
"exportDeclaration.spaceSurroundingNamedExports": true,
@@ -113,7 +114,7 @@
113114
"ifStatement.spaceAfterIfKeyword": true,
114115
"ignoreFileCommentText": "dprint-ignore-file",
115116
"ignoreNodeCommentText": "dprint-ignore",
116-
"importDeclaration.forceMultiLine": false,
117+
"importDeclaration.forceMultiLine": "never",
117118
"importDeclaration.forceSingleLine": false,
118119
"importDeclaration.sortNamedImports": "maintain",
119120
"importDeclaration.spaceSurroundingNamedImports": true,

‎.eslintignore‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
**/node_modules/
1717
**/tsconfig*temp.json
1818
Brewfile
19+
__fixtures__/visit.ts.txt
1920
yarn.lock
2021

2122
# NEGATED PATTERNS

‎.github/infrastructure.yml‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ branches:
4141
- context: test (18)
4242
- context: test (19)
4343
- context: test (20)
44-
- context: typescript (5.3.3)
4544
- context: typescript (5.4.3)
4645
- context: typescript (latest)
4746
strict: true

‎.github/workflows/ci.yml‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,6 @@ jobs:
245245
matrix:
246246
typescript-version:
247247
- ${{ needs.preflight.outputs.version-typescript }}
248-
- 5.3.3
249248
- latest
250249
steps:
251250
- id: checkout

‎.vscode/settings.json‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,6 @@
111111
"emmet.triggerExpansionOnTab": true,
112112
"eslint.enable": true,
113113
"eslint.lintTask.enable": true,
114-
"eslint.nodePath": "node_modules/.bin/eslint",
115114
"eslint.options": {
116115
"extensions": [
117116
"css",
@@ -137,6 +136,7 @@
137136
"overrideConfigFile": ".eslintrc.cjs"
138137
},
139138
"eslint.runtime": "node",
139+
"eslint.trace.server": "messages",
140140
"eslint.validate": [
141141
"css",
142142
"github-actions-workflow",
@@ -154,6 +154,7 @@
154154
"files.associations": {
155155
"*.log": "log",
156156
"*.snap": "jest-snapshot",
157+
"*.ts.txt": "assemblyscript",
157158
".env.zsh": "shellscript",
158159
".markdownlintignore": "ignore",
159160
".npmrc": "ini",
@@ -287,6 +288,11 @@
287288
"format": "svg",
288289
"icon": "testts"
289290
},
291+
{
292+
"extensions": ["ts.txt"],
293+
"format": "svg",
294+
"icon": "typescript"
295+
},
290296
{
291297
"extensions": ["yarnrc.yml"],
292298
"format": "svg",

‎__fixtures__/visit.ts.txt‎

Lines changed: 299 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,299 @@
1+
/**
2+
* @file visit
3+
* @module unist-util-visit/visit
4+
*/
5+
6+
import {
7+
define,
8+
isArray,
9+
isBoolean,
10+
isFalsy,
11+
isFunction,
12+
isNIL,
13+
isNumber,
14+
sift,
15+
type EmptyArray,
16+
type Fn,
17+
type Nullable,
18+
type Optional
19+
} from '@flex-development/tutils'
20+
import type { Index, Test } from '@flex-development/unist-util-types'
21+
import color from '@flex-development/unist-util-visit/color'
22+
import type { Node, Parent } from 'unist'
23+
import { convert, type Check } from 'unist-util-is'
24+
import { CONTINUE, EXIT, SKIP } from './actions'
25+
import type { ActionTuple, Visitor, VisitorResult, Visitors } from './types'
26+
import { nodelike, nodename, parentlike } from './utils'
27+
28+
/**
29+
* Visit nodes, with ancestral information.
30+
*
31+
* This algorithm performs [*depth-first tree traversal*][dft] in
32+
* [*preorder*][preorder] (**NLR**) and/or [*postorder*][postorder] (**LRN**),
33+
* or if `reverse` is given, *reverse preorder* (**NRL**) and/or *reverse
34+
* postorder* (**RLN**). Nodes are handled on [*enter*][enter] during *preorder*
35+
* traversals and on [*exit*][exit] during *postorder* traversals.
36+
*
37+
* Walking the `tree` is an intensive task. Make use of `visitor` return values
38+
* whenever possible. Instead of walking `tree` multiple times, walk it once,
39+
* use [`unist-util-is`][unist-util-is] to check if a node matches, and then
40+
* perform different operations.
41+
*
42+
* You can change `tree`. See {@linkcode Visitor} for more info.
43+
*
44+
* [dft]: https://github.com/syntax-tree/unist#depth-first-traversal
45+
* [enter]: https://github.com/syntax-tree/unist#enter
46+
* [exit]: https://github.com/syntax-tree/unist#exit
47+
* [postorder]: https://github.com/syntax-tree/unist#postorder
48+
* [preorder]: https://github.com/syntax-tree/unist#preorder
49+
* [unist-util-is]: https://github.com/syntax-tree/unist-util-is
50+
*
51+
* @see {@linkcode Node}
52+
* @see {@linkcode Visitors}
53+
*
54+
* @template {Node} [Tree=Node] - Tree to traverse
55+
*
56+
* @param {Tree} tree - Tree to traverse
57+
* @param {Visitor<Tree> | Visitors<Tree>} visitor - A function to handle nodes
58+
* when entering (*preorder*), or an object to handle nodes when entering and
59+
* leaving (*preorder* and *postorder*)
60+
* @param {(boolean | null)?} [reverse] - Traverse in reverse preorder (NRL)
61+
* and/or postorder (RLN) instead of default traversal order(s)
62+
* @return {void} Nothing
63+
*/
64+
function visit<Tree extends Node = Node>(
65+
this: void,
66+
tree: Tree,
67+
visitor: Visitor<Tree> | Visitors<Tree>,
68+
reverse?: boolean | null | undefined
69+
): void
70+
71+
/**
72+
* Visit nodes, with ancestral information.
73+
*
74+
* This algorithm performs [*depth-first tree traversal*][dft] in
75+
* [*preorder*][preorder] (**NLR**) and/or [*postorder*][postorder] (**LRN**),
76+
* or if `reverse` is given, *reverse preorder* (**NRL**) and/or *reverse
77+
* postorder* (**RLN**). Nodes are handled on [*enter*][enter] during *preorder*
78+
* traversals and on [*exit*][exit] during *postorder* traversals.
79+
*
80+
* You can choose which nodes visitor functions handle by passing a
81+
* [`test`][test]. For complex tests, you should test yourself in `visitor`
82+
* instead, as it will be faster and also have improved type information.
83+
*
84+
* Walking the `tree` is an intensive task. Make use of visitor return values
85+
* whenever possible. Instead of walking the `tree` multiple times, walk it
86+
* once, use [`unist-util-is`][unist-util-is] to check if a node matches, and
87+
* then perform different operations.
88+
*
89+
* You can change `tree`. See {@linkcode Visitor} for more info.
90+
*
91+
* [dft]: https://github.com/syntax-tree/unist#depth-first-traversal
92+
* [enter]: https://github.com/syntax-tree/unist#enter
93+
* [exit]: https://github.com/syntax-tree/unist#exit
94+
* [postorder]: https://github.com/syntax-tree/unist#postorder
95+
* [preorder]: https://github.com/syntax-tree/unist#preorder
96+
* [test]: https://github.com/syntax-tree/unist-util-is#test
97+
* [unist-util-is]: https://github.com/syntax-tree/unist-util-is
98+
*
99+
* @see {@linkcode Node}
100+
* @see {@linkcode Test}
101+
* @see {@linkcode Visitors}
102+
*
103+
* @template {Node} [Tree=Node] - Tree to traverse
104+
* @template {Test} [Check=Test] - Visited node test
105+
*
106+
* @param {Tree} tree - Tree to traverse
107+
* @param {Check} test - [`unist-util-is`][unist-util-is]-compatible test
108+
* @param {Visitor<Tree, Check> | Visitors<Tree, Check>} visitor - A function to
109+
* handle nodes passing `test` when entering (*preorder*), or an object to
110+
* handle passing nodes when entering and leaving (*preorder* and *postorder*)
111+
* @param {(boolean | null)?} [reverse] - Traverse in reverse preorder (NRL)
112+
* and/or postorder (RLN) instead of default traversal order(s)
113+
* @return {void} Nothing
114+
*/
115+
function visit<Tree extends Node = Node, Check extends Test = Test>(
116+
this: void,
117+
tree: Tree,
118+
test: Check,
119+
visitor: Visitor<Tree, Check> | Visitors<Tree, Check>,
120+
reverse?: boolean | null
121+
): void
122+
123+
/**
124+
* Visit nodes, with ancestral information.
125+
*
126+
* @see {@linkcode Node}
127+
* @see {@linkcode Test}
128+
* @see {@linkcode Visitor}
129+
* @see {@linkcode Visitors}
130+
*
131+
* @param {Node} tree - Tree to traverse
132+
* @param {Test | Visitor | Visitors} test - Visited node test or `visitor`
133+
* @param {(Visitor | Visitors | boolean | null)?} [visitor] - A function to
134+
* handle entering nodes, an object containing functions to handle entering and
135+
* leaving nodes, or `reverse`
136+
* @param {(boolean | null)?} [reverse] - Traverse in reverse order
137+
* @return {void} Nothing
138+
*/
139+
function visit(
140+
tree: Node,
141+
test: Test | Visitor | Visitors,
142+
visitor?: Visitor | Visitors | boolean | null,
143+
reverse?: boolean | null
144+
): void {
145+
if (isBoolean(visitor) || isNIL(visitor)) {
146+
reverse = visitor
147+
visitor = test
148+
if (isFunction(visitor)) visitor = { enter: visitor }
149+
test = null
150+
} else {
151+
if (isFunction(visitor)) visitor = { enter: visitor }
152+
test = <Test>test
153+
}
154+
155+
/**
156+
* Node checker.
157+
*
158+
* @const {Check} check
159+
*/
160+
const check: Check = convert(<Test>test)
161+
162+
/**
163+
* Default value used to move between child nodes.
164+
*
165+
* @const {number} step
166+
*/
167+
const step: number = reverse ? -1 : 1
168+
169+
/**
170+
* Convert a visitor `result` to an {@linkcode ActionTuple}.
171+
*
172+
* @this {void}
173+
*
174+
* @param {VisitorResult} result - Result returned from visitor function
175+
* @return {ActionTuple} Visitor result as action tuple
176+
*/
177+
function cleanResult(this: void, result: VisitorResult): ActionTuple {
178+
switch (true) {
179+
case isArray(result):
180+
return result
181+
case isNIL(result):
182+
return []
183+
case isNumber(result):
184+
return [CONTINUE, result]
185+
default:
186+
return [result]
187+
}
188+
}
189+
190+
/**
191+
* Build a function to visit a node.
192+
*
193+
* @see {@linkcode ActionTuple}
194+
* @see {@linkcode Index}
195+
* @see {@linkcode Node}
196+
* @see {@linkcode Parent}
197+
*
198+
* @this {void}
199+
*
200+
* @param {Node} node - Found node
201+
* @param {Optional<Index>} index - Index of `node` in `parent.children`
202+
* @param {Optional<Parent>} parent - Parent of `node`
203+
* @param {Parent[]} ancestors - Ancestors of node
204+
* @return {Fn<EmptyArray, Readonly<ActionTuple>>} Visitor function
205+
*/
206+
function factory(
207+
this: void,
208+
node: Node,
209+
index: Optional<Index>,
210+
parent: Optional<Parent>,
211+
ancestors: Parent[]
212+
): Fn<EmptyArray, Readonly<ActionTuple>> {
213+
if (nodelike(node)) {
214+
/**
215+
* Node name.
216+
*
217+
* @const {Nullable<string>} name
218+
*/
219+
const name: Nullable<string> = nodename(node)
220+
221+
// set name of factory visit function to display name for node
222+
define(visit, 'name', {
223+
value: `node(${color(`${node.type}${name ? `<${name}>` : ''}`)})`
224+
})
225+
}
226+
227+
return visit
228+
229+
/**
230+
* Visit `node`.
231+
*
232+
* @see {@linkcode ActionTuple}
233+
*
234+
* @return {Readonly<ActionTuple>} Clean visitor result
235+
*/
236+
function visit(): Readonly<ActionTuple> {
237+
const { enter, leave } = <Visitors>visitor
238+
239+
/**
240+
* Index of current child node.
241+
*
242+
* @var {number} offset
243+
*/
244+
let offset: number = 0
245+
246+
/**
247+
* Clean visitor result.
248+
*
249+
* @var {Readonly<ActionTuple>} result
250+
*/
251+
let result: Readonly<ActionTuple> = cleanResult(null)
252+
253+
// visit node on enter
254+
if (isFalsy(test) || check(node, index, parent)) {
255+
result = cleanResult(enter?.(node, index, parent, ancestors))
256+
if (result[0] === EXIT) return result
257+
}
258+
259+
// visit each child in node.children
260+
if (parentlike(node) && result[0] !== SKIP) {
261+
offset = (reverse ? node.children.length : -1) + step
262+
while (offset > -1 && offset < node.children.length) {
263+
/**
264+
* Child node.
265+
*
266+
* @const {Node} child
267+
*/
268+
const child: Node = node.children[offset]
269+
270+
/**
271+
* Clean visitor result for {@linkcode child}.
272+
*
273+
* @const {Readonly<ActionTuple>} subresult
274+
*/
275+
const subresult: Readonly<ActionTuple> = factory(
276+
child,
277+
offset,
278+
node,
279+
sift([...ancestors, parent])
280+
)()
281+
282+
if (subresult[0] === EXIT) return subresult
283+
offset = isNumber(subresult[1]) ? subresult[1] : offset + step
284+
}
285+
}
286+
287+
// visit node on leave
288+
if (leave && (isFalsy(test) || check(node, index, parent))) {
289+
result = cleanResult(leave(node, index, parent, ancestors))
290+
}
291+
292+
return result
293+
}
294+
}
295+
296+
return void factory(tree, undefined, undefined, [])()
297+
}
298+
299+
export default visit

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /