-
Notifications
You must be signed in to change notification settings - Fork 2.7k
/
require-using-disposable.ts
63 lines (61 loc) · 1.94 KB
/
require-using-disposable.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import { ESLintUtils } from "@typescript-eslint/utils";
import ts from "typescript";
import * as utils from "ts-api-utils";
export const rule = ESLintUtils.RuleCreator.withoutDocs({
create(context) {
return {
VariableDeclaration(node) {
for (const declarator of node.declarations) {
if (!declarator.init) continue;
const services = ESLintUtils.getParserServices(context);
const type = services.getTypeAtLocation(declarator.init);
for (const typePart of parts(type)) {
if (!utils.isObjectType(typePart) || !typePart.symbol) {
continue;
}
if (
// bad check, but will do for now
// in the future, we should check for a `[Symbol.disposable]` property
// but I have no idea how to do that right now
typePart.symbol.escapedName === "Disposable" &&
node.kind != "using"
) {
context.report({
messageId: "missingUsing",
node: declarator,
});
}
if (
// similarly bad check
typePart.symbol.escapedName === "AsyncDisposable" &&
node.kind != "await using"
) {
context.report({
messageId: "missingAwaitUsing",
node: declarator,
});
}
}
}
},
};
},
meta: {
messages: {
missingUsing:
"Disposables should be allocated with `using <disposable>`.",
missingAwaitUsing:
"AsyncDisposables should be allocated with `await using <disposable>`.",
},
type: "suggestion",
schema: [],
},
defaultOptions: [],
});
function parts(type: ts.Type): ts.Type[] {
return (
type.isUnion() ? utils.unionTypeParts(type).flatMap(parts)
: type.isIntersection() ? utils.intersectionTypeParts(type).flatMap(parts)
: [type]
);
}