unguard 0.5.1 → 0.5.2
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.
|
@@ -84,7 +84,7 @@ var noNullishCoalescing = {
|
|
|
84
84
|
// src/rules/single-file/no-optional-call.ts
|
|
85
85
|
var noOptionalCall = {
|
|
86
86
|
id: "no-optional-call",
|
|
87
|
-
severity: "
|
|
87
|
+
severity: "info",
|
|
88
88
|
message: "Optional call (?.) assumes the function could be undefined; if the type guarantees it exists, call directly; if not, fix the type upstream",
|
|
89
89
|
visit(node, _parent, ctx) {
|
|
90
90
|
if (node.type !== "CallExpression") return;
|
|
@@ -96,7 +96,7 @@ var noOptionalCall = {
|
|
|
96
96
|
// src/rules/single-file/no-optional-property-access.ts
|
|
97
97
|
var noOptionalPropertyAccess = {
|
|
98
98
|
id: "no-optional-property-access",
|
|
99
|
-
severity: "
|
|
99
|
+
severity: "info",
|
|
100
100
|
message: "Optional chaining (?.) assumes the object could be nullish; if the type guarantees it, use a direct access; if not, fix the type upstream",
|
|
101
101
|
visit(node, _parent, ctx) {
|
|
102
102
|
if (node.type !== "MemberExpression") return;
|
|
@@ -109,7 +109,7 @@ var noOptionalPropertyAccess = {
|
|
|
109
109
|
// src/rules/single-file/no-optional-element-access.ts
|
|
110
110
|
var noOptionalElementAccess = {
|
|
111
111
|
id: "no-optional-element-access",
|
|
112
|
-
severity: "
|
|
112
|
+
severity: "info",
|
|
113
113
|
message: "Optional element access (?.[]) assumes the object could be nullish; if the type guarantees it, use a direct access; if not, fix the type upstream",
|
|
114
114
|
visit(node, _parent, ctx) {
|
|
115
115
|
if (node.type !== "MemberExpression") return;
|
|
@@ -1131,4 +1131,4 @@ export {
|
|
|
1131
1131
|
allRules,
|
|
1132
1132
|
scan
|
|
1133
1133
|
};
|
|
1134
|
-
//# sourceMappingURL=chunk-
|
|
1134
|
+
//# sourceMappingURL=chunk-XHJYPS37.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/narrow.ts","../src/rules/single-file/no-empty-catch.ts","../src/rules/single-file/no-non-null-assertion.ts","../src/rules/single-file/no-double-negation-coercion.ts","../src/rules/single-file/no-ts-ignore.ts","../src/rules/single-file/no-nullish-coalescing.ts","../src/rules/single-file/no-optional-call.ts","../src/rules/single-file/no-optional-property-access.ts","../src/rules/single-file/no-optional-element-access.ts","../src/utils/ast.ts","../src/rules/single-file/no-logical-or-fallback.ts","../src/rules/single-file/no-null-ternary-normalization.ts","../src/rules/single-file/no-any-cast.ts","../src/rules/single-file/no-explicit-any-annotation.ts","../src/rules/single-file/no-inline-type-in-params.ts","../src/rules/single-file/no-type-assertion.ts","../src/rules/single-file/no-redundant-existence-guard.ts","../src/rules/single-file/prefer-default-param-value.ts","../src/rules/single-file/prefer-required-param-with-guard.ts","../src/rules/cross-file/duplicate-type-declaration.ts","../src/rules/cross-file/duplicate-function-declaration.ts","../src/rules/cross-file/optional-arg-always-used.ts","../src/rules/single-file/no-catch-return.ts","../src/rules/single-file/no-error-rewrap.ts","../src/rules/cross-file/explicit-null-arg.ts","../src/rules/cross-file/duplicate-function-name.ts","../src/rules/cross-file/duplicate-type-name.ts","../src/rules/single-file/no-dynamic-import.ts","../src/rules/index.ts","../src/engine.ts","../src/rules/types.ts","../src/collect/index.ts","../src/utils/hash.ts","../src/collect/type-registry.ts","../src/collect/function-registry.ts"],"sourcesContent":["/**\n * Runtime node property access helpers.\n *\n * oxc-parser's runtime AST diverges from @oxc-project/types in some areas\n * (e.g., all literals use type \"Literal\" at runtime vs NullLiteral/StringLiteral in types).\n * These helpers provide typed access to common node shapes without `as any` casts.\n */\nimport type { Node } from \"oxc-parser\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- intentional escape hatch for untyped AST access\ntype AnyNode = Record<string, any>;\n\n/** Safely access a property on any AST node. */\nexport function prop<T = unknown>(node: Node, key: string): T {\n return (node as AnyNode)[key] as T;\n}\n\n/** Get child node. Returns Node or null. */\nexport function child(node: Node, key: string): Node | null {\n const val = (node as AnyNode)[key];\n if (val === undefined || val === null) return null;\n return val as Node;\n}\n\n/** Get child nodes array. Returns Node[] or empty. */\nexport function children(node: Node, key: string): Node[] {\n const val = (node as AnyNode)[key];\n if (!Array.isArray(val)) return [];\n return val as Node[];\n}\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\nimport { child, children } from \"../../utils/narrow.ts\";\n\nexport const noEmptyCatch: SingleFileRule = {\n id: \"no-empty-catch\",\n severity: \"error\",\n message: \"Empty catch blocks hide failures; handle, annotate, or rethrow explicitly\",\n\n visit(node: Node, _parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"CatchClause\") return;\n const body = child(node, \"body\");\n if (body && body.type === \"BlockStatement\" && children(body, \"body\").length === 0) {\n const hasComment = ctx.comments.some((c) => c.start >= body.start && c.end <= body.end);\n if (hasComment) return;\n ctx.report(node);\n }\n },\n};\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\n\nexport const noNonNullAssertion: SingleFileRule = {\n id: \"no-non-null-assertion\",\n severity: \"warning\",\n message: \"Non-null assertion (!) overrides the type checker; narrow with a type guard or fix the type so it's not nullable\",\n\n visit(node: Node, _parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"TSNonNullExpression\") return;\n ctx.report(node);\n },\n};\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\nimport { prop, child } from \"../../utils/narrow.ts\";\n\nexport const noDoubleNegationCoercion: SingleFileRule = {\n id: \"no-double-negation-coercion\",\n severity: \"info\",\n message: \"!! coercion hides intent; use an explicit check (!== null, !== undefined, .length > 0) so the condition documents what it tests\",\n\n visit(node: Node, _parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"UnaryExpression\") return;\n if (prop<string>(node, \"operator\") !== \"!\") return;\n const arg = child(node, \"argument\");\n if (arg !== null && arg.type === \"UnaryExpression\" && prop<string>(arg, \"operator\") === \"!\") {\n ctx.report(node);\n }\n },\n};\n","import type { Node, Comment } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\n\nexport const noTsIgnore: SingleFileRule = {\n id: \"no-ts-ignore\",\n severity: \"error\",\n message: \"@ts-ignore / @ts-expect-error suppresses type checking; fix the underlying type issue\",\n\n visit(_node: Node, _parent: Node | null, _ctx: VisitContext) {},\n\n visitComment(comment: Comment, ctx: VisitContext) {\n if (comment.value.includes(\"@ts-ignore\") || comment.value.includes(\"@ts-expect-error\")) {\n ctx.report(comment);\n }\n },\n};\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\nimport { prop } from \"../../utils/narrow.ts\";\n\nexport const noNullishCoalescing: SingleFileRule = {\n id: \"no-nullish-coalescing\",\n severity: \"warning\",\n message: \"Nullish coalescing (??) masks a possibly-nullable type; if the type guarantees non-null, remove the fallback; if not, fix the type upstream\",\n\n visit(node: Node, _parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"LogicalExpression\") return;\n if (prop<string>(node, \"operator\") !== \"??\") return;\n ctx.report(node);\n },\n};\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\nimport { prop } from \"../../utils/narrow.ts\";\n\nexport const noOptionalCall: SingleFileRule = {\n id: \"no-optional-call\",\n severity: \"info\",\n message: \"Optional call (?.) assumes the function could be undefined; if the type guarantees it exists, call directly; if not, fix the type upstream\",\n\n visit(node: Node, _parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"CallExpression\") return;\n if (!prop<boolean>(node, \"optional\")) return;\n ctx.report(node);\n },\n};\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\nimport { prop } from \"../../utils/narrow.ts\";\n\nexport const noOptionalPropertyAccess: SingleFileRule = {\n id: \"no-optional-property-access\",\n severity: \"info\",\n message: \"Optional chaining (?.) assumes the object could be nullish; if the type guarantees it, use a direct access; if not, fix the type upstream\",\n\n visit(node: Node, _parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"MemberExpression\") return;\n if (prop<boolean>(node, \"optional\") && !prop<boolean>(node, \"computed\")) {\n ctx.report(node);\n }\n },\n};\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\nimport { prop } from \"../../utils/narrow.ts\";\n\nexport const noOptionalElementAccess: SingleFileRule = {\n id: \"no-optional-element-access\",\n severity: \"info\",\n message: \"Optional element access (?.[]) assumes the object could be nullish; if the type guarantees it, use a direct access; if not, fix the type upstream\",\n\n visit(node: Node, _parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"MemberExpression\") return;\n if (prop<boolean>(node, \"optional\") && prop<boolean>(node, \"computed\")) {\n ctx.report(node);\n }\n },\n};\n","import type { Node } from \"oxc-parser\";\nimport { prop } from \"./narrow.ts\";\n\n/** Check if a node is null or undefined literal. */\nexport function isNullish(node: Node): boolean {\n if (node.type === \"Literal\" && prop(node, \"value\") === null) return true;\n if (node.type === \"Identifier\" && prop<string>(node, \"name\") === \"undefined\") return true;\n return false;\n}\n\n/** Check if a node is a literal value. */\nexport function isLiteral(node: Node): boolean {\n switch (node.type) {\n case \"Literal\":\n case \"TemplateLiteral\":\n case \"ArrayExpression\":\n case \"ObjectExpression\":\n return true;\n case \"Identifier\":\n return prop<string>(node, \"name\") === \"undefined\";\n default:\n return false;\n }\n}\n\n/** Get source text for a node using its span. */\nexport function getNodeText(source: string, node: Node): string {\n return source.slice(node.start, node.end);\n}\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\nimport { prop, child } from \"../../utils/narrow.ts\";\nimport { isLiteral } from \"../../utils/ast.ts\";\n\nexport const noLogicalOrFallback: SingleFileRule = {\n id: \"no-logical-or-fallback\",\n severity: \"warning\",\n message: \"|| with a literal fallback assumes the left side could be falsy; if the type guarantees a value, remove the fallback; if not, fix the type upstream\",\n\n visit(node: Node, _parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"LogicalExpression\") return;\n if (prop<string>(node, \"operator\") !== \"||\") return;\n const right = child(node, \"right\");\n if (right && isLiteral(right)) {\n ctx.report(node);\n }\n },\n};\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\nimport { prop, child } from \"../../utils/narrow.ts\";\nimport { isNullish } from \"../../utils/ast.ts\";\n\nexport const noNullTernaryNormalization: SingleFileRule = {\n id: \"no-null-ternary-normalization\",\n severity: \"warning\",\n message: \"Ternary null-normalization (x == null ? fallback : x); if the type guarantees non-null, remove the ternary; if not, fix the type upstream\",\n\n visit(node: Node, _parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"ConditionalExpression\") return;\n const test = child(node, \"test\");\n if (test === null || test.type !== \"BinaryExpression\") return;\n const op = prop<string>(test, \"operator\");\n if (op !== \"===\" && op !== \"!==\" && op !== \"==\" && op !== \"!=\") return;\n const testLeft = child(test, \"left\");\n const testRight = child(test, \"right\");\n const hasNullishComparand =\n (testLeft !== null && isNullish(testLeft)) || (testRight !== null && isNullish(testRight));\n if (!hasNullishComparand) return;\n const consequent = child(node, \"consequent\");\n const alternate = child(node, \"alternate\");\n if ((consequent !== null && isNullish(consequent)) || (alternate !== null && isNullish(alternate))) {\n ctx.report(node);\n }\n },\n};\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\nimport { child } from \"../../utils/narrow.ts\";\n\nexport const noAnyCast: SingleFileRule = {\n id: \"no-any-cast\",\n severity: \"error\",\n message: \"Casting to `any` erases type safety; use a specific type or generic instead\",\n\n visit(node: Node, _parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"TSAsExpression\") return;\n const typeAnno = child(node, \"typeAnnotation\");\n if (typeAnno !== null && typeAnno.type === \"TSAnyKeyword\") {\n ctx.report(node);\n }\n },\n};\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\n\nexport const noExplicitAnyAnnotation: SingleFileRule = {\n id: \"no-explicit-any-annotation\",\n severity: \"warning\",\n message: \"Explicit `any` annotation erases type safety; use a specific type, `unknown`, or a generic\",\n\n visit(node: Node, parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"TSAnyKeyword\") return;\n // Skip if inside a cast (covered by no-any-cast)\n if (parent !== null && parent.type === \"TSAsExpression\") return;\n ctx.report(node);\n },\n};\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\n\nexport const noInlineTypeInParams: SingleFileRule = {\n id: \"no-inline-type-in-params\",\n severity: \"warning\",\n message: \"Inline type literal in annotation; extract to a named type for reuse and clarity\",\n\n visit(node: Node, parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"TSTypeLiteral\") return;\n if (parent === null || parent.type !== \"TSTypeAnnotation\") return;\n\n if (!isTopLevelFunctionParam(ctx.source, node.start)) return;\n\n ctx.report(node);\n },\n};\n\nfunction isTopLevelFunctionParam(source: string, offset: number): boolean {\n // Only flag if the nearest enclosing \"{\" is the module scope (no enclosing brace)\n // or a plain function body. Skip anything nested inside classes, interfaces,\n // object literals (builder patterns), etc.\n let depth = 0;\n for (let i = offset - 1; i >= 0; i--) {\n if (source[i] === \"}\") depth++;\n if (source[i] === \"{\") {\n if (depth === 0) {\n // Found the enclosing \"{\". If it belongs to a function declaration\n // or arrow, that's fine (we're in a nested function param). But if\n // it's anything else (class, interface, object literal), skip.\n // In practice: only flag when there's NO enclosing \"{\" at all\n // (module-level function), or the enclosing block is a function body.\n const before = source.slice(Math.max(0, i - 150), i).trimEnd();\n // Function body: preceded by \")\" or \"=> {\" or similar\n if (/(\\)|\\bfunction\\b.*\\))\\s*$/.test(before)) {\n // Inside a function body — keep walking to check if that function\n // is itself top-level or nested\n depth--;\n continue;\n }\n // Anything else (class, interface, object, etc.) — not top-level\n return false;\n }\n depth--;\n }\n }\n // Reached beginning of file with no unmatched \"{\" — module scope\n return true;\n}\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\nimport { child } from \"../../utils/narrow.ts\";\n\nexport const noTypeAssertion: SingleFileRule = {\n id: \"no-type-assertion\",\n severity: \"error\",\n message: \"Double type assertion (`as unknown as T`) circumvents the type system; fix the upstream type or use a type guard\",\n\n visit(node: Node, _parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"TSAsExpression\") return;\n // Check if the expression being cast is itself an `as unknown`\n const inner = child(node, \"expression\");\n if (inner === null || inner.type !== \"TSAsExpression\") return;\n const innerType = child(inner, \"typeAnnotation\");\n if (innerType === null || innerType.type !== \"TSUnknownKeyword\") return;\n ctx.report(node);\n },\n};\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\nimport { child, prop } from \"../../utils/narrow.ts\";\n\nexport const noRedundantExistenceGuard: SingleFileRule = {\n id: \"no-redundant-existence-guard\",\n severity: \"warning\",\n message: \"Redundant existence guard (obj && obj.prop); if the type guarantees obj exists, remove the guard; if not, fix the type upstream\",\n\n visit(node: Node, _parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"IfStatement\") return;\n const test = child(node, \"test\");\n if (!test || test.type !== \"LogicalExpression\" || prop<string>(test, \"operator\") !== \"&&\") return;\n\n const left = child(test, \"left\");\n const right = child(test, \"right\");\n if (!left || left.type !== \"Identifier\") return;\n if (!right || right.type !== \"MemberExpression\") return;\n const obj = child(right, \"object\");\n if (!obj || obj.type !== \"Identifier\") return;\n if (prop<string>(left, \"name\") !== prop<string>(obj, \"name\")) return;\n ctx.report(node);\n },\n};\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\nimport { prop, child, children } from \"../../utils/narrow.ts\";\n\nexport const preferDefaultParamValue: SingleFileRule = {\n id: \"prefer-default-param-value\",\n severity: \"info\",\n message: \"Use a default parameter value instead of reassigning from nullish coalescing inside the body\",\n\n visit(node: Node, _parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"FunctionDeclaration\" && node.type !== \"ArrowFunctionExpression\") return;\n const params = children(node, \"params\");\n const body = child(node, \"body\");\n if (body === null || body.type !== \"BlockStatement\") return;\n const stmts = children(body, \"body\");\n if (stmts.length === 0) return;\n\n const firstStmt = stmts[0];\n if (firstStmt.type !== \"ExpressionStatement\") return;\n const expr = child(firstStmt, \"expression\");\n if (expr === null || expr.type !== \"AssignmentExpression\" || prop<string>(expr, \"operator\") !== \"=\") return;\n\n const right = child(expr, \"right\");\n if (right === null || right.type !== \"LogicalExpression\" || prop<string>(right, \"operator\") !== \"??\") return;\n\n const assignee = child(expr, \"left\");\n const coalescedLeft = child(right, \"left\");\n if (assignee === null || assignee.type !== \"Identifier\") return;\n if (coalescedLeft === null || coalescedLeft.type !== \"Identifier\") return;\n if (prop<string>(assignee, \"name\") !== prop<string>(coalescedLeft, \"name\")) return;\n\n const assigneeName = prop<string>(assignee, \"name\");\n const isParam = params.some((p: Node) => {\n if (p.type === \"Identifier\") return prop<string>(p, \"name\") === assigneeName;\n if (p.type === \"AssignmentPattern\") {\n const left = child(p, \"left\");\n return left !== null && left.type === \"Identifier\" && prop<string>(left, \"name\") === assigneeName;\n }\n return false;\n });\n if (isParam) {\n ctx.report(firstStmt);\n }\n },\n};\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\nimport { prop, child, children } from \"../../utils/narrow.ts\";\n\nexport const preferRequiredParamWithGuard: SingleFileRule = {\n id: \"prefer-required-param-with-guard\",\n severity: \"info\",\n message: \"Optional param with immediate guard (if (!param) return/throw); make it required instead\",\n\n visit(node: Node, _parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"FunctionDeclaration\" && node.type !== \"ArrowFunctionExpression\") return;\n const params = children(node, \"params\");\n const body = child(node, \"body\");\n if (body === null || body.type !== \"BlockStatement\") return;\n const stmts = children(body, \"body\");\n if (stmts.length === 0) return;\n\n const firstStmt = stmts[0];\n if (firstStmt.type !== \"IfStatement\") return;\n\n const test = child(firstStmt, \"test\");\n if (test === null) return;\n let guardedName: string | null = null;\n\n // Pattern 1: if (!param)\n if (test.type === \"UnaryExpression\" && prop<string>(test, \"operator\") === \"!\") {\n const arg = child(test, \"argument\");\n if (arg !== null && arg.type === \"Identifier\") guardedName = prop<string>(arg, \"name\");\n }\n // Pattern 2: if (param === undefined)\n if (test.type === \"BinaryExpression\") {\n const op = prop<string>(test, \"operator\");\n if (op === \"===\" || op === \"==\") {\n const left = child(test, \"left\");\n const right = child(test, \"right\");\n if (\n left !== null &&\n left.type === \"Identifier\" &&\n right !== null &&\n right.type === \"Identifier\" &&\n prop<string>(right, \"name\") === \"undefined\"\n ) {\n guardedName = prop<string>(left, \"name\");\n }\n }\n }\n\n if (guardedName === null) return;\n\n const consequent = child(firstStmt, \"consequent\");\n if (consequent === null) return;\n const isGuard =\n consequent.type === \"ReturnStatement\" ||\n consequent.type === \"ThrowStatement\" ||\n (consequent.type === \"BlockStatement\" && isGuardBlock(consequent));\n\n if (!isGuard) return;\n\n const isOptionalParam = params.some(\n (p: Node) => p.type === \"Identifier\" && prop<string>(p, \"name\") === guardedName && prop<boolean>(p, \"optional\") === true,\n );\n if (isOptionalParam) {\n ctx.report(firstStmt);\n }\n },\n};\n\nfunction isGuardBlock(block: Node): boolean {\n const body = children(block, \"body\");\n if (body.length !== 1) return false;\n const stmt = body[0];\n return stmt.type === \"ReturnStatement\" || stmt.type === \"ThrowStatement\";\n}\n","import type { CrossFileRule, Diagnostic, ProjectIndex } from \"../types.ts\";\n\nexport const duplicateTypeDeclaration: CrossFileRule = {\n id: \"duplicate-type-declaration\",\n severity: \"warning\",\n message: \"Identical type shape declared in multiple files; consolidate to a single definition\",\n\n analyze(project: ProjectIndex): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n for (const group of project.types.getDuplicateGroups()) {\n // Only flag if types are in different files\n const files = new Set(group.map((e) => e.file));\n if (files.size < 2) continue;\n\n for (const entry of group) {\n const others = group\n .filter((e) => e !== entry)\n .map((e) => `${e.name} (${e.file}:${e.line})`)\n .join(\", \");\n diagnostics.push({\n ruleId: this.id,\n severity: this.severity,\n message: `Type \"${entry.name}\" has identical shape to: ${others}`,\n file: entry.file,\n line: entry.line,\n column: 1,\n });\n }\n }\n return diagnostics;\n },\n};\n","import type { CrossFileRule, Diagnostic, ProjectIndex } from \"../types.ts\";\n\nexport const duplicateFunctionDeclaration: CrossFileRule = {\n id: \"duplicate-function-declaration\",\n severity: \"warning\",\n message: \"Identical function body declared in multiple files; consolidate to a single definition\",\n\n analyze(project: ProjectIndex): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n for (const group of project.functions.getDuplicateGroups()) {\n const files = new Set(group.map((e) => e.file));\n if (files.size < 2) continue;\n\n for (const entry of group) {\n const others = group\n .filter((e) => e !== entry)\n .map((e) => `${e.name} (${e.file}:${e.line})`)\n .join(\", \");\n diagnostics.push({\n ruleId: this.id,\n severity: this.severity,\n message: `Function \"${entry.name}\" has identical body to: ${others}`,\n file: entry.file,\n line: entry.line,\n column: 1,\n });\n }\n }\n return diagnostics;\n },\n};\n","import type { CrossFileRule, Diagnostic, ProjectIndex } from \"../types.ts\";\n\nexport const optionalArgAlwaysUsed: CrossFileRule = {\n id: \"optional-arg-always-used\",\n severity: \"warning\",\n message: \"Optional parameter is always provided at every call site; make it required\",\n\n analyze(project: ProjectIndex): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n\n for (const fn of project.functions.getAll()) {\n // Find optional params (by index)\n for (let i = 0; i < fn.params.length; i++) {\n const param = fn.params[i];\n if (!param.optional && !param.hasDefault) continue;\n\n // Find all call sites matching this function name\n const callSites = project.callSites.filter((c) => c.calleeName === fn.name);\n\n // Need at least 2 call sites to be meaningful\n if (callSites.length < 2) continue;\n\n // Check if every call site provides this positional argument\n const allProvide = callSites.every((c) => c.argCount > i);\n if (allProvide) {\n diagnostics.push({\n ruleId: this.id,\n severity: this.severity,\n message: `Optional parameter \"${param.name}\" is always provided at all ${callSites.length} call sites; make it required`,\n file: fn.file,\n line: fn.line,\n column: 1,\n });\n }\n }\n }\n\n return diagnostics;\n },\n};\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\nimport { child, prop } from \"../../utils/narrow.ts\";\n\nexport const noCatchReturn: SingleFileRule = {\n id: \"no-catch-return\",\n severity: \"warning\",\n message:\n \"Catch block returns a fallback value, forcing callers to handle two data shapes; rethrow or let the error propagate\",\n\n visit(node: Node, _parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"CatchClause\") return;\n const body = child(node, \"body\");\n if (body === null) return;\n if (hasReturn(body) && !hasThrow(body)) {\n ctx.report(node);\n }\n },\n};\n\nfunction hasReturn(block: Node): boolean {\n return walkForType(block, \"ReturnStatement\");\n}\n\nfunction hasThrow(block: Node): boolean {\n return walkForType(block, \"ThrowStatement\");\n}\n\nfunction walkForType(root: Node, targetType: string): boolean {\n if (root.type === targetType) return true;\n const keys = Object.keys(root);\n for (const key of keys) {\n if (key === \"start\" || key === \"end\" || key === \"type\") continue;\n const val = prop<unknown>(root, key);\n if (val === null || val === undefined || typeof val !== \"object\") continue;\n // Skip nested function scopes — their returns/throws are their own\n if (isFunction(val as Node)) continue;\n if (Array.isArray(val)) {\n for (const item of val) {\n if (item !== null && typeof item === \"object\" && \"type\" in item) {\n if (isFunction(item as Node)) continue;\n if (walkForType(item as Node, targetType)) return true;\n }\n }\n } else if (\"type\" in val) {\n if (walkForType(val as Node, targetType)) return true;\n }\n }\n return false;\n}\n\nfunction isFunction(node: Node): boolean {\n return (\n node.type === \"FunctionDeclaration\" ||\n node.type === \"FunctionExpression\" ||\n node.type === \"ArrowFunctionExpression\"\n );\n}\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\nimport { prop, child, children } from \"../../utils/narrow.ts\";\n\nexport const noErrorRewrap: SingleFileRule = {\n id: \"no-error-rewrap\",\n severity: \"error\",\n message:\n \"Re-wrapped error loses the original stack trace and type; use { cause: originalError } to preserve the error chain\",\n\n visit(node: Node, _parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"CatchClause\") return;\n const param = child(node, \"param\");\n if (param === null || param.type !== \"Identifier\") return;\n const catchName = prop<string>(param, \"name\");\n const body = child(node, \"body\");\n if (body === null) return;\n findRewraps(body, catchName, ctx);\n },\n};\n\nfunction findRewraps(root: Node, catchName: string, ctx: VisitContext): void {\n if (root.type === \"ThrowStatement\") {\n const arg = child(root, \"argument\");\n if (arg !== null && arg.type === \"NewExpression\") {\n const args = children(arg, \"arguments\");\n if (args.length > 0 && referencesName(args, catchName) && !hasCauseArg(args)) {\n ctx.report(root);\n }\n }\n return;\n }\n // Skip nested function scopes\n if (\n root.type === \"FunctionDeclaration\" ||\n root.type === \"FunctionExpression\" ||\n root.type === \"ArrowFunctionExpression\"\n ) {\n return;\n }\n const keys = Object.keys(root);\n for (const key of keys) {\n if (key === \"start\" || key === \"end\" || key === \"type\") continue;\n const val = prop<unknown>(root, key);\n if (val === null || val === undefined || typeof val !== \"object\") continue;\n if (Array.isArray(val)) {\n for (const item of val) {\n if (item !== null && typeof item === \"object\" && \"type\" in item) {\n findRewraps(item as Node, catchName, ctx);\n }\n }\n } else if (\"type\" in val) {\n findRewraps(val as Node, catchName, ctx);\n }\n }\n}\n\nfunction referencesName(nodes: Node[], name: string): boolean {\n for (const node of nodes) {\n if (containsIdentifier(node, name)) return true;\n }\n return false;\n}\n\nfunction containsIdentifier(root: Node, name: string): boolean {\n if (root.type === \"Identifier\" && prop<string>(root, \"name\") === name) return true;\n const keys = Object.keys(root);\n for (const key of keys) {\n if (key === \"start\" || key === \"end\" || key === \"type\") continue;\n const val = prop<unknown>(root, key);\n if (val === null || val === undefined || typeof val !== \"object\") continue;\n if (Array.isArray(val)) {\n for (const item of val) {\n if (item !== null && typeof item === \"object\" && \"type\" in item) {\n if (containsIdentifier(item as Node, name)) return true;\n }\n }\n } else if (\"type\" in val) {\n if (containsIdentifier(val as Node, name)) return true;\n }\n }\n return false;\n}\n\nfunction hasCauseArg(args: Node[]): boolean {\n for (const arg of args) {\n if (arg.type === \"ObjectExpression\") {\n const props = children(arg, \"properties\");\n for (const p of props) {\n const key = child(p, \"key\");\n if (key !== null && key.type === \"Identifier\" && prop<string>(key, \"name\") === \"cause\") {\n return true;\n }\n }\n }\n }\n return false;\n}\n","import type { CrossFileRule, Diagnostic, ProjectIndex } from \"../types.ts\";\nimport { children } from \"../../utils/narrow.ts\";\nimport { isNullish } from \"../../utils/ast.ts\";\n\nexport const explicitNullArg: CrossFileRule = {\n id: \"explicit-null-arg\",\n severity: \"warning\",\n message: \"Explicit null/undefined passed to a project function; consider redesigning the interface to not accept nullish values\",\n\n analyze(project: ProjectIndex): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n\n // Build a set of known project function names for fast lookup\n const projectFnNames = new Set<string>();\n for (const fn of project.functions.getAll()) {\n projectFnNames.add(fn.name);\n }\n\n for (const site of project.callSites) {\n // Only flag calls to functions defined in the project\n if (!projectFnNames.has(site.calleeName)) continue;\n\n const args = children(site.node, \"arguments\");\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (arg === undefined) continue;\n if (isNullish(arg)) {\n const val = arg.type === \"Literal\" ? \"null\" : \"undefined\";\n diagnostics.push({\n ruleId: this.id,\n severity: this.severity,\n message: `Passing explicit ${val} to \"${site.calleeName}\" at argument ${i + 1}; consider redesigning the interface to not accept nullish values`,\n file: site.file,\n line: site.line,\n column: 1,\n });\n break; // one diagnostic per call site\n }\n }\n }\n\n return diagnostics;\n },\n};\n","import type { CrossFileRule, Diagnostic, ProjectIndex } from \"../types.ts\";\n\nexport const duplicateFunctionName: CrossFileRule = {\n id: \"duplicate-function-name\",\n severity: \"warning\",\n message: \"Same function name exported from multiple files; consolidate or rename to avoid ambiguity\",\n\n analyze(project: ProjectIndex): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n for (const group of project.functions.getNameCollisionGroups()) {\n // Skip groups already caught by duplicate-function-declaration (identical bodies)\n const hashes = new Set(group.map((e) => e.hash));\n if (hashes.size === 1) continue;\n\n for (const entry of group) {\n const others = group\n .filter((e) => e !== entry)\n .map((e) => `${e.file}:${e.line}`)\n .join(\", \");\n diagnostics.push({\n ruleId: this.id,\n severity: this.severity,\n message: `Exported function \"${entry.name}\" also defined in: ${others}`,\n file: entry.file,\n line: entry.line,\n column: 1,\n });\n }\n }\n return diagnostics;\n },\n};\n","import type { CrossFileRule, Diagnostic, ProjectIndex } from \"../types.ts\";\n\nexport const duplicateTypeName: CrossFileRule = {\n id: \"duplicate-type-name\",\n severity: \"warning\",\n message: \"Same type name exported from multiple files; consolidate or rename to avoid ambiguity\",\n\n analyze(project: ProjectIndex): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n for (const group of project.types.getNameCollisionGroups()) {\n // Skip groups already caught by duplicate-type-declaration (identical shapes)\n const hashes = new Set(group.map((e) => e.hash));\n if (hashes.size === 1) continue;\n\n for (const entry of group) {\n const others = group\n .filter((e) => e !== entry)\n .map((e) => `${e.file}:${e.line}`)\n .join(\", \");\n diagnostics.push({\n ruleId: this.id,\n severity: this.severity,\n message: `Exported type \"${entry.name}\" also defined in: ${others}`,\n file: entry.file,\n line: entry.line,\n column: 1,\n });\n }\n }\n return diagnostics;\n },\n};\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\n\nexport const noDynamicImport: SingleFileRule = {\n id: \"no-dynamic-import\",\n severity: \"error\",\n message: \"Dynamic import() breaks static analysis and hides dependencies; use a static import instead\",\n\n visit(node: Node, _parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"ImportExpression\") return;\n ctx.report(node);\n },\n};\n","import type { Rule } from \"./types.ts\";\n\nimport { noEmptyCatch } from \"./single-file/no-empty-catch.ts\";\nimport { noNonNullAssertion } from \"./single-file/no-non-null-assertion.ts\";\nimport { noDoubleNegationCoercion } from \"./single-file/no-double-negation-coercion.ts\";\nimport { noTsIgnore } from \"./single-file/no-ts-ignore.ts\";\nimport { noNullishCoalescing } from \"./single-file/no-nullish-coalescing.ts\";\nimport { noOptionalCall } from \"./single-file/no-optional-call.ts\";\nimport { noOptionalPropertyAccess } from \"./single-file/no-optional-property-access.ts\";\nimport { noOptionalElementAccess } from \"./single-file/no-optional-element-access.ts\";\nimport { noLogicalOrFallback } from \"./single-file/no-logical-or-fallback.ts\";\nimport { noNullTernaryNormalization } from \"./single-file/no-null-ternary-normalization.ts\";\nimport { noAnyCast } from \"./single-file/no-any-cast.ts\";\nimport { noExplicitAnyAnnotation } from \"./single-file/no-explicit-any-annotation.ts\";\nimport { noInlineTypeInParams } from \"./single-file/no-inline-type-in-params.ts\";\nimport { noTypeAssertion } from \"./single-file/no-type-assertion.ts\";\nimport { noRedundantExistenceGuard } from \"./single-file/no-redundant-existence-guard.ts\";\nimport { preferDefaultParamValue } from \"./single-file/prefer-default-param-value.ts\";\nimport { preferRequiredParamWithGuard } from \"./single-file/prefer-required-param-with-guard.ts\";\nimport { duplicateTypeDeclaration } from \"./cross-file/duplicate-type-declaration.ts\";\nimport { duplicateFunctionDeclaration } from \"./cross-file/duplicate-function-declaration.ts\";\nimport { optionalArgAlwaysUsed } from \"./cross-file/optional-arg-always-used.ts\";\nimport { noCatchReturn } from \"./single-file/no-catch-return.ts\";\nimport { noErrorRewrap } from \"./single-file/no-error-rewrap.ts\";\nimport { explicitNullArg } from \"./cross-file/explicit-null-arg.ts\";\nimport { duplicateFunctionName } from \"./cross-file/duplicate-function-name.ts\";\nimport { duplicateTypeName } from \"./cross-file/duplicate-type-name.ts\";\nimport { noDynamicImport } from \"./single-file/no-dynamic-import.ts\";\n\nexport const allRules: Rule[] = [\n noEmptyCatch,\n noNonNullAssertion,\n noDoubleNegationCoercion,\n noTsIgnore,\n noNullishCoalescing,\n noOptionalCall,\n noOptionalPropertyAccess,\n noOptionalElementAccess,\n noLogicalOrFallback,\n noNullTernaryNormalization,\n noAnyCast,\n noExplicitAnyAnnotation,\n noInlineTypeInParams,\n noTypeAssertion,\n noRedundantExistenceGuard,\n preferDefaultParamValue,\n preferRequiredParamWithGuard,\n duplicateTypeDeclaration,\n duplicateFunctionDeclaration,\n optionalArgAlwaysUsed,\n noCatchReturn,\n noErrorRewrap,\n explicitNullArg,\n duplicateFunctionName,\n duplicateTypeName,\n noDynamicImport,\n];\n","import { parseSync, type Comment } from \"oxc-parser\";\nimport { walk } from \"oxc-walker\";\nimport fg from \"fast-glob\";\nimport { readFileSync } from \"node:fs\";\nimport type { Node } from \"oxc-parser\";\nimport type { Diagnostic, SingleFileRule, CrossFileRule, Span, VisitContext } from \"./rules/types.ts\";\nimport { allRules } from \"./rules/index.ts\";\nimport { isSingleFileRule } from \"./rules/types.ts\";\nimport { collectProject } from \"./collect/index.ts\";\n\nexport interface ScanOptions {\n paths: string[];\n strict?: boolean;\n rules?: string[];\n}\n\nexport interface ScanResult {\n diagnostics: Diagnostic[];\n fileCount: number;\n}\n\nexport async function scan(options: ScanOptions): Promise<ScanResult> {\n const patterns = options.paths.length > 0 ? options.paths : [\".\"];\n const globs = patterns.map((p) => {\n if (p === \".\") return `./**/*.{ts,cts,mts,tsx}`;\n if (p.endsWith(\"/\")) return `${p}**/*.{ts,cts,mts,tsx}`;\n if (!p.includes(\"*\") && !p.endsWith(\".ts\") && !p.endsWith(\".tsx\") && !p.endsWith(\".cts\") && !p.endsWith(\".mts\")) {\n return `${p}/**/*.{ts,cts,mts,tsx}`;\n }\n return p;\n });\n\n const files = await fg(globs, {\n ignore: [\"**/node_modules/**\", \"**/dist/**\", \"**/.git/**\", \"**/*.d.ts\", \"**/*.d.cts\", \"**/*.d.mts\"],\n absolute: true,\n });\n\n const activeRules = allRules.filter((r) => {\n if (options.rules && !options.rules.includes(r.id)) return false;\n return true;\n });\n\n const singleFileRules = activeRules.filter(isSingleFileRule);\n const crossFileRules = activeRules.filter((r): r is CrossFileRule => !isSingleFileRule(r));\n const diagnostics: Diagnostic[] = [];\n\n // Single-file pass: parse each file and run visitor rules\n for (const file of files) {\n const source = readFileSync(file, \"utf8\");\n const result = parseSync(file, source);\n const fileDiags = runSingleFileRules(singleFileRules, result.program, result.comments, source, file);\n annotate(fileDiags, result.comments, source);\n diagnostics.push(...fileDiags);\n }\n\n // Cross-file pass: collect project index and run analysis rules\n if (crossFileRules.length > 0 && files.length > 0) {\n const projectIndex = collectProject(files);\n for (const rule of crossFileRules) {\n const crossDiags = rule.analyze(projectIndex);\n for (const d of crossDiags) {\n const fileData = projectIndex.files.get(d.file);\n if (fileData !== undefined) annotate([d], fileData.comments, fileData.source);\n }\n diagnostics.push(...crossDiags);\n }\n }\n\n const seen = new Set<string>();\n const deduped: Diagnostic[] = [];\n for (const d of diagnostics) {\n const key = `${d.file}:${d.line}:${d.ruleId}`;\n if (seen.has(key)) continue;\n seen.add(key);\n deduped.push(d);\n }\n\n if (options.strict) {\n for (const d of deduped) {\n d.severity = \"error\";\n }\n }\n\n return { diagnostics: deduped, fileCount: files.length };\n}\n\nexport function runSingleFileRules(\n rules: SingleFileRule[],\n program: Node,\n comments: Comment[],\n source: string,\n filename: string,\n): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n\n const makeCtx = (rule: SingleFileRule): VisitContext => ({\n filename,\n source,\n comments,\n report(span: Span, message?: string) {\n const pos = lineCol(source, span.start);\n diagnostics.push({\n ruleId: rule.id,\n severity: rule.severity,\n message: message === undefined ? rule.message : message,\n file: filename,\n ...pos,\n });\n },\n });\n\n const contexts = rules.map((r) => ({ rule: r, ctx: makeCtx(r) }));\n\n walk(program, {\n enter(node: Node, parent: Node | null) {\n for (const { rule, ctx } of contexts) {\n rule.visit(node, parent, ctx);\n }\n },\n });\n\n for (const { rule, ctx } of contexts) {\n if (rule.visitComment) {\n for (const comment of comments) {\n rule.visitComment(comment, ctx);\n }\n }\n }\n\n return diagnostics;\n}\n\ninterface Position {\n line: number;\n column: number;\n}\n\n/**\n * Attach annotations from comments to diagnostics.\n * A comment annotates a diagnostic if it ends on the line immediately above.\n * Consecutive line comments are joined into a single annotation.\n */\nfunction annotate(diagnostics: Diagnostic[], comments: Comment[], source: string): void {\n if (comments.length === 0 || diagnostics.length === 0) return;\n\n // Build a map: endLine -> comment\n const byEndLine = new Map<number, Comment[]>();\n for (const c of comments) {\n const endLine = lineAt(source, c.end);\n let list = byEndLine.get(endLine);\n if (list === undefined) {\n list = [];\n byEndLine.set(endLine, list);\n }\n list.push(c);\n }\n\n for (const d of diagnostics) {\n // Check inline comment on the same line first\n const inline = findInlineComment(d.line, byEndLine);\n if (inline !== null) {\n d.annotation = inline;\n continue;\n }\n // Then check comment(s) on the line above\n const above = collectAnnotation(d.line - 1, byEndLine, source);\n if (above !== null) d.annotation = above;\n }\n}\n\nfunction findInlineComment(diagLine: number, byEndLine: Map<number, Comment[]>): string | null {\n const commentsOnLine = byEndLine.get(diagLine);\n if (commentsOnLine === undefined || commentsOnLine.length === 0) return null;\n const comment = commentsOnLine.at(-1);\n if (comment === undefined) return null;\n // Only line comments (// ...) count as inline annotations, not block comments\n if (comment.type !== \"Line\") return null;\n const text = comment.value.trim();\n // Skip @expect annotations — those are for the test harness, not user annotations\n if (text.startsWith(\"@expect\")) return null;\n return text;\n}\n\nfunction collectAnnotation(\n commentEndLine: number,\n byEndLine: Map<number, Comment[]>,\n source: string,\n): string | null {\n const commentsOnLine = byEndLine.get(commentEndLine);\n if (commentsOnLine === undefined || commentsOnLine.length === 0) return null;\n const comment = commentsOnLine.at(-1);\n if (comment === undefined) return null;\n\n // Block comment: use its value directly\n if (comment.type === \"Block\") {\n return cleanBlockComment(comment.value);\n }\n\n // Line comment: walk upward to collect consecutive line comments\n const lines: string[] = [comment.value.trim()];\n let prevLine = commentEndLine - 1;\n for (;;) {\n const prev = byEndLine.get(prevLine);\n if (prev === undefined || prev.length === 0) break;\n const prevComment = prev.at(-1);\n if (prevComment === undefined || prevComment.type !== \"Line\") break;\n if (lineAt(source, prevComment.start) !== prevLine) break;\n lines.unshift(prevComment.value.trim());\n prevLine--;\n }\n\n return lines.join(\"\\n\");\n}\n\nfunction cleanBlockComment(value: string): string {\n return value\n .split(\"\\n\")\n .map((line) => line.replace(/^\\s*\\*\\s?/, \"\").trim())\n .filter((line) => line.length > 0)\n .join(\"\\n\");\n}\n\nfunction lineAt(source: string, offset: number): number {\n let line = 1;\n for (let i = 0; i < offset && i < source.length; i++) {\n if (source[i] === \"\\n\") line++;\n }\n return line;\n}\n\nfunction lineCol(source: string, offset: number): Position {\n let line = 1;\n let col = 1;\n for (let i = 0; i < offset && i < source.length; i++) {\n if (source[i] === \"\\n\") {\n line++;\n col = 1;\n } else {\n col++;\n }\n }\n return { line, column: col };\n}\n","import type { Node, Comment } from \"oxc-parser\";\n\nexport interface Diagnostic {\n ruleId: string;\n severity: \"info\" | \"warning\" | \"error\";\n message: string;\n file: string;\n line: number;\n column: number;\n annotation?: string;\n}\n\nexport interface Span {\n start: number;\n end: number;\n}\n\nexport interface VisitContext {\n report(span: Span, message?: string): void;\n filename: string;\n source: string;\n comments: Comment[];\n}\n\nexport interface SingleFileRule {\n id: string;\n severity: \"info\" | \"warning\" | \"error\";\n message: string;\n visit(node: Node, parent: Node | null, ctx: VisitContext): void;\n visitComment?(comment: Comment, ctx: VisitContext): void;\n}\n\nimport type { ProjectIndex } from \"../collect/index.ts\";\nexport type { ProjectIndex };\n\nexport interface CrossFileRule {\n id: string;\n severity: \"info\" | \"warning\" | \"error\";\n message: string;\n analyze(project: ProjectIndex): Diagnostic[];\n}\n\nexport type Rule = SingleFileRule | CrossFileRule;\n\nexport function isSingleFileRule(r: Rule): r is SingleFileRule {\n return \"visit\" in r;\n}\n","import { parseSync, type Comment } from \"oxc-parser\";\nimport { walk } from \"oxc-walker\";\nimport { readFileSync } from \"node:fs\";\nimport type { Node } from \"oxc-parser\";\nimport { TypeRegistry } from \"./type-registry.ts\";\nimport { FunctionRegistry, type FunctionEntry, type ParamInfo } from \"./function-registry.ts\";\nimport { hashFunctionBody } from \"../utils/hash.ts\";\nimport { prop, child, children } from \"../utils/narrow.ts\";\n\nexport interface ProjectIndex {\n types: TypeRegistry;\n functions: FunctionRegistry;\n callSites: CallSite[];\n files: Map<string, { source: string; program: Node; comments: Comment[] }>;\n}\n\nexport interface CallSite {\n calleeName: string;\n file: string;\n line: number;\n argCount: number;\n node: Node;\n}\n\nexport function collectProject(files: string[]): ProjectIndex {\n const types = new TypeRegistry();\n const functions = new FunctionRegistry();\n const callSites: CallSite[] = [];\n const fileMap = new Map<string, { source: string; program: Node; comments: Comment[] }>();\n\n for (const file of files) {\n const source = readFileSync(file, \"utf8\");\n const result = parseSync(file, source);\n fileMap.set(file, { source, program: result.program, comments: result.comments });\n\n walk(result.program, {\n enter(node: Node, parent: Node | null) {\n collectTypes(node, parent, file, source, types);\n collectFunctions(node, parent, file, source, functions);\n collectCallSites(node, file, source, callSites);\n },\n });\n }\n\n return { types, functions, callSites, files: fileMap };\n}\n\nfunction lineAt(source: string, offset: number): number {\n let line = 1;\n for (let i = 0; i < offset; i++) {\n if (source[i] === \"\\n\") line++;\n }\n return line;\n}\n\nfunction collectTypes(node: Node, parent: Node | null, file: string, source: string, registry: TypeRegistry): void {\n if (node.type === \"TSTypeAliasDeclaration\") {\n const id = child(node, \"id\");\n const typeAnno = child(node, \"typeAnnotation\");\n if (id && typeAnno) {\n registry.add(prop<string>(id, \"name\"), file, lineAt(source, node.start), typeAnno, source, isExported(parent));\n }\n }\n if (node.type === \"TSInterfaceDeclaration\") {\n const id = child(node, \"id\");\n const body = child(node, \"body\");\n if (id && body) {\n registry.add(prop<string>(id, \"name\"), file, lineAt(source, node.start), body, source, isExported(parent));\n }\n }\n}\n\nfunction isExported(parent: Node | null): boolean {\n if (parent === null) return false;\n return parent.type === \"ExportNamedDeclaration\" || parent.type === \"ExportDefaultDeclaration\";\n}\n\nfunction collectFunctions(node: Node, parent: Node | null, file: string, source: string, registry: FunctionRegistry): void {\n if (node.type === \"FunctionDeclaration\" || node.type === \"FunctionExpression\") {\n const id = child(node, \"id\");\n const body = child(node, \"body\");\n if (!id || !body) return;\n const name = prop<string>(id, \"name\");\n const params = extractParams(children(node, \"params\"), source);\n const hash = hashFunctionBody(body, source);\n const exported = isExported(parent);\n registry.add({ name, file, line: lineAt(source, node.start), hash, params, node, exported });\n }\n // Arrow functions assigned to const\n if (node.type === \"VariableDeclarator\") {\n const init = child(node, \"init\");\n const id = child(node, \"id\");\n if (init !== null && init.type === \"ArrowFunctionExpression\" && id !== null && id.type === \"Identifier\") {\n const body = child(init, \"body\");\n if (!body) return;\n const name = prop<string>(id, \"name\");\n const params = extractParams(children(init, \"params\"), source);\n const hash = hashFunctionBody(body, source);\n // Parent is VariableDeclaration; check if \"export\" precedes the declaration on the same line\n const lineStart = source.lastIndexOf(\"\\n\", node.start) + 1;\n const linePrefix = source.slice(lineStart, node.start);\n const exported = linePrefix.includes(\"export\");\n registry.add({ name, file, line: lineAt(source, node.start), hash, params, node, exported });\n }\n }\n}\n\nfunction paramName(node: Node, source: string): string {\n const name = prop<string>(node, \"name\");\n if (name !== undefined) return name;\n return source.slice(node.start, node.end);\n}\n\nfunction typeText(node: Node | null, source: string): string | null {\n if (node === null) return null;\n return source.slice(node.start, node.end);\n}\n\nfunction extractParams(params: Node[], source: string): ParamInfo[] {\n return params.map((p) => {\n if (p.type === \"AssignmentPattern\") {\n const left = child(p, \"left\");\n if (left === null) {\n return { name: \"?\", optional: false, hasDefault: true, typeText: null };\n }\n return {\n name: paramName(left, source),\n optional: prop<boolean>(left, \"optional\") === true,\n hasDefault: true,\n typeText: typeText(child(left, \"typeAnnotation\"), source),\n };\n }\n const typeAnno = child(p, \"typeAnnotation\");\n return {\n name: paramName(p, source),\n optional: prop<boolean>(p, \"optional\") === true,\n hasDefault: false,\n typeText: typeText(typeAnno, source),\n };\n });\n}\n\nfunction collectCallSites(node: Node, file: string, source: string, sites: CallSite[]): void {\n if (node.type !== \"CallExpression\") return;\n const callee = child(node, \"callee\");\n let calleeName: string | null = null;\n if (callee !== null && callee.type === \"Identifier\") {\n calleeName = prop<string>(callee, \"name\");\n } else if (callee !== null && callee.type === \"MemberExpression\" && prop<boolean>(callee, \"computed\") !== true) {\n const property = child(callee, \"property\");\n if (property) calleeName = prop<string>(property, \"name\");\n }\n if (calleeName) {\n sites.push({\n calleeName,\n file,\n line: lineAt(source, node.start),\n argCount: children(node, \"arguments\").length,\n node,\n });\n }\n}\n","import { createHash } from \"node:crypto\";\nimport type { Node } from \"oxc-parser\";\nimport { prop, child, children } from \"./narrow.ts\";\n\n/**\n * Create a structural hash of a type node.\n * Normalizes by sorting property names and stripping locations.\n */\nexport function hashTypeShape(node: Node, source: string): string {\n const normalized = normalizeTypeNode(node, source);\n return createHash(\"sha256\").update(normalized).digest(\"hex\").slice(0, 16);\n}\n\nfunction normalizeTypeNode(node: Node, source: string): string {\n if (node.type === \"TSTypeLiteral\") {\n const members = children(node, \"members\");\n const normalized = members.map((m) => normalizeTypeNode(m, source)).sort().join(\";\");\n return `{${normalized}}`;\n }\n if (node.type === \"TSInterfaceBody\") {\n const members = children(node, \"body\");\n const normalized = members.map((m) => normalizeTypeNode(m, source)).sort().join(\";\");\n return `{${normalized}}`;\n }\n if (node.type === \"TSPropertySignature\") {\n const key = child(node, \"key\");\n const rawName = key ? prop<string>(key, \"name\") : undefined;\n const keyName = rawName !== undefined ? rawName : key ? source.slice(key.start, key.end) : \"?\";\n const typeAnno = child(node, \"typeAnnotation\");\n const innerType = typeAnno ? child(typeAnno, \"typeAnnotation\") : null;\n const type = innerType ? normalizeTypeNode(innerType, source) : \"any\";\n const optional = prop<boolean>(node, \"optional\") ? \"?\" : \"\";\n return `${keyName}${optional}:${type}`;\n }\n if (node.type === \"TSTypeAnnotation\") {\n const inner = child(node, \"typeAnnotation\");\n return inner ? normalizeTypeNode(inner, source) : \"any\";\n }\n // Fallback: use source text with whitespace normalized\n return source.slice(node.start, node.end).replace(/\\s+/g, \" \").trim();\n}\n\n/**\n * Hash a function body for duplicate detection.\n * Normalizes whitespace.\n */\nexport function hashFunctionBody(node: Node, source: string): string {\n const bodyText = source.slice(node.start, node.end);\n const normalized = bodyText.replace(/\\s+/g, \" \").trim();\n return createHash(\"sha256\").update(normalized).digest(\"hex\").slice(0, 16);\n}\n","import type { Node } from \"oxc-parser\";\nimport { hashTypeShape } from \"../utils/hash.ts\";\n\nexport interface TypeEntry {\n name: string;\n file: string;\n line: number;\n hash: string;\n node: Node;\n exported: boolean;\n}\n\nexport class TypeRegistry {\n private entries: TypeEntry[] = [];\n private byHash = new Map<string, TypeEntry[]>();\n\n add(name: string, file: string, line: number, typeNode: Node, source: string, exported: boolean): void {\n const hash = hashTypeShape(typeNode, source);\n const entry: TypeEntry = { name, file, line, hash, node: typeNode, exported };\n this.entries.push(entry);\n let list = this.byHash.get(hash);\n if (list === undefined) {\n list = [];\n this.byHash.set(hash, list);\n }\n list.push(entry);\n }\n\n getDuplicateGroups(): TypeEntry[][] {\n return [...this.byHash.values()].filter((group) => group.length > 1);\n }\n\n getAll(): TypeEntry[] {\n return this.entries;\n }\n\n getNameCollisionGroups(): TypeEntry[][] {\n const byName = new Map<string, TypeEntry[]>();\n for (const entry of this.entries) {\n if (!entry.exported) continue;\n let list = byName.get(entry.name);\n if (list === undefined) {\n list = [];\n byName.set(entry.name, list);\n }\n list.push(entry);\n }\n return [...byName.values()].filter((group) => {\n if (group.length < 2) return false;\n const files = new Set(group.map((e) => e.file));\n return files.size > 1;\n });\n }\n}\n","import type { Node } from \"oxc-parser\";\n\nexport interface ParamInfo {\n name: string;\n optional: boolean;\n hasDefault: boolean;\n typeText: string | null;\n}\n\nexport interface FunctionEntry {\n name: string;\n file: string;\n line: number;\n hash: string;\n params: ParamInfo[];\n node: Node;\n exported: boolean;\n}\n\nexport class FunctionRegistry {\n private entries: FunctionEntry[] = [];\n private byHash = new Map<string, FunctionEntry[]>();\n\n add(entry: FunctionEntry): void {\n this.entries.push(entry);\n let list = this.byHash.get(entry.hash);\n if (list === undefined) {\n list = [];\n this.byHash.set(entry.hash, list);\n }\n list.push(entry);\n }\n\n getDuplicateGroups(): FunctionEntry[][] {\n return [...this.byHash.values()].filter((group) => group.length > 1);\n }\n\n getAll(): FunctionEntry[] {\n return this.entries;\n }\n\n getByName(name: string): FunctionEntry[] {\n return this.entries.filter((e) => e.name === name);\n }\n\n getNameCollisionGroups(): FunctionEntry[][] {\n const byName = new Map<string, FunctionEntry[]>();\n for (const entry of this.entries) {\n if (!entry.exported) continue;\n let list = byName.get(entry.name);\n if (list === undefined) {\n list = [];\n byName.set(entry.name, list);\n }\n list.push(entry);\n }\n return [...byName.values()].filter((group) => {\n if (group.length < 2) return false;\n const files = new Set(group.map((e) => e.file));\n return files.size > 1;\n });\n }\n}\n"],"mappings":";AAaO,SAAS,KAAkB,MAAY,KAAgB;AAC5D,SAAQ,KAAiB,GAAG;AAC9B;AAGO,SAAS,MAAM,MAAY,KAA0B;AAC1D,QAAM,MAAO,KAAiB,GAAG;AACjC,MAAI,QAAQ,UAAa,QAAQ,KAAM,QAAO;AAC9C,SAAO;AACT;AAGO,SAAS,SAAS,MAAY,KAAqB;AACxD,QAAM,MAAO,KAAiB,GAAG;AACjC,MAAI,CAAC,MAAM,QAAQ,GAAG,EAAG,QAAO,CAAC;AACjC,SAAO;AACT;;;ACzBO,IAAM,eAA+B;AAAA,EAC1C,IAAI;AAAA,EACJ,UAAU;AAAA,EACV,SAAS;AAAA,EAET,MAAM,MAAY,SAAsB,KAAmB;AACzD,QAAI,KAAK,SAAS,cAAe;AACjC,UAAM,OAAO,MAAM,MAAM,MAAM;AAC/B,QAAI,QAAQ,KAAK,SAAS,oBAAoB,SAAS,MAAM,MAAM,EAAE,WAAW,GAAG;AACjF,YAAM,aAAa,IAAI,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,KAAK,SAAS,EAAE,OAAO,KAAK,GAAG;AACtF,UAAI,WAAY;AAChB,UAAI,OAAO,IAAI;AAAA,IACjB;AAAA,EACF;AACF;;;ACfO,IAAM,qBAAqC;AAAA,EAChD,IAAI;AAAA,EACJ,UAAU;AAAA,EACV,SAAS;AAAA,EAET,MAAM,MAAY,SAAsB,KAAmB;AACzD,QAAI,KAAK,SAAS,sBAAuB;AACzC,QAAI,OAAO,IAAI;AAAA,EACjB;AACF;;;ACRO,IAAM,2BAA2C;AAAA,EACtD,IAAI;AAAA,EACJ,UAAU;AAAA,EACV,SAAS;AAAA,EAET,MAAM,MAAY,SAAsB,KAAmB;AACzD,QAAI,KAAK,SAAS,kBAAmB;AACrC,QAAI,KAAa,MAAM,UAAU,MAAM,IAAK;AAC5C,UAAM,MAAM,MAAM,MAAM,UAAU;AAClC,QAAI,QAAQ,QAAQ,IAAI,SAAS,qBAAqB,KAAa,KAAK,UAAU,MAAM,KAAK;AAC3F,UAAI,OAAO,IAAI;AAAA,IACjB;AAAA,EACF;AACF;;;ACdO,IAAM,aAA6B;AAAA,EACxC,IAAI;AAAA,EACJ,UAAU;AAAA,EACV,SAAS;AAAA,EAET,MAAM,OAAa,SAAsB,MAAoB;AAAA,EAAC;AAAA,EAE9D,aAAa,SAAkB,KAAmB;AAChD,QAAI,QAAQ,MAAM,SAAS,YAAY,KAAK,QAAQ,MAAM,SAAS,kBAAkB,GAAG;AACtF,UAAI,OAAO,OAAO;AAAA,IACpB;AAAA,EACF;AACF;;;ACXO,IAAM,sBAAsC;AAAA,EACjD,IAAI;AAAA,EACJ,UAAU;AAAA,EACV,SAAS;AAAA,EAET,MAAM,MAAY,SAAsB,KAAmB;AACzD,QAAI,KAAK,SAAS,oBAAqB;AACvC,QAAI,KAAa,MAAM,UAAU,MAAM,KAAM;AAC7C,QAAI,OAAO,IAAI;AAAA,EACjB;AACF;;;ACVO,IAAM,iBAAiC;AAAA,EAC5C,IAAI;AAAA,EACJ,UAAU;AAAA,EACV,SAAS;AAAA,EAET,MAAM,MAAY,SAAsB,KAAmB;AACzD,QAAI,KAAK,SAAS,iBAAkB;AACpC,QAAI,CAAC,KAAc,MAAM,UAAU,EAAG;AACtC,QAAI,OAAO,IAAI;AAAA,EACjB;AACF;;;ACVO,IAAM,2BAA2C;AAAA,EACtD,IAAI;AAAA,EACJ,UAAU;AAAA,EACV,SAAS;AAAA,EAET,MAAM,MAAY,SAAsB,KAAmB;AACzD,QAAI,KAAK,SAAS,mBAAoB;AACtC,QAAI,KAAc,MAAM,UAAU,KAAK,CAAC,KAAc,MAAM,UAAU,GAAG;AACvE,UAAI,OAAO,IAAI;AAAA,IACjB;AAAA,EACF;AACF;;;ACXO,IAAM,0BAA0C;AAAA,EACrD,IAAI;AAAA,EACJ,UAAU;AAAA,EACV,SAAS;AAAA,EAET,MAAM,MAAY,SAAsB,KAAmB;AACzD,QAAI,KAAK,SAAS,mBAAoB;AACtC,QAAI,KAAc,MAAM,UAAU,KAAK,KAAc,MAAM,UAAU,GAAG;AACtE,UAAI,OAAO,IAAI;AAAA,IACjB;AAAA,EACF;AACF;;;ACXO,SAAS,UAAU,MAAqB;AAC7C,MAAI,KAAK,SAAS,aAAa,KAAK,MAAM,OAAO,MAAM,KAAM,QAAO;AACpE,MAAI,KAAK,SAAS,gBAAgB,KAAa,MAAM,MAAM,MAAM,YAAa,QAAO;AACrF,SAAO;AACT;AAGO,SAAS,UAAU,MAAqB;AAC7C,UAAQ,KAAK,MAAM;AAAA,IACjB,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO,KAAa,MAAM,MAAM,MAAM;AAAA,IACxC;AACE,aAAO;AAAA,EACX;AACF;;;AClBO,IAAM,sBAAsC;AAAA,EACjD,IAAI;AAAA,EACJ,UAAU;AAAA,EACV,SAAS;AAAA,EAET,MAAM,MAAY,SAAsB,KAAmB;AACzD,QAAI,KAAK,SAAS,oBAAqB;AACvC,QAAI,KAAa,MAAM,UAAU,MAAM,KAAM;AAC7C,UAAM,QAAQ,MAAM,MAAM,OAAO;AACjC,QAAI,SAAS,UAAU,KAAK,GAAG;AAC7B,UAAI,OAAO,IAAI;AAAA,IACjB;AAAA,EACF;AACF;;;ACbO,IAAM,6BAA6C;AAAA,EACxD,IAAI;AAAA,EACJ,UAAU;AAAA,EACV,SAAS;AAAA,EAET,MAAM,MAAY,SAAsB,KAAmB;AACzD,QAAI,KAAK,SAAS,wBAAyB;AAC3C,UAAM,OAAO,MAAM,MAAM,MAAM;AAC/B,QAAI,SAAS,QAAQ,KAAK,SAAS,mBAAoB;AACvD,UAAM,KAAK,KAAa,MAAM,UAAU;AACxC,QAAI,OAAO,SAAS,OAAO,SAAS,OAAO,QAAQ,OAAO,KAAM;AAChE,UAAM,WAAW,MAAM,MAAM,MAAM;AACnC,UAAM,YAAY,MAAM,MAAM,OAAO;AACrC,UAAM,sBACH,aAAa,QAAQ,UAAU,QAAQ,KAAO,cAAc,QAAQ,UAAU,SAAS;AAC1F,QAAI,CAAC,oBAAqB;AAC1B,UAAM,aAAa,MAAM,MAAM,YAAY;AAC3C,UAAM,YAAY,MAAM,MAAM,WAAW;AACzC,QAAK,eAAe,QAAQ,UAAU,UAAU,KAAO,cAAc,QAAQ,UAAU,SAAS,GAAI;AAClG,UAAI,OAAO,IAAI;AAAA,IACjB;AAAA,EACF;AACF;;;ACvBO,IAAM,YAA4B;AAAA,EACvC,IAAI;AAAA,EACJ,UAAU;AAAA,EACV,SAAS;AAAA,EAET,MAAM,MAAY,SAAsB,KAAmB;AACzD,QAAI,KAAK,SAAS,iBAAkB;AACpC,UAAM,WAAW,MAAM,MAAM,gBAAgB;AAC7C,QAAI,aAAa,QAAQ,SAAS,SAAS,gBAAgB;AACzD,UAAI,OAAO,IAAI;AAAA,IACjB;AAAA,EACF;AACF;;;ACbO,IAAM,0BAA0C;AAAA,EACrD,IAAI;AAAA,EACJ,UAAU;AAAA,EACV,SAAS;AAAA,EAET,MAAM,MAAY,QAAqB,KAAmB;AACxD,QAAI,KAAK,SAAS,eAAgB;AAElC,QAAI,WAAW,QAAQ,OAAO,SAAS,iBAAkB;AACzD,QAAI,OAAO,IAAI;AAAA,EACjB;AACF;;;ACXO,IAAM,uBAAuC;AAAA,EAClD,IAAI;AAAA,EACJ,UAAU;AAAA,EACV,SAAS;AAAA,EAET,MAAM,MAAY,QAAqB,KAAmB;AACxD,QAAI,KAAK,SAAS,gBAAiB;AACnC,QAAI,WAAW,QAAQ,OAAO,SAAS,mBAAoB;AAE3D,QAAI,CAAC,wBAAwB,IAAI,QAAQ,KAAK,KAAK,EAAG;AAEtD,QAAI,OAAO,IAAI;AAAA,EACjB;AACF;AAEA,SAAS,wBAAwB,QAAgB,QAAyB;AAIxE,MAAI,QAAQ;AACZ,WAAS,IAAI,SAAS,GAAG,KAAK,GAAG,KAAK;AACpC,QAAI,OAAO,CAAC,MAAM,IAAK;AACvB,QAAI,OAAO,CAAC,MAAM,KAAK;AACrB,UAAI,UAAU,GAAG;AAMf,cAAM,SAAS,OAAO,MAAM,KAAK,IAAI,GAAG,IAAI,GAAG,GAAG,CAAC,EAAE,QAAQ;AAE7D,YAAI,4BAA4B,KAAK,MAAM,GAAG;AAG5C;AACA;AAAA,QACF;AAEA,eAAO;AAAA,MACT;AACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;;;AC5CO,IAAM,kBAAkC;AAAA,EAC7C,IAAI;AAAA,EACJ,UAAU;AAAA,EACV,SAAS;AAAA,EAET,MAAM,MAAY,SAAsB,KAAmB;AACzD,QAAI,KAAK,SAAS,iBAAkB;AAEpC,UAAM,QAAQ,MAAM,MAAM,YAAY;AACtC,QAAI,UAAU,QAAQ,MAAM,SAAS,iBAAkB;AACvD,UAAM,YAAY,MAAM,OAAO,gBAAgB;AAC/C,QAAI,cAAc,QAAQ,UAAU,SAAS,mBAAoB;AACjE,QAAI,OAAO,IAAI;AAAA,EACjB;AACF;;;ACdO,IAAM,4BAA4C;AAAA,EACvD,IAAI;AAAA,EACJ,UAAU;AAAA,EACV,SAAS;AAAA,EAET,MAAM,MAAY,SAAsB,KAAmB;AACzD,QAAI,KAAK,SAAS,cAAe;AACjC,UAAM,OAAO,MAAM,MAAM,MAAM;AAC/B,QAAI,CAAC,QAAQ,KAAK,SAAS,uBAAuB,KAAa,MAAM,UAAU,MAAM,KAAM;AAE3F,UAAM,OAAO,MAAM,MAAM,MAAM;AAC/B,UAAM,QAAQ,MAAM,MAAM,OAAO;AACjC,QAAI,CAAC,QAAQ,KAAK,SAAS,aAAc;AACzC,QAAI,CAAC,SAAS,MAAM,SAAS,mBAAoB;AACjD,UAAM,MAAM,MAAM,OAAO,QAAQ;AACjC,QAAI,CAAC,OAAO,IAAI,SAAS,aAAc;AACvC,QAAI,KAAa,MAAM,MAAM,MAAM,KAAa,KAAK,MAAM,EAAG;AAC9D,QAAI,OAAO,IAAI;AAAA,EACjB;AACF;;;ACnBO,IAAM,0BAA0C;AAAA,EACrD,IAAI;AAAA,EACJ,UAAU;AAAA,EACV,SAAS;AAAA,EAET,MAAM,MAAY,SAAsB,KAAmB;AACzD,QAAI,KAAK,SAAS,yBAAyB,KAAK,SAAS,0BAA2B;AACpF,UAAM,SAAS,SAAS,MAAM,QAAQ;AACtC,UAAM,OAAO,MAAM,MAAM,MAAM;AAC/B,QAAI,SAAS,QAAQ,KAAK,SAAS,iBAAkB;AACrD,UAAM,QAAQ,SAAS,MAAM,MAAM;AACnC,QAAI,MAAM,WAAW,EAAG;AAExB,UAAM,YAAY,MAAM,CAAC;AACzB,QAAI,UAAU,SAAS,sBAAuB;AAC9C,UAAM,OAAO,MAAM,WAAW,YAAY;AAC1C,QAAI,SAAS,QAAQ,KAAK,SAAS,0BAA0B,KAAa,MAAM,UAAU,MAAM,IAAK;AAErG,UAAM,QAAQ,MAAM,MAAM,OAAO;AACjC,QAAI,UAAU,QAAQ,MAAM,SAAS,uBAAuB,KAAa,OAAO,UAAU,MAAM,KAAM;AAEtG,UAAM,WAAW,MAAM,MAAM,MAAM;AACnC,UAAM,gBAAgB,MAAM,OAAO,MAAM;AACzC,QAAI,aAAa,QAAQ,SAAS,SAAS,aAAc;AACzD,QAAI,kBAAkB,QAAQ,cAAc,SAAS,aAAc;AACnE,QAAI,KAAa,UAAU,MAAM,MAAM,KAAa,eAAe,MAAM,EAAG;AAE5E,UAAM,eAAe,KAAa,UAAU,MAAM;AAClD,UAAM,UAAU,OAAO,KAAK,CAAC,MAAY;AACvC,UAAI,EAAE,SAAS,aAAc,QAAO,KAAa,GAAG,MAAM,MAAM;AAChE,UAAI,EAAE,SAAS,qBAAqB;AAClC,cAAM,OAAO,MAAM,GAAG,MAAM;AAC5B,eAAO,SAAS,QAAQ,KAAK,SAAS,gBAAgB,KAAa,MAAM,MAAM,MAAM;AAAA,MACvF;AACA,aAAO;AAAA,IACT,CAAC;AACD,QAAI,SAAS;AACX,UAAI,OAAO,SAAS;AAAA,IACtB;AAAA,EACF;AACF;;;ACxCO,IAAM,+BAA+C;AAAA,EAC1D,IAAI;AAAA,EACJ,UAAU;AAAA,EACV,SAAS;AAAA,EAET,MAAM,MAAY,SAAsB,KAAmB;AACzD,QAAI,KAAK,SAAS,yBAAyB,KAAK,SAAS,0BAA2B;AACpF,UAAM,SAAS,SAAS,MAAM,QAAQ;AACtC,UAAM,OAAO,MAAM,MAAM,MAAM;AAC/B,QAAI,SAAS,QAAQ,KAAK,SAAS,iBAAkB;AACrD,UAAM,QAAQ,SAAS,MAAM,MAAM;AACnC,QAAI,MAAM,WAAW,EAAG;AAExB,UAAM,YAAY,MAAM,CAAC;AACzB,QAAI,UAAU,SAAS,cAAe;AAEtC,UAAM,OAAO,MAAM,WAAW,MAAM;AACpC,QAAI,SAAS,KAAM;AACnB,QAAI,cAA6B;AAGjC,QAAI,KAAK,SAAS,qBAAqB,KAAa,MAAM,UAAU,MAAM,KAAK;AAC7E,YAAM,MAAM,MAAM,MAAM,UAAU;AAClC,UAAI,QAAQ,QAAQ,IAAI,SAAS,aAAc,eAAc,KAAa,KAAK,MAAM;AAAA,IACvF;AAEA,QAAI,KAAK,SAAS,oBAAoB;AACpC,YAAM,KAAK,KAAa,MAAM,UAAU;AACxC,UAAI,OAAO,SAAS,OAAO,MAAM;AAC/B,cAAM,OAAO,MAAM,MAAM,MAAM;AAC/B,cAAM,QAAQ,MAAM,MAAM,OAAO;AACjC,YACE,SAAS,QACT,KAAK,SAAS,gBACd,UAAU,QACV,MAAM,SAAS,gBACf,KAAa,OAAO,MAAM,MAAM,aAChC;AACA,wBAAc,KAAa,MAAM,MAAM;AAAA,QACzC;AAAA,MACF;AAAA,IACF;AAEA,QAAI,gBAAgB,KAAM;AAE1B,UAAM,aAAa,MAAM,WAAW,YAAY;AAChD,QAAI,eAAe,KAAM;AACzB,UAAM,UACJ,WAAW,SAAS,qBACpB,WAAW,SAAS,oBACnB,WAAW,SAAS,oBAAoB,aAAa,UAAU;AAElE,QAAI,CAAC,QAAS;AAEd,UAAM,kBAAkB,OAAO;AAAA,MAC7B,CAAC,MAAY,EAAE,SAAS,gBAAgB,KAAa,GAAG,MAAM,MAAM,eAAe,KAAc,GAAG,UAAU,MAAM;AAAA,IACtH;AACA,QAAI,iBAAiB;AACnB,UAAI,OAAO,SAAS;AAAA,IACtB;AAAA,EACF;AACF;AAEA,SAAS,aAAa,OAAsB;AAC1C,QAAM,OAAO,SAAS,OAAO,MAAM;AACnC,MAAI,KAAK,WAAW,EAAG,QAAO;AAC9B,QAAM,OAAO,KAAK,CAAC;AACnB,SAAO,KAAK,SAAS,qBAAqB,KAAK,SAAS;AAC1D;;;ACtEO,IAAM,2BAA0C;AAAA,EACrD,IAAI;AAAA,EACJ,UAAU;AAAA,EACV,SAAS;AAAA,EAET,QAAQ,SAAqC;AAC3C,UAAM,cAA4B,CAAC;AACnC,eAAW,SAAS,QAAQ,MAAM,mBAAmB,GAAG;AAEtD,YAAM,QAAQ,IAAI,IAAI,MAAM,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;AAC9C,UAAI,MAAM,OAAO,EAAG;AAEpB,iBAAW,SAAS,OAAO;AACzB,cAAM,SAAS,MACZ,OAAO,CAAC,MAAM,MAAM,KAAK,EACzB,IAAI,CAAC,MAAM,GAAG,EAAE,IAAI,KAAK,EAAE,IAAI,IAAI,EAAE,IAAI,GAAG,EAC5C,KAAK,IAAI;AACZ,oBAAY,KAAK;AAAA,UACf,QAAQ,KAAK;AAAA,UACb,UAAU,KAAK;AAAA,UACf,SAAS,SAAS,MAAM,IAAI,6BAA6B,MAAM;AAAA,UAC/D,MAAM,MAAM;AAAA,UACZ,MAAM,MAAM;AAAA,UACZ,QAAQ;AAAA,QACV,CAAC;AAAA,MACH;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACF;;;AC7BO,IAAM,+BAA8C;AAAA,EACzD,IAAI;AAAA,EACJ,UAAU;AAAA,EACV,SAAS;AAAA,EAET,QAAQ,SAAqC;AAC3C,UAAM,cAA4B,CAAC;AACnC,eAAW,SAAS,QAAQ,UAAU,mBAAmB,GAAG;AAC1D,YAAM,QAAQ,IAAI,IAAI,MAAM,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;AAC9C,UAAI,MAAM,OAAO,EAAG;AAEpB,iBAAW,SAAS,OAAO;AACzB,cAAM,SAAS,MACZ,OAAO,CAAC,MAAM,MAAM,KAAK,EACzB,IAAI,CAAC,MAAM,GAAG,EAAE,IAAI,KAAK,EAAE,IAAI,IAAI,EAAE,IAAI,GAAG,EAC5C,KAAK,IAAI;AACZ,oBAAY,KAAK;AAAA,UACf,QAAQ,KAAK;AAAA,UACb,UAAU,KAAK;AAAA,UACf,SAAS,aAAa,MAAM,IAAI,4BAA4B,MAAM;AAAA,UAClE,MAAM,MAAM;AAAA,UACZ,MAAM,MAAM;AAAA,UACZ,QAAQ;AAAA,QACV,CAAC;AAAA,MACH;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACF;;;AC5BO,IAAM,wBAAuC;AAAA,EAClD,IAAI;AAAA,EACJ,UAAU;AAAA,EACV,SAAS;AAAA,EAET,QAAQ,SAAqC;AAC3C,UAAM,cAA4B,CAAC;AAEnC,eAAW,MAAM,QAAQ,UAAU,OAAO,GAAG;AAE3C,eAAS,IAAI,GAAG,IAAI,GAAG,OAAO,QAAQ,KAAK;AACzC,cAAM,QAAQ,GAAG,OAAO,CAAC;AACzB,YAAI,CAAC,MAAM,YAAY,CAAC,MAAM,WAAY;AAG1C,cAAM,YAAY,QAAQ,UAAU,OAAO,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI;AAG1E,YAAI,UAAU,SAAS,EAAG;AAG1B,cAAM,aAAa,UAAU,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC;AACxD,YAAI,YAAY;AACd,sBAAY,KAAK;AAAA,YACf,QAAQ,KAAK;AAAA,YACb,UAAU,KAAK;AAAA,YACf,SAAS,uBAAuB,MAAM,IAAI,+BAA+B,UAAU,MAAM;AAAA,YACzF,MAAM,GAAG;AAAA,YACT,MAAM,GAAG;AAAA,YACT,QAAQ;AAAA,UACV,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AACF;;;ACnCO,IAAM,gBAAgC;AAAA,EAC3C,IAAI;AAAA,EACJ,UAAU;AAAA,EACV,SACE;AAAA,EAEF,MAAM,MAAY,SAAsB,KAAmB;AACzD,QAAI,KAAK,SAAS,cAAe;AACjC,UAAM,OAAO,MAAM,MAAM,MAAM;AAC/B,QAAI,SAAS,KAAM;AACnB,QAAI,UAAU,IAAI,KAAK,CAAC,SAAS,IAAI,GAAG;AACtC,UAAI,OAAO,IAAI;AAAA,IACjB;AAAA,EACF;AACF;AAEA,SAAS,UAAU,OAAsB;AACvC,SAAO,YAAY,OAAO,iBAAiB;AAC7C;AAEA,SAAS,SAAS,OAAsB;AACtC,SAAO,YAAY,OAAO,gBAAgB;AAC5C;AAEA,SAAS,YAAY,MAAY,YAA6B;AAC5D,MAAI,KAAK,SAAS,WAAY,QAAO;AACrC,QAAM,OAAO,OAAO,KAAK,IAAI;AAC7B,aAAW,OAAO,MAAM;AACtB,QAAI,QAAQ,WAAW,QAAQ,SAAS,QAAQ,OAAQ;AACxD,UAAM,MAAM,KAAc,MAAM,GAAG;AACnC,QAAI,QAAQ,QAAQ,QAAQ,UAAa,OAAO,QAAQ,SAAU;AAElE,QAAI,WAAW,GAAW,EAAG;AAC7B,QAAI,MAAM,QAAQ,GAAG,GAAG;AACtB,iBAAW,QAAQ,KAAK;AACtB,YAAI,SAAS,QAAQ,OAAO,SAAS,YAAY,UAAU,MAAM;AAC/D,cAAI,WAAW,IAAY,EAAG;AAC9B,cAAI,YAAY,MAAc,UAAU,EAAG,QAAO;AAAA,QACpD;AAAA,MACF;AAAA,IACF,WAAW,UAAU,KAAK;AACxB,UAAI,YAAY,KAAa,UAAU,EAAG,QAAO;AAAA,IACnD;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,WAAW,MAAqB;AACvC,SACE,KAAK,SAAS,yBACd,KAAK,SAAS,wBACd,KAAK,SAAS;AAElB;;;ACrDO,IAAM,gBAAgC;AAAA,EAC3C,IAAI;AAAA,EACJ,UAAU;AAAA,EACV,SACE;AAAA,EAEF,MAAM,MAAY,SAAsB,KAAmB;AACzD,QAAI,KAAK,SAAS,cAAe;AACjC,UAAM,QAAQ,MAAM,MAAM,OAAO;AACjC,QAAI,UAAU,QAAQ,MAAM,SAAS,aAAc;AACnD,UAAM,YAAY,KAAa,OAAO,MAAM;AAC5C,UAAM,OAAO,MAAM,MAAM,MAAM;AAC/B,QAAI,SAAS,KAAM;AACnB,gBAAY,MAAM,WAAW,GAAG;AAAA,EAClC;AACF;AAEA,SAAS,YAAY,MAAY,WAAmB,KAAyB;AAC3E,MAAI,KAAK,SAAS,kBAAkB;AAClC,UAAM,MAAM,MAAM,MAAM,UAAU;AAClC,QAAI,QAAQ,QAAQ,IAAI,SAAS,iBAAiB;AAChD,YAAM,OAAO,SAAS,KAAK,WAAW;AACtC,UAAI,KAAK,SAAS,KAAK,eAAe,MAAM,SAAS,KAAK,CAAC,YAAY,IAAI,GAAG;AAC5E,YAAI,OAAO,IAAI;AAAA,MACjB;AAAA,IACF;AACA;AAAA,EACF;AAEA,MACE,KAAK,SAAS,yBACd,KAAK,SAAS,wBACd,KAAK,SAAS,2BACd;AACA;AAAA,EACF;AACA,QAAM,OAAO,OAAO,KAAK,IAAI;AAC7B,aAAW,OAAO,MAAM;AACtB,QAAI,QAAQ,WAAW,QAAQ,SAAS,QAAQ,OAAQ;AACxD,UAAM,MAAM,KAAc,MAAM,GAAG;AACnC,QAAI,QAAQ,QAAQ,QAAQ,UAAa,OAAO,QAAQ,SAAU;AAClE,QAAI,MAAM,QAAQ,GAAG,GAAG;AACtB,iBAAW,QAAQ,KAAK;AACtB,YAAI,SAAS,QAAQ,OAAO,SAAS,YAAY,UAAU,MAAM;AAC/D,sBAAY,MAAc,WAAW,GAAG;AAAA,QAC1C;AAAA,MACF;AAAA,IACF,WAAW,UAAU,KAAK;AACxB,kBAAY,KAAa,WAAW,GAAG;AAAA,IACzC;AAAA,EACF;AACF;AAEA,SAAS,eAAe,OAAe,MAAuB;AAC5D,aAAW,QAAQ,OAAO;AACxB,QAAI,mBAAmB,MAAM,IAAI,EAAG,QAAO;AAAA,EAC7C;AACA,SAAO;AACT;AAEA,SAAS,mBAAmB,MAAY,MAAuB;AAC7D,MAAI,KAAK,SAAS,gBAAgB,KAAa,MAAM,MAAM,MAAM,KAAM,QAAO;AAC9E,QAAM,OAAO,OAAO,KAAK,IAAI;AAC7B,aAAW,OAAO,MAAM;AACtB,QAAI,QAAQ,WAAW,QAAQ,SAAS,QAAQ,OAAQ;AACxD,UAAM,MAAM,KAAc,MAAM,GAAG;AACnC,QAAI,QAAQ,QAAQ,QAAQ,UAAa,OAAO,QAAQ,SAAU;AAClE,QAAI,MAAM,QAAQ,GAAG,GAAG;AACtB,iBAAW,QAAQ,KAAK;AACtB,YAAI,SAAS,QAAQ,OAAO,SAAS,YAAY,UAAU,MAAM;AAC/D,cAAI,mBAAmB,MAAc,IAAI,EAAG,QAAO;AAAA,QACrD;AAAA,MACF;AAAA,IACF,WAAW,UAAU,KAAK;AACxB,UAAI,mBAAmB,KAAa,IAAI,EAAG,QAAO;AAAA,IACpD;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,YAAY,MAAuB;AAC1C,aAAW,OAAO,MAAM;AACtB,QAAI,IAAI,SAAS,oBAAoB;AACnC,YAAM,QAAQ,SAAS,KAAK,YAAY;AACxC,iBAAW,KAAK,OAAO;AACrB,cAAM,MAAM,MAAM,GAAG,KAAK;AAC1B,YAAI,QAAQ,QAAQ,IAAI,SAAS,gBAAgB,KAAa,KAAK,MAAM,MAAM,SAAS;AACtF,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;;;AC7FO,IAAM,kBAAiC;AAAA,EAC5C,IAAI;AAAA,EACJ,UAAU;AAAA,EACV,SAAS;AAAA,EAET,QAAQ,SAAqC;AAC3C,UAAM,cAA4B,CAAC;AAGnC,UAAM,iBAAiB,oBAAI,IAAY;AACvC,eAAW,MAAM,QAAQ,UAAU,OAAO,GAAG;AAC3C,qBAAe,IAAI,GAAG,IAAI;AAAA,IAC5B;AAEA,eAAW,QAAQ,QAAQ,WAAW;AAEpC,UAAI,CAAC,eAAe,IAAI,KAAK,UAAU,EAAG;AAE1C,YAAM,OAAO,SAAS,KAAK,MAAM,WAAW;AAC5C,eAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,cAAM,MAAM,KAAK,CAAC;AAClB,YAAI,QAAQ,OAAW;AACvB,YAAI,UAAU,GAAG,GAAG;AAClB,gBAAM,MAAM,IAAI,SAAS,YAAY,SAAS;AAC9C,sBAAY,KAAK;AAAA,YACf,QAAQ,KAAK;AAAA,YACb,UAAU,KAAK;AAAA,YACf,SAAS,oBAAoB,GAAG,QAAQ,KAAK,UAAU,iBAAiB,IAAI,CAAC;AAAA,YAC7E,MAAM,KAAK;AAAA,YACX,MAAM,KAAK;AAAA,YACX,QAAQ;AAAA,UACV,CAAC;AACD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AACF;;;ACzCO,IAAM,wBAAuC;AAAA,EAClD,IAAI;AAAA,EACJ,UAAU;AAAA,EACV,SAAS;AAAA,EAET,QAAQ,SAAqC;AAC3C,UAAM,cAA4B,CAAC;AACnC,eAAW,SAAS,QAAQ,UAAU,uBAAuB,GAAG;AAE9D,YAAM,SAAS,IAAI,IAAI,MAAM,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;AAC/C,UAAI,OAAO,SAAS,EAAG;AAEvB,iBAAW,SAAS,OAAO;AACzB,cAAM,SAAS,MACZ,OAAO,CAAC,MAAM,MAAM,KAAK,EACzB,IAAI,CAAC,MAAM,GAAG,EAAE,IAAI,IAAI,EAAE,IAAI,EAAE,EAChC,KAAK,IAAI;AACZ,oBAAY,KAAK;AAAA,UACf,QAAQ,KAAK;AAAA,UACb,UAAU,KAAK;AAAA,UACf,SAAS,sBAAsB,MAAM,IAAI,sBAAsB,MAAM;AAAA,UACrE,MAAM,MAAM;AAAA,UACZ,MAAM,MAAM;AAAA,UACZ,QAAQ;AAAA,QACV,CAAC;AAAA,MACH;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACF;;;AC7BO,IAAM,oBAAmC;AAAA,EAC9C,IAAI;AAAA,EACJ,UAAU;AAAA,EACV,SAAS;AAAA,EAET,QAAQ,SAAqC;AAC3C,UAAM,cAA4B,CAAC;AACnC,eAAW,SAAS,QAAQ,MAAM,uBAAuB,GAAG;AAE1D,YAAM,SAAS,IAAI,IAAI,MAAM,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;AAC/C,UAAI,OAAO,SAAS,EAAG;AAEvB,iBAAW,SAAS,OAAO;AACzB,cAAM,SAAS,MACZ,OAAO,CAAC,MAAM,MAAM,KAAK,EACzB,IAAI,CAAC,MAAM,GAAG,EAAE,IAAI,IAAI,EAAE,IAAI,EAAE,EAChC,KAAK,IAAI;AACZ,oBAAY,KAAK;AAAA,UACf,QAAQ,KAAK;AAAA,UACb,UAAU,KAAK;AAAA,UACf,SAAS,kBAAkB,MAAM,IAAI,sBAAsB,MAAM;AAAA,UACjE,MAAM,MAAM;AAAA,UACZ,MAAM,MAAM;AAAA,UACZ,QAAQ;AAAA,QACV,CAAC;AAAA,MACH;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACF;;;AC5BO,IAAM,kBAAkC;AAAA,EAC7C,IAAI;AAAA,EACJ,UAAU;AAAA,EACV,SAAS;AAAA,EAET,MAAM,MAAY,SAAsB,KAAmB;AACzD,QAAI,KAAK,SAAS,mBAAoB;AACtC,QAAI,OAAO,IAAI;AAAA,EACjB;AACF;;;ACiBO,IAAM,WAAmB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACxDA,SAAS,aAAAA,kBAA+B;AACxC,SAAS,QAAAC,aAAY;AACrB,OAAO,QAAQ;AACf,SAAS,gBAAAC,qBAAoB;;;ACyCtB,SAAS,iBAAiB,GAA8B;AAC7D,SAAO,WAAW;AACpB;;;AC9CA,SAAS,iBAA+B;AACxC,SAAS,YAAY;AACrB,SAAS,oBAAoB;;;ACF7B,SAAS,kBAAkB;AAQpB,SAAS,cAAc,MAAY,QAAwB;AAChE,QAAM,aAAa,kBAAkB,MAAM,MAAM;AACjD,SAAO,WAAW,QAAQ,EAAE,OAAO,UAAU,EAAE,OAAO,KAAK,EAAE,MAAM,GAAG,EAAE;AAC1E;AAEA,SAAS,kBAAkB,MAAY,QAAwB;AAC7D,MAAI,KAAK,SAAS,iBAAiB;AACjC,UAAM,UAAU,SAAS,MAAM,SAAS;AACxC,UAAM,aAAa,QAAQ,IAAI,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG;AACnF,WAAO,IAAI,UAAU;AAAA,EACvB;AACA,MAAI,KAAK,SAAS,mBAAmB;AACnC,UAAM,UAAU,SAAS,MAAM,MAAM;AACrC,UAAM,aAAa,QAAQ,IAAI,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG;AACnF,WAAO,IAAI,UAAU;AAAA,EACvB;AACA,MAAI,KAAK,SAAS,uBAAuB;AACvC,UAAM,MAAM,MAAM,MAAM,KAAK;AAC7B,UAAM,UAAU,MAAM,KAAa,KAAK,MAAM,IAAI;AAClD,UAAM,UAAU,YAAY,SAAY,UAAU,MAAM,OAAO,MAAM,IAAI,OAAO,IAAI,GAAG,IAAI;AAC3F,UAAM,WAAW,MAAM,MAAM,gBAAgB;AAC7C,UAAM,YAAY,WAAW,MAAM,UAAU,gBAAgB,IAAI;AACjE,UAAM,OAAO,YAAY,kBAAkB,WAAW,MAAM,IAAI;AAChE,UAAM,WAAW,KAAc,MAAM,UAAU,IAAI,MAAM;AACzD,WAAO,GAAG,OAAO,GAAG,QAAQ,IAAI,IAAI;AAAA,EACtC;AACA,MAAI,KAAK,SAAS,oBAAoB;AACpC,UAAM,QAAQ,MAAM,MAAM,gBAAgB;AAC1C,WAAO,QAAQ,kBAAkB,OAAO,MAAM,IAAI;AAAA,EACpD;AAEA,SAAO,OAAO,MAAM,KAAK,OAAO,KAAK,GAAG,EAAE,QAAQ,QAAQ,GAAG,EAAE,KAAK;AACtE;AAMO,SAAS,iBAAiB,MAAY,QAAwB;AACnE,QAAM,WAAW,OAAO,MAAM,KAAK,OAAO,KAAK,GAAG;AAClD,QAAM,aAAa,SAAS,QAAQ,QAAQ,GAAG,EAAE,KAAK;AACtD,SAAO,WAAW,QAAQ,EAAE,OAAO,UAAU,EAAE,OAAO,KAAK,EAAE,MAAM,GAAG,EAAE;AAC1E;;;ACtCO,IAAM,eAAN,MAAmB;AAAA,EAChB,UAAuB,CAAC;AAAA,EACxB,SAAS,oBAAI,IAAyB;AAAA,EAE9C,IAAI,MAAc,MAAc,MAAc,UAAgB,QAAgB,UAAyB;AACrG,UAAM,OAAO,cAAc,UAAU,MAAM;AAC3C,UAAM,QAAmB,EAAE,MAAM,MAAM,MAAM,MAAM,MAAM,UAAU,SAAS;AAC5E,SAAK,QAAQ,KAAK,KAAK;AACvB,QAAI,OAAO,KAAK,OAAO,IAAI,IAAI;AAC/B,QAAI,SAAS,QAAW;AACtB,aAAO,CAAC;AACR,WAAK,OAAO,IAAI,MAAM,IAAI;AAAA,IAC5B;AACA,SAAK,KAAK,KAAK;AAAA,EACjB;AAAA,EAEA,qBAAoC;AAClC,WAAO,CAAC,GAAG,KAAK,OAAO,OAAO,CAAC,EAAE,OAAO,CAAC,UAAU,MAAM,SAAS,CAAC;AAAA,EACrE;AAAA,EAEA,SAAsB;AACpB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,yBAAwC;AACtC,UAAM,SAAS,oBAAI,IAAyB;AAC5C,eAAW,SAAS,KAAK,SAAS;AAChC,UAAI,CAAC,MAAM,SAAU;AACrB,UAAI,OAAO,OAAO,IAAI,MAAM,IAAI;AAChC,UAAI,SAAS,QAAW;AACtB,eAAO,CAAC;AACR,eAAO,IAAI,MAAM,MAAM,IAAI;AAAA,MAC7B;AACA,WAAK,KAAK,KAAK;AAAA,IACjB;AACA,WAAO,CAAC,GAAG,OAAO,OAAO,CAAC,EAAE,OAAO,CAAC,UAAU;AAC5C,UAAI,MAAM,SAAS,EAAG,QAAO;AAC7B,YAAM,QAAQ,IAAI,IAAI,MAAM,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;AAC9C,aAAO,MAAM,OAAO;AAAA,IACtB,CAAC;AAAA,EACH;AACF;;;AClCO,IAAM,mBAAN,MAAuB;AAAA,EACpB,UAA2B,CAAC;AAAA,EAC5B,SAAS,oBAAI,IAA6B;AAAA,EAElD,IAAI,OAA4B;AAC9B,SAAK,QAAQ,KAAK,KAAK;AACvB,QAAI,OAAO,KAAK,OAAO,IAAI,MAAM,IAAI;AACrC,QAAI,SAAS,QAAW;AACtB,aAAO,CAAC;AACR,WAAK,OAAO,IAAI,MAAM,MAAM,IAAI;AAAA,IAClC;AACA,SAAK,KAAK,KAAK;AAAA,EACjB;AAAA,EAEA,qBAAwC;AACtC,WAAO,CAAC,GAAG,KAAK,OAAO,OAAO,CAAC,EAAE,OAAO,CAAC,UAAU,MAAM,SAAS,CAAC;AAAA,EACrE;AAAA,EAEA,SAA0B;AACxB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,UAAU,MAA+B;AACvC,WAAO,KAAK,QAAQ,OAAO,CAAC,MAAM,EAAE,SAAS,IAAI;AAAA,EACnD;AAAA,EAEA,yBAA4C;AAC1C,UAAM,SAAS,oBAAI,IAA6B;AAChD,eAAW,SAAS,KAAK,SAAS;AAChC,UAAI,CAAC,MAAM,SAAU;AACrB,UAAI,OAAO,OAAO,IAAI,MAAM,IAAI;AAChC,UAAI,SAAS,QAAW;AACtB,eAAO,CAAC;AACR,eAAO,IAAI,MAAM,MAAM,IAAI;AAAA,MAC7B;AACA,WAAK,KAAK,KAAK;AAAA,IACjB;AACA,WAAO,CAAC,GAAG,OAAO,OAAO,CAAC,EAAE,OAAO,CAAC,UAAU;AAC5C,UAAI,MAAM,SAAS,EAAG,QAAO;AAC7B,YAAM,QAAQ,IAAI,IAAI,MAAM,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;AAC9C,aAAO,MAAM,OAAO;AAAA,IACtB,CAAC;AAAA,EACH;AACF;;;AHtCO,SAAS,eAAe,OAA+B;AAC5D,QAAM,QAAQ,IAAI,aAAa;AAC/B,QAAM,YAAY,IAAI,iBAAiB;AACvC,QAAM,YAAwB,CAAC;AAC/B,QAAM,UAAU,oBAAI,IAAoE;AAExF,aAAW,QAAQ,OAAO;AACxB,UAAM,SAAS,aAAa,MAAM,MAAM;AACxC,UAAM,SAAS,UAAU,MAAM,MAAM;AACrC,YAAQ,IAAI,MAAM,EAAE,QAAQ,SAAS,OAAO,SAAS,UAAU,OAAO,SAAS,CAAC;AAEhF,SAAK,OAAO,SAAS;AAAA,MACnB,MAAM,MAAY,QAAqB;AACrC,qBAAa,MAAM,QAAQ,MAAM,QAAQ,KAAK;AAC9C,yBAAiB,MAAM,QAAQ,MAAM,QAAQ,SAAS;AACtD,yBAAiB,MAAM,MAAM,QAAQ,SAAS;AAAA,MAChD;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO,EAAE,OAAO,WAAW,WAAW,OAAO,QAAQ;AACvD;AAEA,SAAS,OAAO,QAAgB,QAAwB;AACtD,MAAI,OAAO;AACX,WAAS,IAAI,GAAG,IAAI,QAAQ,KAAK;AAC/B,QAAI,OAAO,CAAC,MAAM,KAAM;AAAA,EAC1B;AACA,SAAO;AACT;AAEA,SAAS,aAAa,MAAY,QAAqB,MAAc,QAAgB,UAA8B;AACjH,MAAI,KAAK,SAAS,0BAA0B;AAC1C,UAAM,KAAK,MAAM,MAAM,IAAI;AAC3B,UAAM,WAAW,MAAM,MAAM,gBAAgB;AAC7C,QAAI,MAAM,UAAU;AAClB,eAAS,IAAI,KAAa,IAAI,MAAM,GAAG,MAAM,OAAO,QAAQ,KAAK,KAAK,GAAG,UAAU,QAAQ,WAAW,MAAM,CAAC;AAAA,IAC/G;AAAA,EACF;AACA,MAAI,KAAK,SAAS,0BAA0B;AAC1C,UAAM,KAAK,MAAM,MAAM,IAAI;AAC3B,UAAM,OAAO,MAAM,MAAM,MAAM;AAC/B,QAAI,MAAM,MAAM;AACd,eAAS,IAAI,KAAa,IAAI,MAAM,GAAG,MAAM,OAAO,QAAQ,KAAK,KAAK,GAAG,MAAM,QAAQ,WAAW,MAAM,CAAC;AAAA,IAC3G;AAAA,EACF;AACF;AAEA,SAAS,WAAW,QAA8B;AAChD,MAAI,WAAW,KAAM,QAAO;AAC5B,SAAO,OAAO,SAAS,4BAA4B,OAAO,SAAS;AACrE;AAEA,SAAS,iBAAiB,MAAY,QAAqB,MAAc,QAAgB,UAAkC;AACzH,MAAI,KAAK,SAAS,yBAAyB,KAAK,SAAS,sBAAsB;AAC7E,UAAM,KAAK,MAAM,MAAM,IAAI;AAC3B,UAAM,OAAO,MAAM,MAAM,MAAM;AAC/B,QAAI,CAAC,MAAM,CAAC,KAAM;AAClB,UAAM,OAAO,KAAa,IAAI,MAAM;AACpC,UAAM,SAAS,cAAc,SAAS,MAAM,QAAQ,GAAG,MAAM;AAC7D,UAAM,OAAO,iBAAiB,MAAM,MAAM;AAC1C,UAAM,WAAW,WAAW,MAAM;AAClC,aAAS,IAAI,EAAE,MAAM,MAAM,MAAM,OAAO,QAAQ,KAAK,KAAK,GAAG,MAAM,QAAQ,MAAM,SAAS,CAAC;AAAA,EAC7F;AAEA,MAAI,KAAK,SAAS,sBAAsB;AACtC,UAAM,OAAO,MAAM,MAAM,MAAM;AAC/B,UAAM,KAAK,MAAM,MAAM,IAAI;AAC3B,QAAI,SAAS,QAAQ,KAAK,SAAS,6BAA6B,OAAO,QAAQ,GAAG,SAAS,cAAc;AACvG,YAAM,OAAO,MAAM,MAAM,MAAM;AAC/B,UAAI,CAAC,KAAM;AACX,YAAM,OAAO,KAAa,IAAI,MAAM;AACpC,YAAM,SAAS,cAAc,SAAS,MAAM,QAAQ,GAAG,MAAM;AAC7D,YAAM,OAAO,iBAAiB,MAAM,MAAM;AAE1C,YAAM,YAAY,OAAO,YAAY,MAAM,KAAK,KAAK,IAAI;AACzD,YAAM,aAAa,OAAO,MAAM,WAAW,KAAK,KAAK;AACrD,YAAM,WAAW,WAAW,SAAS,QAAQ;AAC7C,eAAS,IAAI,EAAE,MAAM,MAAM,MAAM,OAAO,QAAQ,KAAK,KAAK,GAAG,MAAM,QAAQ,MAAM,SAAS,CAAC;AAAA,IAC7F;AAAA,EACF;AACF;AAEA,SAAS,UAAU,MAAY,QAAwB;AACrD,QAAM,OAAO,KAAa,MAAM,MAAM;AACtC,MAAI,SAAS,OAAW,QAAO;AAC/B,SAAO,OAAO,MAAM,KAAK,OAAO,KAAK,GAAG;AAC1C;AAEA,SAAS,SAAS,MAAmB,QAA+B;AAClE,MAAI,SAAS,KAAM,QAAO;AAC1B,SAAO,OAAO,MAAM,KAAK,OAAO,KAAK,GAAG;AAC1C;AAEA,SAAS,cAAc,QAAgB,QAA6B;AAClE,SAAO,OAAO,IAAI,CAAC,MAAM;AACvB,QAAI,EAAE,SAAS,qBAAqB;AAClC,YAAM,OAAO,MAAM,GAAG,MAAM;AAC5B,UAAI,SAAS,MAAM;AACjB,eAAO,EAAE,MAAM,KAAK,UAAU,OAAO,YAAY,MAAM,UAAU,KAAK;AAAA,MACxE;AACA,aAAO;AAAA,QACL,MAAM,UAAU,MAAM,MAAM;AAAA,QAC5B,UAAU,KAAc,MAAM,UAAU,MAAM;AAAA,QAC9C,YAAY;AAAA,QACZ,UAAU,SAAS,MAAM,MAAM,gBAAgB,GAAG,MAAM;AAAA,MAC1D;AAAA,IACF;AACA,UAAM,WAAW,MAAM,GAAG,gBAAgB;AAC1C,WAAO;AAAA,MACL,MAAM,UAAU,GAAG,MAAM;AAAA,MACzB,UAAU,KAAc,GAAG,UAAU,MAAM;AAAA,MAC3C,YAAY;AAAA,MACZ,UAAU,SAAS,UAAU,MAAM;AAAA,IACrC;AAAA,EACF,CAAC;AACH;AAEA,SAAS,iBAAiB,MAAY,MAAc,QAAgB,OAAyB;AAC3F,MAAI,KAAK,SAAS,iBAAkB;AACpC,QAAM,SAAS,MAAM,MAAM,QAAQ;AACnC,MAAI,aAA4B;AAChC,MAAI,WAAW,QAAQ,OAAO,SAAS,cAAc;AACnD,iBAAa,KAAa,QAAQ,MAAM;AAAA,EAC1C,WAAW,WAAW,QAAQ,OAAO,SAAS,sBAAsB,KAAc,QAAQ,UAAU,MAAM,MAAM;AAC9G,UAAM,WAAW,MAAM,QAAQ,UAAU;AACzC,QAAI,SAAU,cAAa,KAAa,UAAU,MAAM;AAAA,EAC1D;AACA,MAAI,YAAY;AACd,UAAM,KAAK;AAAA,MACT;AAAA,MACA;AAAA,MACA,MAAM,OAAO,QAAQ,KAAK,KAAK;AAAA,MAC/B,UAAU,SAAS,MAAM,WAAW,EAAE;AAAA,MACtC;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;AF5IA,eAAsB,KAAK,SAA2C;AACpE,QAAM,WAAW,QAAQ,MAAM,SAAS,IAAI,QAAQ,QAAQ,CAAC,GAAG;AAChE,QAAM,QAAQ,SAAS,IAAI,CAAC,MAAM;AAChC,QAAI,MAAM,IAAK,QAAO;AACtB,QAAI,EAAE,SAAS,GAAG,EAAG,QAAO,GAAG,CAAC;AAChC,QAAI,CAAC,EAAE,SAAS,GAAG,KAAK,CAAC,EAAE,SAAS,KAAK,KAAK,CAAC,EAAE,SAAS,MAAM,KAAK,CAAC,EAAE,SAAS,MAAM,KAAK,CAAC,EAAE,SAAS,MAAM,GAAG;AAC/G,aAAO,GAAG,CAAC;AAAA,IACb;AACA,WAAO;AAAA,EACT,CAAC;AAED,QAAM,QAAQ,MAAM,GAAG,OAAO;AAAA,IAC5B,QAAQ,CAAC,sBAAsB,cAAc,cAAc,aAAa,cAAc,YAAY;AAAA,IAClG,UAAU;AAAA,EACZ,CAAC;AAED,QAAM,cAAc,SAAS,OAAO,CAAC,MAAM;AACzC,QAAI,QAAQ,SAAS,CAAC,QAAQ,MAAM,SAAS,EAAE,EAAE,EAAG,QAAO;AAC3D,WAAO;AAAA,EACT,CAAC;AAED,QAAM,kBAAkB,YAAY,OAAO,gBAAgB;AAC3D,QAAM,iBAAiB,YAAY,OAAO,CAAC,MAA0B,CAAC,iBAAiB,CAAC,CAAC;AACzF,QAAM,cAA4B,CAAC;AAGnC,aAAW,QAAQ,OAAO;AACxB,UAAM,SAASC,cAAa,MAAM,MAAM;AACxC,UAAM,SAASC,WAAU,MAAM,MAAM;AACrC,UAAM,YAAY,mBAAmB,iBAAiB,OAAO,SAAS,OAAO,UAAU,QAAQ,IAAI;AACnG,aAAS,WAAW,OAAO,UAAU,MAAM;AAC3C,gBAAY,KAAK,GAAG,SAAS;AAAA,EAC/B;AAGA,MAAI,eAAe,SAAS,KAAK,MAAM,SAAS,GAAG;AACjD,UAAM,eAAe,eAAe,KAAK;AACzC,eAAW,QAAQ,gBAAgB;AACjC,YAAM,aAAa,KAAK,QAAQ,YAAY;AAC5C,iBAAW,KAAK,YAAY;AAC1B,cAAM,WAAW,aAAa,MAAM,IAAI,EAAE,IAAI;AAC9C,YAAI,aAAa,OAAW,UAAS,CAAC,CAAC,GAAG,SAAS,UAAU,SAAS,MAAM;AAAA,MAC9E;AACA,kBAAY,KAAK,GAAG,UAAU;AAAA,IAChC;AAAA,EACF;AAEA,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,UAAwB,CAAC;AAC/B,aAAW,KAAK,aAAa;AAC3B,UAAM,MAAM,GAAG,EAAE,IAAI,IAAI,EAAE,IAAI,IAAI,EAAE,MAAM;AAC3C,QAAI,KAAK,IAAI,GAAG,EAAG;AACnB,SAAK,IAAI,GAAG;AACZ,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,QAAQ,QAAQ;AAClB,eAAW,KAAK,SAAS;AACvB,QAAE,WAAW;AAAA,IACf;AAAA,EACF;AAEA,SAAO,EAAE,aAAa,SAAS,WAAW,MAAM,OAAO;AACzD;AAEO,SAAS,mBACd,OACA,SACA,UACA,QACA,UACc;AACd,QAAM,cAA4B,CAAC;AAEnC,QAAM,UAAU,CAAC,UAAwC;AAAA,IACvD;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO,MAAY,SAAkB;AACnC,YAAM,MAAM,QAAQ,QAAQ,KAAK,KAAK;AACtC,kBAAY,KAAK;AAAA,QACf,QAAQ,KAAK;AAAA,QACb,UAAU,KAAK;AAAA,QACf,SAAS,YAAY,SAAY,KAAK,UAAU;AAAA,QAChD,MAAM;AAAA,QACN,GAAG;AAAA,MACL,CAAC;AAAA,IACH;AAAA,EACF;AAEA,QAAM,WAAW,MAAM,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK,QAAQ,CAAC,EAAE,EAAE;AAEhE,EAAAC,MAAK,SAAS;AAAA,IACZ,MAAM,MAAY,QAAqB;AACrC,iBAAW,EAAE,MAAM,IAAI,KAAK,UAAU;AACpC,aAAK,MAAM,MAAM,QAAQ,GAAG;AAAA,MAC9B;AAAA,IACF;AAAA,EACF,CAAC;AAED,aAAW,EAAE,MAAM,IAAI,KAAK,UAAU;AACpC,QAAI,KAAK,cAAc;AACrB,iBAAW,WAAW,UAAU;AAC9B,aAAK,aAAa,SAAS,GAAG;AAAA,MAChC;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAYA,SAAS,SAAS,aAA2B,UAAqB,QAAsB;AACtF,MAAI,SAAS,WAAW,KAAK,YAAY,WAAW,EAAG;AAGvD,QAAM,YAAY,oBAAI,IAAuB;AAC7C,aAAW,KAAK,UAAU;AACxB,UAAM,UAAUC,QAAO,QAAQ,EAAE,GAAG;AACpC,QAAI,OAAO,UAAU,IAAI,OAAO;AAChC,QAAI,SAAS,QAAW;AACtB,aAAO,CAAC;AACR,gBAAU,IAAI,SAAS,IAAI;AAAA,IAC7B;AACA,SAAK,KAAK,CAAC;AAAA,EACb;AAEA,aAAW,KAAK,aAAa;AAE3B,UAAM,SAAS,kBAAkB,EAAE,MAAM,SAAS;AAClD,QAAI,WAAW,MAAM;AACnB,QAAE,aAAa;AACf;AAAA,IACF;AAEA,UAAM,QAAQ,kBAAkB,EAAE,OAAO,GAAG,WAAW,MAAM;AAC7D,QAAI,UAAU,KAAM,GAAE,aAAa;AAAA,EACrC;AACF;AAEA,SAAS,kBAAkB,UAAkB,WAAkD;AAC7F,QAAM,iBAAiB,UAAU,IAAI,QAAQ;AAC7C,MAAI,mBAAmB,UAAa,eAAe,WAAW,EAAG,QAAO;AACxE,QAAM,UAAU,eAAe,GAAG,EAAE;AACpC,MAAI,YAAY,OAAW,QAAO;AAElC,MAAI,QAAQ,SAAS,OAAQ,QAAO;AACpC,QAAM,OAAO,QAAQ,MAAM,KAAK;AAEhC,MAAI,KAAK,WAAW,SAAS,EAAG,QAAO;AACvC,SAAO;AACT;AAEA,SAAS,kBACP,gBACA,WACA,QACe;AACf,QAAM,iBAAiB,UAAU,IAAI,cAAc;AACnD,MAAI,mBAAmB,UAAa,eAAe,WAAW,EAAG,QAAO;AACxE,QAAM,UAAU,eAAe,GAAG,EAAE;AACpC,MAAI,YAAY,OAAW,QAAO;AAGlC,MAAI,QAAQ,SAAS,SAAS;AAC5B,WAAO,kBAAkB,QAAQ,KAAK;AAAA,EACxC;AAGA,QAAM,QAAkB,CAAC,QAAQ,MAAM,KAAK,CAAC;AAC7C,MAAI,WAAW,iBAAiB;AAChC,aAAS;AACP,UAAM,OAAO,UAAU,IAAI,QAAQ;AACnC,QAAI,SAAS,UAAa,KAAK,WAAW,EAAG;AAC7C,UAAM,cAAc,KAAK,GAAG,EAAE;AAC9B,QAAI,gBAAgB,UAAa,YAAY,SAAS,OAAQ;AAC9D,QAAIA,QAAO,QAAQ,YAAY,KAAK,MAAM,SAAU;AACpD,UAAM,QAAQ,YAAY,MAAM,KAAK,CAAC;AACtC;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,SAAS,kBAAkB,OAAuB;AAChD,SAAO,MACJ,MAAM,IAAI,EACV,IAAI,CAAC,SAAS,KAAK,QAAQ,aAAa,EAAE,EAAE,KAAK,CAAC,EAClD,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,EAChC,KAAK,IAAI;AACd;AAEA,SAASA,QAAO,QAAgB,QAAwB;AACtD,MAAI,OAAO;AACX,WAAS,IAAI,GAAG,IAAI,UAAU,IAAI,OAAO,QAAQ,KAAK;AACpD,QAAI,OAAO,CAAC,MAAM,KAAM;AAAA,EAC1B;AACA,SAAO;AACT;AAEA,SAAS,QAAQ,QAAgB,QAA0B;AACzD,MAAI,OAAO;AACX,MAAI,MAAM;AACV,WAAS,IAAI,GAAG,IAAI,UAAU,IAAI,OAAO,QAAQ,KAAK;AACpD,QAAI,OAAO,CAAC,MAAM,MAAM;AACtB;AACA,YAAM;AAAA,IACR,OAAO;AACL;AAAA,IACF;AAAA,EACF;AACA,SAAO,EAAE,MAAM,QAAQ,IAAI;AAC7B;","names":["parseSync","walk","readFileSync","readFileSync","parseSync","walk","lineAt"]}
|
package/dist/cli.js
CHANGED
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/narrow.ts","../src/rules/single-file/no-empty-catch.ts","../src/rules/single-file/no-non-null-assertion.ts","../src/rules/single-file/no-double-negation-coercion.ts","../src/rules/single-file/no-ts-ignore.ts","../src/rules/single-file/no-nullish-coalescing.ts","../src/rules/single-file/no-optional-call.ts","../src/rules/single-file/no-optional-property-access.ts","../src/rules/single-file/no-optional-element-access.ts","../src/utils/ast.ts","../src/rules/single-file/no-logical-or-fallback.ts","../src/rules/single-file/no-null-ternary-normalization.ts","../src/rules/single-file/no-any-cast.ts","../src/rules/single-file/no-explicit-any-annotation.ts","../src/rules/single-file/no-inline-type-in-params.ts","../src/rules/single-file/no-type-assertion.ts","../src/rules/single-file/no-redundant-existence-guard.ts","../src/rules/single-file/prefer-default-param-value.ts","../src/rules/single-file/prefer-required-param-with-guard.ts","../src/rules/cross-file/duplicate-type-declaration.ts","../src/rules/cross-file/duplicate-function-declaration.ts","../src/rules/cross-file/optional-arg-always-used.ts","../src/rules/single-file/no-catch-return.ts","../src/rules/single-file/no-error-rewrap.ts","../src/rules/cross-file/explicit-null-arg.ts","../src/rules/cross-file/duplicate-function-name.ts","../src/rules/cross-file/duplicate-type-name.ts","../src/rules/single-file/no-dynamic-import.ts","../src/rules/index.ts","../src/engine.ts","../src/rules/types.ts","../src/collect/index.ts","../src/utils/hash.ts","../src/collect/type-registry.ts","../src/collect/function-registry.ts"],"sourcesContent":["/**\n * Runtime node property access helpers.\n *\n * oxc-parser's runtime AST diverges from @oxc-project/types in some areas\n * (e.g., all literals use type \"Literal\" at runtime vs NullLiteral/StringLiteral in types).\n * These helpers provide typed access to common node shapes without `as any` casts.\n */\nimport type { Node } from \"oxc-parser\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- intentional escape hatch for untyped AST access\ntype AnyNode = Record<string, any>;\n\n/** Safely access a property on any AST node. */\nexport function prop<T = unknown>(node: Node, key: string): T {\n return (node as AnyNode)[key] as T;\n}\n\n/** Get child node. Returns Node or null. */\nexport function child(node: Node, key: string): Node | null {\n const val = (node as AnyNode)[key];\n if (val === undefined || val === null) return null;\n return val as Node;\n}\n\n/** Get child nodes array. Returns Node[] or empty. */\nexport function children(node: Node, key: string): Node[] {\n const val = (node as AnyNode)[key];\n if (!Array.isArray(val)) return [];\n return val as Node[];\n}\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\nimport { child, children } from \"../../utils/narrow.ts\";\n\nexport const noEmptyCatch: SingleFileRule = {\n id: \"no-empty-catch\",\n severity: \"error\",\n message: \"Empty catch blocks hide failures; handle, annotate, or rethrow explicitly\",\n\n visit(node: Node, _parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"CatchClause\") return;\n const body = child(node, \"body\");\n if (body && body.type === \"BlockStatement\" && children(body, \"body\").length === 0) {\n const hasComment = ctx.comments.some((c) => c.start >= body.start && c.end <= body.end);\n if (hasComment) return;\n ctx.report(node);\n }\n },\n};\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\n\nexport const noNonNullAssertion: SingleFileRule = {\n id: \"no-non-null-assertion\",\n severity: \"warning\",\n message: \"Non-null assertion (!) overrides the type checker; narrow with a type guard or fix the type so it's not nullable\",\n\n visit(node: Node, _parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"TSNonNullExpression\") return;\n ctx.report(node);\n },\n};\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\nimport { prop, child } from \"../../utils/narrow.ts\";\n\nexport const noDoubleNegationCoercion: SingleFileRule = {\n id: \"no-double-negation-coercion\",\n severity: \"info\",\n message: \"!! coercion hides intent; use an explicit check (!== null, !== undefined, .length > 0) so the condition documents what it tests\",\n\n visit(node: Node, _parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"UnaryExpression\") return;\n if (prop<string>(node, \"operator\") !== \"!\") return;\n const arg = child(node, \"argument\");\n if (arg !== null && arg.type === \"UnaryExpression\" && prop<string>(arg, \"operator\") === \"!\") {\n ctx.report(node);\n }\n },\n};\n","import type { Node, Comment } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\n\nexport const noTsIgnore: SingleFileRule = {\n id: \"no-ts-ignore\",\n severity: \"error\",\n message: \"@ts-ignore / @ts-expect-error suppresses type checking; fix the underlying type issue\",\n\n visit(_node: Node, _parent: Node | null, _ctx: VisitContext) {},\n\n visitComment(comment: Comment, ctx: VisitContext) {\n if (comment.value.includes(\"@ts-ignore\") || comment.value.includes(\"@ts-expect-error\")) {\n ctx.report(comment);\n }\n },\n};\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\nimport { prop } from \"../../utils/narrow.ts\";\n\nexport const noNullishCoalescing: SingleFileRule = {\n id: \"no-nullish-coalescing\",\n severity: \"warning\",\n message: \"Nullish coalescing (??) masks a possibly-nullable type; if the type guarantees non-null, remove the fallback; if not, fix the type upstream\",\n\n visit(node: Node, _parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"LogicalExpression\") return;\n if (prop<string>(node, \"operator\") !== \"??\") return;\n ctx.report(node);\n },\n};\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\nimport { prop } from \"../../utils/narrow.ts\";\n\nexport const noOptionalCall: SingleFileRule = {\n id: \"no-optional-call\",\n severity: \"warning\",\n message: \"Optional call (?.) assumes the function could be undefined; if the type guarantees it exists, call directly; if not, fix the type upstream\",\n\n visit(node: Node, _parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"CallExpression\") return;\n if (!prop<boolean>(node, \"optional\")) return;\n ctx.report(node);\n },\n};\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\nimport { prop } from \"../../utils/narrow.ts\";\n\nexport const noOptionalPropertyAccess: SingleFileRule = {\n id: \"no-optional-property-access\",\n severity: \"warning\",\n message: \"Optional chaining (?.) assumes the object could be nullish; if the type guarantees it, use a direct access; if not, fix the type upstream\",\n\n visit(node: Node, _parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"MemberExpression\") return;\n if (prop<boolean>(node, \"optional\") && !prop<boolean>(node, \"computed\")) {\n ctx.report(node);\n }\n },\n};\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\nimport { prop } from \"../../utils/narrow.ts\";\n\nexport const noOptionalElementAccess: SingleFileRule = {\n id: \"no-optional-element-access\",\n severity: \"warning\",\n message: \"Optional element access (?.[]) assumes the object could be nullish; if the type guarantees it, use a direct access; if not, fix the type upstream\",\n\n visit(node: Node, _parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"MemberExpression\") return;\n if (prop<boolean>(node, \"optional\") && prop<boolean>(node, \"computed\")) {\n ctx.report(node);\n }\n },\n};\n","import type { Node } from \"oxc-parser\";\nimport { prop } from \"./narrow.ts\";\n\n/** Check if a node is null or undefined literal. */\nexport function isNullish(node: Node): boolean {\n if (node.type === \"Literal\" && prop(node, \"value\") === null) return true;\n if (node.type === \"Identifier\" && prop<string>(node, \"name\") === \"undefined\") return true;\n return false;\n}\n\n/** Check if a node is a literal value. */\nexport function isLiteral(node: Node): boolean {\n switch (node.type) {\n case \"Literal\":\n case \"TemplateLiteral\":\n case \"ArrayExpression\":\n case \"ObjectExpression\":\n return true;\n case \"Identifier\":\n return prop<string>(node, \"name\") === \"undefined\";\n default:\n return false;\n }\n}\n\n/** Get source text for a node using its span. */\nexport function getNodeText(source: string, node: Node): string {\n return source.slice(node.start, node.end);\n}\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\nimport { prop, child } from \"../../utils/narrow.ts\";\nimport { isLiteral } from \"../../utils/ast.ts\";\n\nexport const noLogicalOrFallback: SingleFileRule = {\n id: \"no-logical-or-fallback\",\n severity: \"warning\",\n message: \"|| with a literal fallback assumes the left side could be falsy; if the type guarantees a value, remove the fallback; if not, fix the type upstream\",\n\n visit(node: Node, _parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"LogicalExpression\") return;\n if (prop<string>(node, \"operator\") !== \"||\") return;\n const right = child(node, \"right\");\n if (right && isLiteral(right)) {\n ctx.report(node);\n }\n },\n};\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\nimport { prop, child } from \"../../utils/narrow.ts\";\nimport { isNullish } from \"../../utils/ast.ts\";\n\nexport const noNullTernaryNormalization: SingleFileRule = {\n id: \"no-null-ternary-normalization\",\n severity: \"warning\",\n message: \"Ternary null-normalization (x == null ? fallback : x); if the type guarantees non-null, remove the ternary; if not, fix the type upstream\",\n\n visit(node: Node, _parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"ConditionalExpression\") return;\n const test = child(node, \"test\");\n if (test === null || test.type !== \"BinaryExpression\") return;\n const op = prop<string>(test, \"operator\");\n if (op !== \"===\" && op !== \"!==\" && op !== \"==\" && op !== \"!=\") return;\n const testLeft = child(test, \"left\");\n const testRight = child(test, \"right\");\n const hasNullishComparand =\n (testLeft !== null && isNullish(testLeft)) || (testRight !== null && isNullish(testRight));\n if (!hasNullishComparand) return;\n const consequent = child(node, \"consequent\");\n const alternate = child(node, \"alternate\");\n if ((consequent !== null && isNullish(consequent)) || (alternate !== null && isNullish(alternate))) {\n ctx.report(node);\n }\n },\n};\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\nimport { child } from \"../../utils/narrow.ts\";\n\nexport const noAnyCast: SingleFileRule = {\n id: \"no-any-cast\",\n severity: \"error\",\n message: \"Casting to `any` erases type safety; use a specific type or generic instead\",\n\n visit(node: Node, _parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"TSAsExpression\") return;\n const typeAnno = child(node, \"typeAnnotation\");\n if (typeAnno !== null && typeAnno.type === \"TSAnyKeyword\") {\n ctx.report(node);\n }\n },\n};\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\n\nexport const noExplicitAnyAnnotation: SingleFileRule = {\n id: \"no-explicit-any-annotation\",\n severity: \"warning\",\n message: \"Explicit `any` annotation erases type safety; use a specific type, `unknown`, or a generic\",\n\n visit(node: Node, parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"TSAnyKeyword\") return;\n // Skip if inside a cast (covered by no-any-cast)\n if (parent !== null && parent.type === \"TSAsExpression\") return;\n ctx.report(node);\n },\n};\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\n\nexport const noInlineTypeInParams: SingleFileRule = {\n id: \"no-inline-type-in-params\",\n severity: \"warning\",\n message: \"Inline type literal in annotation; extract to a named type for reuse and clarity\",\n\n visit(node: Node, parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"TSTypeLiteral\") return;\n if (parent === null || parent.type !== \"TSTypeAnnotation\") return;\n\n if (!isTopLevelFunctionParam(ctx.source, node.start)) return;\n\n ctx.report(node);\n },\n};\n\nfunction isTopLevelFunctionParam(source: string, offset: number): boolean {\n // Only flag if the nearest enclosing \"{\" is the module scope (no enclosing brace)\n // or a plain function body. Skip anything nested inside classes, interfaces,\n // object literals (builder patterns), etc.\n let depth = 0;\n for (let i = offset - 1; i >= 0; i--) {\n if (source[i] === \"}\") depth++;\n if (source[i] === \"{\") {\n if (depth === 0) {\n // Found the enclosing \"{\". If it belongs to a function declaration\n // or arrow, that's fine (we're in a nested function param). But if\n // it's anything else (class, interface, object literal), skip.\n // In practice: only flag when there's NO enclosing \"{\" at all\n // (module-level function), or the enclosing block is a function body.\n const before = source.slice(Math.max(0, i - 150), i).trimEnd();\n // Function body: preceded by \")\" or \"=> {\" or similar\n if (/(\\)|\\bfunction\\b.*\\))\\s*$/.test(before)) {\n // Inside a function body — keep walking to check if that function\n // is itself top-level or nested\n depth--;\n continue;\n }\n // Anything else (class, interface, object, etc.) — not top-level\n return false;\n }\n depth--;\n }\n }\n // Reached beginning of file with no unmatched \"{\" — module scope\n return true;\n}\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\nimport { child } from \"../../utils/narrow.ts\";\n\nexport const noTypeAssertion: SingleFileRule = {\n id: \"no-type-assertion\",\n severity: \"error\",\n message: \"Double type assertion (`as unknown as T`) circumvents the type system; fix the upstream type or use a type guard\",\n\n visit(node: Node, _parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"TSAsExpression\") return;\n // Check if the expression being cast is itself an `as unknown`\n const inner = child(node, \"expression\");\n if (inner === null || inner.type !== \"TSAsExpression\") return;\n const innerType = child(inner, \"typeAnnotation\");\n if (innerType === null || innerType.type !== \"TSUnknownKeyword\") return;\n ctx.report(node);\n },\n};\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\nimport { child, prop } from \"../../utils/narrow.ts\";\n\nexport const noRedundantExistenceGuard: SingleFileRule = {\n id: \"no-redundant-existence-guard\",\n severity: \"warning\",\n message: \"Redundant existence guard (obj && obj.prop); if the type guarantees obj exists, remove the guard; if not, fix the type upstream\",\n\n visit(node: Node, _parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"IfStatement\") return;\n const test = child(node, \"test\");\n if (!test || test.type !== \"LogicalExpression\" || prop<string>(test, \"operator\") !== \"&&\") return;\n\n const left = child(test, \"left\");\n const right = child(test, \"right\");\n if (!left || left.type !== \"Identifier\") return;\n if (!right || right.type !== \"MemberExpression\") return;\n const obj = child(right, \"object\");\n if (!obj || obj.type !== \"Identifier\") return;\n if (prop<string>(left, \"name\") !== prop<string>(obj, \"name\")) return;\n ctx.report(node);\n },\n};\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\nimport { prop, child, children } from \"../../utils/narrow.ts\";\n\nexport const preferDefaultParamValue: SingleFileRule = {\n id: \"prefer-default-param-value\",\n severity: \"info\",\n message: \"Use a default parameter value instead of reassigning from nullish coalescing inside the body\",\n\n visit(node: Node, _parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"FunctionDeclaration\" && node.type !== \"ArrowFunctionExpression\") return;\n const params = children(node, \"params\");\n const body = child(node, \"body\");\n if (body === null || body.type !== \"BlockStatement\") return;\n const stmts = children(body, \"body\");\n if (stmts.length === 0) return;\n\n const firstStmt = stmts[0];\n if (firstStmt.type !== \"ExpressionStatement\") return;\n const expr = child(firstStmt, \"expression\");\n if (expr === null || expr.type !== \"AssignmentExpression\" || prop<string>(expr, \"operator\") !== \"=\") return;\n\n const right = child(expr, \"right\");\n if (right === null || right.type !== \"LogicalExpression\" || prop<string>(right, \"operator\") !== \"??\") return;\n\n const assignee = child(expr, \"left\");\n const coalescedLeft = child(right, \"left\");\n if (assignee === null || assignee.type !== \"Identifier\") return;\n if (coalescedLeft === null || coalescedLeft.type !== \"Identifier\") return;\n if (prop<string>(assignee, \"name\") !== prop<string>(coalescedLeft, \"name\")) return;\n\n const assigneeName = prop<string>(assignee, \"name\");\n const isParam = params.some((p: Node) => {\n if (p.type === \"Identifier\") return prop<string>(p, \"name\") === assigneeName;\n if (p.type === \"AssignmentPattern\") {\n const left = child(p, \"left\");\n return left !== null && left.type === \"Identifier\" && prop<string>(left, \"name\") === assigneeName;\n }\n return false;\n });\n if (isParam) {\n ctx.report(firstStmt);\n }\n },\n};\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\nimport { prop, child, children } from \"../../utils/narrow.ts\";\n\nexport const preferRequiredParamWithGuard: SingleFileRule = {\n id: \"prefer-required-param-with-guard\",\n severity: \"info\",\n message: \"Optional param with immediate guard (if (!param) return/throw); make it required instead\",\n\n visit(node: Node, _parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"FunctionDeclaration\" && node.type !== \"ArrowFunctionExpression\") return;\n const params = children(node, \"params\");\n const body = child(node, \"body\");\n if (body === null || body.type !== \"BlockStatement\") return;\n const stmts = children(body, \"body\");\n if (stmts.length === 0) return;\n\n const firstStmt = stmts[0];\n if (firstStmt.type !== \"IfStatement\") return;\n\n const test = child(firstStmt, \"test\");\n if (test === null) return;\n let guardedName: string | null = null;\n\n // Pattern 1: if (!param)\n if (test.type === \"UnaryExpression\" && prop<string>(test, \"operator\") === \"!\") {\n const arg = child(test, \"argument\");\n if (arg !== null && arg.type === \"Identifier\") guardedName = prop<string>(arg, \"name\");\n }\n // Pattern 2: if (param === undefined)\n if (test.type === \"BinaryExpression\") {\n const op = prop<string>(test, \"operator\");\n if (op === \"===\" || op === \"==\") {\n const left = child(test, \"left\");\n const right = child(test, \"right\");\n if (\n left !== null &&\n left.type === \"Identifier\" &&\n right !== null &&\n right.type === \"Identifier\" &&\n prop<string>(right, \"name\") === \"undefined\"\n ) {\n guardedName = prop<string>(left, \"name\");\n }\n }\n }\n\n if (guardedName === null) return;\n\n const consequent = child(firstStmt, \"consequent\");\n if (consequent === null) return;\n const isGuard =\n consequent.type === \"ReturnStatement\" ||\n consequent.type === \"ThrowStatement\" ||\n (consequent.type === \"BlockStatement\" && isGuardBlock(consequent));\n\n if (!isGuard) return;\n\n const isOptionalParam = params.some(\n (p: Node) => p.type === \"Identifier\" && prop<string>(p, \"name\") === guardedName && prop<boolean>(p, \"optional\") === true,\n );\n if (isOptionalParam) {\n ctx.report(firstStmt);\n }\n },\n};\n\nfunction isGuardBlock(block: Node): boolean {\n const body = children(block, \"body\");\n if (body.length !== 1) return false;\n const stmt = body[0];\n return stmt.type === \"ReturnStatement\" || stmt.type === \"ThrowStatement\";\n}\n","import type { CrossFileRule, Diagnostic, ProjectIndex } from \"../types.ts\";\n\nexport const duplicateTypeDeclaration: CrossFileRule = {\n id: \"duplicate-type-declaration\",\n severity: \"warning\",\n message: \"Identical type shape declared in multiple files; consolidate to a single definition\",\n\n analyze(project: ProjectIndex): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n for (const group of project.types.getDuplicateGroups()) {\n // Only flag if types are in different files\n const files = new Set(group.map((e) => e.file));\n if (files.size < 2) continue;\n\n for (const entry of group) {\n const others = group\n .filter((e) => e !== entry)\n .map((e) => `${e.name} (${e.file}:${e.line})`)\n .join(\", \");\n diagnostics.push({\n ruleId: this.id,\n severity: this.severity,\n message: `Type \"${entry.name}\" has identical shape to: ${others}`,\n file: entry.file,\n line: entry.line,\n column: 1,\n });\n }\n }\n return diagnostics;\n },\n};\n","import type { CrossFileRule, Diagnostic, ProjectIndex } from \"../types.ts\";\n\nexport const duplicateFunctionDeclaration: CrossFileRule = {\n id: \"duplicate-function-declaration\",\n severity: \"warning\",\n message: \"Identical function body declared in multiple files; consolidate to a single definition\",\n\n analyze(project: ProjectIndex): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n for (const group of project.functions.getDuplicateGroups()) {\n const files = new Set(group.map((e) => e.file));\n if (files.size < 2) continue;\n\n for (const entry of group) {\n const others = group\n .filter((e) => e !== entry)\n .map((e) => `${e.name} (${e.file}:${e.line})`)\n .join(\", \");\n diagnostics.push({\n ruleId: this.id,\n severity: this.severity,\n message: `Function \"${entry.name}\" has identical body to: ${others}`,\n file: entry.file,\n line: entry.line,\n column: 1,\n });\n }\n }\n return diagnostics;\n },\n};\n","import type { CrossFileRule, Diagnostic, ProjectIndex } from \"../types.ts\";\n\nexport const optionalArgAlwaysUsed: CrossFileRule = {\n id: \"optional-arg-always-used\",\n severity: \"warning\",\n message: \"Optional parameter is always provided at every call site; make it required\",\n\n analyze(project: ProjectIndex): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n\n for (const fn of project.functions.getAll()) {\n // Find optional params (by index)\n for (let i = 0; i < fn.params.length; i++) {\n const param = fn.params[i];\n if (!param.optional && !param.hasDefault) continue;\n\n // Find all call sites matching this function name\n const callSites = project.callSites.filter((c) => c.calleeName === fn.name);\n\n // Need at least 2 call sites to be meaningful\n if (callSites.length < 2) continue;\n\n // Check if every call site provides this positional argument\n const allProvide = callSites.every((c) => c.argCount > i);\n if (allProvide) {\n diagnostics.push({\n ruleId: this.id,\n severity: this.severity,\n message: `Optional parameter \"${param.name}\" is always provided at all ${callSites.length} call sites; make it required`,\n file: fn.file,\n line: fn.line,\n column: 1,\n });\n }\n }\n }\n\n return diagnostics;\n },\n};\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\nimport { child, prop } from \"../../utils/narrow.ts\";\n\nexport const noCatchReturn: SingleFileRule = {\n id: \"no-catch-return\",\n severity: \"warning\",\n message:\n \"Catch block returns a fallback value, forcing callers to handle two data shapes; rethrow or let the error propagate\",\n\n visit(node: Node, _parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"CatchClause\") return;\n const body = child(node, \"body\");\n if (body === null) return;\n if (hasReturn(body) && !hasThrow(body)) {\n ctx.report(node);\n }\n },\n};\n\nfunction hasReturn(block: Node): boolean {\n return walkForType(block, \"ReturnStatement\");\n}\n\nfunction hasThrow(block: Node): boolean {\n return walkForType(block, \"ThrowStatement\");\n}\n\nfunction walkForType(root: Node, targetType: string): boolean {\n if (root.type === targetType) return true;\n const keys = Object.keys(root);\n for (const key of keys) {\n if (key === \"start\" || key === \"end\" || key === \"type\") continue;\n const val = prop<unknown>(root, key);\n if (val === null || val === undefined || typeof val !== \"object\") continue;\n // Skip nested function scopes — their returns/throws are their own\n if (isFunction(val as Node)) continue;\n if (Array.isArray(val)) {\n for (const item of val) {\n if (item !== null && typeof item === \"object\" && \"type\" in item) {\n if (isFunction(item as Node)) continue;\n if (walkForType(item as Node, targetType)) return true;\n }\n }\n } else if (\"type\" in val) {\n if (walkForType(val as Node, targetType)) return true;\n }\n }\n return false;\n}\n\nfunction isFunction(node: Node): boolean {\n return (\n node.type === \"FunctionDeclaration\" ||\n node.type === \"FunctionExpression\" ||\n node.type === \"ArrowFunctionExpression\"\n );\n}\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\nimport { prop, child, children } from \"../../utils/narrow.ts\";\n\nexport const noErrorRewrap: SingleFileRule = {\n id: \"no-error-rewrap\",\n severity: \"error\",\n message:\n \"Re-wrapped error loses the original stack trace and type; use { cause: originalError } to preserve the error chain\",\n\n visit(node: Node, _parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"CatchClause\") return;\n const param = child(node, \"param\");\n if (param === null || param.type !== \"Identifier\") return;\n const catchName = prop<string>(param, \"name\");\n const body = child(node, \"body\");\n if (body === null) return;\n findRewraps(body, catchName, ctx);\n },\n};\n\nfunction findRewraps(root: Node, catchName: string, ctx: VisitContext): void {\n if (root.type === \"ThrowStatement\") {\n const arg = child(root, \"argument\");\n if (arg !== null && arg.type === \"NewExpression\") {\n const args = children(arg, \"arguments\");\n if (args.length > 0 && referencesName(args, catchName) && !hasCauseArg(args)) {\n ctx.report(root);\n }\n }\n return;\n }\n // Skip nested function scopes\n if (\n root.type === \"FunctionDeclaration\" ||\n root.type === \"FunctionExpression\" ||\n root.type === \"ArrowFunctionExpression\"\n ) {\n return;\n }\n const keys = Object.keys(root);\n for (const key of keys) {\n if (key === \"start\" || key === \"end\" || key === \"type\") continue;\n const val = prop<unknown>(root, key);\n if (val === null || val === undefined || typeof val !== \"object\") continue;\n if (Array.isArray(val)) {\n for (const item of val) {\n if (item !== null && typeof item === \"object\" && \"type\" in item) {\n findRewraps(item as Node, catchName, ctx);\n }\n }\n } else if (\"type\" in val) {\n findRewraps(val as Node, catchName, ctx);\n }\n }\n}\n\nfunction referencesName(nodes: Node[], name: string): boolean {\n for (const node of nodes) {\n if (containsIdentifier(node, name)) return true;\n }\n return false;\n}\n\nfunction containsIdentifier(root: Node, name: string): boolean {\n if (root.type === \"Identifier\" && prop<string>(root, \"name\") === name) return true;\n const keys = Object.keys(root);\n for (const key of keys) {\n if (key === \"start\" || key === \"end\" || key === \"type\") continue;\n const val = prop<unknown>(root, key);\n if (val === null || val === undefined || typeof val !== \"object\") continue;\n if (Array.isArray(val)) {\n for (const item of val) {\n if (item !== null && typeof item === \"object\" && \"type\" in item) {\n if (containsIdentifier(item as Node, name)) return true;\n }\n }\n } else if (\"type\" in val) {\n if (containsIdentifier(val as Node, name)) return true;\n }\n }\n return false;\n}\n\nfunction hasCauseArg(args: Node[]): boolean {\n for (const arg of args) {\n if (arg.type === \"ObjectExpression\") {\n const props = children(arg, \"properties\");\n for (const p of props) {\n const key = child(p, \"key\");\n if (key !== null && key.type === \"Identifier\" && prop<string>(key, \"name\") === \"cause\") {\n return true;\n }\n }\n }\n }\n return false;\n}\n","import type { CrossFileRule, Diagnostic, ProjectIndex } from \"../types.ts\";\nimport { children } from \"../../utils/narrow.ts\";\nimport { isNullish } from \"../../utils/ast.ts\";\n\nexport const explicitNullArg: CrossFileRule = {\n id: \"explicit-null-arg\",\n severity: \"warning\",\n message: \"Explicit null/undefined passed to a project function; consider redesigning the interface to not accept nullish values\",\n\n analyze(project: ProjectIndex): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n\n // Build a set of known project function names for fast lookup\n const projectFnNames = new Set<string>();\n for (const fn of project.functions.getAll()) {\n projectFnNames.add(fn.name);\n }\n\n for (const site of project.callSites) {\n // Only flag calls to functions defined in the project\n if (!projectFnNames.has(site.calleeName)) continue;\n\n const args = children(site.node, \"arguments\");\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (arg === undefined) continue;\n if (isNullish(arg)) {\n const val = arg.type === \"Literal\" ? \"null\" : \"undefined\";\n diagnostics.push({\n ruleId: this.id,\n severity: this.severity,\n message: `Passing explicit ${val} to \"${site.calleeName}\" at argument ${i + 1}; consider redesigning the interface to not accept nullish values`,\n file: site.file,\n line: site.line,\n column: 1,\n });\n break; // one diagnostic per call site\n }\n }\n }\n\n return diagnostics;\n },\n};\n","import type { CrossFileRule, Diagnostic, ProjectIndex } from \"../types.ts\";\n\nexport const duplicateFunctionName: CrossFileRule = {\n id: \"duplicate-function-name\",\n severity: \"warning\",\n message: \"Same function name exported from multiple files; consolidate or rename to avoid ambiguity\",\n\n analyze(project: ProjectIndex): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n for (const group of project.functions.getNameCollisionGroups()) {\n // Skip groups already caught by duplicate-function-declaration (identical bodies)\n const hashes = new Set(group.map((e) => e.hash));\n if (hashes.size === 1) continue;\n\n for (const entry of group) {\n const others = group\n .filter((e) => e !== entry)\n .map((e) => `${e.file}:${e.line}`)\n .join(\", \");\n diagnostics.push({\n ruleId: this.id,\n severity: this.severity,\n message: `Exported function \"${entry.name}\" also defined in: ${others}`,\n file: entry.file,\n line: entry.line,\n column: 1,\n });\n }\n }\n return diagnostics;\n },\n};\n","import type { CrossFileRule, Diagnostic, ProjectIndex } from \"../types.ts\";\n\nexport const duplicateTypeName: CrossFileRule = {\n id: \"duplicate-type-name\",\n severity: \"warning\",\n message: \"Same type name exported from multiple files; consolidate or rename to avoid ambiguity\",\n\n analyze(project: ProjectIndex): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n for (const group of project.types.getNameCollisionGroups()) {\n // Skip groups already caught by duplicate-type-declaration (identical shapes)\n const hashes = new Set(group.map((e) => e.hash));\n if (hashes.size === 1) continue;\n\n for (const entry of group) {\n const others = group\n .filter((e) => e !== entry)\n .map((e) => `${e.file}:${e.line}`)\n .join(\", \");\n diagnostics.push({\n ruleId: this.id,\n severity: this.severity,\n message: `Exported type \"${entry.name}\" also defined in: ${others}`,\n file: entry.file,\n line: entry.line,\n column: 1,\n });\n }\n }\n return diagnostics;\n },\n};\n","import type { Node } from \"oxc-parser\";\nimport type { SingleFileRule, VisitContext } from \"../types.ts\";\n\nexport const noDynamicImport: SingleFileRule = {\n id: \"no-dynamic-import\",\n severity: \"error\",\n message: \"Dynamic import() breaks static analysis and hides dependencies; use a static import instead\",\n\n visit(node: Node, _parent: Node | null, ctx: VisitContext) {\n if (node.type !== \"ImportExpression\") return;\n ctx.report(node);\n },\n};\n","import type { Rule } from \"./types.ts\";\n\nimport { noEmptyCatch } from \"./single-file/no-empty-catch.ts\";\nimport { noNonNullAssertion } from \"./single-file/no-non-null-assertion.ts\";\nimport { noDoubleNegationCoercion } from \"./single-file/no-double-negation-coercion.ts\";\nimport { noTsIgnore } from \"./single-file/no-ts-ignore.ts\";\nimport { noNullishCoalescing } from \"./single-file/no-nullish-coalescing.ts\";\nimport { noOptionalCall } from \"./single-file/no-optional-call.ts\";\nimport { noOptionalPropertyAccess } from \"./single-file/no-optional-property-access.ts\";\nimport { noOptionalElementAccess } from \"./single-file/no-optional-element-access.ts\";\nimport { noLogicalOrFallback } from \"./single-file/no-logical-or-fallback.ts\";\nimport { noNullTernaryNormalization } from \"./single-file/no-null-ternary-normalization.ts\";\nimport { noAnyCast } from \"./single-file/no-any-cast.ts\";\nimport { noExplicitAnyAnnotation } from \"./single-file/no-explicit-any-annotation.ts\";\nimport { noInlineTypeInParams } from \"./single-file/no-inline-type-in-params.ts\";\nimport { noTypeAssertion } from \"./single-file/no-type-assertion.ts\";\nimport { noRedundantExistenceGuard } from \"./single-file/no-redundant-existence-guard.ts\";\nimport { preferDefaultParamValue } from \"./single-file/prefer-default-param-value.ts\";\nimport { preferRequiredParamWithGuard } from \"./single-file/prefer-required-param-with-guard.ts\";\nimport { duplicateTypeDeclaration } from \"./cross-file/duplicate-type-declaration.ts\";\nimport { duplicateFunctionDeclaration } from \"./cross-file/duplicate-function-declaration.ts\";\nimport { optionalArgAlwaysUsed } from \"./cross-file/optional-arg-always-used.ts\";\nimport { noCatchReturn } from \"./single-file/no-catch-return.ts\";\nimport { noErrorRewrap } from \"./single-file/no-error-rewrap.ts\";\nimport { explicitNullArg } from \"./cross-file/explicit-null-arg.ts\";\nimport { duplicateFunctionName } from \"./cross-file/duplicate-function-name.ts\";\nimport { duplicateTypeName } from \"./cross-file/duplicate-type-name.ts\";\nimport { noDynamicImport } from \"./single-file/no-dynamic-import.ts\";\n\nexport const allRules: Rule[] = [\n noEmptyCatch,\n noNonNullAssertion,\n noDoubleNegationCoercion,\n noTsIgnore,\n noNullishCoalescing,\n noOptionalCall,\n noOptionalPropertyAccess,\n noOptionalElementAccess,\n noLogicalOrFallback,\n noNullTernaryNormalization,\n noAnyCast,\n noExplicitAnyAnnotation,\n noInlineTypeInParams,\n noTypeAssertion,\n noRedundantExistenceGuard,\n preferDefaultParamValue,\n preferRequiredParamWithGuard,\n duplicateTypeDeclaration,\n duplicateFunctionDeclaration,\n optionalArgAlwaysUsed,\n noCatchReturn,\n noErrorRewrap,\n explicitNullArg,\n duplicateFunctionName,\n duplicateTypeName,\n noDynamicImport,\n];\n","import { parseSync, type Comment } from \"oxc-parser\";\nimport { walk } from \"oxc-walker\";\nimport fg from \"fast-glob\";\nimport { readFileSync } from \"node:fs\";\nimport type { Node } from \"oxc-parser\";\nimport type { Diagnostic, SingleFileRule, CrossFileRule, Span, VisitContext } from \"./rules/types.ts\";\nimport { allRules } from \"./rules/index.ts\";\nimport { isSingleFileRule } from \"./rules/types.ts\";\nimport { collectProject } from \"./collect/index.ts\";\n\nexport interface ScanOptions {\n paths: string[];\n strict?: boolean;\n rules?: string[];\n}\n\nexport interface ScanResult {\n diagnostics: Diagnostic[];\n fileCount: number;\n}\n\nexport async function scan(options: ScanOptions): Promise<ScanResult> {\n const patterns = options.paths.length > 0 ? options.paths : [\".\"];\n const globs = patterns.map((p) => {\n if (p === \".\") return `./**/*.{ts,cts,mts,tsx}`;\n if (p.endsWith(\"/\")) return `${p}**/*.{ts,cts,mts,tsx}`;\n if (!p.includes(\"*\") && !p.endsWith(\".ts\") && !p.endsWith(\".tsx\") && !p.endsWith(\".cts\") && !p.endsWith(\".mts\")) {\n return `${p}/**/*.{ts,cts,mts,tsx}`;\n }\n return p;\n });\n\n const files = await fg(globs, {\n ignore: [\"**/node_modules/**\", \"**/dist/**\", \"**/.git/**\", \"**/*.d.ts\", \"**/*.d.cts\", \"**/*.d.mts\"],\n absolute: true,\n });\n\n const activeRules = allRules.filter((r) => {\n if (options.rules && !options.rules.includes(r.id)) return false;\n return true;\n });\n\n const singleFileRules = activeRules.filter(isSingleFileRule);\n const crossFileRules = activeRules.filter((r): r is CrossFileRule => !isSingleFileRule(r));\n const diagnostics: Diagnostic[] = [];\n\n // Single-file pass: parse each file and run visitor rules\n for (const file of files) {\n const source = readFileSync(file, \"utf8\");\n const result = parseSync(file, source);\n const fileDiags = runSingleFileRules(singleFileRules, result.program, result.comments, source, file);\n annotate(fileDiags, result.comments, source);\n diagnostics.push(...fileDiags);\n }\n\n // Cross-file pass: collect project index and run analysis rules\n if (crossFileRules.length > 0 && files.length > 0) {\n const projectIndex = collectProject(files);\n for (const rule of crossFileRules) {\n const crossDiags = rule.analyze(projectIndex);\n for (const d of crossDiags) {\n const fileData = projectIndex.files.get(d.file);\n if (fileData !== undefined) annotate([d], fileData.comments, fileData.source);\n }\n diagnostics.push(...crossDiags);\n }\n }\n\n const seen = new Set<string>();\n const deduped: Diagnostic[] = [];\n for (const d of diagnostics) {\n const key = `${d.file}:${d.line}:${d.ruleId}`;\n if (seen.has(key)) continue;\n seen.add(key);\n deduped.push(d);\n }\n\n if (options.strict) {\n for (const d of deduped) {\n d.severity = \"error\";\n }\n }\n\n return { diagnostics: deduped, fileCount: files.length };\n}\n\nexport function runSingleFileRules(\n rules: SingleFileRule[],\n program: Node,\n comments: Comment[],\n source: string,\n filename: string,\n): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n\n const makeCtx = (rule: SingleFileRule): VisitContext => ({\n filename,\n source,\n comments,\n report(span: Span, message?: string) {\n const pos = lineCol(source, span.start);\n diagnostics.push({\n ruleId: rule.id,\n severity: rule.severity,\n message: message === undefined ? rule.message : message,\n file: filename,\n ...pos,\n });\n },\n });\n\n const contexts = rules.map((r) => ({ rule: r, ctx: makeCtx(r) }));\n\n walk(program, {\n enter(node: Node, parent: Node | null) {\n for (const { rule, ctx } of contexts) {\n rule.visit(node, parent, ctx);\n }\n },\n });\n\n for (const { rule, ctx } of contexts) {\n if (rule.visitComment) {\n for (const comment of comments) {\n rule.visitComment(comment, ctx);\n }\n }\n }\n\n return diagnostics;\n}\n\ninterface Position {\n line: number;\n column: number;\n}\n\n/**\n * Attach annotations from comments to diagnostics.\n * A comment annotates a diagnostic if it ends on the line immediately above.\n * Consecutive line comments are joined into a single annotation.\n */\nfunction annotate(diagnostics: Diagnostic[], comments: Comment[], source: string): void {\n if (comments.length === 0 || diagnostics.length === 0) return;\n\n // Build a map: endLine -> comment\n const byEndLine = new Map<number, Comment[]>();\n for (const c of comments) {\n const endLine = lineAt(source, c.end);\n let list = byEndLine.get(endLine);\n if (list === undefined) {\n list = [];\n byEndLine.set(endLine, list);\n }\n list.push(c);\n }\n\n for (const d of diagnostics) {\n // Check inline comment on the same line first\n const inline = findInlineComment(d.line, byEndLine);\n if (inline !== null) {\n d.annotation = inline;\n continue;\n }\n // Then check comment(s) on the line above\n const above = collectAnnotation(d.line - 1, byEndLine, source);\n if (above !== null) d.annotation = above;\n }\n}\n\nfunction findInlineComment(diagLine: number, byEndLine: Map<number, Comment[]>): string | null {\n const commentsOnLine = byEndLine.get(diagLine);\n if (commentsOnLine === undefined || commentsOnLine.length === 0) return null;\n const comment = commentsOnLine.at(-1);\n if (comment === undefined) return null;\n // Only line comments (// ...) count as inline annotations, not block comments\n if (comment.type !== \"Line\") return null;\n const text = comment.value.trim();\n // Skip @expect annotations — those are for the test harness, not user annotations\n if (text.startsWith(\"@expect\")) return null;\n return text;\n}\n\nfunction collectAnnotation(\n commentEndLine: number,\n byEndLine: Map<number, Comment[]>,\n source: string,\n): string | null {\n const commentsOnLine = byEndLine.get(commentEndLine);\n if (commentsOnLine === undefined || commentsOnLine.length === 0) return null;\n const comment = commentsOnLine.at(-1);\n if (comment === undefined) return null;\n\n // Block comment: use its value directly\n if (comment.type === \"Block\") {\n return cleanBlockComment(comment.value);\n }\n\n // Line comment: walk upward to collect consecutive line comments\n const lines: string[] = [comment.value.trim()];\n let prevLine = commentEndLine - 1;\n for (;;) {\n const prev = byEndLine.get(prevLine);\n if (prev === undefined || prev.length === 0) break;\n const prevComment = prev.at(-1);\n if (prevComment === undefined || prevComment.type !== \"Line\") break;\n if (lineAt(source, prevComment.start) !== prevLine) break;\n lines.unshift(prevComment.value.trim());\n prevLine--;\n }\n\n return lines.join(\"\\n\");\n}\n\nfunction cleanBlockComment(value: string): string {\n return value\n .split(\"\\n\")\n .map((line) => line.replace(/^\\s*\\*\\s?/, \"\").trim())\n .filter((line) => line.length > 0)\n .join(\"\\n\");\n}\n\nfunction lineAt(source: string, offset: number): number {\n let line = 1;\n for (let i = 0; i < offset && i < source.length; i++) {\n if (source[i] === \"\\n\") line++;\n }\n return line;\n}\n\nfunction lineCol(source: string, offset: number): Position {\n let line = 1;\n let col = 1;\n for (let i = 0; i < offset && i < source.length; i++) {\n if (source[i] === \"\\n\") {\n line++;\n col = 1;\n } else {\n col++;\n }\n }\n return { line, column: col };\n}\n","import type { Node, Comment } from \"oxc-parser\";\n\nexport interface Diagnostic {\n ruleId: string;\n severity: \"info\" | \"warning\" | \"error\";\n message: string;\n file: string;\n line: number;\n column: number;\n annotation?: string;\n}\n\nexport interface Span {\n start: number;\n end: number;\n}\n\nexport interface VisitContext {\n report(span: Span, message?: string): void;\n filename: string;\n source: string;\n comments: Comment[];\n}\n\nexport interface SingleFileRule {\n id: string;\n severity: \"info\" | \"warning\" | \"error\";\n message: string;\n visit(node: Node, parent: Node | null, ctx: VisitContext): void;\n visitComment?(comment: Comment, ctx: VisitContext): void;\n}\n\nimport type { ProjectIndex } from \"../collect/index.ts\";\nexport type { ProjectIndex };\n\nexport interface CrossFileRule {\n id: string;\n severity: \"info\" | \"warning\" | \"error\";\n message: string;\n analyze(project: ProjectIndex): Diagnostic[];\n}\n\nexport type Rule = SingleFileRule | CrossFileRule;\n\nexport function isSingleFileRule(r: Rule): r is SingleFileRule {\n return \"visit\" in r;\n}\n","import { parseSync, type Comment } from \"oxc-parser\";\nimport { walk } from \"oxc-walker\";\nimport { readFileSync } from \"node:fs\";\nimport type { Node } from \"oxc-parser\";\nimport { TypeRegistry } from \"./type-registry.ts\";\nimport { FunctionRegistry, type FunctionEntry, type ParamInfo } from \"./function-registry.ts\";\nimport { hashFunctionBody } from \"../utils/hash.ts\";\nimport { prop, child, children } from \"../utils/narrow.ts\";\n\nexport interface ProjectIndex {\n types: TypeRegistry;\n functions: FunctionRegistry;\n callSites: CallSite[];\n files: Map<string, { source: string; program: Node; comments: Comment[] }>;\n}\n\nexport interface CallSite {\n calleeName: string;\n file: string;\n line: number;\n argCount: number;\n node: Node;\n}\n\nexport function collectProject(files: string[]): ProjectIndex {\n const types = new TypeRegistry();\n const functions = new FunctionRegistry();\n const callSites: CallSite[] = [];\n const fileMap = new Map<string, { source: string; program: Node; comments: Comment[] }>();\n\n for (const file of files) {\n const source = readFileSync(file, \"utf8\");\n const result = parseSync(file, source);\n fileMap.set(file, { source, program: result.program, comments: result.comments });\n\n walk(result.program, {\n enter(node: Node, parent: Node | null) {\n collectTypes(node, parent, file, source, types);\n collectFunctions(node, parent, file, source, functions);\n collectCallSites(node, file, source, callSites);\n },\n });\n }\n\n return { types, functions, callSites, files: fileMap };\n}\n\nfunction lineAt(source: string, offset: number): number {\n let line = 1;\n for (let i = 0; i < offset; i++) {\n if (source[i] === \"\\n\") line++;\n }\n return line;\n}\n\nfunction collectTypes(node: Node, parent: Node | null, file: string, source: string, registry: TypeRegistry): void {\n if (node.type === \"TSTypeAliasDeclaration\") {\n const id = child(node, \"id\");\n const typeAnno = child(node, \"typeAnnotation\");\n if (id && typeAnno) {\n registry.add(prop<string>(id, \"name\"), file, lineAt(source, node.start), typeAnno, source, isExported(parent));\n }\n }\n if (node.type === \"TSInterfaceDeclaration\") {\n const id = child(node, \"id\");\n const body = child(node, \"body\");\n if (id && body) {\n registry.add(prop<string>(id, \"name\"), file, lineAt(source, node.start), body, source, isExported(parent));\n }\n }\n}\n\nfunction isExported(parent: Node | null): boolean {\n if (parent === null) return false;\n return parent.type === \"ExportNamedDeclaration\" || parent.type === \"ExportDefaultDeclaration\";\n}\n\nfunction collectFunctions(node: Node, parent: Node | null, file: string, source: string, registry: FunctionRegistry): void {\n if (node.type === \"FunctionDeclaration\" || node.type === \"FunctionExpression\") {\n const id = child(node, \"id\");\n const body = child(node, \"body\");\n if (!id || !body) return;\n const name = prop<string>(id, \"name\");\n const params = extractParams(children(node, \"params\"), source);\n const hash = hashFunctionBody(body, source);\n const exported = isExported(parent);\n registry.add({ name, file, line: lineAt(source, node.start), hash, params, node, exported });\n }\n // Arrow functions assigned to const\n if (node.type === \"VariableDeclarator\") {\n const init = child(node, \"init\");\n const id = child(node, \"id\");\n if (init !== null && init.type === \"ArrowFunctionExpression\" && id !== null && id.type === \"Identifier\") {\n const body = child(init, \"body\");\n if (!body) return;\n const name = prop<string>(id, \"name\");\n const params = extractParams(children(init, \"params\"), source);\n const hash = hashFunctionBody(body, source);\n // Parent is VariableDeclaration; check if \"export\" precedes the declaration on the same line\n const lineStart = source.lastIndexOf(\"\\n\", node.start) + 1;\n const linePrefix = source.slice(lineStart, node.start);\n const exported = linePrefix.includes(\"export\");\n registry.add({ name, file, line: lineAt(source, node.start), hash, params, node, exported });\n }\n }\n}\n\nfunction paramName(node: Node, source: string): string {\n const name = prop<string>(node, \"name\");\n if (name !== undefined) return name;\n return source.slice(node.start, node.end);\n}\n\nfunction typeText(node: Node | null, source: string): string | null {\n if (node === null) return null;\n return source.slice(node.start, node.end);\n}\n\nfunction extractParams(params: Node[], source: string): ParamInfo[] {\n return params.map((p) => {\n if (p.type === \"AssignmentPattern\") {\n const left = child(p, \"left\");\n if (left === null) {\n return { name: \"?\", optional: false, hasDefault: true, typeText: null };\n }\n return {\n name: paramName(left, source),\n optional: prop<boolean>(left, \"optional\") === true,\n hasDefault: true,\n typeText: typeText(child(left, \"typeAnnotation\"), source),\n };\n }\n const typeAnno = child(p, \"typeAnnotation\");\n return {\n name: paramName(p, source),\n optional: prop<boolean>(p, \"optional\") === true,\n hasDefault: false,\n typeText: typeText(typeAnno, source),\n };\n });\n}\n\nfunction collectCallSites(node: Node, file: string, source: string, sites: CallSite[]): void {\n if (node.type !== \"CallExpression\") return;\n const callee = child(node, \"callee\");\n let calleeName: string | null = null;\n if (callee !== null && callee.type === \"Identifier\") {\n calleeName = prop<string>(callee, \"name\");\n } else if (callee !== null && callee.type === \"MemberExpression\" && prop<boolean>(callee, \"computed\") !== true) {\n const property = child(callee, \"property\");\n if (property) calleeName = prop<string>(property, \"name\");\n }\n if (calleeName) {\n sites.push({\n calleeName,\n file,\n line: lineAt(source, node.start),\n argCount: children(node, \"arguments\").length,\n node,\n });\n }\n}\n","import { createHash } from \"node:crypto\";\nimport type { Node } from \"oxc-parser\";\nimport { prop, child, children } from \"./narrow.ts\";\n\n/**\n * Create a structural hash of a type node.\n * Normalizes by sorting property names and stripping locations.\n */\nexport function hashTypeShape(node: Node, source: string): string {\n const normalized = normalizeTypeNode(node, source);\n return createHash(\"sha256\").update(normalized).digest(\"hex\").slice(0, 16);\n}\n\nfunction normalizeTypeNode(node: Node, source: string): string {\n if (node.type === \"TSTypeLiteral\") {\n const members = children(node, \"members\");\n const normalized = members.map((m) => normalizeTypeNode(m, source)).sort().join(\";\");\n return `{${normalized}}`;\n }\n if (node.type === \"TSInterfaceBody\") {\n const members = children(node, \"body\");\n const normalized = members.map((m) => normalizeTypeNode(m, source)).sort().join(\";\");\n return `{${normalized}}`;\n }\n if (node.type === \"TSPropertySignature\") {\n const key = child(node, \"key\");\n const rawName = key ? prop<string>(key, \"name\") : undefined;\n const keyName = rawName !== undefined ? rawName : key ? source.slice(key.start, key.end) : \"?\";\n const typeAnno = child(node, \"typeAnnotation\");\n const innerType = typeAnno ? child(typeAnno, \"typeAnnotation\") : null;\n const type = innerType ? normalizeTypeNode(innerType, source) : \"any\";\n const optional = prop<boolean>(node, \"optional\") ? \"?\" : \"\";\n return `${keyName}${optional}:${type}`;\n }\n if (node.type === \"TSTypeAnnotation\") {\n const inner = child(node, \"typeAnnotation\");\n return inner ? normalizeTypeNode(inner, source) : \"any\";\n }\n // Fallback: use source text with whitespace normalized\n return source.slice(node.start, node.end).replace(/\\s+/g, \" \").trim();\n}\n\n/**\n * Hash a function body for duplicate detection.\n * Normalizes whitespace.\n */\nexport function hashFunctionBody(node: Node, source: string): string {\n const bodyText = source.slice(node.start, node.end);\n const normalized = bodyText.replace(/\\s+/g, \" \").trim();\n return createHash(\"sha256\").update(normalized).digest(\"hex\").slice(0, 16);\n}\n","import type { Node } from \"oxc-parser\";\nimport { hashTypeShape } from \"../utils/hash.ts\";\n\nexport interface TypeEntry {\n name: string;\n file: string;\n line: number;\n hash: string;\n node: Node;\n exported: boolean;\n}\n\nexport class TypeRegistry {\n private entries: TypeEntry[] = [];\n private byHash = new Map<string, TypeEntry[]>();\n\n add(name: string, file: string, line: number, typeNode: Node, source: string, exported: boolean): void {\n const hash = hashTypeShape(typeNode, source);\n const entry: TypeEntry = { name, file, line, hash, node: typeNode, exported };\n this.entries.push(entry);\n let list = this.byHash.get(hash);\n if (list === undefined) {\n list = [];\n this.byHash.set(hash, list);\n }\n list.push(entry);\n }\n\n getDuplicateGroups(): TypeEntry[][] {\n return [...this.byHash.values()].filter((group) => group.length > 1);\n }\n\n getAll(): TypeEntry[] {\n return this.entries;\n }\n\n getNameCollisionGroups(): TypeEntry[][] {\n const byName = new Map<string, TypeEntry[]>();\n for (const entry of this.entries) {\n if (!entry.exported) continue;\n let list = byName.get(entry.name);\n if (list === undefined) {\n list = [];\n byName.set(entry.name, list);\n }\n list.push(entry);\n }\n return [...byName.values()].filter((group) => {\n if (group.length < 2) return false;\n const files = new Set(group.map((e) => e.file));\n return files.size > 1;\n });\n }\n}\n","import type { Node } from \"oxc-parser\";\n\nexport interface ParamInfo {\n name: string;\n optional: boolean;\n hasDefault: boolean;\n typeText: string | null;\n}\n\nexport interface FunctionEntry {\n name: string;\n file: string;\n line: number;\n hash: string;\n params: ParamInfo[];\n node: Node;\n exported: boolean;\n}\n\nexport class FunctionRegistry {\n private entries: FunctionEntry[] = [];\n private byHash = new Map<string, FunctionEntry[]>();\n\n add(entry: FunctionEntry): void {\n this.entries.push(entry);\n let list = this.byHash.get(entry.hash);\n if (list === undefined) {\n list = [];\n this.byHash.set(entry.hash, list);\n }\n list.push(entry);\n }\n\n getDuplicateGroups(): FunctionEntry[][] {\n return [...this.byHash.values()].filter((group) => group.length > 1);\n }\n\n getAll(): FunctionEntry[] {\n return this.entries;\n }\n\n getByName(name: string): FunctionEntry[] {\n return this.entries.filter((e) => e.name === name);\n }\n\n getNameCollisionGroups(): FunctionEntry[][] {\n const byName = new Map<string, FunctionEntry[]>();\n for (const entry of this.entries) {\n if (!entry.exported) continue;\n let list = byName.get(entry.name);\n if (list === undefined) {\n list = [];\n byName.set(entry.name, list);\n }\n list.push(entry);\n }\n return [...byName.values()].filter((group) => {\n if (group.length < 2) return false;\n const files = new Set(group.map((e) => e.file));\n return files.size > 1;\n });\n }\n}\n"],"mappings":"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","names":["parseSync","walk","readFileSync","readFileSync","parseSync","walk","lineAt"]}
|