@llui/compiler 0.5.1 → 0.5.3
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/dist/accessor-resolver.d.ts +9 -1
- package/dist/accessor-resolver.d.ts.map +1 -1
- package/dist/accessor-resolver.js +68 -9
- package/dist/accessor-resolver.js.map +1 -1
- package/dist/collect-deps.d.ts +5 -1
- package/dist/collect-deps.d.ts.map +1 -1
- package/dist/collect-deps.js +117 -14
- package/dist/collect-deps.js.map +1 -1
- package/dist/cross-file-walker.d.ts +4 -1
- package/dist/cross-file-walker.d.ts.map +1 -1
- package/dist/cross-file-walker.js +72 -9
- package/dist/cross-file-walker.js.map +1 -1
- package/dist/lint-modules.d.ts.map +1 -1
- package/dist/lint-modules.js +2 -0
- package/dist/lint-modules.js.map +1 -1
- package/dist/module.d.ts +12 -1
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +2 -1
- package/dist/module.js.map +1 -1
- package/dist/modules/bitmask-overflow.js +1 -1
- package/dist/modules/bitmask-overflow.js.map +1 -1
- package/dist/modules/core-synthesis.d.ts +7 -0
- package/dist/modules/core-synthesis.d.ts.map +1 -1
- package/dist/modules/core-synthesis.js +24 -12
- package/dist/modules/core-synthesis.js.map +1 -1
- package/dist/modules/opaque-state-flow.d.ts +3 -0
- package/dist/modules/opaque-state-flow.d.ts.map +1 -0
- package/dist/modules/opaque-state-flow.js +240 -0
- package/dist/modules/opaque-state-flow.js.map +1 -0
- package/dist/transform.d.ts +1 -1
- package/dist/transform.d.ts.map +1 -1
- package/dist/transform.js +84 -6
- package/dist/transform.js.map +1 -1
- package/package.json +1 -1
|
@@ -418,6 +418,7 @@ export function toCanonicalDiagnostic(d, sourceText, projectRoot) {
|
|
|
418
418
|
export function crossFileAccessorPaths(program, focalFile) {
|
|
419
419
|
const checker = program.getTypeChecker();
|
|
420
420
|
const paths = new Set();
|
|
421
|
+
const opaqueOut = { value: false };
|
|
421
422
|
const visitedHelpers = new Set();
|
|
422
423
|
const isViewHelperCallArg0 = (arrow) => {
|
|
423
424
|
const parent = arrow.parent;
|
|
@@ -436,14 +437,14 @@ export function crossFileAccessorPaths(program, focalFile) {
|
|
|
436
437
|
const p0 = node.parameters[0];
|
|
437
438
|
if (ts.isIdentifier(p0.name) && node.body) {
|
|
438
439
|
if (isReactiveAccessor(node) || isViewHelperCallArg0(node)) {
|
|
439
|
-
walkAccessorBody(node.body, p0.name.text, paths, checker, visitedHelpers);
|
|
440
|
+
walkAccessorBody(node.body, p0.name.text, paths, checker, visitedHelpers, opaqueOut);
|
|
440
441
|
}
|
|
441
442
|
}
|
|
442
443
|
}
|
|
443
444
|
ts.forEachChild(node, visit);
|
|
444
445
|
};
|
|
445
446
|
visit(focalFile);
|
|
446
|
-
return paths;
|
|
447
|
+
return { paths, opaque: opaqueOut.value };
|
|
447
448
|
}
|
|
448
449
|
// Helpers whose arrow args are NOT state accessors — same exclusion list
|
|
449
450
|
// the file-local walker uses (collect-deps.ts § NON_DELEGATION_HELPERS).
|
|
@@ -452,7 +453,7 @@ export function crossFileAccessorPaths(program, focalFile) {
|
|
|
452
453
|
// `unsafeHtml` already have their inline arrow walked by the top-level
|
|
453
454
|
// visitor — we'd double-count if we recursed through the call again.
|
|
454
455
|
const NON_DELEGATION_CALLEES = new Set(['sample', 'item', 'memo', 'text', 'unsafeHtml']);
|
|
455
|
-
function walkAccessorBody(body, paramName, paths, checker, visitedHelpers) {
|
|
456
|
+
function walkAccessorBody(body, paramName, paths, checker, visitedHelpers, opaqueOut) {
|
|
456
457
|
const visit = (node) => {
|
|
457
458
|
// Property-chain extraction (mirrors collect-deps' depth-2 normaliser).
|
|
458
459
|
if (ts.isPropertyAccessExpression(node)) {
|
|
@@ -460,6 +461,43 @@ function walkAccessorBody(body, paramName, paths, checker, visitedHelpers) {
|
|
|
460
461
|
if (chain)
|
|
461
462
|
paths.add(chain);
|
|
462
463
|
}
|
|
464
|
+
// Opaque-state-flow classifier (mirrors the per-binding mask
|
|
465
|
+
// classifier in transform.ts:computeAccessorMask). Any standalone
|
|
466
|
+
// appearance of the param identifier in a non-tracked container
|
|
467
|
+
// means the helper reads through an expression we can't trace, so
|
|
468
|
+
// a precise prefix table is insufficient — the host needs a
|
|
469
|
+
// whole-state sentinel in `__prefixes`.
|
|
470
|
+
if (ts.isIdentifier(node) && node.text === paramName) {
|
|
471
|
+
const parent = node.parent;
|
|
472
|
+
const isBinding = !!parent && ts.isParameter(parent);
|
|
473
|
+
if (!isBinding) {
|
|
474
|
+
let isTracked = false;
|
|
475
|
+
if (parent) {
|
|
476
|
+
if (ts.isPropertyAccessExpression(parent) && parent.expression === node) {
|
|
477
|
+
isTracked = true;
|
|
478
|
+
}
|
|
479
|
+
else if (ts.isElementAccessExpression(parent) && parent.expression === node) {
|
|
480
|
+
isTracked =
|
|
481
|
+
ts.isStringLiteralLike(parent.argumentExpression) ||
|
|
482
|
+
ts.isNumericLiteral(parent.argumentExpression);
|
|
483
|
+
}
|
|
484
|
+
else if (ts.isCallExpression(parent) &&
|
|
485
|
+
ts.isIdentifier(parent.expression) &&
|
|
486
|
+
parent.arguments[0] === node &&
|
|
487
|
+
!NON_DELEGATION_CALLEES.has(parent.expression.text)) {
|
|
488
|
+
// Identifier-callee delegations are handled by the
|
|
489
|
+
// descend-into-helper branch below — if the callee
|
|
490
|
+
// resolves, recursion finds opaque inside; if not, the
|
|
491
|
+
// call's `sym` is undefined and the host sees no descent.
|
|
492
|
+
// Treat as tracked here so this branch alone doesn't flip
|
|
493
|
+
// opaque on every well-formed `helper(s)`.
|
|
494
|
+
isTracked = true;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
if (!isTracked)
|
|
498
|
+
opaqueOut.value = true;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
463
501
|
if (ts.isCallExpression(node)) {
|
|
464
502
|
const callee = node.expression;
|
|
465
503
|
const sym = resolveAliasedSymbol(callee, checker);
|
|
@@ -471,7 +509,7 @@ function walkAccessorBody(body, paramName, paths, checker, visitedHelpers) {
|
|
|
471
509
|
// into our state, identifier args pass our state through).
|
|
472
510
|
visitedHelpers.add(decl);
|
|
473
511
|
descendIntoHelper(decl, node, paramName, paths, checker, visitedHelpers,
|
|
474
|
-
/*viewHelper*/ true);
|
|
512
|
+
/*viewHelper*/ true, opaqueOut);
|
|
475
513
|
}
|
|
476
514
|
else if (decl && !visitedHelpers.has(decl)) {
|
|
477
515
|
// Non-view-helper: only follow if our state param is passed
|
|
@@ -490,10 +528,35 @@ function walkAccessorBody(body, paramName, paths, checker, visitedHelpers) {
|
|
|
490
528
|
!NON_DELEGATION_CALLEES.has(callee.text) &&
|
|
491
529
|
callPassesParamIdent(node, paramName)) {
|
|
492
530
|
visitedHelpers.add(decl);
|
|
493
|
-
|
|
494
|
-
|
|
531
|
+
const fnDecl = decl;
|
|
532
|
+
if (fnDecl.body) {
|
|
533
|
+
descendIntoHelper(decl, node, paramName, paths, checker, visitedHelpers,
|
|
534
|
+
/*viewHelper*/ false, opaqueOut);
|
|
535
|
+
}
|
|
536
|
+
else {
|
|
537
|
+
// Declaration without a body — ambient `declare function`,
|
|
538
|
+
// overload signature, or compiled .d.ts. State flows in
|
|
539
|
+
// but we can't see what it reads. Conservative: opaque.
|
|
540
|
+
opaqueOut.value = true;
|
|
541
|
+
}
|
|
495
542
|
}
|
|
496
543
|
}
|
|
544
|
+
else if (!decl && ts.isIdentifier(callee) && !NON_DELEGATION_CALLEES.has(callee.text)) {
|
|
545
|
+
// Callee resolved to a symbol but no function-like
|
|
546
|
+
// declaration (e.g., ambient declaration, type-only import,
|
|
547
|
+
// or a binding whose initializer the checker can't pin
|
|
548
|
+
// down). If state flows in, treat as opaque — same
|
|
549
|
+
// conservative read as the file-local classifier.
|
|
550
|
+
if (callPassesParamIdent(node, paramName))
|
|
551
|
+
opaqueOut.value = true;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
else if (ts.isIdentifier(callee) && !NON_DELEGATION_CALLEES.has(callee.text)) {
|
|
555
|
+
// Callee identifier didn't resolve to ANY symbol (declared
|
|
556
|
+
// outside the program, lost through transient binding, etc.).
|
|
557
|
+
// The standalone `s` classifier above already flagged the arg
|
|
558
|
+
// as opaque, so no additional bookkeeping is needed here; the
|
|
559
|
+
// branch is kept to mirror the file-local handling shape.
|
|
497
560
|
}
|
|
498
561
|
}
|
|
499
562
|
ts.forEachChild(node, visit);
|
|
@@ -507,7 +570,7 @@ function callPassesParamIdent(call, paramName) {
|
|
|
507
570
|
}
|
|
508
571
|
return false;
|
|
509
572
|
}
|
|
510
|
-
function descendIntoHelper(decl, callSite, outerParamName, paths, checker, visitedHelpers, viewHelper) {
|
|
573
|
+
function descendIntoHelper(decl, callSite, outerParamName, paths, checker, visitedHelpers, viewHelper, opaqueOut) {
|
|
511
574
|
// Match each parameter to its argument at the call site.
|
|
512
575
|
//
|
|
513
576
|
// For §2.1 view-helpers: arrow-arg accessors like `(t) => t.foo` are
|
|
@@ -533,11 +596,11 @@ function descendIntoHelper(decl, callSite, outerParamName, paths, checker, visit
|
|
|
533
596
|
if (viewHelper && (ts.isArrowFunction(arg) || ts.isFunctionExpression(arg))) {
|
|
534
597
|
const a0 = arg.parameters[0];
|
|
535
598
|
if (a0 && ts.isIdentifier(a0.name) && arg.body) {
|
|
536
|
-
walkAccessorBody(arg.body, a0.name.text, paths, checker, visitedHelpers);
|
|
599
|
+
walkAccessorBody(arg.body, a0.name.text, paths, checker, visitedHelpers, opaqueOut);
|
|
537
600
|
}
|
|
538
601
|
}
|
|
539
602
|
else if (ts.isIdentifier(arg) && arg.text === outerParamName) {
|
|
540
|
-
walkAccessorBody(fnDecl.body, param.name.text, paths, checker, visitedHelpers);
|
|
603
|
+
walkAccessorBody(fnDecl.body, param.name.text, paths, checker, visitedHelpers, opaqueOut);
|
|
541
604
|
}
|
|
542
605
|
}
|
|
543
606
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cross-file-walker.js","sourceRoot":"","sources":["../src/cross-file-walker.ts"],"names":[],"mappings":"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","sourcesContent":["// Cross-file walker — v2b prototype (Phase 1).\n//\n// Classifies every call expression in a TypeScript Program against the\n// §2.1 view-helper resolution rule. Returns diagnostics + a per-callsite\n// classification trace.\n//\n// This is *prototype-grade*: no manifest consumption, no incremental cache,\n// no reverse-deps tracking. Phase 3 adds those layers on top.\n//\n// The rule (§2.1):\n// A call is a view-helper iff at least one of:\n// case 1 — the callee accepts a parameter assignable to View<S,M> or\n// one of the documented structural subsets (send-only,\n// text-only, send+text, send+show+each+branch).\n// case 2 — the callee's *declared* return type is assignable to\n// Node, Node[], Node|undefined, or ReadonlyArray<Node>.\n// case 3 — the callee has a `/** @llui-helper */` JSDoc tag.\n//\n// Async helpers (declared return Promise<Node[]>) are NOT view-helpers\n// and produce `llui/async-view-helper` (hard error).\n//\n// Everything else: opaque. Emits `llui/opaque-view-call` if the call site\n// is structurally a view position (its result flows into a view-returning\n// expression); otherwise the call is uninteresting and not reported.\n\nimport ts from 'typescript'\nimport {\n type Diagnostic,\n type DiagnosticCategory,\n type DiagnosticSeverity,\n rangeFromOffsets,\n relativizeFile,\n} from './diagnostic.js'\nimport { isReactiveAccessor } from './collect-deps.js'\n\nexport type ViewHelperKind = 'walked' | 'opaque' | 'async' | 'not-a-helper'\n\nexport interface ViewHelperClassification {\n kind: ViewHelperKind\n /** Which §2.1 case fired. Only populated when kind === 'walked'. */\n cases: Array<1 | 2 | 3>\n /** Human-readable reason. */\n reason: string\n}\n\nexport type DiagnosticId = 'llui/opaque-view-call' | 'llui/async-view-helper' | 'llui/helper-cycle'\n\nexport interface WalkerDiagnostic {\n id: DiagnosticId\n file: string\n pos: number\n end: number\n message: string\n helperName: string | undefined\n}\n\nexport interface WalkerResult {\n diagnostics: WalkerDiagnostic[]\n /** Per-file counts for telemetry. */\n perFile: Map<\n string,\n {\n callsClassified: number\n walked: number\n opaque: number\n async: number\n notAHelper: number\n }\n >\n}\n\n/**\n * Classify the symbol's declaration against the §2.1 rule.\n *\n * Operates on the *declared* type (`getTypeOfSymbolAtLocation(symbol,\n * symbol.declarations[0])`), not the inferred-at-call-site type. This is\n * load-bearing: TypeScript inference at call sites widens to union\n * shapes (`Node[] | undefined`, `JSX.Element | string`) that miss\n * assignability for case 2. The rule's intent is \"did the author commit\n * to a view-helper signature in the declaration\" — inference-narrowed\n * types don't satisfy that intent.\n */\nexport function classifyViewHelper(\n symbol: ts.Symbol,\n checker: ts.TypeChecker,\n): ViewHelperClassification {\n const decls = symbol.getDeclarations() ?? []\n const decl = decls.find(isCallableDeclaration)\n if (!decl) return { kind: 'not-a-helper', cases: [], reason: 'no callable declaration found' }\n\n const cases: Array<1 | 2 | 3> = []\n const reasons: string[] = []\n\n // Case 3: @llui-helper JSDoc tag. Cheap to check, decisive when present.\n if (hasLluiHelperTag(decl)) {\n cases.push(3)\n reasons.push('@llui-helper tag')\n }\n\n // Get the signature's parameters + return type from the *declaration*.\n const declType = checker.getTypeOfSymbolAtLocation(symbol, decl)\n const sigs = declType.getCallSignatures()\n if (sigs.length === 0) {\n if (cases.includes(3)) {\n return { kind: 'walked', cases, reason: reasons.join('; ') }\n }\n return { kind: 'not-a-helper', cases: [], reason: 'declared type has no call signature' }\n }\n // Use the first signature. Overloaded helpers are rare in view code;\n // production walker should iterate all.\n const sig = sigs[0]!\n\n // Case 2: declared return type assignable to Node / Node[] / etc.\n const returnType = checker.getReturnTypeOfSignature(sig)\n const asyncMatch = returnTypeIsAsyncNode(returnType, checker)\n if (asyncMatch) {\n return { kind: 'async', cases: [], reason: 'declared return is Promise<Node[] | Node>' }\n }\n if (returnTypeIsNodeShape(returnType, checker)) {\n cases.push(2)\n reasons.push('declared return is Node[]-like')\n }\n\n // Case 1: at least one parameter assignable to View<S,M> or a documented\n // structural subset. Match on the declared parameter type's shape — we\n // use property-name plus per-property callability as a structural\n // signature. The 5 documented subsets are listed below.\n for (const param of sig.getParameters()) {\n const paramDecl = param.getDeclarations()?.[0]\n if (!paramDecl) continue\n const paramType = checker.getTypeOfSymbolAtLocation(param, paramDecl)\n const subset = matchViewSubset(paramType, checker)\n if (subset) {\n cases.push(1)\n reasons.push(`accepts View subset (${subset})`)\n break\n }\n }\n\n if (cases.length === 0) {\n return { kind: 'opaque', cases: [], reason: 'no §2.1 case matched' }\n }\n return { kind: 'walked', cases, reason: reasons.join('; ') }\n}\n\n/**\n * The 5 documented View subsets, enumerated. New subsets require a doc\n * revision and a fixture per §2.1.\n *\n * Returns the subset's identifier when matched, undefined otherwise.\n * Matching is by *property presence* — we check that the parameter type\n * exposes the required property names, each with a callable type. We\n * intentionally do NOT call `isTypeAssignableTo` against a synthetic\n * subset type, because TypeScript's structural assignability would\n * accept arbitrary supersets and lose the \"documented subset\" guarantee.\n */\nfunction matchViewSubset(t: ts.Type, _checker: ts.TypeChecker): string | undefined {\n if (!isObjectLike(t)) return undefined\n const props = t.getProperties().map((p) => p.getName())\n const has = (name: string): boolean => props.includes(name)\n\n // Full View<S,M> bag — must expose at least send + show + each + branch.\n // Real-world callers spread or destructure; the type they pass is the\n // full View<S,M> regardless of how much they use.\n if (has('send') && has('show') && has('each') && has('branch') && has('text')) {\n return 'View<S, M>'\n }\n // send + show + each + branch (no text)\n if (has('send') && has('show') && has('each') && has('branch') && !has('text')) {\n return '{ send, show, each, branch }'\n }\n // send + text\n if (has('send') && has('text') && !has('show') && !has('each')) {\n return '{ send, text }'\n }\n // send only\n if (has('send') && !has('text') && !has('show') && !has('each')) {\n return '{ send }'\n }\n // text only\n if (has('text') && !has('send') && !has('show') && !has('each')) {\n return '{ text }'\n }\n\n return undefined\n}\n\nfunction isObjectLike(t: ts.Type): boolean {\n return (t.getFlags() & ts.TypeFlags.Object) !== 0\n}\n\n/**\n * Returns true if `t` is assignable to one of: `Node`, `Node[]`,\n * `Node | undefined`, `ReadonlyArray<Node>`.\n *\n * Uses the type checker's structural matching against a synthesized\n * `Node`-like — we look up the global `Node` symbol from the lib.dom\n * declarations.\n */\nfunction returnTypeIsNodeShape(t: ts.Type, checker: ts.TypeChecker): boolean {\n // Strip undefined from a union for the \"Node | undefined\" case.\n const nonUndefined = stripUndefined(t)\n\n // Array / ReadonlyArray case: element type is Node-like.\n // TypeScript represents both as a `TypeReference` whose target is the\n // global Array / ReadonlyArray and whose first type-arg is the element.\n if (isArrayOrReadonlyArray(nonUndefined)) {\n const elem = getFirstTypeArg(nonUndefined)\n if (elem && isNodeLike(elem, checker)) return true\n }\n // Singular Node return: `function (...): Node`.\n if (isNodeLike(nonUndefined, checker)) return true\n // Union: any member is Node-shaped.\n if (nonUndefined.isUnion()) {\n for (const u of nonUndefined.types) {\n if (returnTypeIsNodeShape(u, checker)) return true\n }\n }\n return false\n}\n\nfunction returnTypeIsAsyncNode(t: ts.Type, checker: ts.TypeChecker): boolean {\n // Promise<X> where X is Node-shaped.\n const sym = t.getSymbol()\n if (!sym || sym.getName() !== 'Promise') return false\n const args = (t as ts.TypeReference).typeArguments\n if (!args || args.length === 0) return false\n return returnTypeIsNodeShape(args[0]!, checker)\n}\n\nfunction stripUndefined(t: ts.Type): ts.Type {\n if (!t.isUnion()) return t\n const nonUndef = t.types.filter(\n (u) => (u.getFlags() & (ts.TypeFlags.Undefined | ts.TypeFlags.Void)) === 0,\n )\n if (nonUndef.length === t.types.length) return t\n if (nonUndef.length === 1) return nonUndef[0]!\n return t\n}\n\nfunction isArrayOrReadonlyArray(t: ts.Type): boolean {\n const sym = t.getSymbol()\n if (!sym) return false\n const name = sym.getName()\n return name === 'ReadonlyArray' || name === 'Array'\n}\n\nfunction getFirstTypeArg(t: ts.Type): ts.Type | undefined {\n const args = (t as ts.TypeReference).typeArguments\n return args?.[0]\n}\n\nfunction isNodeLike(t: ts.Type, _checker: ts.TypeChecker): boolean {\n const sym = t.getSymbol()\n if (!sym) return false\n const name = sym.getName()\n // Built-in DOM Node base types — return true on the abstract names.\n if (\n name === 'Node' ||\n name === 'Element' ||\n name === 'HTMLElement' ||\n name === 'Text' ||\n name === 'Comment' ||\n name === 'DocumentFragment' ||\n name === 'ChildNode'\n ) {\n return true\n }\n // The concrete `HTMLDivElement` / `SVGCircleElement` / `MathMLMathElement`\n // names that `HTMLElementTagNameMap[K]` resolves to. Element helpers\n // (`div(...)`, `button(...)`) all hit this branch — without it they\n // would be misclassified as opaque and flood the diagnostic stream.\n return (\n /^HTML[A-Z]\\w*Element$/.test(name) ||\n /^SVG[A-Z]\\w*Element$/.test(name) ||\n /^MathML[A-Z]\\w*Element$/.test(name)\n )\n}\n\nfunction hasLluiHelperTag(decl: ts.Declaration): boolean {\n const jsDocs = ts.getJSDocTags(decl)\n for (const tag of jsDocs) {\n if (tag.tagName.text === 'llui-helper') return true\n }\n return false\n}\n\nfunction isCallableDeclaration(d: ts.Declaration): boolean {\n return (\n ts.isFunctionDeclaration(d) ||\n ts.isFunctionExpression(d) ||\n ts.isArrowFunction(d) ||\n ts.isMethodDeclaration(d) ||\n ts.isVariableDeclaration(d)\n )\n}\n\n/**\n * Whether the call site is structurally in a view position. A view\n * position is one where the result flows into:\n * - the return of a `view()` callback,\n * - a `Node[]` literal element being built by a structural primitive\n * (`each.render`, `show.render`, `branch.cases.X`, `scope.render`),\n * - the children array of an element-helper call.\n *\n * Approximation for the prototype: the call is inside a function whose\n * return type (declared OR inferred from the surrounding context) is\n * Node-shaped. Less precise than tracking JSX-style returns, but\n * sufficient to gate the diagnostic emission for the validation run.\n */\nfunction isViewPositionCall(call: ts.CallExpression, checker: ts.TypeChecker): boolean {\n // Walk up: an enclosing function declaration / arrow whose return is\n // Node-shaped. Stop at the source file.\n let cur: ts.Node | undefined = call.parent\n while (cur) {\n if (\n ts.isFunctionDeclaration(cur) ||\n ts.isFunctionExpression(cur) ||\n ts.isArrowFunction(cur) ||\n ts.isMethodDeclaration(cur)\n ) {\n const sig = checker.getSignatureFromDeclaration(cur)\n if (sig) {\n const ret = checker.getReturnTypeOfSignature(sig)\n if (returnTypeIsNodeShape(ret, checker)) return true\n }\n return false\n }\n cur = cur.parent\n }\n return false\n}\n\n/**\n * Walk a Program looking for call expressions that should be classified\n * by the §2.1 rule. Restricts the walk to files matching `filter` so\n * tests can scope to a subdirectory.\n */\nexport function walkProgram(\n program: ts.Program,\n options: { filter?: (sourceFile: ts.SourceFile) => boolean } = {},\n): WalkerResult {\n const checker = program.getTypeChecker()\n const filter = options.filter ?? (() => true)\n const diagnostics: WalkerDiagnostic[] = []\n const perFile = new Map<\n string,\n WalkerResult['perFile'] extends Map<string, infer V> ? V : never\n >()\n\n for (const sf of program.getSourceFiles()) {\n if (sf.isDeclarationFile) continue\n if (!filter(sf)) continue\n const counts = { callsClassified: 0, walked: 0, opaque: 0, async: 0, notAHelper: 0 }\n perFile.set(sf.fileName, counts)\n\n const visit = (node: ts.Node): void => {\n if (ts.isCallExpression(node)) {\n // Resolve the symbol of the callee.\n const callee = node.expression\n let symbol = checker.getSymbolAtLocation(callee)\n if (symbol && symbol.flags & ts.SymbolFlags.Alias) {\n symbol = checker.getAliasedSymbol(symbol)\n }\n if (symbol && !(symbol.flags & ts.SymbolFlags.Transient)) {\n const cls = classifyViewHelper(symbol, checker)\n counts.callsClassified++\n if (cls.kind === 'walked') counts.walked++\n else if (cls.kind === 'opaque') counts.opaque++\n else if (cls.kind === 'async') counts.async++\n else counts.notAHelper++\n\n if (cls.kind === 'opaque' && isViewPositionCall(node, checker)) {\n diagnostics.push({\n id: 'llui/opaque-view-call',\n file: sf.fileName,\n pos: node.getStart(sf),\n end: node.getEnd(),\n helperName: getCalleeName(callee),\n message: `Call to \"${getCalleeName(callee) ?? '<unknown>'}\" in a view position is opaque to the cross-file walker (${cls.reason}). Either add an explicit return-type annotation (Node[] / Node / ReadonlyArray<Node>), accept a View bag parameter (or a documented subset), or mark with /** @llui-helper */ if the helper genuinely cannot be annotated. As a last resort, use track({ deps: ... }) at the call site.`,\n })\n } else if (cls.kind === 'async' && isViewPositionCall(node, checker)) {\n diagnostics.push({\n id: 'llui/async-view-helper',\n file: sf.fileName,\n pos: node.getStart(sf),\n end: node.getEnd(),\n helperName: getCalleeName(callee),\n message: `Call to \"${getCalleeName(callee) ?? '<unknown>'}\" in a view position returns Promise<Node[] | Node>. LLui's view layer is synchronous — wrap async work in onMount() or use clientOnly() instead.`,\n })\n }\n }\n }\n ts.forEachChild(node, visit)\n }\n visit(sf)\n }\n\n return { diagnostics, perFile }\n}\n\nfunction getCalleeName(expr: ts.Expression): string | undefined {\n if (ts.isIdentifier(expr)) return expr.text\n if (ts.isPropertyAccessExpression(expr)) return expr.name.text\n return undefined\n}\n\n// ── Diagnostic schema integration (v2c §3) ──────────────────────────\n//\n// The walker emits a lightweight `WalkerDiagnostic` (with raw byte\n// offsets) for internal accumulation. Adapters and the host pipeline\n// want the canonical `Diagnostic` shape with project-relative paths\n// and line/column ranges. This converter resolves the position pair to\n// a Range and relativizes the file path; the caller supplies the\n// project root.\n\nconst WALKER_DIAGNOSTIC_META: Record<\n DiagnosticId,\n {\n severity: DiagnosticSeverity\n category: DiagnosticCategory\n documentation?: string\n }\n> = {\n 'llui/opaque-view-call': {\n severity: 'warning',\n category: 'reactivity',\n documentation:\n 'https://github.com/fponticelli/llui/blob/main/docs/proposals/v2-compiler/v2b.md#21-view-helper-resolution-rule',\n },\n 'llui/async-view-helper': {\n severity: 'error',\n category: 'composition',\n documentation:\n 'https://github.com/fponticelli/llui/blob/main/docs/proposals/v2-compiler/v2b.md#21-view-helper-resolution-rule',\n },\n 'llui/helper-cycle': {\n severity: 'warning',\n category: 'composition',\n documentation:\n 'https://github.com/fponticelli/llui/blob/main/docs/proposals/v2-compiler/v2b.md#23-recursion-and-cycles',\n },\n}\n\n/**\n * Convert a walker-internal diagnostic to the canonical `Diagnostic`\n * shape. Reads the source text (for line/column resolution) and a\n * project root (for path relativization).\n */\nexport function toCanonicalDiagnostic(\n d: WalkerDiagnostic,\n sourceText: string,\n projectRoot: string,\n): Diagnostic {\n const meta = WALKER_DIAGNOSTIC_META[d.id]\n return {\n id: d.id,\n severity: meta.severity,\n category: meta.category,\n message: d.message,\n location: {\n file: relativizeFile(d.file, projectRoot),\n range: rangeFromOffsets(sourceText, d.pos, d.end),\n },\n ...(meta.documentation ? { documentation: meta.documentation } : {}),\n }\n}\n\n// ── Cross-file accessor path collection ─────────────────────────────\n//\n// Given a focal source file inside a Program, walk every reactive-accessor\n// arrow in the file. For each accessor:\n// - Collect paths it reads directly (the existing AST-only collector\n// handles this — see `collect-deps.ts`).\n// - For every call site inside the accessor whose callee resolves to a\n// view-helper (per §2.1), descend into the callee and merge its reads.\n//\n// This is the cross-file extension of `collectStatePathsFromSource`. The\n// AST-only collector terminates at the file boundary; the cross-file\n// version follows view-helper calls into other files using the TypeChecker.\n//\n// Used by the focal file's compiler to compute its __prefixes table. The\n// production wiring (Vite adapter builds a Program; compileFile consumes\n// it) is v2c module work — for v2b this is exposed as a callable engine\n// API that downstream tools can drive.\n\n/**\n * Collect the cross-file union of accessor paths read from a focal file.\n * Returns the union over every reactive accessor in `focalFile`, with\n * cross-file view-helper descents merged in.\n *\n * Reactive-accessor entry is gated by `isReactiveAccessor` (the same\n * predicate the file-local `collect-deps` walker uses) *plus* a\n * cross-file extension: an arrow at the first-arg position of a call\n * to a §2.1 view-helper also counts as reactive, because that's the\n * lift the helper applies to our state.\n *\n * Without the gate, every 1-param arrow in the file gets walked —\n * including `onEffect: (bag) => bag.send(...)`, where `bag.send` ends\n * up in the path set as a phantom \"send\" prefix. Issue #5, bug 3.\n */\nexport function crossFileAccessorPaths(program: ts.Program, focalFile: ts.SourceFile): Set<string> {\n const checker = program.getTypeChecker()\n const paths = new Set<string>()\n const visitedHelpers = new Set<ts.Declaration>()\n\n const isViewHelperCallArg0 = (arrow: ts.ArrowFunction | ts.FunctionExpression): boolean => {\n const parent = arrow.parent\n if (!parent || !ts.isCallExpression(parent)) return false\n if (parent.arguments[0] !== arrow) return false\n const sym = resolveAliasedSymbol(parent.expression, checker)\n if (!sym) return false\n return classifyViewHelper(sym, checker).kind === 'walked'\n }\n\n const visit = (node: ts.Node): void => {\n if (\n (ts.isArrowFunction(node) || ts.isFunctionExpression(node)) &&\n node.parameters.length === 1\n ) {\n const p0 = node.parameters[0]!\n if (ts.isIdentifier(p0.name) && node.body) {\n if (isReactiveAccessor(node) || isViewHelperCallArg0(node)) {\n walkAccessorBody(node.body, p0.name.text, paths, checker, visitedHelpers)\n }\n }\n }\n ts.forEachChild(node, visit)\n }\n visit(focalFile)\n return paths\n}\n\n// Helpers whose arrow args are NOT state accessors — same exclusion list\n// the file-local walker uses (collect-deps.ts § NON_DELEGATION_HELPERS).\n// `item` / `sample` read state imperatively or per-row; descending into\n// their bodies would attribute reads to the wrong scope. `memo` / `text` /\n// `unsafeHtml` already have their inline arrow walked by the top-level\n// visitor — we'd double-count if we recursed through the call again.\nconst NON_DELEGATION_CALLEES = new Set(['sample', 'item', 'memo', 'text', 'unsafeHtml'])\n\nfunction walkAccessorBody(\n body: ts.Node,\n paramName: string,\n paths: Set<string>,\n checker: ts.TypeChecker,\n visitedHelpers: Set<ts.Declaration>,\n): void {\n const visit = (node: ts.Node): void => {\n // Property-chain extraction (mirrors collect-deps' depth-2 normaliser).\n if (ts.isPropertyAccessExpression(node)) {\n const chain = resolveDepth2(node, paramName)\n if (chain) paths.add(chain)\n }\n\n if (ts.isCallExpression(node)) {\n const callee = node.expression\n const sym = resolveAliasedSymbol(callee, checker)\n if (sym) {\n const cls = classifyViewHelper(sym, checker)\n const decl = sym.getDeclarations()?.find(isFunctionLikeDecl)\n\n if (cls.kind === 'walked' && decl && !visitedHelpers.has(decl)) {\n // §2.1 view-helper: full descent (arrow-arg accessors lift\n // into our state, identifier args pass our state through).\n visitedHelpers.add(decl)\n descendIntoHelper(\n decl,\n node,\n paramName,\n paths,\n checker,\n visitedHelpers,\n /*viewHelper*/ true,\n )\n } else if (decl && !visitedHelpers.has(decl)) {\n // Non-view-helper: only follow if our state param is passed\n // through unchanged. A helper returning string / boolean /\n // anything-non-Node that reads `s.foo.bar` still contributes\n // those paths to our accessor's read set when called as\n // `helper(s)`. Without this, helpers like\n // `(s) => s.route.kind === 'a'` would have their reads\n // silently dropped, producing a stale-render bug rather than\n // a crash (issue #5, bug 3 false-negative).\n //\n // Skip framework primitives whose arrow args are visited\n // separately (see NON_DELEGATION_CALLEES) — descending would\n // double-count.\n if (\n ts.isIdentifier(callee) &&\n !NON_DELEGATION_CALLEES.has(callee.text) &&\n callPassesParamIdent(node, paramName)\n ) {\n visitedHelpers.add(decl)\n descendIntoHelper(\n decl,\n node,\n paramName,\n paths,\n checker,\n visitedHelpers,\n /*viewHelper*/ false,\n )\n }\n }\n }\n }\n\n ts.forEachChild(node, visit)\n }\n visit(body)\n}\n\nfunction callPassesParamIdent(call: ts.CallExpression, paramName: string): boolean {\n for (const arg of call.arguments) {\n if (ts.isIdentifier(arg) && arg.text === paramName) return true\n }\n return false\n}\n\nfunction descendIntoHelper(\n decl: ts.Declaration,\n callSite: ts.CallExpression,\n outerParamName: string,\n paths: Set<string>,\n checker: ts.TypeChecker,\n visitedHelpers: Set<ts.Declaration>,\n viewHelper: boolean,\n): void {\n // Match each parameter to its argument at the call site.\n //\n // For §2.1 view-helpers: arrow-arg accessors like `(t) => t.foo` are\n // lifts that bind the helper's parameter to a slice of our state;\n // walk their bodies so the slice's reads chain into our path set.\n //\n // For non-view-helpers: we don't know what the helper does with its\n // arrow args — could be a filter callback over a per-item type, or a\n // mapper that doesn't touch state at all. Only the identifier-arg\n // branch (`helper(s)`) is unambiguous, so the non-view-helper case\n // is conservative and only takes that path.\n const fnDecl = decl as ts.FunctionLikeDeclaration\n if (!fnDecl.body) return\n const params = fnDecl.parameters\n for (let i = 0; i < params.length; i++) {\n const param = params[i]!\n const arg = callSite.arguments[i]\n if (!arg) continue\n if (!ts.isIdentifier(param.name)) continue\n if (viewHelper && (ts.isArrowFunction(arg) || ts.isFunctionExpression(arg))) {\n const a0 = arg.parameters[0]\n if (a0 && ts.isIdentifier(a0.name) && arg.body) {\n walkAccessorBody(arg.body, a0.name.text, paths, checker, visitedHelpers)\n }\n } else if (ts.isIdentifier(arg) && arg.text === outerParamName) {\n walkAccessorBody(fnDecl.body, param.name.text, paths, checker, visitedHelpers)\n }\n }\n}\n\nfunction resolveAliasedSymbol(node: ts.Node, checker: ts.TypeChecker): ts.Symbol | undefined {\n let sym = checker.getSymbolAtLocation(node)\n if (!sym) return undefined\n if (sym.flags & ts.SymbolFlags.Alias) sym = checker.getAliasedSymbol(sym)\n if (sym.flags & ts.SymbolFlags.Transient) return undefined\n return sym\n}\n\nfunction resolveDepth2(node: ts.PropertyAccessExpression, paramName: string): string | null {\n const parts: string[] = []\n let current: ts.Expression = node\n while (ts.isPropertyAccessExpression(current)) {\n parts.unshift(current.name.text)\n current = current.expression\n }\n if (!ts.isIdentifier(current) || current.text !== paramName) return null\n if (parts.length === 0) return null\n return parts.slice(0, 2).join('.')\n}\n\nfunction isFunctionLikeDecl(d: ts.Declaration): boolean {\n return (\n ts.isFunctionDeclaration(d) ||\n ts.isFunctionExpression(d) ||\n ts.isArrowFunction(d) ||\n ts.isMethodDeclaration(d)\n )\n}\n"]}
|
|
1
|
+
{"version":3,"file":"cross-file-walker.js","sourceRoot":"","sources":["../src/cross-file-walker.ts"],"names":[],"mappings":"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","sourcesContent":["// Cross-file walker — v2b prototype (Phase 1).\n//\n// Classifies every call expression in a TypeScript Program against the\n// §2.1 view-helper resolution rule. Returns diagnostics + a per-callsite\n// classification trace.\n//\n// This is *prototype-grade*: no manifest consumption, no incremental cache,\n// no reverse-deps tracking. Phase 3 adds those layers on top.\n//\n// The rule (§2.1):\n// A call is a view-helper iff at least one of:\n// case 1 — the callee accepts a parameter assignable to View<S,M> or\n// one of the documented structural subsets (send-only,\n// text-only, send+text, send+show+each+branch).\n// case 2 — the callee's *declared* return type is assignable to\n// Node, Node[], Node|undefined, or ReadonlyArray<Node>.\n// case 3 — the callee has a `/** @llui-helper */` JSDoc tag.\n//\n// Async helpers (declared return Promise<Node[]>) are NOT view-helpers\n// and produce `llui/async-view-helper` (hard error).\n//\n// Everything else: opaque. Emits `llui/opaque-view-call` if the call site\n// is structurally a view position (its result flows into a view-returning\n// expression); otherwise the call is uninteresting and not reported.\n\nimport ts from 'typescript'\nimport {\n type Diagnostic,\n type DiagnosticCategory,\n type DiagnosticSeverity,\n rangeFromOffsets,\n relativizeFile,\n} from './diagnostic.js'\nimport { isReactiveAccessor } from './collect-deps.js'\n\nexport type ViewHelperKind = 'walked' | 'opaque' | 'async' | 'not-a-helper'\n\nexport interface ViewHelperClassification {\n kind: ViewHelperKind\n /** Which §2.1 case fired. Only populated when kind === 'walked'. */\n cases: Array<1 | 2 | 3>\n /** Human-readable reason. */\n reason: string\n}\n\nexport type DiagnosticId = 'llui/opaque-view-call' | 'llui/async-view-helper' | 'llui/helper-cycle'\n\nexport interface WalkerDiagnostic {\n id: DiagnosticId\n file: string\n pos: number\n end: number\n message: string\n helperName: string | undefined\n}\n\nexport interface WalkerResult {\n diagnostics: WalkerDiagnostic[]\n /** Per-file counts for telemetry. */\n perFile: Map<\n string,\n {\n callsClassified: number\n walked: number\n opaque: number\n async: number\n notAHelper: number\n }\n >\n}\n\n/**\n * Classify the symbol's declaration against the §2.1 rule.\n *\n * Operates on the *declared* type (`getTypeOfSymbolAtLocation(symbol,\n * symbol.declarations[0])`), not the inferred-at-call-site type. This is\n * load-bearing: TypeScript inference at call sites widens to union\n * shapes (`Node[] | undefined`, `JSX.Element | string`) that miss\n * assignability for case 2. The rule's intent is \"did the author commit\n * to a view-helper signature in the declaration\" — inference-narrowed\n * types don't satisfy that intent.\n */\nexport function classifyViewHelper(\n symbol: ts.Symbol,\n checker: ts.TypeChecker,\n): ViewHelperClassification {\n const decls = symbol.getDeclarations() ?? []\n const decl = decls.find(isCallableDeclaration)\n if (!decl) return { kind: 'not-a-helper', cases: [], reason: 'no callable declaration found' }\n\n const cases: Array<1 | 2 | 3> = []\n const reasons: string[] = []\n\n // Case 3: @llui-helper JSDoc tag. Cheap to check, decisive when present.\n if (hasLluiHelperTag(decl)) {\n cases.push(3)\n reasons.push('@llui-helper tag')\n }\n\n // Get the signature's parameters + return type from the *declaration*.\n const declType = checker.getTypeOfSymbolAtLocation(symbol, decl)\n const sigs = declType.getCallSignatures()\n if (sigs.length === 0) {\n if (cases.includes(3)) {\n return { kind: 'walked', cases, reason: reasons.join('; ') }\n }\n return { kind: 'not-a-helper', cases: [], reason: 'declared type has no call signature' }\n }\n // Use the first signature. Overloaded helpers are rare in view code;\n // production walker should iterate all.\n const sig = sigs[0]!\n\n // Case 2: declared return type assignable to Node / Node[] / etc.\n const returnType = checker.getReturnTypeOfSignature(sig)\n const asyncMatch = returnTypeIsAsyncNode(returnType, checker)\n if (asyncMatch) {\n return { kind: 'async', cases: [], reason: 'declared return is Promise<Node[] | Node>' }\n }\n if (returnTypeIsNodeShape(returnType, checker)) {\n cases.push(2)\n reasons.push('declared return is Node[]-like')\n }\n\n // Case 1: at least one parameter assignable to View<S,M> or a documented\n // structural subset. Match on the declared parameter type's shape — we\n // use property-name plus per-property callability as a structural\n // signature. The 5 documented subsets are listed below.\n for (const param of sig.getParameters()) {\n const paramDecl = param.getDeclarations()?.[0]\n if (!paramDecl) continue\n const paramType = checker.getTypeOfSymbolAtLocation(param, paramDecl)\n const subset = matchViewSubset(paramType, checker)\n if (subset) {\n cases.push(1)\n reasons.push(`accepts View subset (${subset})`)\n break\n }\n }\n\n if (cases.length === 0) {\n return { kind: 'opaque', cases: [], reason: 'no §2.1 case matched' }\n }\n return { kind: 'walked', cases, reason: reasons.join('; ') }\n}\n\n/**\n * The 5 documented View subsets, enumerated. New subsets require a doc\n * revision and a fixture per §2.1.\n *\n * Returns the subset's identifier when matched, undefined otherwise.\n * Matching is by *property presence* — we check that the parameter type\n * exposes the required property names, each with a callable type. We\n * intentionally do NOT call `isTypeAssignableTo` against a synthetic\n * subset type, because TypeScript's structural assignability would\n * accept arbitrary supersets and lose the \"documented subset\" guarantee.\n */\nfunction matchViewSubset(t: ts.Type, _checker: ts.TypeChecker): string | undefined {\n if (!isObjectLike(t)) return undefined\n const props = t.getProperties().map((p) => p.getName())\n const has = (name: string): boolean => props.includes(name)\n\n // Full View<S,M> bag — must expose at least send + show + each + branch.\n // Real-world callers spread or destructure; the type they pass is the\n // full View<S,M> regardless of how much they use.\n if (has('send') && has('show') && has('each') && has('branch') && has('text')) {\n return 'View<S, M>'\n }\n // send + show + each + branch (no text)\n if (has('send') && has('show') && has('each') && has('branch') && !has('text')) {\n return '{ send, show, each, branch }'\n }\n // send + text\n if (has('send') && has('text') && !has('show') && !has('each')) {\n return '{ send, text }'\n }\n // send only\n if (has('send') && !has('text') && !has('show') && !has('each')) {\n return '{ send }'\n }\n // text only\n if (has('text') && !has('send') && !has('show') && !has('each')) {\n return '{ text }'\n }\n\n return undefined\n}\n\nfunction isObjectLike(t: ts.Type): boolean {\n return (t.getFlags() & ts.TypeFlags.Object) !== 0\n}\n\n/**\n * Returns true if `t` is assignable to one of: `Node`, `Node[]`,\n * `Node | undefined`, `ReadonlyArray<Node>`.\n *\n * Uses the type checker's structural matching against a synthesized\n * `Node`-like — we look up the global `Node` symbol from the lib.dom\n * declarations.\n */\nfunction returnTypeIsNodeShape(t: ts.Type, checker: ts.TypeChecker): boolean {\n // Strip undefined from a union for the \"Node | undefined\" case.\n const nonUndefined = stripUndefined(t)\n\n // Array / ReadonlyArray case: element type is Node-like.\n // TypeScript represents both as a `TypeReference` whose target is the\n // global Array / ReadonlyArray and whose first type-arg is the element.\n if (isArrayOrReadonlyArray(nonUndefined)) {\n const elem = getFirstTypeArg(nonUndefined)\n if (elem && isNodeLike(elem, checker)) return true\n }\n // Singular Node return: `function (...): Node`.\n if (isNodeLike(nonUndefined, checker)) return true\n // Union: any member is Node-shaped.\n if (nonUndefined.isUnion()) {\n for (const u of nonUndefined.types) {\n if (returnTypeIsNodeShape(u, checker)) return true\n }\n }\n return false\n}\n\nfunction returnTypeIsAsyncNode(t: ts.Type, checker: ts.TypeChecker): boolean {\n // Promise<X> where X is Node-shaped.\n const sym = t.getSymbol()\n if (!sym || sym.getName() !== 'Promise') return false\n const args = (t as ts.TypeReference).typeArguments\n if (!args || args.length === 0) return false\n return returnTypeIsNodeShape(args[0]!, checker)\n}\n\nfunction stripUndefined(t: ts.Type): ts.Type {\n if (!t.isUnion()) return t\n const nonUndef = t.types.filter(\n (u) => (u.getFlags() & (ts.TypeFlags.Undefined | ts.TypeFlags.Void)) === 0,\n )\n if (nonUndef.length === t.types.length) return t\n if (nonUndef.length === 1) return nonUndef[0]!\n return t\n}\n\nfunction isArrayOrReadonlyArray(t: ts.Type): boolean {\n const sym = t.getSymbol()\n if (!sym) return false\n const name = sym.getName()\n return name === 'ReadonlyArray' || name === 'Array'\n}\n\nfunction getFirstTypeArg(t: ts.Type): ts.Type | undefined {\n const args = (t as ts.TypeReference).typeArguments\n return args?.[0]\n}\n\nfunction isNodeLike(t: ts.Type, _checker: ts.TypeChecker): boolean {\n const sym = t.getSymbol()\n if (!sym) return false\n const name = sym.getName()\n // Built-in DOM Node base types — return true on the abstract names.\n if (\n name === 'Node' ||\n name === 'Element' ||\n name === 'HTMLElement' ||\n name === 'Text' ||\n name === 'Comment' ||\n name === 'DocumentFragment' ||\n name === 'ChildNode'\n ) {\n return true\n }\n // The concrete `HTMLDivElement` / `SVGCircleElement` / `MathMLMathElement`\n // names that `HTMLElementTagNameMap[K]` resolves to. Element helpers\n // (`div(...)`, `button(...)`) all hit this branch — without it they\n // would be misclassified as opaque and flood the diagnostic stream.\n return (\n /^HTML[A-Z]\\w*Element$/.test(name) ||\n /^SVG[A-Z]\\w*Element$/.test(name) ||\n /^MathML[A-Z]\\w*Element$/.test(name)\n )\n}\n\nfunction hasLluiHelperTag(decl: ts.Declaration): boolean {\n const jsDocs = ts.getJSDocTags(decl)\n for (const tag of jsDocs) {\n if (tag.tagName.text === 'llui-helper') return true\n }\n return false\n}\n\nfunction isCallableDeclaration(d: ts.Declaration): boolean {\n return (\n ts.isFunctionDeclaration(d) ||\n ts.isFunctionExpression(d) ||\n ts.isArrowFunction(d) ||\n ts.isMethodDeclaration(d) ||\n ts.isVariableDeclaration(d)\n )\n}\n\n/**\n * Whether the call site is structurally in a view position. A view\n * position is one where the result flows into:\n * - the return of a `view()` callback,\n * - a `Node[]` literal element being built by a structural primitive\n * (`each.render`, `show.render`, `branch.cases.X`, `scope.render`),\n * - the children array of an element-helper call.\n *\n * Approximation for the prototype: the call is inside a function whose\n * return type (declared OR inferred from the surrounding context) is\n * Node-shaped. Less precise than tracking JSX-style returns, but\n * sufficient to gate the diagnostic emission for the validation run.\n */\nfunction isViewPositionCall(call: ts.CallExpression, checker: ts.TypeChecker): boolean {\n // Walk up: an enclosing function declaration / arrow whose return is\n // Node-shaped. Stop at the source file.\n let cur: ts.Node | undefined = call.parent\n while (cur) {\n if (\n ts.isFunctionDeclaration(cur) ||\n ts.isFunctionExpression(cur) ||\n ts.isArrowFunction(cur) ||\n ts.isMethodDeclaration(cur)\n ) {\n const sig = checker.getSignatureFromDeclaration(cur)\n if (sig) {\n const ret = checker.getReturnTypeOfSignature(sig)\n if (returnTypeIsNodeShape(ret, checker)) return true\n }\n return false\n }\n cur = cur.parent\n }\n return false\n}\n\n/**\n * Walk a Program looking for call expressions that should be classified\n * by the §2.1 rule. Restricts the walk to files matching `filter` so\n * tests can scope to a subdirectory.\n */\nexport function walkProgram(\n program: ts.Program,\n options: { filter?: (sourceFile: ts.SourceFile) => boolean } = {},\n): WalkerResult {\n const checker = program.getTypeChecker()\n const filter = options.filter ?? (() => true)\n const diagnostics: WalkerDiagnostic[] = []\n const perFile = new Map<\n string,\n WalkerResult['perFile'] extends Map<string, infer V> ? V : never\n >()\n\n for (const sf of program.getSourceFiles()) {\n if (sf.isDeclarationFile) continue\n if (!filter(sf)) continue\n const counts = { callsClassified: 0, walked: 0, opaque: 0, async: 0, notAHelper: 0 }\n perFile.set(sf.fileName, counts)\n\n const visit = (node: ts.Node): void => {\n if (ts.isCallExpression(node)) {\n // Resolve the symbol of the callee.\n const callee = node.expression\n let symbol = checker.getSymbolAtLocation(callee)\n if (symbol && symbol.flags & ts.SymbolFlags.Alias) {\n symbol = checker.getAliasedSymbol(symbol)\n }\n if (symbol && !(symbol.flags & ts.SymbolFlags.Transient)) {\n const cls = classifyViewHelper(symbol, checker)\n counts.callsClassified++\n if (cls.kind === 'walked') counts.walked++\n else if (cls.kind === 'opaque') counts.opaque++\n else if (cls.kind === 'async') counts.async++\n else counts.notAHelper++\n\n if (cls.kind === 'opaque' && isViewPositionCall(node, checker)) {\n diagnostics.push({\n id: 'llui/opaque-view-call',\n file: sf.fileName,\n pos: node.getStart(sf),\n end: node.getEnd(),\n helperName: getCalleeName(callee),\n message: `Call to \"${getCalleeName(callee) ?? '<unknown>'}\" in a view position is opaque to the cross-file walker (${cls.reason}). Either add an explicit return-type annotation (Node[] / Node / ReadonlyArray<Node>), accept a View bag parameter (or a documented subset), or mark with /** @llui-helper */ if the helper genuinely cannot be annotated. As a last resort, use track({ deps: ... }) at the call site.`,\n })\n } else if (cls.kind === 'async' && isViewPositionCall(node, checker)) {\n diagnostics.push({\n id: 'llui/async-view-helper',\n file: sf.fileName,\n pos: node.getStart(sf),\n end: node.getEnd(),\n helperName: getCalleeName(callee),\n message: `Call to \"${getCalleeName(callee) ?? '<unknown>'}\" in a view position returns Promise<Node[] | Node>. LLui's view layer is synchronous — wrap async work in onMount() or use clientOnly() instead.`,\n })\n }\n }\n }\n ts.forEachChild(node, visit)\n }\n visit(sf)\n }\n\n return { diagnostics, perFile }\n}\n\nfunction getCalleeName(expr: ts.Expression): string | undefined {\n if (ts.isIdentifier(expr)) return expr.text\n if (ts.isPropertyAccessExpression(expr)) return expr.name.text\n return undefined\n}\n\n// ── Diagnostic schema integration (v2c §3) ──────────────────────────\n//\n// The walker emits a lightweight `WalkerDiagnostic` (with raw byte\n// offsets) for internal accumulation. Adapters and the host pipeline\n// want the canonical `Diagnostic` shape with project-relative paths\n// and line/column ranges. This converter resolves the position pair to\n// a Range and relativizes the file path; the caller supplies the\n// project root.\n\nconst WALKER_DIAGNOSTIC_META: Record<\n DiagnosticId,\n {\n severity: DiagnosticSeverity\n category: DiagnosticCategory\n documentation?: string\n }\n> = {\n 'llui/opaque-view-call': {\n severity: 'warning',\n category: 'reactivity',\n documentation:\n 'https://github.com/fponticelli/llui/blob/main/docs/proposals/v2-compiler/v2b.md#21-view-helper-resolution-rule',\n },\n 'llui/async-view-helper': {\n severity: 'error',\n category: 'composition',\n documentation:\n 'https://github.com/fponticelli/llui/blob/main/docs/proposals/v2-compiler/v2b.md#21-view-helper-resolution-rule',\n },\n 'llui/helper-cycle': {\n severity: 'warning',\n category: 'composition',\n documentation:\n 'https://github.com/fponticelli/llui/blob/main/docs/proposals/v2-compiler/v2b.md#23-recursion-and-cycles',\n },\n}\n\n/**\n * Convert a walker-internal diagnostic to the canonical `Diagnostic`\n * shape. Reads the source text (for line/column resolution) and a\n * project root (for path relativization).\n */\nexport function toCanonicalDiagnostic(\n d: WalkerDiagnostic,\n sourceText: string,\n projectRoot: string,\n): Diagnostic {\n const meta = WALKER_DIAGNOSTIC_META[d.id]\n return {\n id: d.id,\n severity: meta.severity,\n category: meta.category,\n message: d.message,\n location: {\n file: relativizeFile(d.file, projectRoot),\n range: rangeFromOffsets(sourceText, d.pos, d.end),\n },\n ...(meta.documentation ? { documentation: meta.documentation } : {}),\n }\n}\n\n// ── Cross-file accessor path collection ─────────────────────────────\n//\n// Given a focal source file inside a Program, walk every reactive-accessor\n// arrow in the file. For each accessor:\n// - Collect paths it reads directly (the existing AST-only collector\n// handles this — see `collect-deps.ts`).\n// - For every call site inside the accessor whose callee resolves to a\n// view-helper (per §2.1), descend into the callee and merge its reads.\n//\n// This is the cross-file extension of `collectStatePathsFromSource`. The\n// AST-only collector terminates at the file boundary; the cross-file\n// version follows view-helper calls into other files using the TypeChecker.\n//\n// Used by the focal file's compiler to compute its __prefixes table. The\n// production wiring (Vite adapter builds a Program; compileFile consumes\n// it) is v2c module work — for v2b this is exposed as a callable engine\n// API that downstream tools can drive.\n\n/**\n * Collect the cross-file union of accessor paths read from a focal file.\n * Returns the union over every reactive accessor in `focalFile`, with\n * cross-file view-helper descents merged in.\n *\n * Reactive-accessor entry is gated by `isReactiveAccessor` (the same\n * predicate the file-local `collect-deps` walker uses) *plus* a\n * cross-file extension: an arrow at the first-arg position of a call\n * to a §2.1 view-helper also counts as reactive, because that's the\n * lift the helper applies to our state.\n *\n * Without the gate, every 1-param arrow in the file gets walked —\n * including `onEffect: (bag) => bag.send(...)`, where `bag.send` ends\n * up in the path set as a phantom \"send\" prefix. Issue #5, bug 3.\n */\nexport function crossFileAccessorPaths(\n program: ts.Program,\n focalFile: ts.SourceFile,\n): { paths: Set<string>; opaque: boolean } {\n const checker = program.getTypeChecker()\n const paths = new Set<string>()\n const opaqueOut = { value: false }\n const visitedHelpers = new Set<ts.Declaration>()\n\n const isViewHelperCallArg0 = (arrow: ts.ArrowFunction | ts.FunctionExpression): boolean => {\n const parent = arrow.parent\n if (!parent || !ts.isCallExpression(parent)) return false\n if (parent.arguments[0] !== arrow) return false\n const sym = resolveAliasedSymbol(parent.expression, checker)\n if (!sym) return false\n return classifyViewHelper(sym, checker).kind === 'walked'\n }\n\n const visit = (node: ts.Node): void => {\n if (\n (ts.isArrowFunction(node) || ts.isFunctionExpression(node)) &&\n node.parameters.length === 1\n ) {\n const p0 = node.parameters[0]!\n if (ts.isIdentifier(p0.name) && node.body) {\n if (isReactiveAccessor(node) || isViewHelperCallArg0(node)) {\n walkAccessorBody(node.body, p0.name.text, paths, checker, visitedHelpers, opaqueOut)\n }\n }\n }\n ts.forEachChild(node, visit)\n }\n visit(focalFile)\n return { paths, opaque: opaqueOut.value }\n}\n\n// Helpers whose arrow args are NOT state accessors — same exclusion list\n// the file-local walker uses (collect-deps.ts § NON_DELEGATION_HELPERS).\n// `item` / `sample` read state imperatively or per-row; descending into\n// their bodies would attribute reads to the wrong scope. `memo` / `text` /\n// `unsafeHtml` already have their inline arrow walked by the top-level\n// visitor — we'd double-count if we recursed through the call again.\nconst NON_DELEGATION_CALLEES = new Set(['sample', 'item', 'memo', 'text', 'unsafeHtml'])\n\nfunction walkAccessorBody(\n body: ts.Node,\n paramName: string,\n paths: Set<string>,\n checker: ts.TypeChecker,\n visitedHelpers: Set<ts.Declaration>,\n opaqueOut: { value: boolean },\n): void {\n const visit = (node: ts.Node): void => {\n // Property-chain extraction (mirrors collect-deps' depth-2 normaliser).\n if (ts.isPropertyAccessExpression(node)) {\n const chain = resolveDepth2(node, paramName)\n if (chain) paths.add(chain)\n }\n\n // Opaque-state-flow classifier (mirrors the per-binding mask\n // classifier in transform.ts:computeAccessorMask). Any standalone\n // appearance of the param identifier in a non-tracked container\n // means the helper reads through an expression we can't trace, so\n // a precise prefix table is insufficient — the host needs a\n // whole-state sentinel in `__prefixes`.\n if (ts.isIdentifier(node) && node.text === paramName) {\n const parent = node.parent\n const isBinding = !!parent && ts.isParameter(parent)\n if (!isBinding) {\n let isTracked = false\n if (parent) {\n if (ts.isPropertyAccessExpression(parent) && parent.expression === node) {\n isTracked = true\n } else if (ts.isElementAccessExpression(parent) && parent.expression === node) {\n isTracked =\n ts.isStringLiteralLike(parent.argumentExpression) ||\n ts.isNumericLiteral(parent.argumentExpression)\n } else if (\n ts.isCallExpression(parent) &&\n ts.isIdentifier(parent.expression) &&\n parent.arguments[0] === node &&\n !NON_DELEGATION_CALLEES.has(parent.expression.text)\n ) {\n // Identifier-callee delegations are handled by the\n // descend-into-helper branch below — if the callee\n // resolves, recursion finds opaque inside; if not, the\n // call's `sym` is undefined and the host sees no descent.\n // Treat as tracked here so this branch alone doesn't flip\n // opaque on every well-formed `helper(s)`.\n isTracked = true\n }\n }\n if (!isTracked) opaqueOut.value = true\n }\n }\n\n if (ts.isCallExpression(node)) {\n const callee = node.expression\n const sym = resolveAliasedSymbol(callee, checker)\n if (sym) {\n const cls = classifyViewHelper(sym, checker)\n const decl = sym.getDeclarations()?.find(isFunctionLikeDecl)\n\n if (cls.kind === 'walked' && decl && !visitedHelpers.has(decl)) {\n // §2.1 view-helper: full descent (arrow-arg accessors lift\n // into our state, identifier args pass our state through).\n visitedHelpers.add(decl)\n descendIntoHelper(\n decl,\n node,\n paramName,\n paths,\n checker,\n visitedHelpers,\n /*viewHelper*/ true,\n opaqueOut,\n )\n } else if (decl && !visitedHelpers.has(decl)) {\n // Non-view-helper: only follow if our state param is passed\n // through unchanged. A helper returning string / boolean /\n // anything-non-Node that reads `s.foo.bar` still contributes\n // those paths to our accessor's read set when called as\n // `helper(s)`. Without this, helpers like\n // `(s) => s.route.kind === 'a'` would have their reads\n // silently dropped, producing a stale-render bug rather than\n // a crash (issue #5, bug 3 false-negative).\n //\n // Skip framework primitives whose arrow args are visited\n // separately (see NON_DELEGATION_CALLEES) — descending would\n // double-count.\n if (\n ts.isIdentifier(callee) &&\n !NON_DELEGATION_CALLEES.has(callee.text) &&\n callPassesParamIdent(node, paramName)\n ) {\n visitedHelpers.add(decl)\n const fnDecl = decl as ts.FunctionLikeDeclaration\n if (fnDecl.body) {\n descendIntoHelper(\n decl,\n node,\n paramName,\n paths,\n checker,\n visitedHelpers,\n /*viewHelper*/ false,\n opaqueOut,\n )\n } else {\n // Declaration without a body — ambient `declare function`,\n // overload signature, or compiled .d.ts. State flows in\n // but we can't see what it reads. Conservative: opaque.\n opaqueOut.value = true\n }\n }\n } else if (!decl && ts.isIdentifier(callee) && !NON_DELEGATION_CALLEES.has(callee.text)) {\n // Callee resolved to a symbol but no function-like\n // declaration (e.g., ambient declaration, type-only import,\n // or a binding whose initializer the checker can't pin\n // down). If state flows in, treat as opaque — same\n // conservative read as the file-local classifier.\n if (callPassesParamIdent(node, paramName)) opaqueOut.value = true\n }\n } else if (ts.isIdentifier(callee) && !NON_DELEGATION_CALLEES.has(callee.text)) {\n // Callee identifier didn't resolve to ANY symbol (declared\n // outside the program, lost through transient binding, etc.).\n // The standalone `s` classifier above already flagged the arg\n // as opaque, so no additional bookkeeping is needed here; the\n // branch is kept to mirror the file-local handling shape.\n }\n }\n\n ts.forEachChild(node, visit)\n }\n visit(body)\n}\n\nfunction callPassesParamIdent(call: ts.CallExpression, paramName: string): boolean {\n for (const arg of call.arguments) {\n if (ts.isIdentifier(arg) && arg.text === paramName) return true\n }\n return false\n}\n\nfunction descendIntoHelper(\n decl: ts.Declaration,\n callSite: ts.CallExpression,\n outerParamName: string,\n paths: Set<string>,\n checker: ts.TypeChecker,\n visitedHelpers: Set<ts.Declaration>,\n viewHelper: boolean,\n opaqueOut: { value: boolean },\n): void {\n // Match each parameter to its argument at the call site.\n //\n // For §2.1 view-helpers: arrow-arg accessors like `(t) => t.foo` are\n // lifts that bind the helper's parameter to a slice of our state;\n // walk their bodies so the slice's reads chain into our path set.\n //\n // For non-view-helpers: we don't know what the helper does with its\n // arrow args — could be a filter callback over a per-item type, or a\n // mapper that doesn't touch state at all. Only the identifier-arg\n // branch (`helper(s)`) is unambiguous, so the non-view-helper case\n // is conservative and only takes that path.\n const fnDecl = decl as ts.FunctionLikeDeclaration\n if (!fnDecl.body) return\n const params = fnDecl.parameters\n for (let i = 0; i < params.length; i++) {\n const param = params[i]!\n const arg = callSite.arguments[i]\n if (!arg) continue\n if (!ts.isIdentifier(param.name)) continue\n if (viewHelper && (ts.isArrowFunction(arg) || ts.isFunctionExpression(arg))) {\n const a0 = arg.parameters[0]\n if (a0 && ts.isIdentifier(a0.name) && arg.body) {\n walkAccessorBody(arg.body, a0.name.text, paths, checker, visitedHelpers, opaqueOut)\n }\n } else if (ts.isIdentifier(arg) && arg.text === outerParamName) {\n walkAccessorBody(fnDecl.body, param.name.text, paths, checker, visitedHelpers, opaqueOut)\n }\n }\n}\n\nfunction resolveAliasedSymbol(node: ts.Node, checker: ts.TypeChecker): ts.Symbol | undefined {\n let sym = checker.getSymbolAtLocation(node)\n if (!sym) return undefined\n if (sym.flags & ts.SymbolFlags.Alias) sym = checker.getAliasedSymbol(sym)\n if (sym.flags & ts.SymbolFlags.Transient) return undefined\n return sym\n}\n\nfunction resolveDepth2(node: ts.PropertyAccessExpression, paramName: string): string | null {\n const parts: string[] = []\n let current: ts.Expression = node\n while (ts.isPropertyAccessExpression(current)) {\n parts.unshift(current.name.text)\n current = current.expression\n }\n if (!ts.isIdentifier(current) || current.text !== paramName) return null\n if (parts.length === 0) return null\n return parts.slice(0, 2).join('.')\n}\n\nfunction isFunctionLikeDecl(d: ts.Declaration): boolean {\n return (\n ts.isFunctionDeclaration(d) ||\n ts.isFunctionExpression(d) ||\n ts.isArrowFunction(d) ||\n ts.isMethodDeclaration(d)\n )\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lint-modules.d.ts","sourceRoot":"","sources":["../src/lint-modules.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"lint-modules.d.ts","sourceRoot":"","sources":["../src/lint-modules.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AA8CjD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,IAAI,cAAc,EAAE,CA+CpD"}
|
package/dist/lint-modules.js
CHANGED
|
@@ -55,6 +55,7 @@ import { noSampleInEventHandlerModule } from './modules/no-sample-in-event-handl
|
|
|
55
55
|
import { noRepeatedItemCurrentModule } from './modules/no-repeated-item-current.js';
|
|
56
56
|
import { agentEmitsDriftModule } from './modules/agent-emits-drift.js';
|
|
57
57
|
import { agentMsgResolvableModule } from './modules/agent-msg-resolvable.js';
|
|
58
|
+
import { opaqueStateFlowModule } from './modules/opaque-state-flow.js';
|
|
58
59
|
/**
|
|
59
60
|
* Construct fresh instances of every always-on lint module.
|
|
60
61
|
*
|
|
@@ -107,6 +108,7 @@ export function createLintModules() {
|
|
|
107
108
|
noRepeatedItemCurrentModule(),
|
|
108
109
|
agentEmitsDriftModule(),
|
|
109
110
|
agentMsgResolvableModule(),
|
|
111
|
+
opaqueStateFlowModule(),
|
|
110
112
|
];
|
|
111
113
|
}
|
|
112
114
|
//# sourceMappingURL=lint-modules.js.map
|
package/dist/lint-modules.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lint-modules.js","sourceRoot":"","sources":["../src/lint-modules.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"lint-modules.js","sourceRoot":"","sources":["../src/lint-modules.ts"],"names":[],"mappings":"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","sourcesContent":["// Always-on lint modules.\n//\n// Every entry here is a zero-arg `CompilerModule` factory whose output\n// is registered unconditionally on every `transformLlui` invocation.\n// The function is the single source of truth — `transform.ts`'s active-\n// module list spreads it, and `scripts/generate-rule-docs.ts` calls it\n// to enumerate diagnostic IDs for the rule reference. Adding or removing\n// a rule in one place propagates everywhere.\n//\n// Note: this does NOT include modules with per-file options (e.g.\n// `maskLegendModule({ fieldBits, fieldBitsHi })`, `coreSynthesisModule`,\n// etc.) — those stay constructed inline in `transform.ts` because they\n// take per-file context. The `compilerStampModule` is unconditional but\n// it's an instance-not-factory; appended separately by callers.\n\nimport type { CompilerModule } from './module.js'\nimport { bitmaskOverflowModule } from './modules/bitmask-overflow.js'\nimport { asyncUpdateModule } from './modules/async-update.js'\nimport { mapOnStateArrayModule } from './modules/map-on-state-array.js'\nimport { nestedSendInUpdateModule } from './modules/nested-send-in-update.js'\nimport { directStateInViewModule } from './modules/direct-state-in-view.js'\nimport { imperativeDomInViewModule } from './modules/imperative-dom-in-view.js'\nimport { accessorSideEffectModule } from './modules/accessor-side-effect.js'\nimport { stateMutationModule } from './modules/state-mutation.js'\nimport { effectWithoutHandlerModule } from './modules/effect-without-handler.js'\nimport { exhaustiveEffectHandlingModule } from './modules/exhaustive-effect-handling.js'\nimport { noEagerItemAccessorModule } from './modules/no-eager-item-accessor.js'\nimport { pureUpdateFunctionModule } from './modules/pure-update-function.js'\nimport { exhaustiveUpdateModule } from './modules/exhaustive-update.js'\nimport { noLetReactiveAccessorModule } from './modules/no-let-reactive-accessor.js'\nimport { eachClosureViolationModule } from './modules/each-closure-violation.js'\nimport { stringEffectCallbackModule } from './modules/string-effect-callback.js'\nimport { agentMissingIntentModule } from './modules/agent-missing-intent.js'\nimport { agentWarningOnConfirmModule } from './modules/agent-warning-on-confirm.js'\nimport { agentExampleOnPayloadModule } from './modules/agent-example-on-payload.js'\nimport { agentExclusiveAnnotationsModule } from './modules/agent-exclusive-annotations.js'\nimport { agentOptionalFieldUndocumentedModule } from './modules/agent-optional-field-undocumented.js'\nimport { agentTagsendTranslatorMissingModule } from './modules/agent-tagsend-translator-missing.js'\nimport { agentNonextractableHandlerModule } from './modules/agent-nonextractable-handler.js'\nimport { subappRequiresReasonModule } from './modules/subapp-requires-reason.js'\nimport { emptyPropsModule } from './modules/empty-props.js'\nimport { forgottenSpreadModule } from './modules/forgotten-spread.js'\nimport { accessibilityModule } from './modules/accessibility.js'\nimport { viewBagImportModule } from './modules/view-bag-import.js'\nimport { controlledInputModule } from './modules/controlled-input.js'\nimport { missingMemoModule } from './modules/missing-memo.js'\nimport { namespaceImportModule } from './modules/namespace-import.js'\nimport { noBarrelImportWhenSubpathExistsModule } from './modules/no-barrel-import-when-subpath-exists.js'\nimport { formBoilerplateModule } from './modules/form-boilerplate.js'\nimport { spreadInChildrenModule } from './modules/spread-in-children.js'\nimport { staticItemsModule } from './modules/static-items.js'\nimport { staticOnModule } from './modules/static-on.js'\nimport { noListRenderInSampleModule } from './modules/no-list-render-in-sample.js'\nimport { noSampleInAccessorModule } from './modules/no-sample-in-accessor.js'\nimport { noSampleInReactivePositionModule } from './modules/no-sample-in-reactive-position.js'\nimport { noSampleInEventHandlerModule } from './modules/no-sample-in-event-handler.js'\nimport { noRepeatedItemCurrentModule } from './modules/no-repeated-item-current.js'\nimport { agentEmitsDriftModule } from './modules/agent-emits-drift.js'\nimport { agentMsgResolvableModule } from './modules/agent-msg-resolvable.js'\nimport { opaqueStateFlowModule } from './modules/opaque-state-flow.js'\n\n/**\n * Construct fresh instances of every always-on lint module.\n *\n * Returns a new array per call. Modules are stateful within a single\n * `ModuleRegistry.run()` (slot accumulators), so reusing instances\n * across files would leak state — always call this once per file.\n */\nexport function createLintModules(): CompilerModule[] {\n return [\n bitmaskOverflowModule(),\n asyncUpdateModule(),\n mapOnStateArrayModule(),\n nestedSendInUpdateModule(),\n directStateInViewModule(),\n imperativeDomInViewModule(),\n accessorSideEffectModule(),\n stateMutationModule(),\n effectWithoutHandlerModule(),\n exhaustiveEffectHandlingModule(),\n noEagerItemAccessorModule(),\n pureUpdateFunctionModule(),\n exhaustiveUpdateModule(),\n noLetReactiveAccessorModule(),\n eachClosureViolationModule(),\n stringEffectCallbackModule(),\n agentMissingIntentModule(),\n agentWarningOnConfirmModule(),\n agentExampleOnPayloadModule(),\n agentExclusiveAnnotationsModule(),\n agentOptionalFieldUndocumentedModule(),\n agentTagsendTranslatorMissingModule(),\n agentNonextractableHandlerModule(),\n subappRequiresReasonModule(),\n emptyPropsModule(),\n forgottenSpreadModule(),\n accessibilityModule(),\n viewBagImportModule(),\n controlledInputModule(),\n missingMemoModule(),\n namespaceImportModule(),\n noBarrelImportWhenSubpathExistsModule(),\n formBoilerplateModule(),\n spreadInChildrenModule(),\n staticItemsModule(),\n staticOnModule(),\n noListRenderInSampleModule(),\n noSampleInAccessorModule(),\n noSampleInReactivePositionModule(),\n noSampleInEventHandlerModule(),\n noRepeatedItemCurrentModule(),\n agentEmitsDriftModule(),\n agentMsgResolvableModule(),\n opaqueStateFlowModule(),\n ]\n}\n"]}
|
package/dist/module.d.ts
CHANGED
|
@@ -56,6 +56,17 @@ export interface AnalysisContext {
|
|
|
56
56
|
sourceFile: ts.SourceFile;
|
|
57
57
|
/** TS TypeChecker, when the host adapter has built a Program. May be undefined for AST-only paths. */
|
|
58
58
|
checker: ts.TypeChecker | undefined;
|
|
59
|
+
/**
|
|
60
|
+
* The cross-file Program the checker is bound to, when available.
|
|
61
|
+
* Modules that need to resolve identifiers across files (e.g. the
|
|
62
|
+
* opaque-state-flow lint walking through imported helpers) must walk
|
|
63
|
+
* Program-bound nodes — the file the registry hands them is a
|
|
64
|
+
* locally-reparsed copy and its identifiers won't resolve through the
|
|
65
|
+
* checker. Use `program.getSourceFile(sourceFile.fileName)` to fetch
|
|
66
|
+
* the Program-bound counterpart. Undefined when the host doesn't
|
|
67
|
+
* supply a Program (test path, lint adapters without cross-file).
|
|
68
|
+
*/
|
|
69
|
+
program: ts.Program | undefined;
|
|
59
70
|
/**
|
|
60
71
|
* Get the named module's accumulator slot (creating it lazily). The
|
|
61
72
|
* slot is whatever shape the module wrote; type-safe access is the
|
|
@@ -245,7 +256,7 @@ export declare class ModuleRegistry {
|
|
|
245
256
|
* 4. Emission: each module's `emit?` fires; the registry merges
|
|
246
257
|
* contributions, detecting (field, target) conflicts.
|
|
247
258
|
*/
|
|
248
|
-
run(sourceFile: ts.SourceFile, checker?: ts.TypeChecker, externalTypes?: ModuleExternalTypes): RegistryRunResult;
|
|
259
|
+
run(sourceFile: ts.SourceFile, checker?: ts.TypeChecker, externalTypes?: ModuleExternalTypes, program?: ts.Program): RegistryRunResult;
|
|
249
260
|
/** Module names in declaration order. Adapters surface this for debug logs / config diagnostics. */
|
|
250
261
|
listModules(): string[];
|
|
251
262
|
/** All diagnostic definitions across active modules. Used by adapters to enumerate stable IDs. */
|
package/dist/module.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"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"}
|
package/dist/module.js
CHANGED
|
@@ -79,7 +79,7 @@ export class ModuleRegistry {
|
|
|
79
79
|
* 4. Emission: each module's `emit?` fires; the registry merges
|
|
80
80
|
* contributions, detecting (field, target) conflicts.
|
|
81
81
|
*/
|
|
82
|
-
run(sourceFile, checker, externalTypes) {
|
|
82
|
+
run(sourceFile, checker, externalTypes, program) {
|
|
83
83
|
const analysis = {
|
|
84
84
|
sourceFile,
|
|
85
85
|
perModule: new Map(),
|
|
@@ -101,6 +101,7 @@ export class ModuleRegistry {
|
|
|
101
101
|
const ctx = {
|
|
102
102
|
sourceFile: currentSf,
|
|
103
103
|
checker,
|
|
104
|
+
program,
|
|
104
105
|
getSlot: (name, init) => {
|
|
105
106
|
let slot = analysis.perModule.get(name);
|
|
106
107
|
if (slot === undefined) {
|