yuku-parser 0.5.20 → 0.5.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +11 -0
  2. package/decode.js +5 -25
  3. package/package.json +12 -12
package/README.md CHANGED
@@ -71,6 +71,16 @@ const { line, column } = result.locOf(result.program.body[0].start);
71
71
 
72
72
  Lines are 1-based and columns are 0-based, matching ESTree's `loc` convention. The lookup is an O(log n) binary search: tens of nanoseconds per call, safe to invoke per node during a walk.
73
73
 
74
+ When resolving many offsets in roughly source order, `locNear` is faster: it scans from a hint line instead of binary searching. Pass the previously returned `line` as the next `hintLine` so each lookup starts near the answer.
75
+
76
+ ```ts
77
+ let hintLine = 1;
78
+ for (const node of nodesInSourceOrder) {
79
+ const { line, column } = result.locNear(node.start, hintLine);
80
+ hintLine = line;
81
+ }
82
+ ```
83
+
74
84
  ## Walking the AST
75
85
 
76
86
  [`yuku-ast`](https://www.npmjs.com/package/yuku-ast) is the companion toolkit built for this AST: a typed walker, node builders (`b`), type guards (`is`), and identifier validators.
@@ -131,6 +141,7 @@ interface ParseResult {
131
141
  diagnostics: Diagnostic[];
132
142
  lineStarts: number[];
133
143
  locOf(offset: number): { line: number; column: number };
144
+ locNear(offset: number, hintLine: number): { line: number; column: number };
134
145
  }
135
146
  ```
136
147
 
package/decode.js CHANGED
@@ -1,6 +1,4 @@
1
1
  // generated by tools/gen_estree_decoder.zig, do not edit
2
- // `_u32` is an Int32Array so NodeIndex NULL reads as -1 and fits in
3
- // an SMI/int32, avoiding heap-number boxing on every field read in JSC.
4
2
  const NULL = -1;
5
3
  const _td = new TextDecoder("utf-8", { ignoreBOM: true });
6
4
  const BINARY_OPS = ["==", "!=", "===", "!==", "<", "<=", ">", ">=", "+", "-", "*", "/", "%", "**", "|", "^", "&", "<<", ">>", ">>>", "in", "instanceof"];
@@ -21,11 +19,6 @@ const TS_METHOD_SIGNATURE_KINDS = ["method", "get", "set"];
21
19
  const TS_MODULE_KINDS = ["namespace", "module"];
22
20
  const TS_MAPPED_OPTIONAL = [false, true, "+", "-"];
23
21
  const TS_MAPPED_READONLY = [null, true, "+", "-"];
24
- // builds a partial pos-map covering bytes [startByte, byteLen]. for any
25
- // byte position v >= startByte, m[v - startByte] is the corresponding
26
- // UTF-16 code-unit index into `src`. positions below startByte are an
27
- // identity map (byte position == UTF-16 position because the prefix is
28
- // pure ASCII), so the caller checks `v < startByte` and returns v directly.
29
22
  function buildPosMap(src, byteLen, startByte) {
30
23
  const m = new Uint32Array(byteLen - startByte + 1);
31
24
  const len = src.length;
@@ -80,8 +73,6 @@ function decode(buffer, source) {
80
73
  const eOff = _nodesOff + nodeCount * 48;
81
74
  const _extraBase = eOff >> 2;
82
75
  const _spOff = eOff + extraCount * 4;
83
- // sections after the variable-length string pool may be at any
84
- // byte alignment, so reads against them use `dv`, not `_u32`.
85
76
  const dv = new DataView(buffer);
86
77
  const _aoOff = _spOff + spLen;
87
78
  const _acOff = _attached ? _aoOff + (nodeCount + 1) * 4 : _aoOff;
@@ -115,22 +106,12 @@ function decode(buffer, source) {
115
106
  }
116
107
  return r;
117
108
  }
118
- // `_p` and `str` translate UTF-8 byte offsets into JS UTF-16 indices.
119
- // for any offset below `_firstNa` (the prefix of the source that is pure
120
- // ASCII) the mapping is the identity, so we short-circuit and skip
121
- // building a pos-map. when offsets cross into non-ASCII territory we
122
- // lazily build a pos-map for `[_firstNa, _srcLen]` on first use.
123
- let pm = null;
124
- const _p = v => {
125
- if (v < _firstNa) return v;
126
- if (pm === null) pm = buildPosMap(_src, _srcLen, _firstNa);
127
- return pm[v - _firstNa];
128
- };
109
+ const pm = _firstNa < _srcLen ? buildPosMap(_src, _srcLen, _firstNa) : null;
110
+ const _p = v => v <= _firstNa ? v : pm[v - _firstNa];
129
111
  const str = (s, e) => {
130
112
  if (s === e) return "";
131
113
  if (s >= _srcLen) return _poolDecode(s, e);
132
114
  if (e <= _firstNa) return _src.slice(s, e);
133
- if (pm === null) pm = buildPosMap(_src, _srcLen, _firstNa);
134
115
  const ss = s < _firstNa ? s : pm[s - _firstNa];
135
116
  return _src.slice(ss, pm[e - _firstNa]);
136
117
  };
@@ -175,8 +156,6 @@ function decode(buffer, source) {
175
156
  }
176
157
  function nodeWithComments(i) {
177
158
  const r = _decode(i);
178
- // skip unwrap cases whose inner node already carries its own
179
- // comments (e.g. formal_parameter returning its pattern)
180
159
  if (r && r.type !== undefined && r.comments === undefined) {
181
160
  const off = _aoOff + i * 4;
182
161
  const a = dv.getUint32(off, true), e = dv.getUint32(off + 4, true);
@@ -194,7 +173,9 @@ function decode(buffer, source) {
194
173
  f3 = _u32[b + 4], f4 = _u32[b + 5],
195
174
  f5 = _u32[b + 6], f6 = _u32[b + 7],
196
175
  f7 = _u32[b + 8], f8 = _u32[b + 9];
197
- const start = _p(_u32[b + 10]), end = _p(_u32[b + 11]);
176
+ const _ss = _u32[b + 10], _se = _u32[b + 11];
177
+ const start = _ss <= _firstNa ? _ss : pm[_ss - _firstNa];
178
+ const end = _se <= _firstNa ? _se : pm[_se - _firstNa];
198
179
  switch (tag) {
199
180
  case 0: return { type: "SequenceExpression", start, end, expressions: nodeArr(f1, f0) };
200
181
  case 1: return { type: "ParenthesizedExpression", start, end, expression: f1 !== NULL ? node(f1) : null };
@@ -640,7 +621,6 @@ function decode(buffer, source) {
640
621
  }
641
622
  return out;
642
623
  }
643
- if (pm === null) pm = buildPosMap(_src, _srcLen, _firstNa);
644
624
  for (let j = 0; j < lineStartsCount; j++) {
645
625
  const v = dv.getUint32(lsOff + j * 4, true);
646
626
  out[j] = v < _firstNa ? v : (v >= _srcLen ? pm[pm.length - 1] : pm[v - _firstNa]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yuku-parser",
3
- "version": "0.5.20",
3
+ "version": "0.5.24",
4
4
  "description": "High-performance JavaScript/TypeScript parser",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -17,17 +17,17 @@
17
17
  "decode.js"
18
18
  ],
19
19
  "optionalDependencies": {
20
- "@yuku-parser/binding-linux-x64-gnu": "0.5.20",
21
- "@yuku-parser/binding-linux-arm64-gnu": "0.5.20",
22
- "@yuku-parser/binding-linux-arm-gnu": "0.5.20",
23
- "@yuku-parser/binding-linux-x64-musl": "0.5.20",
24
- "@yuku-parser/binding-linux-arm64-musl": "0.5.20",
25
- "@yuku-parser/binding-linux-arm-musl": "0.5.20",
26
- "@yuku-parser/binding-darwin-x64": "0.5.20",
27
- "@yuku-parser/binding-darwin-arm64": "0.5.20",
28
- "@yuku-parser/binding-win32-x64": "0.5.20",
29
- "@yuku-parser/binding-win32-arm64": "0.5.20",
30
- "@yuku-parser/binding-freebsd-x64": "0.5.20"
20
+ "@yuku-parser/binding-linux-x64-gnu": "0.5.24",
21
+ "@yuku-parser/binding-linux-arm64-gnu": "0.5.24",
22
+ "@yuku-parser/binding-linux-arm-gnu": "0.5.24",
23
+ "@yuku-parser/binding-linux-x64-musl": "0.5.24",
24
+ "@yuku-parser/binding-linux-arm64-musl": "0.5.24",
25
+ "@yuku-parser/binding-linux-arm-musl": "0.5.24",
26
+ "@yuku-parser/binding-darwin-x64": "0.5.24",
27
+ "@yuku-parser/binding-darwin-arm64": "0.5.24",
28
+ "@yuku-parser/binding-win32-x64": "0.5.24",
29
+ "@yuku-parser/binding-win32-arm64": "0.5.24",
30
+ "@yuku-parser/binding-freebsd-x64": "0.5.24"
31
31
  },
32
32
  "keywords": [
33
33
  "acorn",