Replaces the R1 seed .scm emitter with a bespoke Rust walker (codegraph-kernel/src/tsjs/) that mirrors TreeSitterExtractor's TS/JS paths function-for-function: declarations (incl. #808 field/property classification), qualified names, docstrings (#780 wrapper climbs), signatures, imports/re-exports + per-binding refs, calls with receiver-qualified callees (#1230 literal-receiver skip), instantiations, decorators, inheritance, type annotations (#381), type-alias members + tuple contracts (#359/#634), React component recognition (#841 forwardRef/memo/styled), object-of-functions / zustand-through-middleware / RTK Query endpoints + generated hooks / vuex + pinia store shapes, function-as-value capture with the flush gate (#756), and value-reference edges with the shadow prune (#895/#897). The generic query emitter is deleted — extraction parity needs logic .scm can't express; future languages get walkers too (migration plan §4a). Positions and JS string-slice semantics are emitted in UTF-16 code units natively, so kernel output is byte-identical to web-tree-sitter's — no column diff class exists. Parity evidence (macOS): scripts/kernel-parity.mjs (full-object multiset diff per file) — this repo 353/353 files, excalidraw 643/643 (10,650 nodes / 10,726 edges / 68,307 refs), plus torture fixtures checked into __tests__/fixtures/kernel-parity/ and enforced in npm test by kernel-tsjs-parity.test.ts. The strict compare caught one real decoder bug the loose harness missed: refs must NOT carry denormalized filePath/language at the extractFromSource seam (the store fills them). Perf: extraction 2.6× single-thread on excalidraw (487ms vs 1,255ms, identical outputs). Routing stays opt-in (CODEGRAPH_KERNEL_LANGS) until the R3 equivalence gate (large repo, DB dump-diff, retrieval invariants, agent A/B, Linux/Windows) passes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
76 lines
1.4 KiB
JavaScript
76 lines
1.4 KiB
JavaScript
/**
|
|
* JS-grammar torture fixture (javascript variant: no type machinery, JS class
|
|
* fields use `field_definition` with a `property` field).
|
|
*/
|
|
import { EventEmitter } from 'node:events';
|
|
const { promisify } = require('node:util');
|
|
|
|
/** Legacy prototype-style helper. */
|
|
function legacyHelper(a, b) {
|
|
return a + b;
|
|
}
|
|
|
|
const arrow = (x) => legacyHelper(x, 1);
|
|
|
|
class Widget extends EventEmitter {
|
|
static registry = new Map();
|
|
#privateField = 1;
|
|
label = 'w';
|
|
onTick = () => {
|
|
this.render();
|
|
};
|
|
wrapped = debounce(function () {
|
|
expensive();
|
|
}, 50);
|
|
|
|
constructor(opts) {
|
|
super();
|
|
this.opts = opts;
|
|
register(this.onTick);
|
|
}
|
|
|
|
render() {
|
|
paint(this.label);
|
|
}
|
|
|
|
static create(opts) {
|
|
return new Widget(opts);
|
|
}
|
|
}
|
|
|
|
// AMD-style wrapper — anonymous, but inner functions must still surface.
|
|
(function () {
|
|
function hiddenInner() {
|
|
return 7;
|
|
}
|
|
hiddenInner();
|
|
})();
|
|
|
|
module.exports.makeWidget = function makeWidget(opts) {
|
|
return Widget.create(opts);
|
|
};
|
|
|
|
// Vuex module shape (store-file signals: mutations + actions + getters).
|
|
const mutations = {
|
|
SET_USER(state, user) {
|
|
state.user = user;
|
|
},
|
|
};
|
|
const actions = {
|
|
async loadUser({ commit }, id) {
|
|
const user = await fetchUser(id);
|
|
commit('SET_USER', user);
|
|
},
|
|
};
|
|
export default {
|
|
namespaced: true,
|
|
state: () => ({ user: null }),
|
|
mutations,
|
|
actions,
|
|
getters: {
|
|
userName(state) {
|
|
return state.user?.name;
|
|
},
|
|
},
|
|
};
|