tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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;