From f2e63b01bccbaa92009176294d697378503ade31 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Sun, 4 Feb 2024 14:29:18 -0500 Subject: [PATCH] chore: enable no-confusing-void-expression internally --- .eslintrc.js | 1 - packages/ast-spec/tests/fixtures.test.ts | 4 +- .../src/rules/no-poorly-typed-ts-props.ts | 3 +- .../src/rules/plugin-test-formatting.ts | 18 +- .../src/rules/prefer-ast-types-enum.ts | 3 +- packages/eslint-plugin/src/rules/ban-types.ts | 3 +- .../rules/explicit-function-return-type.ts | 12 +- .../rules/explicit-module-boundary-types.ts | 52 ++++-- .../src/rules/func-call-spacing.ts | 3 +- packages/eslint-plugin/src/rules/indent.ts | 28 ++- .../src/rules/lines-around-comment.ts | 2 +- .../src/rules/member-ordering.ts | 3 +- .../src/rules/no-confusing-void-expression.ts | 18 +- .../src/rules/no-dupe-class-members.ts | 2 +- .../src/rules/no-extra-parens.ts | 93 ++++++---- .../src/rules/no-restricted-imports.ts | 15 +- .../eslint-plugin/src/rules/no-type-alias.ts | 5 +- .../src/rules/no-unnecessary-condition.ts | 26 ++- .../src/rules/no-unsafe-return.ts | 6 +- .../src/rules/prefer-regexp-exec.ts | 15 +- .../src/rules/promise-function-async.ts | 3 +- .../src/rules/restrict-plus-operands.ts | 6 +- .../src/rules/sort-type-constituents.ts | 3 +- packages/eslint-plugin/tests/docs.test.ts | 6 +- .../src/utils/validationHelpers.ts | 12 +- packages/rule-tester/tests/RuleTester.test.ts | 10 +- .../src/referencer/ClassVisitor.ts | 24 ++- .../src/referencer/Referencer.ts | 4 +- packages/scope-manager/src/scope/ScopeBase.ts | 4 +- packages/scope-manager/src/scope/WithScope.ts | 4 +- .../tests/eslint-scope/references.test.ts | 18 +- packages/scope-manager/tests/fixtures.test.ts | 4 +- .../type-utils/tests/isTypeReadonly.test.ts | 15 +- packages/types/tools/copy-ast-spec.ts | 12 +- .../getWatchProgramsForProjects.ts | 18 +- .../tests/lib/persistentParse.test.ts | 160 +++++++++++++----- .../tests/lib/semanticInfo.test.ts | 4 +- .../src/components/OptionsSelector.tsx | 20 ++- .../website/src/components/Playground.tsx | 4 +- .../src/components/RulesTable/index.tsx | 41 +++-- .../src/components/config/ConfigEditor.tsx | 13 +- .../src/components/editor/LoadedEditor.tsx | 40 +++-- .../src/components/inputs/Checkbox.tsx | 6 +- .../website/src/components/inputs/Text.tsx | 4 +- .../src/components/layout/EditorTabs.tsx | 4 +- .../src/components/lib/createEventsBinder.ts | 4 +- .../website/src/components/linter/bridge.ts | 4 +- .../typeDetails/SimplifiedTreeView.tsx | 3 +- packages/website/src/hooks/useBool.ts | 7 +- packages/website/src/hooks/useMediaQuery.ts | 3 +- .../src/theme/CodeBlock/Content/String.tsx | 4 +- 51 files changed, 523 insertions(+), 253 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 1398b8f04d87..1e542e149e59 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -52,7 +52,6 @@ module.exports = { 'deprecation/deprecation': 'error', // TODO(#7130): Investigate changing these in or removing these from presets - '@typescript-eslint/no-confusing-void-expression': 'off', '@typescript-eslint/prefer-string-starts-ends-with': 'off', // diff --git a/packages/ast-spec/tests/fixtures.test.ts b/packages/ast-spec/tests/fixtures.test.ts index d107cc320255..bffaf911a814 100644 --- a/packages/ast-spec/tests/fixtures.test.ts +++ b/packages/ast-spec/tests/fixtures.test.ts @@ -333,7 +333,9 @@ function nestDescribe(fixture: Fixture, segments = fixture.segments): void { } describe('AST Fixtures', () => { - FIXTURES.forEach(f => nestDescribe(f)); + FIXTURES.forEach(f => { + nestDescribe(f); + }); // once we've run all the tests, snapshot the list of fixtures that have differences for easy reference it('List fixtures with AST differences', () => { diff --git a/packages/eslint-plugin-internal/src/rules/no-poorly-typed-ts-props.ts b/packages/eslint-plugin-internal/src/rules/no-poorly-typed-ts-props.ts index 1d07e54351b4..1b0bbdb57ad1 100644 --- a/packages/eslint-plugin-internal/src/rules/no-poorly-typed-ts-props.ts +++ b/packages/eslint-plugin-internal/src/rules/no-poorly-typed-ts-props.ts @@ -73,7 +73,7 @@ export default createRule({ continue; } - return context.report({ + context.report({ node, messageId: banned.fixWith ? 'doNotUseWithFixer' : 'doNotUse', data: banned, @@ -87,6 +87,7 @@ export default createRule({ }, ], }); + return; } }, }; diff --git a/packages/eslint-plugin-internal/src/rules/plugin-test-formatting.ts b/packages/eslint-plugin-internal/src/rules/plugin-test-formatting.ts index 4c13b42b9cc5..76a635ffba5c 100644 --- a/packages/eslint-plugin-internal/src/rules/plugin-test-formatting.ts +++ b/packages/eslint-plugin-internal/src/rules/plugin-test-formatting.ts @@ -274,7 +274,7 @@ export default createRule({ if (literal.loc.end.line === literal.loc.start.line) { // don't use template strings for single line tests - return context.report({ + context.report({ node: literal, messageId: 'singleLineQuotes', fix(fixer) { @@ -295,6 +295,7 @@ export default createRule({ ]; }, }); + return; } const lines = text.split('\n'); @@ -305,7 +306,7 @@ export default createRule({ const isEndEmpty = lastLine.trimStart() === ''; if (!isStartEmpty || !isEndEmpty) { // multiline template strings must have an empty first/last line - return context.report({ + context.report({ node: literal, messageId: 'templateLiteralEmptyEnds', *fix(fixer) { @@ -324,11 +325,12 @@ export default createRule({ } }, }); + return; } const parentIndent = getExpectedIndentForNode(literal, sourceCode.lines); if (lastLine.length !== parentIndent) { - return context.report({ + context.report({ node: literal, messageId: 'templateLiteralLastLineIndent', fix(fixer) { @@ -338,6 +340,7 @@ export default createRule({ ); }, }); + return; } // remove the empty lines @@ -353,13 +356,14 @@ export default createRule({ const requiresIndent = firstLineIndent.length > 0; if (requiresIndent) { if (firstLineIndent.length !== expectedIndent) { - return context.report({ + context.report({ node: literal, messageId: 'templateStringRequiresIndent', data: { indent: expectedIndent, }, }); + return; } // quick-and-dirty validation that lines are roughly indented correctly @@ -373,13 +377,14 @@ export default createRule({ const indent = matches[1]; if (indent.length < expectedIndent) { - return context.report({ + context.report({ node: literal, messageId: 'templateStringMinimumIndent', data: { indent: expectedIndent, }, }); + return; } } @@ -404,7 +409,7 @@ export default createRule({ .join('\n') : formatted; - return context.report({ + context.report({ node: literal, messageId: isErrorTest ? 'invalidFormattingErrorTest' @@ -419,6 +424,7 @@ export default createRule({ ); }, }); + return; } } diff --git a/packages/eslint-plugin-internal/src/rules/prefer-ast-types-enum.ts b/packages/eslint-plugin-internal/src/rules/prefer-ast-types-enum.ts index 9e97e44d2536..ffbfa8716f9e 100755 --- a/packages/eslint-plugin-internal/src/rules/prefer-ast-types-enum.ts +++ b/packages/eslint-plugin-internal/src/rules/prefer-ast-types-enum.ts @@ -28,7 +28,7 @@ export default createRule({ const report = ( enumName: 'AST_NODE_TYPES' | 'AST_TOKEN_TYPES' | 'DefinitionType', literal: TSESTree.StringLiteral, - ): void => + ): void => { context.report({ data: { enumName, literal: literal.value }, messageId: 'preferEnum', @@ -36,6 +36,7 @@ export default createRule({ fix: fixer => fixer.replaceText(literal, `${enumName}.${literal.value}`), }); + }; return { Literal(node: TSESTree.Literal): void { diff --git a/packages/eslint-plugin/src/rules/ban-types.ts b/packages/eslint-plugin/src/rules/ban-types.ts index 574c16937e98..10418463c75b 100644 --- a/packages/eslint-plugin/src/rules/ban-types.ts +++ b/packages/eslint-plugin/src/rules/ban-types.ts @@ -261,8 +261,9 @@ export default createRule({ TYPE_KEYWORDS, (acc: TSESLint.RuleListener, keyword) => { if (bannedTypes.has(keyword)) { - acc[TYPE_KEYWORDS[keyword]] = (node: TSESTree.Node): void => + acc[TYPE_KEYWORDS[keyword]] = (node: TSESTree.Node): void => { checkBannedTypes(node, keyword); + }; } return acc; diff --git a/packages/eslint-plugin/src/rules/explicit-function-return-type.ts b/packages/eslint-plugin/src/rules/explicit-function-return-type.ts index e6201df8e9e6..37d6007fe14b 100644 --- a/packages/eslint-plugin/src/rules/explicit-function-return-type.ts +++ b/packages/eslint-plugin/src/rules/explicit-function-return-type.ts @@ -196,13 +196,13 @@ export default createRule({ return; } - checkFunctionReturnType(node, options, sourceCode, loc => + checkFunctionReturnType(node, options, sourceCode, loc => { context.report({ node, loc, messageId: 'missingReturnType', - }), - ); + }); + }); }, FunctionDeclaration(node): void { if (isAllowedFunction(node)) { @@ -212,13 +212,13 @@ export default createRule({ return; } - checkFunctionReturnType(node, options, sourceCode, loc => + checkFunctionReturnType(node, options, sourceCode, loc => { context.report({ node, loc, messageId: 'missingReturnType', - }), - ); + }); + }); }, }; }, diff --git a/packages/eslint-plugin/src/rules/explicit-module-boundary-types.ts b/packages/eslint-plugin/src/rules/explicit-module-boundary-types.ts index 092179f8187d..fe65dc1fbba4 100644 --- a/packages/eslint-plugin/src/rules/explicit-module-boundary-types.ts +++ b/packages/eslint-plugin/src/rules/explicit-module-boundary-types.ts @@ -213,8 +213,10 @@ export default createRule({ } return; - case AST_NODE_TYPES.TSParameterProperty: - return checkParameter(param.parameter); + case AST_NODE_TYPES.TSParameterProperty: { + checkParameter(param.parameter); + return; + } case AST_NODE_TYPES.AssignmentPattern: // ignored as it has a type via its assignment return; @@ -338,8 +340,10 @@ export default createRule({ switch (node.type) { case AST_NODE_TYPES.ArrowFunctionExpression: - case AST_NODE_TYPES.FunctionExpression: - return checkFunctionExpression(node); + case AST_NODE_TYPES.FunctionExpression: { + checkFunctionExpression(node); + return; + } case AST_NODE_TYPES.ArrayExpression: for (const element of node.elements) { @@ -354,7 +358,10 @@ export default createRule({ ) { return; } - return checkNode(node.value); + { + checkNode(node.value); + return; + } case AST_NODE_TYPES.ClassDeclaration: case AST_NODE_TYPES.ClassExpression: @@ -363,8 +370,10 @@ export default createRule({ } return; - case AST_NODE_TYPES.FunctionDeclaration: - return checkFunction(node); + case AST_NODE_TYPES.FunctionDeclaration: { + checkFunction(node); + return; + } case AST_NODE_TYPES.MethodDefinition: case AST_NODE_TYPES.TSAbstractMethodDefinition: @@ -374,10 +383,15 @@ export default createRule({ ) { return; } - return checkNode(node.value); + { + checkNode(node.value); + return; + } - case AST_NODE_TYPES.Identifier: - return followReference(node); + case AST_NODE_TYPES.Identifier: { + followReference(node); + return; + } case AST_NODE_TYPES.ObjectExpression: for (const property of node.properties) { @@ -385,11 +399,15 @@ export default createRule({ } return; - case AST_NODE_TYPES.Property: - return checkNode(node.value); + case AST_NODE_TYPES.Property: { + checkNode(node.value); + return; + } - case AST_NODE_TYPES.TSEmptyBodyFunctionExpression: - return checkEmptyBodyFunctionExpression(node); + case AST_NODE_TYPES.TSEmptyBodyFunctionExpression: { + checkEmptyBodyFunctionExpression(node); + return; + } case AST_NODE_TYPES.VariableDeclaration: for (const declaration of node.declarations) { @@ -397,8 +415,10 @@ export default createRule({ } return; - case AST_NODE_TYPES.VariableDeclarator: - return checkNode(node.init); + case AST_NODE_TYPES.VariableDeclarator: { + checkNode(node.init); + return; + } } } diff --git a/packages/eslint-plugin/src/rules/func-call-spacing.ts b/packages/eslint-plugin/src/rules/func-call-spacing.ts index 510730fca997..c05f8946c315 100644 --- a/packages/eslint-plugin/src/rules/func-call-spacing.ts +++ b/packages/eslint-plugin/src/rules/func-call-spacing.ts @@ -117,7 +117,7 @@ export default createRule({ if (option === 'never') { if (hasWhitespace) { - return context.report({ + context.report({ node, loc: lastCalleeToken.loc.start, messageId: 'unexpectedWhitespace', @@ -140,6 +140,7 @@ export default createRule({ return null; }, }); + return; } } else if (isOptionalCall) { // disallow: diff --git a/packages/eslint-plugin/src/rules/indent.ts b/packages/eslint-plugin/src/rules/indent.ts index c2d61583405a..d97d853278eb 100644 --- a/packages/eslint-plugin/src/rules/indent.ts +++ b/packages/eslint-plugin/src/rules/indent.ts @@ -197,12 +197,12 @@ export default createRule({ return; } - return rules.VariableDeclaration(node); + rules.VariableDeclaration(node); }, TSAsExpression(node: TSESTree.TSAsExpression) { // transform it to a BinaryExpression - return rules['BinaryExpression, LogicalExpression']({ + rules['BinaryExpression, LogicalExpression']({ type: AST_NODE_TYPES.BinaryExpression, operator: 'as' as any, left: node.expression, @@ -218,7 +218,7 @@ export default createRule({ TSConditionalType(node: TSESTree.TSConditionalType) { // transform it to a ConditionalExpression - return rules.ConditionalExpression({ + rules.ConditionalExpression({ type: AST_NODE_TYPES.ConditionalExpression, test: { parent: node, @@ -248,7 +248,7 @@ export default createRule({ node: TSESTree.TSEnumDeclaration | TSESTree.TSTypeLiteral, ) { // transform it to an ObjectExpression - return rules['ObjectExpression, ObjectPattern']({ + rules['ObjectExpression, ObjectPattern']({ type: AST_NODE_TYPES.ObjectExpression, properties: ( node.members as (TSESTree.TSEnumMember | TSESTree.TypeElement)[] @@ -269,7 +269,7 @@ export default createRule({ // use VariableDeclaration instead of ImportDeclaration because it's essentially the same thing const { id, moduleReference } = node; - return rules.VariableDeclaration({ + rules.VariableDeclaration({ type: AST_NODE_TYPES.VariableDeclaration, kind: 'const' as const, declarations: [ @@ -320,7 +320,7 @@ export default createRule({ TSIndexedAccessType(node: TSESTree.TSIndexedAccessType) { // convert to a MemberExpression - return rules['MemberExpression, JSXMemberExpression, MetaProperty']({ + rules['MemberExpression, JSXMemberExpression, MetaProperty']({ type: AST_NODE_TYPES.MemberExpression, object: node.objectType as any, property: node.indexType as any, @@ -336,7 +336,7 @@ export default createRule({ TSInterfaceBody(node: TSESTree.TSInterfaceBody) { // transform it to an ClassBody - return rules['BlockStatement, ClassBody']({ + rules['BlockStatement, ClassBody']({ type: AST_NODE_TYPES.ClassBody, body: node.body.map( p => @@ -357,9 +357,7 @@ export default createRule({ node: TSESTree.TSInterfaceDeclaration, ) { // transform it to a ClassDeclaration - return rules[ - 'ClassDeclaration[superClass], ClassExpression[superClass]' - ]({ + rules['ClassDeclaration[superClass], ClassExpression[superClass]']({ type: AST_NODE_TYPES.ClassDeclaration, body: node.body as any, id: null, @@ -387,7 +385,7 @@ export default createRule({ )!; // transform it to an ObjectExpression - return rules['ObjectExpression, ObjectPattern']({ + rules['ObjectExpression, ObjectPattern']({ type: AST_NODE_TYPES.ObjectExpression, properties: [ { @@ -426,7 +424,7 @@ export default createRule({ TSModuleBlock(node: TSESTree.TSModuleBlock) { // transform it to a BlockStatement - return rules['BlockStatement, ClassBody']({ + rules['BlockStatement, ClassBody']({ type: AST_NODE_TYPES.BlockStatement, body: node.body as any, @@ -438,7 +436,7 @@ export default createRule({ }, TSQualifiedName(node: TSESTree.TSQualifiedName) { - return rules['MemberExpression, JSXMemberExpression, MetaProperty']({ + rules['MemberExpression, JSXMemberExpression, MetaProperty']({ type: AST_NODE_TYPES.MemberExpression, object: node.left as any, property: node.right as any, @@ -454,7 +452,7 @@ export default createRule({ TSTupleType(node: TSESTree.TSTupleType) { // transform it to an ArrayExpression - return rules['ArrayExpression, ArrayPattern']({ + rules['ArrayExpression, ArrayPattern']({ type: AST_NODE_TYPES.ArrayExpression, elements: node.elementTypes as any, @@ -474,7 +472,7 @@ export default createRule({ // JSX is about the closest we can get because the angle brackets // it's not perfect but it works! - return rules.JSXOpeningElement({ + rules.JSXOpeningElement({ type: AST_NODE_TYPES.JSXOpeningElement, selfClosing: false, name: name as any, diff --git a/packages/eslint-plugin/src/rules/lines-around-comment.ts b/packages/eslint-plugin/src/rules/lines-around-comment.ts index 9c25d24351a6..c37eb1eee84c 100644 --- a/packages/eslint-plugin/src/rules/lines-around-comment.ts +++ b/packages/eslint-plugin/src/rules/lines-around-comment.ts @@ -410,7 +410,7 @@ export default createRule({ } } } - return context.report(descriptor); + context.report(descriptor); }; const customContext = { report: customReport }; diff --git a/packages/eslint-plugin/src/rules/member-ordering.ts b/packages/eslint-plugin/src/rules/member-ordering.ts index 34fed637e6c8..069004bc4ac6 100644 --- a/packages/eslint-plugin/src/rules/member-ordering.ts +++ b/packages/eslint-plugin/src/rules/member-ordering.ts @@ -880,7 +880,7 @@ export default createRule({ i && isMemberOptional(member) !== isMemberOptional(members[i - 1]), ); - const report = (member: Member): void => + const report = (member: Member): void => { context.report({ messageId: 'incorrectRequiredMembersOrder', loc: member.loc, @@ -890,6 +890,7 @@ export default createRule({ optionalityOrder === 'required-first' ? 'required' : 'optional', }, }); + }; // if the optionality of the first item is correct (based on optionalityOrder) // then the first 0 inclusive to switchIndex exclusive members all diff --git a/packages/eslint-plugin/src/rules/no-confusing-void-expression.ts b/packages/eslint-plugin/src/rules/no-confusing-void-expression.ts index 3eae588d0079..57654487e920 100644 --- a/packages/eslint-plugin/src/rules/no-confusing-void-expression.ts +++ b/packages/eslint-plugin/src/rules/no-confusing-void-expression.ts @@ -115,16 +115,17 @@ export default createRule({ if (options.ignoreVoidOperator) { // handle wrapping with `void` - return context.report({ + context.report({ node, messageId: 'invalidVoidExprArrowWrapVoid', fix: wrapVoidFix, }); + return; } // handle wrapping with braces const arrowFunction = invalidAncestor; - return context.report({ + context.report({ node, messageId: 'invalidVoidExprArrow', fix(fixer) { @@ -151,6 +152,7 @@ export default createRule({ return fixer.replaceText(arrowBody, newArrowBodyText); }, }); + return; } if (invalidAncestor.type === AST_NODE_TYPES.ReturnStatement) { @@ -158,18 +160,19 @@ export default createRule({ if (options.ignoreVoidOperator) { // handle wrapping with `void` - return context.report({ + context.report({ node, messageId: 'invalidVoidExprReturnWrapVoid', fix: wrapVoidFix, }); + return; } const returnStmt = invalidAncestor; if (isFinalReturn(returnStmt)) { // remove the `return` keyword - return context.report({ + context.report({ node, messageId: 'invalidVoidExprReturnLast', fix(fixer) { @@ -186,10 +189,11 @@ export default createRule({ return fixer.replaceText(returnStmt, newReturnStmtText); }, }); + return; } // move before the `return` keyword - return context.report({ + context.report({ node, messageId: 'invalidVoidExprReturn', fix(fixer) { @@ -208,16 +212,18 @@ export default createRule({ return fixer.replaceText(returnStmt, newReturnStmtText); }, }); + return; } // handle generic case if (options.ignoreVoidOperator) { // this would be reported by this rule btw. such irony - return context.report({ + context.report({ node, messageId: 'invalidVoidExprWrapVoid', suggest: [{ messageId: 'voidExprWrapVoid', fix: wrapVoidFix }], }); + return; } context.report({ diff --git a/packages/eslint-plugin/src/rules/no-dupe-class-members.ts b/packages/eslint-plugin/src/rules/no-dupe-class-members.ts index 09c734a75585..26691f222345 100644 --- a/packages/eslint-plugin/src/rules/no-dupe-class-members.ts +++ b/packages/eslint-plugin/src/rules/no-dupe-class-members.ts @@ -44,7 +44,7 @@ export default createRule({ return; } - return coreListener(node); + coreListener(node); }; } diff --git a/packages/eslint-plugin/src/rules/no-extra-parens.ts b/packages/eslint-plugin/src/rules/no-extra-parens.ts index 8360df8e3ee4..e1e3d858322c 100644 --- a/packages/eslint-plugin/src/rules/no-extra-parens.ts +++ b/packages/eslint-plugin/src/rules/no-extra-parens.ts @@ -49,25 +49,27 @@ export default createRule({ return; // ignore } if (isLeftTypeAssertion) { - return rule({ + rule({ ...node, left: { ...node.left, type: AST_NODE_TYPES.SequenceExpression as any, }, }); + return; } if (isRightTypeAssertion) { - return rule({ + rule({ ...node, right: { ...node.right, type: AST_NODE_TYPES.SequenceExpression as any, }, }); + return; } - return rule(node); + rule(node); } function callExp( node: TSESTree.CallExpression | TSESTree.NewExpression, @@ -76,13 +78,14 @@ export default createRule({ if (isTypeAssertion(node.callee)) { // reduces the precedence of the node so the rule thinks it needs to be wrapped - return rule({ + rule({ ...node, callee: { ...node.callee, type: AST_NODE_TYPES.SequenceExpression as any, }, }); + return; } if ( @@ -91,7 +94,7 @@ export default createRule({ sourceCode.getTokenAfter(node.callee, isOpeningParenToken) !== sourceCode.getTokenBefore(node.arguments[0], isOpeningParenToken) ) { - return rule({ + rule({ ...node, arguments: [ { @@ -100,9 +103,10 @@ export default createRule({ }, ], }); + return; } - return rule(node); + rule(node); } function unaryUpdateExpression( node: TSESTree.UnaryExpression | TSESTree.UpdateExpression, @@ -111,125 +115,137 @@ export default createRule({ if (isTypeAssertion(node.argument)) { // reduces the precedence of the node so the rule thinks it needs to be wrapped - return rule({ + rule({ ...node, argument: { ...node.argument, type: AST_NODE_TYPES.SequenceExpression as any, }, }); + return; } - return rule(node); + rule(node); } const overrides: TSESLint.RuleListener = { // ArrayExpression ArrowFunctionExpression(node) { if (!isTypeAssertion(node.body)) { - return rules.ArrowFunctionExpression(node); + rules.ArrowFunctionExpression(node); + return; } }, // AssignmentExpression AwaitExpression(node) { if (isTypeAssertion(node.argument)) { // reduces the precedence of the node so the rule thinks it needs to be wrapped - return rules.AwaitExpression({ + rules.AwaitExpression({ ...node, argument: { ...node.argument, type: AST_NODE_TYPES.SequenceExpression as any, }, }); + return; } - return rules.AwaitExpression(node); + rules.AwaitExpression(node); }, BinaryExpression: binaryExp, CallExpression: callExp, ClassDeclaration(node) { if (node.superClass?.type === AST_NODE_TYPES.TSAsExpression) { - return rules.ClassDeclaration({ + rules.ClassDeclaration({ ...node, superClass: { ...node.superClass, type: AST_NODE_TYPES.SequenceExpression as any, }, }); + return; } - return rules.ClassDeclaration(node); + rules.ClassDeclaration(node); }, ClassExpression(node) { if (node.superClass?.type === AST_NODE_TYPES.TSAsExpression) { - return rules.ClassExpression({ + rules.ClassExpression({ ...node, superClass: { ...node.superClass, type: AST_NODE_TYPES.SequenceExpression as any, }, }); + return; } - return rules.ClassExpression(node); + rules.ClassExpression(node); }, ConditionalExpression(node) { // reduces the precedence of the node so the rule thinks it needs to be wrapped if (isTypeAssertion(node.test)) { - return rules.ConditionalExpression({ + rules.ConditionalExpression({ ...node, test: { ...node.test, type: AST_NODE_TYPES.SequenceExpression as any, }, }); + return; } if (isTypeAssertion(node.consequent)) { - return rules.ConditionalExpression({ + rules.ConditionalExpression({ ...node, consequent: { ...node.consequent, type: AST_NODE_TYPES.SequenceExpression as any, }, }); + return; } if (isTypeAssertion(node.alternate)) { // reduces the precedence of the node so the rule thinks it needs to be wrapped - return rules.ConditionalExpression({ + rules.ConditionalExpression({ ...node, alternate: { ...node.alternate, type: AST_NODE_TYPES.SequenceExpression as any, }, }); + return; } - return rules.ConditionalExpression(node); + rules.ConditionalExpression(node); }, // DoWhileStatement // ForIn and ForOf are guarded by eslint version ForStatement(node) { // make the rule skip the piece by removing it entirely if (node.init && isTypeAssertion(node.init)) { - return rules.ForStatement({ + rules.ForStatement({ ...node, init: null, }); + return; } if (node.test && isTypeAssertion(node.test)) { - return rules.ForStatement({ + rules.ForStatement({ ...node, test: null, }); + return; } if (node.update && isTypeAssertion(node.update)) { - return rules.ForStatement({ + rules.ForStatement({ ...node, update: null, }); + return; } - return rules.ForStatement(node); + rules.ForStatement(node); }, 'ForStatement > *.init:exit'(node: TSESTree.Node) { if (!isTypeAssertion(node)) { - return rules['ForStatement > *.init:exit'](node); + rules['ForStatement > *.init:exit'](node); + return; } }, // IfStatement @@ -237,16 +253,17 @@ export default createRule({ MemberExpression(node) { if (isTypeAssertion(node.object)) { // reduces the precedence of the node so the rule thinks it needs to be wrapped - return rules.MemberExpression({ + rules.MemberExpression({ ...node, object: { ...node.object, type: AST_NODE_TYPES.SequenceExpression as any, }, }); + return; } - return rules.MemberExpression(node); + rules.MemberExpression(node); }, NewExpression: callExp, // ObjectExpression @@ -254,18 +271,21 @@ export default createRule({ // SequenceExpression SpreadElement(node) { if (!isTypeAssertion(node.argument)) { - return rules.SpreadElement(node); + rules.SpreadElement(node); + return; } }, SwitchCase(node) { if (node.test && !isTypeAssertion(node.test)) { - return rules.SwitchCase(node); + rules.SwitchCase(node); + return; } }, // SwitchStatement ThrowStatement(node) { if (node.argument && !isTypeAssertion(node.argument)) { - return rules.ThrowStatement(node); + rules.ThrowStatement(node); + return; } }, UnaryExpression: unaryUpdateExpression, @@ -275,7 +295,8 @@ export default createRule({ // WithStatement - i'm not going to even bother implementing this terrible and never used feature YieldExpression(node) { if (node.argument && !isTypeAssertion(node.argument)) { - return rules.YieldExpression(node); + rules.YieldExpression(node); + return; } }, }; @@ -288,12 +309,12 @@ export default createRule({ return; } - return rules.ForInStatement(node); + rules.ForInStatement(node); }; overrides.ForOfStatement = function (node): void { if (isTypeAssertion(node.right)) { // makes the rule skip checking of the right - return rules.ForOfStatement({ + rules.ForOfStatement({ ...node, type: AST_NODE_TYPES.ForOfStatement, right: { @@ -301,9 +322,10 @@ export default createRule({ type: AST_NODE_TYPES.SequenceExpression as any, }, }); + return; } - return rules.ForOfStatement(node); + rules.ForOfStatement(node); }; } else { overrides['ForInStatement, ForOfStatement'] = function ( @@ -311,7 +333,7 @@ export default createRule({ ): void { if (isTypeAssertion(node.right)) { // makes the rule skip checking of the right - return rules['ForInStatement, ForOfStatement']({ + rules['ForInStatement, ForOfStatement']({ ...node, type: AST_NODE_TYPES.ForOfStatement as any, right: { @@ -319,9 +341,10 @@ export default createRule({ type: AST_NODE_TYPES.SequenceExpression as any, }, }); + return; } - return rules['ForInStatement, ForOfStatement'](node); + rules['ForInStatement, ForOfStatement'](node); }; } return Object.assign({}, rules, overrides); diff --git a/packages/eslint-plugin/src/rules/no-restricted-imports.ts b/packages/eslint-plugin/src/rules/no-restricted-imports.ts index b1e2d229f6a7..8026ad3fd18c 100644 --- a/packages/eslint-plugin/src/rules/no-restricted-imports.ts +++ b/packages/eslint-plugin/src/rules/no-restricted-imports.ts @@ -300,10 +300,12 @@ export default createRule({ !isAllowedTypeImportPath(importSource) && !isAllowedTypeImportPattern(importSource) ) { - return rules.ImportDeclaration(node); + rules.ImportDeclaration(node); + return; } } else { - return rules.ImportDeclaration(node); + rules.ImportDeclaration(node); + return; } } @@ -331,7 +333,8 @@ export default createRule({ }, ], } satisfies TSESTree.ImportDeclaration; - return checkImportNode(synthesizedImport); + checkImportNode(synthesizedImport); + return; } }, ImportDeclaration: checkImportNode, @@ -350,10 +353,12 @@ export default createRule({ !isAllowedTypeImportPath(importSource) && !isAllowedTypeImportPattern(importSource) ) { - return rules.ExportNamedDeclaration(node); + rules.ExportNamedDeclaration(node); + return; } } else { - return rules.ExportNamedDeclaration(node); + rules.ExportNamedDeclaration(node); + return; } }, ExportAllDeclaration: rules.ExportAllDeclaration, diff --git a/packages/eslint-plugin/src/rules/no-type-alias.ts b/packages/eslint-plugin/src/rules/no-type-alias.ts index b72c1f8b991a..57ffedecd21a 100644 --- a/packages/eslint-plugin/src/rules/no-type-alias.ts +++ b/packages/eslint-plugin/src/rules/no-type-alias.ts @@ -188,16 +188,17 @@ export default createRule({ type: string, ): void { if (isRoot) { - return context.report({ + context.report({ node, messageId: 'noTypeAlias', data: { alias: type.toLowerCase(), }, }); + return; } - return context.report({ + context.report({ node, messageId: 'noCompositionAlias', data: { diff --git a/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts b/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts index 34ebfc018d6a..36639ccf26fc 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts @@ -232,7 +232,8 @@ export default createRule({ node.type === AST_NODE_TYPES.UnaryExpression && node.operator === '!' ) { - return checkNode(node.argument, true); + checkNode(node.argument, true); + return; } // Since typescript array index signature types don't represent the @@ -252,7 +253,8 @@ export default createRule({ node.type === AST_NODE_TYPES.LogicalExpression && node.operator !== '??' ) { - return checkNode(node.right); + checkNode(node.right); + return; } const type = getConstrainedTypeAtLocation(services, node); @@ -477,7 +479,8 @@ export default createRule({ // Two special cases, where we can directly check the node that's returned: // () => something if (callback.body.type !== AST_NODE_TYPES.BlockStatement) { - return checkNode(callback.body); + checkNode(callback.body); + return; } // () => { return something; } const callbackBody = callback.body.body; @@ -486,7 +489,8 @@ export default createRule({ callbackBody[0].type === AST_NODE_TYPES.ReturnStatement && callbackBody[0].argument ) { - return checkNode(callbackBody[0].argument); + checkNode(callbackBody[0].argument); + return; } // Potential enhancement: could use code-path analysis to check // any function with a single return statement @@ -507,16 +511,18 @@ export default createRule({ return; } if (!returnTypes.some(isPossiblyFalsy)) { - return context.report({ + context.report({ node: callback, messageId: 'alwaysTruthyFunc', }); + return; } if (!returnTypes.some(isPossiblyTruthy)) { - return context.report({ + context.report({ node: callback, messageId: 'alwaysFalsyFunc', }); + return; } } } @@ -716,10 +722,14 @@ export default createRule({ AssignmentExpression: checkAssignmentExpression, BinaryExpression: checkIfBinaryExpressionIsNecessaryConditional, CallExpression: checkCallExpression, - ConditionalExpression: (node): void => checkNode(node.test), + ConditionalExpression: (node): void => { + checkNode(node.test); + }, DoWhileStatement: checkIfLoopIsNecessaryConditional, ForStatement: checkIfLoopIsNecessaryConditional, - IfStatement: (node): void => checkNode(node.test), + IfStatement: (node): void => { + checkNode(node.test); + }, LogicalExpression: checkLogicalExpressionForUnnecessaryConditionals, WhileStatement: checkIfLoopIsNecessaryConditional, 'MemberExpression[optional = true]': checkOptionalMemberExpression, diff --git a/packages/eslint-plugin/src/rules/no-unsafe-return.ts b/packages/eslint-plugin/src/rules/no-unsafe-return.ts index fa301bafa652..7fc94597b0b9 100644 --- a/packages/eslint-plugin/src/rules/no-unsafe-return.ts +++ b/packages/eslint-plugin/src/rules/no-unsafe-return.ts @@ -152,13 +152,14 @@ export default createRule({ } // If the function return type was not unknown/unknown[], mark usage as unsafeReturn. - return context.report({ + context.report({ node: reportingNode, messageId, data: { type: anyType === AnyType.Any ? 'any' : 'any[]', }, }); + return; } for (const signature of functionType.getCallSignatures()) { @@ -174,7 +175,7 @@ export default createRule({ } const { sender, receiver } = result; - return context.report({ + context.report({ node: reportingNode, messageId: 'unsafeReturnAssignment', data: { @@ -182,6 +183,7 @@ export default createRule({ receiver: checker.typeToString(receiver), }, }); + return; } } diff --git a/packages/eslint-plugin/src/rules/prefer-regexp-exec.ts b/packages/eslint-plugin/src/rules/prefer-regexp-exec.ts index 4669cc2a97c6..4cff91a19e84 100644 --- a/packages/eslint-plugin/src/rules/prefer-regexp-exec.ts +++ b/packages/eslint-plugin/src/rules/prefer-regexp-exec.ts @@ -125,7 +125,7 @@ export default createRule({ } catch { return; } - return context.report({ + context.report({ node: memberNode.property, messageId: 'regExpExecOverStringMatch', fix: getWrappingFixer({ @@ -135,6 +135,7 @@ export default createRule({ wrap: objectCode => `${regExp.toString()}.exec(${objectCode})`, }), }); + return; } const argumentType = services.getTypeAtLocation(argumentNode); @@ -142,8 +143,8 @@ export default createRule({ tsutils.unionTypeParts(argumentType), ); switch (argumentTypes) { - case ArgumentType.RegExp: - return context.report({ + case ArgumentType.RegExp: { + context.report({ node: memberNode.property, messageId: 'regExpExecOverStringMatch', fix: getWrappingFixer({ @@ -154,9 +155,11 @@ export default createRule({ `${argumentCode}.exec(${objectCode})`, }), }); + return; + } - case ArgumentType.String: - return context.report({ + case ArgumentType.String: { + context.report({ node: memberNode.property, messageId: 'regExpExecOverStringMatch', fix: getWrappingFixer({ @@ -167,6 +170,8 @@ export default createRule({ `RegExp(${argumentCode}).exec(${objectCode})`, }), }); + return; + } } }, }; diff --git a/packages/eslint-plugin/src/rules/promise-function-async.ts b/packages/eslint-plugin/src/rules/promise-function-async.ts index 2c286cb45506..868563984804 100644 --- a/packages/eslint-plugin/src/rules/promise-function-async.ts +++ b/packages/eslint-plugin/src/rules/promise-function-async.ts @@ -142,11 +142,12 @@ export default createRule({ if (isTypeFlagSet(returnType, ts.TypeFlags.Any | ts.TypeFlags.Unknown)) { // Report without auto fixer because the return type is unknown - return context.report({ + context.report({ messageId: 'missingAsync', node, loc: getFunctionHeadLoc(node, sourceCode), }); + return; } context.report({ diff --git a/packages/eslint-plugin/src/rules/restrict-plus-operands.ts b/packages/eslint-plugin/src/rules/restrict-plus-operands.ts index 9e17fa486b52..3ffc346510d2 100644 --- a/packages/eslint-plugin/src/rules/restrict-plus-operands.ts +++ b/packages/eslint-plugin/src/rules/restrict-plus-operands.ts @@ -208,7 +208,7 @@ export default createRule({ isTypeFlagSetInUnion(baseType, ts.TypeFlags.StringLike) && isTypeFlagSetInUnion(otherType, ts.TypeFlags.NumberLike) ) { - return context.report({ + context.report({ data: { stringLike, left: typeChecker.typeToString(leftType), @@ -217,13 +217,14 @@ export default createRule({ messageId: 'mismatched', node, }); + return; } if ( isTypeFlagSetInUnion(baseType, ts.TypeFlags.NumberLike) && isTypeFlagSetInUnion(otherType, ts.TypeFlags.BigIntLike) ) { - return context.report({ + context.report({ data: { left: typeChecker.typeToString(leftType), right: typeChecker.typeToString(rightType), @@ -231,6 +232,7 @@ export default createRule({ messageId: 'bigintAndNumber', node, }); + return; } } } diff --git a/packages/eslint-plugin/src/rules/sort-type-constituents.ts b/packages/eslint-plugin/src/rules/sort-type-constituents.ts index 856ed2067727..d48de4b350b6 100644 --- a/packages/eslint-plugin/src/rules/sort-type-constituents.ts +++ b/packages/eslint-plugin/src/rules/sort-type-constituents.ts @@ -232,7 +232,7 @@ export default createRule({ return fixer.replaceText(node, sorted); }; - return context.report({ + context.report({ node, messageId, data, @@ -249,6 +249,7 @@ export default createRule({ } : { fix }), }); + return; } } } diff --git a/packages/eslint-plugin/tests/docs.test.ts b/packages/eslint-plugin/tests/docs.test.ts index 9d99ca159103..965d86bc653c 100644 --- a/packages/eslint-plugin/tests/docs.test.ts +++ b/packages/eslint-plugin/tests/docs.test.ts @@ -107,9 +107,9 @@ describe('Validating rule docs', () => { // Get all H2 headings objects as the other levels are variable by design. const headings = tokens.filter(tokenIsH2); - headings.forEach(heading => - expect(heading.text).toBe(titleCase(heading.text)), - ); + headings.forEach(heading => { + expect(heading.text).toBe(titleCase(heading.text)); + }); }); const headings = tokens.filter(tokenIsHeading); diff --git a/packages/rule-tester/src/utils/validationHelpers.ts b/packages/rule-tester/src/utils/validationHelpers.ts index 34e0ca3277de..72885c4aef97 100644 --- a/packages/rule-tester/src/utils/validationHelpers.ts +++ b/packages/rule-tester/src/utils/validationHelpers.ts @@ -111,10 +111,16 @@ export function wrapParser(parser: Parser.ParserModule): Parser.ParserModule { simpleTraverse(ast, { visitorKeys: visitorKeys, - enter: node => defineStartEndAsError('node', node), + enter: node => { + defineStartEndAsError('node', node); + }, + }); + ast.tokens?.forEach(token => { + defineStartEndAsError('token', token); + }); + ast.comments?.forEach(comment => { + defineStartEndAsError('token', comment); }); - ast.tokens?.forEach(token => defineStartEndAsError('token', token)); - ast.comments?.forEach(comment => defineStartEndAsError('token', comment)); } if ('parseForESLint' in parser) { diff --git a/packages/rule-tester/tests/RuleTester.test.ts b/packages/rule-tester/tests/RuleTester.test.ts index 2cfc3678ad58..25faa360f2fc 100644 --- a/packages/rule-tester/tests/RuleTester.test.ts +++ b/packages/rule-tester/tests/RuleTester.test.ts @@ -60,7 +60,9 @@ jest.mock('@typescript-eslint/parser', () => { /* eslint-disable jest/prefer-spy-on -- we need to specifically assign to the properties or else it will use the global value and register actual tests! */ -const IMMEDIATE_CALLBACK: RuleTesterTestFrameworkFunctionBase = (_, cb) => cb(); +const IMMEDIATE_CALLBACK: RuleTesterTestFrameworkFunctionBase = (_, cb) => { + cb(); +}; RuleTester.afterAll = jest.fn(/* intentionally don't immediate callback here */); RuleTester.describe = jest.fn(IMMEDIATE_CALLBACK); @@ -309,7 +311,7 @@ describe('RuleTester', () => { }, }); - expect(() => + expect(() => { ruleTester.run('my-rule', NOOP_RULE, { valid: [ { @@ -319,8 +321,8 @@ describe('RuleTester', () => { ], invalid: [], - }), - ).toThrowErrorMatchingInlineSnapshot( + }); + }).toThrowErrorMatchingInlineSnapshot( `"Do not set the parser at the test level unless you want to use a parser other than "@typescript-eslint/parser""`, ); }); diff --git a/packages/scope-manager/src/referencer/ClassVisitor.ts b/packages/scope-manager/src/referencer/ClassVisitor.ts index 33b48c7a103b..d96131132d6e 100644 --- a/packages/scope-manager/src/referencer/ClassVisitor.ts +++ b/packages/scope-manager/src/referencer/ClassVisitor.ts @@ -57,7 +57,9 @@ class ClassVisitor extends Visitor { .defineIdentifier(node.id, new ClassNameDefinition(node.id, node)); } - node.decorators.forEach(d => this.#referencer.visit(d)); + node.decorators.forEach(d => { + this.#referencer.visit(d); + }); this.#referencer.scopeManager.nestClassScope(node); @@ -75,7 +77,9 @@ class ClassVisitor extends Visitor { this.visitType(node.typeParameters); // then the usages this.visitType(node.superTypeArguments); - node.implements.forEach(imp => this.visitType(imp)); + node.implements.forEach(imp => { + this.visitType(imp); + }); this.visit(node.body); @@ -218,7 +222,9 @@ class ClassVisitor extends Visitor { { processRightHandNodes: true }, ); this.visitFunctionParameterTypeAnnotation(param, withMethodDecorators); - param.decorators.forEach(d => this.visit(d)); + param.decorators.forEach(d => { + this.visit(d); + }); } this.visitMetadataType(node.returnType, withMethodDecorators); @@ -260,7 +266,9 @@ class ClassVisitor extends Visitor { } } - node.decorators.forEach(d => this.#referencer.visit(d)); + node.decorators.forEach(d => { + this.#referencer.visit(d); + }); } protected visitMethod(node: TSESTree.MethodDefinition): void { @@ -274,7 +282,9 @@ class ClassVisitor extends Visitor { this.#referencer.visit(node.value); } - node.decorators.forEach(d => this.#referencer.visit(d)); + node.decorators.forEach(d => { + this.#referencer.visit(d); + }); } protected visitType(node: TSESTree.Node | null | undefined): void { @@ -378,7 +388,9 @@ class ClassVisitor extends Visitor { protected StaticBlock(node: TSESTree.StaticBlock): void { this.#referencer.scopeManager.nestClassStaticBlockScope(node); - node.body.forEach(b => this.visit(b)); + node.body.forEach(b => { + this.visit(b); + }); this.#referencer.close(node); } diff --git a/packages/scope-manager/src/referencer/Referencer.ts b/packages/scope-manager/src/referencer/Referencer.ts index 6082f4846611..e8ad0c26ab8d 100644 --- a/packages/scope-manager/src/referencer/Referencer.ts +++ b/packages/scope-manager/src/referencer/Referencer.ts @@ -270,7 +270,9 @@ class Referencer extends Visitor { { processRightHandNodes: true }, ); this.visitFunctionParameterTypeAnnotation(param); - param.decorators.forEach(d => this.visit(d)); + param.decorators.forEach(d => { + this.visit(d); + }); } this.visitType(node.returnType); diff --git a/packages/scope-manager/src/scope/ScopeBase.ts b/packages/scope-manager/src/scope/ScopeBase.ts index 1cdb2c98586c..6cd33f93fa80 100644 --- a/packages/scope-manager/src/scope/ScopeBase.ts +++ b/packages/scope-manager/src/scope/ScopeBase.ts @@ -365,7 +365,9 @@ abstract class ScopeBase< // Try Resolving all references in this scope. assert(this.leftToResolve); - this.leftToResolve.forEach(ref => closeRef(ref, scopeManager)); + this.leftToResolve.forEach(ref => { + closeRef(ref, scopeManager); + }); this.leftToResolve = null; return this.upper; diff --git a/packages/scope-manager/src/scope/WithScope.ts b/packages/scope-manager/src/scope/WithScope.ts index 7058ab70faa5..9ab1a377697b 100644 --- a/packages/scope-manager/src/scope/WithScope.ts +++ b/packages/scope-manager/src/scope/WithScope.ts @@ -23,7 +23,9 @@ class WithScope extends ScopeBase< return super.close(scopeManager); } assert(this.leftToResolve); - this.leftToResolve.forEach(ref => this.delegateToUpperScope(ref)); + this.leftToResolve.forEach(ref => { + this.delegateToUpperScope(ref); + }); this.leftToResolve = null; return this.upper; } diff --git a/packages/scope-manager/tests/eslint-scope/references.test.ts b/packages/scope-manager/tests/eslint-scope/references.test.ts index c7973556f269..db75364ee1ce 100644 --- a/packages/scope-manager/tests/eslint-scope/references.test.ts +++ b/packages/scope-manager/tests/eslint-scope/references.test.ts @@ -447,7 +447,7 @@ describe('References:', () => { 'new function({b: a = 0} = {}) {}', ]; - trueCodes.forEach(code => + trueCodes.forEach(code => { it(`"${code}", all references should be true.`, () => { const { scopeManager } = parseAndAnalyze(code); @@ -464,8 +464,8 @@ describe('References:', () => { expect(reference.isWrite()).toBeTruthy(); expect(reference.init).toBeTruthy(); }); - }), - ); + }); + }); let falseCodes = [ 'let a; a = 0;', @@ -481,7 +481,7 @@ describe('References:', () => { 'let a; for ({a = 0} in []);', ]; - falseCodes.forEach(code => + falseCodes.forEach(code => { it(`"${code}", all references should be false.`, () => { const { scopeManager } = parseAndAnalyze(code); @@ -498,8 +498,8 @@ describe('References:', () => { expect(reference.isWrite()).toBeTruthy(); expect(reference.init).toBeFalsy(); }); - }), - ); + }); + }); falseCodes = [ 'let a; let b = a;', @@ -517,7 +517,7 @@ describe('References:', () => { 'let a; a.foo = 0;', 'let a,b; b = a.foo;', ]; - falseCodes.forEach(code => + falseCodes.forEach(code => { it(`"${code}", readonly references of "a" should be undefined.`, () => { const { scopeManager } = parseAndAnalyze(code); @@ -537,8 +537,8 @@ describe('References:', () => { expect(reference.isRead()).toBeTruthy(); expect(reference.init).toBeUndefined(); }); - }), - ); + }); + }); }); describe('When emitDecoratorMetadata is true', () => { diff --git a/packages/scope-manager/tests/fixtures.test.ts b/packages/scope-manager/tests/fixtures.test.ts index 94510960bd97..6e28ae8f219b 100644 --- a/packages/scope-manager/tests/fixtures.test.ts +++ b/packages/scope-manager/tests/fixtures.test.ts @@ -172,7 +172,9 @@ function nestDescribe( } } -fixtures.forEach(f => nestDescribe(f)); +fixtures.forEach(f => { + nestDescribe(f); +}); if (ONLY === '') { // ensure that the snapshots are cleaned up, because jest-specific-snapshot won't do this check diff --git a/packages/type-utils/tests/isTypeReadonly.test.ts b/packages/type-utils/tests/isTypeReadonly.test.ts index 2adfaaec7aa8..c88970dc8975 100644 --- a/packages/type-utils/tests/isTypeReadonly.test.ts +++ b/packages/type-utils/tests/isTypeReadonly.test.ts @@ -139,13 +139,15 @@ describe('isTypeReadonly', () => { describe('is readonly circular', () => { const runTests = runTestIsReadonly; - it('handles circular readonly PropertySignature inside a readonly IndexSignature', () => - runTests('interface Test { readonly [key: string]: Test };')); + it('handles circular readonly PropertySignature inside a readonly IndexSignature', () => { + runTests('interface Test { readonly [key: string]: Test };'); + }); - it('handles circular readonly PropertySignature inside interdependent objects', () => + it('handles circular readonly PropertySignature inside interdependent objects', () => { runTests( 'interface Test1 { readonly [key: string]: Test } interface Test { readonly [key: string]: Test1 }', - )); + ); + }); }); describe('is not readonly', () => { @@ -163,8 +165,9 @@ describe('isTypeReadonly', () => { describe('is not readonly circular', () => { const runTests = runTestIsNotReadonly; - it('handles circular mutable PropertySignature', () => - runTests('interface Test { [key: string]: Test };')); + it('handles circular mutable PropertySignature', () => { + runTests('interface Test { [key: string]: Test };'); + }); it.each([ [ diff --git a/packages/types/tools/copy-ast-spec.ts b/packages/types/tools/copy-ast-spec.ts index fe5412061c8e..66c008191f0f 100644 --- a/packages/types/tools/copy-ast-spec.ts +++ b/packages/types/tools/copy-ast-spec.ts @@ -19,9 +19,15 @@ async function execAsync( stdio: 'inherit', }); - child.on('error', e => reject(e)); - child.on('exit', () => resolve()); - child.on('close', () => resolve()); + child.on('error', e => { + reject(e); + }); + child.on('exit', () => { + resolve(); + }); + child.on('close', () => { + resolve(); + }); }); } diff --git a/packages/typescript-estree/src/create-program/getWatchProgramsForProjects.ts b/packages/typescript-estree/src/create-program/getWatchProgramsForProjects.ts index 21178000ee5e..f206371ecebf 100644 --- a/packages/typescript-estree/src/create-program/getWatchProgramsForProjects.ts +++ b/packages/typescript-estree/src/create-program/getWatchProgramsForProjects.ts @@ -146,9 +146,9 @@ function getWatchProgramsForProjects( fileWatchCallbacks && fileWatchCallbacks.size > 0 ) { - fileWatchCallbacks.forEach(cb => - cb(filePath, ts.FileWatcherEventKind.Changed), - ); + fileWatchCallbacks.forEach(cb => { + cb(filePath, ts.FileWatcherEventKind.Changed); + }); } const currentProjectsFromSettings = new Set(parseSettings.projects); @@ -400,9 +400,9 @@ function maybeInvalidateProgram( * We need to make sure typescript knows this so it can update appropriately */ log('tsconfig has changed - triggering program update. %s', tsconfigPath); - fileWatchCallbackTrackingMap - .get(tsconfigPath)! - .forEach(cb => cb(tsconfigPath, ts.FileWatcherEventKind.Changed)); + fileWatchCallbackTrackingMap.get(tsconfigPath)!.forEach(cb => { + cb(tsconfigPath, ts.FileWatcherEventKind.Changed); + }); // tsconfig change means that the file list more than likely changed, so clear the cache programFileListCache.delete(tsconfigPath); @@ -487,9 +487,9 @@ function maybeInvalidateProgram( } log('Marking file as deleted. %s', deletedFile); - fileWatchCallbacks.forEach(cb => - cb(deletedFile, ts.FileWatcherEventKind.Deleted), - ); + fileWatchCallbacks.forEach(cb => { + cb(deletedFile, ts.FileWatcherEventKind.Deleted); + }); // deleted files means that the file list _has_ changed, so clear the cache programFileListCache.delete(tsconfigPath); diff --git a/packages/typescript-estree/tests/lib/persistentParse.test.ts b/packages/typescript-estree/tests/lib/persistentParse.test.ts index 710b9c54ab5a..5c601a842a34 100644 --- a/packages/typescript-estree/tests/lib/persistentParse.test.ts +++ b/packages/typescript-estree/tests/lib/persistentParse.test.ts @@ -23,7 +23,9 @@ afterEach(() => { clearWatchCaches(); // clean up the temporary files and folders - tmpDirs.forEach(t => t.removeCallback()); + tmpDirs.forEach(t => { + t.removeCallback(); + }); tmpDirs.clear(); // restore original cwd @@ -95,31 +97,47 @@ function baseTests( it('parses both files successfully when included', () => { const PROJECT_DIR = setup(tsConfigIncludeAll); - expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); - expect(() => parseFile('bar', PROJECT_DIR)).not.toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR); + }).not.toThrow(); + expect(() => { + parseFile('bar', PROJECT_DIR); + }).not.toThrow(); }); it('parses included files, and throws on excluded files', () => { const PROJECT_DIR = setup(tsConfigExcludeBar); - expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); - expect(() => parseFile('bar', PROJECT_DIR)).toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR); + }).not.toThrow(); + expect(() => { + parseFile('bar', PROJECT_DIR); + }).toThrow(); }); it('allows parsing of new files', () => { const PROJECT_DIR = setup(tsConfigIncludeAll, false); // parse once to: assert the config as correct, and to make sure the program is setup - expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR); + }).not.toThrow(); // bar should throw because it doesn't exist yet - expect(() => parseFile('bar', PROJECT_DIR)).toThrow(); + expect(() => { + parseFile('bar', PROJECT_DIR); + }).toThrow(); // write a new file and attempt to parse it writeFile(PROJECT_DIR, 'bar'); // both files should parse fine now - expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); - expect(() => parseFile('bar', PROJECT_DIR)).not.toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR); + }).not.toThrow(); + expect(() => { + parseFile('bar', PROJECT_DIR); + }).not.toThrow(); }); it('allows parsing of deeply nested new files', () => { @@ -127,22 +145,32 @@ function baseTests( const bazSlashBar = 'baz/bar' as const; // parse once to: assert the config as correct, and to make sure the program is setup - expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR); + }).not.toThrow(); // bar should throw because it doesn't exist yet - expect(() => parseFile(bazSlashBar, PROJECT_DIR)).toThrow(); + expect(() => { + parseFile(bazSlashBar, PROJECT_DIR); + }).toThrow(); // write a new file and attempt to parse it writeFile(PROJECT_DIR, bazSlashBar); // both files should parse fine now - expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); - expect(() => parseFile(bazSlashBar, PROJECT_DIR)).not.toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR); + }).not.toThrow(); + expect(() => { + parseFile(bazSlashBar, PROJECT_DIR); + }).not.toThrow(); }); it('allows parsing of deeply nested new files in new folder', () => { const PROJECT_DIR = setup(tsConfigIncludeAll); - expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR); + }).not.toThrow(); // Create deep folder structure after first parse (this is important step) // context: https://github.com/typescript-eslint/typescript-eslint/issues/1394 @@ -154,7 +182,9 @@ function baseTests( // write a new file and attempt to parse it writeFile(PROJECT_DIR, bazSlashBar); - expect(() => parseFile(bazSlashBar, PROJECT_DIR)).not.toThrow(); + expect(() => { + parseFile(bazSlashBar, PROJECT_DIR); + }).not.toThrow(); }); it('allows renaming of files', () => { @@ -162,40 +192,60 @@ function baseTests( const bazSlashBar = 'baz/bar' as const; // parse once to: assert the config as correct, and to make sure the program is setup - expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR); + }).not.toThrow(); // bar should throw because it doesn't exist yet - expect(() => parseFile(bazSlashBar, PROJECT_DIR)).toThrow(); + expect(() => { + parseFile(bazSlashBar, PROJECT_DIR); + }).toThrow(); // write a new file and attempt to parse it renameFile(PROJECT_DIR, 'bar', bazSlashBar); // both files should parse fine now - expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); - expect(() => parseFile(bazSlashBar, PROJECT_DIR)).not.toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR); + }).not.toThrow(); + expect(() => { + parseFile(bazSlashBar, PROJECT_DIR); + }).not.toThrow(); }); it('reacts to changes in the tsconfig', () => { const PROJECT_DIR = setup(tsConfigExcludeBar); // parse once to: assert the config as correct, and to make sure the program is setup - expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); - expect(() => parseFile('bar', PROJECT_DIR)).toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR); + }).not.toThrow(); + expect(() => { + parseFile('bar', PROJECT_DIR); + }).toThrow(); // change the config file so it now includes all files writeTSConfig(PROJECT_DIR, tsConfigIncludeAll); clearCaches(); - expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); - expect(() => parseFile('bar', PROJECT_DIR)).not.toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR); + }).not.toThrow(); + expect(() => { + parseFile('bar', PROJECT_DIR); + }).not.toThrow(); }); it('should work with relative paths', () => { const PROJECT_DIR = setup(tsConfigIncludeAll, false); // parse once to: assert the config as correct, and to make sure the program is setup - expect(() => parseFile('foo', PROJECT_DIR, true)).not.toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR, true); + }).not.toThrow(); // bar should throw because it doesn't exist yet - expect(() => parseFile('bar', PROJECT_DIR, true)).toThrow(); + expect(() => { + parseFile('bar', PROJECT_DIR, true); + }).toThrow(); // write a new file and attempt to parse it writeFile(PROJECT_DIR, 'bar'); @@ -204,8 +254,12 @@ function baseTests( expect(existsSync('bar', PROJECT_DIR)).toBe(true); // both files should parse fine now - expect(() => parseFile('foo', PROJECT_DIR, true)).not.toThrow(); - expect(() => parseFile('bar', PROJECT_DIR, true)).not.toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR, true); + }).not.toThrow(); + expect(() => { + parseFile('bar', PROJECT_DIR, true); + }).not.toThrow(); }); it('should work with relative paths without tsconfig root', () => { @@ -213,9 +267,13 @@ function baseTests( process.chdir(PROJECT_DIR); // parse once to: assert the config as correct, and to make sure the program is setup - expect(() => parseFile('foo', PROJECT_DIR, true, true)).not.toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR, true, true); + }).not.toThrow(); // bar should throw because it doesn't exist yet - expect(() => parseFile('bar', PROJECT_DIR, true, true)).toThrow(); + expect(() => { + parseFile('bar', PROJECT_DIR, true, true); + }).toThrow(); // write a new file and attempt to parse it writeFile(PROJECT_DIR, 'bar'); @@ -225,8 +283,12 @@ function baseTests( expect(existsSync('bar', PROJECT_DIR)).toBe(true); // both files should parse fine now - expect(() => parseFile('foo', PROJECT_DIR, true, true)).not.toThrow(); - expect(() => parseFile('bar', PROJECT_DIR, true, true)).not.toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR, true, true); + }).not.toThrow(); + expect(() => { + parseFile('bar', PROJECT_DIR, true, true); + }).not.toThrow(); }); } @@ -278,15 +340,23 @@ describe('persistent parse', () => { const PROJECT_DIR = setup({}, false); // parse once to: assert the config as correct, and to make sure the program is setup - expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); - expect(() => parseFile('bar', PROJECT_DIR)).toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR); + }).not.toThrow(); + expect(() => { + parseFile('bar', PROJECT_DIR); + }).toThrow(); // write a new file and attempt to parse it writeFile(PROJECT_DIR, 'bar'); clearCaches(); - expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); - expect(() => parseFile('bar', PROJECT_DIR)).not.toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR); + }).not.toThrow(); + expect(() => { + parseFile('bar', PROJECT_DIR); + }).not.toThrow(); }); it('handles tsconfigs with no includes/excludes (nested)', () => { @@ -294,15 +364,23 @@ describe('persistent parse', () => { const bazSlashBar = 'baz/bar' as const; // parse once to: assert the config as correct, and to make sure the program is setup - expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); - expect(() => parseFile(bazSlashBar, PROJECT_DIR)).toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR); + }).not.toThrow(); + expect(() => { + parseFile(bazSlashBar, PROJECT_DIR); + }).toThrow(); // write a new file and attempt to parse it writeFile(PROJECT_DIR, bazSlashBar); clearCaches(); - expect(() => parseFile('foo', PROJECT_DIR)).not.toThrow(); - expect(() => parseFile(bazSlashBar, PROJECT_DIR)).not.toThrow(); + expect(() => { + parseFile('foo', PROJECT_DIR); + }).not.toThrow(); + expect(() => { + parseFile(bazSlashBar, PROJECT_DIR); + }).not.toThrow(); }); }); } @@ -346,7 +424,9 @@ describe('persistent parse', () => { it(`first parse of ${name} should not throw`, () => { const PROJECT_DIR = setup(tsConfigIncludeAll); writeFile(PROJECT_DIR, name); - expect(() => parseFile(name, PROJECT_DIR)).not.toThrow(); + expect(() => { + parseFile(name, PROJECT_DIR); + }).not.toThrow(); }); } }); diff --git a/packages/typescript-estree/tests/lib/semanticInfo.test.ts b/packages/typescript-estree/tests/lib/semanticInfo.test.ts index f5f78934a880..8e0e00dc5309 100644 --- a/packages/typescript-estree/tests/lib/semanticInfo.test.ts +++ b/packages/typescript-estree/tests/lib/semanticInfo.test.ts @@ -37,7 +37,9 @@ function createOptions(fileName: string): TSESTreeOptions & { cwd?: string } { } // ensure tsconfig-parser watch caches are clean for each test -beforeEach(() => clearCaches()); +beforeEach(() => { + clearCaches(); +}); describe('semanticInfo', () => { // test all AST snapshots diff --git a/packages/website/src/components/OptionsSelector.tsx b/packages/website/src/components/OptionsSelector.tsx index b881319e58ab..bc3b2febec1e 100644 --- a/packages/website/src/components/OptionsSelector.tsx +++ b/packages/website/src/components/OptionsSelector.tsx @@ -56,7 +56,9 @@ function OptionsSelectorContent({ className="text--right" value={state.ts} disabled={!tsVersions.length} - onChange={(ts): void => setState({ ts })} + onChange={(ts): void => { + setState({ ts }); + }} options={tsVersions.length ? tsVersions : [state.ts]} /> @@ -68,7 +70,9 @@ function OptionsSelectorContent({ setState({ fileType })} + onChange={(fileType): void => { + setState({ fileType }); + }} options={fileTypes} /> @@ -76,7 +80,9 @@ function OptionsSelectorContent({ setState({ sourceType })} + onChange={(sourceType): void => { + setState({ sourceType }); + }} options={['script', 'module']} /> @@ -84,14 +90,18 @@ function OptionsSelectorContent({ setState({ scroll })} + onChange={(scroll): void => { + setState({ scroll }); + }} /> setState({ showTokens })} + onChange={(showTokens): void => { + setState({ showTokens }); + }} /> diff --git a/packages/website/src/components/Playground.tsx b/packages/website/src/components/Playground.tsx index ac06e4652ee4..a717d84fa035 100644 --- a/packages/website/src/components/Playground.tsx +++ b/packages/website/src/components/Playground.tsx @@ -174,7 +174,9 @@ function Playground(): React.JSX.Element { setState({ showAST: v })} + change={(v): void => { + setState({ showAST: v }); + }} /> {state.showAST === 'es' && ( void; mode: FilterMode; }): React.JSX.Element { - const toNextMode = (): void => + const toNextMode = (): void => { setMode(filterModes[(filterModes.indexOf(mode) + 1) % filterModes.length]); + }; return (
  • diff --git a/packages/website/src/components/lib/createEventsBinder.ts b/packages/website/src/components/lib/createEventsBinder.ts index 6b5bfaecbee1..47cc37fd3d17 100644 --- a/packages/website/src/components/lib/createEventsBinder.ts +++ b/packages/website/src/components/lib/createEventsBinder.ts @@ -7,7 +7,9 @@ export function createEventsBinder void>(): { return { trigger(...args: Parameters): void { - events.forEach(cb => cb(...args)); + events.forEach(cb => { + cb(...args); + }); }, register(cb: T): () => void { events.add(cb); diff --git a/packages/website/src/components/linter/bridge.ts b/packages/website/src/components/linter/bridge.ts index 4a4d52e44637..03ffb58e33aa 100644 --- a/packages/website/src/components/linter/bridge.ts +++ b/packages/website/src/components/linter/bridge.ts @@ -48,7 +48,9 @@ export function createFileSystem( ): void => { fileWatcherCallbacks.forEach((callbacks, key) => { if (key.test(path)) { - callbacks.forEach(cb => cb(path, type)); + callbacks.forEach(cb => { + cb(path, type); + }); } }); }; diff --git a/packages/website/src/components/typeDetails/SimplifiedTreeView.tsx b/packages/website/src/components/typeDetails/SimplifiedTreeView.tsx index c5dc1b37926d..3208d85cac17 100644 --- a/packages/website/src/components/typeDetails/SimplifiedTreeView.tsx +++ b/packages/website/src/components/typeDetails/SimplifiedTreeView.tsx @@ -32,7 +32,8 @@ function SimplifiedItem({ const onHover = useCallback( (v: boolean) => { if (isTSNode(value) && onHoverNode) { - return onHoverNode(v ? getRange(value, 'tsNode') : undefined); + onHoverNode(v ? getRange(value, 'tsNode') : undefined); + return; } }, [onHoverNode, value], diff --git a/packages/website/src/hooks/useBool.ts b/packages/website/src/hooks/useBool.ts index b06c9c40e5a4..c4e6c569e8da 100644 --- a/packages/website/src/hooks/useBool.ts +++ b/packages/website/src/hooks/useBool.ts @@ -6,10 +6,9 @@ export function useBool( ): [boolean, () => void, Dispatch>] { const [value, setValue] = useState(initialState); - const toggle = useCallback( - (): void => setValue(currentValue => !currentValue), - [], - ); + const toggle = useCallback((): void => { + setValue(currentValue => !currentValue); + }, []); return [value, toggle, setValue]; } diff --git a/packages/website/src/hooks/useMediaQuery.ts b/packages/website/src/hooks/useMediaQuery.ts index 1bd928c4a4b2..964797e20ddd 100644 --- a/packages/website/src/hooks/useMediaQuery.ts +++ b/packages/website/src/hooks/useMediaQuery.ts @@ -17,8 +17,9 @@ const useMediaQuery = (mediaQuery: string): boolean => { useEffect(() => { const mediaQueryList = window.matchMedia(mediaQuery); - const documentChangeHandler = (): void => + const documentChangeHandler = (): void => { setIsVerified(!!mediaQueryList.matches); + }; try { mediaQueryList.addEventListener('change', documentChangeHandler); diff --git a/packages/website/src/theme/CodeBlock/Content/String.tsx b/packages/website/src/theme/CodeBlock/Content/String.tsx index 6895cab853e2..906ebe3edca3 100644 --- a/packages/website/src/theme/CodeBlock/Content/String.tsx +++ b/packages/website/src/theme/CodeBlock/Content/String.tsx @@ -128,7 +128,9 @@ export default function CodeBlockString({ {(wordWrap.isEnabled || wordWrap.isCodeScrollable) && ( wordWrap.toggle()} + onClick={(): void => { + wordWrap.toggle(); + }} isEnabled={wordWrap.isEnabled} /> )} pFad - Phonifier reborn

    Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

    Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


    Alternative Proxies:

    Alternative Proxy

    pFad Proxy

    pFad v3 Proxy

    pFad v4 Proxy