rules/eslint/scoped-resource-release.eslint.rule.ts
rules/eslint/scoped-resource-release.eslint.rule.ts is a file in GovLab Extension Host. 70 lines of code and 9 definitions.
import type { LocalRule, RuleContext, RuleListener, RuleNode } from "../../types/rule.types.ts";
import { RESOURCE_MARK, SCOPED_RESOURCES } from "../../shared/manifests/invariant.manifest.ts";
import {
declaredAtTop,
importedNamesOf,
isType,
literalString,
nameOf,
nodeAt,
nodesAt,
} from "../../shared/selectors/syntax.selector.ts";
import { defineCheck } from "@govlab/context/check";
import { listener } from "../../shared/factories/listener.factory.ts";
interface Acquired {
readonly acquirer: string;
readonly node: RuleNode;
readonly release: string;
}
export default {
create(context: RuleContext): RuleListener {
const names = new Set<string>();
const acquired: Acquired[] = [];
return listener(
{
importDeclaration(view, raw) {
const source = literalString(nodeAt(view, "source")) ?? "";
for (const specifier of nodesAt(view, "specifiers")) {
if (!isType(specifier, "ImportSpecifier")) {
continue;
}
const acquirer = nameOf(nodeAt(specifier, "imported"));
const release = SCOPED_RESOURCES.get(source + RESOURCE_MARK + acquirer);
if (release !== undefined) {
acquired.push({ acquirer, node: raw, release });
}
}
},
program(view) {
for (const name of [...declaredAtTop(view), ...importedNamesOf(view)]) {
names.add(name);
}
},
},
() => {
for (const entry of acquired) {
if (!names.has(entry.release)) {
context.report({
data: { acquirer: entry.acquirer, release: entry.release },
messageId: "unreleased",
node: entry.node,
});
}
}
},
);
},
meta: {
docs: {
checks: defineCheck({ detects: ["lexicon:resource-waste-saturation"], enforces: [] }),
description:
"A resource whose release takes more than its own close is acquired only beside its one release function. The resource and its release are data in the scoped resources registry. A file that acquires one without importing or declaring the release leaves what the close keeps reachable in memory.",
},
messages: {
unreleased:
"'{{acquirer}}' acquires a resource whose close keeps its contents reachable. Release it through '{{release}}', imported or declared in this file.",
},
schema: [],
type: "problem",
},
} satisfies LocalRule;