unguard 0.16.0 → 0.16.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyze-Cccs9TDD.js","names":["normalizeText","isLengthAccess","statementTerminates","isZeroLiteral"],"sources":["../src/rules/cross-file/call-site-utils.ts","../src/rules/cross-file/constant-argument.ts","../src/rules/cross-file/dead-overload.ts","../src/rules/types.ts","../src/rules/cross-file/duplicate-constant-declaration.ts","../src/rules/cross-file/duplicate-file.ts","../src/rules/cross-file/duplicate-function-declaration.ts","../src/rules/cross-file/duplicate-function-name.ts","../src/rules/cross-file/duplicate-inline-type-in-params.ts","../src/rules/cross-file/duplicate-statement-sequence.ts","../src/rules/cross-file/duplicate-type-declaration.ts","../src/rules/cross-file/duplicate-type-name.ts","../src/typecheck/utils.ts","../src/rules/cross-file/explicit-null-arg.ts","../src/rules/cross-file/near-duplicate-function.ts","../src/rules/cross-file/optional-arg-always-used.ts","../src/rules/cross-file/optional-arg-never-used.ts","../src/rules/cross-file/repeated-literal-property.ts","../src/rules/cross-file/object-shape.ts","../src/rules/cross-file/repeated-return-shape.ts","../src/rules/cross-file/trivial-wrapper.ts","../src/rules/cross-file/unused-export.ts","../src/rules/ts/no-any-cast.ts","../src/rules/ts/no-await-coalesce.ts","../src/rules/ts/no-coalesce-then-guard.ts","../src/rules/ts/no-coalesce-undefined.ts","../src/rules/ts/no-dead-narrowing.ts","../src/rules/ts/no-defaulted-required-port-arg.ts","../src/rules/ts/no-double-negation-coercion.ts","../src/rules/ts/no-dynamic-import.ts","../src/rules/ts/no-error-rewrap.ts","../src/rules/ts/no-explicit-any-annotation.ts","../src/rules/ts/no-inline-param-type.ts","../src/rules/ts/no-inline-type-assertion.ts","../src/rules/ts/no-never-cast.ts","../src/rules/ts/no-redundant-cast.ts","../src/rules/ts/no-unvalidated-cast.ts","../src/rules/ts/no-useless-await.ts","../src/rules/ts/redundant-boolean-branch.ts","../src/rules/ts/redundant-destructure-default.ts","../src/rules/ts/redundant-narrowing-then-cast.ts","../src/rules/ts/trivial-type-alias.ts","../src/rules/ts/return-type-widens-via-destructure.ts","../src/rules/ts/prefer-type-predicate.ts","../src/rules/ts/no-logical-or-fallback.ts","../src/rules/ts/no-non-null-assertion.ts","../src/rules/ts/no-swallowed-catch.ts","../src/rules/ts/no-null-ternary-normalization.ts","../src/rules/ts/no-nullish-coalescing.ts","../src/rules/ts/optional-chain.ts","../src/rules/ts/no-optional-call.ts","../src/rules/ts/no-optional-element-access.ts","../src/rules/ts/no-optional-property-access.ts","../src/rules/ts/no-redundant-existence-guard.ts","../src/rules/ts/no-ts-expect-error.ts","../src/rules/ts/no-ts-ignore.ts","../src/rules/ts/no-type-assertion.ts","../src/rules/ts/optional-param-coerced-in-body.ts","../src/rules/index.ts","../src/utils/hash.ts","../src/collect/base-registry.ts","../src/collect/type-registry.ts","../src/collect/function-registry.ts","../src/collect/constant-registry.ts","../src/collect/statement-sequence-registry.ts","../src/collect/inline-type-registry.ts","../src/typecheck/walk.ts","../src/typecheck/semantic-cache.ts","../src/collect/index.ts","../src/typecheck/program.ts","../src/scan/worker-pool.ts","../src/scan/analyze.ts"],"sourcesContent":["import * as ts from \"typescript\";\nimport type { CallSite } from \"../../collect/index.ts\";\nimport type { FunctionEntry, ParamInfo } from \"../../collect/function-registry.ts\";\nimport type { ProjectIndex } from \"../types.ts\";\n\n/**\n * Call sites that license a signature change: symbol-matched, enough of them\n * to be a signal, none with spread arguments (arity unknowable), and the\n * function owns its signature (not an interface implementation, no rest\n * parameter). Returns null when any precondition fails.\n */\nexport function signatureChangeCallSites(\n fn: FunctionEntry,\n project: ProjectIndex,\n minSites: number,\n): CallSite[] | null {\n if (fn.symbol === undefined) return null;\n if (fn.implementsInterface) return null;\n if (hasRestParam(fn.node)) return null;\n const callSites = project.callSites.filter((c) => c.symbol === fn.symbol);\n if (callSites.length < minSites) return null;\n if (callSites.some((c) => c.node.arguments.some(ts.isSpreadElement))) return null;\n return callSites;\n}\n\n/** Optional/defaulted parameters with their positional index. */\nexport function optionalParams(fn: FunctionEntry): Array<{ index: number; param: ParamInfo }> {\n const result: Array<{ index: number; param: ParamInfo }> = [];\n for (let i = 0; i < fn.params.length; i++) {\n const param = fn.params[i];\n if (param === undefined) continue;\n if (!param.optional && !param.hasDefault) continue;\n result.push({ index: i, param });\n }\n return result;\n}\n\nfunction hasRestParam(node: ts.Node): boolean {\n if (!ts.isFunctionLike(node)) return false;\n return node.parameters.some((p) => p.dotDotDotToken !== undefined);\n}\n","import * as ts from \"typescript\";\nimport type { CrossFileRule, Diagnostic, ProjectIndex } from \"../types.ts\";\nimport { signatureChangeCallSites } from \"./call-site-utils.ts\";\n\n/**\n * A parameter that receives the identical literal at every call site is not\n * really a parameter — the \"choice\" it offers is never exercised. Inline the\n * value and fold any branching on it.\n */\nexport const constantArgument: CrossFileRule = {\n id: \"constant-argument\",\n severity: \"warning\",\n message: \"Parameter receives the same literal at every call site; inline the value\",\n requires: [\"functions\", \"functionSymbols\", \"callSites\", \"callSiteSymbols\"],\n\n analyze(project: ProjectIndex): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n\n for (const fn of project.functions.getAll()) {\n const callSites = signatureChangeCallSites(fn, project, 3);\n if (callSites === null) continue;\n\n for (let i = 0; i < fn.params.length; i++) {\n const param = fn.params[i];\n if (param === undefined) continue;\n\n const texts = callSites.map((c) => literalArgText(c.node.arguments[i]));\n const first = texts[0];\n if (first === null || first === undefined) continue;\n if (!texts.every((t) => t === first)) continue;\n\n diagnostics.push({\n ruleId: this.id,\n severity: this.severity,\n message: `Parameter \"${param.name}\" receives ${first} at all ${callSites.length} call sites; inline the value and remove the parameter`,\n file: fn.file,\n line: fn.line,\n column: 1,\n });\n }\n }\n\n return diagnostics;\n },\n};\n\n/** Source text of a value-stable literal argument, or null. */\nfunction literalArgText(arg: ts.Expression | undefined): string | null {\n if (arg === undefined) return null;\n if (ts.isStringLiteral(arg) || ts.isNoSubstitutionTemplateLiteral(arg)) return arg.getText();\n if (ts.isNumericLiteral(arg)) return arg.getText();\n if (\n ts.isPrefixUnaryExpression(arg) &&\n arg.operator === ts.SyntaxKind.MinusToken &&\n ts.isNumericLiteral(arg.operand)\n ) {\n return arg.getText();\n }\n if (\n arg.kind === ts.SyntaxKind.TrueKeyword ||\n arg.kind === ts.SyntaxKind.FalseKeyword ||\n arg.kind === ts.SyntaxKind.NullKeyword\n ) {\n return arg.getText();\n }\n return null;\n}\n","import * as ts from \"typescript\";\nimport type { CrossFileRule, Diagnostic, ProjectIndex } from \"../types.ts\";\n\ntype OverloadDeclaration = ts.FunctionDeclaration | ts.MethodDeclaration;\n\ninterface OverloadFamily {\n name: string;\n file: string;\n sourceFile: ts.SourceFile;\n overloads: OverloadDeclaration[];\n implementation: OverloadDeclaration;\n}\n\nexport const deadOverload: CrossFileRule = {\n id: \"dead-overload\",\n severity: \"warning\",\n message: \"Overload signature has no matching call sites in the project\",\n requires: [\"files\", \"callSites\", \"overloadCallSignatures\"],\n\n analyze(project: ProjectIndex): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n\n for (const [file, { sourceFile }] of project.files) {\n for (const family of collectOverloadFamilies(sourceFile, file)) {\n const matchedOverloads = new Set<OverloadDeclaration>();\n\n for (const site of project.callSites) {\n const declaration = site.resolvedDeclaration;\n if (declaration === undefined) continue;\n if (family.overloads.includes(declaration as OverloadDeclaration)) {\n matchedOverloads.add(declaration as OverloadDeclaration);\n }\n }\n\n if (matchedOverloads.size === 0) continue;\n\n const deadOverloads = family.overloads.filter((overload) => !matchedOverloads.has(overload));\n const liveOverloads = family.overloads.filter((overload) => matchedOverloads.has(overload));\n\n for (const overload of deadOverloads) {\n diagnostics.push({\n ruleId: this.id,\n severity: this.severity,\n message: buildMessage(family, overload, deadOverloads, liveOverloads),\n file,\n line: lineOf(sourceFile, overload),\n column: 1,\n });\n }\n }\n }\n\n return diagnostics;\n },\n};\n\nfunction buildMessage(\n family: OverloadFamily,\n overload: OverloadDeclaration,\n deadOverloads: OverloadDeclaration[],\n liveOverloads: OverloadDeclaration[],\n): string {\n const base = `Overload signature for \"${family.name}\" has no matching call sites in the project`;\n if (!shouldMentionCascade(family, overload, deadOverloads, liveOverloads)) {\n return base;\n }\n return `${base}; removing it may let you collapse to the remaining constrained signature and drop implementation casts`;\n}\n\nfunction shouldMentionCascade(\n family: OverloadFamily,\n overload: OverloadDeclaration,\n deadOverloads: OverloadDeclaration[],\n liveOverloads: OverloadDeclaration[],\n): boolean {\n if (deadOverloads.length !== 1 || liveOverloads.length !== 1) return false;\n if (deadOverloads[0] !== overload) return false;\n const liveOverload = liveOverloads[0];\n if (liveOverload === undefined) return false;\n if (family.implementation.typeParameters === undefined || liveOverload.typeParameters === undefined) return false;\n const body = family.implementation.body;\n if (body === undefined) return false;\n\n const implementationTypeParams = family.implementation.typeParameters;\n const liveTypeParams = liveOverload.typeParameters;\n if (implementationTypeParams.length === 0 || implementationTypeParams.length !== liveTypeParams.length) return false;\n\n const constrainedParams = implementationTypeParams.flatMap((typeParam, index) => {\n const liveTypeParam = liveTypeParams[index];\n if (liveTypeParam === undefined) return [];\n if (typeParam.constraint !== undefined) return [];\n if (liveTypeParam.constraint === undefined) return [];\n return [{\n paramName: typeParam.name.text,\n constraintText: normalizeText(liveTypeParam.constraint.getText(family.sourceFile)),\n }];\n });\n\n if (constrainedParams.length === 0) return false;\n\n return constrainedParams.some(({ paramName, constraintText }) =>\n hasIntersectionCast(body, family.sourceFile, paramName, constraintText)\n );\n}\n\nfunction hasIntersectionCast(\n body: ts.Block,\n sourceFile: ts.SourceFile,\n paramName: string,\n constraintText: string,\n): boolean {\n let found = false;\n\n function visit(node: ts.Node): void {\n if (found) return;\n\n if (ts.isAsExpression(node) || ts.isTypeAssertionExpression(node)) {\n if (isConstraintIntersection(node.type, sourceFile, paramName, constraintText)) {\n found = true;\n return;\n }\n }\n\n ts.forEachChild(node, visit);\n }\n\n visit(body);\n return found;\n}\n\nfunction isConstraintIntersection(\n typeNode: ts.TypeNode,\n sourceFile: ts.SourceFile,\n paramName: string,\n constraintText: string,\n): boolean {\n const target = unwrapParenthesizedType(typeNode);\n if (!ts.isIntersectionTypeNode(target)) return false;\n\n let hasParam = false;\n let hasConstraint = false;\n\n for (const part of target.types) {\n const text = normalizeText(unwrapParenthesizedType(part).getText(sourceFile));\n if (text === paramName) hasParam = true;\n if (text === constraintText) hasConstraint = true;\n }\n\n return hasParam && hasConstraint;\n}\n\nfunction unwrapParenthesizedType(typeNode: ts.TypeNode): ts.TypeNode {\n let current = typeNode;\n while (ts.isParenthesizedTypeNode(current)) {\n current = current.type;\n }\n return current;\n}\n\nfunction collectOverloadFamilies(sourceFile: ts.SourceFile, file: string): OverloadFamily[] {\n const families: OverloadFamily[] = [];\n\n collectFromList(sourceFile.statements, sourceFile, file, families);\n\n function visit(node: ts.Node): void {\n if (ts.isClassDeclaration(node) || ts.isClassExpression(node)) {\n collectFromList(node.members, sourceFile, file, families);\n }\n ts.forEachChild(node, visit);\n }\n\n ts.forEachChild(sourceFile, visit);\n return families;\n}\n\nfunction collectFromList(\n nodes: ts.NodeArray<ts.Node>,\n sourceFile: ts.SourceFile,\n file: string,\n families: OverloadFamily[],\n): void {\n for (let index = 0; index < nodes.length; index++) {\n const current = asOverloadDeclaration(nodes[index]);\n const name = current ? getDeclarationName(current) : null;\n if (current === null || name === null) continue;\n\n const run: OverloadDeclaration[] = [current];\n let nextIndex = index + 1;\n while (nextIndex < nodes.length) {\n const next = asOverloadDeclaration(nodes[nextIndex]);\n if (next === null) break;\n if (getDeclarationName(next) !== name) break;\n run.push(next);\n nextIndex++;\n }\n\n const family = toOverloadFamily(run, name, file, sourceFile);\n if (family !== null) {\n families.push(family);\n }\n\n index = nextIndex - 1;\n }\n}\n\nfunction toOverloadFamily(\n run: OverloadDeclaration[],\n name: string,\n file: string,\n sourceFile: ts.SourceFile,\n): OverloadFamily | null {\n if (run.length < 2) return null;\n\n const implementation = run.at(-1);\n if (implementation === undefined || implementation.body === undefined) return null;\n if (run.slice(0, -1).some((declaration) => declaration.body !== undefined)) return null;\n\n return {\n name,\n file,\n sourceFile,\n overloads: run.slice(0, -1),\n implementation,\n };\n}\n\nfunction asOverloadDeclaration(node: ts.Node | undefined): OverloadDeclaration | null {\n if (node === undefined) return null;\n if (ts.isFunctionDeclaration(node)) return node;\n if (ts.isMethodDeclaration(node)) return node;\n return null;\n}\n\nfunction getDeclarationName(node: OverloadDeclaration): string | null {\n if (ts.isFunctionDeclaration(node)) {\n return node.name?.text ?? null;\n }\n\n if (ts.isIdentifier(node.name) || ts.isStringLiteral(node.name) || ts.isNumericLiteral(node.name)) {\n return node.name.text;\n }\n\n return null;\n}\n\nfunction lineOf(sourceFile: ts.SourceFile, node: ts.Node): number {\n return ts.getLineAndCharacterOfPosition(sourceFile, node.getStart(sourceFile)).line + 1;\n}\n\nfunction normalizeText(text: string): string {\n return text.replace(/\\s+/g, \"\");\n}\n","import type * as ts from \"typescript\";\n\nexport interface SemanticServices {\n checker: ts.TypeChecker;\n typeAtLocation(node: ts.Node): ts.Type;\n symbolAtLocation(node: ts.Node): ts.Symbol | undefined;\n resolvedSignature(node: ts.CallLikeExpression): ts.Signature | undefined;\n typeFromTypeNode(node: ts.TypeNode): ts.Type;\n contextualType(node: ts.Expression): ts.Type | undefined;\n typeOfSymbolAtLocation(symbol: ts.Symbol, node: ts.Node): ts.Type;\n aliasedSymbol(symbol: ts.Symbol): ts.Symbol;\n awaitedType(type: ts.Type): ts.Type | undefined;\n apparentType(type: ts.Type): ts.Type;\n isArrayType(type: ts.Type): boolean;\n isTupleType(type: ts.Type): boolean;\n isTypeAssignableTo(source: ts.Type, target: ts.Type): boolean;\n}\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 fix?: FixEdit;\n}\n\n/**\n * A single text replacement with absolute offsets into the file's source.\n * Only attach a fix when the replacement is provably semantics-preserving;\n * `--fix` applies these mechanically.\n */\nexport interface FixEdit {\n start: number;\n end: number;\n text: string;\n}\n\nexport interface TSVisitContext {\n report(node: ts.Node, message?: string, fix?: FixEdit): void;\n reportAtOffset(offset: number, message?: string): void;\n filename: string;\n source: string;\n sourceFile: ts.SourceFile;\n checker: ts.TypeChecker;\n semantics: SemanticServices;\n compilerOptions: ts.CompilerOptions;\n isNullable(node: ts.Node): boolean;\n isExternal(node: ts.Node): boolean;\n}\n\nexport interface TSRule {\n kind: \"ts\";\n id: string;\n severity: \"info\" | \"warning\" | \"error\";\n message: string;\n /** Restrict visits to these node kinds. Omit only for rules that truly need every node. */\n syntaxKinds?: readonly ts.SyntaxKind[];\n /** Defaults to true. Set false only when the rule never touches checker/isNullable/isExternal. */\n requiresTypeInfo?: boolean;\n /**\n * Set true when the rule's reasoning collapses without `strictNullChecks`:\n * every type reads as non-nullable, inverting \"this guard is dead\" into\n * advice to delete load-bearing guards. Such rules are skipped (with a\n * notice) when the analyzed project has strictNullChecks off.\n */\n requiresStrictNullChecks?: boolean;\n visit(node: ts.Node, ctx: TSVisitContext): void;\n}\n\nimport type { ProjectIndex } from \"../collect/index.ts\";\nexport type { ProjectIndex };\n\nexport type ProjectIndexNeed =\n | \"files\"\n | \"types\"\n | \"functions\"\n | \"functionSymbols\"\n | \"constants\"\n | \"callSites\"\n | \"callSiteSymbols\"\n | \"overloadCallSignatures\"\n | \"imports\"\n | \"fileHashes\"\n | \"statementSequences\"\n | \"inlineParamTypes\";\n\nexport interface CrossFileRule {\n id: string;\n severity: \"info\" | \"warning\" | \"error\";\n message: string;\n requires?: readonly ProjectIndexNeed[];\n analyze(project: ProjectIndex, context?: CrossFileAnalysisContext): Diagnostic[];\n /**\n * Cross-group merge, both hooks or neither. Analysis runs one tsconfig\n * group at a time; a rule that would mistake another group's usage for\n * absence (e.g. unused-export in a monorepo) implements these instead of\n * relying on `analyze` alone. `collectGlobalFacts` runs per group — possibly\n * in a worker, so facts must survive structuredClone (no ts.Node/ts.Symbol).\n * `finalizeGlobal` runs once on the main thread with every group's facts.\n */\n collectGlobalFacts?(project: ProjectIndex, context?: CrossFileAnalysisContext): unknown;\n finalizeGlobal?(facts: unknown[]): Diagnostic[];\n}\n\nexport interface CrossFileAnalysisContext {\n /** Files explicitly requested by the scan; project context outside this set is non-reportable. */\n reportableFiles?: ReadonlySet<string>;\n}\n\nexport type Rule = CrossFileRule | TSRule;\n\nexport function isTSRule(r: Rule): r is TSRule {\n return \"kind\" in r && r.kind === \"ts\";\n}\n\n/**\n * Emit ONE diagnostic per group of duplicates, not N-1.\n *\n * Each duplicate-* rule represents a single refactor decision per group\n * (extract a helper, unify the type, name the constant). Emitting per site\n * would inflate the issue count to (group size − 1) for what is one fix,\n * and IDE squiggle navigation is preserved by listing every location in the\n * message.\n *\n * Diagnostic location: the first non-canonical, reportable occurrence (the\n * \"first copy\"). This preserves @expect-on-the-copy semantics in tests where\n * fixtures historically marked the second occurrence.\n */\nexport function reportDuplicateGroup<T extends DuplicateGroupEntry>(\n group: T[],\n ruleId: string,\n severity: Diagnostic[\"severity\"],\n formatOther: (entry: T) => string,\n formatMessage: (entry: T, others: string) => string,\n diagnostics: Diagnostic[],\n context: CrossFileAnalysisContext,\n): void {\n const sorted = [...group].sort((a, b) => a.file.localeCompare(b.file) || a.line - b.line);\n const target = selectDuplicateReportTarget(sorted, context.reportableFiles);\n if (target === undefined) return;\n const others = sorted\n .filter((e) => e !== target)\n .map(formatOther)\n .join(\", \");\n diagnostics.push({\n ruleId,\n severity,\n message: formatMessage(target, others),\n file: target.file,\n line: target.line,\n column: target.column ?? 1,\n });\n}\n\nexport interface DuplicateGroupEntry {\n file: string;\n line: number;\n /** Optional 1-based column to host the diagnostic. Defaults to 1 when omitted. */\n column?: number;\n}\n\nexport function selectReportTarget<T extends { file: string; line: number }>(\n group: T[],\n reportableFiles?: ReadonlySet<string>,\n): T | undefined {\n const sorted = [...group].sort((a, b) => a.file.localeCompare(b.file) || a.line - b.line);\n if (reportableFiles === undefined) return sorted[0];\n return sorted.find((entry) => reportableFiles.has(entry.file));\n}\n\n/**\n * Choose the one entry to host the diagnostic. Prefer the first \"copy\"\n * (sorted index 1) so we point at duplication rather than at the canonical\n * declaration. Fall back to the canonical when it's the only reportable site.\n */\nfunction selectDuplicateReportTarget<T extends { file: string; line: number }>(\n sorted: T[],\n reportableFiles: ReadonlySet<string> | undefined,\n): T | undefined {\n if (sorted.length < 2) return undefined;\n if (reportableFiles === undefined) return sorted[1];\n\n for (let i = 1; i < sorted.length; i++) {\n const entry = sorted[i];\n if (entry !== undefined && reportableFiles.has(entry.file)) return entry;\n }\n const first = sorted[0];\n if (first !== undefined && reportableFiles.has(first.file)) return first;\n return undefined;\n}\n","import type { ConstantEntry } from \"../../collect/constant-registry.ts\";\nimport { type CrossFileAnalysisContext, type CrossFileRule, type Diagnostic, type ProjectIndex, reportDuplicateGroup } from \"../types.ts\";\n\n/**\n * Iffy by this project's own standard: `hasNameOverlap` gates on identifier\n * name segments, so renaming a constant changes the diagnostics — a sanctioned\n * violation of the \"structure and types, never names\" hard rule. Without the\n * gate, every unrelated pair of `100`s across the project would group. Kept at\n * `info` severity to reflect that reduced confidence.\n */\nexport const duplicateConstantDeclaration: CrossFileRule = {\n id: \"duplicate-constant-declaration\",\n severity: \"info\",\n message: \"Identical constant value declared in multiple files; consolidate to a single definition\",\n requires: [\"constants\"],\n\n analyze(project: ProjectIndex, context: CrossFileAnalysisContext = {}): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n for (const group of project.constants.getDuplicateGroups()) {\n const files = new Set(group.map((e) => e.file));\n if (files.size < 2) continue;\n if (!hasNameOverlap(group)) continue;\n reportDuplicateGroup(group, this.id, this.severity,\n (e) => `${e.name} (${e.file}:${e.line})`,\n (e, others) => `Constant \"${e.name}\" has identical value \\`${e.valueText}\\` to: ${others}`,\n diagnostics,\n context);\n }\n return diagnostics;\n },\n};\n\n/** Check whether any two constants in the group share a name segment. */\nfunction hasNameOverlap(group: ConstantEntry[]): boolean {\n const segmentSets = group.map((e) => nameSegments(e.name));\n for (let i = 0; i < segmentSets.length; i++) {\n const left = segmentSets[i];\n if (left === undefined) continue;\n for (let j = i + 1; j < segmentSets.length; j++) {\n const right = segmentSets[j];\n if (right === undefined) continue;\n for (const seg of left) {\n if (right.has(seg)) return true;\n }\n }\n }\n return false;\n}\n\n/** Split a constant name into lowercase segments on _ and camelCase boundaries. */\nfunction nameSegments(name: string): Set<string> {\n const segments = new Set<string>();\n for (const part of name.split(\"_\")) {\n for (const seg of part.split(/(?<=[a-z])(?=[A-Z])/)) {\n const lower = seg.toLowerCase();\n if (lower.length > 0) segments.add(lower);\n }\n }\n return segments;\n}\n","import { type CrossFileAnalysisContext, type CrossFileRule, type Diagnostic, type ProjectIndex, reportDuplicateGroup } from \"../types.ts\";\n\nexport const duplicateFile: CrossFileRule = {\n id: \"duplicate-file\",\n severity: \"warning\",\n message: \"File has identical content to another file; one is likely dead code\",\n requires: [\"fileHashes\"],\n\n analyze(project: ProjectIndex, context: CrossFileAnalysisContext = {}): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n for (const files of project.fileHashes.values()) {\n if (files.length < 2) continue;\n const group = files.map((file) => ({ file, line: 1 }));\n reportDuplicateGroup(group, this.id, this.severity,\n (entry) => entry.file,\n (_entry, others) => `File is identical to: ${others}`,\n diagnostics,\n context);\n }\n return diagnostics;\n },\n};\n","import * as ts from \"typescript\";\nimport { type CrossFileAnalysisContext, type CrossFileRule, type Diagnostic, type ProjectIndex, reportDuplicateGroup } 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 requires: [\"functions\"],\n\n analyze(project: ProjectIndex, context: CrossFileAnalysisContext = {}): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n for (const group of project.functions.getDuplicateGroups()) {\n const first = group[0];\n if (first === undefined) continue;\n if (isSingleStatement(first.node)) continue;\n if (isSetter(first.node)) continue;\n\n reportDuplicateGroup(group, this.id, this.severity,\n (e) => `${e.name} (${e.file}:${e.line})`,\n (e, others) => `Function \"${e.name}\" has identical body to: ${others}`,\n diagnostics,\n context);\n }\n return diagnostics;\n },\n};\n\nfunction getBodyBlock(node: ts.Node): ts.Block | undefined {\n if (ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node)) return node.body;\n if (ts.isArrowFunction(node)) return ts.isBlock(node.body) ? node.body : undefined;\n if (ts.isMethodDeclaration(node)) return node.body;\n return undefined;\n}\n\nfunction isSingleStatement(node: ts.Node): boolean {\n if (ts.isArrowFunction(node) && !ts.isBlock(node.body)) return true;\n const body = getBodyBlock(node);\n return body !== undefined && body.statements.length <= 1;\n}\n\nfunction isSetter(node: ts.Node): boolean {\n const body = getBodyBlock(node);\n if (!body || body.statements.length !== 1) return false;\n const stmt = body.statements[0];\n if (stmt === undefined || !ts.isExpressionStatement(stmt)) return false;\n return ts.isBinaryExpression(stmt.expression) &&\n stmt.expression.operatorToken.kind === ts.SyntaxKind.EqualsToken;\n}\n","import { dirname, resolve } from \"node:path\";\nimport { type CrossFileAnalysisContext, type CrossFileRule, type Diagnostic, type ProjectIndex, reportDuplicateGroup } from \"../types.ts\";\n\nconst EXTENSIONS = [\".ts\", \".tsx\", \".mts\", \".cts\", \".js\", \".jsx\", \".mjs\", \".cjs\"];\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 requires: [\"functions\", \"imports\"],\n\n analyze(project: ProjectIndex, context: CrossFileAnalysisContext = {}): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n for (const group of project.functions.getNameCollisionGroups()) {\n const hashes = new Set(group.map((e) => e.hash));\n if (hashes.size === 1) continue;\n\n const groupFiles = new Set(group.map((e) => e.file));\n const first = group[0];\n if (first === undefined) continue;\n const funcName = first.name;\n const hasImportLink = project.imports.some((imp) => {\n if (!groupFiles.has(imp.file)) return false;\n if (imp.importedName !== funcName && imp.localName !== funcName) return false;\n if (!imp.source.startsWith(\".\")) return false;\n const candidates = resolveCandidates(imp.file, imp.source);\n if (candidates.some((c) => groupFiles.has(c))) return true;\n return candidates.some((c) =>\n project.imports.some((reExp) => {\n if (reExp.file !== c) return false;\n if (reExp.importedName !== funcName && reExp.localName !== funcName) return false;\n if (!reExp.source.startsWith(\".\")) return false;\n const innerCandidates = resolveCandidates(reExp.file, reExp.source);\n return innerCandidates.some((ic) => groupFiles.has(ic));\n }),\n );\n });\n if (hasImportLink) continue;\n\n reportDuplicateGroup(group, this.id, this.severity,\n (e) => `${e.file}:${e.line}`,\n (e, others) => `Exported function \"${e.name}\" also defined in: ${others}`,\n diagnostics,\n context);\n }\n return diagnostics;\n },\n};\n\nfunction resolveCandidates(fromFile: string, specifier: string): string[] {\n const base = resolve(dirname(fromFile), specifier);\n const candidates = [base];\n for (const ext of EXTENSIONS) {\n candidates.push(base + ext);\n candidates.push(resolve(base, `index${ext}`));\n }\n return candidates;\n}\n","import { type CrossFileAnalysisContext, type CrossFileRule, type Diagnostic, type ProjectIndex, reportDuplicateGroup } from \"../types.ts\";\n\nexport const duplicateInlineTypeInParams: CrossFileRule = {\n id: \"duplicate-inline-type-in-params\",\n severity: \"warning\",\n message: \"Same inline param type shape appears in multiple places; extract to a shared named type\",\n requires: [\"inlineParamTypes\"],\n\n analyze(project: ProjectIndex, context: CrossFileAnalysisContext = {}): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n for (const group of project.inlineParamTypes.getDuplicateGroups()) {\n reportDuplicateGroup(group, this.id, this.severity,\n (e) => `${e.typeText} (${e.file}:${e.line})`,\n (e, others) => `Inline param type \\`${e.typeText}\\` also appears at: ${others}`,\n diagnostics,\n context);\n }\n return diagnostics;\n },\n};\n","import { type CrossFileAnalysisContext, type CrossFileRule, type Diagnostic, type ProjectIndex, reportDuplicateGroup } from \"../types.ts\";\n\nexport const duplicateStatementSequence: CrossFileRule = {\n id: \"duplicate-statement-sequence\",\n severity: \"warning\",\n message: \"Repeated statement sequence; consider extracting to a shared helper\",\n requires: [\"statementSequences\"],\n\n // The registry returns maximal matches (longest run of consecutive statements\n // shared by ≥2 locations, can't extend in either direction). That format\n // describes \"this block is duplicated\" in the same shape the developer would\n // describe it — no overlapping window noise, no sub-windows of a larger match.\n //\n // The structural check that varies-only-by-literals (lookup/dispatch tables)\n // doesn't duplicate is preserved by the hashing primitive: each statement is\n // hashed as comment-stripped text with identifiers AND literals retained, so\n // two `set(\"alpha\", 1)` and `set(\"beta\", 2)` statements have different hashes.\n // Function-level near-duplication with renamed identifiers belongs to\n // near-duplicate-function, not here.\n analyze(project: ProjectIndex, context: CrossFileAnalysisContext = {}): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n const MIN_STATEMENT_COUNT = 3;\n const MIN_NORMALIZED_BODY = 128;\n\n for (const match of project.statementSequences.getMaximalMatches(\n MIN_STATEMENT_COUNT,\n MIN_NORMALIZED_BODY,\n )) {\n reportDuplicateGroup(\n match.participants,\n this.id,\n this.severity,\n (entry) => `${entry.file}:${entry.line}`,\n (_entry, others) =>\n `Statement sequence (${match.statementCount} statements) appears ${match.participants.length} times; also at: ${others}`,\n diagnostics,\n context,\n );\n }\n return diagnostics;\n },\n};\n","import * as ts from \"typescript\";\nimport { type CrossFileAnalysisContext, type CrossFileRule, type Diagnostic, type ProjectIndex, reportDuplicateGroup } 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 requires: [\"types\"],\n\n analyze(project: ProjectIndex, context: CrossFileAnalysisContext = {}): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n for (const group of project.types.getDuplicateGroups()) {\n const files = new Set(group.map((e) => e.file));\n if (files.size < 2) continue;\n if (group.every((e) => isTrivialObjectShape(e.node))) continue;\n reportDuplicateGroup(group, this.id, this.severity,\n (e) => `${e.name} (${e.file}:${e.line})`,\n (e, others) => `Type \"${e.name}\" has identical shape to: ${others}`,\n diagnostics,\n context);\n }\n return diagnostics;\n },\n};\n\nfunction isTrivialObjectShape(node: ts.Node): boolean {\n if (ts.isTypeLiteralNode(node)) return node.members.length <= 1;\n if (ts.isInterfaceDeclaration(node)) return node.members.length <= 1;\n return false;\n}\n","import * as ts from \"typescript\";\nimport { type CrossFileAnalysisContext, type CrossFileRule, type Diagnostic, type ProjectIndex, reportDuplicateGroup } 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 requires: [\"types\"],\n\n analyze(project: ProjectIndex, context: CrossFileAnalysisContext = {}): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n for (const group of project.types.getNameCollisionGroups()) {\n const hashes = new Set(group.map((e) => e.hash));\n if (hashes.size === 1) continue;\n\n const hasInferredType = group.some(\n (e) => !ts.isTypeLiteralNode(e.node) && !ts.isInterfaceDeclaration(e.node),\n );\n if (hasInferredType) continue;\n\n reportDuplicateGroup(group, this.id, this.severity,\n (e) => `${e.file}:${e.line}`,\n (e, others) => `Exported type \"${e.name}\" also defined in: ${others}`,\n diagnostics,\n context);\n }\n return diagnostics;\n },\n};\n","import * as ts from \"typescript\";\nimport type { SemanticServices, TSVisitContext } from \"../rules/types.ts\";\n\nfunction hasFlags(flags: number, mask: number): boolean {\n return (flags & mask) !== 0;\n}\n\n/**\n * True when `expr` reads an index whose static type omits `undefined` only\n * because `noUncheckedIndexedAccess` is off: element access into a non-tuple\n * array, or any access resolved through an index signature rather than a\n * declared member. The read can produce `undefined` at runtime even though\n * the checker says otherwise, so a guard on it is load-bearing — rules that\n * flag \"dead\" guards must suppress on these reads.\n */\nexport function isUncheckedIndexRead(\n expr: ts.Node,\n semantics: SemanticServices,\n compilerOptions: ts.CompilerOptions,\n): boolean {\n if (compilerOptions.noUncheckedIndexedAccess === true) return false;\n\n let cur: ts.Node = expr;\n while (ts.isParenthesizedExpression(cur) || ts.isNonNullExpression(cur)) {\n cur = cur.expression;\n }\n\n if (ts.isElementAccessExpression(cur)) {\n // A resolved symbol means a declared member (tuple slot in range, known\n // literal key) — the type is honest.\n if (semantics.symbolAtLocation(cur) !== undefined) return false;\n return hasIndexedElementType(semantics.typeAtLocation(cur.expression), semantics);\n }\n\n if (ts.isPropertyAccessExpression(cur)) {\n // Property resolved through a string index signature has no symbol.\n if (semantics.symbolAtLocation(cur) !== undefined) return false;\n const apparent = semantics.apparentType(semantics.typeAtLocation(cur.expression));\n return apparent.getStringIndexType() !== undefined;\n }\n\n return false;\n}\n\nfunction hasIndexedElementType(type: ts.Type, semantics: SemanticServices): boolean {\n if (type.isUnion()) return type.types.some((t) => hasIndexedElementType(t, semantics));\n if (semantics.isArrayType(type) || semantics.isTupleType(type)) return true;\n const apparent = semantics.apparentType(type);\n return apparent.getStringIndexType() !== undefined || apparent.getNumberIndexType() !== undefined;\n}\n\n/** Type has a callable `then` member anywhere in its union/intersection. */\nexport function isPromiseLike(type: ts.Type, semantics: SemanticServices): boolean {\n if (hasThenMethod(type, semantics)) return true;\n if (type.isUnion()) return type.types.some((t) => isPromiseLike(t, semantics));\n if (type.isIntersection()) return type.types.some((t) => isPromiseLike(t, semantics));\n return false;\n}\n\nfunction hasThenMethod(type: ts.Type, semantics: SemanticServices): boolean {\n const apparent = semantics.apparentType(type);\n const then = apparent.getProperty(\"then\");\n if (!then) return false;\n const declaration = then.valueDeclaration ?? then.declarations?.[0];\n if (!declaration) return false;\n const thenType = semantics.typeOfSymbolAtLocation(then, declaration);\n return thenType.getCallSignatures().length > 0;\n}\n\nconst NULLISH_FLAGS = ts.TypeFlags.Null | ts.TypeFlags.Undefined | ts.TypeFlags.Void;\n\nexport function isNullableType(checker: ts.TypeChecker, type: ts.Type): boolean {\n if (type.isUnion()) {\n return type.types.some((t) => hasFlags(t.flags, NULLISH_FLAGS));\n }\n return hasFlags(type.flags, NULLISH_FLAGS);\n}\n\nexport function isFromNodeModules(node: ts.Node): boolean {\n const sourceFile = node.getSourceFile();\n return sourceFile.fileName.includes(\"/node_modules/\");\n}\n\nexport function includesNumberType(type: ts.Type): boolean {\n if (type.isUnion()) {\n return type.types.some((t) => hasFlags(t.flags, ts.TypeFlags.NumberLike));\n }\n return hasFlags(type.flags, ts.TypeFlags.NumberLike);\n}\n\nexport function includesBooleanType(type: ts.Type): boolean {\n if (type.isUnion()) {\n return type.types.some((t) => hasFlags(t.flags, ts.TypeFlags.BooleanLike));\n }\n return hasFlags(type.flags, ts.TypeFlags.BooleanLike);\n}\n\nexport function isNullishLiteral(node: ts.Node): boolean {\n if (node.kind === ts.SyntaxKind.NullKeyword) return true;\n return ts.isIdentifier(node) && node.text === \"undefined\";\n}\n\n/**\n * For binary equality tests like `x === null` or `null == x`, return the\n * identifier side and the literal side. Caller decides whether the literal\n * is meaningful (e.g. a nullish literal). Returns null when neither operand\n * is a bare identifier.\n */\nexport function splitEqualityOperands(\n test: ts.BinaryExpression,\n): { id: ts.Identifier; lit: ts.Expression } | null {\n const { left, right } = test;\n if (ts.isIdentifier(left)) return { id: left, lit: right };\n if (ts.isIdentifier(right)) return { id: right, lit: left };\n return null;\n}\n\n/**\n * Function-like signature carriers. Useful for rules that need to introspect\n * params, generics, and return types uniformly across declarations and\n * expressions.\n */\nexport type SignatureLike =\n | ts.FunctionDeclaration\n | ts.FunctionExpression\n | ts.ArrowFunction\n | ts.MethodDeclaration;\n\nexport function asSignatureLike(node: ts.Node): SignatureLike | null {\n if (ts.isFunctionDeclaration(node)) return node;\n if (ts.isFunctionExpression(node)) return node;\n if (ts.isArrowFunction(node)) return node;\n if (ts.isMethodDeclaration(node)) return node;\n return null;\n}\n\nexport function getFunctionBodyStatements(node: ts.Node): { statements: ts.NodeArray<ts.Statement>; fn: SignatureLike } | null {\n const fn = asSignatureLike(node);\n if (fn === null) return null;\n if (!fn.body || !ts.isBlock(fn.body)) return null;\n if (fn.body.statements.length === 0) return null;\n return { statements: fn.body.statements, fn };\n}\n\n\n/**\n * Resolved signature of a call whose declaration lives in a declaration file\n * (lib/dependency surface), else null. Used to recognize platform calls by\n * declaration origin instead of by name.\n */\nexport function libDeclaredSignature(call: ts.CallExpression, semantics: SemanticServices): ts.Signature | null {\n const signature = semantics.resolvedSignature(call);\n const declaration = signature?.declaration;\n if (signature === undefined || declaration === undefined) return null;\n if (!declaration.getSourceFile().isDeclarationFile) return null;\n return signature;\n}\n\ninterface CommentDirectiveInfo {\n pos: number;\n expectError: boolean;\n}\n\n/**\n * Reports each parser-collected `@ts-ignore` / `@ts-expect-error` directive\n * of the requested kind. Shared core of `no-ts-ignore` and\n * `no-ts-expect-error`.\n */\nexport function reportCommentDirectives(node: ts.Node, ctx: TSVisitContext, expectError: boolean): void {\n if (!ts.isSourceFile(node)) return;\n const directives = getCommentDirectives(node);\n if (directives === undefined) return;\n for (const directive of directives) {\n if (directive.expectError !== expectError) continue;\n ctx.reportAtOffset(directive.pos);\n }\n}\n\n/**\n * Extracts the parser-collected `@ts-ignore` / `@ts-expect-error` directives\n * from a source file. `commentDirectives` and its `type` enum\n * (`CommentDirectiveType`: ExpectError = 0, Ignore = 1) are internal TS API,\n * hence the defensive extraction — returns undefined if the shape ever changes.\n */\nfunction getCommentDirectives(sourceFile: ts.SourceFile): CommentDirectiveInfo[] | undefined {\n const directives = Reflect.get(sourceFile, \"commentDirectives\");\n if (!Array.isArray(directives)) return undefined;\n if (!directives.every(isRawCommentDirective)) return undefined;\n return directives.map((directive) => ({\n pos: directive.range.pos,\n expectError: directive.type === 0,\n }));\n}\n\ninterface RawCommentDirective {\n range: { pos: number };\n type: number;\n}\n\nfunction isRawCommentDirective(value: unknown): value is RawCommentDirective {\n if (typeof value !== \"object\" || value === null) return false;\n if (!(\"range\" in value) || !(\"type\" in value)) return false;\n if (typeof value.type !== \"number\") return false;\n const range = value.range;\n if (typeof range !== \"object\" || range === null) return false;\n if (!(\"pos\" in range)) return false;\n return typeof range.pos === \"number\";\n}\n\nexport function isInlineParamType(node: ts.Node): boolean {\n if (!ts.isTypeLiteralNode(node)) return false;\n // ts.Node#parent is declared non-null but is undefined at unparented nodes.\n const parent: ts.Node | undefined = node.parent;\n if (!parent || !ts.isParameter(parent)) return false;\n return parent.type === node;\n}\n","import * as ts from \"typescript\";\nimport type { CrossFileRule, Diagnostic, ProjectIndex } from \"../types.ts\";\nimport { isNullishLiteral } from \"../../typecheck/utils.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 requires: [\"functions\", \"functionSymbols\", \"callSites\", \"callSiteSymbols\"],\n\n analyze(project: ProjectIndex): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n\n // Build lookup structures for known project functions\n const projectFnSymbols = new Set<ts.Symbol>();\n for (const fn of project.functions.getAll()) {\n if (fn.symbol) projectFnSymbols.add(fn.symbol);\n }\n\n for (const site of project.callSites) {\n // Only flag calls that resolve, by symbol, to a project function.\n // A name fallback would misfire on unrelated same-named callees.\n if (site.symbol === undefined || !projectFnSymbols.has(site.symbol)) continue;\n\n for (let i = 0; i < site.node.arguments.length; i++) {\n const arg = site.node.arguments[i];\n if (arg === undefined) continue;\n if (isNullishLiteral(arg)) {\n const val = arg.kind === ts.SyntaxKind.NullKeyword ? \"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 * as ts from \"typescript\";\nimport type { FunctionEntry } from \"../../collect/function-registry.ts\";\nimport { type CrossFileAnalysisContext, type CrossFileRule, type Diagnostic, type ProjectIndex, reportDuplicateGroup } from \"../types.ts\";\n\nexport const nearDuplicateFunction: CrossFileRule = {\n id: \"near-duplicate-function\",\n severity: \"warning\",\n message: \"Near-duplicate function bodies across files; consider parameterizing\",\n requires: [\"functions\"],\n\n analyze(project: ProjectIndex, context: CrossFileAnalysisContext = {}): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n for (const group of project.functions.getNearDuplicateGroups()) {\n const MIN_NORMALIZED_BODY = 32;\n if (group.every((e) => e.normalizedBodyLength < MIN_NORMALIZED_BODY)) continue;\n // Precision-first: tiny wrappers/callbacks are often intentionally repeated.\n if (group.every(isSimpleStructure)) continue;\n reportDuplicateGroup(group, this.id, this.severity,\n (e) => `${e.name} (${e.file}:${e.line})`,\n (e, others) => `Function \"${e.name}\" is near-duplicate of: ${others}`,\n diagnostics,\n context);\n }\n return diagnostics;\n },\n};\n\nfunction getFunctionBody(node: ts.Node): ts.Block | ts.Expression | undefined {\n if (ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node)) return node.body;\n if (ts.isArrowFunction(node)) return node.body;\n if (ts.isMethodDeclaration(node)) return node.body;\n return undefined;\n}\n\nfunction getTopLevelStatementCount(body: ts.Block | ts.Expression): number {\n if (ts.isBlock(body)) return body.statements.length;\n return 1;\n}\n\nfunction hasControlFlow(node: ts.Node): boolean {\n let found = false;\n function visit(current: ts.Node): void {\n if (found) return;\n if (\n ts.isIfStatement(current) ||\n ts.isSwitchStatement(current) ||\n ts.isTryStatement(current) ||\n ts.isForStatement(current) ||\n ts.isForInStatement(current) ||\n ts.isForOfStatement(current) ||\n ts.isWhileStatement(current) ||\n ts.isDoStatement(current)\n ) {\n found = true;\n return;\n }\n ts.forEachChild(current, visit);\n }\n visit(node);\n return found;\n}\n\nfunction isSimpleStructure(entry: FunctionEntry): boolean {\n const body = getFunctionBody(entry.node);\n if (!body) return false;\n if (hasControlFlow(body)) return false;\n return getTopLevelStatementCount(body) <= 2;\n}\n","import type { CrossFileRule, Diagnostic, ProjectIndex } from \"../types.ts\";\nimport { optionalParams, signatureChangeCallSites } from \"./call-site-utils.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 requires: [\"functions\", \"functionSymbols\", \"callSites\", \"callSiteSymbols\"],\n\n analyze(project: ProjectIndex): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n\n for (const fn of project.functions.getAll()) {\n const callSites = signatureChangeCallSites(fn, project, 2);\n if (callSites === null) continue;\n\n for (const { index, param } of optionalParams(fn)) {\n // Check if every call site provides this positional argument\n if (!callSites.every((c) => c.argCount > index)) continue;\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 return diagnostics;\n },\n};\n","import type { CrossFileRule, Diagnostic, ProjectIndex } from \"../types.ts\";\nimport { optionalParams, signatureChangeCallSites } from \"./call-site-utils.ts\";\n\n/**\n * The mirror of `optional-arg-always-used`: an optional (or defaulted)\n * parameter that no call site ever provides is speculative API surface —\n * remove it and inline its default into the body.\n */\nexport const optionalArgNeverUsed: CrossFileRule = {\n id: \"optional-arg-never-used\",\n severity: \"warning\",\n message: \"Optional parameter is never provided at any call site; remove it\",\n requires: [\"functions\", \"functionSymbols\", \"callSites\", \"callSiteSymbols\"],\n\n analyze(project: ProjectIndex): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n\n for (const fn of project.functions.getAll()) {\n const callSites = signatureChangeCallSites(fn, project, 2);\n if (callSites === null) continue;\n\n const neverProvided: string[] = [];\n for (const { index, param } of optionalParams(fn)) {\n if (callSites.every((c) => c.argCount <= index)) {\n neverProvided.push(param.name);\n }\n }\n if (neverProvided.length === 0) continue;\n\n const names = neverProvided.map((n) => `\"${n}\"`).join(\", \");\n diagnostics.push({\n ruleId: this.id,\n severity: this.severity,\n message: `Optional parameter${neverProvided.length > 1 ? \"s\" : \"\"} ${names} ${neverProvided.length > 1 ? \"are\" : \"is\"} never provided at any of the ${callSites.length} call sites; remove ${neverProvided.length > 1 ? \"them\" : \"it\"} and inline the default`,\n file: fn.file,\n line: fn.line,\n column: 1,\n });\n }\n\n return diagnostics;\n },\n};\n","import * as ts from \"typescript\";\nimport type { CrossFileRule, Diagnostic, ProjectIndex } from \"../types.ts\";\n\nconst MODULE_SCOPE = -1;\n\ninterface LiteralOccurrence {\n line: number;\n isAsConst: boolean;\n scopeId: number;\n key: string;\n}\n\nexport const repeatedLiteralProperty: CrossFileRule = {\n id: \"repeated-literal-property\",\n severity: \"warning\",\n message: \"Repeated literal value in object properties; consider extracting a constant or factory\",\n requires: [\"files\"],\n\n analyze(project: ProjectIndex): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n\n for (const [file, { sourceFile }] of project.files) {\n const valueMap = new Map<string, LiteralOccurrence[]>();\n\n function visit(node: ts.Node): void {\n if (ts.isObjectLiteralExpression(node)) {\n for (const prop of node.properties) {\n if (!ts.isPropertyAssignment(prop)) continue;\n const result = extractLiteral(prop.initializer, sourceFile);\n if (result.literalText === null) continue;\n let list = valueMap.get(result.literalText);\n if (!list) {\n list = [];\n valueMap.set(result.literalText, list);\n }\n const line = ts.getLineAndCharacterOfPosition(sourceFile, prop.getStart(sourceFile)).line + 1;\n const scopeId = findEnclosingFunctionStart(prop, sourceFile);\n const key = ts.isIdentifier(prop.name) ? prop.name.text\n : ts.isStringLiteral(prop.name) ? prop.name.text\n : \"\";\n list.push({ line, isAsConst: result.isAsConst, scopeId, key });\n }\n }\n ts.forEachChild(node, visit);\n }\n ts.forEachChild(sourceFile, visit);\n\n for (const [value, occurrences] of valueMap) {\n // All occurrences on the same property key = discriminant pattern, not a DRY violation\n const uniqueKeys = new Set(occurrences.map((o) => o.key).filter((k) => k !== \"\"));\n if (uniqueKeys.size === 1) continue;\n\n const hasAsConst = occurrences.some((o) => o.isAsConst);\n // Deduplicate by scope — count distinct functions, not raw occurrences\n const uniqueScopes = new Set(occurrences.map((o) => o.scopeId));\n const threshold = hasAsConst ? 3 : 5;\n if (uniqueScopes.size < threshold) continue;\n\n const sorted = [...occurrences].sort((a, b) => a.line - b.line);\n const first = sorted[0];\n if (first === undefined) continue;\n const otherLines = sorted.slice(1).map((o) => o.line).join(\", \");\n diagnostics.push({\n ruleId: this.id,\n severity: this.severity,\n message: `${JSON.stringify(value)}${hasAsConst ? \" as const\" : \"\"} repeated across ${uniqueScopes.size} scopes as property value (also at lines ${otherLines})`,\n file,\n line: first.line,\n column: 1,\n });\n }\n }\n\n return diagnostics;\n },\n};\n\nfunction findEnclosingFunctionStart(node: ts.Node, sourceFile: ts.SourceFile): number {\n let current: ts.Node | undefined = node.parent;\n while (current) {\n if (\n ts.isFunctionDeclaration(current) ||\n ts.isFunctionExpression(current) ||\n ts.isArrowFunction(current) ||\n ts.isMethodDeclaration(current)\n ) {\n return current.getStart(sourceFile);\n }\n current = current.parent;\n }\n return MODULE_SCOPE;\n}\n\nfunction extractLiteral(\n node: ts.Node,\n sourceFile: ts.SourceFile,\n): { literalText: string | null; isAsConst: boolean } {\n if (ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)) {\n return { literalText: node.text, isAsConst: false };\n }\n\n if (ts.isAsExpression(node) && node.type.getText(sourceFile).trim() === \"const\") {\n const inner = extractLiteral(node.expression, sourceFile);\n if (inner.literalText !== null) {\n return { literalText: inner.literalText, isAsConst: true };\n }\n }\n\n return { literalText: null, isAsConst: false };\n}\n","import * as ts from \"typescript\";\n\n/** Extract static property names from an object literal. Returns null if any property is dynamic (spread, computed). */\nexport function extractPropertyNames(node: ts.ObjectLiteralExpression): string[] | null {\n const names: string[] = [];\n for (const prop of node.properties) {\n if (ts.isSpreadAssignment(prop)) return null;\n if (ts.isPropertyAssignment(prop)) {\n if (ts.isIdentifier(prop.name)) names.push(prop.name.text);\n else if (ts.isStringLiteral(prop.name)) names.push(prop.name.text);\n else return null;\n } else if (ts.isShorthandPropertyAssignment(prop)) {\n names.push(prop.name.text);\n } else if (ts.isMethodDeclaration(prop)) {\n if (ts.isIdentifier(prop.name)) names.push(prop.name.text);\n else return null;\n } else if (ts.isGetAccessorDeclaration(prop) || ts.isSetAccessorDeclaration(prop)) {\n if (ts.isIdentifier(prop.name)) names.push(prop.name.text);\n else return null;\n }\n }\n return names;\n}\n\n/** Sort property names, compute a canonical key, and get-or-create the group list in the map. */\nexport function getShapeGroup<T>(map: Map<string, T[]>, props: string[]): { sorted: string[]; list: T[] } {\n const sorted = [...props].sort();\n const key = sorted.join(\"\\0\");\n let list = map.get(key);\n if (!list) {\n list = [];\n map.set(key, list);\n }\n return { sorted, list };\n}\n","import * as ts from \"typescript\";\nimport { type CrossFileAnalysisContext, type CrossFileRule, type Diagnostic, type ProjectIndex, selectReportTarget } from \"../types.ts\";\nimport { extractPropertyNames, getShapeGroup } from \"./object-shape.ts\";\nimport type { TypeEntry } from \"../../collect/type-registry.ts\";\n\ninterface ReturnShapeEntry {\n file: string;\n line: number;\n functionName: string;\n props: string[];\n}\n\nexport const repeatedReturnShape: CrossFileRule = {\n id: \"repeated-return-shape\",\n severity: \"warning\",\n message: \"Multiple functions return the same object shape; consider a shared return type\",\n requires: [\"files\", \"types\"],\n\n analyze(project: ProjectIndex, context: CrossFileAnalysisContext = {}): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n const THRESHOLD = 3;\n const shapeMap = new Map<string, ReturnShapeEntry[]>();\n\n for (const [file, { sourceFile }] of project.files) {\n function visit(node: ts.Node): void {\n if (isFunctionLike(node) && !isCallbackArgument(node)) {\n const functionName = deriveFunctionName(node, sourceFile);\n const line = ts.getLineAndCharacterOfPosition(sourceFile, node.getStart(sourceFile)).line + 1;\n collectReturnShapes(node, file, line, functionName, sourceFile, shapeMap);\n }\n ts.forEachChild(node, visit);\n }\n ts.forEachChild(sourceFile, visit);\n }\n\n const knownTypeShapes = buildKnownTypeShapes(project.types.getAll());\n\n for (const [shapeKey, entries] of shapeMap) {\n if (knownTypeShapes.has(shapeKey)) continue;\n // Deduplicate: one entry per function (same file + line)\n const byFunction = new Map<string, ReturnShapeEntry>();\n for (const entry of entries) {\n const key = `${entry.file}:${entry.line}`;\n if (!byFunction.has(key)) {\n byFunction.set(key, entry);\n }\n }\n const unique = [...byFunction.values()];\n if (unique.length < THRESHOLD) continue;\n\n // Same-file repetition is visible and likely intentional (protocol/framework pattern).\n // Only flag shapes that span multiple files — that's where the developer can't see the duplication.\n const uniqueFiles = new Set(unique.map((e) => e.file));\n if (uniqueFiles.size < 2) continue;\n\n const sorted = unique.sort((a, b) => a.file.localeCompare(b.file) || a.line - b.line);\n const target = selectReportTarget(sorted, context.reportableFiles);\n if (target === undefined) continue;\n const others = sorted\n .filter((e) => e !== target)\n .map((e) => `${e.functionName} (${e.file}:${e.line})`)\n .join(\", \");\n diagnostics.push({\n ruleId: this.id,\n severity: this.severity,\n message: `${unique.length} functions return shape {${target.props.join(\", \")}}; consider a shared return type (${others})`,\n file: target.file,\n line: target.line,\n column: 1,\n });\n }\n\n return diagnostics;\n },\n};\n\nfunction isFunctionLike(node: ts.Node): boolean {\n return (\n ts.isFunctionDeclaration(node) ||\n ts.isFunctionExpression(node) ||\n ts.isArrowFunction(node) ||\n ts.isMethodDeclaration(node)\n );\n}\n\nfunction unwrapExpression(node: ts.Expression): ts.Expression {\n if (ts.isParenthesizedExpression(node)) return unwrapExpression(node.expression);\n if (ts.isAsExpression(node)) return unwrapExpression(node.expression);\n return node;\n}\n\nfunction getBody(node: ts.Node): ts.Block | undefined {\n if (ts.isFunctionDeclaration(node) && node.body) return node.body;\n if (ts.isFunctionExpression(node) && node.body) return node.body;\n if (ts.isArrowFunction(node) && ts.isBlock(node.body)) return node.body;\n if (ts.isMethodDeclaration(node) && node.body) return node.body;\n return undefined;\n}\n\nfunction collectReturnShapes(\n funcNode: ts.Node,\n file: string,\n funcLine: number,\n functionName: string,\n sourceFile: ts.SourceFile,\n shapeMap: Map<string, ReturnShapeEntry[]>,\n): void {\n // Arrow function with expression body\n if (ts.isArrowFunction(funcNode) && !ts.isBlock(funcNode.body)) {\n const expr = unwrapExpression(funcNode.body);\n if (ts.isObjectLiteralExpression(expr)) {\n addShape(expr, file, funcLine, functionName, sourceFile, shapeMap);\n }\n return;\n }\n\n const body = getBody(funcNode);\n if (!body) return;\n\n function walkForReturns(node: ts.Node): void {\n if (ts.isReturnStatement(node) && node.expression) {\n const expr = unwrapExpression(node.expression);\n if (ts.isObjectLiteralExpression(expr)) {\n addShape(expr, file, funcLine, functionName, sourceFile, shapeMap);\n }\n }\n // Don't recurse into nested function-like nodes\n if (isFunctionLike(node)) return;\n ts.forEachChild(node, walkForReturns);\n }\n ts.forEachChild(body, walkForReturns);\n}\n\nfunction addShape(\n objLiteral: ts.ObjectLiteralExpression,\n file: string,\n funcLine: number,\n functionName: string,\n sourceFile: ts.SourceFile,\n shapeMap: Map<string, ReturnShapeEntry[]>,\n): void {\n const props = extractPropertyNames(objLiteral);\n if (props === null || props.length < 2) return;\n const { sorted, list } = getShapeGroup(shapeMap, props);\n list.push({ file, line: funcLine, functionName, props: sorted });\n}\n\nfunction isCallbackArgument(node: ts.Node): boolean {\n let current: ts.Node = node;\n if (ts.isParenthesizedExpression(current.parent)) {\n current = current.parent;\n }\n const parent = current.parent;\n if (!ts.isCallExpression(parent)) return false;\n return parent.arguments.some((arg) => arg === current);\n}\n\nfunction buildKnownTypeShapes(typeEntries: TypeEntry[]): Set<string> {\n const shapes = new Set<string>();\n for (const entry of typeEntries) {\n const props = extractTypePropertyNames(entry.node);\n if (props && props.length >= 2) {\n shapes.add([...props].sort().join(\"\\0\"));\n }\n }\n return shapes;\n}\n\nfunction extractTypePropertyNames(node: ts.Node): string[] | null {\n let members: ts.NodeArray<ts.TypeElement> | undefined;\n if (ts.isTypeLiteralNode(node)) {\n members = node.members;\n } else if (ts.isInterfaceDeclaration(node)) {\n members = node.members;\n }\n if (!members) return null;\n\n const names: string[] = [];\n for (const member of members) {\n if (ts.isPropertySignature(member) && member.name) {\n if (ts.isIdentifier(member.name)) names.push(member.name.text);\n else if (ts.isStringLiteral(member.name)) names.push(member.name.text);\n else return null;\n }\n }\n return names.length > 0 ? names : null;\n}\n\nfunction deriveFunctionName(node: ts.Node, sourceFile: ts.SourceFile): string {\n if (ts.isFunctionDeclaration(node) && node.name) {\n return node.name.text;\n }\n if (ts.isMethodDeclaration(node) && ts.isIdentifier(node.name)) {\n const parent = node.parent;\n if (ts.isClassDeclaration(parent) && parent.name) {\n return `${parent.name.text}.${node.name.text}`;\n }\n return node.name.text;\n }\n const parent = node.parent;\n if (ts.isVariableDeclaration(parent) && ts.isIdentifier(parent.name)) {\n return parent.name.text;\n }\n if (ts.isPropertyAssignment(parent) && ts.isIdentifier(parent.name)) {\n return parent.name.text;\n }\n const line = ts.getLineAndCharacterOfPosition(sourceFile, node.getStart(sourceFile)).line + 1;\n return `<anonymous>:${line}`;\n}\n","import * as ts from \"typescript\";\nimport type { CrossFileRule, Diagnostic, ProjectIndex } from \"../types.ts\";\nimport type { FunctionEntry } from \"../../collect/function-registry.ts\";\nimport { asSignatureLike, type SignatureLike } from \"../../typecheck/utils.ts\";\n\ninterface TrivialCallTarget {\n calleeName: string;\n callExpr: ts.CallExpression;\n}\n\nfunction getCalleeName(expr: ts.Expression): string | undefined {\n if (ts.isIdentifier(expr)) return expr.text;\n if (ts.isPropertyAccessExpression(expr)) return expr.name.text;\n return undefined;\n}\n\n/**\n * Structural fences that disqualify a wrapper from being \"trivial\" regardless\n * of body shape. Each represents a type/contract transformation that's lost\n * if a caller switches to the wrappee directly.\n */\nfunction hasTypeLevelTransformation(fn: SignatureLike): boolean {\n // Wrapper specializes a type predicate (e.g. `x is RangeError` vs `x is Error`).\n if (fn.type !== undefined && ts.isTypePredicateNode(fn.type)) return true;\n // Wrapper introduces its own generic parameters — the type contract differs.\n return fn.typeParameters !== undefined && fn.typeParameters.length > 0;\n}\n\nfunction getTrivialCallTarget(fn: FunctionEntry): TrivialCallTarget | null {\n const signature = asSignatureLike(fn.node);\n if (signature === null) return null;\n if (hasTypeLevelTransformation(signature)) return null;\n\n const body = signature.body;\n if (!body) return null;\n\n let callExpr: ts.CallExpression | undefined;\n\n if (ts.isBlock(body)) {\n // Block body: exactly one statement that is `return callee(args)`\n if (body.statements.length !== 1) return null;\n const stmt = body.statements[0];\n if (!stmt || !ts.isReturnStatement(stmt) || !stmt.expression) return null;\n if (!ts.isCallExpression(stmt.expression)) return null;\n callExpr = stmt.expression;\n } else {\n // Expression body arrow: `=> callee(args)`\n if (!ts.isCallExpression(body)) return null;\n callExpr = body;\n }\n\n // If the call carries explicit type arguments, the wrapper is specializing the\n // wrappee's generics at the call site — type-level transformation.\n if (callExpr.typeArguments !== undefined && callExpr.typeArguments.length > 0) return null;\n\n const calleeName = getCalleeName(callExpr.expression);\n if (!calleeName) return null;\n\n // Arguments must be plain identifiers matching the wrapper's param list IN ORDER\n // (no reordering — that's a semantic transformation) and pass every param\n // position (no skipping — wrapper.params.length === call.arguments.length).\n const paramNames = fn.params.map((p) => p.name);\n const args = callExpr.arguments;\n if (args.length !== paramNames.length) return null;\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (arg === undefined || !ts.isIdentifier(arg)) return null;\n if (arg.text !== paramNames[i]) return null;\n }\n\n return { calleeName, callExpr };\n}\n\nexport const trivialWrapper: CrossFileRule = {\n id: \"trivial-wrapper\",\n severity: \"warning\",\n message:\n \"Function is a trivial wrapper that delegates without transformation; consider using the target directly\",\n requires: [\"functions\", \"functionSymbols\", \"callSites\", \"callSiteSymbols\"],\n\n analyze(project: ProjectIndex): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n const projectFnSymbols = new Set<ts.Symbol>();\n for (const f of project.functions.getAll()) {\n if (f.symbol !== undefined) projectFnSymbols.add(f.symbol);\n }\n const callSiteSymbols = new Map<ts.CallExpression, ts.Symbol>();\n for (const site of project.callSites) {\n if (site.symbol !== undefined) callSiteSymbols.set(site.node, site.symbol);\n }\n\n for (const fn of project.functions.getAll()) {\n const target = getTrivialCallTarget(fn);\n if (!target) continue;\n // The callee must resolve, by symbol identity, to a project function.\n // Name matching would misattribute across files and miss aliased imports.\n const calleeSymbol = callSiteSymbols.get(target.callExpr);\n if (calleeSymbol === undefined) continue;\n if (!projectFnSymbols.has(calleeSymbol)) continue;\n // Self-delegation (recursion / re-export binding) is not a wrapper.\n if (fn.symbol !== undefined && calleeSymbol === fn.symbol) continue;\n\n diagnostics.push({\n ruleId: this.id,\n severity: this.severity,\n message: `Function \"${fn.name}\" trivially wraps \"${target.calleeName}\" without transformation`,\n file: fn.file,\n line: fn.line,\n column: 1,\n });\n }\n return diagnostics;\n },\n};\n","import * as path from \"node:path\";\nimport * as ts from \"typescript\";\nimport type { CrossFileAnalysisContext, CrossFileRule, Diagnostic, ProjectIndex } from \"../types.ts\";\n\n/**\n * Analysis runs per tsconfig group, so from inside one group an export\n * consumed only by a sibling package looks unused. This rule therefore\n * merges across groups: each group contributes its locally-unused export\n * candidates plus every usage fact it can see (imports it resolves, call\n * sites it binds), and the final pass drops any candidate some other group\n * proved alive. Still heuristic — consumers outside the scanned tree\n * (published API surface, dynamic access) are invisible to any program.\n */\nexport const unusedExport: CrossFileRule = {\n id: \"unused-export\",\n severity: \"warning\",\n message: \"Export has no usages within the project\",\n requires: [\"functions\", \"functionSymbols\", \"callSites\", \"callSiteSymbols\", \"imports\", \"types\", \"constants\"],\n\n collectGlobalFacts(project: ProjectIndex, context?: CrossFileAnalysisContext): UnusedExportFacts {\n return collectFacts(project, context);\n },\n\n finalizeGlobal(facts: unknown[]): Diagnostic[] {\n return finalize(facts as UnusedExportFacts[], this.severity);\n },\n\n analyze(project: ProjectIndex, context?: CrossFileAnalysisContext): Diagnostic[] {\n // Single-group view: the merge pipeline with exactly one group's facts.\n return finalize([collectFacts(project, context)], this.severity);\n },\n};\n\ninterface ExportCandidate {\n file: string;\n name: string;\n /** Message wording only: \"function\" | \"type\" | \"constant\". */\n kindLabel: string;\n line: number;\n exportedAsDefault: boolean;\n /** Declaring class for methods — alive when the class is used anywhere. */\n className: string | null;\n}\n\ninterface UnusedExportFacts {\n candidates: ExportCandidate[];\n /** `${file}\\0${name}` keys proven used: resolved imports + bound call sites. */\n usedKeys: string[];\n wildcardImportedFiles: string[];\n defaultUsedFiles: string[];\n}\n\nfunction collectFacts(project: ProjectIndex, context: CrossFileAnalysisContext | undefined): UnusedExportFacts {\n // Declaration nodes referenced by call sites. Using valueDeclaration (the\n // AST node) instead of symbol identity so that inherited class methods are\n // correctly matched — a call to `subclass.method()` resolves through the\n // prototype chain to the same declaration node as the base class entry.\n const usedDeclarations = new Set<ts.Node>();\n const usedKeys = new Set<string>();\n // Files whose default export is referenced by some importer.\n const defaultUsedFiles = new Set<string>();\n const wildcardImportedFiles = new Set<string>();\n\n for (const site of project.callSites) {\n const symbol = site.symbol;\n if (symbol?.valueDeclaration === undefined) continue;\n usedDeclarations.add(symbol.valueDeclaration);\n // Cross-group reach: a sibling group's program may compile this file too,\n // so record the usage by (declaring file, symbol name) for the merge.\n usedKeys.add(exportKey(symbol.valueDeclaration.getSourceFile().fileName, symbol.name));\n }\n\n // Count source-resolved imports as usage. Default imports are tracked by\n // target file because the consumer may freely rename the local binding.\n // Namespace imports / star re-exports make every export of the target\n // reachable, so the whole file is exempted. The checker-resolved target\n // (path aliases, workspace packages) takes precedence; textual resolution\n // covers source-only mode where no program exists.\n const projectFiles = new Set(project.files.keys());\n for (const imp of project.imports) {\n const target = imp.resolvedFile ?? resolveImportTarget(imp.file, imp.source, projectFiles);\n if (target === null) continue;\n if (imp.importedName === \"*\") {\n wildcardImportedFiles.add(target);\n } else if (imp.importedName === \"default\") {\n defaultUsedFiles.add(target);\n } else {\n usedKeys.add(exportKey(target, imp.importedName));\n }\n }\n\n // Class names imported from other files. When a class is imported, its\n // public methods are reachable — callers may interact through an interface\n // type (DI, Effect layers) where the call-site symbol resolves to the\n // interface method, not the class method.\n const importedClassNames = buildImportedClassNames(project);\n\n // Per-file identifier occurrence counts. A declaration contributes one\n // occurrence of its own name; any second occurrence in the same file is a\n // same-file reference (value use, type annotation, callback, re-export\n // list). Shadowing can over-count, which only under-reports — safe.\n const identifierCounts = buildIdentifierCounts(project);\n const usedInOwnFile = (file: string, name: string): boolean =>\n (identifierCounts.get(file)?.get(name) ?? 0) > 1;\n\n const reportable = context?.reportableFiles;\n const candidates: ExportCandidate[] = [];\n\n for (const fn of project.functions.getAll()) {\n if (!fn.exported) continue;\n if (reportable !== undefined && !reportable.has(fn.file)) continue;\n if (isEntryPoint(fn.file)) continue;\n if (wildcardImportedFiles.has(fn.file)) continue;\n\n // Class methods on classes that implement an interface are contract\n // obligations — they exist to fulfill the interface, not as independent API\n if (fn.implementsInterface) continue;\n\n // Class methods on classes imported from other files are reachable\n // through the class instance, even when calls go through an interface type\n if (fn.className !== undefined && isClassImported(fn.className, fn.file, importedClassNames)) continue;\n\n // Declaration-based usage (handles inheritance)\n if (fn.symbol?.valueDeclaration && usedDeclarations.has(fn.symbol.valueDeclaration)) continue;\n\n if (usedKeys.has(exportKey(fn.file, fn.name))) continue;\n\n // Default-export reachability: if this function is the file's default\n // export and some importer's default import resolves to this file,\n // the function is in use even without a textual name match (consumers\n // can rename the binding: `import Whatever from \"./file\"`).\n if (fn.exportedAsDefault === true && defaultUsedFiles.has(fn.file)) continue;\n\n // Same-file reference without a call — passed as a callback, etc.\n if (usedInOwnFile(fn.file, fn.name)) continue;\n\n candidates.push({\n file: fn.file,\n name: fn.name,\n kindLabel: \"function\",\n line: fn.line,\n exportedAsDefault: fn.exportedAsDefault === true,\n className: fn.className ?? null,\n });\n }\n\n for (const type of project.types.getAll()) {\n if (!type.exported) continue;\n if (reportable !== undefined && !reportable.has(type.file)) continue;\n if (isEntryPoint(type.file)) continue;\n if (wildcardImportedFiles.has(type.file)) continue;\n if (usedKeys.has(exportKey(type.file, type.name))) continue;\n if (usedInOwnFile(type.file, type.name)) continue;\n\n candidates.push({\n file: type.file,\n name: type.name,\n kindLabel: \"type\",\n line: type.line,\n exportedAsDefault: false,\n className: null,\n });\n }\n\n for (const constant of project.constants.getAll()) {\n if (!constant.exported) continue;\n if (reportable !== undefined && !reportable.has(constant.file)) continue;\n if (isEntryPoint(constant.file)) continue;\n if (wildcardImportedFiles.has(constant.file)) continue;\n if (usedKeys.has(exportKey(constant.file, constant.name))) continue;\n if (usedInOwnFile(constant.file, constant.name)) continue;\n\n candidates.push({\n file: constant.file,\n name: constant.name,\n kindLabel: \"constant\",\n line: constant.line,\n exportedAsDefault: false,\n className: null,\n });\n }\n\n return {\n candidates,\n usedKeys: [...usedKeys],\n wildcardImportedFiles: [...wildcardImportedFiles],\n defaultUsedFiles: [...defaultUsedFiles],\n };\n}\n\nfunction finalize(factsList: UnusedExportFacts[], severity: Diagnostic[\"severity\"]): Diagnostic[] {\n const used = new Set<string>();\n const wildcard = new Set<string>();\n const defaultUsed = new Set<string>();\n for (const facts of factsList) {\n for (const key of facts.usedKeys) used.add(key);\n for (const file of facts.wildcardImportedFiles) wildcard.add(file);\n for (const file of facts.defaultUsedFiles) defaultUsed.add(file);\n }\n\n const diagnostics: Diagnostic[] = [];\n const seen = new Set<string>();\n for (const facts of factsList) {\n for (const candidate of facts.candidates) {\n const key = exportKey(candidate.file, candidate.name);\n if (seen.has(key)) continue;\n seen.add(key);\n if (used.has(key)) continue;\n if (wildcard.has(candidate.file)) continue;\n if (candidate.exportedAsDefault && defaultUsed.has(candidate.file)) continue;\n if (candidate.className !== null && used.has(exportKey(candidate.file, candidate.className))) continue;\n\n diagnostics.push({\n ruleId: unusedExport.id,\n severity,\n message: `Exported ${candidate.kindLabel} \"${candidate.name}\" has no usages in the project`,\n file: candidate.file,\n line: candidate.line,\n column: 1,\n });\n }\n }\n return diagnostics;\n}\n\n/** Count identifier occurrences per file; the declaration itself counts once. */\nfunction buildIdentifierCounts(project: ProjectIndex): Map<string, Map<string, number>> {\n const counts = new Map<string, Map<string, number>>();\n for (const [file, { sourceFile }] of project.files) {\n const fileCounts = new Map<string, number>();\n counts.set(file, fileCounts);\n const visit = (node: ts.Node): void => {\n if (ts.isIdentifier(node)) {\n fileCounts.set(node.text, (fileCounts.get(node.text) ?? 0) + 1);\n }\n ts.forEachChild(node, visit);\n };\n visit(sourceFile);\n }\n return counts;\n}\n\nfunction isEntryPoint(file: string): boolean {\n if (/\\/index\\.[cm]?[jt]sx?$/.test(file)) return true;\n return /\\/bin\\//.test(file);\n}\n\n/** Map each class name to the set of files that import it. */\nfunction buildImportedClassNames(project: ProjectIndex): Map<string, Set<string>> {\n const map = new Map<string, Set<string>>();\n for (const imp of project.imports) {\n let files = map.get(imp.importedName);\n if (!files) {\n files = new Set();\n map.set(imp.importedName, files);\n }\n files.add(imp.file);\n }\n return map;\n}\n\n/** Check if a class is imported from a file other than where it's declared. */\nfunction isClassImported(className: string, declFile: string, importedNames: Map<string, Set<string>>): boolean {\n const importers = importedNames.get(className);\n if (!importers) return false;\n return [...importers].some((f) => f !== declFile);\n}\n\nconst MODULE_EXTENSIONS = [\".ts\", \".tsx\", \".js\", \".jsx\", \".mjs\", \".cjs\"] as const;\nconst INDEX_BASENAMES = MODULE_EXTENSIONS.map((ext) => `index${ext}`);\n\nfunction exportKey(file: string, name: string): string {\n return `${file}\\0${name}`;\n}\n\n/**\n * Resolve a relative import source to a project file path. Returns null for\n * non-relative imports (package names) or when no candidate is in the project.\n */\nfunction resolveImportTarget(\n importerFile: string,\n importSource: string,\n projectFiles: Set<string>,\n): string | null {\n if (!importSource.startsWith(\".\")) return null;\n const base = path.resolve(path.dirname(importerFile), importSource);\n\n // Direct extension match (./foo -> ./foo.ts)\n for (const ext of MODULE_EXTENSIONS) {\n const candidate = base + ext;\n if (projectFiles.has(candidate)) return candidate;\n }\n // Already-extensioned (./foo.ts)\n if (projectFiles.has(base)) return base;\n // Directory with index file (./foo -> ./foo/index.ts)\n for (const idx of INDEX_BASENAMES) {\n const candidate = path.join(base, idx);\n if (projectFiles.has(candidate)) return candidate;\n }\n return null;\n}\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\n\nexport const noAnyCast: TSRule = {\n kind: \"ts\",\n id: \"no-any-cast\",\n severity: \"error\",\n message: \"Casting to `any` erases type safety; use a specific type or generic instead\",\n syntaxKinds: [ts.SyntaxKind.AsExpression],\n requiresTypeInfo: false,\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isAsExpression(node)) return;\n if (node.type.kind !== ts.SyntaxKind.AnyKeyword) return;\n ctx.report(node);\n },\n};\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\n\nexport const noAwaitCoalesce: TSRule = {\n kind: \"ts\",\n id: \"no-await-coalesce\",\n severity: \"warning\",\n message:\n \"?? on a value whose nullability comes from a call's return type collapses failure modes; check the result and branch instead of defaulting\",\n syntaxKinds: [ts.SyntaxKind.BinaryExpression],\n requiresStrictNullChecks: true,\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isBinaryExpression(node)) return;\n if (node.operatorToken.kind !== ts.SyntaxKind.QuestionQuestionToken) return;\n\n const walk = walkLeftChain(node.left);\n if (!walk || !walk.call) return;\n\n const sig = ctx.semantics.resolvedSignature(walk.call);\n if (!sig) return;\n\n // Built-in container APIs (Map.get, Array.find, ts.forEachChild, etc.) use\n // `T | undefined` to encode \"not present\" — that's structural absence by design,\n // not a fallible operation. Only flag user-defined calls.\n const declSourceFile = sig.declaration?.getSourceFile();\n if (\n declSourceFile &&\n (declSourceFile.isDeclarationFile || declSourceFile.fileName.includes(\"/node_modules/\"))\n ) {\n return;\n }\n\n let returnType = sig.getReturnType();\n if (walk.awaited) {\n const awaitedType = ctx.semantics.awaitedType(returnType);\n if (awaitedType) returnType = awaitedType;\n }\n\n const includesNull = typeIncludes(returnType, ts.TypeFlags.Null);\n const includesUndefined = typeIncludes(returnType, ts.TypeFlags.Undefined | ts.TypeFlags.Void);\n\n // Optional chains in the LHS contribute `undefined` structurally — that's not\n // call-derived nullability. Only flag undefined-only return types when no chain\n // is present; flag null-bearing return types regardless (null doesn't come from `?.`).\n if (walk.optionalChain) {\n if (!includesNull) return;\n } else {\n if (!includesNull && !includesUndefined) return;\n }\n\n ctx.report(node);\n },\n};\n\ninterface ChainWalk {\n call: ts.CallExpression | null;\n awaited: boolean;\n optionalChain: boolean;\n}\n\n/**\n * Walk an expression tree from the outside in, collecting chain properties.\n * Pass-throughs: parens, await, property access, element access, non-null assertion.\n * Stops at the first call (returning it) or at any non-passthrough shape.\n */\nfunction walkLeftChain(expr: ts.Expression): ChainWalk | null {\n const result: ChainWalk = { call: null, awaited: false, optionalChain: false };\n let cur: ts.Node = expr;\n for (;;) {\n while (ts.isParenthesizedExpression(cur)) cur = cur.expression;\n if (ts.isCallExpression(cur)) {\n if (cur.questionDotToken !== undefined) result.optionalChain = true;\n result.call = cur;\n return result;\n }\n if (ts.isAwaitExpression(cur)) {\n result.awaited = true;\n cur = cur.expression;\n continue;\n }\n if (ts.isPropertyAccessExpression(cur)) {\n if (cur.questionDotToken !== undefined) result.optionalChain = true;\n cur = cur.expression;\n continue;\n }\n if (ts.isElementAccessExpression(cur)) {\n if (cur.questionDotToken !== undefined) result.optionalChain = true;\n cur = cur.expression;\n continue;\n }\n if (ts.isNonNullExpression(cur)) {\n cur = cur.expression;\n continue;\n }\n return null;\n }\n}\n\nfunction typeIncludes(type: ts.Type, mask: number): boolean {\n if (type.isUnion()) return type.types.some((t) => (t.flags & mask) !== 0);\n return (type.flags & mask) !== 0;\n}\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\n\ntype Fallback =\n | { kind: \"null\" }\n | { kind: \"undefined\" }\n | { kind: \"empty-array\" };\n\nexport const noCoalesceThenGuard: TSRule = {\n kind: \"ts\",\n id: \"no-coalesce-then-guard\",\n severity: \"warning\",\n message:\n \"?? fallback fuses with subsequent guard; the partition is identical to checking the original value directly\",\n syntaxKinds: [ts.SyntaxKind.BinaryExpression],\n requiresTypeInfo: false,\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isBinaryExpression(node)) return;\n if (node.operatorToken.kind !== ts.SyntaxKind.QuestionQuestionToken) return;\n\n const decl = getDeclarationContext(node);\n if (!decl) return;\n\n const fallback = classifyFallback(node.right);\n if (!fallback) return;\n\n const block = decl.statement.parent;\n if (!ts.isBlock(block) && !ts.isSourceFile(block)) return;\n const stmts = block.statements;\n const idx = stmts.indexOf(decl.statement);\n if (idx < 0) return;\n\n for (let i = idx + 1; i < stmts.length; i++) {\n const stmt = stmts[i];\n if (stmt === undefined) break;\n if (containsAssignmentTo(stmt, decl.binding)) break;\n if (!ts.isIfStatement(stmt)) continue;\n if (matchesGuard(stmt.expression, decl.binding, fallback)) {\n ctx.report(node);\n return;\n }\n }\n },\n};\n\ninterface DeclarationContext {\n binding: string;\n statement: ts.VariableStatement;\n}\n\nfunction getDeclarationContext(coalesce: ts.BinaryExpression): DeclarationContext | undefined {\n let cur: ts.Node = coalesce;\n while (cur.parent && ts.isParenthesizedExpression(cur.parent)) cur = cur.parent;\n const decl: ts.Node | undefined = cur.parent;\n if (!decl || !ts.isVariableDeclaration(decl)) return undefined;\n if (!ts.isIdentifier(decl.name)) return undefined;\n const list: ts.Node | undefined = decl.parent;\n if (!list || !ts.isVariableDeclarationList(list)) return undefined;\n const stmt: ts.Node | undefined = list.parent;\n if (!stmt || !ts.isVariableStatement(stmt)) return undefined;\n return { binding: decl.name.text, statement: stmt };\n}\n\nfunction classifyFallback(node: ts.Expression): Fallback | undefined {\n let inner = node;\n while (ts.isParenthesizedExpression(inner)) inner = inner.expression;\n if (inner.kind === ts.SyntaxKind.NullKeyword) return { kind: \"null\" };\n if (ts.isIdentifier(inner) && inner.text === \"undefined\") return { kind: \"undefined\" };\n if (ts.isArrayLiteralExpression(inner) && inner.elements.length === 0) return { kind: \"empty-array\" };\n return undefined;\n}\n\nfunction matchesGuard(expr: ts.Expression, binding: string, fallback: Fallback): boolean {\n let cond = expr;\n while (ts.isParenthesizedExpression(cond)) cond = cond.expression;\n\n // `if (!x)` after `x = a ?? null/undefined`: !(a ?? null) ≡ !a, so the\n // guard partitions identically to testing the original value — the ??\n // contributes nothing.\n if (\n (fallback.kind === \"null\" || fallback.kind === \"undefined\") &&\n ts.isPrefixUnaryExpression(cond) &&\n cond.operator === ts.SyntaxKind.ExclamationToken &&\n isIdentifierNamed(cond.operand, binding)\n ) {\n return true;\n }\n\n if (!ts.isBinaryExpression(cond)) return false;\n\n if (fallback.kind === \"null\") {\n if (!isEqOp(cond.operatorToken.kind)) return false;\n return matchesSidedLiteral(cond, binding, (n) => n.kind === ts.SyntaxKind.NullKeyword);\n }\n if (fallback.kind === \"undefined\") {\n if (!isEqOp(cond.operatorToken.kind)) return false;\n return matchesSidedLiteral(cond, binding, (n) => ts.isIdentifier(n) && n.text === \"undefined\");\n }\n return matchesEmptyArrayPartition(cond, binding);\n}\n\nfunction isEqOp(kind: ts.SyntaxKind): boolean {\n return (\n kind === ts.SyntaxKind.EqualsEqualsEqualsToken ||\n kind === ts.SyntaxKind.EqualsEqualsToken ||\n kind === ts.SyntaxKind.ExclamationEqualsEqualsToken ||\n kind === ts.SyntaxKind.ExclamationEqualsToken\n );\n}\n\nfunction matchesSidedLiteral(\n bin: ts.BinaryExpression,\n binding: string,\n isLit: (n: ts.Node) => boolean,\n): boolean {\n if (isIdentifierNamed(bin.left, binding) && isLit(bin.right)) return true;\n return isIdentifierNamed(bin.right, binding) && isLit(bin.left);\n}\n\nfunction isIdentifierNamed(node: ts.Node, name: string): boolean {\n return ts.isIdentifier(node) && node.text === name;\n}\n\n/**\n * binding.length checked against 0/1 in a way that partitions identically to\n * \"binding was nullish (and thus the [] fallback ran)\" for an empty-array fallback.\n */\nfunction matchesEmptyArrayPartition(cond: ts.BinaryExpression, binding: string): boolean {\n const lengthOnLeft = isLengthAccess(cond.left, binding);\n const lengthOnRight = isLengthAccess(cond.right, binding);\n if (!lengthOnLeft && !lengthOnRight) return false;\n const numNode = lengthOnLeft ? cond.right : cond.left;\n if (!ts.isNumericLiteral(numNode)) return false;\n const n = Number(numNode.text);\n if (Number.isNaN(n)) return false;\n const op = cond.operatorToken.kind;\n\n if (\n (op === ts.SyntaxKind.EqualsEqualsEqualsToken || op === ts.SyntaxKind.EqualsEqualsToken) &&\n n === 0\n ) {\n return true;\n }\n if (\n (op === ts.SyntaxKind.ExclamationEqualsEqualsToken || op === ts.SyntaxKind.ExclamationEqualsToken) &&\n n === 0\n ) {\n return true;\n }\n if (lengthOnLeft) {\n if (op === ts.SyntaxKind.GreaterThanToken && n === 0) return true;\n if (op === ts.SyntaxKind.GreaterThanEqualsToken && n === 1) return true;\n if (op === ts.SyntaxKind.LessThanToken && n === 1) return true;\n } else {\n if (op === ts.SyntaxKind.LessThanToken && n === 0) return true;\n if (op === ts.SyntaxKind.LessThanEqualsToken && n === 1) return true;\n if (op === ts.SyntaxKind.GreaterThanToken && n === 1) return true;\n }\n return false;\n}\n\nfunction isLengthAccess(node: ts.Node, bindingName: string): boolean {\n if (!ts.isPropertyAccessExpression(node)) return false;\n if (node.name.text !== \"length\") return false;\n return isIdentifierNamed(node.expression, bindingName);\n}\n\nfunction containsAssignmentTo(stmt: ts.Node, name: string): boolean {\n let found = false;\n function walk(node: ts.Node): void {\n if (found) return;\n if (ts.isBinaryExpression(node) && isAssignmentOp(node.operatorToken.kind)) {\n if (isIdentifierNamed(node.left, name)) {\n found = true;\n return;\n }\n }\n ts.forEachChild(node, walk);\n }\n walk(stmt);\n return found;\n}\n\nfunction isAssignmentOp(kind: ts.SyntaxKind): boolean {\n return (\n kind === ts.SyntaxKind.EqualsToken ||\n kind === ts.SyntaxKind.PlusEqualsToken ||\n kind === ts.SyntaxKind.MinusEqualsToken ||\n kind === ts.SyntaxKind.AsteriskEqualsToken ||\n kind === ts.SyntaxKind.SlashEqualsToken ||\n kind === ts.SyntaxKind.QuestionQuestionEqualsToken ||\n kind === ts.SyntaxKind.BarBarEqualsToken ||\n kind === ts.SyntaxKind.AmpersandAmpersandEqualsToken\n );\n}\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\n\n/**\n * `x ?? undefined` where `x` can be undefined but never null: the expression\n * maps undefined to undefined — an identity no-op. Only meaningful when the\n * left side can be null (it normalizes null to undefined); when the left side\n * is not nullable at all, `no-nullish-coalescing` owns the diagnostic.\n */\nexport const noCoalesceUndefined: TSRule = {\n kind: \"ts\",\n id: \"no-coalesce-undefined\",\n severity: \"warning\",\n message: \"?? undefined is an identity no-op here: the value can be undefined but never null\",\n syntaxKinds: [ts.SyntaxKind.BinaryExpression],\n requiresStrictNullChecks: true,\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isBinaryExpression(node)) return;\n if (node.operatorToken.kind !== ts.SyntaxKind.QuestionQuestionToken) return;\n\n // The replacement value must itself be plain `undefined` (covers the\n // identifier, `void 0`, and constants typed undefined).\n const rhsType = ctx.semantics.typeAtLocation(node.right);\n if (rhsType.flags !== ts.TypeFlags.Undefined) return;\n\n const lhsType = ctx.semantics.typeAtLocation(node.left);\n const parts = lhsType.isUnion() ? lhsType.types : [lhsType];\n if (parts.some((p) => (p.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown | ts.TypeFlags.Instantiable)) !== 0)) {\n return;\n }\n const hasUndefined = parts.some((p) => (p.flags & (ts.TypeFlags.Undefined | ts.TypeFlags.Void)) !== 0);\n const hasNull = parts.some((p) => (p.flags & ts.TypeFlags.Null) !== 0);\n if (!hasUndefined || hasNull) return;\n\n ctx.report(node, undefined, {\n start: node.getStart(ctx.sourceFile),\n end: node.getEnd(),\n text: node.left.getText(ctx.sourceFile),\n });\n },\n};\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\n\n/**\n * Narrowing constructs whose outcome the types already decide: truthiness\n * checks on always-truthy values, typeof comparisons that can only go one\n * way, instanceof on a value whose class already extends the target, and\n * type-predicate calls whose argument is already of the predicate type.\n * These are the literal \"defensive checks for impossible states\" — the\n * branch (or its absence) is dead code.\n *\n * Only condition positions are examined (if/while/do/for/ternary tests and\n * the operands of !/&&/|| within them); a boolean produced for a typed slot\n * is not a narrowing.\n */\nexport const noDeadNarrowing: TSRule = {\n kind: \"ts\",\n id: \"no-dead-narrowing\",\n severity: \"warning\",\n message: \"Condition is statically decided by the operand's type; the check is dead code\",\n syntaxKinds: [\n ts.SyntaxKind.IfStatement,\n ts.SyntaxKind.WhileStatement,\n ts.SyntaxKind.DoStatement,\n ts.SyntaxKind.ForStatement,\n ts.SyntaxKind.ConditionalExpression,\n ],\n requiresStrictNullChecks: true,\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n const condition = conditionOf(node);\n if (condition === undefined) return;\n checkCondition(condition, ctx);\n },\n};\n\nfunction conditionOf(node: ts.Node): ts.Expression | undefined {\n if (ts.isIfStatement(node) || ts.isWhileStatement(node) || ts.isDoStatement(node)) {\n return node.expression;\n }\n if (ts.isForStatement(node)) return node.condition;\n if (ts.isConditionalExpression(node)) return node.condition;\n return undefined;\n}\n\n/** Decompose `!`/`&&`/`||`/parens and check each atomic test. */\nfunction checkCondition(expr: ts.Expression, ctx: TSVisitContext): void {\n if (ts.isParenthesizedExpression(expr)) {\n checkCondition(expr.expression, ctx);\n return;\n }\n if (ts.isPrefixUnaryExpression(expr) && expr.operator === ts.SyntaxKind.ExclamationToken) {\n checkCondition(expr.operand, ctx);\n return;\n }\n if (ts.isBinaryExpression(expr)) {\n const op = expr.operatorToken.kind;\n if (op === ts.SyntaxKind.AmpersandAmpersandToken || op === ts.SyntaxKind.BarBarToken) {\n checkCondition(expr.left, ctx);\n checkCondition(expr.right, ctx);\n return;\n }\n checkTypeofComparison(expr, ctx);\n checkInstanceof(expr, ctx);\n return;\n }\n if (ts.isCallExpression(expr)) {\n checkPredicateCall(expr, ctx);\n return;\n }\n if (ts.isIdentifier(expr) || ts.isPropertyAccessExpression(expr)) {\n checkTruthiness(expr, ctx);\n }\n}\n\n// ---------- (a) truthiness ----------\n\nfunction checkTruthiness(expr: ts.Expression, ctx: TSVisitContext): void {\n // Without noUncheckedIndexedAccess, every value that flowed through an\n // index read (`rows[0]`, `const [first] = list`) — directly or behind a\n // helper's return type — carries a type with `undefined` erased. An\n // \"always truthy\" verdict on such a type is advice to delete a\n // load-bearing guard. We can only prove truthiness when the type system\n // tracks absence everywhere.\n if (ctx.compilerOptions.noUncheckedIndexedAccess !== true) return;\n // Declaration files describe a foreign runtime and are known to lie under\n // edge conditions (ts.Node#parent is undefined at roots, DOM properties\n // before load). A truthiness check against an ambient claim is boundary\n // validation, not a dead branch.\n if (isAmbientDeclared(expr, ctx)) return;\n // Judge by the DECLARED type, not the flow type: flow analysis carries an\n // initializer's (possibly lying) type past an honest `| undefined`\n // annotation, which would flag the very check the annotation asks for.\n const declaredType = declaredTypeOf(expr, ctx);\n if (declaredType === null) return;\n const parts = analyzableParts(declaredType);\n if (parts === null) return;\n if (!parts.every(isDefinitelyTruthyType)) return;\n ctx.report(\n expr,\n `\\`${expr.getText(ctx.sourceFile)}\\` is declared \\`${ctx.checker.typeToString(declaredType)}\\`, which is always truthy; the condition is dead`,\n );\n}\n\n/** The expression's DECLARED type via its symbol, or null when unresolvable. */\nfunction declaredTypeOf(expr: ts.Expression, ctx: TSVisitContext): ts.Type | null {\n const symbol = ctx.semantics.symbolAtLocation(expr);\n const declaration = symbol?.valueDeclaration;\n if (symbol === undefined || declaration === undefined) return null;\n return ctx.checker.getTypeOfSymbolAtLocation(symbol, declaration);\n}\n\n/** Union members when every one is analyzable (no any/unknown/type params), else null. */\nfunction analyzableParts(type: ts.Type): ts.Type[] | null {\n if (isUnanalyzableType(type)) return null;\n const parts = type.isUnion() ? type.types : [type];\n if (parts.some(isUnanalyzableType)) return null;\n return parts;\n}\n\nfunction isAmbientDeclared(expr: ts.Expression, ctx: TSVisitContext): boolean {\n const symbol = ctx.semantics.symbolAtLocation(expr);\n const declaration = symbol?.valueDeclaration ?? symbol?.declarations?.[0];\n if (declaration === undefined) return false;\n return declaration.getSourceFile().isDeclarationFile;\n}\n\nfunction isUnanalyzableType(type: ts.Type): boolean {\n return (type.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown | ts.TypeFlags.Instantiable)) !== 0;\n}\n\nfunction isDefinitelyTruthyType(type: ts.Type): boolean {\n // Enum members carry literal flags too, but enum value sets evolve — skip.\n if (type.flags & ts.TypeFlags.EnumLike) return false;\n if (type.isStringLiteral()) return type.value.length > 0;\n if (type.isNumberLiteral()) return type.value !== 0;\n if (type.flags & ts.TypeFlags.BigIntLiteral) {\n const value = (type as ts.BigIntLiteralType).value;\n return value.base10Value !== \"0\";\n }\n if (type.flags & ts.TypeFlags.BooleanLiteral) {\n return ctxIntrinsicName(type) === \"true\";\n }\n if (type.flags & (ts.TypeFlags.ESSymbol | ts.TypeFlags.UniqueESSymbol | ts.TypeFlags.NonPrimitive)) {\n return true;\n }\n if (type.flags & ts.TypeFlags.Object) {\n // `{}` and bare anonymous shells are satisfiable by primitives (\"\" has\n // string's members) — only structured object types are reliably truthy.\n return (\n type.getProperties().length > 0 ||\n type.getCallSignatures().length > 0 ||\n type.getConstructSignatures().length > 0 ||\n type.getStringIndexType() !== undefined ||\n type.getNumberIndexType() !== undefined\n );\n }\n return false;\n}\n\nfunction ctxIntrinsicName(type: ts.Type): string | undefined {\n const name = Reflect.get(type, \"intrinsicName\");\n return typeof name === \"string\" ? name : undefined;\n}\n\n// ---------- (b) typeof ----------\n\nconst EQUALITY_OPS = new Set([\n ts.SyntaxKind.EqualsEqualsEqualsToken,\n ts.SyntaxKind.ExclamationEqualsEqualsToken,\n ts.SyntaxKind.EqualsEqualsToken,\n ts.SyntaxKind.ExclamationEqualsToken,\n]);\n\nfunction checkTypeofComparison(expr: ts.BinaryExpression, ctx: TSVisitContext): void {\n if (!EQUALITY_OPS.has(expr.operatorToken.kind)) return;\n let typeofExpr: ts.TypeOfExpression;\n let literal: ts.StringLiteral;\n if (ts.isTypeOfExpression(expr.left) && ts.isStringLiteral(expr.right)) {\n typeofExpr = expr.left;\n literal = expr.right;\n } else if (ts.isTypeOfExpression(expr.right) && ts.isStringLiteral(expr.left)) {\n typeofExpr = expr.right;\n literal = expr.left;\n } else {\n return;\n }\n\n // `typeof document === \"undefined\"` and friends: ambient globals exist in\n // some runtimes and not others (SSR, workers, tests). The declaration is an\n // environment claim, not a guarantee — the guard is the point.\n if (isAmbientDeclared(typeofExpr.expression, ctx)) return;\n\n const operandType = ctx.semantics.typeAtLocation(typeofExpr.expression);\n const parts = analyzableParts(operandType);\n if (parts === null) return;\n if (parts.some((p) => (p.flags & ts.TypeFlags.EnumLike) !== 0)) return;\n\n const memberSets = parts.map(possibleTypeofResults);\n if (memberSets.some((s) => s === null)) return;\n const sets = memberSets as Set<string>[];\n\n const canMatch = sets.some((s) => s.has(literal.text));\n const mustMatch = sets.every((s) => s.size === 1 && s.has(literal.text));\n const isNegated =\n expr.operatorToken.kind === ts.SyntaxKind.ExclamationEqualsEqualsToken ||\n expr.operatorToken.kind === ts.SyntaxKind.ExclamationEqualsToken;\n\n const operandText = typeofExpr.expression.getText(ctx.sourceFile);\n const typeText = ctx.checker.typeToString(operandType);\n if (!canMatch) {\n ctx.report(\n expr,\n `typeof comparison is always ${isNegated ? \"true\" : \"false\"}: \\`${operandText}\\` is \\`${typeText}\\`, and typeof never yields \"${literal.text}\" for that type`,\n );\n } else if (mustMatch) {\n ctx.report(\n expr,\n `typeof comparison is always ${isNegated ? \"false\" : \"true\"}: \\`${operandText}\\` is \\`${typeText}\\`, and typeof always yields \"${literal.text}\" for that type`,\n );\n }\n}\n\n/** The set of strings `typeof` can produce for a type, or null if undecidable. */\nfunction possibleTypeofResults(type: ts.Type): Set<string> | null {\n if (type.flags & (ts.TypeFlags.String | ts.TypeFlags.StringLiteral)) return new Set([\"string\"]);\n if (type.flags & (ts.TypeFlags.Number | ts.TypeFlags.NumberLiteral)) return new Set([\"number\"]);\n if (type.flags & (ts.TypeFlags.BigInt | ts.TypeFlags.BigIntLiteral)) return new Set([\"bigint\"]);\n if (type.flags & (ts.TypeFlags.Boolean | ts.TypeFlags.BooleanLiteral)) return new Set([\"boolean\"]);\n if (type.flags & (ts.TypeFlags.Undefined | ts.TypeFlags.Void)) return new Set([\"undefined\"]);\n if (type.flags & ts.TypeFlags.Null) return new Set([\"object\"]);\n if (type.flags & (ts.TypeFlags.ESSymbol | ts.TypeFlags.UniqueESSymbol)) return new Set([\"symbol\"]);\n if (type.flags & ts.TypeFlags.Object) {\n // A callable is always \"function\"; a non-callable object type can still be\n // implemented by a function with matching properties, so keep \"function\".\n if (type.getCallSignatures().length > 0 || type.getConstructSignatures().length > 0) {\n return new Set([\"function\"]);\n }\n // `{}` (e.g. `unknown` narrowed by `!== undefined`) admits primitives too.\n if (\n type.getProperties().length === 0 &&\n type.getStringIndexType() === undefined &&\n type.getNumberIndexType() === undefined\n ) {\n return null;\n }\n return new Set([\"object\", \"function\"]);\n }\n if (type.flags & ts.TypeFlags.NonPrimitive) return new Set([\"object\", \"function\"]);\n return null;\n}\n\n// ---------- (c) instanceof ----------\n\nfunction checkInstanceof(expr: ts.BinaryExpression, ctx: TSVisitContext): void {\n if (expr.operatorToken.kind !== ts.SyntaxKind.InstanceOfKeyword) return;\n\n const targetDecl = classDeclarationOf(resolveAlias(ctx.semantics.symbolAtLocation(expr.right), ctx));\n if (targetDecl === null) return;\n\n const leftType = ctx.semantics.typeAtLocation(expr.left);\n const parts = analyzableParts(leftType);\n if (parts === null) return;\n\n // Always-true only, and only via the nominal heritage chain — structural\n // matches and cross-realm objects make always-false unprovable.\n for (const part of parts) {\n const decl = classDeclarationOf(part.getSymbol());\n if (decl === null) return;\n if (!heritageReaches(decl, targetDecl, ctx, 0)) return;\n }\n ctx.report(\n expr,\n `instanceof is always true: \\`${expr.left.getText(ctx.sourceFile)}\\` is \\`${ctx.checker.typeToString(leftType)}\\`, which already extends \\`${expr.right.getText(ctx.sourceFile)}\\``,\n );\n}\n\nfunction resolveAlias(symbol: ts.Symbol | undefined, ctx: TSVisitContext): ts.Symbol | undefined {\n if (symbol === undefined) return undefined;\n if (symbol.flags & ts.SymbolFlags.Alias) return ctx.checker.getAliasedSymbol(symbol);\n return symbol;\n}\n\nfunction classDeclarationOf(symbol: ts.Symbol | undefined): ts.ClassLikeDeclaration | null {\n for (const decl of symbol?.declarations ?? []) {\n if (ts.isClassDeclaration(decl) || ts.isClassExpression(decl)) return decl;\n }\n return null;\n}\n\nfunction heritageReaches(\n decl: ts.ClassLikeDeclaration,\n target: ts.ClassLikeDeclaration,\n ctx: TSVisitContext,\n depth: number,\n): boolean {\n if (decl === target) return true;\n if (depth > 50) return false;\n const extendsClause = decl.heritageClauses?.find((c) => c.token === ts.SyntaxKind.ExtendsKeyword);\n const base = extendsClause?.types[0];\n if (base === undefined) return false;\n const baseDecl = classDeclarationOf(resolveAlias(ctx.semantics.symbolAtLocation(base.expression), ctx));\n if (baseDecl === null) return false;\n return heritageReaches(baseDecl, target, ctx, depth + 1);\n}\n\n// ---------- (d) type-predicate calls ----------\n\nfunction checkPredicateCall(call: ts.CallExpression, ctx: TSVisitContext): void {\n const signature = ctx.checker.getResolvedSignature(call);\n if (signature === undefined) return;\n const predicate = ctx.checker.getTypePredicateOfSignature(signature);\n if (predicate === undefined) return;\n if (predicate.kind !== ts.TypePredicateKind.Identifier) return;\n if (predicate.type === undefined) return;\n\n // Judge the argument by its DECLARED type, not the flow type: inside an\n // `else if` ladder or `a(x) || b(x)` chain the flow type is narrowed by the\n // preceding tests, which would mark the deliberate exhaustive listing as\n // dead. A predicate is only dead when it can't fail on the declaration.\n const arg = call.arguments[predicate.parameterIndex];\n if (arg === undefined || !ts.isIdentifier(arg)) return;\n if (isAmbientDeclared(arg, ctx)) return;\n const declaredType = declaredTypeOf(arg, ctx);\n if (declaredType === null) return;\n if (analyzableParts(declaredType) === null) return;\n\n if (ctx.semantics.isTypeAssignableTo(declaredType, predicate.type)) {\n ctx.report(\n call,\n `Type predicate is always true: \\`${arg.text}\\` is declared \\`${ctx.checker.typeToString(declaredType)}\\`, already assignable to \\`${ctx.checker.typeToString(predicate.type)}\\``,\n );\n }\n}\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\n\nexport const noDefaultedRequiredPortArg: TSRule = {\n kind: \"ts\",\n id: \"no-defaulted-required-port-arg\",\n severity: \"warning\",\n message:\n \"Default value on a parameter the implemented interface declares required; the implementation widens the contract — drop the default or change the interface\",\n syntaxKinds: [ts.SyntaxKind.MethodDeclaration],\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isMethodDeclaration(node)) return;\n if (!ts.isIdentifier(node.name)) return;\n if (node.parameters.every((p) => p.initializer === undefined)) return;\n\n const ifaceSignatures = resolveImplementedSignatures(node, ctx);\n if (ifaceSignatures.length === 0) return;\n\n for (let i = 0; i < node.parameters.length; i++) {\n const implParam = node.parameters[i];\n if (!implParam || implParam.initializer === undefined) continue;\n if (implParam.dotDotDotToken !== undefined) continue;\n if (ifaceSignatures.some((sig) => isParamRequired(sig, i))) {\n ctx.report(implParam);\n }\n }\n },\n};\n\nfunction isParamRequired(sig: ts.Signature, paramIndex: number): boolean {\n const param = sig.parameters[paramIndex];\n if (!param) return false;\n const decl = param.valueDeclaration;\n if (!decl || !ts.isParameter(decl)) return false;\n if (decl.questionToken !== undefined) return false;\n if (decl.initializer !== undefined) return false;\n return !(decl.dotDotDotToken !== undefined);\n}\n\nfunction resolveImplementedSignatures(\n method: ts.MethodDeclaration,\n ctx: TSVisitContext,\n): ts.Signature[] {\n const signatures: ts.Signature[] = [];\n if (!ts.isIdentifier(method.name)) return signatures;\n const methodName = method.name.text;\n const parent = method.parent;\n\n if (ts.isClassDeclaration(parent) || ts.isClassExpression(parent)) {\n for (const clause of parent.heritageClauses ?? []) {\n if (clause.token !== ts.SyntaxKind.ImplementsKeyword) continue;\n for (const typeNode of clause.types) {\n collectSignatures(typeNode, methodName, ctx, signatures);\n }\n }\n } else if (ts.isObjectLiteralExpression(parent)) {\n const contextualType = ctx.semantics.contextualType(parent);\n if (contextualType) {\n collectSignaturesFromType(contextualType, methodName, parent, ctx, signatures);\n }\n }\n\n return signatures;\n}\n\nfunction collectSignatures(\n typeNode: ts.Node,\n methodName: string,\n ctx: TSVisitContext,\n out: ts.Signature[],\n): void {\n const t = ctx.semantics.typeAtLocation(typeNode);\n collectSignaturesFromType(t, methodName, typeNode, ctx, out);\n}\n\nfunction collectSignaturesFromType(\n type: ts.Type,\n methodName: string,\n location: ts.Node,\n ctx: TSVisitContext,\n out: ts.Signature[],\n): void {\n const prop = type.getProperty(methodName);\n if (!prop) return;\n const propType = ctx.semantics.typeOfSymbolAtLocation(prop, location);\n for (const sig of propType.getCallSignatures()) {\n out.push(sig);\n }\n}\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\nimport { includesBooleanType } from \"../../typecheck/utils.ts\";\n\nexport const noDoubleNegationCoercion: TSRule = {\n kind: \"ts\",\n id: \"no-double-negation-coercion\",\n severity: \"warning\",\n message: \"!! is noise in a boolean-evaluation context (if/while/ternary test); the surrounding construct already coerces — use the value directly\",\n syntaxKinds: [ts.SyntaxKind.PrefixUnaryExpression],\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isPrefixUnaryExpression(node)) return;\n if (node.operator !== ts.SyntaxKind.ExclamationToken) return;\n const inner = node.operand;\n if (!ts.isPrefixUnaryExpression(inner)) return;\n if (inner.operator !== ts.SyntaxKind.ExclamationToken) return;\n\n const operand = inner.operand;\n const fix = {\n start: node.getStart(ctx.sourceFile),\n end: node.getEnd(),\n text: operand.getText(ctx.sourceFile),\n };\n\n // Already boolean -> !! is a no-op everywhere, not just in eval contexts.\n const innerType = ctx.semantics.typeAtLocation(operand);\n if (includesBooleanType(innerType) && !(innerType.flags & ts.TypeFlags.Union)) {\n ctx.report(node, \"!! on an already-boolean type is a no-op; remove the double negation\", fix);\n return;\n }\n\n // Bitwise expression: !!(flags & MASK) is the standard idiom for flag testing\n if (isBitwiseExpression(operand)) return;\n\n // Only fire when the surrounding context will boolean-coerce the result anyway.\n // Outside such contexts (variable initializers, return values, function args\n // with boolean contextual type, object properties), !! is legitimate boolean\n // production — the user is explicitly producing a boolean for a typed slot.\n if (!isInBooleanEvalContext(node)) return;\n\n ctx.report(node, undefined, fix);\n },\n};\n\n/**\n * True when `node`'s value will be boolean-coerced by its surrounding construct.\n * Walks up through parentheses and short-circuit operators (`&&`/`||`) since the\n * result of those flows to the same enclosing position.\n */\nfunction isInBooleanEvalContext(node: ts.Node): boolean {\n let current: ts.Node = node;\n let parent: ts.Node | undefined = current.parent;\n while (parent) {\n if (ts.isParenthesizedExpression(parent)) {\n current = parent;\n parent = current.parent;\n continue;\n }\n if (ts.isIfStatement(parent) && parent.expression === current) return true;\n if (ts.isWhileStatement(parent) && parent.expression === current) return true;\n if (ts.isDoStatement(parent) && parent.expression === current) return true;\n if (ts.isForStatement(parent) && parent.condition === current) return true;\n if (ts.isConditionalExpression(parent) && parent.condition === current) return true;\n if (ts.isPrefixUnaryExpression(parent) && parent.operator === ts.SyntaxKind.ExclamationToken) return true;\n if (\n ts.isBinaryExpression(parent) &&\n (parent.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken ||\n parent.operatorToken.kind === ts.SyntaxKind.BarBarToken)\n ) {\n // Result of `a && b` / `a || b` flows to the binary expression's enclosing context.\n current = parent;\n parent = current.parent;\n continue;\n }\n return false;\n }\n return false;\n}\n\nconst BITWISE_OPS = new Set([\n ts.SyntaxKind.AmpersandToken,\n ts.SyntaxKind.BarToken,\n ts.SyntaxKind.CaretToken,\n ts.SyntaxKind.LessThanLessThanToken,\n ts.SyntaxKind.GreaterThanGreaterThanToken,\n ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken,\n]);\n\nfunction isBitwiseExpression(node: ts.Node): boolean {\n // Direct: !!(a & b)\n if (ts.isBinaryExpression(node) && BITWISE_OPS.has(node.operatorToken.kind)) return true;\n // Parenthesized: !!((a & b) | c)\n if (ts.isParenthesizedExpression(node)) return isBitwiseExpression(node.expression);\n return false;\n}\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\n\n// warning, not error: import() is the only code-splitting mechanism and the\n// standard lazy-load for heavy optional deps — a flat error would just train\n// users to turn the rule off.\nexport const noDynamicImport: TSRule = {\n kind: \"ts\",\n id: \"no-dynamic-import\",\n severity: \"warning\",\n message: \"Dynamic import() breaks static analysis and hides dependencies; use a static import instead\",\n syntaxKinds: [ts.SyntaxKind.CallExpression],\n requiresTypeInfo: false,\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isCallExpression(node)) return;\n if (node.expression.kind !== ts.SyntaxKind.ImportKeyword) return;\n ctx.report(node);\n },\n};\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\n\nexport const noErrorRewrap: TSRule = {\n kind: \"ts\",\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 syntaxKinds: [ts.SyntaxKind.CatchClause],\n requiresTypeInfo: false,\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isCatchClause(node)) return;\n if (!node.variableDeclaration) return;\n const param = node.variableDeclaration.name;\n if (!ts.isIdentifier(param)) return;\n const catchName = param.text;\n findRewraps(node.block, catchName, ctx);\n },\n};\n\nfunction findRewraps(block: ts.Block, catchName: string, ctx: TSVisitContext): void {\n function visit(node: ts.Node): void {\n if (ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) || ts.isArrowFunction(node)) return;\n if (ts.isThrowStatement(node) && node.expression) {\n if (ts.isNewExpression(node.expression)) {\n const args = node.expression.arguments;\n if (args && args.length > 0 && referencesName(args, catchName) && !hasCauseArg(args)) {\n ctx.report(node);\n }\n return;\n }\n // Call form: `throw Error(e.message)`. Only the lossy projection is\n // flagged — passing the error whole (`throw wrap(e)`) hands it off to\n // a callee that may preserve it, the same contract trust\n // no-swallowed-catch extends.\n if (ts.isCallExpression(node.expression)) {\n const args = node.expression.arguments;\n if (\n args.length > 0 &&\n args.some((arg) => referencesPropertyOf(arg, catchName)) &&\n !hasCauseArg(args)\n ) {\n ctx.report(node);\n }\n return;\n }\n }\n ts.forEachChild(node, visit);\n }\n ts.forEachChild(block, visit);\n}\n\n/** Node reads a property of `name` (e.g. `e.message`) somewhere in its tree. */\nfunction referencesPropertyOf(node: ts.Node, name: string): boolean {\n if (ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === name) {\n return true;\n }\n return ts.forEachChild(node, (child) => referencesPropertyOf(child, name) || undefined) ?? false;\n}\n\nfunction referencesName(args: readonly ts.Expression[], name: string): boolean {\n for (const arg of args) {\n if (containsIdentifier(arg, name)) return true;\n }\n return false;\n}\n\nfunction containsIdentifier(node: ts.Node, name: string): boolean {\n if (ts.isIdentifier(node) && node.text === name) return true;\n return ts.forEachChild(node, (child) => containsIdentifier(child, name) || undefined) ?? false;\n}\n\nfunction hasCauseArg(args: readonly ts.Expression[]): boolean {\n for (const arg of args) {\n if (ts.isObjectLiteralExpression(arg)) {\n for (const prop of arg.properties) {\n if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name) && prop.name.text === \"cause\") return true;\n if (ts.isShorthandPropertyAssignment(prop) && prop.name.text === \"cause\") return true;\n }\n }\n }\n return false;\n}\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\n\nexport const noExplicitAnyAnnotation: TSRule = {\n kind: \"ts\",\n id: \"no-explicit-any-annotation\",\n severity: \"error\",\n message: \"Explicit `any` annotation erases type safety; use a specific type, `unknown`, or a generic\",\n syntaxKinds: [ts.SyntaxKind.AnyKeyword],\n requiresTypeInfo: false,\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (node.kind !== ts.SyntaxKind.AnyKeyword) return;\n if (node.parent && ts.isAsExpression(node.parent)) return;\n ctx.report(node);\n },\n};\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\nimport { isInlineParamType } from \"../../typecheck/utils.ts\";\n\nexport const noInlineParamType: TSRule = {\n kind: \"ts\",\n id: \"no-inline-param-type\",\n severity: \"warning\",\n message:\n \"Inline object type on parameter; extract to a named type\",\n syntaxKinds: [ts.SyntaxKind.TypeLiteral],\n requiresTypeInfo: false,\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (isInlineParamType(node)) ctx.report(node);\n },\n};\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\n\nfunction containsTypeLiteral(type: ts.TypeNode): boolean {\n if (ts.isTypeLiteralNode(type)) return true;\n if (ts.isArrayTypeNode(type)) return containsTypeLiteral(type.elementType);\n if (ts.isTypeReferenceNode(type) && type.typeArguments) {\n return type.typeArguments.some(containsTypeLiteral);\n }\n if (ts.isTypeOperatorNode(type)) return containsTypeLiteral(type.type);\n return false;\n}\n\nexport const noInlineTypeAssertion: TSRule = {\n kind: \"ts\",\n id: \"no-inline-type-assertion\",\n severity: \"error\",\n message: \"Type assertion contains inline object type; extract a named type or fix the upstream type\",\n syntaxKinds: [ts.SyntaxKind.AsExpression, ts.SyntaxKind.TypeAssertionExpression],\n requiresTypeInfo: false,\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (ts.isAsExpression(node) && containsTypeLiteral(node.type)) {\n ctx.report(node);\n return;\n }\n\n if (ts.isTypeAssertionExpression(node) && containsTypeLiteral(node.type)) {\n ctx.report(node);\n }\n },\n};\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\n\nexport const noNeverCast: TSRule = {\n kind: \"ts\",\n id: \"no-never-cast\",\n severity: \"warning\",\n message:\n \"Casting to `never` silences the type checker completely; use a specific type or a type guard\",\n syntaxKinds: [ts.SyntaxKind.AsExpression],\n requiresTypeInfo: false,\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isAsExpression(node)) return;\n if (node.type.kind !== ts.SyntaxKind.NeverKeyword) return;\n ctx.report(node);\n },\n};\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\n\nexport const noRedundantCast: TSRule = {\n kind: \"ts\",\n id: \"no-redundant-cast\",\n severity: \"error\",\n message:\n \"Type assertion is redundant; the expression already has this type\",\n syntaxKinds: [ts.SyntaxKind.AsExpression],\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isAsExpression(node)) return;\n\n // skip `as const`\n if (\n ts.isTypeReferenceNode(node.type) &&\n node.type.getText(ctx.sourceFile).trim() === \"const\"\n ) {\n return;\n }\n\n const exprType = ctx.semantics.typeAtLocation(node.expression);\n\n // `any` is bidirectionally assignable to everything — these casts carry intent, not redundancy\n if (exprType.flags & ts.TypeFlags.Any) return;\n\n const targetType = ctx.semantics.typeFromTypeNode(node.type);\n\n // Redundant if both directions are assignable (types are equivalent)\n if (\n ctx.semantics.isTypeAssignableTo(exprType, targetType) &&\n ctx.semantics.isTypeAssignableTo(targetType, exprType)\n ) {\n ctx.report(node, undefined, {\n start: node.getStart(ctx.sourceFile),\n end: node.getEnd(),\n text: node.expression.getText(ctx.sourceFile),\n });\n }\n },\n};\n","import * as ts from \"typescript\";\nimport type { SemanticServices, TSRule, TSVisitContext } from \"../types.ts\";\n\nfunction isUntypedSource(type: ts.Type): boolean {\n if (type.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) return true;\n if (type.isUnion()) return type.types.some(isUntypedSource);\n if (type.isIntersection()) return type.types.some(isUntypedSource);\n return false;\n}\n\nfunction isPrimitiveFamily(type: ts.Type): boolean {\n if (\n type.flags &\n (ts.TypeFlags.String |\n ts.TypeFlags.StringLiteral |\n ts.TypeFlags.Number |\n ts.TypeFlags.NumberLiteral |\n ts.TypeFlags.Boolean |\n ts.TypeFlags.BooleanLiteral |\n ts.TypeFlags.BigInt |\n ts.TypeFlags.BigIntLiteral |\n ts.TypeFlags.ESSymbol |\n ts.TypeFlags.UniqueESSymbol |\n ts.TypeFlags.Void |\n ts.TypeFlags.Undefined |\n ts.TypeFlags.Null |\n ts.TypeFlags.Never)\n ) {\n return true;\n }\n\n // Branded types like `string & { __brand: \"X\" }` — check if any intersection member is primitive\n if (type.isIntersection()) {\n return type.types.some(isPrimitiveFamily);\n }\n\n // Unions: all members must be primitive\n if (type.isUnion()) {\n return type.types.every(isPrimitiveFamily);\n }\n\n return false;\n}\n\nfunction isConcreteTarget(\n type: ts.Type,\n semantics: SemanticServices,\n): boolean {\n if (\n type.flags &\n (ts.TypeFlags.Any |\n ts.TypeFlags.Unknown |\n ts.TypeFlags.Never |\n ts.TypeFlags.Void |\n ts.TypeFlags.Undefined |\n ts.TypeFlags.Null |\n ts.TypeFlags.TypeParameter |\n ts.TypeFlags.NonPrimitive)\n ) {\n return false;\n }\n\n if (isPrimitiveFamily(type)) return false;\n\n if (semantics.isArrayType(type) || semantics.isTupleType(type)) return true;\n\n const apparent = semantics.apparentType(type);\n if (apparent.getProperties().length > 0) return true;\n if (apparent.getStringIndexType() !== undefined) return true;\n if (apparent.getNumberIndexType() !== undefined) return true;\n\n // Unions: concrete if any non-null member is concrete\n if (type.isUnion()) {\n return type.types.some((t) => isConcreteTarget(t, semantics));\n }\n\n return false;\n}\n\nfunction isEmptyArrayLiteral(node: ts.Expression): boolean {\n return (\n ts.isArrayLiteralExpression(node) && node.elements.length === 0\n );\n}\n\nexport const noUnvalidatedCast: TSRule = {\n kind: \"ts\",\n id: \"no-unvalidated-cast\",\n severity: \"error\",\n message:\n \"Casting `any`/`unknown` to a concrete type without runtime validation fabricates structure; validate first or narrow with a type guard\",\n syntaxKinds: [ts.SyntaxKind.AsExpression, ts.SyntaxKind.TypeAssertionExpression],\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isAsExpression(node) && !ts.isTypeAssertionExpression(node))\n return;\n\n // skip `as const`\n if (\n ts.isTypeReferenceNode(node.type) &&\n node.type.getText(ctx.sourceFile).trim() === \"const\"\n ) {\n return;\n }\n\n const expr = ts.isParenthesizedExpression(node.expression)\n ? node.expression.expression\n : node.expression;\n\n if (isEmptyArrayLiteral(expr)) return;\n\n const sourceType = ctx.semantics.typeAtLocation(expr);\n if (!isUntypedSource(sourceType)) return;\n\n const targetType = ctx.semantics.typeFromTypeNode(node.type);\n if (!isConcreteTarget(targetType, ctx.semantics)) return;\n\n ctx.report(node);\n },\n};\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\nimport { isPromiseLike } from \"../../typecheck/utils.ts\";\n\n/**\n * `await` on a value whose type has no `then` method is a dead keyword: it\n * adds a microtask hop and tells the reader work is asynchronous when it\n * isn't. Usually left behind after a refactor made a function synchronous.\n */\nexport const noUselessAwait: TSRule = {\n kind: \"ts\",\n id: \"no-useless-await\",\n severity: \"warning\",\n message: \"await on a non-promise value is a no-op; the operand's type has no then method\",\n syntaxKinds: [ts.SyntaxKind.AwaitExpression],\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isAwaitExpression(node)) return;\n\n const type = ctx.semantics.typeAtLocation(node.expression);\n if (type.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown | ts.TypeFlags.Instantiable)) return;\n if (isPromiseLike(type, ctx.semantics)) return;\n\n ctx.report(node, undefined, {\n start: node.getStart(ctx.sourceFile),\n end: node.getEnd(),\n text: node.expression.getText(ctx.sourceFile),\n });\n },\n};\n","import * as ts from \"typescript\";\nimport type { FixEdit, TSRule, TSVisitContext } from \"../types.ts\";\n\n/**\n * `if (cond) return true; return false;` and `cond ? true : false` restate a\n * condition that is already a boolean. Only fires when the condition's type is\n * boolean — on any other type the branch performs a coercion, which is a\n * legitimate (if inelegant) operation owned by other rules.\n */\nexport const redundantBooleanBranch: TSRule = {\n kind: \"ts\",\n id: \"redundant-boolean-branch\",\n severity: \"warning\",\n message: \"Branch restates an already-boolean condition; return the expression directly\",\n syntaxKinds: [ts.SyntaxKind.ConditionalExpression, ts.SyntaxKind.IfStatement],\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (ts.isConditionalExpression(node)) {\n checkTernary(node, ctx);\n return;\n }\n if (ts.isIfStatement(node)) {\n checkIfReturn(node, ctx);\n }\n },\n};\n\nfunction checkTernary(node: ts.ConditionalExpression, ctx: TSVisitContext): void {\n const whenTrue = booleanLiteralValue(node.whenTrue);\n const whenFalse = booleanLiteralValue(node.whenFalse);\n if (whenTrue === null || whenFalse === null || whenTrue === whenFalse) return;\n if (!isBooleanOnly(ctx.semantics.typeAtLocation(node.condition))) return;\n if (whenTrue === false && !isCleanlyNegatable(node.condition)) return;\n\n ctx.report(node, undefined, {\n start: node.getStart(ctx.sourceFile),\n end: node.getEnd(),\n text: conditionText(node.condition, whenTrue === false, ctx),\n });\n}\n\nfunction checkIfReturn(node: ts.IfStatement, ctx: TSVisitContext): void {\n const thenValue = returnedBooleanLiteral(node.thenStatement);\n if (thenValue === null) return;\n\n let elseValue: boolean | null = null;\n let fixEnd: number | null = null;\n if (node.elseStatement !== undefined) {\n elseValue = returnedBooleanLiteral(node.elseStatement);\n fixEnd = node.getEnd();\n } else {\n const next = nextSiblingStatement(node);\n if (next === undefined) return;\n elseValue = returnedBooleanLiteral(next);\n fixEnd = next.getEnd();\n }\n if (elseValue === null || elseValue === thenValue) return;\n if (!isBooleanOnly(ctx.semantics.typeAtLocation(node.expression))) return;\n if (thenValue === false && !isCleanlyNegatable(node.expression)) return;\n\n const fix: FixEdit = {\n start: node.getStart(ctx.sourceFile),\n end: fixEnd,\n text: `return ${conditionText(node.expression, thenValue === false, ctx)};`,\n };\n ctx.report(node, undefined, fix);\n}\n\nfunction nextSiblingStatement(node: ts.IfStatement): ts.Statement | undefined {\n const parent = node.parent;\n if (!ts.isBlock(parent) && !ts.isSourceFile(parent)) return undefined;\n const statements = parent.statements;\n const index = statements.indexOf(node);\n if (index === -1) return undefined;\n return statements[index + 1];\n}\n\n/** The boolean literal a statement returns: `return true;` or `{ return true; }`. */\nfunction returnedBooleanLiteral(stmt: ts.Statement): boolean | null {\n if (ts.isBlock(stmt)) {\n if (stmt.statements.length !== 1) return null;\n const only = stmt.statements[0];\n if (only === undefined) return null;\n return returnedBooleanLiteral(only);\n }\n if (!ts.isReturnStatement(stmt) || stmt.expression === undefined) return null;\n return booleanLiteralValue(stmt.expression);\n}\n\nfunction booleanLiteralValue(expr: ts.Expression): boolean | null {\n if (expr.kind === ts.SyntaxKind.TrueKeyword) return true;\n if (expr.kind === ts.SyntaxKind.FalseKeyword) return false;\n return null;\n}\n\nfunction isBooleanOnly(type: ts.Type): boolean {\n const parts = type.isUnion() ? type.types : [type];\n return parts.every((part) => (part.flags & ts.TypeFlags.BooleanLike) !== 0);\n}\n\n/**\n * Inverted branches (`if (cond) return false; return true;`) only count as\n * redundant when `!cond` stays readable. Synthesizing `!(a && b)` from a\n * compound condition trades an idiomatic guard clause for a parse puzzle —\n * that direction is left alone.\n */\nfunction isCleanlyNegatable(condition: ts.Expression): boolean {\n return ts.isIdentifier(condition) || ts.isPropertyAccessExpression(condition) || ts.isCallExpression(condition);\n}\n\nfunction conditionText(condition: ts.Expression, negate: boolean, ctx: TSVisitContext): string {\n const text = condition.getText(ctx.sourceFile);\n if (!negate) return text;\n return `!${text}`;\n}\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\n\n/**\n * `const { a = 1 } = obj` where `obj.a` can never be undefined: the default\n * is dead code, same family as `no-nullish-coalescing` but in binding-pattern\n * position. Object patterns only — array destructuring is governed by\n * `noUncheckedIndexedAccess` and tuple arity, handled elsewhere. Only direct\n * destructuring of a typed source (annotated parameter, or variable with an\n * initializer/annotation) is checked.\n */\nexport const redundantDestructureDefault: TSRule = {\n kind: \"ts\",\n id: \"redundant-destructure-default\",\n severity: \"warning\",\n message: \"Destructuring default can never apply: the property's type does not include undefined\",\n syntaxKinds: [ts.SyntaxKind.BindingElement],\n requiresStrictNullChecks: true,\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isBindingElement(node)) return;\n if (node.initializer === undefined) return;\n const pattern = node.parent;\n if (!ts.isObjectBindingPattern(pattern)) return;\n\n const sourceType = destructuredSourceType(pattern, ctx);\n if (sourceType === null) return;\n if (sourceType.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown | ts.TypeFlags.Instantiable)) return;\n\n const propertyName = node.propertyName ?? node.name;\n if (!ts.isIdentifier(propertyName)) return;\n const property = sourceType.getProperty(propertyName.text);\n if (property === undefined) return;\n if (property.flags & ts.SymbolFlags.Optional) return;\n\n const propertyType = ctx.checker.getTypeOfSymbolAtLocation(property, node);\n const parts = propertyType.isUnion() ? propertyType.types : [propertyType];\n const undecidable = ts.TypeFlags.Any | ts.TypeFlags.Unknown | ts.TypeFlags.Instantiable;\n if (parts.some((p) => (p.flags & undecidable) !== 0)) return;\n if (parts.some((p) => (p.flags & (ts.TypeFlags.Undefined | ts.TypeFlags.Void)) !== 0)) return;\n\n ctx.report(node, undefined, {\n start: node.name.getEnd(),\n end: node.initializer.getEnd(),\n text: \"\",\n });\n },\n};\n\n/** The declared type of the value being destructured, when statically known. */\nfunction destructuredSourceType(pattern: ts.ObjectBindingPattern, ctx: TSVisitContext): ts.Type | null {\n const holder = pattern.parent;\n if (ts.isVariableDeclaration(holder)) {\n if (holder.type !== undefined) return ctx.semantics.typeFromTypeNode(holder.type);\n if (holder.initializer !== undefined) return ctx.semantics.typeAtLocation(holder.initializer);\n return null;\n }\n if (ts.isParameter(holder)) {\n if (holder.type !== undefined) return ctx.semantics.typeFromTypeNode(holder.type);\n return null;\n }\n return null;\n}\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\n\n/**\n * Cast inside a narrowed branch whose target is something the narrowing\n * already established. After the narrowing, the type checker already knows\n * the value satisfies the cast's target type — the cast adds nothing.\n *\n * Builds on top of `no-non-null-assertion` and `no-type-assertion`: those\n * eliminate the escape-hatch casts, and what remains is genuine \"I had to\n * cast\" — sometimes legitimate (subclass narrowing inside an instanceof\n * branch), sometimes a missed narrowing.\n */\nexport const redundantNarrowingThenCast: TSRule = {\n kind: \"ts\",\n id: \"redundant-narrowing-then-cast\",\n severity: \"warning\",\n message:\n \"Cast is redundant: the surrounding narrowing already established this type. Drop the cast.\",\n syntaxKinds: [ts.SyntaxKind.AsExpression, ts.SyntaxKind.TypeAssertionExpression],\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isAsExpression(node) && !ts.isTypeAssertionExpression(node)) return;\n\n // skip `as const`\n if (ts.isTypeReferenceNode(node.type) && node.type.getText(ctx.sourceFile).trim() === \"const\") return;\n\n // The cast must apply to an identifier or property-access whose root symbol\n // was the subject of the narrowing.\n const castSubject = node.expression;\n const subjectExpr = leftmostExpression(castSubject);\n if (subjectExpr === null) return;\n\n // The narrowed type at the cast's subject position (TS computed it from the\n // narrowing) must already be assignable to the cast's target type.\n const narrowedType = ctx.semantics.typeAtLocation(castSubject);\n if ((narrowedType.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) !== 0) return;\n const targetType = ctx.semantics.typeFromTypeNode(node.type);\n if (!ctx.semantics.isTypeAssignableTo(narrowedType, targetType)) return;\n\n const fix = {\n start: node.getStart(ctx.sourceFile),\n end: node.getEnd(),\n text: castSubject.getText(ctx.sourceFile),\n };\n\n // Path 1 — flow-proven, any narrowing construct (early return, else\n // branch, switch, assignment): the subject is a bare identifier whose\n // flow type satisfies the target while its declared type does not. The\n // type difference is itself the proof that narrowing already happened.\n if (ts.isIdentifier(castSubject)) {\n const symbol = ctx.semantics.symbolAtLocation(castSubject);\n const declaration = symbol?.valueDeclaration;\n if (symbol !== undefined && declaration !== undefined) {\n const declaredType = ctx.checker.getTypeOfSymbolAtLocation(symbol, declaration);\n if (!ctx.semantics.isTypeAssignableTo(declaredType, targetType)) {\n ctx.report(node, undefined, fix);\n return;\n }\n }\n }\n\n // Path 2 — property chains: confirm an enclosing if-test narrowed the\n // chain's root symbol. Without this, casts on unrelated identifiers\n // inside a branch could spuriously match.\n const enclosingIf = findEnclosingIfWithThen(node);\n if (enclosingIf === null) return;\n const subjectSymbol = ctx.semantics.symbolAtLocation(subjectExpr);\n if (subjectSymbol === undefined) return;\n if (!testNarrowsSymbol(enclosingIf.expression, subjectSymbol, ctx)) return;\n\n ctx.report(node, undefined, fix);\n },\n};\n\n/** Walk ancestors. Returns the enclosing IfStatement iff the node is inside its then-branch. */\nfunction findEnclosingIfWithThen(node: ts.Node): ts.IfStatement | null {\n let current: ts.Node = node;\n while (current.parent) {\n const parent: ts.Node = current.parent;\n if (ts.isIfStatement(parent)) {\n if (parent.thenStatement === current) return parent;\n // Inside the else-branch: the narrowing doesn't apply.\n return null;\n }\n current = parent;\n }\n return null;\n}\n\n/** Get the leftmost identifier-or-`this`-rooted expression of a property chain. */\nfunction leftmostExpression(expr: ts.Expression): ts.Expression | null {\n let current: ts.Expression = expr;\n while (ts.isPropertyAccessExpression(current)) {\n current = current.expression;\n }\n if (ts.isIdentifier(current)) return current;\n if (current.kind === ts.SyntaxKind.ThisKeyword) return current;\n return null;\n}\n\n/**\n * True when the if-test narrows `symbol`. Structural patterns recognized:\n * - `typeof X === ...` / `typeof X !== ...`\n * - `X instanceof Y`\n * - `X === null/undefined`, `X !== null/undefined`, `X == null`, `X != null`\n * - bare `X` (truthy)\n * - bare `!X` (falsy — but we're in the then-branch of a positive guard; falsy\n * check's then-branch goes to the else side, so we don't accept this)\n * - `&&`/`||` chains containing any of the above on `symbol`\n */\nfunction testNarrowsSymbol(test: ts.Expression, symbol: ts.Symbol, ctx: TSVisitContext): boolean {\n if (matchesSymbol(test, symbol, ctx)) return true;\n if (ts.isParenthesizedExpression(test)) return testNarrowsSymbol(test.expression, symbol, ctx);\n if (ts.isBinaryExpression(test)) {\n const op = test.operatorToken.kind;\n if (op === ts.SyntaxKind.AmpersandAmpersandToken || op === ts.SyntaxKind.BarBarToken) {\n return testNarrowsSymbol(test.left, symbol, ctx) || testNarrowsSymbol(test.right, symbol, ctx);\n }\n if (isEqualityOp(op)) {\n return matchesSymbol(test.left, symbol, ctx) || matchesSymbol(test.right, symbol, ctx);\n }\n if (op === ts.SyntaxKind.InstanceOfKeyword) {\n return matchesSymbol(test.left, symbol, ctx);\n }\n }\n if (ts.isTypeOfExpression(test)) {\n return matchesSymbol(test.expression, symbol, ctx);\n }\n return false;\n}\n\nfunction matchesSymbol(expr: ts.Expression, symbol: ts.Symbol, ctx: TSVisitContext): boolean {\n if (ts.isTypeOfExpression(expr)) {\n return matchesSymbol(expr.expression, symbol, ctx);\n }\n if (ts.isParenthesizedExpression(expr)) {\n return matchesSymbol(expr.expression, symbol, ctx);\n }\n const root = leftmostExpression(expr);\n if (root === null) return false;\n const rootSymbol = ctx.semantics.symbolAtLocation(root);\n return rootSymbol === symbol;\n}\n\nfunction isEqualityOp(op: ts.SyntaxKind): boolean {\n return (\n op === ts.SyntaxKind.EqualsEqualsEqualsToken ||\n op === ts.SyntaxKind.ExclamationEqualsEqualsToken ||\n op === ts.SyntaxKind.EqualsEqualsToken ||\n op === ts.SyntaxKind.ExclamationEqualsToken\n );\n}\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\n\n/**\n * `type Foo = Bar` — a non-generic alias to another named type with no type\n * arguments is pure indirection: two names for one type, and every reader has\n * to chase the alias to learn nothing. Aliases that *do* carry information\n * are exempt by construction: primitives (`type ID = string` — keyword, not a\n * type reference), instantiations (`type Rows = Result<Row>`), and shapes\n * (unions, literals, mapped types).\n *\n * No autofix — removing the alias is a project-wide rename.\n *\n * Info, not warning: in real codebases roughly half of these aliases are\n * deliberate — parallel naming across a family (`AdminDeps = UserDeps` next\n * to branded siblings) or a domain boundary giving its own name to an\n * imported type. The other half are refactor leftovers. The rule can't tell\n * intent from structure, so it prompts review instead of demanding a fix.\n */\nexport const trivialTypeAlias: TSRule = {\n kind: \"ts\",\n id: \"trivial-type-alias\",\n severity: \"info\",\n message: \"Type alias adds a second name for an existing type without changing it; use the original type\",\n syntaxKinds: [ts.SyntaxKind.TypeAliasDeclaration],\n requiresTypeInfo: false,\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isTypeAliasDeclaration(node)) return;\n if (node.typeParameters !== undefined && node.typeParameters.length > 0) return;\n if (!ts.isTypeReferenceNode(node.type)) return;\n if (node.type.typeArguments !== undefined && node.type.typeArguments.length > 0) return;\n ctx.report(node);\n },\n};\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\nimport { isNullishLiteral, splitEqualityOperands } from \"../../typecheck/utils.ts\";\n\n/**\n * Fires when a function returns a variable that was bound via array destructure\n * from an array-typed source, AND the declared return type doesn't admit\n * `undefined`. The destructured element is `T | undefined` at runtime\n * (without `noUncheckedIndexedAccess`), so the declared return type is a lie.\n *\n * Skipped when:\n * - the source is a tuple type (element presence is guaranteed)\n * - the declared return type already includes undefined (honest)\n * - a terminating nullish guard or reassignment intervenes before the return\n */\nexport const returnTypeWidensViaDestructure: TSRule = {\n kind: \"ts\",\n id: \"return-type-widens-via-destructure\",\n severity: \"warning\",\n message:\n \"Return value comes from an array destructure, but the declared return type doesn't include undefined. The destructured element is T | undefined; widen the return type or guard before returning.\",\n syntaxKinds: [ts.SyntaxKind.ReturnStatement],\n requiresStrictNullChecks: true,\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isReturnStatement(node)) return;\n if (node.expression === undefined) return;\n if (!ts.isIdentifier(node.expression)) return;\n\n const enclosingFn = findEnclosingFunction(node);\n if (enclosingFn === null) return;\n if (enclosingFn.type === undefined) return; // no explicit return annotation; nothing to lie about\n\n const declaredReturn = unwrapPromise(\n ctx.semantics.typeFromTypeNode(enclosingFn.type),\n ctx,\n );\n if (typeIncludesUndefined(declaredReturn)) return;\n\n const symbol = ctx.semantics.symbolAtLocation(node.expression);\n if (symbol === undefined) return;\n const declaration = symbol.valueDeclaration;\n if (declaration === undefined) return;\n if (!ts.isBindingElement(declaration)) return;\n\n const parentBindingPattern = declaration.parent;\n if (!ts.isArrayBindingPattern(parentBindingPattern)) return;\n\n const variableDecl = parentBindingPattern.parent;\n if (!ts.isVariableDeclaration(variableDecl)) return;\n if (variableDecl.initializer === undefined) return;\n\n // Source must be array-typed (not tuple, not iterable-with-known-length).\n const sourceType = ctx.semantics.typeAtLocation(variableDecl.initializer);\n if (!ctx.semantics.isArrayType(sourceType)) return;\n if (ctx.semantics.isTupleType(sourceType)) return;\n\n // Only runtime proof that executes before the return defuses the widening.\n if (hasInterveningGuardOrReassign(declaration, node, symbol, ctx)) return;\n\n ctx.report(node);\n },\n};\n\nfunction findEnclosingFunction(node: ts.Node): ts.SignatureDeclaration | null {\n let current: ts.Node | undefined = node.parent;\n while (current) {\n if (\n ts.isFunctionDeclaration(current) ||\n ts.isFunctionExpression(current) ||\n ts.isArrowFunction(current) ||\n ts.isMethodDeclaration(current)\n ) {\n return current;\n }\n current = current.parent;\n }\n return null;\n}\n\nfunction unwrapPromise(type: ts.Type, ctx: TSVisitContext): ts.Type {\n const awaited = ctx.semantics.awaitedType(type);\n return awaited ?? type;\n}\n\nfunction typeIncludesUndefined(type: ts.Type): boolean {\n if ((type.flags & ts.TypeFlags.Undefined) !== 0) return true;\n if (type.isUnion()) {\n return type.types.some((t) => (t.flags & ts.TypeFlags.Undefined) !== 0);\n }\n return false;\n}\n\n/**\n * Walks statements from the array destructure up to the return and looks for\n * proof that the destructured value can no longer be undefined at the return:\n * a reassignment, or a nullish guard whose nullish branch terminates.\n */\nfunction hasInterveningGuardOrReassign(\n bindingDecl: ts.BindingElement,\n returnStmt: ts.ReturnStatement,\n symbol: ts.Symbol,\n ctx: TSVisitContext,\n): boolean {\n const variableStatement = findEnclosingVariableStatement(bindingDecl);\n if (variableStatement === null) return false;\n\n const containingBlock = variableStatement.parent;\n if (!ts.isBlock(containingBlock) && !ts.isSourceFile(containingBlock)) return false;\n\n const returnOwner = directChildStatementContaining(returnStmt, containingBlock);\n if (returnOwner === null) return false;\n\n const statements = containingBlock.statements;\n const start = statements.indexOf(variableStatement);\n const end = statements.indexOf(returnOwner);\n if (start < 0 || end < 0 || end <= start) return false;\n\n for (let i = start + 1; i < end; i++) {\n const stmt = statements[i];\n if (stmt !== undefined && containsDefusingProof(stmt, symbol, ctx)) return true;\n }\n return false;\n}\n\nfunction findEnclosingVariableStatement(node: ts.Node): ts.VariableStatement | null {\n let current: ts.Node | undefined = node;\n while (current) {\n if (ts.isVariableStatement(current)) return current;\n current = current.parent;\n }\n return null;\n}\n\nfunction directChildStatementContaining(\n node: ts.Node,\n block: ts.Block | ts.SourceFile,\n): ts.Statement | null {\n let current: ts.Node = node;\n while (current.parent !== undefined && current.parent !== block) {\n current = current.parent;\n }\n return ts.isStatement(current) ? current : null;\n}\n\nfunction containsDefusingProof(node: ts.Node, symbol: ts.Symbol, ctx: TSVisitContext): boolean {\n let found = false;\n function walk(n: ts.Node): void {\n if (found) return;\n if (\n ts.isFunctionDeclaration(n) ||\n ts.isFunctionExpression(n) ||\n ts.isArrowFunction(n) ||\n ts.isMethodDeclaration(n)\n ) {\n return;\n }\n if (isReassignOf(n, symbol, ctx)) {\n found = true;\n return;\n }\n if (ts.isIfStatement(n) && nullishBranchTerminates(n, symbol, ctx)) {\n found = true;\n return;\n }\n ts.forEachChild(n, walk);\n }\n walk(node);\n return found;\n}\n\nfunction isReassignOf(node: ts.Node, symbol: ts.Symbol, ctx: TSVisitContext): boolean {\n if (!ts.isBinaryExpression(node)) return false;\n const op = node.operatorToken.kind;\n if (\n op !== ts.SyntaxKind.EqualsToken &&\n op !== ts.SyntaxKind.QuestionQuestionEqualsToken &&\n op !== ts.SyntaxKind.BarBarEqualsToken &&\n op !== ts.SyntaxKind.AmpersandAmpersandEqualsToken\n ) {\n return false;\n }\n if (!ts.isIdentifier(node.left)) return false;\n return ctx.semantics.symbolAtLocation(node.left) === symbol;\n}\n\nfunction nullishBranchTerminates(stmt: ts.IfStatement, symbol: ts.Symbol, ctx: TSVisitContext): boolean {\n const branch = nullishBranch(stmt.expression, symbol, ctx);\n if (branch === null) return false;\n if (branch === \"then\") return statementTerminates(stmt.thenStatement);\n return stmt.elseStatement !== undefined && statementTerminates(stmt.elseStatement);\n}\n\nfunction nullishBranch(\n test: ts.Expression,\n symbol: ts.Symbol,\n ctx: TSVisitContext,\n): \"then\" | \"else\" | null {\n if (ts.isParenthesizedExpression(test)) return nullishBranch(test.expression, symbol, ctx);\n if (ts.isPrefixUnaryExpression(test) && test.operator === ts.SyntaxKind.ExclamationToken) {\n if (ts.isIdentifier(test.operand) && ctx.semantics.symbolAtLocation(test.operand) === symbol) {\n return \"then\";\n }\n return null;\n }\n if (ts.isIdentifier(test)) {\n return ctx.semantics.symbolAtLocation(test) === symbol ? \"else\" : null;\n }\n if (ts.isBinaryExpression(test)) {\n const op = test.operatorToken.kind;\n if (\n op === ts.SyntaxKind.EqualsEqualsEqualsToken ||\n op === ts.SyntaxKind.ExclamationEqualsEqualsToken ||\n op === ts.SyntaxKind.EqualsEqualsToken ||\n op === ts.SyntaxKind.ExclamationEqualsToken\n ) {\n const operands = splitEqualityOperands(test);\n if (operands === null) return null;\n if (ctx.semantics.symbolAtLocation(operands.id) !== symbol) return null;\n if (!isNullishLiteral(operands.lit)) return null;\n if (\n op === ts.SyntaxKind.EqualsEqualsEqualsToken ||\n op === ts.SyntaxKind.EqualsEqualsToken\n ) {\n return \"then\";\n }\n return \"else\";\n }\n }\n return null;\n}\n\nfunction statementTerminates(stmt: ts.Statement): boolean {\n if (ts.isReturnStatement(stmt) || ts.isThrowStatement(stmt)) return true;\n if (ts.isBlock(stmt)) {\n const last = stmt.statements.at(-1);\n return last !== undefined && statementTerminates(last);\n }\n if (ts.isIfStatement(stmt)) {\n return stmt.elseStatement !== undefined &&\n statementTerminates(stmt.thenStatement) &&\n statementTerminates(stmt.elseStatement);\n }\n return false;\n}\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\nimport { asSignatureLike, isNullishLiteral } from \"../../typecheck/utils.ts\";\n\n/**\n * Single-param function with a wide param type and a `boolean` return whose\n * body performs structural narrowing on the parameter. Such a function would\n * be strictly more useful as a type predicate (`param is T`) — every caller\n * gains narrowing in the success branch.\n *\n * Fires only when ALL of:\n * - Function has exactly 1 parameter (excluding rest)\n * - Parameter has an explicit type annotation\n * - Parameter type is wide: `unknown`, `any`, or a top-level union with\n * >= 2 non-nullish constituents\n * - Return type annotation exists and is exactly `boolean` (NOT a TypePredicate)\n * - Body's return expression(s) consist of narrowing checks on the parameter\n * combined via `&&`/`||`: typeof X, X instanceof Y, X === literal, X != null,\n * \"prop\" in X, or nested type-predicate calls on X\n */\nexport const preferTypePredicate: TSRule = {\n kind: \"ts\",\n id: \"prefer-type-predicate\",\n severity: \"warning\",\n message:\n \"Function performs structural narrowing on its parameter and returns plain `boolean`. Make it a type predicate (`param is T`) so callers benefit from the narrowing.\",\n syntaxKinds: [\n ts.SyntaxKind.FunctionDeclaration,\n ts.SyntaxKind.ArrowFunction,\n ts.SyntaxKind.FunctionExpression,\n ts.SyntaxKind.MethodDeclaration,\n ],\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n const fn = asSignatureLike(node);\n if (fn === null) return;\n // Exactly one parameter, with an explicit type annotation\n if (fn.parameters.length !== 1) return;\n const param = fn.parameters[0];\n if (param === undefined) return;\n if (param.dotDotDotToken !== undefined) return;\n if (param.type === undefined) return;\n if (!ts.isIdentifier(param.name)) return;\n const paramName = param.name.text;\n\n // Return type must be explicit and exactly `boolean` (not a predicate already).\n if (fn.type === undefined) return;\n if (ts.isTypePredicateNode(fn.type)) return;\n if (fn.type.kind !== ts.SyntaxKind.BooleanKeyword) return;\n\n // Param type must be \"wide\" — unknown/any, or a union of >=2 non-nullish.\n const paramType = ctx.semantics.typeFromTypeNode(param.type);\n if (!isWideParamType(paramType)) return;\n\n // Every return path must be a structural narrowing on the param.\n if (fn.body === undefined) return;\n if (!everyReturnIsNarrowing(fn.body, paramName, ctx)) return;\n\n ctx.report(fn);\n },\n};\n\nfunction isWideParamType(type: ts.Type): boolean {\n if ((type.flags & ts.TypeFlags.Unknown) !== 0) return true;\n if ((type.flags & ts.TypeFlags.Any) !== 0) return true;\n if (type.isUnion()) {\n const nonNullish = type.types.filter(\n (t) => (t.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined | ts.TypeFlags.Void)) === 0,\n );\n if (nonNullish.length < 2) return false;\n // Skip unions whose members are ALL literal types (string-/number-/enum-literal).\n // Such a function is an enum-membership test; the predicate refactor would\n // produce an anonymous subset type that's more verbose than the original.\n const LITERAL_FLAGS =\n ts.TypeFlags.StringLiteral |\n ts.TypeFlags.NumberLiteral |\n ts.TypeFlags.BooleanLiteral |\n ts.TypeFlags.EnumLiteral |\n ts.TypeFlags.BigIntLiteral |\n ts.TypeFlags.UniqueESSymbol;\n const allLiteral = nonNullish.every((t) => (t.flags & LITERAL_FLAGS) !== 0);\n return !allLiteral;\n }\n return false;\n}\n\n/** All return paths must be narrowing predicates on `paramName`. */\nfunction everyReturnIsNarrowing(\n body: ts.Block | ts.Expression,\n paramName: string,\n ctx: TSVisitContext,\n): boolean {\n const returnExprs = collectReturnExpressions(body);\n if (returnExprs.length === 0) return false;\n return returnExprs.every((e) => isNarrowingExpression(e, paramName, ctx));\n}\n\n/**\n * For a block body, collect the expressions returned by every reachable\n * `return` statement. For an expression body (arrow), return that expression.\n * Skip nested function bodies (their returns belong to a different scope).\n */\nfunction collectReturnExpressions(body: ts.Block | ts.Expression): ts.Expression[] {\n if (!ts.isBlock(body)) return [body];\n const out: ts.Expression[] = [];\n function walk(node: ts.Node): void {\n if (\n ts.isFunctionDeclaration(node) ||\n ts.isFunctionExpression(node) ||\n ts.isArrowFunction(node) ||\n ts.isMethodDeclaration(node)\n ) {\n return;\n }\n if (ts.isReturnStatement(node)) {\n if (node.expression !== undefined) out.push(node.expression);\n return;\n }\n ts.forEachChild(node, walk);\n }\n ts.forEachChild(body, walk);\n return out;\n}\n\n/**\n * True if `expr` is a structural narrowing on `paramName`. Recognized patterns:\n * - typeof X === literal / typeof X !== literal\n * - X instanceof Y\n * - X === literal / X !== literal / X == null / X != null\n * - \"prop\" in X\n * - bare X (truthy)\n * - type-predicate calls whose predicate argument references X\n * - (a && b), (a || b) where both operands are narrowing expressions\n * - parenthesized variants\n */\nfunction isNarrowingExpression(expr: ts.Expression, paramName: string, ctx: TSVisitContext): boolean {\n if (ts.isParenthesizedExpression(expr)) return isNarrowingExpression(expr.expression, paramName, ctx);\n if (ts.isBinaryExpression(expr)) {\n const op = expr.operatorToken.kind;\n if (op === ts.SyntaxKind.AmpersandAmpersandToken || op === ts.SyntaxKind.BarBarToken) {\n return isNarrowingExpression(expr.left, paramName, ctx) && isNarrowingExpression(expr.right, paramName, ctx);\n }\n if (\n op === ts.SyntaxKind.EqualsEqualsEqualsToken ||\n op === ts.SyntaxKind.ExclamationEqualsEqualsToken ||\n op === ts.SyntaxKind.EqualsEqualsToken ||\n op === ts.SyntaxKind.ExclamationEqualsToken\n ) {\n return isNarrowingEquality(expr, paramName);\n }\n if (op === ts.SyntaxKind.InstanceOfKeyword) {\n return mentionsParam(expr.left, paramName);\n }\n if (op === ts.SyntaxKind.InKeyword) {\n // `\"prop\" in X` — narrowing on the right operand\n return mentionsParam(expr.right, paramName);\n }\n return false;\n }\n if (ts.isPrefixUnaryExpression(expr) && expr.operator === ts.SyntaxKind.ExclamationToken) {\n return isNarrowingExpression(expr.operand, paramName, ctx);\n }\n if (ts.isCallExpression(expr)) return isPredicateCallOnParam(expr, paramName, ctx);\n if (ts.isIdentifier(expr) && expr.text === paramName) return true;\n if (ts.isPropertyAccessExpression(expr)) {\n // `expr.length > 0` style — accept truthy probe on the param's property chain\n return mentionsParam(expr, paramName);\n }\n return false;\n}\n\nfunction isPredicateCallOnParam(\n expr: ts.CallExpression,\n paramName: string,\n ctx: TSVisitContext,\n): boolean {\n const signature = ctx.semantics.resolvedSignature(expr);\n if (signature === undefined) return false;\n const predicate = ctx.checker.getTypePredicateOfSignature(signature);\n if (predicate === undefined) return false;\n if (predicate.kind !== ts.TypePredicateKind.Identifier) return false;\n const arg = expr.arguments[predicate.parameterIndex];\n if (arg === undefined) return false;\n return mentionsParam(arg, paramName);\n}\n\nfunction isNarrowingEquality(expr: ts.BinaryExpression, paramName: string): boolean {\n const leftMentions = mentionsParam(expr.left, paramName);\n const rightMentions = mentionsParam(expr.right, paramName);\n if (leftMentions === rightMentions) return false;\n const other = leftMentions ? expr.right : expr.left;\n return isNarrowingLiteral(other);\n}\n\nfunction isNarrowingLiteral(expr: ts.Expression): boolean {\n if (ts.isParenthesizedExpression(expr)) return isNarrowingLiteral(expr.expression);\n if (isNullishLiteral(expr)) return true;\n if (ts.isStringLiteral(expr) || ts.isNumericLiteral(expr) || ts.isBigIntLiteral(expr)) return true;\n return expr.kind === ts.SyntaxKind.TrueKeyword || expr.kind === ts.SyntaxKind.FalseKeyword;\n}\n\nfunction mentionsParam(expr: ts.Node, paramName: string): boolean {\n if (ts.isTypeOfExpression(expr)) return mentionsParam(expr.expression, paramName);\n if (ts.isParenthesizedExpression(expr)) return mentionsParam(expr.expression, paramName);\n if (ts.isPropertyAccessExpression(expr)) return mentionsParam(expr.expression, paramName);\n if (ts.isElementAccessExpression(expr)) return mentionsParam(expr.expression, paramName);\n if (ts.isIdentifier(expr)) return expr.text === paramName;\n return false;\n}\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\nimport { includesNumberType, isNullableType, isUncheckedIndexRead, libDeclaredSignature } from \"../../typecheck/utils.ts\";\n\nexport const noLogicalOrFallback: TSRule = {\n kind: \"ts\",\n id: \"no-logical-or-fallback\",\n severity: \"warning\",\n message:\n '|| fallback on a nullable value swallows valid falsy values (0, \"\"); use ?? to only catch null/undefined',\n syntaxKinds: [ts.SyntaxKind.BinaryExpression],\n requiresStrictNullChecks: true,\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isBinaryExpression(node)) return;\n if (node.operatorToken.kind !== ts.SyntaxKind.BarBarToken) return;\n\n const right = node.right;\n if (!isLiteral(right)) return;\n\n const left = node.left;\n const lhsType = ctx.semantics.typeAtLocation(left);\n\n // Lib-declared free function returning number (Number, parseInt, ...):\n // || catches NaN/0 intentionally, ?? would not help.\n if (isLibNumericCoercionCall(left, ctx)) return;\n\n // String type without undefined: || catches \"\" intentionally — suppress\n // String | undefined: || swallows \"\" AND catches undefined — should use ??\n if (isStringNotNullable(lhsType, ctx.semantics.checker)) return;\n\n // LHS includes number and RHS is not 0 -> catches bugs like `seed || undefined`\n if (includesNumberType(lhsType) && !isZeroLiteral(right)) {\n ctx.report(node, \"|| on a numeric type swallows 0; use ?? to only catch null/undefined\");\n return;\n }\n\n // Lookup-shaped reads, detected structurally: the absence encoded in the\n // type (or hidden by noUncheckedIndexedAccess) is what the fallback is\n // for, and || conflates absence with falsiness. Plain property reads of\n // `string | undefined` (e.g. env vars, where \"\" conventionally means\n // \"unset\") are deliberately not flagged.\n if (isDataStructureLookup(left, lhsType, ctx)) {\n ctx.report(node);\n }\n },\n};\n\nfunction isDataStructureLookup(left: ts.Expression, lhsType: ts.Type, ctx: TSVisitContext): boolean {\n // x[key] / arr[0] — nullable element, or unchecked when noUncheckedIndexedAccess is off\n if (ts.isElementAccessExpression(left)) {\n if (isNullableType(ctx.semantics.checker, lhsType)) return true;\n return isUncheckedIndexRead(left, ctx.semantics, ctx.compilerOptions);\n }\n\n // a?.b chains contribute undefined structurally\n if (hasOptionalChaining(left)) return true;\n\n // A call whose declared return type models absence (Map.get, Array.find,\n // any user lookup returning T | undefined or T | null)\n if (ts.isCallExpression(left)) {\n const signature = ctx.semantics.resolvedSignature(left);\n if (signature === undefined) return false;\n return isNullableType(ctx.semantics.checker, signature.getReturnType());\n }\n\n return false;\n}\n\nfunction hasOptionalChaining(node: ts.Node): boolean {\n if (ts.isPropertyAccessExpression(node) || ts.isElementAccessExpression(node) || ts.isCallExpression(node)) {\n if (node.questionDotToken) return true;\n return hasOptionalChaining(node.expression);\n }\n return false;\n}\n\n/** LHS is string (or string-like) without null/undefined in the union. */\nfunction isStringNotNullable(type: ts.Type, checker: ts.TypeChecker): boolean {\n if (isNullableType(checker, type)) return false;\n if (type.isUnion()) {\n return type.types.every((t) => (t.flags & ts.TypeFlags.StringLike) !== 0);\n }\n return (type.flags & ts.TypeFlags.StringLike) !== 0;\n}\n\nfunction isLiteral(node: ts.Node): boolean {\n if (ts.isStringLiteral(node) || ts.isNumericLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)) return true;\n if (ts.isTemplateExpression(node)) return true;\n if (ts.isArrayLiteralExpression(node) || ts.isObjectLiteralExpression(node)) return true;\n if (ts.isIdentifier(node) && node.text === \"undefined\") return true;\n if (node.kind === ts.SyntaxKind.NullKeyword) return true;\n return node.kind === ts.SyntaxKind.TrueKeyword || node.kind === ts.SyntaxKind.FalseKeyword;\n}\n\n/**\n * Free function declared in a lib .d.ts returning number — the standard\n * numeric coercions (Number, parseInt, parseFloat). || after these catches\n * NaN and 0 deliberately; ?? wouldn't. Matched by declaration origin and\n * return type, not by callee name.\n */\nfunction isLibNumericCoercionCall(node: ts.Node, ctx: TSVisitContext): boolean {\n if (!ts.isCallExpression(node)) return false;\n if (!ts.isIdentifier(node.expression)) return false;\n const signature = libDeclaredSignature(node, ctx.semantics);\n if (signature === null) return false;\n const returnType = signature.getReturnType();\n return (returnType.flags & ts.TypeFlags.NumberLike) !== 0;\n}\n\nfunction isZeroLiteral(node: ts.Node): boolean {\n return ts.isNumericLiteral(node) && node.text === \"0\";\n}\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\nimport { libDeclaredSignature } from \"../../typecheck/utils.ts\";\n\nexport const noNonNullAssertion: TSRule = {\n kind: \"ts\",\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 syntaxKinds: [ts.SyntaxKind.NonNullExpression],\n requiresStrictNullChecks: true,\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isNonNullExpression(node)) return;\n\n const inner = node.expression;\n\n // Type already non-nullable -> ! is redundant noise, not worth flagging\n if (!ctx.isNullable(inner)) return;\n\n // External library type gap -> suppress\n if (ctx.isExternal(inner)) return;\n\n // First element of a string split — the one index a split guarantees\n if (isGuaranteedFirstSplitElement(inner, ctx)) return;\n\n // arr[n]! after a length guard — provably safe\n if (isLengthGuardedAccess(inner)) return;\n\n ctx.report(node);\n },\n};\n\n/**\n * `str.split(sep)[0]!` — String.prototype.split always yields at least one\n * element, so index 0 is present. Matched structurally, not by method name:\n * a lib-declared method on a string receiver returning string[], indexed\n * with the literal 0. Indexes past 0 carry no such guarantee and are flagged.\n */\nfunction isGuaranteedFirstSplitElement(node: ts.Node, ctx: TSVisitContext): boolean {\n if (!ts.isElementAccessExpression(node)) return false;\n const indexArg = node.argumentExpression;\n if (!ts.isNumericLiteral(indexArg) || indexArg.text !== \"0\") return false;\n\n const call = node.expression;\n if (!ts.isCallExpression(call)) return false;\n if (!ts.isPropertyAccessExpression(call.expression)) return false;\n\n const signature = libDeclaredSignature(call, ctx.semantics);\n if (signature === null) return false;\n\n const receiverType = ctx.semantics.typeAtLocation(call.expression.expression);\n if (!isStringLike(receiverType)) return false;\n\n const returnType = signature.getReturnType();\n if (!ctx.semantics.isArrayType(returnType)) return false;\n const elementType = ctx.checker.getTypeArguments(returnType as ts.TypeReference)[0];\n return elementType !== undefined && isStringLike(elementType);\n}\n\nfunction isStringLike(type: ts.Type): boolean {\n if (type.isUnion()) return type.types.every(isStringLike);\n return (type.flags & ts.TypeFlags.StringLike) !== 0;\n}\n\n/** Detect arr[n]! where arr.length is checked in a preceding guard or enclosing for-loop. */\nfunction isLengthGuardedAccess(node: ts.Node): boolean {\n if (!ts.isElementAccessExpression(node)) return false;\n const arr = node.expression;\n\n const arrName = getIdentifierName(arr);\n if (!arrName) return false;\n\n // Check for enclosing for-loop: for (let i = 0; i < arr.length; i++)\n if (isInsideForLoopBoundedBy(node, arrName)) return true;\n\n // Check for preceding length guard in same block\n return hasPrecedingLengthGuard(node, arrName);\n}\n\n/** Walk ancestors to find a for-loop whose condition bounds against arrName.length. */\nfunction isInsideForLoopBoundedBy(node: ts.Node, arrName: string): boolean {\n let current: ts.Node = node;\n while (current.parent) {\n current = current.parent;\n if (ts.isForStatement(current) && current.condition) {\n if (isLengthBoundCondition(current.condition, arrName)) return true;\n }\n }\n return false;\n}\n\n/** Check if a condition is `i < arr.length` or similar. */\nfunction isLengthBoundCondition(cond: ts.Expression, arrName: string): boolean {\n if (!ts.isBinaryExpression(cond)) return false;\n const op = cond.operatorToken.kind;\n // i < arr.length or i <= arr.length - 1\n if (op === ts.SyntaxKind.LessThanToken || op === ts.SyntaxKind.LessThanEqualsToken) {\n return isLengthAccess(cond.right, arrName);\n }\n // arr.length > i\n if (op === ts.SyntaxKind.GreaterThanToken || op === ts.SyntaxKind.GreaterThanEqualsToken) {\n return isLengthAccess(cond.left, arrName);\n }\n return false;\n}\n\n/** Check if node is `arrName.length`. */\nfunction isLengthAccess(node: ts.Node, arrName: string): boolean {\n if (!ts.isPropertyAccessExpression(node)) return false;\n if (node.name.text !== \"length\") return false;\n return getIdentifierName(node.expression) === arrName;\n}\n\n/**\n * Check if there's a preceding statement in the same block (or a parent block)\n * that guards on arrName.length, implying the array is non-empty.\n *\n * Patterns:\n * - if (arr.length === 0) return;\n * - if (arr.length < N) return; (where N >= 1)\n * - if (arr.length > 0) { ... arr[0]! ... }\n * - if (arr.length !== 0) { ... arr[0]! ... }\n * - if (arr.length >= 1) { ... arr[0]! ... }\n * - if (arr.length !== N) return; (where N >= 1)\n */\nfunction hasPrecedingLengthGuard(node: ts.Node, arrName: string): boolean {\n // Walk up to find the containing block/if-statement\n let current: ts.Node = node;\n while (current.parent) {\n const parent = current.parent;\n\n // Case 1: we're in a block and a preceding if-statement guards length with early return\n if (ts.isBlock(parent)) {\n for (const stmt of parent.statements) {\n if (stmt === current || stmt.pos >= current.pos) break;\n if (ts.isIfStatement(stmt) && isLengthGuardWithEarlyExit(stmt, arrName)) return true;\n }\n }\n\n // Case 2: we're inside the then-branch of an if that checks length > 0\n if (ts.isIfStatement(parent) && parent.thenStatement === current) {\n if (isPositiveLengthCheck(parent.expression, arrName)) return true;\n }\n // Also handle: if (...) { <block containing current> }\n if (ts.isBlock(current) && ts.isIfStatement(parent) && parent.thenStatement === current) {\n if (isPositiveLengthCheck(parent.expression, arrName)) return true;\n }\n\n current = parent;\n }\n return false;\n}\n\n/** if (arr.length === 0) return/throw; or if (arr.length < 1) return/throw; etc. */\nfunction isLengthGuardWithEarlyExit(stmt: ts.IfStatement, arrName: string): boolean {\n if (!isEarlyExit(stmt.thenStatement)) return false;\n return isZeroLengthCheck(stmt.expression, arrName);\n}\n\n/** Checks if condition means \"arr is empty\": arr.length === 0, arr.length < 1, arr.length !== N (N>=1) */\nfunction isZeroLengthCheck(expr: ts.Expression, arrName: string): boolean {\n if (!ts.isBinaryExpression(expr)) return false;\n const op = expr.operatorToken.kind;\n\n // arr.length === 0\n if ((op === ts.SyntaxKind.EqualsEqualsEqualsToken || op === ts.SyntaxKind.EqualsEqualsToken)) {\n if (isLengthAccess(expr.left, arrName) && isZeroLiteral(expr.right)) return true;\n if (isLengthAccess(expr.right, arrName) && isZeroLiteral(expr.left)) return true;\n }\n\n // arr.length < 1 (or any N >= 1)\n if (op === ts.SyntaxKind.LessThanToken) {\n if (isLengthAccess(expr.left, arrName) && isPositiveIntLiteral(expr.right)) return true;\n }\n\n // arr.length !== N where N >= 1 (e.g., if (arr.length !== 1) return; arr[0]!)\n if ((op === ts.SyntaxKind.ExclamationEqualsEqualsToken || op === ts.SyntaxKind.ExclamationEqualsToken)) {\n if (isLengthAccess(expr.left, arrName) && isPositiveIntLiteral(expr.right)) return true;\n }\n\n return false;\n}\n\n/** Checks if condition means \"arr is non-empty\": arr.length > 0, arr.length !== 0, arr.length >= 1 */\nfunction isPositiveLengthCheck(expr: ts.Expression, arrName: string): boolean {\n if (!ts.isBinaryExpression(expr)) return false;\n const op = expr.operatorToken.kind;\n\n // arr.length > 0\n if (op === ts.SyntaxKind.GreaterThanToken) {\n if (isLengthAccess(expr.left, arrName) && isZeroLiteral(expr.right)) return true;\n }\n\n // arr.length >= 1\n if (op === ts.SyntaxKind.GreaterThanEqualsToken) {\n if (isLengthAccess(expr.left, arrName) && isPositiveIntLiteral(expr.right)) return true;\n }\n\n // arr.length !== 0\n if ((op === ts.SyntaxKind.ExclamationEqualsEqualsToken || op === ts.SyntaxKind.ExclamationEqualsToken)) {\n if (isLengthAccess(expr.left, arrName) && isZeroLiteral(expr.right)) return true;\n }\n\n return false;\n}\n\nfunction isEarlyExit(stmt: ts.Statement): boolean {\n if (ts.isReturnStatement(stmt) || ts.isThrowStatement(stmt)) return true;\n if (ts.isBlock(stmt) && stmt.statements.length === 1) {\n const inner = stmt.statements[0];\n if (inner === undefined) return false;\n return ts.isReturnStatement(inner) || ts.isThrowStatement(inner);\n }\n return false;\n}\n\nfunction isZeroLiteral(node: ts.Node): boolean {\n return ts.isNumericLiteral(node) && node.text === \"0\";\n}\n\nfunction isPositiveIntLiteral(node: ts.Node): boolean {\n return ts.isNumericLiteral(node) && Number(node.text) >= 1;\n}\n\nfunction getIdentifierName(node: ts.Node): string | null {\n if (ts.isIdentifier(node)) return node.text;\n return null;\n}\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\nimport { isPromiseLike } from \"../../typecheck/utils.ts\";\n\nexport const noSwallowedCatch: TSRule = {\n kind: \"ts\",\n id: \"no-swallowed-catch\",\n severity: \"warning\",\n message:\n \"Catch swallows the error: it neither throws nor returns a value referencing the caught error. Propagate via throw, or model failure into the return type carrying the original error\",\n syntaxKinds: [ts.SyntaxKind.CatchClause, ts.SyntaxKind.CallExpression],\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (ts.isCatchClause(node)) {\n const binding = identifierBindingName(node.variableDeclaration);\n if (handlesError(node.block, binding)) return;\n ctx.report(node);\n return;\n }\n\n if (ts.isCallExpression(node)) {\n const callee = node.expression;\n if (!ts.isPropertyAccessExpression(callee)) return;\n if (callee.name.text !== \"catch\") return;\n if (node.arguments.length !== 1) return;\n const handler = node.arguments[0];\n if (!handler) return;\n if (!ts.isArrowFunction(handler) && !ts.isFunctionExpression(handler)) return;\n\n const recvType = ctx.semantics.typeAtLocation(callee.expression);\n if (!isPromiseLike(recvType, ctx.semantics)) return;\n\n const binding = identifierBindingName(handler.parameters[0]);\n if (handlesError(handler.body, binding)) return;\n ctx.report(node);\n }\n },\n};\n\nfunction identifierBindingName(\n decl: ts.VariableDeclaration | ts.ParameterDeclaration | undefined,\n): string | undefined {\n if (!decl) return undefined;\n if (!ts.isIdentifier(decl.name)) return undefined;\n return decl.name.text;\n}\n\n/**\n * Treats catch/handler body as handled iff one of:\n * - body throws (rethrow / wrap-and-throw)\n * - a return references the binding (carried into the return shape)\n * - the binding is passed as an argument to some call (handed off to a sink)\n */\nfunction handlesError(body: ts.Node, binding: string | undefined): boolean {\n if (!ts.isBlock(body)) {\n return binding !== undefined && expressionReferencesBinding(body, binding);\n }\n if (blockThrows(body)) return true;\n if (binding === undefined) return false;\n if (blockReturnsReferencingBinding(body, binding)) return true;\n return blockPassesBindingToCall(body, binding);\n}\n\n/**\n * True when some CallExpression in the body has an argument tree that references\n * the catch binding. The structural claim: a call that takes the error as an\n * argument is contracted to do something with it (log, capture, report, wrap,\n * transform). We trust the call's contract — same trust we extend to returns.\n *\n * Walks the body excluding nested function scopes (those would have their own\n * catch/return semantics for the binding).\n */\nfunction blockPassesBindingToCall(body: ts.Block, binding: string): boolean {\n return walkSkippingFunctions(body, (n) => {\n if (!ts.isCallExpression(n)) return false;\n return n.arguments.some((arg) => expressionReferencesBinding(arg, binding));\n });\n}\n\nfunction blockThrows(body: ts.Block): boolean {\n return walkSkippingFunctions(body, (n) => ts.isThrowStatement(n));\n}\n\nfunction blockReturnsReferencingBinding(body: ts.Block, binding: string): boolean {\n return walkSkippingFunctions(body, (n) => {\n if (!ts.isReturnStatement(n)) return false;\n if (!n.expression) return false;\n return expressionReferencesBinding(n.expression, binding);\n });\n}\n\nfunction walkSkippingFunctions(root: ts.Node, predicate: (n: ts.Node) => boolean): boolean {\n let found = false;\n function walk(node: ts.Node): void {\n if (found) return;\n if (\n ts.isFunctionDeclaration(node) ||\n ts.isFunctionExpression(node) ||\n ts.isArrowFunction(node) ||\n ts.isMethodDeclaration(node)\n ) {\n return;\n }\n if (predicate(node)) {\n found = true;\n return;\n }\n if (ts.isBlock(node) || ts.isSourceFile(node)) {\n for (const stmt of node.statements) {\n walk(stmt);\n if (found || statementTerminates(stmt)) return;\n }\n return;\n }\n ts.forEachChild(node, walk);\n }\n walk(root);\n return found;\n}\n\nfunction statementTerminates(stmt: ts.Statement): boolean {\n if (ts.isReturnStatement(stmt) || ts.isThrowStatement(stmt)) return true;\n if (!ts.isIfStatement(stmt)) return false;\n if (stmt.elseStatement === undefined) return false;\n return branchTerminates(stmt.thenStatement) && branchTerminates(stmt.elseStatement);\n}\n\nfunction branchTerminates(stmt: ts.Statement): boolean {\n if (statementTerminates(stmt)) return true;\n if (!ts.isBlock(stmt)) return false;\n const last = stmt.statements.at(-1);\n return last !== undefined && statementTerminates(last);\n}\n\nfunction expressionReferencesBinding(expr: ts.Node, binding: string): boolean {\n let found = false;\n function walk(node: ts.Node): void {\n if (found) return;\n if (\n ts.isFunctionDeclaration(node) ||\n ts.isFunctionExpression(node) ||\n ts.isArrowFunction(node) ||\n ts.isMethodDeclaration(node)\n ) {\n return;\n }\n if (ts.isIdentifier(node) && node.text === binding && isReferenceUse(node)) {\n found = true;\n return;\n }\n ts.forEachChild(node, walk);\n }\n walk(expr);\n return found;\n}\n\nfunction isReferenceUse(id: ts.Identifier): boolean {\n const parent: ts.Node | undefined = id.parent;\n if (!parent) return true;\n if (ts.isPropertyAccessExpression(parent) && parent.name === id) return false;\n if (ts.isPropertyAssignment(parent) && parent.name === id) return false;\n if (ts.isMethodDeclaration(parent) && parent.name === id) return false;\n if (ts.isQualifiedName(parent) && parent.right === id) return false;\n if (ts.isBindingElement(parent) && parent.propertyName === id) return false;\n if (ts.isParameter(parent) && parent.name === id) return false;\n return !(ts.isVariableDeclaration(parent) && parent.name === id);\n}\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\nimport { isUncheckedIndexRead } from \"../../typecheck/utils.ts\";\n\nexport const noNullTernaryNormalization: TSRule = {\n kind: \"ts\",\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 syntaxKinds: [ts.SyntaxKind.ConditionalExpression],\n requiresStrictNullChecks: true,\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isConditionalExpression(node)) return;\n const test = node.condition;\n if (!ts.isBinaryExpression(test)) return;\n\n const op = test.operatorToken.kind;\n if (\n op !== ts.SyntaxKind.EqualsEqualsEqualsToken &&\n op !== ts.SyntaxKind.ExclamationEqualsEqualsToken &&\n op !== ts.SyntaxKind.EqualsEqualsToken &&\n op !== ts.SyntaxKind.ExclamationEqualsToken\n ) return;\n\n const hasNullishComparand = isNullish(test.left) || isNullish(test.right);\n if (!hasNullishComparand) return;\n\n if (isNullish(node.whenTrue) || isNullish(node.whenFalse)) {\n // Non-nullable tested value -> this is dead code\n const tested = isNullish(test.left) ? test.right : test.left;\n // Index reads hide runtime undefined when noUncheckedIndexedAccess is off\n if (isUncheckedIndexRead(tested, ctx.semantics, ctx.compilerOptions)) return;\n if (!ctx.isNullable(tested)) {\n ctx.report(node, \"Ternary null-normalization on a non-nullable type is dead code; remove the ternary\");\n return;\n }\n ctx.report(node);\n }\n },\n};\n\nfunction isNullish(node: ts.Node): boolean {\n if (node.kind === ts.SyntaxKind.NullKeyword) return true;\n if (ts.isIdentifier(node) && node.text === \"undefined\") return true;\n // void 0\n return ts.isVoidExpression(node);\n}\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\nimport { isUncheckedIndexRead } from \"../../typecheck/utils.ts\";\n\nexport const noNullishCoalescing: TSRule = {\n kind: \"ts\",\n id: \"no-nullish-coalescing\",\n severity: \"warning\",\n message: \"Nullish coalescing (??) fallback on a non-nullable type is dead code; remove the fallback or fix the type upstream\",\n syntaxKinds: [ts.SyntaxKind.BinaryExpression],\n requiresStrictNullChecks: true,\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isBinaryExpression(node)) return;\n if (node.operatorToken.kind !== ts.SyntaxKind.QuestionQuestionToken) return;\n if (isPossiblyMissingArrayBindingValue(node.left, ctx)) return;\n // arr[i] / record[key] reads can be undefined at runtime even when the\n // checker says otherwise (noUncheckedIndexedAccess off) — the fallback is real.\n if (isUncheckedIndexRead(node.left, ctx.semantics, ctx.compilerOptions)) return;\n if (ctx.isNullable(node.left)) return;\n ctx.report(node, undefined, {\n start: node.getStart(ctx.sourceFile),\n end: node.getEnd(),\n text: node.left.getText(ctx.sourceFile),\n });\n },\n};\n\nfunction isPossiblyMissingArrayBindingValue(node: ts.Node, ctx: TSVisitContext): boolean {\n if (!ts.isIdentifier(node)) return false;\n\n const symbol = ctx.semantics.symbolAtLocation(node);\n if (!symbol) return false;\n\n for (const declaration of symbol.declarations ?? []) {\n if (!ts.isBindingElement(declaration)) continue;\n if (declaration.initializer || declaration.dotDotDotToken) continue;\n if (!ts.isArrayBindingPattern(declaration.parent)) continue;\n\n const pattern = declaration.parent;\n const index = pattern.elements.indexOf(declaration);\n if (index < 0) continue;\n\n if (!isTupleSlotDefinitelyPresent(ctx.semantics.typeAtLocation(pattern), index, ctx)) {\n // Without noUncheckedIndexedAccess, TS treats `[x] = T[]` as `x: T`, even though runtime can produce undefined.\n return true;\n }\n }\n\n return false;\n}\n\nfunction isTupleSlotDefinitelyPresent(type: ts.Type, index: number, ctx: TSVisitContext): boolean {\n if (type.isUnion()) {\n return type.types.every((member) => isTupleSlotDefinitelyPresent(member, index, ctx));\n }\n\n const apparent = ctx.semantics.apparentType(type);\n if (!isTupleTypeReference(apparent, ctx)) return false;\n return index < apparent.target.minLength;\n}\n\nfunction isTupleTypeReference(type: ts.Type, ctx: TSVisitContext): type is ts.TupleTypeReference {\n if (!ctx.semantics.isTupleType(type)) return false;\n if (!(\"target\" in type)) return false;\n\n const target = type.target;\n if (typeof target !== \"object\" || target === null) return false;\n if (!(\"minLength\" in target)) return false;\n\n return typeof target.minLength === \"number\";\n}\n","import type * as ts from \"typescript\";\nimport type { TSVisitContext } from \"../types.ts\";\nimport { isUncheckedIndexRead } from \"../../typecheck/utils.ts\";\n\n/**\n * Shared core of the dead-`?.` rules: report the question-dot when the\n * receiver's type can never be nullish. `removalText` is what the fix leaves\n * behind (`\".\"` for property access, `\"\"` for element access and calls).\n */\nexport function reportDeadQuestionDot(\n node: ts.PropertyAccessExpression | ts.ElementAccessExpression | ts.CallExpression,\n removalText: string,\n ctx: TSVisitContext,\n): void {\n if (!node.questionDotToken) return;\n if (isUncheckedIndexRead(node.expression, ctx.semantics, ctx.compilerOptions)) return;\n if (ctx.isNullable(node.expression)) return;\n ctx.report(node, undefined, {\n start: node.questionDotToken.getStart(ctx.sourceFile),\n end: node.questionDotToken.getEnd(),\n text: removalText,\n });\n}\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\nimport { reportDeadQuestionDot } from \"./optional-chain.ts\";\n\nexport const noOptionalCall: TSRule = {\n kind: \"ts\",\n id: \"no-optional-call\",\n severity: \"warning\",\n message: \"Optional call (?.) on a non-nullable function is redundant; call directly or fix the type upstream\",\n syntaxKinds: [ts.SyntaxKind.CallExpression],\n requiresStrictNullChecks: true,\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isCallExpression(node)) return;\n reportDeadQuestionDot(node, \"\", ctx);\n },\n};\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\nimport { reportDeadQuestionDot } from \"./optional-chain.ts\";\n\nexport const noOptionalElementAccess: TSRule = {\n kind: \"ts\",\n id: \"no-optional-element-access\",\n severity: \"warning\",\n message: \"Optional element access (?.[]) on a non-nullable type is redundant; use direct access or fix the type upstream\",\n syntaxKinds: [ts.SyntaxKind.ElementAccessExpression],\n requiresStrictNullChecks: true,\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isElementAccessExpression(node)) return;\n reportDeadQuestionDot(node, \"\", ctx);\n },\n};\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\nimport { reportDeadQuestionDot } from \"./optional-chain.ts\";\n\nexport const noOptionalPropertyAccess: TSRule = {\n kind: \"ts\",\n id: \"no-optional-property-access\",\n severity: \"warning\",\n message: \"Optional chaining (?.) on a non-nullable type is redundant; use direct access or fix the type upstream\",\n syntaxKinds: [ts.SyntaxKind.PropertyAccessExpression],\n requiresStrictNullChecks: true,\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isPropertyAccessExpression(node)) return;\n reportDeadQuestionDot(node, \".\", ctx);\n },\n};\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\nimport { isNullishLiteral } from \"../../typecheck/utils.ts\";\n\nexport const noRedundantExistenceGuard: TSRule = {\n kind: \"ts\",\n id: \"no-redundant-existence-guard\",\n severity: \"warning\",\n message: \"Redundant existence guard (obj && obj.prop) on a non-nullable type; remove the guard or fix the type upstream\",\n syntaxKinds: [ts.SyntaxKind.BinaryExpression],\n requiresStrictNullChecks: true,\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isBinaryExpression(node)) return;\n if (node.operatorToken.kind !== ts.SyntaxKind.AmpersandAmpersandToken) return;\n\n const left = node.left;\n const right = node.right;\n\n // Pattern 1: obj && obj.prop / obj.method() / obj[key]\n if (ts.isIdentifier(left) && accessesIdentifier(right, left.text)) {\n if (ctx.isNullable(left)) return;\n ctx.report(node);\n return;\n }\n\n // Pattern 2: obj != null && obj.prop (or !== null, !== undefined)\n if (ts.isBinaryExpression(left) && isNullCheck(left)) {\n const checked = getNullCheckedIdentifier(left);\n if (checked && accessesIdentifier(right, checked)) {\n // The null-check LHS is the identifier — check its type before the comparison\n // If the type is non-nullable, the entire guard is redundant\n const identNode = ts.isIdentifier(left.left) ? left.left : left.right;\n if (ts.isIdentifier(identNode) && identNode.text === checked && !ctx.isNullable(identNode)) {\n ctx.report(node);\n }\n }\n }\n },\n};\n\n/** Check if the root object of `expr` is identifier `name`. */\nfunction accessesIdentifier(expr: ts.Node, name: string): boolean {\n const root = getExpressionRoot(expr);\n return ts.isIdentifier(root) && root.text === name;\n}\n\n/** Walk through property access, element access, and call chains to find the root expression. */\nfunction getExpressionRoot(node: ts.Node): ts.Node {\n if (ts.isPropertyAccessExpression(node)) return getExpressionRoot(node.expression);\n if (ts.isElementAccessExpression(node)) return getExpressionRoot(node.expression);\n if (ts.isCallExpression(node)) return getExpressionRoot(node.expression);\n return node;\n}\n\n/** Check if expr is a null/undefined comparison: x != null, x !== null, x !== undefined */\nfunction isNullCheck(expr: ts.BinaryExpression): boolean {\n const op = expr.operatorToken.kind;\n if (op !== ts.SyntaxKind.ExclamationEqualsToken && op !== ts.SyntaxKind.ExclamationEqualsEqualsToken) return false;\n return isNullishLiteral(expr.right) || isNullishLiteral(expr.left);\n}\n\n/** Get the identifier name being null-checked. */\nfunction getNullCheckedIdentifier(expr: ts.BinaryExpression): string | null {\n if (ts.isIdentifier(expr.left) && isNullishLiteral(expr.right)) return expr.left.text;\n if (ts.isIdentifier(expr.right) && isNullishLiteral(expr.left)) return expr.right.text;\n return null;\n}\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\nimport { reportCommentDirectives } from \"../../typecheck/utils.ts\";\n\n// Warning, not error: unlike @ts-ignore it self-expires (compile error once the\n// suppressed error disappears), so it has legitimate uses — testing invalid\n// inputs, working around upstream .d.ts bugs. It still hides a real type error.\nexport const noTsExpectError: TSRule = {\n kind: \"ts\",\n id: \"no-ts-expect-error\",\n severity: \"warning\",\n message:\n \"@ts-expect-error suppresses a real type error; fix the underlying type issue\",\n syntaxKinds: [ts.SyntaxKind.SourceFile],\n requiresTypeInfo: false,\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n reportCommentDirectives(node, ctx, true);\n },\n};\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\nimport { reportCommentDirectives } from \"../../typecheck/utils.ts\";\n\nexport const noTsIgnore: TSRule = {\n kind: \"ts\",\n id: \"no-ts-ignore\",\n severity: \"error\",\n message:\n \"@ts-ignore silently suppresses type checking and keeps suppressing after the error is gone; fix the underlying type issue\",\n syntaxKinds: [ts.SyntaxKind.SourceFile],\n requiresTypeInfo: false,\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n reportCommentDirectives(node, ctx, false);\n },\n};\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\n\nexport const noTypeAssertion: TSRule = {\n kind: \"ts\",\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 syntaxKinds: [ts.SyntaxKind.AsExpression],\n requiresTypeInfo: false,\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isAsExpression(node)) return;\n if (!ts.isAsExpression(node.expression)) return;\n if (node.expression.type.kind !== ts.SyntaxKind.UnknownKeyword) return;\n ctx.report(node);\n },\n};\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\nimport { getFunctionBodyStatements, isNullishLiteral, splitEqualityOperands } from \"../../typecheck/utils.ts\";\n\n/**\n * Optional parameter coerced to non-optional in the function body.\n *\n * Scans the body's prologue (statements before the first other use of the\n * param) for either:\n * - a reassignment via ??: `param = param ?? X` / `param ??= X`\n * - a nullish guard that throws: `if (!param) throw`\n * or `if (param === undefined) throw`\n *\n * AND the parameter is declared optional (`?:`).\n *\n * A nullish guard that returns is an honest no-op optional contract and is not\n * flagged.\n */\nexport const optionalParamCoercedInBody: TSRule = {\n kind: \"ts\",\n id: \"optional-param-coerced-in-body\",\n severity: \"warning\",\n message:\n \"Optional parameter is forced non-optional in the body. Make the contract honest: make it required, use a default value in the signature, or split into a discriminated alternative.\",\n syntaxKinds: [\n ts.SyntaxKind.FunctionDeclaration,\n ts.SyntaxKind.ArrowFunction,\n ts.SyntaxKind.FunctionExpression,\n ts.SyntaxKind.MethodDeclaration,\n ],\n requiresTypeInfo: false,\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n const result = getFunctionBodyStatements(node);\n if (result === null) return;\n const { statements, fn } = result;\n\n const pending = new Set(\n fn.parameters\n .filter((p) => p.questionToken !== undefined && ts.isIdentifier(p.name))\n .map((p) => (p.name as ts.Identifier).text),\n );\n if (pending.size === 0) return;\n\n for (const stmt of statements) {\n if (pending.size === 0) return;\n let coerced = detectCoerceReassign(stmt);\n if (coerced === null) coerced = detectNullishGuard(stmt);\n if (coerced !== null && pending.has(coerced)) {\n ctx.report(stmt);\n pending.delete(coerced);\n continue;\n }\n // Any other use of a param ends its prologue: a later coercion no\n // longer describes the parameter's contract, just local logic.\n for (const name of pending) {\n if (statementReferencesName(stmt, name)) pending.delete(name);\n }\n }\n },\n};\n\nfunction statementReferencesName(stmt: ts.Statement, name: string): boolean {\n let found = false;\n function walk(node: ts.Node): void {\n if (found) return;\n if (ts.isIdentifier(node) && node.text === name) {\n found = true;\n return;\n }\n ts.forEachChild(node, walk);\n }\n walk(stmt);\n return found;\n}\n\n/** Pattern A: `param = param ?? X` or `param ??= X`. Returns the param name or null. */\nfunction detectCoerceReassign(stmt: ts.Statement): string | null {\n if (!ts.isExpressionStatement(stmt)) return null;\n const expr = stmt.expression;\n if (!ts.isBinaryExpression(expr)) return null;\n\n // `param ??= X`\n if (expr.operatorToken.kind === ts.SyntaxKind.QuestionQuestionEqualsToken) {\n return ts.isIdentifier(expr.left) ? expr.left.text : null;\n }\n // `param = param ?? X`\n if (expr.operatorToken.kind !== ts.SyntaxKind.EqualsToken) return null;\n if (!ts.isIdentifier(expr.left)) return null;\n const rhs = expr.right;\n if (!ts.isBinaryExpression(rhs)) return null;\n if (rhs.operatorToken.kind !== ts.SyntaxKind.QuestionQuestionToken) return null;\n if (!ts.isIdentifier(rhs.left)) return null;\n if (rhs.left.text !== expr.left.text) return null;\n return expr.left.text;\n}\n\n/**\n * Pattern B: `if (NULL-CHECK on param) THROW`. Returns the param name or null.\n * NULL-CHECK is one of: `!param`, `param === undefined`, `param == undefined`,\n * `param === null`, `param == null`.\n */\nfunction detectNullishGuard(stmt: ts.Statement): string | null {\n if (!ts.isIfStatement(stmt)) return null;\n const test = stmt.expression;\n const guardedName = extractNullCheckIdentifier(test);\n if (guardedName === null) return null;\n\n const consequent = stmt.thenStatement;\n if (!isThrow(consequent)) return null;\n return guardedName;\n}\n\nfunction extractNullCheckIdentifier(test: ts.Expression): string | null {\n // `!param`\n if (ts.isPrefixUnaryExpression(test) && test.operator === ts.SyntaxKind.ExclamationToken) {\n return ts.isIdentifier(test.operand) ? test.operand.text : null;\n }\n // `param === undefined` / `param == undefined` / `param === null` / `param == null`\n if (ts.isBinaryExpression(test)) {\n const op = test.operatorToken.kind;\n if (\n op !== ts.SyntaxKind.EqualsEqualsEqualsToken &&\n op !== ts.SyntaxKind.EqualsEqualsToken\n ) {\n return null;\n }\n const operands = splitEqualityOperands(test);\n if (operands === null) return null;\n if (isNullishLiteral(operands.lit)) return operands.id.text;\n }\n return null;\n}\n\nfunction isThrow(stmt: ts.Statement): boolean {\n if (ts.isThrowStatement(stmt)) return true;\n if (!ts.isBlock(stmt)) return false;\n if (stmt.statements.length !== 1) return false;\n const inner = stmt.statements[0];\n return inner !== undefined && ts.isThrowStatement(inner);\n}\n","import type { Rule } from \"./types.ts\";\n\nimport { constantArgument } from \"./cross-file/constant-argument.ts\";\nimport { deadOverload } from \"./cross-file/dead-overload.ts\";\nimport { duplicateConstantDeclaration } from \"./cross-file/duplicate-constant-declaration.ts\";\nimport { duplicateFile } from \"./cross-file/duplicate-file.ts\";\nimport { duplicateFunctionDeclaration } from \"./cross-file/duplicate-function-declaration.ts\";\nimport { duplicateFunctionName } from \"./cross-file/duplicate-function-name.ts\";\nimport { duplicateInlineTypeInParams } from \"./cross-file/duplicate-inline-type-in-params.ts\";\nimport { duplicateStatementSequence } from \"./cross-file/duplicate-statement-sequence.ts\";\nimport { duplicateTypeDeclaration } from \"./cross-file/duplicate-type-declaration.ts\";\nimport { duplicateTypeName } from \"./cross-file/duplicate-type-name.ts\";\nimport { explicitNullArg } from \"./cross-file/explicit-null-arg.ts\";\nimport { nearDuplicateFunction } from \"./cross-file/near-duplicate-function.ts\";\nimport { optionalArgAlwaysUsed } from \"./cross-file/optional-arg-always-used.ts\";\nimport { optionalArgNeverUsed } from \"./cross-file/optional-arg-never-used.ts\";\nimport { repeatedLiteralProperty } from \"./cross-file/repeated-literal-property.ts\";\nimport { repeatedReturnShape } from \"./cross-file/repeated-return-shape.ts\";\nimport { trivialWrapper } from \"./cross-file/trivial-wrapper.ts\";\nimport { unusedExport } from \"./cross-file/unused-export.ts\";\nimport { noAnyCast } from \"./ts/no-any-cast.ts\";\nimport { noAwaitCoalesce } from \"./ts/no-await-coalesce.ts\";\nimport { noCoalesceThenGuard } from \"./ts/no-coalesce-then-guard.ts\";\nimport { noCoalesceUndefined } from \"./ts/no-coalesce-undefined.ts\";\nimport { noDeadNarrowing } from \"./ts/no-dead-narrowing.ts\";\nimport { noDefaultedRequiredPortArg } from \"./ts/no-defaulted-required-port-arg.ts\";\nimport { noDoubleNegationCoercion } from \"./ts/no-double-negation-coercion.ts\";\nimport { noDynamicImport } from \"./ts/no-dynamic-import.ts\";\nimport { noErrorRewrap } from \"./ts/no-error-rewrap.ts\";\nimport { noExplicitAnyAnnotation } from \"./ts/no-explicit-any-annotation.ts\";\nimport { noInlineParamType } from \"./ts/no-inline-param-type.ts\";\nimport { noInlineTypeAssertion } from \"./ts/no-inline-type-assertion.ts\";\nimport { noNeverCast } from \"./ts/no-never-cast.ts\";\nimport { noRedundantCast } from \"./ts/no-redundant-cast.ts\";\nimport { noUnvalidatedCast } from \"./ts/no-unvalidated-cast.ts\";\nimport { noUselessAwait } from \"./ts/no-useless-await.ts\";\nimport { redundantBooleanBranch } from \"./ts/redundant-boolean-branch.ts\";\nimport { redundantDestructureDefault } from \"./ts/redundant-destructure-default.ts\";\nimport { redundantNarrowingThenCast } from \"./ts/redundant-narrowing-then-cast.ts\";\nimport { trivialTypeAlias } from \"./ts/trivial-type-alias.ts\";\nimport { returnTypeWidensViaDestructure } from \"./ts/return-type-widens-via-destructure.ts\";\nimport { preferTypePredicate } from \"./ts/prefer-type-predicate.ts\";\nimport { noLogicalOrFallback } from \"./ts/no-logical-or-fallback.ts\";\nimport { noNonNullAssertion } from \"./ts/no-non-null-assertion.ts\";\nimport { noSwallowedCatch } from \"./ts/no-swallowed-catch.ts\";\nimport { noNullTernaryNormalization } from \"./ts/no-null-ternary-normalization.ts\";\nimport { noNullishCoalescing } from \"./ts/no-nullish-coalescing.ts\";\nimport { noOptionalCall } from \"./ts/no-optional-call.ts\";\nimport { noOptionalElementAccess } from \"./ts/no-optional-element-access.ts\";\nimport { noOptionalPropertyAccess } from \"./ts/no-optional-property-access.ts\";\nimport { noRedundantExistenceGuard } from \"./ts/no-redundant-existence-guard.ts\";\nimport { noTsExpectError } from \"./ts/no-ts-expect-error.ts\";\nimport { noTsIgnore } from \"./ts/no-ts-ignore.ts\";\nimport { noTypeAssertion } from \"./ts/no-type-assertion.ts\";\nimport { optionalParamCoercedInBody } from \"./ts/optional-param-coerced-in-body.ts\";\n\nexport type RuleCategory =\n | \"type-evasion\"\n | \"defensive-code\"\n | \"error-handling\"\n | \"interface-design\"\n | \"cross-file\"\n | \"imports\";\n\n/**\n * The epistemic tier of a rule, orthogonal to severity.\n *\n * - `proven`: the checker or AST demonstrates the defect — the fallback is\n * dead, the cast evades, the error vanishes. Every finding demands a fix\n * (or an explicit `@unguard` annotation). These run on `unguard scan`.\n * - `heuristic`: pattern evidence that warrants review — duplication, API\n * shape, speculative parameters. A finding can have a correct alternative\n * reading the analysis cannot see (deliberate test explicitness, parallel\n * naming, convention-driven usage). These run on `unguard audit`.\n *\n * The test for `proven`: would deleting/changing the flagged code ever be\n * wrong when the types are honest? If yes, the rule is heuristic.\n */\nexport type RuleConfidence = \"proven\" | \"heuristic\";\n\nexport interface RuleMetadata {\n category: RuleCategory;\n tags: string[];\n confidence: RuleConfidence;\n}\n\nexport const allRules: Rule[] = [\n noNonNullAssertion,\n noDoubleNegationCoercion,\n noTsIgnore,\n noTsExpectError,\n noNullishCoalescing,\n noOptionalCall,\n noOptionalPropertyAccess,\n noOptionalElementAccess,\n noLogicalOrFallback,\n noNullTernaryNormalization,\n noCoalesceThenGuard,\n noCoalesceUndefined,\n noAwaitCoalesce,\n noDeadNarrowing,\n redundantBooleanBranch,\n noUselessAwait,\n trivialTypeAlias,\n redundantDestructureDefault,\n noAnyCast,\n noExplicitAnyAnnotation,\n duplicateInlineTypeInParams,\n noInlineTypeAssertion,\n noTypeAssertion,\n noNeverCast,\n noRedundantCast,\n noUnvalidatedCast,\n redundantNarrowingThenCast,\n returnTypeWidensViaDestructure,\n preferTypePredicate,\n noRedundantExistenceGuard,\n optionalParamCoercedInBody,\n noDefaultedRequiredPortArg,\n noInlineParamType,\n duplicateTypeDeclaration,\n duplicateFunctionDeclaration,\n optionalArgAlwaysUsed,\n optionalArgNeverUsed,\n constantArgument,\n noErrorRewrap,\n noSwallowedCatch,\n explicitNullArg,\n duplicateFunctionName,\n duplicateTypeName,\n duplicateConstantDeclaration,\n noDynamicImport,\n nearDuplicateFunction,\n trivialWrapper,\n unusedExport,\n duplicateFile,\n duplicateStatementSequence,\n deadOverload,\n repeatedLiteralProperty,\n repeatedReturnShape,\n];\n\nconst ruleMetadata: Record<string, RuleMetadata> = {\n \"no-any-cast\": { category: \"type-evasion\", tags: [\"safety\"], confidence: \"proven\" },\n \"no-explicit-any-annotation\": { category: \"type-evasion\", tags: [\"safety\"], confidence: \"proven\" },\n \"no-inline-type-assertion\": { category: \"type-evasion\", tags: [\"safety\"], confidence: \"proven\" },\n \"no-type-assertion\": { category: \"type-evasion\", tags: [\"safety\"], confidence: \"proven\" },\n \"no-ts-ignore\": { category: \"type-evasion\", tags: [\"safety\"], confidence: \"proven\" },\n \"no-ts-expect-error\": { category: \"type-evasion\", tags: [\"safety\"], confidence: \"proven\" },\n \"no-never-cast\": { category: \"type-evasion\", tags: [\"safety\"], confidence: \"proven\" },\n \"no-redundant-cast\": { category: \"type-evasion\", tags: [\"type-aware\"], confidence: \"proven\" },\n \"no-unvalidated-cast\": { category: \"type-evasion\", tags: [\"safety\", \"type-aware\"], confidence: \"proven\" },\n \"redundant-narrowing-then-cast\": { category: \"type-evasion\", tags: [\"type-aware\"], confidence: \"proven\" },\n \"return-type-widens-via-destructure\": { category: \"type-evasion\", tags: [\"type-aware\", \"safety\"], confidence: \"proven\" },\n // Converting `(x): boolean` to a predicate is a design suggestion, not a defect.\n \"prefer-type-predicate\": { category: \"interface-design\", tags: [\"api\", \"type-aware\"], confidence: \"heuristic\" },\n\n \"no-optional-property-access\": { category: \"defensive-code\", tags: [\"type-aware\"], confidence: \"proven\" },\n \"no-optional-element-access\": { category: \"defensive-code\", tags: [\"type-aware\"], confidence: \"proven\" },\n \"no-optional-call\": { category: \"defensive-code\", tags: [\"type-aware\"], confidence: \"proven\" },\n \"no-nullish-coalescing\": { category: \"defensive-code\", tags: [\"type-aware\"], confidence: \"proven\" },\n \"no-logical-or-fallback\": { category: \"defensive-code\", tags: [\"type-aware\"], confidence: \"proven\" },\n \"no-null-ternary-normalization\": { category: \"defensive-code\", tags: [\"type-aware\"], confidence: \"proven\" },\n \"no-coalesce-then-guard\": { category: \"defensive-code\", tags: [\"readability\"], confidence: \"proven\" },\n // Fusing the call's failure mode into a fallback can be a deliberate choice.\n \"no-await-coalesce\": { category: \"defensive-code\", tags: [\"type-aware\"], confidence: \"heuristic\" },\n \"no-non-null-assertion\": { category: \"defensive-code\", tags: [\"type-aware\"], confidence: \"proven\" },\n \"no-double-negation-coercion\": { category: \"defensive-code\", tags: [\"readability\"], confidence: \"proven\" },\n \"no-redundant-existence-guard\": { category: \"defensive-code\", tags: [\"type-aware\"], confidence: \"proven\" },\n \"no-dead-narrowing\": { category: \"defensive-code\", tags: [\"type-aware\", \"safety\"], confidence: \"proven\" },\n \"redundant-boolean-branch\": { category: \"defensive-code\", tags: [\"readability\", \"type-aware\"], confidence: \"proven\" },\n \"no-useless-await\": { category: \"defensive-code\", tags: [\"readability\", \"type-aware\"], confidence: \"proven\" },\n \"no-coalesce-undefined\": { category: \"defensive-code\", tags: [\"type-aware\"], confidence: \"proven\" },\n \"redundant-destructure-default\": { category: \"defensive-code\", tags: [\"type-aware\"], confidence: \"proven\" },\n // Roughly half of trivial aliases are deliberate parallel/boundary naming.\n \"trivial-type-alias\": { category: \"interface-design\", tags: [\"api\", \"readability\"], confidence: \"heuristic\" },\n\n \"no-error-rewrap\": { category: \"error-handling\", tags: [\"safety\"], confidence: \"proven\" },\n \"no-swallowed-catch\": { category: \"error-handling\", tags: [\"safety\"], confidence: \"proven\" },\n\n \"duplicate-inline-type-in-params\": { category: \"cross-file\", tags: [\"duplicate\", \"api\"], confidence: \"heuristic\" },\n // The body's coercion proves the optionality is fake; the fix is mechanical.\n \"optional-param-coerced-in-body\": { category: \"interface-design\", tags: [\"api\"], confidence: \"proven\" },\n // Type-proven divergence between the interface contract and the implementation.\n \"no-defaulted-required-port-arg\": { category: \"interface-design\", tags: [\"api\", \"type-aware\"], confidence: \"proven\" },\n // Inline param shapes are idiomatic in some ecosystems (React props).\n \"no-inline-param-type\": { category: \"interface-design\", tags: [\"api\"], confidence: \"heuristic\" },\n \"duplicate-type-declaration\": { category: \"cross-file\", tags: [\"duplicate\"], confidence: \"heuristic\" },\n \"duplicate-type-name\": { category: \"cross-file\", tags: [\"duplicate\"], confidence: \"heuristic\" },\n \"duplicate-function-declaration\": { category: \"cross-file\", tags: [\"duplicate\"], confidence: \"heuristic\" },\n \"duplicate-function-name\": { category: \"cross-file\", tags: [\"duplicate\"], confidence: \"heuristic\" },\n \"duplicate-constant-declaration\": { category: \"cross-file\", tags: [\"duplicate\"], confidence: \"heuristic\" },\n \"optional-arg-always-used\": { category: \"cross-file\", tags: [\"api\"], confidence: \"heuristic\" },\n \"optional-arg-never-used\": { category: \"cross-file\", tags: [\"api\"], confidence: \"heuristic\" },\n \"constant-argument\": { category: \"cross-file\", tags: [\"api\"], confidence: \"heuristic\" },\n \"explicit-null-arg\": { category: \"cross-file\", tags: [\"api\"], confidence: \"heuristic\" },\n\n // Code-splitting and lazy loading are legitimate dynamic imports.\n \"no-dynamic-import\": { category: \"imports\", tags: [\"safety\"], confidence: \"heuristic\" },\n\n \"near-duplicate-function\": { category: \"cross-file\", tags: [\"duplicate\"], confidence: \"heuristic\" },\n \"trivial-wrapper\": { category: \"cross-file\", tags: [\"duplicate\"], confidence: \"heuristic\" },\n // Convention-driven and reflective usage is invisible to import analysis.\n \"unused-export\": { category: \"cross-file\", tags: [\"api\"], confidence: \"heuristic\" },\n \"duplicate-file\": { category: \"cross-file\", tags: [\"duplicate\"], confidence: \"heuristic\" },\n \"duplicate-statement-sequence\": { category: \"cross-file\", tags: [\"duplicate\"], confidence: \"heuristic\" },\n \"dead-overload\": { category: \"cross-file\", tags: [\"api\", \"type-evasion\"], confidence: \"heuristic\" },\n\n \"repeated-literal-property\": { category: \"interface-design\", tags: [\"duplicate\", \"readability\"], confidence: \"heuristic\" },\n \"repeated-return-shape\": { category: \"interface-design\", tags: [\"duplicate\", \"readability\"], confidence: \"heuristic\" },\n};\n\nexport function getRuleMetadata(ruleId: string): RuleMetadata {\n const metadata = ruleMetadata[ruleId];\n if (metadata === undefined) {\n throw new Error(`unguard: rule \"${ruleId}\" has no metadata entry in src/rules/index.ts`);\n }\n return metadata;\n}\n","import { createHash } from \"node:crypto\";\nimport * as ts from \"typescript\";\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: ts.Node, sourceFile: ts.SourceFile): string {\n const normalized = normalizeTypeNode(node, sourceFile);\n return createHash(\"sha256\").update(normalized).digest(\"hex\").slice(0, 16);\n}\n\nfunction normalizeTypeNode(node: ts.Node, sourceFile: ts.SourceFile): string {\n if (ts.isTypeLiteralNode(node)) {\n const normalized = node.members.map((m) => normalizeTypeNode(m, sourceFile)).sort().join(\";\");\n return `{${normalized}}`;\n }\n if (ts.isInterfaceDeclaration(node)) {\n const normalized = node.members.map((m) => normalizeTypeNode(m, sourceFile)).sort().join(\";\");\n return `{${normalized}}`;\n }\n if (ts.isPropertySignature(node)) {\n const keyName = node.name.getText(sourceFile);\n const optional = node.questionToken ? \"?\" : \"\";\n const type = node.type ? normalizeTypeNode(node.type, sourceFile) : \"any\";\n return `${keyName}${optional}:${type}`;\n }\n if (ts.isTypeAliasDeclaration(node)) {\n return normalizeTypeNode(node.type, sourceFile);\n }\n // Fallback: use source text with whitespace normalized\n return node.getText(sourceFile).replace(/\\s+/g, \" \").trim();\n}\n\n/**\n * Function-body hashes and lengths used by duplicate and near-duplicate rules.\n */\nexport interface FunctionBodyAnalysis {\n hash: string;\n normalizedHash: string;\n bodyLength: number;\n normalizedBodyLength: number;\n}\n\nfunction normalizeBodyText(text: string, paramNames: string[]): string {\n let normalized = text;\n // Normalize string literals (double-quoted, single-quoted, template)\n normalized = normalized.replace(/\"(?:[^\"\\\\]|\\\\.)*\"/g, '\"__STR__\"');\n normalized = normalized.replace(/'(?:[^'\\\\]|\\\\.)*'/g, '\"__STR__\"');\n normalized = normalized.replace(/`(?:[^`\\\\]|\\\\.)*`/g, '\"__STR__\"');\n // Normalize numeric literals (standalone numbers, not inside identifiers)\n normalized = normalized.replace(/\\b\\d+(?:\\.\\d+)?\\b/g, \"__NUM__\");\n // Normalize parameter names to positional placeholders\n for (let i = 0; i < paramNames.length; i++) {\n const name = paramNames[i] as string;\n const escaped = name.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n normalized = normalized.replace(new RegExp(`\\\\b${escaped}\\\\b`, \"g\"), `$${i}`);\n }\n // Normalize member-access objects: this.x and $N.x both become $_.x\n normalized = normalized.replace(/\\bthis\\s*\\.\\s*/g, \"$_.\");\n normalized = normalized.replace(/\\$\\d+\\s*\\.\\s*/g, \"$_.\");\n // Normalize whitespace\n normalized = normalized.replace(/\\s+/g, \" \").trim();\n return normalized;\n}\n\nexport function analyzeFunctionBody(\n node: ts.Node,\n sourceFile: ts.SourceFile,\n paramNames: string[],\n): FunctionBodyAnalysis {\n const stripped = stripCommentsAndWhitespace(node.getText(sourceFile));\n const normalized = normalizeBodyText(stripped, paramNames);\n return {\n hash: hashText(stripped),\n normalizedHash: hashText(normalized),\n bodyLength: stripped.length,\n normalizedBodyLength: normalized.length,\n };\n}\n\n/**\n * Strip comments and normalize token spacing without touching literal contents.\n * Used as the textual canonical form for hashing so strings like `\"http://x\"`\n * remain intact while comment/trivia layout does not affect identity.\n */\nexport function stripCommentsAndWhitespace(text: string): string {\n const scanner = ts.createScanner(\n ts.ScriptTarget.Latest,\n true,\n ts.LanguageVariant.Standard,\n text,\n );\n const tokens: string[] = [];\n let token = scanner.scan();\n while (token !== ts.SyntaxKind.EndOfFileToken) {\n tokens.push(scanner.getTokenText());\n token = scanner.scan();\n }\n return tokens.join(\" \").trim();\n}\n\n/**\n * Normalize raw text (not from an AST node) using the same normalization pipeline.\n * Used for statement-sequence hashing.\n */\nexport function normalizeText(text: string): string {\n let t = stripCommentsAndWhitespace(text);\n // Normalize string literals\n t = t.replace(/\"(?:[^\"\\\\]|\\\\.)*\"/g, '\"__STR__\"');\n t = t.replace(/'(?:[^'\\\\]|\\\\.)*'/g, '\"__STR__\"');\n t = t.replace(/`(?:[^`\\\\]|\\\\.)*`/g, '\"__STR__\"');\n // Normalize numeric literals\n t = t.replace(/\\b\\d+(?:\\.\\d+)?\\b/g, \"__NUM__\");\n // Normalize member-access objects\n t = t.replace(/\\bthis\\./g, \"$_.\");\n return t;\n}\n\nexport function hashText(text: string): string {\n return createHash(\"sha256\").update(text).digest(\"hex\").slice(0, 16);\n}\n","export class BaseRegistry<T> {\n protected entries: T[] = [];\n protected byHash = new Map<string, T[]>();\n\n protected addEntry(entry: T, hash: string): void {\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(): T[][] {\n return [...this.byHash.values()].filter((group) => group.length > 1);\n }\n\n getAll(): T[] {\n return this.entries;\n }\n}\n\nexport class DualHashRegistry<T> extends BaseRegistry<T> {\n private bySecondaryHash = new Map<string, T[]>();\n\n protected addWithSecondary(entry: T, primaryHash: string, secondaryHash: string): void {\n this.addEntry(entry, primaryHash);\n let list = this.bySecondaryHash.get(secondaryHash);\n if (list === undefined) {\n list = [];\n this.bySecondaryHash.set(secondaryHash, list);\n }\n list.push(entry);\n }\n\n getSecondaryDuplicateGroups(): T[][] {\n return [...this.bySecondaryHash.values()].filter((group) => group.length > 1);\n }\n}\n","import type * as ts from \"typescript\";\nimport { existsSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { hashTypeShape } from \"../utils/hash.ts\";\nimport { BaseRegistry } from \"./base-registry.ts\";\n\nexport interface TypeEntry {\n name: string;\n file: string;\n line: number;\n column: number;\n hash: string;\n node: ts.Node;\n exported: boolean;\n}\n\nexport class TypeRegistry extends BaseRegistry<TypeEntry> {\n add(name: string, file: string, line: number, column: number, typeNode: ts.Node, sourceFile: ts.SourceFile, exported: boolean): void {\n const hash = hashTypeShape(typeNode, sourceFile);\n const entry: TypeEntry = { name, file, line, column, hash, node: typeNode, exported };\n this.addEntry(entry, hash);\n }\n\n getNameCollisionGroups(): TypeEntry[][] {\n return getExportedNameCollisions(this.entries);\n }\n}\n\nexport function getExportedNameCollisions<T extends { name: string; file: string; exported: boolean }>(entries: T[]): T[][] {\n const byNameAndPackage = new Map<string, T[]>();\n for (const entry of entries) {\n if (!entry.exported) continue;\n const pkg = findPackageRoot(entry.file);\n const key = `${pkg}\\0${entry.name}`;\n let list = byNameAndPackage.get(key);\n if (list === undefined) {\n list = [];\n byNameAndPackage.set(key, list);\n }\n list.push(entry);\n }\n return [...byNameAndPackage.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\nconst packageRootCache = new Map<string, string>();\n\nfunction findPackageRoot(filePath: string): string {\n let dir = dirname(filePath);\n const cached = packageRootCache.get(dir);\n if (cached !== undefined) return cached;\n\n const startDir = dir;\n const visited: string[] = [dir];\n while (dir !== dirname(dir)) {\n if (existsSync(join(dir, \"package.json\"))) {\n for (const d of visited) packageRootCache.set(d, dir);\n return dir;\n }\n dir = dirname(dir);\n visited.push(dir);\n }\n for (const d of visited) packageRootCache.set(d, dir);\n return dir;\n}\n","import type * as ts from \"typescript\";\nimport { DualHashRegistry } from \"./base-registry.ts\";\nimport { getExportedNameCollisions } from \"./type-registry.ts\";\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 column: number;\n hash: string;\n normalizedHash: string;\n params: ParamInfo[];\n node: ts.Node;\n exported: boolean;\n /** True when the declaration carries the `default` modifier (export default) */\n exportedAsDefault?: boolean;\n symbol?: ts.Symbol;\n /** Whitespace-normalized body text length (for trivial-body filtering) */\n bodyLength: number;\n /** Fully-normalized body text length (strings/numbers/params replaced) */\n normalizedBodyLength: number;\n /** Class name for class methods (e.g. \"Foo\" for \"Foo.bar\"), undefined for standalone functions */\n className?: string;\n /** True if the declaring class has an `implements` clause */\n implementsInterface?: boolean;\n}\n\nexport class FunctionRegistry extends DualHashRegistry<FunctionEntry> {\n add(entry: FunctionEntry): void {\n this.addWithSecondary(entry, entry.hash, entry.normalizedHash);\n }\n\n getNearDuplicateGroups(): FunctionEntry[][] {\n return this.getSecondaryDuplicateGroups().filter((group) => {\n // Exclude groups where all entries share the same exact hash\n // (those are already caught by duplicate-function-declaration)\n const hashes = new Set(group.map((e) => e.hash));\n return hashes.size > 1;\n });\n }\n\n getByName(name: string): FunctionEntry[] {\n return this.entries.filter((e) => e.name === name);\n }\n\n getNameCollisionGroups(): FunctionEntry[][] {\n return getExportedNameCollisions(this.entries);\n }\n}\n","import { BaseRegistry } from \"./base-registry.ts\";\n\nexport interface ConstantEntry {\n name: string;\n file: string;\n line: number;\n column: number;\n valueHash: string;\n valueText: string;\n exported: boolean;\n}\n\nexport class ConstantRegistry extends BaseRegistry<ConstantEntry> {\n add(entry: ConstantEntry): void {\n this.addEntry(entry, entry.valueHash);\n }\n}\n","/**\n * Detect maximal duplicated runs of consecutive statements across all collected\n * blocks. \"Maximal\" means the run can't be extended in either direction without\n * breaking the match — this is the standard formulation used by CPD/Simian and\n * avoids the fragmentation a fixed-window sliding-hash approach produces (where\n * one underlying duplication shows up as many overlapping window matches at\n * different sizes).\n *\n * Algorithm:\n * 1. Each statement is hashed individually (text identity, comments and\n * whitespace normalized). Per-statement hashes are indexed globally.\n * 2. For each anchor position p with a non-unique hash, collect candidate\n * positions sharing the same hash whose left predecessor differs from p's\n * (or one of them is at block start). This \"left-distinct\" filter ensures\n * a match between two positions is only emitted from its leftmost\n * starting point — anywhere else, it would be subsumed.\n * 3. Extend right one statement at a time. Whenever some candidates drop out\n * (their next statement diverges), the cluster as it stood is recorded as\n * a maximal match at the current length. Continue with the surviving\n * subset for the longer match.\n * 4. Across anchors, dedupe by (sorted participant file:line, length).\n * 5. Drop matches whose participant set is a strict subset of a kept match\n * at the same length — these are the same maximal run found from a less\n * complete anchor.\n */\nexport interface StatementInBlock {\n hash: string;\n line: number;\n column: number;\n endLine: number;\n normalizedLength: number;\n}\n\nexport interface MaximalMatchParticipant {\n file: string;\n line: number;\n column: number;\n endLine: number;\n /** Number of statements in this match (same for every participant). */\n statementCount: number;\n}\n\nexport interface MaximalMatch {\n participants: MaximalMatchParticipant[];\n statementCount: number;\n /** Sum of per-statement normalized text lengths across the matched run. */\n normalizedBodyLength: number;\n}\n\ninterface PositionRef {\n block: BlockData;\n pos: number;\n}\n\ninterface BlockData {\n file: string;\n stmts: StatementInBlock[];\n}\n\ninterface RecordedMatch {\n participants: PositionRef[];\n length: number;\n}\n\nexport class StatementSequenceRegistry {\n private blocks: BlockData[] = [];\n private byHash = new Map<string, PositionRef[]>();\n\n addBlock(file: string, stmts: StatementInBlock[]): void {\n if (stmts.length === 0) return;\n const block: BlockData = { file, stmts };\n this.blocks.push(block);\n for (let pos = 0; pos < stmts.length; pos++) {\n const stmt = stmts[pos];\n if (stmt === undefined) continue;\n let list = this.byHash.get(stmt.hash);\n if (list === undefined) {\n list = [];\n this.byHash.set(stmt.hash, list);\n }\n list.push({ block, pos });\n }\n }\n\n getMaximalMatches(minStatementCount: number, minNormalizedBodyLength: number): MaximalMatch[] {\n const recorded = new Map<string, RecordedMatch>();\n\n for (const block of this.blocks) {\n for (let pos = 0; pos < block.stmts.length; pos++) {\n this.findMatchesFromAnchor(block, pos, minStatementCount, recorded);\n }\n }\n\n // Sort by (length desc, participant count desc) so subset filtering keeps\n // the larger participant set for any given length.\n const ordered = [...recorded.values()].sort((a, b) => {\n if (b.length !== a.length) return b.length - a.length;\n return b.participants.length - a.participants.length;\n });\n\n const kept: RecordedMatch[] = [];\n for (const match of ordered) {\n const subsumed = kept.some(\n (k) =>\n k.length === match.length &&\n isStrictParticipantSubset(match.participants, k.participants),\n );\n if (!subsumed) kept.push(match);\n }\n\n const out: MaximalMatch[] = [];\n for (const match of kept) {\n const materialized = materialize(match, minNormalizedBodyLength);\n if (materialized !== null) out.push(materialized);\n }\n return out;\n }\n\n private findMatchesFromAnchor(\n anchorBlock: BlockData,\n anchorPos: number,\n minStatementCount: number,\n recorded: Map<string, RecordedMatch>,\n ): void {\n const anchorStmt = anchorBlock.stmts[anchorPos];\n if (anchorStmt === undefined) return;\n const candidates = this.byHash.get(anchorStmt.hash);\n if (candidates === undefined || candidates.length < 2) return;\n\n const anchorLeftHash = leftHash(anchorBlock, anchorPos);\n\n // Left-distinct filter: a candidate whose left predecessor matches the\n // anchor's would be discovered from the leftward position with a longer\n // match. Skip it here to avoid emitting subset matches.\n let active: PositionRef[] = [];\n for (const candidate of candidates) {\n if (candidate.block === anchorBlock && candidate.pos === anchorPos) continue;\n const cLeftHash = leftHash(candidate.block, candidate.pos);\n if (anchorLeftHash === null || cLeftHash === null || anchorLeftHash !== cLeftHash) {\n active.push(candidate);\n }\n }\n if (active.length === 0) return;\n\n let length = 1;\n while (true) {\n const nextAnchorStmt = anchorBlock.stmts[anchorPos + length];\n const anchorCanExtend = nextAnchorStmt !== undefined;\n const next: PositionRef[] = [];\n if (anchorCanExtend) {\n const targetHash = nextAnchorStmt.hash;\n for (const candidate of active) {\n const nextCandidateStmt = candidate.block.stmts[candidate.pos + length];\n if (nextCandidateStmt === undefined) continue;\n if (nextCandidateStmt.hash !== targetHash) continue;\n next.push(candidate);\n }\n }\n\n const shrank = next.length < active.length;\n if ((shrank || !anchorCanExtend) && length >= minStatementCount) {\n const participants: PositionRef[] = [{ block: anchorBlock, pos: anchorPos }, ...active];\n const key = matchKey(participants, length);\n if (!recorded.has(key)) {\n recorded.set(key, { participants, length });\n }\n }\n\n if (!anchorCanExtend || next.length === 0) break;\n active = next;\n length++;\n }\n }\n}\n\nfunction leftHash(block: BlockData, pos: number): string | null {\n if (pos === 0) return null;\n const prev = block.stmts[pos - 1];\n if (prev === undefined) return null;\n return prev.hash;\n}\n\nfunction materialize(match: RecordedMatch, minNormalizedBodyLength: number): MaximalMatch | null {\n const first = match.participants[0];\n if (first === undefined) return null;\n\n let normalizedBodyLength = 0;\n for (let k = 0; k < match.length; k++) {\n const stmt = first.block.stmts[first.pos + k];\n if (stmt === undefined) return null;\n normalizedBodyLength += stmt.normalizedLength;\n }\n if (normalizedBodyLength < minNormalizedBodyLength) return null;\n\n const participants: MaximalMatchParticipant[] = [];\n for (const p of match.participants) {\n const start = p.block.stmts[p.pos];\n const last = p.block.stmts[p.pos + match.length - 1];\n if (start === undefined || last === undefined) return null;\n participants.push({\n file: p.block.file,\n line: start.line,\n column: start.column,\n endLine: last.endLine,\n statementCount: match.length,\n });\n }\n return { participants, statementCount: match.length, normalizedBodyLength };\n}\n\nfunction matchKey(participants: PositionRef[], length: number): string {\n const parts: string[] = [];\n for (const p of participants) {\n const stmt = p.block.stmts[p.pos];\n if (stmt === undefined) continue;\n parts.push(`${p.block.file}:${stmt.line}`);\n }\n parts.sort();\n return `${parts.join(\"|\")}#${length}`;\n}\n\nfunction isStrictParticipantSubset(small: PositionRef[], big: PositionRef[]): boolean {\n if (small.length >= big.length) return false;\n const bigSet = new Set<string>();\n for (const p of big) bigSet.add(`${p.block.file}:${p.pos}`);\n for (const p of small) {\n if (!bigSet.has(`${p.block.file}:${p.pos}`)) return false;\n }\n return true;\n}\n","import type * as ts from \"typescript\";\nimport { hashTypeShape } from \"../utils/hash.ts\";\nimport { BaseRegistry } from \"./base-registry.ts\";\n\nexport interface InlineParamTypeEntry {\n file: string;\n line: number;\n column: number;\n hash: string;\n typeText: string;\n node: ts.Node;\n}\n\nexport class InlineParamTypeRegistry extends BaseRegistry<InlineParamTypeEntry> {\n add(file: string, line: number, column: number, typeNode: ts.TypeLiteralNode, sourceFile: ts.SourceFile): void {\n const hash = hashTypeShape(typeNode, sourceFile);\n const typeText = typeNode.getText(sourceFile).replace(/\\s+/g, \" \").trim();\n this.addEntry({ file, line, column, hash, typeText, node: typeNode }, hash);\n }\n}\n","import * as ts from \"typescript\";\nimport type { Diagnostic, FixEdit, SemanticServices, TSRule, TSVisitContext } from \"../rules/types.ts\";\nimport { isNullableType, isFromNodeModules } from \"./utils.ts\";\n\nexport function buildContext(\n rule: TSRule,\n sourceFile: ts.SourceFile,\n semantics: SemanticServices,\n source: string,\n filename: string,\n diagnostics: Diagnostic[],\n compilerOptions: ts.CompilerOptions,\n): TSVisitContext {\n const checker = semantics.checker;\n return {\n filename,\n source,\n sourceFile,\n checker,\n semantics,\n compilerOptions,\n\n report(node: ts.Node, message?: string, fix?: FixEdit) {\n const { line, character } = ts.getLineAndCharacterOfPosition(sourceFile, node.getStart(sourceFile));\n diagnostics.push({\n ruleId: rule.id,\n severity: rule.severity,\n message: message ?? rule.message,\n file: filename,\n line: line + 1,\n column: character + 1,\n ...(fix !== undefined ? { fix } : {}),\n });\n },\n\n reportAtOffset(offset: number, message?: string) {\n const { line, character } = ts.getLineAndCharacterOfPosition(sourceFile, offset);\n diagnostics.push({\n ruleId: rule.id,\n severity: rule.severity,\n message: message ?? rule.message,\n file: filename,\n line: line + 1,\n column: character + 1,\n });\n },\n\n isNullable(node: ts.Node): boolean {\n const type = semantics.typeAtLocation(node);\n return isNullableType(checker, type);\n },\n\n isExternal(node: ts.Node): boolean {\n const type = semantics.typeAtLocation(node);\n const symbol = type.getSymbol();\n if (!symbol) return false;\n const declarations = symbol.getDeclarations();\n if (!declarations || declarations.length === 0) return false;\n return declarations.some((d) => isFromNodeModules(d));\n },\n };\n}\n","import type * as ts from \"typescript\";\nimport type { SemanticServices } from \"../rules/types.ts\";\n\nexport class SemanticCache implements SemanticServices {\n private readonly typesAtLocation = new WeakMap<ts.Node, ts.Type>();\n private readonly symbolsAtLocation = new WeakMap<ts.Node, ts.Symbol | null>();\n private readonly resolvedSignatures = new WeakMap<ts.CallLikeExpression, ts.Signature | null>();\n private readonly typesFromTypeNodes = new WeakMap<ts.TypeNode, ts.Type>();\n private readonly contextualTypes = new WeakMap<ts.Expression, ts.Type | null>();\n private readonly typesOfSymbols = new WeakMap<ts.Symbol, WeakMap<ts.Node, ts.Type>>();\n private readonly aliasedSymbols = new WeakMap<ts.Symbol, ts.Symbol>();\n private readonly awaitedTypes = new WeakMap<ts.Type, ts.Type | null>();\n private readonly apparentTypes = new WeakMap<ts.Type, ts.Type>();\n private readonly arrayTypes = new WeakMap<ts.Type, boolean>();\n private readonly tupleTypes = new WeakMap<ts.Type, boolean>();\n private readonly assignability = new WeakMap<ts.Type, WeakMap<ts.Type, boolean>>();\n\n constructor(readonly checker: ts.TypeChecker) {}\n\n typeAtLocation(node: ts.Node): ts.Type {\n const cached = this.typesAtLocation.get(node);\n if (cached !== undefined) return cached;\n const type = this.checker.getTypeAtLocation(node);\n this.typesAtLocation.set(node, type);\n return type;\n }\n\n symbolAtLocation(node: ts.Node): ts.Symbol | undefined {\n const cached = this.symbolsAtLocation.get(node);\n if (cached !== undefined) return cached ?? undefined;\n const symbol = this.checker.getSymbolAtLocation(node);\n this.symbolsAtLocation.set(node, symbol ?? null);\n return symbol;\n }\n\n resolvedSignature(node: ts.CallLikeExpression): ts.Signature | undefined {\n const cached = this.resolvedSignatures.get(node);\n if (cached !== undefined) return cached ?? undefined;\n const signature = this.checker.getResolvedSignature(node);\n this.resolvedSignatures.set(node, signature ?? null);\n return signature;\n }\n\n typeFromTypeNode(node: ts.TypeNode): ts.Type {\n const cached = this.typesFromTypeNodes.get(node);\n if (cached !== undefined) return cached;\n const type = this.checker.getTypeFromTypeNode(node);\n this.typesFromTypeNodes.set(node, type);\n return type;\n }\n\n contextualType(node: ts.Expression): ts.Type | undefined {\n const cached = this.contextualTypes.get(node);\n if (cached !== undefined) return cached ?? undefined;\n const type = this.checker.getContextualType(node);\n this.contextualTypes.set(node, type ?? null);\n return type;\n }\n\n typeOfSymbolAtLocation(symbol: ts.Symbol, node: ts.Node): ts.Type {\n let byNode = this.typesOfSymbols.get(symbol);\n if (byNode === undefined) {\n byNode = new WeakMap();\n this.typesOfSymbols.set(symbol, byNode);\n }\n const cached = byNode.get(node);\n if (cached !== undefined) return cached;\n const type = this.checker.getTypeOfSymbolAtLocation(symbol, node);\n byNode.set(node, type);\n return type;\n }\n\n aliasedSymbol(symbol: ts.Symbol): ts.Symbol {\n const cached = this.aliasedSymbols.get(symbol);\n if (cached !== undefined) return cached;\n const aliased = this.checker.getAliasedSymbol(symbol);\n this.aliasedSymbols.set(symbol, aliased);\n return aliased;\n }\n\n awaitedType(type: ts.Type): ts.Type | undefined {\n const cached = this.awaitedTypes.get(type);\n if (cached !== undefined) return cached ?? undefined;\n const awaited = this.checker.getAwaitedType(type);\n this.awaitedTypes.set(type, awaited ?? null);\n return awaited;\n }\n\n apparentType(type: ts.Type): ts.Type {\n const cached = this.apparentTypes.get(type);\n if (cached !== undefined) return cached;\n const apparent = this.checker.getApparentType(type);\n this.apparentTypes.set(type, apparent);\n return apparent;\n }\n\n isArrayType(type: ts.Type): boolean {\n const cached = this.arrayTypes.get(type);\n if (cached !== undefined) return cached;\n const result = this.checker.isArrayType(type);\n this.arrayTypes.set(type, result);\n return result;\n }\n\n isTupleType(type: ts.Type): boolean {\n const cached = this.tupleTypes.get(type);\n if (cached !== undefined) return cached;\n const result = this.checker.isTupleType(type);\n this.tupleTypes.set(type, result);\n return result;\n }\n\n isTypeAssignableTo(source: ts.Type, target: ts.Type): boolean {\n let byTarget = this.assignability.get(source);\n if (byTarget === undefined) {\n byTarget = new WeakMap();\n this.assignability.set(source, byTarget);\n }\n const cached = byTarget.get(target);\n if (cached !== undefined) return cached;\n const result = this.checker.isTypeAssignableTo(source, target);\n byTarget.set(target, result);\n return result;\n }\n}\n","import * as ts from \"typescript\";\nimport { createHash } from \"node:crypto\";\nimport { TypeRegistry } from \"./type-registry.ts\";\nimport { FunctionRegistry, type FunctionEntry, type ParamInfo } from \"./function-registry.ts\";\nimport { ConstantRegistry } from \"./constant-registry.ts\";\nimport {\n analyzeFunctionBody,\n hashText,\n normalizeText,\n stripCommentsAndWhitespace,\n type FunctionBodyAnalysis,\n} from \"../utils/hash.ts\";\nimport { StatementSequenceRegistry, type StatementInBlock } from \"./statement-sequence-registry.ts\";\nimport { InlineParamTypeRegistry } from \"./inline-type-registry.ts\";\nimport type { Diagnostic, FixEdit, ProjectIndexNeed, SemanticServices, TSRule, TSVisitContext } from \"../rules/types.ts\";\nimport { buildContext } from \"../typecheck/walk.ts\";\nimport { isInlineParamType } from \"../typecheck/utils.ts\";\nimport { SemanticCache } from \"../typecheck/semantic-cache.ts\";\n\nexport interface CommentInfo {\n type: \"Line\" | \"Block\";\n value: string;\n start: number;\n end: number;\n}\n\nconst commentCache = new WeakMap<ts.SourceFile, CommentInfo[]>();\n\nexport interface ProjectIndex {\n types: TypeRegistry;\n functions: FunctionRegistry;\n constants: ConstantRegistry;\n callSites: CallSite[];\n imports: ImportEntry[];\n files: Map<string, { source: string; sourceFile: ts.SourceFile }>;\n /** Whitespace-normalized file content hash -> list of file paths */\n fileHashes: Map<string, string[]>;\n statementSequences: StatementSequenceRegistry;\n inlineParamTypes: InlineParamTypeRegistry;\n}\n\nexport interface CollectProjectOptions {\n /**\n * Restrict registry/index collection to these files while keeping the full\n * ts.Program available for type resolution.\n */\n collectFiles?: Set<string>;\n needs?: ProjectIndexNeeds;\n index?: ProjectIndex;\n}\n\nexport interface SyntaxFileAnalysis {\n diagnostics: Diagnostic[];\n}\n\nexport interface CollectSourceTextOptions {\n index?: ProjectIndex;\n needs?: ProjectIndexNeeds;\n retainFile?: boolean;\n}\n\nexport interface CallSite {\n calleeName: string;\n file: string;\n line: number;\n argCount: number;\n node: ts.CallExpression;\n symbol?: ts.Symbol;\n resolvedDeclaration?: ts.SignatureDeclaration | ts.JSDocSignature;\n}\n\nexport interface ImportEntry {\n file: string;\n localName: string;\n importedName: string;\n source: string;\n /**\n * The module specifier resolved to a project source file via the checker.\n * Handles tsconfig path aliases and workspace packages that textual\n * resolution cannot. Absent in source-only mode or when the specifier\n * resolves outside the program (npm package, declaration file).\n */\n resolvedFile?: string;\n}\n\ninterface RuleContext {\n rule: TSRule;\n ctx: TSVisitContext;\n}\n\ninterface RuleDispatch {\n byKind: Map<ts.SyntaxKind, RuleContext[]>;\n global: RuleContext[];\n}\n\nexport type ProjectIndexNeeds = ReadonlySet<ProjectIndexNeed>;\n\nconst ALL_PROJECT_INDEX_NEEDS: ProjectIndexNeeds = new Set<ProjectIndexNeed>([\n \"files\",\n \"types\",\n \"functions\",\n \"functionSymbols\",\n \"constants\",\n \"callSites\",\n \"callSiteSymbols\",\n \"overloadCallSignatures\",\n \"imports\",\n \"fileHashes\",\n \"statementSequences\",\n \"inlineParamTypes\",\n]);\n\nexport function createProjectIndex(): ProjectIndex {\n return {\n types: new TypeRegistry(),\n functions: new FunctionRegistry(),\n constants: new ConstantRegistry(),\n callSites: [],\n imports: [],\n files: new Map(),\n fileHashes: new Map(),\n statementSequences: new StatementSequenceRegistry(),\n inlineParamTypes: new InlineParamTypeRegistry(),\n };\n}\n\nexport function collectSourceText(\n file: string,\n source: string,\n tsRules: TSRule[],\n options: CollectSourceTextOptions = {},\n): SyntaxFileAnalysis {\n const sourceFile = ts.createSourceFile(file, source, ts.ScriptTarget.Latest, true, scriptKindForFile(file));\n const diagnostics: Diagnostic[] = [];\n const semantics = buildUnavailableSemantics(file);\n const needs = options.needs ?? new Set<ProjectIndexNeed>();\n const index = options.index;\n\n if (index !== undefined) {\n if (needs.has(\"fileHashes\")) addFileHash(index, file, source);\n }\n\n const ruleDispatch = buildRuleDispatch(tsRules.map((rule) => ({\n rule,\n ctx: buildSyntaxContext(rule, sourceFile, source, file, diagnostics),\n })));\n\n function visit(node: ts.Node): void {\n visitRuleContexts(node, ruleDispatch);\n if (index !== undefined && needs.size > 0) {\n collectIndexNode(node, file, sourceFile, semantics, index, needs);\n }\n ts.forEachChild(node, visit);\n }\n visit(sourceFile);\n if (index !== undefined && options.retainFile !== false) {\n index.files.set(file, { source, sourceFile });\n }\n\n return { diagnostics };\n}\n\nfunction scriptKindForFile(file: string): ts.ScriptKind {\n if (file.endsWith(\".tsx\")) return ts.ScriptKind.TSX;\n if (file.endsWith(\".jsx\")) return ts.ScriptKind.JSX;\n if (file.endsWith(\".js\") || file.endsWith(\".mjs\") || file.endsWith(\".cjs\")) return ts.ScriptKind.JS;\n if (file.endsWith(\".json\")) return ts.ScriptKind.JSON;\n return ts.ScriptKind.TS;\n}\n\nfunction buildSyntaxContext(\n rule: TSRule,\n sourceFile: ts.SourceFile,\n source: string,\n filename: string,\n diagnostics: Diagnostic[],\n): TSVisitContext {\n const checker = buildUnavailableChecker(`rule \"${rule.id}\"`);\n const semantics = buildUnavailableSemantics(`rule \"${rule.id}\"`);\n\n return {\n filename,\n source,\n sourceFile,\n checker,\n semantics,\n compilerOptions: {},\n\n report(node: ts.Node, message?: string, fix?: FixEdit) {\n const { line, character } = ts.getLineAndCharacterOfPosition(sourceFile, node.getStart(sourceFile));\n diagnostics.push({\n ruleId: rule.id,\n severity: rule.severity,\n message: message ?? rule.message,\n file: filename,\n line: line + 1,\n column: character + 1,\n ...(fix !== undefined ? { fix } : {}),\n });\n },\n\n reportAtOffset(offset: number, message?: string) {\n const { line, character } = ts.getLineAndCharacterOfPosition(sourceFile, offset);\n diagnostics.push({\n ruleId: rule.id,\n severity: rule.severity,\n message: message ?? rule.message,\n file: filename,\n line: line + 1,\n column: character + 1,\n });\n },\n\n isNullable: unavailableTypeInfo,\n isExternal: unavailableTypeInfo,\n };\n}\n\nfunction buildUnavailableChecker(label: string): ts.TypeChecker {\n return new Proxy({}, {\n get(): never {\n throw new Error(`${label} requires type checking and cannot run in source-only mode.`);\n },\n }) as ts.TypeChecker;\n}\n\nfunction unavailableTypeInfo(): never {\n throw new Error(\"This rule requires type checking and cannot run in source-only mode.\");\n}\n\nfunction buildUnavailableSemantics(label: string): SemanticServices {\n const checker = buildUnavailableChecker(label);\n return {\n checker,\n typeAtLocation: unavailableTypeInfo,\n symbolAtLocation: unavailableTypeInfo,\n resolvedSignature: unavailableTypeInfo,\n typeFromTypeNode: unavailableTypeInfo,\n contextualType: unavailableTypeInfo,\n typeOfSymbolAtLocation: unavailableTypeInfo,\n aliasedSymbol: unavailableTypeInfo,\n awaitedType: unavailableTypeInfo,\n apparentType: unavailableTypeInfo,\n isArrayType: unavailableTypeInfo,\n isTupleType: unavailableTypeInfo,\n isTypeAssignableTo: unavailableTypeInfo,\n };\n}\n\nexport function collectProject(\n program: ts.Program,\n tsRules?: TSRule[],\n allowedFiles?: Set<string>,\n options: CollectProjectOptions = {},\n): { index: ProjectIndex; diagnostics: Diagnostic[] } {\n const index = options.index ?? createProjectIndex();\n const needs = options.needs ?? ALL_PROJECT_INDEX_NEEDS;\n const checker = program.getTypeChecker();\n const compilerOptions = program.getCompilerOptions();\n const semantics = new SemanticCache(checker);\n const diagnostics: Diagnostic[] = [];\n const overloadCalleeNames = needs.has(\"overloadCallSignatures\")\n ? collectOverloadCalleeNames(program, options.collectFiles ?? allowedFiles)\n : undefined;\n\n for (const sourceFile of program.getSourceFiles()) {\n const file = sourceFile.fileName;\n if (sourceFile.isDeclarationFile) continue;\n if (file.includes(\"node_modules\")) continue;\n\n const isReportable = !allowedFiles || allowedFiles.has(file);\n const shouldCollect = options.collectFiles === undefined || options.collectFiles.has(file);\n if (!isReportable && !shouldCollect) continue;\n const source = sourceFile.getFullText();\n\n if (isReportable || (shouldCollect && needs.has(\"files\"))) {\n index.files.set(file, { source, sourceFile });\n }\n if (shouldCollect && needs.has(\"fileHashes\")) {\n addFileHash(index, file, source);\n }\n\n const ruleDispatch = isReportable\n ? buildRuleDispatch(tsRules?.map((rule) => ({\n rule,\n ctx: buildContext(rule, sourceFile, semantics, source, file, diagnostics, compilerOptions),\n })) ?? [])\n : undefined;\n\n function visit(node: ts.Node): void {\n if (shouldCollect) {\n collectIndexNode(node, file, sourceFile, semantics, index, needs, overloadCalleeNames, checker);\n }\n if (ruleDispatch) {\n visitRuleContexts(node, ruleDispatch);\n }\n ts.forEachChild(node, visit);\n }\n visit(sourceFile);\n }\n\n return { index, diagnostics };\n}\n\nfunction collectIndexNode(\n node: ts.Node,\n file: string,\n sourceFile: ts.SourceFile,\n semantics: SemanticServices,\n index: ProjectIndex,\n needs: ProjectIndexNeeds,\n overloadCalleeNames?: Set<string>,\n /** Absent in source-only mode; module specifiers stay textually resolved. */\n checker?: ts.TypeChecker,\n): void {\n switch (node.kind) {\n case ts.SyntaxKind.TypeAliasDeclaration:\n case ts.SyntaxKind.InterfaceDeclaration:\n if (!needs.has(\"types\")) return;\n collectTypes(node, file, sourceFile, index.types);\n return;\n case ts.SyntaxKind.VariableStatement:\n if (needs.has(\"functions\")) {\n collectFunctions(node, file, sourceFile, semantics, index.functions, needs.has(\"functionSymbols\"));\n }\n if (needs.has(\"constants\")) {\n collectConstants(node, file, sourceFile, index.constants);\n }\n return;\n case ts.SyntaxKind.FunctionDeclaration:\n case ts.SyntaxKind.PropertyAssignment:\n case ts.SyntaxKind.ArrowFunction:\n case ts.SyntaxKind.FunctionExpression:\n case ts.SyntaxKind.MethodDeclaration:\n if (needs.has(\"functions\")) {\n collectFunctions(node, file, sourceFile, semantics, index.functions, needs.has(\"functionSymbols\"));\n }\n return;\n case ts.SyntaxKind.CallExpression:\n if (!needs.has(\"callSites\")) return;\n collectCallSites(\n node,\n file,\n sourceFile,\n semantics,\n index.callSites,\n needs.has(\"callSiteSymbols\"),\n needs.has(\"overloadCallSignatures\"),\n overloadCalleeNames,\n );\n return;\n case ts.SyntaxKind.Block:\n if (!needs.has(\"statementSequences\")) return;\n collectStatementSequences(node, file, sourceFile, index.statementSequences);\n return;\n case ts.SyntaxKind.TypeLiteral:\n if (!needs.has(\"inlineParamTypes\")) return;\n collectInlineParamTypes(node, file, sourceFile, index.inlineParamTypes);\n return;\n case ts.SyntaxKind.ImportDeclaration:\n case ts.SyntaxKind.ExportDeclaration:\n if (!needs.has(\"imports\")) return;\n collectImports(node, file, index.imports, checker);\n return;\n }\n}\n\nfunction addFileHash(index: ProjectIndex, file: string, source: string): void {\n const normalized = source.replace(/\\s+/g, \" \").trim();\n const hash = createHash(\"sha256\").update(normalized).digest(\"hex\").slice(0, 16);\n let list = index.fileHashes.get(hash);\n if (list === undefined) {\n list = [];\n index.fileHashes.set(hash, list);\n }\n if (!list.includes(file)) list.push(file);\n}\n\nfunction buildRuleDispatch(ruleContexts: RuleContext[]): RuleDispatch {\n const byKind = new Map<ts.SyntaxKind, RuleContext[]>();\n const global: RuleContext[] = [];\n\n for (const ruleContext of ruleContexts) {\n const kinds = ruleContext.rule.syntaxKinds;\n if (kinds === undefined) {\n global.push(ruleContext);\n continue;\n }\n for (const kind of kinds) {\n let contexts = byKind.get(kind);\n if (contexts === undefined) {\n contexts = [];\n byKind.set(kind, contexts);\n }\n contexts.push(ruleContext);\n }\n }\n\n return { byKind, global };\n}\n\nfunction visitRuleContexts(node: ts.Node, ruleDispatch: RuleDispatch): void {\n const contexts = ruleDispatch.byKind.get(node.kind);\n if (contexts !== undefined) {\n for (const { rule, ctx } of contexts) {\n rule.visit(node, ctx);\n }\n }\n for (const { rule, ctx } of ruleDispatch.global) {\n rule.visit(node, ctx);\n }\n}\n\nfunction collectOverloadCalleeNames(\n program: ts.Program,\n collectFiles: Set<string> | undefined,\n): Set<string> {\n const overloaded = new Set<string>();\n\n for (const sourceFile of program.getSourceFiles()) {\n if (sourceFile.isDeclarationFile) continue;\n if (sourceFile.fileName.includes(\"node_modules\")) continue;\n if (collectFiles !== undefined && !collectFiles.has(sourceFile.fileName)) continue;\n\n const implementations = new Set<string>();\n const signatures: string[] = [];\n\n function visit(node: ts.Node): void {\n if ((ts.isFunctionDeclaration(node) || ts.isMethodDeclaration(node)) && node.name !== undefined) {\n const name = node.name.getText(sourceFile);\n if (node.body === undefined) {\n signatures.push(name);\n } else {\n implementations.add(name);\n }\n }\n ts.forEachChild(node, visit);\n }\n\n visit(sourceFile);\n\n for (const name of signatures) {\n if (implementations.has(name)) overloaded.add(name);\n }\n }\n\n return overloaded;\n}\n\nfunction hasNonPublicModifier(node: ts.Node): boolean {\n const mods = modifiersOf(node);\n return mods.some(\n (m) => m.kind === ts.SyntaxKind.PrivateKeyword || m.kind === ts.SyntaxKind.ProtectedKeyword,\n );\n}\n\nfunction isExported(node: ts.Node): boolean {\n return modifiersOf(node).some((m) => m.kind === ts.SyntaxKind.ExportKeyword);\n}\n\nfunction isExportedAsDefault(node: ts.Node): boolean {\n const mods = modifiersOf(node);\n const hasExport = mods.some((m) => m.kind === ts.SyntaxKind.ExportKeyword);\n const hasDefault = mods.some((m) => m.kind === ts.SyntaxKind.DefaultKeyword);\n return hasExport && hasDefault;\n}\n\nfunction modifiersOf(node: ts.Node): readonly ts.Modifier[] {\n if (!ts.canHaveModifiers(node)) return [];\n const mods = ts.getModifiers(node);\n return mods ?? [];\n}\n\nfunction collectTypes(node: ts.Node, file: string, sourceFile: ts.SourceFile, registry: TypeRegistry): void {\n if (ts.isTypeAliasDeclaration(node)) {\n const { line, column } = lineColumnAt(sourceFile, node);\n registry.add(node.name.text, file, line, column, node.type, sourceFile, isExported(node));\n }\n if (ts.isInterfaceDeclaration(node)) {\n const { line, column } = lineColumnAt(sourceFile, node);\n registry.add(node.name.text, file, line, column, node, sourceFile, isExported(node));\n }\n}\n\nfunction lineColumnAt(sourceFile: ts.SourceFile, node: ts.Node): { line: number; column: number } {\n const pos = ts.getLineAndCharacterOfPosition(sourceFile, node.getStart(sourceFile));\n return { line: pos.line + 1, column: pos.character + 1 };\n}\n\nfunction isConstantValue(node: ts.Node): boolean {\n if (ts.isStringLiteral(node)) return true;\n if (ts.isNumericLiteral(node)) return true;\n if (ts.isNoSubstitutionTemplateLiteral(node)) return true;\n if (ts.isPrefixUnaryExpression(node)) return isConstantValue(node.operand);\n if (ts.isBinaryExpression(node)) return isConstantValue(node.left) && isConstantValue(node.right);\n return false;\n}\n\nfunction collectConstants(node: ts.Node, file: string, sourceFile: ts.SourceFile, registry: ConstantRegistry): void {\n if (!ts.isVariableStatement(node)) return;\n if (!(node.declarationList.flags & ts.NodeFlags.Const)) return;\n const exported = isExported(node);\n for (const decl of node.declarationList.declarations) {\n if (!decl.initializer || !ts.isIdentifier(decl.name)) continue;\n if (!isConstantValue(decl.initializer)) continue;\n const valueText = decl.initializer.getText(sourceFile).replace(/\\s+/g, \" \").trim();\n const valueHash = createHash(\"sha256\").update(valueText).digest(\"hex\").slice(0, 16);\n const { line, column } = lineColumnAt(sourceFile, decl);\n registry.add({ name: decl.name.text, file, line, column, valueHash, valueText, exported });\n }\n}\n\nfunction buildFunctionEntry(\n body: ts.Node,\n parameters: ts.NodeArray<ts.ParameterDeclaration>,\n sourceFile: ts.SourceFile,\n file: string,\n lineNode: ts.Node,\n name: string,\n extra: Partial<Pick<FunctionEntry, \"exported\" | \"exportedAsDefault\" | \"symbol\" | \"className\" | \"implementsInterface\" | \"node\">>,\n bodyAnalysis?: FunctionBodyAnalysis,\n): FunctionEntry {\n const { line, column } = lineColumnAt(sourceFile, lineNode);\n const params = extractParams(parameters, sourceFile);\n const paramNames = params.map((p) => p.name);\n const analysis = bodyAnalysis ?? analyzeFunctionBody(body, sourceFile, paramNames);\n return {\n name,\n file,\n line,\n column,\n hash: analysis.hash,\n normalizedHash: analysis.normalizedHash,\n params,\n node: extra.node ?? body,\n exported: extra.exported ?? false,\n bodyLength: analysis.bodyLength,\n normalizedBodyLength: analysis.normalizedBodyLength,\n ...extra,\n };\n}\n\nfunction collectFunctions(\n node: ts.Node,\n file: string,\n sourceFile: ts.SourceFile,\n semantics: SemanticServices,\n registry: FunctionRegistry,\n resolveSymbols: boolean,\n): void {\n if (ts.isFunctionDeclaration(node) && node.name && node.body) {\n registry.add(buildFunctionEntry(node.body, node.parameters, sourceFile, file, node, node.name.text, {\n exported: isExported(node) || isExportedAsDefault(node),\n exportedAsDefault: isExportedAsDefault(node),\n symbol: resolveSymbols ? semantics.symbolAtLocation(node.name) : undefined,\n node,\n }));\n }\n\n // Arrow functions and function expressions assigned to const: const foo = (...) => { ... } / const foo = function() { ... }\n if (ts.isVariableStatement(node)) {\n const exported = isExported(node);\n for (const decl of node.declarationList.declarations) {\n if (decl.initializer && ts.isArrowFunction(decl.initializer) && ts.isIdentifier(decl.name)) {\n const arrow = decl.initializer;\n registry.add(buildFunctionEntry(arrow.body, arrow.parameters, sourceFile, file, decl, decl.name.text, {\n exported, symbol: resolveSymbols ? semantics.symbolAtLocation(decl.name) : undefined, node: arrow,\n }));\n }\n if (decl.initializer && ts.isFunctionExpression(decl.initializer) && ts.isIdentifier(decl.name)) {\n const fn = decl.initializer;\n if (fn.body) {\n registry.add(buildFunctionEntry(fn.body, fn.parameters, sourceFile, file, decl, decl.name.text, {\n exported, symbol: resolveSymbols ? semantics.symbolAtLocation(decl.name) : undefined, node: fn,\n }));\n }\n }\n }\n }\n\n // Object property functions: { key: (...) => { ... } } or { key: function(...) { ... } }\n if (ts.isPropertyAssignment(node) && (ts.isIdentifier(node.name) || ts.isStringLiteral(node.name))) {\n const init = node.initializer;\n const propName = node.name.text;\n if (ts.isArrowFunction(init)) {\n registry.add(buildFunctionEntry(init.body, init.parameters, sourceFile, file, node, propName, { node: init }));\n }\n if (ts.isFunctionExpression(init) && init.body) {\n registry.add(buildFunctionEntry(init.body, init.parameters, sourceFile, file, node, propName, { node: init }));\n }\n }\n\n // Anonymous/nested functions (catch-all for ArrowFunction/FunctionExpression not already collected)\n if (ts.isArrowFunction(node) || ts.isFunctionExpression(node)) {\n const parent = node.parent;\n // Skip if already collected by VariableStatement path\n if (ts.isVariableDeclaration(parent) && ts.isIdentifier(parent.name)) {\n // Already collected above\n }\n // Skip if already collected by PropertyAssignment path\n else if (ts.isPropertyAssignment(parent)) {\n // Already collected above\n }\n else {\n const body = node.body;\n const MIN_ANON_BODY = 64;\n const params = extractParams(node.parameters, sourceFile);\n const bodyAnalysis = analyzeFunctionBody(body, sourceFile, params.map((p) => p.name));\n if (bodyAnalysis.bodyLength >= MIN_ANON_BODY) {\n const name = deriveAnonymousName(node, sourceFile);\n registry.add(buildFunctionEntry(body, node.parameters, sourceFile, file, node, name, { node }, bodyAnalysis));\n }\n }\n }\n\n // Class methods\n if (ts.isMethodDeclaration(node) && node.body && ts.isIdentifier(node.name)) {\n const parent = node.parent;\n if (ts.isClassDeclaration(parent)) {\n if (hasNonPublicModifier(node)) return;\n const className = parent.name ? parent.name.text : \"<anonymous>\";\n const name = `${className}.${node.name.text}`;\n const implementsInterface = parent.heritageClauses?.some(\n (c) => c.token === ts.SyntaxKind.ImplementsKeyword,\n ) ?? false;\n registry.add(buildFunctionEntry(node.body, node.parameters, sourceFile, file, node, name, {\n exported: isExported(parent),\n symbol: resolveSymbols ? semantics.symbolAtLocation(node.name) : undefined,\n node,\n className,\n implementsInterface,\n }));\n }\n }\n}\n\nfunction extractParams(parameters: ts.NodeArray<ts.ParameterDeclaration>, sourceFile: ts.SourceFile): ParamInfo[] {\n return parameters.map((p) => {\n const name = p.name.getText(sourceFile);\n const optional = p.questionToken !== undefined;\n const hasDefault = p.initializer !== undefined;\n const typeText = p.type ? p.type.getText(sourceFile) : null;\n return { name, optional, hasDefault, typeText };\n });\n}\n\nfunction deriveAnonymousName(node: ts.ArrowFunction | ts.FunctionExpression, sourceFile: ts.SourceFile): string {\n const parent = node.parent;\n const line = ts.getLineAndCharacterOfPosition(sourceFile, node.getStart(sourceFile)).line + 1;\n\n // Parent is CallExpression — check if grandparent is a PropertyAssignment with a name\n if (ts.isCallExpression(parent)) {\n const grandparent = parent.parent;\n if (ts.isPropertyAssignment(grandparent) && ts.isIdentifier(grandparent.name)) {\n return grandparent.name.text;\n }\n // Callee name + arg index\n let calleeName: string | null = null;\n if (ts.isIdentifier(parent.expression)) {\n calleeName = parent.expression.text;\n } else if (ts.isPropertyAccessExpression(parent.expression)) {\n calleeName = parent.expression.name.text;\n }\n if (calleeName) {\n const argIndex = parent.arguments.indexOf(node as ts.Expression);\n if (argIndex >= 0) return `${calleeName}.$arg${argIndex}`;\n }\n }\n\n return `<anonymous>:${line}`;\n}\n\nfunction collectImports(node: ts.Node, file: string, imports: ImportEntry[], checker: ts.TypeChecker | undefined): void {\n if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier)) {\n const moduleSource = node.moduleSpecifier.text;\n const clause = node.importClause;\n if (!clause) return;\n const resolvedFile = resolveModuleSpecifier(node.moduleSpecifier, checker);\n\n // Default import\n if (clause.name) {\n imports.push({\n file,\n localName: clause.name.text,\n importedName: \"default\",\n source: moduleSource,\n resolvedFile,\n });\n }\n\n // Named imports\n if (clause.namedBindings && ts.isNamedImports(clause.namedBindings)) {\n for (const el of clause.namedBindings.elements) {\n imports.push({\n file,\n localName: el.name.text,\n importedName: el.propertyName ? el.propertyName.text : el.name.text,\n source: moduleSource,\n resolvedFile,\n });\n }\n }\n\n // Namespace import: import * as ns from \"./mod\" — every export reachable\n if (clause.namedBindings && ts.isNamespaceImport(clause.namedBindings)) {\n imports.push({\n file,\n localName: clause.namedBindings.name.text,\n importedName: \"*\",\n source: moduleSource,\n resolvedFile,\n });\n }\n }\n\n // Re-exports: export { x } from \"./mod\"\n if (ts.isExportDeclaration(node) && node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier)) {\n const moduleSource = node.moduleSpecifier.text;\n const resolvedFile = resolveModuleSpecifier(node.moduleSpecifier, checker);\n if (node.exportClause && ts.isNamedExports(node.exportClause)) {\n for (const el of node.exportClause.elements) {\n imports.push({\n file,\n localName: el.name.text,\n importedName: el.propertyName ? el.propertyName.text : el.name.text,\n source: moduleSource,\n resolvedFile,\n });\n }\n }\n // export * from \"./mod\" — every export reachable through the barrel\n if (!node.exportClause) {\n imports.push({ file, localName: \"*\", importedName: \"*\", source: moduleSource, resolvedFile });\n }\n }\n}\n\n/**\n * Resolve a module specifier to its source file through the program's own\n * module resolution (path aliases, baseUrl, workspace packages included).\n * Declaration files are excluded: an import that lands in `.d.ts` points at\n * built output, not at a project source file.\n */\nfunction resolveModuleSpecifier(specifier: ts.StringLiteral, checker: ts.TypeChecker | undefined): string | undefined {\n if (checker === undefined) return undefined;\n const moduleSymbol = checker.getSymbolAtLocation(specifier);\n const declaration = moduleSymbol?.valueDeclaration ?? moduleSymbol?.declarations?.[0];\n if (declaration === undefined || !ts.isSourceFile(declaration)) return undefined;\n if (declaration.isDeclarationFile) return undefined;\n return declaration.fileName;\n}\n\nfunction collectStatementSequences(\n node: ts.Node,\n file: string,\n sourceFile: ts.SourceFile,\n registry: StatementSequenceRegistry,\n): void {\n if (!ts.isBlock(node)) return;\n const stmts = node.statements;\n if (stmts.length < 2) return;\n\n const collected: StatementInBlock[] = [];\n for (const stmt of stmts) {\n const raw = stmt.getText(sourceFile);\n const stripped = stripCommentsAndWhitespace(raw);\n if (stripped.length === 0) continue;\n const normalized = normalizeText(raw);\n const { line, column } = lineColumnAt(sourceFile, stmt);\n const endLine = ts.getLineAndCharacterOfPosition(sourceFile, stmt.getEnd()).line + 1;\n collected.push({\n hash: hashText(stripped),\n line,\n column,\n endLine,\n normalizedLength: normalized.length,\n });\n }\n registry.addBlock(file, collected);\n}\n\nfunction collectInlineParamTypes(\n node: ts.Node,\n file: string,\n sourceFile: ts.SourceFile,\n registry: InlineParamTypeRegistry,\n): void {\n if (!isInlineParamType(node)) return;\n const { line, column } = lineColumnAt(sourceFile, node);\n registry.add(file, line, column, node as ts.TypeLiteralNode, sourceFile);\n}\n\nfunction collectCallSites(\n node: ts.Node,\n file: string,\n sourceFile: ts.SourceFile,\n semantics: SemanticServices,\n sites: CallSite[],\n resolveSymbol: boolean,\n resolveOverloadSignatures: boolean,\n overloadCalleeNames?: Set<string>,\n): void {\n if (!ts.isCallExpression(node)) return;\n let calleeName: string | null = null;\n if (ts.isIdentifier(node.expression)) {\n calleeName = node.expression.text;\n } else if (ts.isPropertyAccessExpression(node.expression)) {\n calleeName = node.expression.name.text;\n }\n if (calleeName) {\n const line = ts.getLineAndCharacterOfPosition(sourceFile, node.getStart(sourceFile)).line + 1;\n // Resolve the symbol the call refers to (follows imports to the declaration)\n let symbol = resolveSymbol ? semantics.symbolAtLocation(node.expression) : undefined;\n if (symbol !== undefined && (symbol.flags & ts.SymbolFlags.Alias)) {\n symbol = semantics.aliasedSymbol(symbol);\n }\n const shouldResolveSignature = resolveOverloadSignatures && overloadCalleeNames?.has(calleeName) === true;\n const signature = shouldResolveSignature ? semantics.resolvedSignature(node) : undefined;\n const resolvedDeclaration = signature?.declaration;\n sites.push({\n calleeName,\n file,\n line,\n argCount: node.arguments.length,\n node,\n symbol,\n resolvedDeclaration,\n });\n }\n}\n\n/** Collect all comments from a source file. */\nexport function collectAllComments(sourceFile: ts.SourceFile): CommentInfo[] {\n const cached = commentCache.get(sourceFile);\n if (cached !== undefined) return cached;\n\n const comments: CommentInfo[] = [];\n const source = sourceFile.getFullText();\n const seen = new Set<number>();\n\n function addRanges(ranges: ts.CommentRange[] | undefined): void {\n if (!ranges) return;\n for (const r of ranges) {\n if (seen.has(r.pos)) continue;\n seen.add(r.pos);\n const isLine = r.kind === ts.SyntaxKind.SingleLineCommentTrivia;\n comments.push({\n type: isLine ? \"Line\" : \"Block\",\n value: source.slice(r.pos + 2, isLine ? r.end : r.end - 2),\n start: r.pos,\n end: r.end,\n });\n }\n }\n\n function visit(node: ts.Node): void {\n addRanges(ts.getLeadingCommentRanges(source, node.getFullStart()));\n addRanges(ts.getTrailingCommentRanges(source, node.getEnd()));\n ts.forEachChild(node, visit);\n }\n visit(sourceFile);\n\n commentCache.set(sourceFile, comments);\n return comments;\n}\n","import * as ts from \"typescript\";\nimport { dirname } from \"node:path\";\n\nexport interface ProgramGroupConfig {\n configPath: string | undefined;\n scanFiles: string[];\n /** Additional tsconfig paths whose project files should be included when expanding. */\n expandConfigPaths?: string[];\n}\n\nexport interface ProgramGroupOptions {\n expandProjectFiles?: boolean;\n cache?: ProgramBuildCache;\n}\n\nexport interface ProgramBuildCache {\n sourceFiles: Map<string, ts.SourceFile>;\n readFiles: Map<string, string | undefined>;\n fileExists: Map<string, boolean>;\n directoryExists: Map<string, boolean>;\n}\n\nconst defaultOptions: ts.CompilerOptions = {\n target: ts.ScriptTarget.ESNext,\n module: ts.ModuleKind.ESNext,\n moduleResolution: ts.ModuleResolutionKind.Bundler,\n strict: true,\n skipLibCheck: true,\n noEmit: true,\n};\n\nfunction findTsconfig(file: string): string | undefined {\n return ts.findConfigFile(dirname(file), ts.sys.fileExists, \"tsconfig.json\");\n}\n\nexport function createProgramBuildCache(): ProgramBuildCache {\n return {\n sourceFiles: new Map(),\n readFiles: new Map(),\n fileExists: new Map(),\n directoryExists: new Map(),\n };\n}\n\nfunction createProgramForConfig(\n files: string[],\n configPath: string | undefined,\n cache: ProgramBuildCache | undefined,\n): ts.Program {\n if (configPath) {\n const configFile = ts.readConfigFile(configPath, ts.sys.readFile);\n const parsed = ts.parseJsonConfigFileContent(configFile.config, ts.sys, dirname(configPath));\n const options = { ...parsed.options, skipLibCheck: true };\n return ts.createProgram({\n rootNames: files,\n options,\n host: maybeCachedCompilerHost(options, cache),\n });\n }\n return ts.createProgram({\n rootNames: files,\n options: defaultOptions,\n host: maybeCachedCompilerHost(defaultOptions, cache),\n });\n}\n\nfunction maybeCachedCompilerHost(\n options: ts.CompilerOptions,\n cache: ProgramBuildCache | undefined,\n): ts.CompilerHost | undefined {\n if (cache === undefined) return undefined;\n return createCachedCompilerHost(options, cache);\n}\n\nfunction createCachedCompilerHost(\n options: ts.CompilerOptions,\n cache: ProgramBuildCache,\n): ts.CompilerHost {\n const host = ts.createCompilerHost(options);\n const baseGetSourceFile = host.getSourceFile.bind(host);\n const baseReadFile = host.readFile.bind(host);\n const baseFileExists = host.fileExists.bind(host);\n const baseDirectoryExists = host.directoryExists?.bind(host);\n\n function cacheKey(fileName: string): string {\n return host.getCanonicalFileName(ts.sys.resolvePath(fileName));\n }\n\n host.readFile = (fileName) => {\n const key = cacheKey(fileName);\n if (cache.readFiles.has(key)) return cache.readFiles.get(key);\n const text = baseReadFile(fileName);\n cache.readFiles.set(key, text);\n return text;\n };\n\n host.fileExists = (fileName) => {\n const key = cacheKey(fileName);\n const cached = cache.fileExists.get(key);\n if (cached !== undefined) return cached;\n const exists = baseFileExists(fileName);\n cache.fileExists.set(key, exists);\n return exists;\n };\n\n if (baseDirectoryExists !== undefined) {\n host.directoryExists = (directoryName) => {\n const key = cacheKey(directoryName);\n const cached = cache.directoryExists.get(key);\n if (cached !== undefined) return cached;\n const exists = baseDirectoryExists(directoryName);\n cache.directoryExists.set(key, exists);\n return exists;\n };\n }\n\n host.getSourceFile = (\n fileName,\n languageVersionOrOptions,\n onError,\n shouldCreateNewSourceFile,\n ) => {\n if (!isStableCachedSourceFile(fileName)) {\n return baseGetSourceFile(fileName, languageVersionOrOptions, onError, shouldCreateNewSourceFile);\n }\n\n const key = sourceFileCacheKey(cacheKey(fileName), languageVersionOrOptions);\n if (!shouldCreateNewSourceFile) {\n const cached = cache.sourceFiles.get(key);\n if (cached !== undefined) return cached;\n }\n\n const sourceFile = baseGetSourceFile(fileName, languageVersionOrOptions, onError, shouldCreateNewSourceFile);\n if (sourceFile !== undefined) cache.sourceFiles.set(key, sourceFile);\n return sourceFile;\n };\n\n return host;\n}\n\nfunction isStableCachedSourceFile(_fileName: string): boolean {\n // TS binder guards on `!file.locals`, so a shared SourceFile is reused across Programs without re-binding.\n return true;\n}\n\nfunction sourceFileCacheKey(\n fileKey: string,\n languageVersionOrOptions: ts.ScriptTarget | ts.CreateSourceFileOptions,\n): string {\n if (typeof languageVersionOrOptions !== \"object\") {\n return `${fileKey}\\0${languageVersionOrOptions}\\0\\0`;\n }\n return `${fileKey}\\0${languageVersionOrOptions.languageVersion}\\0${languageVersionOrOptions.impliedNodeFormat ?? \"\"}\\0${languageVersionOrOptions.jsDocParsingMode ?? \"\"}`;\n}\n\nexport function expandProjectFiles(group: ProgramGroupConfig): string[] {\n const configs = [group.configPath, ...(group.expandConfigPaths ?? [])];\n const expanded = new Set(group.scanFiles);\n for (const cp of configs) {\n if (!cp) continue;\n const configFile = ts.readConfigFile(cp, ts.sys.readFile);\n const parsed = ts.parseJsonConfigFileContent(configFile.config, ts.sys, dirname(cp));\n for (const f of parsed.fileNames) expanded.add(f);\n }\n return [...expanded];\n}\n\nfunction effectiveOptionsKey(configPath: string | undefined): string {\n if (!configPath) return \"\\0default\";\n const configFile = ts.readConfigFile(configPath, ts.sys.readFile);\n const parsed = ts.parseJsonConfigFileContent(configFile.config, ts.sys, dirname(configPath));\n const o = parsed.options;\n return JSON.stringify({\n target: o.target,\n module: o.module,\n moduleResolution: o.moduleResolution,\n jsx: o.jsx,\n strict: o.strict,\n paths: o.paths,\n baseUrl: o.baseUrl,\n lib: o.lib,\n types: o.types,\n esModuleInterop: o.esModuleInterop,\n });\n}\n\n/** Merge groups whose tsconfigs produce identical effective compiler options. */\nexport function mergeCompatibleGroups(groups: ProgramGroupConfig[]): ProgramGroupConfig[] {\n if (groups.length <= 1) return groups;\n\n const byKey = new Map<string, ProgramGroupConfig[]>();\n for (const group of groups) {\n const key = effectiveOptionsKey(group.configPath);\n let list = byKey.get(key);\n if (!list) {\n list = [];\n byKey.set(key, list);\n }\n list.push(group);\n }\n\n return [...byKey.values()].flatMap((compatible) => {\n const primary = compatible[0];\n if (primary === undefined) return [];\n const rest = compatible.slice(1);\n if (rest.length === 0) return primary;\n return {\n configPath: primary.configPath,\n scanFiles: compatible.flatMap((g) => g.scanFiles),\n expandConfigPaths: rest\n .map((g) => g.configPath)\n .filter((cp): cp is string => cp !== undefined),\n };\n });\n}\n\n/** Group scan files by nearest tsconfig (metadata only, no program creation). */\nexport function groupFilesByTsconfig(scanFiles: string[]): ProgramGroupConfig[] {\n if (scanFiles.length === 0) return [];\n\n const groups = new Map<string | undefined, string[]>();\n for (const file of scanFiles) {\n const configPath = findTsconfig(file);\n let group = groups.get(configPath);\n if (!group) {\n group = [];\n groups.set(configPath, group);\n }\n group.push(file);\n }\n\n return [...groups.entries()].map(([configPath, files]) => ({ configPath, scanFiles: files }));\n}\n\n/** Create a ts.Program from a group config. */\nexport function createProgramForGroup(\n group: ProgramGroupConfig,\n options: ProgramGroupOptions,\n): ts.Program {\n const rootFiles = options.expandProjectFiles\n ? expandProjectFiles(group)\n : group.scanFiles;\n return createProgramForConfig(rootFiles, group.configPath, options.cache);\n}\n","import { existsSync } from \"node:fs\";\nimport { Worker } from \"node:worker_threads\";\nimport { fileURLToPath } from \"node:url\";\nimport type { Diagnostic, ProjectIndexNeed } from \"../rules/types.ts\";\nimport type { ProgramGroupConfig } from \"../typecheck/program.ts\";\nimport type { GroupAnalysisResult } from \"./analyze.ts\";\nimport type { RulePolicySeverity } from \"./types.ts\";\n\nexport interface RuleSpec {\n id: string;\n severity: RulePolicySeverity;\n}\n\nexport interface GroupTask {\n id: number;\n groupConfig: ProgramGroupConfig;\n}\n\nexport interface WorkerRequest {\n taskId: number;\n groupConfig: ProgramGroupConfig;\n ruleSpecs: RuleSpec[];\n indexNeeds: ProjectIndexNeed[];\n}\n\nexport type WorkerResponse =\n | ({ taskId: number; ok: true } & GroupAnalysisResult)\n | { taskId: number; ok: false; error: string };\n\nconst WORKER_URL = new URL(\"./worker.js\", import.meta.url);\n\n/** False when running from source (no built `worker.js`); callers should fall back to serial. */\nexport function workersAvailable(): boolean {\n return existsSync(fileURLToPath(WORKER_URL));\n}\n\nexport async function runGroupsInWorkers(\n tasks: GroupTask[],\n ruleSpecs: RuleSpec[],\n indexNeeds: ProjectIndexNeed[],\n concurrency: number,\n): Promise<GroupAnalysisResult[]> {\n if (tasks.length === 0) return [];\n\n // Heaviest groups first -> reduces tail latency when group count > worker count.\n const ordered = [...tasks].sort((a, b) => b.groupConfig.scanFiles.length - a.groupConfig.scanFiles.length);\n const workerCount = Math.min(concurrency, ordered.length);\n const workers: Worker[] = [];\n const results = new Array<GroupAnalysisResult>(tasks.length);\n\n for (let i = 0; i < tasks.length; i++) results[i] = { diagnostics: [], globalFacts: {} };\n\n let nextIndex = 0;\n let remaining = ordered.length;\n let firstError: Error | null = null;\n\n await new Promise<void>((resolve, reject) => {\n function finishOne(): void {\n remaining--;\n if (remaining === 0) {\n if (firstError !== null) reject(firstError);\n else resolve();\n }\n }\n\n function dispatchNext(worker: Worker): void {\n if (nextIndex >= ordered.length) return;\n const task = ordered[nextIndex];\n if (task === undefined) return;\n nextIndex++;\n const req: WorkerRequest = {\n taskId: task.id,\n groupConfig: task.groupConfig,\n ruleSpecs,\n indexNeeds,\n };\n worker.postMessage(req);\n }\n\n for (let i = 0; i < workerCount; i++) {\n const worker = new Worker(fileURLToPath(WORKER_URL));\n workers.push(worker);\n\n worker.on(\"message\", (response: WorkerResponse) => {\n if (response.ok) {\n results[response.taskId] = { diagnostics: response.diagnostics, globalFacts: response.globalFacts };\n } else if (firstError === null) {\n firstError = new Error(`unguard worker error: ${response.error}`);\n }\n finishOne();\n dispatchNext(worker);\n });\n\n worker.on(\"error\", (err: unknown) => {\n if (firstError === null) {\n firstError = err instanceof Error ? err : new Error(String(err));\n }\n finishOne();\n });\n\n worker.on(\"exit\", (code) => {\n // Only an error if the worker died mid-task; the .finally() terminates after completion (code=1, benign).\n if (remaining > 0 && code !== 0 && firstError === null) {\n firstError = new Error(`unguard worker exited with code ${code}`);\n finishOne();\n }\n });\n\n dispatchNext(worker);\n }\n }).finally(() => {\n // @unguard no-swallowed-catch terminate is idempotent; rejection on already-exited worker is benign.\n for (const w of workers) w.terminate().catch(() => {});\n });\n\n return results;\n}\n","import { readFileSync } from \"node:fs\";\nimport * as ts from \"typescript\";\nimport { collectAllComments, collectProject, collectSourceText, createProjectIndex, type CommentInfo, type ProjectIndexNeeds } from \"../collect/index.ts\";\nimport { isTSRule } from \"../rules/types.ts\";\nimport type { CrossFileRule, Diagnostic, ProjectIndexNeed, Rule, TSRule } from \"../rules/types.ts\";\nimport { groupFilesByTsconfig, mergeCompatibleGroups, createProgramForGroup, createProgramBuildCache, expandProjectFiles, type ProgramGroupConfig } from \"../typecheck/program.ts\";\nimport { runGroupsInWorkers, workersAvailable, type GroupTask } from \"./worker-pool.ts\";\n\nexport interface AnalyzeOptions {\n /** Maximum number of worker threads. <= 1 disables parallelism. */\n concurrency?: number;\n}\n\nexport async function analyzeFiles(files: string[], rules: Rule[], options: AnalyzeOptions): Promise<Diagnostic[]> {\n const tsRules = rules.filter(isTSRule);\n const crossFileRules = rules.filter((r): r is CrossFileRule => !isTSRule(r));\n const indexNeeds = collectIndexNeeds(crossFileRules);\n\n if (!requiresProgram(tsRules, indexNeeds)) {\n return analyzeSourceOnlyFiles(files, tsRules, crossFileRules, indexNeeds);\n }\n\n const groupConfigs = mergeCompatibleGroups(groupFilesByTsconfig(files));\n if (groupConfigs.length === 0) return [];\n\n const concurrency = resolveConcurrency(options.concurrency, groupConfigs.length);\n if (concurrency > 1 && groupConfigs.length > 1 && workersAvailable()) {\n return await runGroupsViaWorkers(groupConfigs, rules, indexNeeds, concurrency);\n }\n\n return runGroupsSerial(groupConfigs, tsRules, crossFileRules, indexNeeds);\n}\n\n/** A cross-file rule that merges facts across tsconfig groups before judging. */\ntype GlobalCrossFileRule = CrossFileRule & {\n collectGlobalFacts: NonNullable<CrossFileRule[\"collectGlobalFacts\"]>;\n finalizeGlobal: NonNullable<CrossFileRule[\"finalizeGlobal\"]>;\n};\n\nfunction isGlobalRule(rule: CrossFileRule): rule is GlobalCrossFileRule {\n return rule.collectGlobalFacts !== undefined && rule.finalizeGlobal !== undefined;\n}\n\nexport interface GroupAnalysisResult {\n diagnostics: Diagnostic[];\n /** ruleId -> structuredClone-safe facts from rules that merge across groups. */\n globalFacts: Record<string, unknown>;\n}\n\nfunction runGroupsSerial(\n groupConfigs: ProgramGroupConfig[],\n tsRules: TSRule[],\n crossFileRules: CrossFileRule[],\n indexNeeds: ProjectIndexNeeds,\n): Diagnostic[] {\n const programCache = createProgramBuildCache();\n const allDiagnostics: Diagnostic[] = [];\n const factsByRule = new Map<string, unknown[]>();\n\n for (const groupConfig of groupConfigs) {\n const result = analyzeGroup(groupConfig, tsRules, crossFileRules, indexNeeds, programCache);\n allDiagnostics.push(...result.diagnostics);\n addGroupFacts(factsByRule, result.globalFacts);\n }\n\n allDiagnostics.push(...annotateGlobalDiagnostics(mergeGlobalRuleDiagnostics(crossFileRules, factsByRule)));\n return dedupeDiagnostics(allDiagnostics);\n}\n\nasync function runGroupsViaWorkers(\n groupConfigs: ProgramGroupConfig[],\n rules: Rule[],\n indexNeeds: ProjectIndexNeeds,\n concurrency: number,\n): Promise<Diagnostic[]> {\n const ruleSpecs = rules.map((rule) => ({ id: rule.id, severity: rule.severity }));\n const tasks: GroupTask[] = groupConfigs.map((groupConfig, idx) => ({ id: idx, groupConfig }));\n\n const resultsByTask = await runGroupsInWorkers(tasks, ruleSpecs, [...indexNeeds], concurrency);\n const allDiagnostics: Diagnostic[] = [];\n const factsByRule = new Map<string, unknown[]>();\n for (const result of resultsByTask) {\n allDiagnostics.push(...result.diagnostics);\n addGroupFacts(factsByRule, result.globalFacts);\n }\n\n const crossFileRules = rules.filter((r): r is CrossFileRule => !isTSRule(r));\n allDiagnostics.push(...annotateGlobalDiagnostics(mergeGlobalRuleDiagnostics(crossFileRules, factsByRule)));\n return dedupeDiagnostics(allDiagnostics);\n}\n\nfunction addGroupFacts(factsByRule: Map<string, unknown[]>, globalFacts: Record<string, unknown>): void {\n for (const [ruleId, facts] of Object.entries(globalFacts)) {\n let list = factsByRule.get(ruleId);\n if (list === undefined) {\n list = [];\n factsByRule.set(ruleId, list);\n }\n list.push(facts);\n }\n}\n\nfunction mergeGlobalRuleDiagnostics(\n crossFileRules: CrossFileRule[],\n factsByRule: Map<string, unknown[]>,\n): Diagnostic[] {\n const merged: Diagnostic[] = [];\n for (const rule of crossFileRules.filter(isGlobalRule)) {\n const facts = factsByRule.get(rule.id);\n if (facts === undefined || facts.length === 0) continue;\n merged.push(...rule.finalizeGlobal(facts));\n }\n return merged;\n}\n\n/**\n * Suppression comments (`@unguard <rule>`) live in source the per-group file\n * data no longer holds by the time merged diagnostics exist, so re-parse just\n * the flagged files. The set is small: only files with findings.\n */\nfunction annotateGlobalDiagnostics(diagnostics: Diagnostic[]): Diagnostic[] {\n if (diagnostics.length === 0) return diagnostics;\n const fileData = new Map<string, FileDiagnosticData>();\n for (const diagnostic of diagnostics) {\n if (fileData.has(diagnostic.file)) continue;\n const source = readFileSync(diagnostic.file, \"utf8\");\n fileData.set(diagnostic.file, {\n source,\n sourceFile: ts.createSourceFile(diagnostic.file, source, ts.ScriptTarget.Latest, true),\n });\n }\n return finalizeDiagnostics(diagnostics, fileData);\n}\n\n/** Run the full analysis pipeline for one tsconfig group. Callable from main thread or worker. */\nexport function analyzeGroup(\n groupConfig: ProgramGroupConfig,\n tsRules: TSRule[],\n crossFileRules: CrossFileRule[],\n indexNeeds: ProjectIndexNeeds,\n programCache?: ReturnType<typeof createProgramBuildCache>,\n): GroupAnalysisResult {\n const projectIndex = createProjectIndex();\n const program = createProgramForGroup(groupConfig, { expandProjectFiles: true, cache: programCache });\n const allowed = new Set(groupConfig.scanFiles);\n const collectFiles = indexNeeds.size > 0\n ? new Set(expandProjectFiles(groupConfig).filter(isAnalyzableSourcePath))\n : new Set<string>();\n const runnableTsRules = filterRulesForCompilerOptions(tsRules, program.getCompilerOptions());\n const { diagnostics } = collectProject(program, runnableTsRules, allowed, {\n collectFiles,\n needs: indexNeeds,\n index: projectIndex,\n });\n\n const groupDiagnostics: Diagnostic[] = [...diagnostics];\n groupDiagnostics.push(...runCrossFileRules(crossFileRules.filter((r) => !isGlobalRule(r)), projectIndex, allowed));\n\n const globalFacts: Record<string, unknown> = {};\n for (const rule of crossFileRules.filter(isGlobalRule)) {\n globalFacts[rule.id] = rule.collectGlobalFacts(projectIndex, { reportableFiles: allowed });\n }\n\n const fileData = new Map<string, FileDiagnosticData>();\n addFileData(fileData, projectIndex, allowed);\n\n return { diagnostics: finalizeDiagnostics(groupDiagnostics, fileData), globalFacts };\n}\n\n/**\n * Without strictNullChecks the checker erases null/undefined from every type,\n * so nullability-driven rules would report each load-bearing guard as dead\n * code. Skipping them (loudly) is the only honest behavior.\n */\nfunction filterRulesForCompilerOptions(tsRules: TSRule[], options: ts.CompilerOptions): TSRule[] {\n const strictNullChecks = options.strictNullChecks ?? options.strict ?? false;\n if (strictNullChecks) return tsRules;\n const skipped = tsRules.filter((rule) => rule.requiresStrictNullChecks === true);\n if (skipped.length > 0) {\n console.warn(\n `unguard: strictNullChecks is off for this tsconfig group; skipped ${skipped.length} nullability rules (${skipped.map((r) => r.id).join(\", \")}). Enable strictNullChecks to run them.`,\n );\n }\n return tsRules.filter((rule) => rule.requiresStrictNullChecks !== true);\n}\n\nfunction analyzeSourceOnlyFiles(\n files: string[],\n tsRules: TSRule[],\n crossFileRules: CrossFileRule[],\n indexNeeds: ProjectIndexNeeds,\n): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n const allFiles = new Map<string, FileDiagnosticData>();\n const factsByRule = new Map<string, unknown[]>();\n\n const groupConfigs = mergeCompatibleGroups(groupFilesByTsconfig(files));\n for (const groupConfig of groupConfigs) {\n const projectIndex = createProjectIndex();\n const allowed = new Set(groupConfig.scanFiles.filter(isAnalyzableSourcePath));\n const collectFiles = (indexNeeds.size > 0 ? expandProjectFiles(groupConfig) : groupConfig.scanFiles)\n .filter(isAnalyzableSourcePath);\n\n for (const file of collectFiles) {\n const source = readFileSync(file, \"utf8\");\n const result = collectSourceText(file, source, allowed.has(file) ? tsRules : [], {\n index: projectIndex,\n needs: indexNeeds,\n retainFile: allowed.has(file) || indexNeeds.has(\"files\"),\n });\n diagnostics.push(...result.diagnostics);\n }\n\n diagnostics.push(...runCrossFileRules(crossFileRules.filter((r) => !isGlobalRule(r)), projectIndex, allowed));\n for (const rule of crossFileRules.filter(isGlobalRule)) {\n addGroupFacts(factsByRule, { [rule.id]: rule.collectGlobalFacts(projectIndex, { reportableFiles: allowed }) });\n }\n addFileData(allFiles, projectIndex, allowed);\n }\n\n // Merged diagnostics point at allowed files, whose data `allFiles` already\n // holds — the shared finalize below annotates them with everything else.\n diagnostics.push(...mergeGlobalRuleDiagnostics(crossFileRules, factsByRule));\n\n return finalizeDiagnostics(diagnostics, allFiles);\n}\n\nfunction runCrossFileRules(\n rules: CrossFileRule[],\n projectIndex: ReturnType<typeof createProjectIndex>,\n allowed: Set<string>,\n): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n const crossFileContext = { reportableFiles: allowed };\n for (const rule of rules) {\n const ruleDiags = rule.analyze(projectIndex, crossFileContext);\n diagnostics.push(...ruleDiags.filter((d) => allowed.has(d.file)));\n }\n return diagnostics;\n}\n\nfunction addFileData(\n files: Map<string, FileDiagnosticData>,\n projectIndex: ReturnType<typeof createProjectIndex>,\n allowed: Set<string>,\n): void {\n for (const [k, v] of projectIndex.files) {\n if (!allowed.has(k)) continue;\n files.set(k, { source: v.source, sourceFile: v.sourceFile });\n }\n}\n\nfunction isAnalyzableSourcePath(file: string): boolean {\n const normalized = file.replaceAll(\"\\\\\", \"/\");\n if (normalized.includes(\"/node_modules/\")) return false;\n return !/\\.d\\.[cm]?ts$/i.test(normalized);\n}\n\nfunction requiresProgram(tsRules: TSRule[], indexNeeds: ProjectIndexNeeds): boolean {\n if (tsRules.some((rule) => rule.requiresTypeInfo !== false)) return true;\n return indexNeeds.has(\"functionSymbols\")\n || indexNeeds.has(\"callSiteSymbols\")\n || indexNeeds.has(\"overloadCallSignatures\");\n}\n\nfunction collectIndexNeeds(rules: CrossFileRule[]): ProjectIndexNeeds {\n const needs = new Set<ProjectIndexNeed>();\n for (const rule of rules) {\n for (const need of rule.requires ?? []) {\n needs.add(need);\n }\n }\n if (needs.has(\"functionSymbols\")) needs.add(\"functions\");\n if (needs.has(\"callSiteSymbols\") || needs.has(\"overloadCallSignatures\")) needs.add(\"callSites\");\n if (needs.has(\"overloadCallSignatures\")) needs.add(\"callSiteSymbols\");\n return needs;\n}\n\nfunction dedupeDiagnostics(diagnostics: Diagnostic[]): Diagnostic[] {\n const seen = new Set<string>();\n const deduped: Diagnostic[] = [];\n for (const diagnostic of diagnostics) {\n const key = `${diagnostic.file}:${diagnostic.line}:${diagnostic.ruleId}`;\n if (seen.has(key)) continue;\n seen.add(key);\n deduped.push(diagnostic);\n }\n return deduped;\n}\n\nfunction finalizeDiagnostics(\n diagnostics: Diagnostic[],\n files: Map<string, FileDiagnosticData>,\n): Diagnostic[] {\n const diagnosticsByFile = new Map<string, Diagnostic[]>();\n for (const diagnostic of diagnostics) {\n let list = diagnosticsByFile.get(diagnostic.file);\n if (list === undefined) {\n list = [];\n diagnosticsByFile.set(diagnostic.file, list);\n }\n list.push(diagnostic);\n }\n\n const finalized: Diagnostic[] = [];\n for (const [file, fileDiagnostics] of diagnosticsByFile) {\n const fileData = files.get(file);\n if (fileData === undefined) {\n finalized.push(...fileDiagnostics);\n continue;\n }\n finalized.push(...annotateAndFilter(fileDiagnostics, collectAllComments(fileData.sourceFile), fileData.source));\n }\n\n return dedupeDiagnostics(finalized);\n}\n\nfunction resolveConcurrency(requested: number | undefined, groupCount: number): number {\n if (requested !== undefined) {\n if (!Number.isInteger(requested) || requested < 1) return 1;\n return Math.min(requested, groupCount);\n }\n return 1;\n}\n\ninterface FileDiagnosticData {\n source: string;\n sourceFile: ts.SourceFile;\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 annotateAndFilter(diagnostics: Diagnostic[], comments: CommentInfo[], source: string): Diagnostic[] {\n if (diagnostics.length === 0) return diagnostics;\n if (comments.length === 0) return diagnostics;\n\n const byEndLine = new Map<number, CommentInfo[]>();\n for (const comment of comments) {\n const endLine = lineAt(source, comment.end);\n let list = byEndLine.get(endLine);\n if (list === undefined) {\n list = [];\n byEndLine.set(endLine, list);\n }\n list.push(comment);\n }\n\n const kept: Diagnostic[] = [];\n for (const diagnostic of diagnostics) {\n if (isSatisfiedByComment(diagnostic, byEndLine, source)) continue;\n\n const inline = findInlineComment(diagnostic.line, byEndLine);\n if (inline !== null) {\n diagnostic.annotation = inline;\n kept.push(diagnostic);\n continue;\n }\n const above = collectAnnotation(diagnostic.line - 1, byEndLine, source);\n if (above !== null) diagnostic.annotation = above;\n kept.push(diagnostic);\n }\n\n return kept;\n}\n\nfunction lastCommentOnLine(line: number, byEndLine: Map<number, CommentInfo[]>): CommentInfo | null {\n const commentsOnLine = byEndLine.get(line);\n if (commentsOnLine === undefined || commentsOnLine.length === 0) return null;\n return commentsOnLine.at(-1) ?? null;\n}\n\nfunction findInlineComment(diagLine: number, byEndLine: Map<number, CommentInfo[]>): string | null {\n const comment = lastCommentOnLine(diagLine, byEndLine);\n if (comment === null || comment.type !== \"Line\") return null;\n const text = comment.value.trim();\n if (isDirectiveComment(text)) return null;\n return text;\n}\n\nfunction collectAnnotation(\n commentEndLine: number,\n byEndLine: Map<number, CommentInfo[]>,\n source: string,\n): string | null {\n const comments = collectCommentsAbove(commentEndLine, byEndLine, source);\n if (comments.length === 0) return null;\n const first = comments[0];\n if (comments.length === 1 && first !== undefined && first.type === \"Block\") {\n return cleanBlockComment(first.value);\n }\n return comments.map((c) => c.value.trim()).join(\"\\n\");\n}\n\nfunction isSatisfiedByComment(\n diagnostic: Diagnostic,\n byEndLine: Map<number, CommentInfo[]>,\n source: string,\n): boolean {\n if (diagnostic.severity === \"error\") return false;\n\n const candidates = getCommentCandidates(diagnostic.line, byEndLine, source);\n return candidates.some((comment) => commentSatisfiesRule(comment, diagnostic.ruleId));\n}\n\nfunction getCommentCandidates(\n diagLine: number,\n byEndLine: Map<number, CommentInfo[]>,\n source: string,\n): CommentInfo[] {\n const inline = byEndLine.get(diagLine) ?? [];\n const above = collectCommentsAbove(diagLine - 1, byEndLine, source);\n // Also check the line immediately below (inside a block body).\n // Formatters like Biome/Prettier enforce `} catch {` on one line,\n // forcing suppression comments into the block where they end up on diagLine + 1.\n const below = byEndLine.get(diagLine + 1) ?? [];\n return [...inline, ...above, ...below];\n}\n\nfunction collectCommentsAbove(\n commentEndLine: number,\n byEndLine: Map<number, CommentInfo[]>,\n source: string,\n): CommentInfo[] {\n const comment = lastCommentOnLine(commentEndLine, byEndLine);\n if (comment === null) return [];\n if (comment.type === \"Block\") return [comment];\n\n const lines: CommentInfo[] = [comment];\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);\n prevLine--;\n }\n\n return lines;\n}\n\nfunction commentSatisfiesRule(comment: CommentInfo, ruleId: string): boolean {\n for (const line of commentLines(comment)) {\n const match = line.match(/^@unguard\\s+([^\\s]+)\\b/);\n if (match?.[1] === ruleId) return true;\n }\n return false;\n}\n\nfunction commentLines(comment: CommentInfo): string[] {\n if (comment.type === \"Block\") {\n const cleaned = cleanBlockComment(comment.value);\n if (cleaned.length === 0) return [];\n return cleaned.split(\"\\n\");\n }\n return [comment.value.trim()];\n}\n\nfunction isDirectiveComment(text: string): boolean {\n return text.startsWith(\"@expect\") || text.startsWith(\"@unguard\");\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"],"mappings":"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"}