use-using.ts (2641B)
1 /** 2 * @license 3 * Copyright 2023 Google Inc. 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 import {ESLintUtils, TSESTree} from '@typescript-eslint/utils'; 8 9 const usingSymbols = ['ElementHandle', 'JSHandle']; 10 11 const createRule = ESLintUtils.RuleCreator<{ 12 requiresTypeChecking: boolean; 13 }>(name => { 14 return `https://github.com/puppeteer/puppeteer/tree/main/tools/eslint/${name}.js`; 15 }); 16 17 const useUsingRule = createRule<[], 'useUsing' | 'useUsingFix'>({ 18 name: 'use-using', 19 meta: { 20 docs: { 21 description: "Requires 'using' for element/JS handles.", 22 requiresTypeChecking: true, 23 }, 24 hasSuggestions: true, 25 messages: { 26 useUsing: "Use 'using'.", 27 useUsingFix: "Replace with 'using' to ignore.", 28 }, 29 schema: [], 30 type: 'problem', 31 }, 32 defaultOptions: [], 33 create(context) { 34 const services = ESLintUtils.getParserServices(context); 35 const checker = services.program.getTypeChecker(); 36 37 return { 38 VariableDeclaration(node): void { 39 if (['using', 'await using'].includes(node.kind) || node.declare) { 40 return; 41 } 42 for (const declaration of node.declarations) { 43 if (declaration.id.type === TSESTree.AST_NODE_TYPES.Identifier) { 44 const tsNode = services.esTreeNodeToTSNodeMap.get(declaration.id); 45 const type = checker.getTypeAtLocation(tsNode); 46 let isElementHandleReference = false; 47 if (type.isUnionOrIntersection()) { 48 for (const member of type.types) { 49 if ( 50 member.symbol !== undefined && 51 usingSymbols.includes(member.symbol.escapedName as string) 52 ) { 53 isElementHandleReference = true; 54 break; 55 } 56 } 57 } else { 58 isElementHandleReference = 59 type.symbol !== undefined 60 ? usingSymbols.includes(type.symbol.escapedName as string) 61 : false; 62 } 63 if (isElementHandleReference) { 64 context.report({ 65 node: declaration.id, 66 messageId: 'useUsing', 67 suggest: [ 68 { 69 messageId: 'useUsingFix', 70 fix(fixer) { 71 return fixer.replaceTextRange( 72 [node.range[0], node.range[0] + node.kind.length], 73 'using', 74 ); 75 }, 76 }, 77 ], 78 }); 79 } 80 } 81 } 82 }, 83 }; 84 }, 85 }); 86 87 export = useUsingRule;