yuku-analyzer 0.5.39 → 0.5.42

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.
package/README.md CHANGED
@@ -66,6 +66,28 @@ module.resolve("name") // scope-chain lookup, like the engine does at runtime
66
66
 
67
67
  Node identity is exact: the node you reach by walking `module.ast` and the node a semantic query returns are the same JavaScript object, so `===` always works.
68
68
 
69
+ ## Editing the AST
70
+
71
+ That identity is the payoff. Because the `node` on a symbol or reference _is_ the AST node, a refactor is a plain assignment, and [`yuku-codegen`](https://www.npmjs.com/package/yuku-codegen) prints the mutated tree back to source. No visitor to register, no separate model to translate back.
72
+
73
+ ```js
74
+ import { print } from "yuku-codegen";
75
+
76
+ const m = analyzer.addFile("util.ts", `const tmp = load();\nexport const data = tmp.value + tmp.size;`);
77
+ const tmp = m.rootScope.find("tmp");
78
+ tmp.declarations[0] === m.ast.body[0].declarations[0].id; // true, literally the same node
79
+
80
+ tmp.declarations[0].name = "raw"; // rename the binding
81
+ for (const ref of tmp.references) ref.node.name = "raw"; // and every resolved use
82
+
83
+ // across files, analyzer.referencesOf(symbol) hands back these same live nodes for every use
84
+ print(m.ast).code;
85
+ // const raw = load();
86
+ // export const data = raw.value + raw.size;
87
+ ```
88
+
89
+ The uses come from resolved references, not a name search, so a shadowing inner `tmp` is left untouched: the rename only reaches the identifiers that actually bind to this symbol.
90
+
69
91
  ## Walking with semantic context
70
92
 
71
93
  `module.walk` is a typed visitor walk where every handler also receives the current scope, symbol, and reference. No manual scope tracking, ever:
package/decode.js CHANGED
@@ -619,15 +619,14 @@ function decode(buffer, source) {
619
619
  extraCount = _u32[1],
620
620
  spLen = _u32[2];
621
621
  const commentCount = _u32[4],
622
- lineStartsCount = _u32[6],
623
- diagCount = _u32[7],
624
- progIdx = _u32[8];
622
+ diagCount = _u32[6],
623
+ progIdx = _u32[7];
625
624
  const attachedCommentCount = _u32[5];
626
- const _flags = _u32[9];
625
+ const _flags = _u32[8];
627
626
  const _isTs = !!(_flags & 1);
628
627
  const _attached = !!(_flags & 2);
629
- const _firstNa = _u32[10];
630
- const _nodesOff = 44;
628
+ const _firstNa = _u32[9];
629
+ const _nodesOff = 40;
631
630
  const eOff = _nodesOff + nodeCount * 48;
632
631
  const _extraBase = eOff >> 2;
633
632
  const _spOff = eOff + extraCount * 4;
@@ -670,19 +669,20 @@ function decode(buffer, source) {
670
669
  if (s === e) return "";
671
670
  if (s >= _srcLen) return _poolDecode(s, e);
672
671
  if (e <= _firstNa) return _src.slice(s, e);
673
- const ss = s < _firstNa ? s : pm[s - _firstNa];
674
- return _src.slice(ss, pm[e - _firstNa]);
672
+ return _src.slice(s < _firstNa ? s : pm[s - _firstNa], pm[e - _firstNa]);
675
673
  };
676
674
  function nodeArr(s, len) {
677
- const r = Array.from({ length: len });
678
- for (let j = 0; j < len; j++) r[j] = node(_u32[_extraBase + s + j]);
675
+ const r = [];
676
+ const base = _extraBase + s;
677
+ for (let j = 0; j < len; j++) r.push(node(_u32[base + j]));
679
678
  return r;
680
679
  }
681
680
  function nodeArrHoles(s, len) {
682
- const r = Array.from({ length: len });
681
+ const r = [];
682
+ const base = _extraBase + s;
683
683
  for (let j = 0; j < len; j++) {
684
- const x = _u32[_extraBase + s + j];
685
- r[j] = x !== NULL ? node(x) : null;
684
+ const x = _u32[base + j];
685
+ r.push(x !== NULL ? node(x) : null);
686
686
  }
687
687
  return r;
688
688
  }
@@ -722,11 +722,11 @@ function decode(buffer, source) {
722
722
  return r;
723
723
  }
724
724
  function _decode(i) {
725
- const o = _nodesOff + i * 48;
726
- const tag = _u8[o];
727
- const flags = _u8[o + 2] | (_u8[o + 3] << 8);
728
- const f0 = _u8[o + 4] | (_u8[o + 5] << 8);
729
- const b = o >> 2;
725
+ const b = (_nodesOff + i * 48) >> 2;
726
+ const h0 = _u32[b];
727
+ const tag = h0 & 255;
728
+ const flags = h0 >>> 16;
729
+ const f0 = _u32[b + 1] & 65535;
730
730
  const f1 = _u32[b + 2], f2 = _u32[b + 3],
731
731
  f3 = _u32[b + 4], f4 = _u32[b + 5],
732
732
  f5 = _u32[b + 6], f6 = _u32[b + 7],
@@ -1164,8 +1164,7 @@ function decode(buffer, source) {
1164
1164
  const _nodesU32 = _nodesOff >> 2;
1165
1165
  function startOf(i) { return _p(_u32[_nodesU32 + i * 12 + 10]); }
1166
1166
  function endOf(i) { return _p(_u32[_nodesU32 + i * 12 + 11]); }
1167
- const lsOff = _cOff + commentCount * 20;
1168
- const dOff = lsOff + lineStartsCount * 4;
1167
+ const dOff = _cOff + commentCount * 20;
1169
1168
  function _decodeComments() {
1170
1169
  const out = Array.from({ length: commentCount });
1171
1170
  for (let j = 0; j < commentCount; j++) {
@@ -1184,20 +1183,6 @@ function decode(buffer, source) {
1184
1183
  }
1185
1184
  return out;
1186
1185
  }
1187
- function _decodeLineStarts() {
1188
- const out = Array.from({ length: lineStartsCount });
1189
- if (_firstNa >= _srcLen) {
1190
- for (let j = 0; j < lineStartsCount; j++) {
1191
- out[j] = dv.getUint32(lsOff + j * 4, true);
1192
- }
1193
- return out;
1194
- }
1195
- for (let j = 0; j < lineStartsCount; j++) {
1196
- const v = dv.getUint32(lsOff + j * 4, true);
1197
- out[j] = v < _firstNa ? v : (v >= _srcLen ? pm[pm.length - 1] : pm[v - _firstNa]);
1198
- }
1199
- return out;
1200
- }
1201
1186
  function _decodeDiagnostics() {
1202
1187
  const out = Array.from({ length: diagCount });
1203
1188
  let dp = dOff;
@@ -1359,11 +1344,7 @@ function decode(buffer, source) {
1359
1344
  nodeScope: (i) => nodeScopes[i],
1360
1345
  });
1361
1346
  }
1362
- let _program, _lineStarts, _diagnostics, _comments;
1363
- function _getLineStarts() {
1364
- if (_lineStarts === undefined) _lineStarts = _decodeLineStarts();
1365
- return _lineStarts;
1366
- }
1347
+ let _program, _diagnostics, _comments;
1367
1348
  return {
1368
1349
  get program() {
1369
1350
  return _program !== undefined ? _program : (_program = node(progIdx));
@@ -1378,16 +1359,6 @@ function decode(buffer, source) {
1378
1359
  ? _diagnostics
1379
1360
  : (_diagnostics = _decodeDiagnostics());
1380
1361
  },
1381
- get lineStarts() { return _getLineStarts(); },
1382
- locOf(offset) {
1383
- const ls = _getLineStarts();
1384
- let lo = 0, hi = ls.length;
1385
- while (lo < hi) {
1386
- const mid = (lo + hi) >>> 1;
1387
- if (ls[mid] <= offset) lo = mid + 1; else hi = mid;
1388
- }
1389
- return { line: lo, column: offset - ls[lo - 1] };
1390
- },
1391
1362
  nodeOf: node,
1392
1363
  indexOf: (n) => _nodeIndexes.get(n),
1393
1364
  parentIndex: (i) => _parents()[i],
package/index.d.ts CHANGED
@@ -13,7 +13,6 @@ import type {
13
13
  NodeType,
14
14
  Program,
15
15
  SourceLang,
16
- SourceLocation,
17
16
  SourceType,
18
17
  WalkContext as BaseWalkContext,
19
18
  } from "@yuku-toolchain/types";
@@ -364,10 +363,6 @@ interface Module {
364
363
  readonly diagnostics: Diagnostic[];
365
364
  /** Every comment in source order. */
366
365
  readonly comments: Comment[];
367
- /** Sorted offsets where each line begins. */
368
- readonly lineStarts: number[];
369
- /** Resolves an offset to a `(line, column)` pair. */
370
- locOf(offset: number): SourceLocation;
371
366
 
372
367
  /** Every lexical scope; index is the scope id. `scopes[0]` is global. */
373
368
  readonly scopes: Scope[];
package/module.js CHANGED
@@ -256,12 +256,6 @@ export class Module {
256
256
  get comments() {
257
257
  return this.#r.comments;
258
258
  }
259
- get lineStarts() {
260
- return this.#r.lineStarts;
261
- }
262
- locOf(offset) {
263
- return this.#r.locOf(offset);
264
- }
265
259
 
266
260
  get scopes() {
267
261
  return (this.#scopes ??= this.#rows(Scope, this.#sem.scope.count));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yuku-analyzer",
3
- "version": "0.5.39",
3
+ "version": "0.5.42",
4
4
  "description": "Full JavaScript and TypeScript semantic analysis: scopes, symbols, resolved references, closures, and cross-file module linking, computed natively in Zig and queried as plain JavaScript objects",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -21,17 +21,17 @@
21
21
  "decode.js"
22
22
  ],
23
23
  "optionalDependencies": {
24
- "@yuku-analyzer/binding-linux-x64-gnu": "0.5.39",
25
- "@yuku-analyzer/binding-linux-arm64-gnu": "0.5.39",
26
- "@yuku-analyzer/binding-linux-arm-gnu": "0.5.39",
27
- "@yuku-analyzer/binding-linux-x64-musl": "0.5.39",
28
- "@yuku-analyzer/binding-linux-arm64-musl": "0.5.39",
29
- "@yuku-analyzer/binding-linux-arm-musl": "0.5.39",
30
- "@yuku-analyzer/binding-darwin-x64": "0.5.39",
31
- "@yuku-analyzer/binding-darwin-arm64": "0.5.39",
32
- "@yuku-analyzer/binding-win32-x64": "0.5.39",
33
- "@yuku-analyzer/binding-win32-arm64": "0.5.39",
34
- "@yuku-analyzer/binding-freebsd-x64": "0.5.39"
24
+ "@yuku-analyzer/binding-linux-x64-gnu": "0.5.42",
25
+ "@yuku-analyzer/binding-linux-arm64-gnu": "0.5.42",
26
+ "@yuku-analyzer/binding-linux-arm-gnu": "0.5.42",
27
+ "@yuku-analyzer/binding-linux-x64-musl": "0.5.42",
28
+ "@yuku-analyzer/binding-linux-arm64-musl": "0.5.42",
29
+ "@yuku-analyzer/binding-linux-arm-musl": "0.5.42",
30
+ "@yuku-analyzer/binding-darwin-x64": "0.5.42",
31
+ "@yuku-analyzer/binding-darwin-arm64": "0.5.42",
32
+ "@yuku-analyzer/binding-win32-x64": "0.5.42",
33
+ "@yuku-analyzer/binding-win32-arm64": "0.5.42",
34
+ "@yuku-analyzer/binding-freebsd-x64": "0.5.42"
35
35
  },
36
36
  "keywords": [
37
37
  "analyzer",
@@ -49,6 +49,6 @@
49
49
  "typescript"
50
50
  ],
51
51
  "dependencies": {
52
- "@yuku-toolchain/types": "0.5.37"
52
+ "@yuku-toolchain/types": "0.5.41"
53
53
  }
54
54
  }