Repository navigation
javascript: call-graph engine for the JavaScript front end (tracking) #456
Description
Activity
- addedengineResolution / call-graph engine rulesResolution / call-graph engine rulesenhancementNew feature or requestNew feature or requestjavascriptJavaScriptJavaScript
on Sep 13, 2026 swapnilpaliwal-sd commented
on Sep 14, 2026 ContributorAuthorMore actionsEdge-case sweep (2026-09-13), synthetic programs scored against both the compiler and execution oracles — nine probe projects covering value flow, classes, async/callbacks, CommonJS and ES module forms, JSDoc, heritage, precision traps and class fields. Two WRONG edges found (#479 superclass by last-segment name, #481 call through a getter); the rest are misses with a known mechanism:
- javascript: class field initializers are never read —
dep = new Service(),static shared = …,#priv = …hold nothing #480 class field initializers never read - javascript: a call through a getter resolves to the accessor itself (WRONG), a getter's return is never the property's value, and a setter's parameter receives nothing #481 getters/setters: accessor as callee (WRONG), getter return, setter parameter
- javascript:
class A extends ns.Baseis linked to an unrelated import by its last segment (a WRONG superclass), and EXTENDS_CLAUSE rows carry no expression link #479 / javascript: a superclass that is a parameter, a call (mixin), a conditional, or a qualified name the parser did not link is unresolved — resolveextendsthrough the expression's value #482 heritage: parser link by simple name (WRONG) + no expression link; mixins, parameter and qualified superclasses - javascript: ES re-exports other than
export *yield nothing —export { a as b } from,export { default } from,export * as ns from#483 ES re-exports other thanexport * - javascript: anonymous
export default classresolves to nothing (the class residue of parser#176) #484 anonymousexport default class - javascript: promise values are opaque —
Promise.resolve,new Promise,.thencontinuations,Promise.all/race,Promise<T>#485 promise values - javascript: a generator's yielded values never reach
for..of, spread,.next().value,yield*,for await#486 generators - javascript: destructuring patterns carry no property path or rest flag — renamed, nested and rest bindings resolve to nothing #487 destructuring paths and rest (parser)
- javascript: JSDoc
@this,Map<K,V>/Set<T>/Promise<T>generics and inline/** @type */ (x)casts are emitted by the parser and not read #488 JSDoc@this, non-Array generics, casts - javascript: members installed through a property descriptor are invisible —
Object.defineProperty,defineProperties,Object.create(proto, descriptors), and the OBJECT_DEFINE_PROPERTY export form #489 property descriptors incl. theOBJECT_DEFINE_PROPERTYexport form - javascript: five callee spellings with a known value still end unresolved —
arr[0](),(0, f)(), numeric and template keys,new F()returning an object #490arr[0](),(0, f)(), numeric/template keys,new F()returning an object - javascript: small platform models —
Object.freeze,Reflect.construct,new Map(entries),forEach(fn, thisArg), emitter-handlerthis,Array.from,Object.values,Symbol.iterator#491 small platform models
Module resolution (
requireof a directory,index.js,package.json#main,.jsextension, JSON, circular requires,module.exports = require(),exports.a = exports.b =, conditional exports, spread of a required module) scored 47/50 EXACT with the three misses in the list above.- javascript: class field initializers are never read —
swapnilpaliwal-sd commented
on Sep 14, 2026 ContributorAuthorMore actionsThe engine is on
main(21864ff, #472, task #577): 19/19 suite, development 0.985 exact / 0.998 recall / WRONG 0 over 9,867 compiler-decided sites, held-out 0.938 / 0.989 / 0.999 over 9,649, torture 0.982 and real-app 0.980 against execution. What is deliberately not resolved stays listed in #465; the CI gate (#418) and the engine build (#478) are being extended to cover JavaScript and land after the C# engine.
JavaScript front end — tracking
A call-graph engine for JavaScript over the parser's
js_*IR, on the long-livedjavascript-enginebranch. Nothing merges tomainuntil the engine is code-complete and evaluated on both a development and a held-out corpus; every mechanism lands on the branch through its own issue.Shape of the engine
JavaScript declares no types, so the engine is a may-analysis over values rather than a type lookup: every expression, binding, parameter, property and return carries the set of values it may hold — a function, a class, an instance, a prototype, a module surface, an object literal, an array, or the platform — and a call site resolves through the callee's value. An untyped receiver produces nothing: the site is a declared unknown, never a name match.
Ground truth
checker.getResolvedSignaturefrom ats.Programbuilt withallowJs+checkJsover the project's own files, per site, positions exact on both sides. Sites the compiler types asany(about half) enter no rate.Layers
this, returns, properties, member writesextendsin all its spellings, nearest-declaration member lookup, constructor targets@param/@type/@returns,import()types, typedef aliasespush, index writes,map, callbacks,for..of--library)Status (draft PR #466)
Development: exact 0.988, recall 0.996, WRONG 0 over 9,867 sites. Held-out: exact 0.942, recall 0.984, precision 0.999 over 9,649 sites; the gap is width on one project, not misses. Every project solves in ≤ 9 s after #467.
Acceptance for merge to main