mirror of
https://github.com/puppeteer/puppeteer
synced 2024-06-14 14:02:48 +00:00
chore: implement use-using rule (#10798)
This commit is contained in:
parent
085936bd7e
commit
dca327f99f
@ -1,3 +1,6 @@
|
|||||||
|
const rulesDirPlugin = require('eslint-plugin-rulesdir');
|
||||||
|
rulesDirPlugin.RULES_DIR = 'tools/eslint/lib';
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
root: true,
|
root: true,
|
||||||
env: {
|
env: {
|
||||||
@ -136,10 +139,12 @@ module.exports = {
|
|||||||
'plugin:@typescript-eslint/recommended',
|
'plugin:@typescript-eslint/recommended',
|
||||||
'plugin:@typescript-eslint/stylistic',
|
'plugin:@typescript-eslint/stylistic',
|
||||||
],
|
],
|
||||||
plugins: ['eslint-plugin-tsdoc', 'local'],
|
plugins: ['eslint-plugin-tsdoc', 'rulesdir'],
|
||||||
rules: {
|
rules: {
|
||||||
// Keeps comments formatted.
|
// Keeps comments formatted.
|
||||||
'local/prettier-comments': 'error',
|
'rulesdir/prettier-comments': 'error',
|
||||||
|
// Enforces clean up of used resources.
|
||||||
|
'rulesdir/use-using': 'off',
|
||||||
// Brackets keep code readable.
|
// Brackets keep code readable.
|
||||||
curly: ['error', 'all'],
|
curly: ['error', 'all'],
|
||||||
// Brackets keep code readable and `return` intentions clear.
|
// Brackets keep code readable and `return` intentions clear.
|
||||||
|
53
package-lock.json
generated
53
package-lock.json
generated
@ -9,7 +9,8 @@
|
|||||||
"workspaces": [
|
"workspaces": [
|
||||||
"packages/*",
|
"packages/*",
|
||||||
"test",
|
"test",
|
||||||
"test/installation"
|
"test/installation",
|
||||||
|
"tools/eslint"
|
||||||
],
|
],
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@actions/core": "1.10.0",
|
"@actions/core": "1.10.0",
|
||||||
@ -45,9 +46,9 @@
|
|||||||
"eslint-config-prettier": "9.0.0",
|
"eslint-config-prettier": "9.0.0",
|
||||||
"eslint-formatter-codeframe": "7.32.1",
|
"eslint-formatter-codeframe": "7.32.1",
|
||||||
"eslint-plugin-import": "2.28.1",
|
"eslint-plugin-import": "2.28.1",
|
||||||
"eslint-plugin-local": "1.0.0",
|
|
||||||
"eslint-plugin-mocha": "10.1.0",
|
"eslint-plugin-mocha": "10.1.0",
|
||||||
"eslint-plugin-prettier": "5.0.0",
|
"eslint-plugin-prettier": "5.0.0",
|
||||||
|
"eslint-plugin-rulesdir": "0.2.2",
|
||||||
"eslint-plugin-tsdoc": "0.2.17",
|
"eslint-plugin-tsdoc": "0.2.17",
|
||||||
"eslint-plugin-unused-imports": "3.0.0",
|
"eslint-plugin-unused-imports": "3.0.0",
|
||||||
"esprima": "4.0.1",
|
"esprima": "4.0.1",
|
||||||
@ -80,6 +81,12 @@
|
|||||||
"zod": "3.22.2"
|
"zod": "3.22.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"eslint": {
|
||||||
|
"name": "@puppeteer/eslint",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"extraneous": true,
|
||||||
|
"license": "Apache-2.0"
|
||||||
|
},
|
||||||
"node_modules/@aashutoshrathi/word-wrap": {
|
"node_modules/@aashutoshrathi/word-wrap": {
|
||||||
"version": "1.2.6",
|
"version": "1.2.6",
|
||||||
"resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz",
|
"resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz",
|
||||||
@ -1873,6 +1880,10 @@
|
|||||||
"resolved": "packages/browsers",
|
"resolved": "packages/browsers",
|
||||||
"link": true
|
"link": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@puppeteer/eslint": {
|
||||||
|
"resolved": "tools/eslint",
|
||||||
|
"link": true
|
||||||
|
},
|
||||||
"node_modules/@puppeteer/ng-schematics": {
|
"node_modules/@puppeteer/ng-schematics": {
|
||||||
"resolved": "packages/ng-schematics",
|
"resolved": "packages/ng-schematics",
|
||||||
"link": true
|
"link": true
|
||||||
@ -4523,11 +4534,6 @@
|
|||||||
"semver": "bin/semver.js"
|
"semver": "bin/semver.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-plugin-local": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/eslint-plugin-mocha": {
|
"node_modules/eslint-plugin-mocha": {
|
||||||
"version": "10.1.0",
|
"version": "10.1.0",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@ -4622,6 +4628,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/eslint-plugin-rulesdir": {
|
||||||
|
"version": "0.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint-plugin-rulesdir/-/eslint-plugin-rulesdir-0.2.2.tgz",
|
||||||
|
"integrity": "sha512-qhBtmrWgehAIQeMDJ+Q+PnOz1DWUZMPeVrI0wE9NZtnpIMFUfh3aPKFYt2saeMSemZRrvUtjWfYwepsC8X+mjQ==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/eslint-plugin-tsdoc": {
|
"node_modules/eslint-plugin-tsdoc": {
|
||||||
"version": "0.2.17",
|
"version": "0.2.17",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@ -11191,6 +11206,12 @@
|
|||||||
"ws": "8.13.0"
|
"ws": "8.13.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"packages/ts-plugin": {
|
||||||
|
"name": "@puppeteer/ts-plugin",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"extraneous": true,
|
||||||
|
"license": "Apache-2.0"
|
||||||
|
},
|
||||||
"test": {
|
"test": {
|
||||||
"name": "@puppeteer-test/test",
|
"name": "@puppeteer-test/test",
|
||||||
"version": "latest",
|
"version": "latest",
|
||||||
@ -11205,6 +11226,11 @@
|
|||||||
"glob": "10.3.3",
|
"glob": "10.3.3",
|
||||||
"mocha": "10.2.0"
|
"mocha": "10.2.0"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"tools/eslint": {
|
||||||
|
"name": "@puppeteer/eslint",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"license": "Apache-2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -12367,6 +12393,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@puppeteer/eslint": {
|
||||||
|
"version": "file:tools/eslint"
|
||||||
|
},
|
||||||
"@puppeteer/ng-schematics": {
|
"@puppeteer/ng-schematics": {
|
||||||
"version": "file:packages/ng-schematics",
|
"version": "file:packages/ng-schematics",
|
||||||
"requires": {
|
"requires": {
|
||||||
@ -14304,10 +14333,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"eslint-plugin-local": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"eslint-plugin-mocha": {
|
"eslint-plugin-mocha": {
|
||||||
"version": "10.1.0",
|
"version": "10.1.0",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@ -14357,6 +14382,12 @@
|
|||||||
"synckit": "^0.8.5"
|
"synckit": "^0.8.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"eslint-plugin-rulesdir": {
|
||||||
|
"version": "0.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint-plugin-rulesdir/-/eslint-plugin-rulesdir-0.2.2.tgz",
|
||||||
|
"integrity": "sha512-qhBtmrWgehAIQeMDJ+Q+PnOz1DWUZMPeVrI0wE9NZtnpIMFUfh3aPKFYt2saeMSemZRrvUtjWfYwepsC8X+mjQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"eslint-plugin-tsdoc": {
|
"eslint-plugin-tsdoc": {
|
||||||
"version": "0.2.17",
|
"version": "0.2.17",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
"lint:prettier": "prettier --check .",
|
"lint:prettier": "prettier --check .",
|
||||||
"lint": "run-s lint:prettier lint:eslint",
|
"lint": "run-s lint:prettier lint:eslint",
|
||||||
"postinstall": "npm run postinstall --workspaces --if-present",
|
"postinstall": "npm run postinstall --workspaces --if-present",
|
||||||
|
"prepare": "npm run prepare --workspaces --if-present",
|
||||||
"test-install": "npm run test --workspace @puppeteer-test/installation",
|
"test-install": "npm run test --workspace @puppeteer-test/installation",
|
||||||
"test-types": "tsd -t packages/puppeteer",
|
"test-types": "tsd -t packages/puppeteer",
|
||||||
"test:chrome:headful": "wireit",
|
"test:chrome:headful": "wireit",
|
||||||
@ -137,7 +138,7 @@
|
|||||||
"eslint-config-prettier": "9.0.0",
|
"eslint-config-prettier": "9.0.0",
|
||||||
"eslint-formatter-codeframe": "7.32.1",
|
"eslint-formatter-codeframe": "7.32.1",
|
||||||
"eslint-plugin-import": "2.28.1",
|
"eslint-plugin-import": "2.28.1",
|
||||||
"eslint-plugin-local": "1.0.0",
|
"eslint-plugin-rulesdir": "0.2.2",
|
||||||
"eslint-plugin-mocha": "10.1.0",
|
"eslint-plugin-mocha": "10.1.0",
|
||||||
"eslint-plugin-prettier": "5.0.0",
|
"eslint-plugin-prettier": "5.0.0",
|
||||||
"eslint-plugin-tsdoc": "0.2.17",
|
"eslint-plugin-tsdoc": "0.2.17",
|
||||||
@ -174,6 +175,7 @@
|
|||||||
"workspaces": [
|
"workspaces": [
|
||||||
"packages/*",
|
"packages/*",
|
||||||
"test",
|
"test",
|
||||||
"test/installation"
|
"test/installation",
|
||||||
|
"tools/eslint"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
34
tools/eslint/package.json
Normal file
34
tools/eslint/package.json
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"name": "@puppeteer/eslint",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"private": true,
|
||||||
|
"type": "commonjs",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/puppeteer/puppeteer/tree/main/tools/eslint"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "wireit",
|
||||||
|
"prepare": "wireit"
|
||||||
|
},
|
||||||
|
"wireit": {
|
||||||
|
"build": {
|
||||||
|
"command": "tsc -b",
|
||||||
|
"clean": "if-file-deleted",
|
||||||
|
"files": [
|
||||||
|
"src/**"
|
||||||
|
],
|
||||||
|
"output": [
|
||||||
|
"lib/**",
|
||||||
|
"tsconfig.tsbuildinfo"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"prepare": {
|
||||||
|
"dependencies": [
|
||||||
|
"build"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"author": "The Chromium Authors",
|
||||||
|
"license": "Apache-2.0"
|
||||||
|
}
|
@ -1,5 +1,26 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2023 Google Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// @ts-nocheck
|
||||||
|
// TODO: We should convert this to types.
|
||||||
|
|
||||||
const prettier = require('@prettier/sync');
|
const prettier = require('@prettier/sync');
|
||||||
const prettierConfig = require('./.prettierrc.cjs');
|
|
||||||
|
const prettierConfigPath = '../../../.prettierrc.cjs';
|
||||||
|
const prettierConfig = require(prettierConfigPath);
|
||||||
|
|
||||||
const cleanupBlockComment = value => {
|
const cleanupBlockComment = value => {
|
||||||
return value
|
return value
|
||||||
@ -46,7 +67,7 @@ const buildBlockComment = (value, offset) => {
|
|||||||
/**
|
/**
|
||||||
* @type import("eslint").Rule.RuleModule
|
* @type import("eslint").Rule.RuleModule
|
||||||
*/
|
*/
|
||||||
const rule = {
|
const prettierCommentsRule = {
|
||||||
meta: {
|
meta: {
|
||||||
type: 'suggestion',
|
type: 'suggestion',
|
||||||
docs: {
|
docs: {
|
||||||
@ -85,8 +106,4 @@ const rule = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = prettierCommentsRule;
|
||||||
rules: {
|
|
||||||
'prettier-comments': rule,
|
|
||||||
},
|
|
||||||
};
|
|
89
tools/eslint/src/use-using.ts
Normal file
89
tools/eslint/src/use-using.ts
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2023 Google Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {ESLintUtils, TSESTree} from '@typescript-eslint/utils';
|
||||||
|
import type {
|
||||||
|
RuleListener,
|
||||||
|
RuleModule,
|
||||||
|
} from '@typescript-eslint/utils/ts-eslint';
|
||||||
|
|
||||||
|
const usingSymbols = ['ElementHandle', 'JSHandle'];
|
||||||
|
|
||||||
|
const createRule = ESLintUtils.RuleCreator(name => {
|
||||||
|
return `https://github.com/puppeteer/puppeteer/tree/main/tools/eslint/${name}.js`;
|
||||||
|
});
|
||||||
|
|
||||||
|
const useUsingRule: RuleModule<'useUsing', [], RuleListener> = createRule<
|
||||||
|
[],
|
||||||
|
'useUsing'
|
||||||
|
>({
|
||||||
|
name: 'use-using',
|
||||||
|
meta: {
|
||||||
|
docs: {
|
||||||
|
description: "Requires 'using' for element/JS handles.",
|
||||||
|
requiresTypeChecking: true,
|
||||||
|
},
|
||||||
|
messages: {
|
||||||
|
useUsing: "Use 'using'.",
|
||||||
|
},
|
||||||
|
schema: [],
|
||||||
|
type: 'problem',
|
||||||
|
},
|
||||||
|
defaultOptions: [],
|
||||||
|
create(context) {
|
||||||
|
const services = ESLintUtils.getParserServices(context);
|
||||||
|
const checker = services.program.getTypeChecker();
|
||||||
|
|
||||||
|
return {
|
||||||
|
VariableDeclaration(node): void {
|
||||||
|
if (['using', 'await using'].includes(node.kind)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (const declaration of node.declarations) {
|
||||||
|
if (declaration.id.type === TSESTree.AST_NODE_TYPES.Identifier) {
|
||||||
|
const tsNode = services.esTreeNodeToTSNodeMap.get(declaration.id);
|
||||||
|
const type = checker.getTypeAtLocation(tsNode);
|
||||||
|
let isElementHandleReference = false;
|
||||||
|
if (type.isUnionOrIntersection()) {
|
||||||
|
for (const member of type.types) {
|
||||||
|
if (
|
||||||
|
member.symbol !== undefined &&
|
||||||
|
usingSymbols.includes(member.symbol.escapedName as string)
|
||||||
|
) {
|
||||||
|
isElementHandleReference = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
isElementHandleReference =
|
||||||
|
type.symbol !== undefined
|
||||||
|
? usingSymbols.includes(type.symbol.escapedName as string)
|
||||||
|
: false;
|
||||||
|
}
|
||||||
|
if (isElementHandleReference) {
|
||||||
|
context.report({
|
||||||
|
node: declaration.id,
|
||||||
|
messageId: 'useUsing',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export = useUsingRule;
|
14
tools/eslint/tsconfig.json
Normal file
14
tools/eslint/tsconfig.json
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"module": "NodeNext",
|
||||||
|
"moduleResolution": "NodeNext",
|
||||||
|
"rootDir": "./src",
|
||||||
|
"outDir": "./lib",
|
||||||
|
"declaration": false,
|
||||||
|
"declarationMap": false,
|
||||||
|
"sourceMap": false,
|
||||||
|
"composite": false,
|
||||||
|
"removeComments": true
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user