@ttt-productions/repo-guards 0.1.17 → 0.1.18
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read-state-branches.d.ts","sourceRoot":"","sources":["../../../src/modules/frontend-reads/read-state-branches.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAqB,KAAK,cAAc,EAAE,KAAK,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAa1F,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,MAAM,EAAE;QACN,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;QACxB,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;QAC3B,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;QACnC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;KAC5B,CAAC;IACF,UAAU,EAAE;QACV,eAAe,EAAE,SAAS,cAAc,EAAE,CAAC;QAC3C,qBAAqB,EAAE,SAAS,cAAc,EAAE,CAAC;KAClD,CAAC;CACH;AAED,KAAK,MAAM,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;AAC7C,KAAK,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AAE3D,UAAU,OAAO;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,QAAQ,CAAC;IACnB,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC;CACrB;AAyDD,eAAO,MAAM,QAAQ,GAAI,MAAM,MAAM,KAAG,MAA0D,CAAC;AAEnG,wBAAgB,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,EAAE,CA6FlE;
|
|
1
|
+
{"version":3,"file":"read-state-branches.d.ts","sourceRoot":"","sources":["../../../src/modules/frontend-reads/read-state-branches.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAqB,KAAK,cAAc,EAAE,KAAK,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAa1F,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,MAAM,EAAE;QACN,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;QACxB,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;QAC3B,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;QACnC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;KAC5B,CAAC;IACF,UAAU,EAAE;QACV,eAAe,EAAE,SAAS,cAAc,EAAE,CAAC;QAC3C,qBAAqB,EAAE,SAAS,cAAc,EAAE,CAAC;KAClD,CAAC;CACH;AAED,KAAK,MAAM,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;AAC7C,KAAK,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AAE3D,UAAU,OAAO;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,QAAQ,CAAC;IACnB,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC;CACrB;AAyDD,eAAO,MAAM,QAAQ,GAAI,MAAM,MAAM,KAAG,MAA0D,CAAC;AAEnG,wBAAgB,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,EAAE,CA6FlE;AAyGD,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,GAAG,EAAE,CAkBlF;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,GAAG,EAAE,CAgB3E;AAED,eAAO,MAAM,sBAAsB,EAAE,sBAAsB,CAAC,oBAAoB,CAkH/E,CAAC"}
|
|
@@ -181,8 +181,26 @@ function noDataCheck(node) {
|
|
|
181
181
|
}
|
|
182
182
|
return null;
|
|
183
183
|
}
|
|
184
|
+
const isNullish = (node) => node.kind === ts.SyntaxKind.NullKeyword || (ts.isIdentifier(node) && node.text === 'undefined');
|
|
185
|
+
function failureTest(node) {
|
|
186
|
+
let at = outerParens(node);
|
|
187
|
+
let present = true;
|
|
188
|
+
const parent = at.parent;
|
|
189
|
+
if (ts.isBinaryExpression(parent)) {
|
|
190
|
+
const other = unwrapped(parent.left === at ? parent.right : parent.left);
|
|
191
|
+
const op = parent.operatorToken.kind;
|
|
192
|
+
const absentWhenEqual = op === ts.SyntaxKind.EqualsEqualsEqualsToken || op === ts.SyntaxKind.EqualsEqualsToken;
|
|
193
|
+
const presentWhenUnequal = op === ts.SyntaxKind.ExclamationEqualsEqualsToken ||
|
|
194
|
+
op === ts.SyntaxKind.ExclamationEqualsToken;
|
|
195
|
+
if (isNullish(other) && (absentWhenEqual || presentWhenUnequal)) {
|
|
196
|
+
at = parent;
|
|
197
|
+
present = presentWhenUnequal;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return { at, present: isNegated(at) ? !present : present };
|
|
201
|
+
}
|
|
184
202
|
function conjoinedNoData(failure, inside) {
|
|
185
|
-
const top = chainTop(failure.node);
|
|
203
|
+
const top = chainTop(failureTest(failure.node).at);
|
|
186
204
|
return inside.some((r) => {
|
|
187
205
|
if (r.category !== 'data' || r.read !== failure.read)
|
|
188
206
|
return false;
|
|
@@ -226,7 +244,7 @@ export function failureBranchesWithoutNoData(file, fields) {
|
|
|
226
244
|
const hits = [];
|
|
227
245
|
for (const condition of replacingConditions(file)) {
|
|
228
246
|
const inside = refs.filter((r) => within(r.node, condition));
|
|
229
|
-
const failures = inside.filter((r) => r.category === 'failure' &&
|
|
247
|
+
const failures = inside.filter((r) => r.category === 'failure' && failureTest(r.node).present);
|
|
230
248
|
const reported = new Set();
|
|
231
249
|
for (const failure of failures) {
|
|
232
250
|
if (reported.has(failure.read))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read-state-branches.js","sourceRoot":"","sources":["../../../src/modules/frontend-reads/read-state-branches.ts"],"names":[],"mappings":"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","sourcesContent":["import ts from 'typescript';\nimport type { GenericGuardDefinition } from '../../node/suite/config.js';\nimport type { FileView } from '../../reader/view.js';\nimport { reviewedAllowlist, type AllowlistEntry, type Hit } from '../../shapes/shapes.js';\nimport { allowlistProblems, objectProblem } from '../../support/facts.js';\nimport { isUnder } from '../../support/text.js';\nimport {\n APP_CODE,\n filesUnder,\n identifierListProblem,\n isHookName,\n pathListProblem,\n} from './shared.js';\n\nconst RETRY_STATE_HELPERS = new Set(['useReadRetryState']);\n\nexport interface ReadStateBranchFacts {\n surfaceTrees: readonly string[];\n fields: {\n data: readonly string[];\n failure: readonly string[];\n failureCarriers: readonly string[];\n loading: readonly string[];\n };\n exceptions: {\n failureBranches: readonly AllowlistEntry[];\n loadingWithoutFailure: readonly AllowlistEntry[];\n };\n}\n\ntype Fields = ReadStateBranchFacts['fields'];\ntype Category = 'data' | 'failure' | 'carrier' | 'loading';\n\ninterface ReadRef {\n read: string;\n category: Category;\n node: ts.Expression;\n}\n\nfunction categoryOf(name: string, fields: Fields): Category | null {\n if (fields.data.includes(name)) return 'data';\n if (fields.failure.includes(name)) return 'failure';\n if (fields.failureCarriers.includes(name)) return 'carrier';\n if (fields.loading.includes(name)) return 'loading';\n return null;\n}\n\nconst unwrapped = (node: ts.Expression): ts.Expression => {\n let e = node;\n while (ts.isParenthesizedExpression(e) || ts.isNonNullExpression(e)) e = e.expression;\n return e;\n};\n\nfunction bindingFor(name: ts.BindingName, text: string): ts.Node | null {\n if (ts.isIdentifier(name)) return name.text === text ? name.parent : null;\n for (const el of name.elements) {\n if (ts.isOmittedExpression(el)) continue;\n const hit = bindingFor(el.name, text);\n if (hit) return hit;\n }\n return null;\n}\n\nfunction declarationOf(id: ts.Identifier): ts.Node | null {\n for (let scope: ts.Node | undefined = id.parent; scope; scope = scope.parent) {\n if (ts.isFunctionLike(scope))\n for (const parameter of scope.parameters) {\n const hit = bindingFor(parameter.name, id.text);\n if (hit) return hit;\n }\n const statements =\n ts.isBlock(scope) ||\n ts.isSourceFile(scope) ||\n ts.isModuleBlock(scope) ||\n ts.isCaseClause(scope) ||\n ts.isDefaultClause(scope)\n ? scope.statements\n : null;\n for (const statement of statements ?? []) {\n if (!ts.isVariableStatement(statement)) continue;\n for (const d of statement.declarationList.declarations) {\n const hit = bindingFor(d.name, id.text);\n if (hit) return hit;\n }\n }\n }\n return null;\n}\n\ntype Binding =\n | { kind: 'hook'; read: string }\n | { kind: 'retry'; source: ts.Expression }\n | { kind: 'field'; read: string; category: Category };\n\nexport const readName = (read: string): string => read.replace(/@\\d+$/, '()').replace(/#\\d+$/, '');\n\nexport function readRefs(file: FileView, fields: Fields): ReadRef[] {\n const sf = file.sourceFile;\n const bindings = new Map<ts.Node, Binding>();\n const visitBindings = (node: ts.Node): void => {\n if (ts.isVariableDeclaration(node) && node.initializer) {\n const init = unwrapped(node.initializer);\n if (ts.isCallExpression(init)) {\n const callee = init.expression.getText(sf);\n if (ts.isObjectBindingPattern(node.name) && isHookName(callee)) {\n const read = `${callee}@${node.getStart(sf)}`;\n for (const el of node.name.elements) {\n if (el.dotDotDotToken || !ts.isIdentifier(el.name)) continue;\n const category = categoryOf((el.propertyName ?? el.name).getText(sf), fields);\n if (category) bindings.set(el, { kind: 'field', read, category });\n }\n } else if (\n ts.isIdentifier(node.name) &&\n RETRY_STATE_HELPERS.has(callee) &&\n init.arguments[0]\n ) {\n bindings.set(node, { kind: 'retry', source: init.arguments[0] });\n } else if (ts.isIdentifier(node.name) && isHookName(callee)) {\n bindings.set(node, { kind: 'hook', read: `${node.name.text}#${node.getStart(sf)}` });\n }\n }\n }\n ts.forEachChild(node, visitBindings);\n };\n visitBindings(sf);\n\n const bindingOf = (id: ts.Identifier): Binding | undefined => {\n const declaration = declarationOf(id);\n return declaration ? bindings.get(declaration) : undefined;\n };\n\n const ownerOf = (receiver: ts.Expression, depth = 0): string => {\n const r = unwrapped(receiver);\n if (ts.isIdentifier(r)) {\n const binding = bindingOf(r);\n if (binding?.kind === 'hook' || binding?.kind === 'field') return binding.read;\n if (binding?.kind === 'retry' && depth < 8) return ownerOf(binding.source, depth + 1);\n return r.text;\n }\n if (ts.isPropertyAccessExpression(r) && fields.failureCarriers.includes(r.name.text))\n return ownerOf(r.expression, depth);\n return r.getText(sf);\n };\n\n const isRead = (receiver: ts.Expression): boolean => {\n const r = unwrapped(receiver);\n if (ts.isIdentifier(r)) {\n const binding = bindingOf(r);\n return (\n binding?.kind === 'hook' ||\n binding?.kind === 'retry' ||\n (binding?.kind === 'field' && binding.category === 'carrier')\n );\n }\n return ts.isPropertyAccessExpression(r) && fields.failureCarriers.includes(r.name.text)\n ? isRead(r.expression)\n : false;\n };\n\n const refs: ReadRef[] = [];\n const isReceiver = (node: ts.Node) =>\n ts.isPropertyAccessExpression(node.parent) && node.parent.expression === node;\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAccessExpression(node)) {\n const category = categoryOf(node.name.text, fields);\n if (category && !(category === 'carrier' && isReceiver(node)) && isRead(node.expression))\n refs.push({ read: ownerOf(node.expression), category, node });\n } else if (ts.isIdentifier(node)) {\n const parent = node.parent;\n const isName =\n (ts.isPropertyAccessExpression(parent) && parent.name === node) ||\n ((ts.isBindingElement(parent) ||\n ts.isVariableDeclaration(parent) ||\n ts.isPropertyAssignment(parent) ||\n ts.isParameter(parent)) &&\n parent.name === node) ||\n (ts.isBindingElement(parent) && parent.propertyName === node) ||\n ts.isShorthandPropertyAssignment(parent) ||\n ts.isJsxAttribute(parent);\n const binding = isName ? undefined : bindingOf(node);\n if (binding?.kind === 'field' && !(binding.category === 'carrier' && isReceiver(node)))\n refs.push({ read: binding.read, category: binding.category, node });\n else if (binding?.kind === 'retry' && !isReceiver(node))\n refs.push({ read: ownerOf(node), category: 'carrier', node });\n }\n ts.forEachChild(node, visit);\n };\n visit(sf);\n return refs;\n}\n\nconst within = (node: ts.Node, root: ts.Node) =>\n node.getStart() >= root.getStart() && node.getEnd() <= root.getEnd();\n\nconst isNot = (node: ts.Node): node is ts.PrefixUnaryExpression =>\n ts.isPrefixUnaryExpression(node) && node.operator === ts.SyntaxKind.ExclamationToken;\n\nconst isAnd = (node: ts.Node): node is ts.BinaryExpression =>\n ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken;\n\nfunction outerParens(node: ts.Node): ts.Node {\n let at = node;\n while (ts.isParenthesizedExpression(at.parent) || ts.isNonNullExpression(at.parent))\n at = at.parent;\n return at;\n}\n\nfunction chainTop(node: ts.Node): ts.Node {\n let at = outerParens(node);\n while (isAnd(at.parent)) at = outerParens(at.parent);\n return at;\n}\n\nfunction noDataCheck(node: ts.Expression): ts.Node | null {\n const at = outerParens(node);\n const parent = at.parent;\n if (isNot(parent)) return isNot(outerParens(parent).parent) ? null : parent;\n if (\n ts.isBinaryExpression(parent) &&\n [ts.SyntaxKind.EqualsEqualsEqualsToken, ts.SyntaxKind.EqualsEqualsToken].includes(\n parent.operatorToken.kind,\n )\n ) {\n const other = unwrapped(parent.left === at ? parent.right : parent.left);\n const absent =\n other.kind === ts.SyntaxKind.NullKeyword ||\n (ts.isIdentifier(other) && other.text === 'undefined');\n return absent ? parent : null;\n }\n return null;\n}\n\nfunction conjoinedNoData(failure: ReadRef, inside: readonly ReadRef[]): boolean {\n const top = chainTop(failure.node);\n return inside.some((r) => {\n if (r.category !== 'data' || r.read !== failure.read) return false;\n const check = noDataCheck(r.node);\n return !!check && isAnd(outerParens(check).parent) && chainTop(check) === top;\n });\n}\n\nfunction isNegated(node: ts.Expression): boolean {\n let at: ts.Node = node;\n while (ts.isParenthesizedExpression(at.parent)) at = at.parent;\n return (\n ts.isPrefixUnaryExpression(at.parent) && at.parent.operator === ts.SyntaxKind.ExclamationToken\n );\n}\n\nconst returns = (statement: ts.Statement): boolean => {\n let found = false;\n const visit = (node: ts.Node): void => {\n if (found || ts.isFunctionLike(node)) return;\n if (ts.isReturnStatement(node)) found = true;\n else ts.forEachChild(node, visit);\n };\n visit(statement);\n return found;\n};\n\nfunction replacingConditions(file: FileView): ts.Expression[] {\n const out: ts.Expression[] = [];\n const visit = (node: ts.Node): void => {\n if (ts.isConditionalExpression(node)) out.push(node.condition);\n else if (ts.isIfStatement(node) && returns(node.thenStatement)) out.push(node.expression);\n ts.forEachChild(node, visit);\n };\n visit(file.sourceFile);\n return out;\n}\n\nexport function failureBranchesWithoutNoData(file: FileView, fields: Fields): Hit[] {\n const refs = readRefs(file, fields);\n const hits: Hit[] = [];\n for (const condition of replacingConditions(file)) {\n const inside = refs.filter((r) => within(r.node, condition));\n const failures = inside.filter((r) => r.category === 'failure' && !isNegated(r.node));\n const reported = new Set<string>();\n for (const failure of failures) {\n if (reported.has(failure.read)) continue;\n if (conjoinedNoData(failure, inside)) continue;\n reported.add(failure.read);\n hits.push({\n index: failure.node.getStart(file.sourceFile),\n detail: `${failure.node.getText(file.sourceFile)} branches without checking that ${readName(failure.read)} holds no answer`,\n });\n }\n }\n return hits.sort((a, b) => a.index - b.index);\n}\n\nexport function loadingWithoutFailure(file: FileView, fields: Fields): Hit[] {\n const refs = readRefs(file, fields);\n const failing = new Set(\n refs.filter((r) => r.category === 'failure' || r.category === 'carrier').map((r) => r.read),\n );\n const hits: Hit[] = [];\n const reported = new Set<string>();\n for (const ref of refs) {\n if (ref.category !== 'loading' || failing.has(ref.read) || reported.has(ref.read)) continue;\n reported.add(ref.read);\n hits.push({\n index: ref.node.getStart(file.sourceFile),\n detail: `${ref.node.getText(file.sourceFile)} is used, but ${readName(ref.read)}'s failure never is`,\n });\n }\n return hits.sort((a, b) => a.index - b.index);\n}\n\nexport const readStateBranchesGuard: GenericGuardDefinition<ReadStateBranchFacts> = {\n id: 'readStateBranches',\n absentWhen: false,\n factProblems(facts) {\n const problems: string[] = [];\n pathListProblem(facts?.surfaceTrees, 'surfaceTrees', problems);\n if (objectProblem(facts?.fields, 'fields', problems)) {\n identifierListProblem(facts.fields.data, 'fields.data', problems, { nonEmpty: true });\n identifierListProblem(facts.fields.failure, 'fields.failure', problems, { nonEmpty: true });\n identifierListProblem(facts.fields.failureCarriers, 'fields.failureCarriers', problems, {\n nonEmpty: false,\n });\n identifierListProblem(facts.fields.loading, 'fields.loading', problems, { nonEmpty: true });\n const all = [\n ...(facts.fields.data ?? []),\n ...(facts.fields.failure ?? []),\n ...(facts.fields.failureCarriers ?? []),\n ...(facts.fields.loading ?? []),\n ];\n const seen = new Set<string>();\n for (const name of all) {\n if (seen.has(name)) problems.push(`fields names ${name} in two roles`);\n seen.add(name);\n }\n }\n if (objectProblem(facts?.exceptions, 'exceptions', problems)) {\n allowlistProblems(facts.exceptions.failureBranches, 'exceptions.failureBranches', problems);\n allowlistProblems(\n facts.exceptions.loadingWithoutFailure,\n 'exceptions.loadingWithoutFailure',\n problems,\n );\n }\n return problems;\n },\n build(facts) {\n const { fields } = facts;\n const inTrees = (file: FileView) => facts.surfaceTrees.some((tree) => isUnder(file.path, tree));\n const sample = `${facts.surfaceTrees[0]}/sample.tsx`;\n const [data] = fields.data;\n const [failure] = fields.failure;\n const [loading] = fields.loading;\n const failureBranch = reviewedAllowlist({\n title: 'a failure branch that replaces a read also checks that nothing answered',\n description:\n `In a render surface (${facts.surfaceTrees.join(', ')}), a branch that swaps the content for the failure — a ` +\n `ternary, or an if that returns — on a read's failure (${[...fields.failure, ...fields.failureCarriers].join(' / ')}) ` +\n `is conjoined with a check that the same read holds no answer (!${fields.data.join(' / !')}, or a compare with ` +\n 'null or undefined). A read that answered and then fails keeps its answer: the content, and any editor open in ' +\n 'it, stays on screen with the failure inline, and only a failure with nothing answered replaces it. A reviewed ' +\n 'exception names the file and its why.',\n scope: APP_CODE,\n match: (file) => (inTrees(file) ? failureBranchesWithoutNoData(file, fields) : []),\n allowlist: facts.exceptions.failureBranches,\n samples: {\n flags: [\n {\n path: sample,\n text: `const { ${data}, ${failure} } = useRows();\\nreturn ${failure} ? <Failed /> : <List rows={${data}} />;`,\n },\n {\n path: sample,\n text: `const rows = useRows();\\nif (rows.${failure}) return <Failed />;\\nreturn <List rows={rows.${data}} />;`,\n },\n ],\n passes: [\n {\n path: sample,\n text: `const { ${data}, ${failure} } = useRows();\\nreturn ${failure} && !${data} ? <Failed /> : <List rows={${data}} />;`,\n },\n {\n path: sample,\n text: `const rows = useRows();\\nif (rows.${failure} && rows.${data} === undefined) return <Failed />;\\nreturn <List rows={rows.${data}} />;`,\n },\n {\n path: sample,\n text: `const rows = useRows();\\nreturn <>{rows.${failure} && <InlineFailure />}<List rows={rows.${data}} /></>;`,\n },\n ],\n },\n });\n const loadingAlone = reviewedAllowlist({\n title: \"a surface that renders a read's loading state also renders its failure\",\n description:\n `A render surface (${facts.surfaceTrees.join(', ')}) that reads a read's loading state ` +\n `(${fields.loading.join(' / ')}) also reads that read's failure (${[...fields.failure, ...fields.failureCarriers].join(' / ')}). ` +\n 'A surface with a loading branch and no failure branch renders a failed read as an endless pending state or ' +\n 'as an empty answer. A reviewed exception names the file and its why.',\n scope: APP_CODE,\n match: (file) => (inTrees(file) ? loadingWithoutFailure(file, fields) : []),\n allowlist: facts.exceptions.loadingWithoutFailure,\n samples: {\n flags: [\n {\n path: sample,\n text: `const { ${data}, ${loading} } = useRows();\\nif (${loading}) return <Spinner />;\\nreturn <List rows={${data}} />;`,\n },\n ],\n passes: [\n {\n path: sample,\n text: `const { ${data}, ${loading}, ${failure} } = useRows();\\nif (${loading}) return <Spinner />;\\nif (${failure} && !${data}) return <Failed />;\\nreturn <List rows={${data}} />;`,\n },\n ],\n },\n });\n const withTrees = (guard: typeof failureBranch): typeof failureBranch => ({\n ...guard,\n async run(context) {\n return [...filesUnder(context, facts.surfaceTrees).findings, ...(await guard.run(context))];\n },\n });\n return [withTrees(failureBranch), withTrees(loadingAlone)];\n },\n};\n"]}
|
|
1
|
+
{"version":3,"file":"read-state-branches.js","sourceRoot":"","sources":["../../../src/modules/frontend-reads/read-state-branches.ts"],"names":[],"mappings":"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","sourcesContent":["import ts from 'typescript';\nimport type { GenericGuardDefinition } from '../../node/suite/config.js';\nimport type { FileView } from '../../reader/view.js';\nimport { reviewedAllowlist, type AllowlistEntry, type Hit } from '../../shapes/shapes.js';\nimport { allowlistProblems, objectProblem } from '../../support/facts.js';\nimport { isUnder } from '../../support/text.js';\nimport {\n APP_CODE,\n filesUnder,\n identifierListProblem,\n isHookName,\n pathListProblem,\n} from './shared.js';\n\nconst RETRY_STATE_HELPERS = new Set(['useReadRetryState']);\n\nexport interface ReadStateBranchFacts {\n surfaceTrees: readonly string[];\n fields: {\n data: readonly string[];\n failure: readonly string[];\n failureCarriers: readonly string[];\n loading: readonly string[];\n };\n exceptions: {\n failureBranches: readonly AllowlistEntry[];\n loadingWithoutFailure: readonly AllowlistEntry[];\n };\n}\n\ntype Fields = ReadStateBranchFacts['fields'];\ntype Category = 'data' | 'failure' | 'carrier' | 'loading';\n\ninterface ReadRef {\n read: string;\n category: Category;\n node: ts.Expression;\n}\n\nfunction categoryOf(name: string, fields: Fields): Category | null {\n if (fields.data.includes(name)) return 'data';\n if (fields.failure.includes(name)) return 'failure';\n if (fields.failureCarriers.includes(name)) return 'carrier';\n if (fields.loading.includes(name)) return 'loading';\n return null;\n}\n\nconst unwrapped = (node: ts.Expression): ts.Expression => {\n let e = node;\n while (ts.isParenthesizedExpression(e) || ts.isNonNullExpression(e)) e = e.expression;\n return e;\n};\n\nfunction bindingFor(name: ts.BindingName, text: string): ts.Node | null {\n if (ts.isIdentifier(name)) return name.text === text ? name.parent : null;\n for (const el of name.elements) {\n if (ts.isOmittedExpression(el)) continue;\n const hit = bindingFor(el.name, text);\n if (hit) return hit;\n }\n return null;\n}\n\nfunction declarationOf(id: ts.Identifier): ts.Node | null {\n for (let scope: ts.Node | undefined = id.parent; scope; scope = scope.parent) {\n if (ts.isFunctionLike(scope))\n for (const parameter of scope.parameters) {\n const hit = bindingFor(parameter.name, id.text);\n if (hit) return hit;\n }\n const statements =\n ts.isBlock(scope) ||\n ts.isSourceFile(scope) ||\n ts.isModuleBlock(scope) ||\n ts.isCaseClause(scope) ||\n ts.isDefaultClause(scope)\n ? scope.statements\n : null;\n for (const statement of statements ?? []) {\n if (!ts.isVariableStatement(statement)) continue;\n for (const d of statement.declarationList.declarations) {\n const hit = bindingFor(d.name, id.text);\n if (hit) return hit;\n }\n }\n }\n return null;\n}\n\ntype Binding =\n | { kind: 'hook'; read: string }\n | { kind: 'retry'; source: ts.Expression }\n | { kind: 'field'; read: string; category: Category };\n\nexport const readName = (read: string): string => read.replace(/@\\d+$/, '()').replace(/#\\d+$/, '');\n\nexport function readRefs(file: FileView, fields: Fields): ReadRef[] {\n const sf = file.sourceFile;\n const bindings = new Map<ts.Node, Binding>();\n const visitBindings = (node: ts.Node): void => {\n if (ts.isVariableDeclaration(node) && node.initializer) {\n const init = unwrapped(node.initializer);\n if (ts.isCallExpression(init)) {\n const callee = init.expression.getText(sf);\n if (ts.isObjectBindingPattern(node.name) && isHookName(callee)) {\n const read = `${callee}@${node.getStart(sf)}`;\n for (const el of node.name.elements) {\n if (el.dotDotDotToken || !ts.isIdentifier(el.name)) continue;\n const category = categoryOf((el.propertyName ?? el.name).getText(sf), fields);\n if (category) bindings.set(el, { kind: 'field', read, category });\n }\n } else if (\n ts.isIdentifier(node.name) &&\n RETRY_STATE_HELPERS.has(callee) &&\n init.arguments[0]\n ) {\n bindings.set(node, { kind: 'retry', source: init.arguments[0] });\n } else if (ts.isIdentifier(node.name) && isHookName(callee)) {\n bindings.set(node, { kind: 'hook', read: `${node.name.text}#${node.getStart(sf)}` });\n }\n }\n }\n ts.forEachChild(node, visitBindings);\n };\n visitBindings(sf);\n\n const bindingOf = (id: ts.Identifier): Binding | undefined => {\n const declaration = declarationOf(id);\n return declaration ? bindings.get(declaration) : undefined;\n };\n\n const ownerOf = (receiver: ts.Expression, depth = 0): string => {\n const r = unwrapped(receiver);\n if (ts.isIdentifier(r)) {\n const binding = bindingOf(r);\n if (binding?.kind === 'hook' || binding?.kind === 'field') return binding.read;\n if (binding?.kind === 'retry' && depth < 8) return ownerOf(binding.source, depth + 1);\n return r.text;\n }\n if (ts.isPropertyAccessExpression(r) && fields.failureCarriers.includes(r.name.text))\n return ownerOf(r.expression, depth);\n return r.getText(sf);\n };\n\n const isRead = (receiver: ts.Expression): boolean => {\n const r = unwrapped(receiver);\n if (ts.isIdentifier(r)) {\n const binding = bindingOf(r);\n return (\n binding?.kind === 'hook' ||\n binding?.kind === 'retry' ||\n (binding?.kind === 'field' && binding.category === 'carrier')\n );\n }\n return ts.isPropertyAccessExpression(r) && fields.failureCarriers.includes(r.name.text)\n ? isRead(r.expression)\n : false;\n };\n\n const refs: ReadRef[] = [];\n const isReceiver = (node: ts.Node) =>\n ts.isPropertyAccessExpression(node.parent) && node.parent.expression === node;\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAccessExpression(node)) {\n const category = categoryOf(node.name.text, fields);\n if (category && !(category === 'carrier' && isReceiver(node)) && isRead(node.expression))\n refs.push({ read: ownerOf(node.expression), category, node });\n } else if (ts.isIdentifier(node)) {\n const parent = node.parent;\n const isName =\n (ts.isPropertyAccessExpression(parent) && parent.name === node) ||\n ((ts.isBindingElement(parent) ||\n ts.isVariableDeclaration(parent) ||\n ts.isPropertyAssignment(parent) ||\n ts.isParameter(parent)) &&\n parent.name === node) ||\n (ts.isBindingElement(parent) && parent.propertyName === node) ||\n ts.isShorthandPropertyAssignment(parent) ||\n ts.isJsxAttribute(parent);\n const binding = isName ? undefined : bindingOf(node);\n if (binding?.kind === 'field' && !(binding.category === 'carrier' && isReceiver(node)))\n refs.push({ read: binding.read, category: binding.category, node });\n else if (binding?.kind === 'retry' && !isReceiver(node))\n refs.push({ read: ownerOf(node), category: 'carrier', node });\n }\n ts.forEachChild(node, visit);\n };\n visit(sf);\n return refs;\n}\n\nconst within = (node: ts.Node, root: ts.Node) =>\n node.getStart() >= root.getStart() && node.getEnd() <= root.getEnd();\n\nconst isNot = (node: ts.Node): node is ts.PrefixUnaryExpression =>\n ts.isPrefixUnaryExpression(node) && node.operator === ts.SyntaxKind.ExclamationToken;\n\nconst isAnd = (node: ts.Node): node is ts.BinaryExpression =>\n ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken;\n\nfunction outerParens(node: ts.Node): ts.Node {\n let at = node;\n while (ts.isParenthesizedExpression(at.parent) || ts.isNonNullExpression(at.parent))\n at = at.parent;\n return at;\n}\n\nfunction chainTop(node: ts.Node): ts.Node {\n let at = outerParens(node);\n while (isAnd(at.parent)) at = outerParens(at.parent);\n return at;\n}\n\nfunction noDataCheck(node: ts.Expression): ts.Node | null {\n const at = outerParens(node);\n const parent = at.parent;\n if (isNot(parent)) return isNot(outerParens(parent).parent) ? null : parent;\n if (\n ts.isBinaryExpression(parent) &&\n [ts.SyntaxKind.EqualsEqualsEqualsToken, ts.SyntaxKind.EqualsEqualsToken].includes(\n parent.operatorToken.kind,\n )\n ) {\n const other = unwrapped(parent.left === at ? parent.right : parent.left);\n const absent =\n other.kind === ts.SyntaxKind.NullKeyword ||\n (ts.isIdentifier(other) && other.text === 'undefined');\n return absent ? parent : null;\n }\n return null;\n}\n\nconst isNullish = (node: ts.Expression): boolean =>\n node.kind === ts.SyntaxKind.NullKeyword || (ts.isIdentifier(node) && node.text === 'undefined');\n\nfunction failureTest(node: ts.Expression): { at: ts.Expression; present: boolean } {\n let at = outerParens(node) as ts.Expression;\n let present = true;\n const parent = at.parent;\n if (ts.isBinaryExpression(parent)) {\n const other = unwrapped(parent.left === at ? parent.right : parent.left);\n const op = parent.operatorToken.kind;\n const absentWhenEqual =\n op === ts.SyntaxKind.EqualsEqualsEqualsToken || op === ts.SyntaxKind.EqualsEqualsToken;\n const presentWhenUnequal =\n op === ts.SyntaxKind.ExclamationEqualsEqualsToken ||\n op === ts.SyntaxKind.ExclamationEqualsToken;\n if (isNullish(other) && (absentWhenEqual || presentWhenUnequal)) {\n at = parent;\n present = presentWhenUnequal;\n }\n }\n return { at, present: isNegated(at) ? !present : present };\n}\n\nfunction conjoinedNoData(failure: ReadRef, inside: readonly ReadRef[]): boolean {\n const top = chainTop(failureTest(failure.node).at);\n return inside.some((r) => {\n if (r.category !== 'data' || r.read !== failure.read) return false;\n const check = noDataCheck(r.node);\n return !!check && isAnd(outerParens(check).parent) && chainTop(check) === top;\n });\n}\n\nfunction isNegated(node: ts.Expression): boolean {\n let at: ts.Node = node;\n while (ts.isParenthesizedExpression(at.parent)) at = at.parent;\n return (\n ts.isPrefixUnaryExpression(at.parent) && at.parent.operator === ts.SyntaxKind.ExclamationToken\n );\n}\n\nconst returns = (statement: ts.Statement): boolean => {\n let found = false;\n const visit = (node: ts.Node): void => {\n if (found || ts.isFunctionLike(node)) return;\n if (ts.isReturnStatement(node)) found = true;\n else ts.forEachChild(node, visit);\n };\n visit(statement);\n return found;\n};\n\nfunction replacingConditions(file: FileView): ts.Expression[] {\n const out: ts.Expression[] = [];\n const visit = (node: ts.Node): void => {\n if (ts.isConditionalExpression(node)) out.push(node.condition);\n else if (ts.isIfStatement(node) && returns(node.thenStatement)) out.push(node.expression);\n ts.forEachChild(node, visit);\n };\n visit(file.sourceFile);\n return out;\n}\n\nexport function failureBranchesWithoutNoData(file: FileView, fields: Fields): Hit[] {\n const refs = readRefs(file, fields);\n const hits: Hit[] = [];\n for (const condition of replacingConditions(file)) {\n const inside = refs.filter((r) => within(r.node, condition));\n const failures = inside.filter((r) => r.category === 'failure' && failureTest(r.node).present);\n const reported = new Set<string>();\n for (const failure of failures) {\n if (reported.has(failure.read)) continue;\n if (conjoinedNoData(failure, inside)) continue;\n reported.add(failure.read);\n hits.push({\n index: failure.node.getStart(file.sourceFile),\n detail: `${failure.node.getText(file.sourceFile)} branches without checking that ${readName(failure.read)} holds no answer`,\n });\n }\n }\n return hits.sort((a, b) => a.index - b.index);\n}\n\nexport function loadingWithoutFailure(file: FileView, fields: Fields): Hit[] {\n const refs = readRefs(file, fields);\n const failing = new Set(\n refs.filter((r) => r.category === 'failure' || r.category === 'carrier').map((r) => r.read),\n );\n const hits: Hit[] = [];\n const reported = new Set<string>();\n for (const ref of refs) {\n if (ref.category !== 'loading' || failing.has(ref.read) || reported.has(ref.read)) continue;\n reported.add(ref.read);\n hits.push({\n index: ref.node.getStart(file.sourceFile),\n detail: `${ref.node.getText(file.sourceFile)} is used, but ${readName(ref.read)}'s failure never is`,\n });\n }\n return hits.sort((a, b) => a.index - b.index);\n}\n\nexport const readStateBranchesGuard: GenericGuardDefinition<ReadStateBranchFacts> = {\n id: 'readStateBranches',\n absentWhen: false,\n factProblems(facts) {\n const problems: string[] = [];\n pathListProblem(facts?.surfaceTrees, 'surfaceTrees', problems);\n if (objectProblem(facts?.fields, 'fields', problems)) {\n identifierListProblem(facts.fields.data, 'fields.data', problems, { nonEmpty: true });\n identifierListProblem(facts.fields.failure, 'fields.failure', problems, { nonEmpty: true });\n identifierListProblem(facts.fields.failureCarriers, 'fields.failureCarriers', problems, {\n nonEmpty: false,\n });\n identifierListProblem(facts.fields.loading, 'fields.loading', problems, { nonEmpty: true });\n const all = [\n ...(facts.fields.data ?? []),\n ...(facts.fields.failure ?? []),\n ...(facts.fields.failureCarriers ?? []),\n ...(facts.fields.loading ?? []),\n ];\n const seen = new Set<string>();\n for (const name of all) {\n if (seen.has(name)) problems.push(`fields names ${name} in two roles`);\n seen.add(name);\n }\n }\n if (objectProblem(facts?.exceptions, 'exceptions', problems)) {\n allowlistProblems(facts.exceptions.failureBranches, 'exceptions.failureBranches', problems);\n allowlistProblems(\n facts.exceptions.loadingWithoutFailure,\n 'exceptions.loadingWithoutFailure',\n problems,\n );\n }\n return problems;\n },\n build(facts) {\n const { fields } = facts;\n const inTrees = (file: FileView) => facts.surfaceTrees.some((tree) => isUnder(file.path, tree));\n const sample = `${facts.surfaceTrees[0]}/sample.tsx`;\n const [data] = fields.data;\n const [failure] = fields.failure;\n const [loading] = fields.loading;\n const failureBranch = reviewedAllowlist({\n title: 'a failure branch that replaces a read also checks that nothing answered',\n description:\n `In a render surface (${facts.surfaceTrees.join(', ')}), a branch that swaps the content for the failure — a ` +\n `ternary, or an if that returns — on a read's failure (${[...fields.failure, ...fields.failureCarriers].join(' / ')}) ` +\n `is conjoined with a check that the same read holds no answer (!${fields.data.join(' / !')}, or a compare with ` +\n 'null or undefined). A read that answered and then fails keeps its answer: the content, and any editor open in ' +\n 'it, stays on screen with the failure inline, and only a failure with nothing answered replaces it. A reviewed ' +\n 'exception names the file and its why.',\n scope: APP_CODE,\n match: (file) => (inTrees(file) ? failureBranchesWithoutNoData(file, fields) : []),\n allowlist: facts.exceptions.failureBranches,\n samples: {\n flags: [\n {\n path: sample,\n text: `const { ${data}, ${failure} } = useRows();\\nreturn ${failure} ? <Failed /> : <List rows={${data}} />;`,\n },\n {\n path: sample,\n text: `const rows = useRows();\\nif (rows.${failure}) return <Failed />;\\nreturn <List rows={rows.${data}} />;`,\n },\n ],\n passes: [\n {\n path: sample,\n text: `const { ${data}, ${failure} } = useRows();\\nreturn ${failure} && !${data} ? <Failed /> : <List rows={${data}} />;`,\n },\n {\n path: sample,\n text: `const rows = useRows();\\nif (rows.${failure} && rows.${data} === undefined) return <Failed />;\\nreturn <List rows={rows.${data}} />;`,\n },\n {\n path: sample,\n text: `const rows = useRows();\\nreturn <>{rows.${failure} && <InlineFailure />}<List rows={rows.${data}} /></>;`,\n },\n ],\n },\n });\n const loadingAlone = reviewedAllowlist({\n title: \"a surface that renders a read's loading state also renders its failure\",\n description:\n `A render surface (${facts.surfaceTrees.join(', ')}) that reads a read's loading state ` +\n `(${fields.loading.join(' / ')}) also reads that read's failure (${[...fields.failure, ...fields.failureCarriers].join(' / ')}). ` +\n 'A surface with a loading branch and no failure branch renders a failed read as an endless pending state or ' +\n 'as an empty answer. A reviewed exception names the file and its why.',\n scope: APP_CODE,\n match: (file) => (inTrees(file) ? loadingWithoutFailure(file, fields) : []),\n allowlist: facts.exceptions.loadingWithoutFailure,\n samples: {\n flags: [\n {\n path: sample,\n text: `const { ${data}, ${loading} } = useRows();\\nif (${loading}) return <Spinner />;\\nreturn <List rows={${data}} />;`,\n },\n ],\n passes: [\n {\n path: sample,\n text: `const { ${data}, ${loading}, ${failure} } = useRows();\\nif (${loading}) return <Spinner />;\\nif (${failure} && !${data}) return <Failed />;\\nreturn <List rows={${data}} />;`,\n },\n ],\n },\n });\n const withTrees = (guard: typeof failureBranch): typeof failureBranch => ({\n ...guard,\n async run(context) {\n return [...filesUnder(context, facts.surfaceTrees).findings, ...(await guard.run(context))];\n },\n });\n return [withTrees(failureBranch), withTrees(loadingAlone)];\n },\n};\n"]}
|