From c53875054d257fb4e9c088562107bb5038909682 Mon Sep 17 00:00:00 2001 From: Victor Hom Date: Fri, 15 May 2020 22:39:24 -0400 Subject: [PATCH 1/5] add rule for no setState in componentDidUpdate and tests --- packages/@romejs/diagnostics/categories.ts | 61 +++ packages/@romejs/diagnostics/descriptions.ts | 480 ++++++++++++++++++ .../@romejs/js-compiler/lint/rules/index.ts | 121 +++++ .../rules/react/noDidUpdateSetState.test.md | 219 ++++++++ .../rules/react/noDidUpdateSetState.test.ts | 91 ++++ .../lint/rules/react/noDidUpdateSetState.ts | 82 +++ 6 files changed, 1054 insertions(+) create mode 100644 packages/@romejs/js-compiler/lint/rules/react/noDidUpdateSetState.test.md create mode 100644 packages/@romejs/js-compiler/lint/rules/react/noDidUpdateSetState.test.ts create mode 100644 packages/@romejs/js-compiler/lint/rules/react/noDidUpdateSetState.ts diff --git a/packages/@romejs/diagnostics/categories.ts b/packages/@romejs/diagnostics/categories.ts index 8a65544b2a8..99e017aceda 100644 --- a/packages/@romejs/diagnostics/categories.ts +++ b/packages/@romejs/diagnostics/categories.ts @@ -92,6 +92,7 @@ export type DiagnosticCategoryPrefix = // EVERYTHING BELOW IS AUTOGENERATED. SEE SCRIPTS FOLDER FOR UPDATE SCRIPTS type LintDiagnosticCategory = +<<<<<<< HEAD | "lint/camelCase" | "lint/caseSingleStatement" | "lint/confusingLanguage" @@ -155,3 +156,63 @@ type LintDiagnosticCategory = | "lint/unsafeNegation" | "lint/unusedVariables" | "lint/voidDomElementsNoChildren"; +======= + | 'lint/camelCase' + | 'lint/caseSingleStatement' + | 'lint/defaultExportSameBasename' + | 'lint/doubleEquals' + | 'lint/duplicateImportSource' + | 'lint/emptyBlocks' + | 'lint/emptyMatches' + | 'lint/getterReturn' + | 'lint/importDefaultBasename' + | 'lint/inconsiderateLanguage' + | 'lint/jsxKey' + | 'lint/jsxNoCommentText' + | 'lint/negationElse' + | 'lint/noArguments' + | 'lint/noAsyncPromiseExecutor' + | 'lint/noCatchAssign' + | 'lint/noChildrenProp' + | 'lint/noCommaOperator' + | 'lint/noCompareNegZero' + | 'lint/noCondAssign' + | 'lint/noDangerWithChildren' + | 'lint/noDebugger' + | 'lint/noDelete' + | 'lint/noDeleteVars' + | 'lint/noDidUpdateSetState' + | 'lint/noDupeArgs' + | 'lint/noDuplicateCase' + | 'lint/noDuplicateGroupNamesInRegularExpressions' + | 'lint/noDuplicateKeys' + | 'lint/noEmptyCharacterClass' + | 'lint/noExplicitAny' + | 'lint/noExtraBooleanCast' + | 'lint/noFunctionAssign' + | 'lint/noImportAssign' + | 'lint/noLabelVar' + | 'lint/noMultipleSpacesInRegularExpressionLiterals' + | 'lint/noPosixInRegularExpression' + | 'lint/noReferenceToNonExistingGroup' + | 'lint/noSetterReturn' + | 'lint/noShadowRestrictedNames' + | 'lint/noShorthandArrayType' + | 'lint/noTemplateCurlyInString' + | 'lint/noUnsafeFinally' + | 'lint/noVar' + | 'lint/preferBlockStatements' + | 'lint/preferFunctionDeclarations' + | 'lint/preferTemplate' + | 'lint/preferWhile' + | 'lint/reactInJsxScope' + | 'lint/restrictedGlobals' + | 'lint/singleVarDeclarator' + | 'lint/sortImportExportSpecifiers' + | 'lint/sparseArray' + | 'lint/stylePropObject' + | 'lint/undeclaredVariables' + | 'lint/unsafeNegation' + | 'lint/unusedVariables' + | 'lint/voidDomElementsNoChildren'; +>>>>>>> add rule for no setState in componentDidUpdate and tests diff --git a/packages/@romejs/diagnostics/descriptions.ts b/packages/@romejs/diagnostics/descriptions.ts index 14913613a00..3be8eaa4527 100644 --- a/packages/@romejs/diagnostics/descriptions.ts +++ b/packages/@romejs/diagnostics/descriptions.ts @@ -170,6 +170,7 @@ function buildJSXOpeningAdvice( } export const descriptions = createMessages({ +<<<<<<< HEAD FLAGS: { UNSUPPORTED_SHORTHANDS: `Shorthand flags are not supported`, INCORRECT_CASED_FLAG: (flag: string) => ({ @@ -663,6 +664,485 @@ export const descriptions = createMessages({ }, ) => { let adviceMessage = ""; +======= + FLAGS: { + UNSUPPORTED_SHORTHANDS: `Shorthand flags are not supported`, + INCORRECT_CASED_FLAG: (flag: string) => ({ + message: `Incorrect cased flag name`, + advice: [ + { + type: 'log', + category: 'info', + text: markup`Use ${toKebabCase(flag)} instead`, + }, + ], + }), + INCORRECT_ARG_COUNT: (excessive: boolean, message: string) => ({ + message: excessive ? 'Too many arguments' : 'Missing arguments', + advice: [ + { + type: 'log', + category: 'info', + text: message, + }, + ], + }), + DISALLOWED_REVIEW_FLAG: (key: string) => ({ + message: `Flag ${key} is not allowed with review`, + }), + DISALLOWED_REQUEST_FLAG: (key: string) => ({ + message: `This command does not support the ${key} flag`, + }), + UNKNOWN_ACTION: (action: string) => ({ + message: `Unknown action ${action}`, + }), + NO_FILES_FOUND: (noun: undefined | string) => ({ + message: noun === undefined + ? 'No files found' + : `No files to ${noun} found`, + }), + }, + // @romejs/parser-core + PARSER_CORE: { + EXPECTED_SPACE: 'Expected no space between', + EXPECTED_EOF: 'Expected end of file', + UNEXPECTED_EOF: 'Unexpected end of file', + UNEXPECTED: (type: string) => ({ + message: markup`Unexpected ${type}`, + }), + UNEXPECTED_CHARACTER: (char: string) => ({ + message: markup`Unexpected character ${char}`, + }), + EXPECTED_TOKEN: (got: string, expected: string) => { + return { + message: markup`Expected token ${expected} but got ${got}`, + }; + }, + }, + // @romejs/codec-js-regexp + REGEX_PARSER: { + INVALID_CAPTURE_GROUP_MODIFIER: 'Invalid capture group modifier', + UNCLOSED_GROUP: 'Unclosed group', + UNOPENED_GROUP: 'Unopened group', + INVALID_QUANTIFIER_TARGET: 'Invalid target for quantifier', + UNKNOWN_REGEX_PART: 'Unknown regex part', + REVERSED_CHAR_SET_RANGE: 'Range values reversed. Start char code is greater than end char code', + UNCLOSED_CHAR_SET: 'Unclosed character set', + DUPLICATE_FLAG: 'Duplicate regular expression flag', + INVALID_FLAG: 'Invalid regular expression flag', + REVERSED_QUANTIFIER_RANGE: 'Quantifier minimum is greater than maximum', + NO_TARGET_QUANTIFIER: 'Nothing to repeat', + INVALID_NAMED_CAPTURE: 'Invalid named capture referenced', + UNCLOSED_NAMED_CAPTURE: 'Unclosed named capture', + }, + // @romejs/codec-json + JSON: { + SINGLE_QUOTE_USAGE: 'You can only use double quoted strings', + TRAILING_COMMA_VALUE: 'Trailing comma is only allowed after a value', + UNCLOSED_STRING: 'Unclosed string', + UNCLOSED_BLOCK_COMMENT: 'Unclosed block comment', + MISTAKEN_ARRAY_IDENTITY: 'Trying to use an array element as an object property. Did you mean to make an object?', + REDUNDANT_COMMA: 'Redundant comma', + EMPTY_INPUT_IN_JSON: 'Empty input', + PROPERTY_KEY_UNQUOTED_IN_JSON: 'Property keys must be quoted in JSON', + IMPLICIT_OBJECT_IN_JSON: 'Objects must be wrapped in curly braces in JSON', + COMMENTS_IN_JSON: "Comments aren't allowed in JSON", + TRAILING_COMMA_IN_JSON: "Trailing commas aren't allowed in JSON", + REGEX_IN_JSON: "Regular expressions aren't allowed in JSON", + UNKNOWN_WORD_IN_JSON: (word: string) => ({ + message: markup`${word} isn't a valid JSON word`, + }), + STRING_NEWLINES_IN_JSON: "Newlines aren't allowed in JSON, you insert a newline by escaping it like this \"\\n\"", + UNDEFINED_IN_JSON: "undefined isn't allowed in JSON, you could use null instead", + BIGINT_IN_JSON: "Bigints aren't allowed in JSON", + NUMERIC_SEPARATORS_IN_JSON: 'Numeric separators are not allowed in JSON', + }, + // @romejs/codec-semver + SEMVER: { + MISSING_MINOR_VERSION: 'A minor number is required for a version', + MISSING_PATCH_VERSION: 'A patch number is required for a version', + EXCESSIVE_VERSION_PARTS: 'Too many parts for version', + INVALID_QUANTIFIER_PART: 'Invalid version qualifier part', + WILDCARD_IN_VERSION: "Wildcard aren't allowed in a hard version", + INVALID_VERSION_NUMBER: "This isn't a valid version part, expected a number", + INVALID_RANGE: 'A semver range can only be defined with versions', + BARE_PIPE_WITHOUT_LOOSE: 'Bare pipes are only allowed in loose mode', + UNEXPECTED_WORD: (word: string) => ({ + message: markup`Unexpected word ${word}`, + }), + UNKNOWN_START: 'Unknown start of atom', + EXPECTED_VERSION: 'Unexpected value for version', + }, + V8: { + SYNTAX_ERROR: (message: string) => ({message, category: 'v8/syntaxError'}), + }, + // @romejs/core/master/commands/lint.ts + LINT_COMMAND: { + INVALID_DECISION_ACTION: (action: string) => ({ + message: markup`${action} is not a valid decision action`, + }), + INVALID_DECISION_PART_COUNT: (i: number) => ({ + message: `Segment ${i} contains an invalid number of decision parts`, + }), + }, + // @romejs/js-compiler + LINT: { + NO_DID_UPDATE_SET_STATE: { + category: 'lint/noDidUpdateSetState', + message: 'Avoid use setState in ComponentDidUpdate', + }, + IMPORT_DEFAULT_BASENAME: (prev: string, basename: string) => ({ + category: 'lint/importDefaultBasename', + message: markup`When importing the default, use the basename ${basename}`, + advice: [ + { + type: 'log', + category: 'info', + text: 'If you really meant this then use this instead', + }, + { + type: 'code', + code: markup`import {default as ${prev}}`, + }, + ], + }), + NO_COMMA_OPERATOR: { + category: 'lint/noCommaOperator', + message: 'Avoid usage of the comma operator. It can lead to easy mistakes and ambiguous code.', + advice: [ + { + type: 'log', + category: 'info', + text: 'If you want multiple expressions then break it up.', + }, + ], + }, + NEGATION_ELSE: { + category: 'lint/negationElse', + message: 'Invert the blocks when you have a negation test', + }, + STYLE_PROP_OBJECT: { + category: 'lint/stylePropObject', + message: 'style property value must be an object.', + }, + NO_DANGER_WITH_CHILDREN: { + category: 'lint/noDangerWithChildren', + message: 'Only set one of children or props.dangerouslySetInnerHTML.', + }, + PENDING_FIXES: ( + relativeFilename: string, + original: string, + formatted: string, + ) => ({ + category: 'lint/pendingFixes', + message: 'Pending formatting and recommended autofixes', + advice: [ + { + type: 'diff', + diff: stringDiff(original, formatted), + }, + ({ + type: 'action', + command: 'lint', + shortcut: 'f', + instruction: 'To apply fixes and formatting run', + noun: 'Apply fixes and format', + args: [relativeFilename], + commandFlags: { + save: true, + }, + } as DiagnosticAdviceAction), + ({ + type: 'action', + hidden: true, + command: 'lint', + shortcut: 'o', + instruction: 'To format this file without any fixes run', + noun: 'Only format', + args: [relativeFilename], + commandFlags: { + format: true, + }, + } as DiagnosticAdviceAction), + ], + }), + DUPLICATE_IMPORT_SOURCE: (seenLocation: DiagnosticLocation) => ({ + category: 'lint/duplicateImportSource', + message: 'This module has already been imported', + advice: [ + { + type: 'log', + category: 'info', + text: 'Previously imported here', + }, + { + type: 'frame', + location: seenLocation, + }, + ], + }), + NO_CHILDREN_PROP: { + category: 'lint/noChildrenProp', + message: 'children should not be passed as a prop', + }, + PREFER_BLOCK_STATEMENT: { + category: 'lint/preferBlockStatements', + message: 'Block statements are preferred in this position', + }, + PREFER_TEMPLATE: { + category: 'lint/preferTemplate', + message: 'Template literals are preferred over string concatenation', + }, + PREFER_WHILE: { + category: 'lint/preferWhile', + message: 'A while loop should be used over a for loop', + }, + REACT_IN_JSX_SCOPE: { + category: 'lint/reactInJsxScope', + message: markup`"React" must be in scope when using JSX`, + }, + REACT_JSX_VOID_DOM_ELEMENTS_NO_CHILDREN: ( + element: string, + properties: Array, + ) => ({ + category: 'lint/voidDomElementsNoChildren', + message: markup`${element} is a void element tag and must not have ${orJoin( + properties, + )}.`, + }), + REACT_JSX_NO_COMMENT_TEXT: { + category: 'lint/jsxNoCommentText', + message: 'Comments inside children should be placed in braces', + }, + REACT_JSX_KEY: (origin: string) => ({ + category: 'lint/jsxKey', + message: markup`Missing the "key" prop for element in ${origin}`, + }), + UNSAFE_NEGATION: { + category: 'lint/unsafeNegation', + message: 'Unsafe usage of negation operator in left side of binary expression', + }, + UNUSED_VARIABLES: (kind: string, name: string) => ({ + category: 'lint/unusedVariables', + message: markup`Unused ${kind} ${name}`, + }), + UNDECLARED_VARIABLES: (name: string) => ({ + category: 'lint/undeclaredVariables', + message: markup`Undeclared variable ${name}`, + }), + VARIABLE_CAMEL_CASE: (name: string, camelCaseName: string) => ({ + category: 'lint/camelCase', + message: markup`Variable ${name} should be camel cased as ${camelCaseName}`, + }), + IDENTIFIER_CAMEL_CASE: (name: string, camelCaseName: string) => ({ + category: 'lint/camelCase', + message: markup`Identifier ${name} should be camel cased as ${camelCaseName}`, + }), + CASE_SINGLE_STATEMENT: { + category: 'lint/caseSingleStatement', + message: 'A switch case should only have a single statement. If you want more then wrap it in a block.', + }, + INCONSIDERATE_LANGUAGE: ( + description: string, + word: string, + suggestion: string, + ) => ({ + category: 'lint/inconsiderateLanguage', + message: description, + advice: [ + { + type: 'log', + category: 'info', + text: markup`Instead of ${word} use ${suggestion}`, + }, + ], + }), + DOUBLE_EQUALS: { + category: 'lint/doubleEquals', + message: 'Use === instead of ==', + advice: [ + { + type: 'log', + category: 'info', + text: '== is only allowed when comparing against null', + }, + ], + }, + EMPTY_MATCHES: { + category: 'lint/emptyMatches', + message: 'The expression can return empty matches, and may match infinitely in some use cases', + }, + NEGATE_DOUBLE_EQUALS: { + category: 'lint/doubleEquals', + message: 'Use !== instead of !=', + advice: [ + { + type: 'log', + category: 'info', + text: '!= is only allowed when comparing against null', + }, + ], + }, + NO_CATCH_ASSIGN: { + category: 'lint/noCatchAssign', + message: "Don't reassign catch parameters", + }, + SPARSE_ARRAY: { + category: 'lint/sparseArray', + message: 'Your array contains an empty slot', + }, + SINGLE_VAR_DECLARATOR: { + category: 'lint/singleVarDeclarator', + message: 'Declare each variable separately', + }, + PREFER_FUNCTION_DECLARATIONS: { + category: 'lint/preferFunctionDeclarations', + message: 'Use a function declaration instead of a const function', + }, + NO_VAR: { + category: 'lint/noVar', + message: 'Variable declarations using `var` are disallowed, use `let` or `const` instead.', + }, + NO_SHORTHAND_ARRAY_TYPE: { + category: 'lint/noShorthandArrayType', + message: escapeMarkup('Use Array instead of shorthand T[]'), + }, + NO_UNSAFE_FINALLY: (type: string) => ({ + category: 'lint/noUnsafeFinally', + message: markup`Unsafe usage of ${type}.`, + }), + NO_TEMPLATE_CURLY_IN_STRING: { + category: 'lint/noTemplateCurlyInString', + message: `Unexpected template string expression.`, + }, + NO_SHADOW_RESTRICTED_NAMES: (name: string) => ({ + category: 'lint/noShadowRestrictedNames', + message: markup`Shadowing of global property ${name}`, + advice: [ + { + type: 'log', + category: 'info', + text: "Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.", + }, + ], + }), + NO_MULTIPLE_SPACES_IN_REGEX_LITERAL: (count: number) => ({ + category: 'lint/noMultipleSpacesInRegularExpressionLiterals', + message: 'Unclear multiple spaces in regular expression', + advice: [ + { + type: 'log', + category: 'info', + text: `It's hard to visually count the amount of spaces, it's clearer if you use a quantifier instead. eg / {${String( + count, + )}}/`, + }, + ], + }), + NO_LABEL_VAR: { + category: 'lint/noLabelVar', + message: 'Labels should not be variable names', + }, + NO_IMPORT_ASSIGN: (name: string) => ({ + category: 'lint/noImportAssign', + message: markup`${name} is read-only`, + }), + NO_EXTRA_BOOLEAN_CAST: { + category: 'lint/noExtraBooleanCast', + message: `Redundant double negation.`, + }, + NO_FUNCTION_ASSIGN: { + category: 'lint/noFunctionAssign', + message: 'Reassignment of function declaration', + }, + NO_EXPLICIT_ANY: { + category: 'lint/noExplicitAny', + message: 'Unexpected any. Specify a different type.', + }, + NO_EMPTY_CHAR_SET: { + category: 'lint/noEmptyCharacterClass', + message: 'Empty character classes in regular expressions are not allowed', + }, + NO_DUPLICATE_KEYS: (key: string) => ({ + category: 'lint/noDuplicateKeys', + message: markup`Duplicate key ${key}`, + }), + NO_POSIX_IN_REGULAR_EXPRESSION: { + category: 'lint/noPosixInRegularExpression', + message: 'POSIX Character Classes and Collating Sequences are not supported in ECMAscript Regular Expressions', + }, + NO_DUPLICATE_CASE: (value: string) => ({ + category: 'lint/noDuplicateCase', + message: markup`Duplicate case ${value} not allowed.`, + }), + NO_DUPE_ARGS: (name: string) => ({ + category: 'lint/noDupeArgs', + message: markup`Duplicate argument ${name} in function definition`, + }), + NO_DELETE: { + category: 'lint/noDelete', + message: `Unexpected 'delete' operator.`, + }, + NO_DELETE_VARS: { + category: 'lint/noDeleteVars', + message: 'Variables should not be deleted.', + }, + NO_DEBUGGER: { + category: 'lint/noDebugger', + message: "Unexpected 'debugger' statement", + }, + NO_COND_ASSIGN: { + category: 'lint/noCondAssign', + message: 'Cannot assign variable in loop condition', + }, + NO_COMPARE_NEG_ZERO: (op: string) => ({ + category: 'lint/noCompareNegZero', + message: `Do not use the '${op}' operator to compare against -0`, + fixable: op === '===', + }), + NO_ASYNC_PROMISE_EXECUTOR: { + category: 'lint/noAsyncPromiseExecutor', + message: 'Promise executor functions should not be async.', + }, + GETTER_RETURN: (got: string) => ({ + category: 'lint/getterReturn', + message: `Expected a 'return' at end of a getter method but got ${got}`, + }), + NO_SETTER_RETURN: { + category: 'lint/noSetterReturn', + message: `Setter cannot return a value`, + }, + EMPTY_BLOCKS: { + category: 'lint/emptyBlocks', + message: 'Empty block', + }, + NO_ARGUMENTS: { + category: 'lint/noArguments', + message: "Use the rest parameters instead of 'arguments'", + }, + DUPLICATE_REGEX_GROUP_NAME: (name: string) => ({ + category: 'lint/noDuplicateGroupNamesInRegularExpressions', + message: `Duplicate group name ${name} in regular expression`, + }), + NO_REFERENCE_TO_NON_EXISTING_GROUP: (name: string) => ({ + category: 'lint/noReferenceToNonExistingGroup', + message: `Reference to non-existent group "${name}"`, + }), + DEFAULT_EXPORT_SAME_BASENAME: ( + { + defaultName, + defaultType, + actualFilename, + correctFilename, + }: { + defaultName: string; + defaultType: string; + actualFilename: string; + correctFilename: string; + }, + ) => { + let adviceMessage = ''; +>>>>>>> add rule for no setState in componentDidUpdate and tests if (defaultName === "*default*") { adviceMessage += "The"; diff --git a/packages/@romejs/js-compiler/lint/rules/index.ts b/packages/@romejs/js-compiler/lint/rules/index.ts index 7cc0e6d5c4a..6d4ebd0919e 100644 --- a/packages/@romejs/js-compiler/lint/rules/index.ts +++ b/packages/@romejs/js-compiler/lint/rules/index.ts @@ -6,6 +6,7 @@ */ // EVERYTHING BELOW IS AUTOGENERATED. SEE SCRIPTS FOLDER FOR UPDATE SCRIPTS +<<<<<<< HEAD import camelCase from "./regular/camelCase"; import caseSingleStatement from "./regular/caseSingleStatement"; import confusingLanguage from "./regular/confusingLanguage"; @@ -134,4 +135,124 @@ export const lintTransforms = [ unsafeNegation, unusedVariables, voidDomElementsNoChildren, +======= +import camelCase from './regular/camelCase'; +import caseSingleStatement from './regular/caseSingleStatement'; +import defaultExportSameBasename from './regular/defaultExportSameBasename'; +import doubleEquals from './regular/doubleEquals'; +import duplicateImportSource from './regular/duplicateImportSource'; +import emptyBlocks from './regular/emptyBlocks'; +import emptyMatches from './regular/emptyMatches'; +import getterReturn from './regular/getterReturn'; +import importDefaultBasename from './regular/importDefaultBasename'; +import inconsiderateLanguage from './regular/inconsiderateLanguage'; +import jsxKey from './react/jsxKey'; +import jsxNoCommentText from './react/jsxNoCommentText'; +import negationElse from './regular/negationElse'; +import noArguments from './regular/noArguments'; +import noAsyncPromiseExecutor from './regular/noAsyncPromiseExecutor'; +import noCatchAssign from './regular/noCatchAssign'; +import noChildrenProp from './react/noChildrenProp'; +import noCommaOperator from './regular/noCommaOperator'; +import noCompareNegZero from './regular/noCompareNegZero'; +import noCondAssign from './regular/noCondAssign'; +import noDangerWithChildren from './react/noDangerWithChildren'; +import noDebugger from './regular/noDebugger'; +import noDelete from './regular/noDelete'; +import noDeleteVars from './regular/noDeleteVars'; +import noDidUpdateSetState from './react/noDidUpdateSetState'; +import noDupeArgs from './regular/noDupeArgs'; +import noDuplicateCase from './regular/noDuplicateCase'; +import noDuplicateGroupNamesInRegularExpressions from './regular/noDuplicateGroupNamesInRegularExpressions'; +import noDuplicateKeys from './regular/noDuplicateKeys'; +import noEmptyCharacterClass from './regular/noEmptyCharacterClass'; +import noExplicitAny from './regular/noExplicitAny'; +import noExtraBooleanCast from './regular/noExtraBooleanCast'; +import noFunctionAssign from './regular/noFunctionAssign'; +import noImportAssign from './regular/noImportAssign'; +import noLabelVar from './regular/noLabelVar'; +import noMultipleSpacesInRegularExpressionLiterals from './regular/noMultipleSpacesInRegularExpressionLiterals'; +import noPosixInRegularExpression from './regular/noPosixInRegularExpression'; +import noReferenceToNonExistingGroup from './regular/noReferenceToNonExistingGroup'; +import noSetterReturn from './regular/noSetterReturn'; +import noShadowRestrictedNames from './regular/noShadowRestrictedNames'; +import noShorthandArrayType from './regular/noShorthandArrayType'; +import noTemplateCurlyInString from './regular/noTemplateCurlyInString'; +import noUnsafeFinally from './regular/noUnsafeFinally'; +import noVar from './regular/noVar'; +import preferBlockStatements from './regular/preferBlockStatements'; +import preferFunctionDeclarations from './regular/preferFunctionDeclarations'; +import preferTemplate from './regular/preferTemplate'; +import preferWhile from './regular/preferWhile'; +import reactInJsxScope from './react/reactInJsxScope'; +import restrictedGlobals from './regular/restrictedGlobals'; +import singleVarDeclarator from './regular/singleVarDeclarator'; +import sortImportExportSpecifiers from './regular/sortImportExportSpecifiers'; +import sparseArray from './regular/sparseArray'; +import stylePropObject from './react/stylePropObject'; +import undeclaredVariables from './regular/undeclaredVariables'; +import unsafeNegation from './regular/unsafeNegation'; +import unusedVariables from './regular/unusedVariables'; +import voidDomElementsNoChildren from './react/voidDomElementsNoChildren'; + +export const lintTransforms = [ + camelCase, + caseSingleStatement, + defaultExportSameBasename, + doubleEquals, + duplicateImportSource, + emptyBlocks, + emptyMatches, + getterReturn, + importDefaultBasename, + inconsiderateLanguage, + jsxKey, + jsxNoCommentText, + negationElse, + noArguments, + noAsyncPromiseExecutor, + noCatchAssign, + noChildrenProp, + noCommaOperator, + noCompareNegZero, + noCondAssign, + noDangerWithChildren, + noDebugger, + noDelete, + noDeleteVars, + noDidUpdateSetState, + noDupeArgs, + noDuplicateCase, + noDuplicateGroupNamesInRegularExpressions, + noDuplicateKeys, + noEmptyCharacterClass, + noExplicitAny, + noExtraBooleanCast, + noFunctionAssign, + noImportAssign, + noLabelVar, + noMultipleSpacesInRegularExpressionLiterals, + noPosixInRegularExpression, + noReferenceToNonExistingGroup, + noSetterReturn, + noShadowRestrictedNames, + noShorthandArrayType, + noTemplateCurlyInString, + noUnsafeFinally, + noVar, + preferBlockStatements, + preferFunctionDeclarations, + preferTemplate, + preferWhile, + reactInJsxScope, + restrictedGlobals, + singleVarDeclarator, + sortImportExportSpecifiers, + sparseArray, + stylePropObject, + undeclaredVariables, + unsafeNegation, + unusedVariables, + voidDomElementsNoChildren, +>>>>>>> add rule for no setState in componentDidUpdate and tests ]; diff --git a/packages/@romejs/js-compiler/lint/rules/react/noDidUpdateSetState.test.md b/packages/@romejs/js-compiler/lint/rules/react/noDidUpdateSetState.test.md new file mode 100644 index 00000000000..0da21439103 --- /dev/null +++ b/packages/@romejs/js-compiler/lint/rules/react/noDidUpdateSetState.test.md @@ -0,0 +1,219 @@ +# `noDidUpdateSetState.test.ts` + +**DO NOT MODIFY**. This file has been autogenerated. Run `rome test packages/@romejs/js-compiler/lint/rules/react/noDidUpdateSetState.test.ts --update-snapshots` to update. + +## `no did update set state` + +### `0` + +``` + + unknown:2:37 lint/noDidUpdateSetState ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ✖ Avoid use setState in ComponentDidUpdate + + > 2 │ var Hello = createReactClass({ + > 3 │ componentDidUpdate: function() { + > 4 │ this.setState({ + > 5 │ name: 'John' + > 6 │ }); + > 7 │ } + > 8 │ }); + │ ^^^^^^^^^ + 9 │ + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +✖ Found 1 problem + +``` + +### `0: formatted` + +``` +var Hello = createReactClass({ + componentDidUpdate: function() { + this.setState({ + name: 'John', + }); + }, +}); + +``` + +### `1` + +``` + + unknown:2:37 lint/noDidUpdateSetState ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ✖ Avoid use setState in ComponentDidUpdate + + > 2 │ var Hello = createReactClass({ + > 3 │ componentDidUpdate: function() { + > 4 │ foo(); + > 5 │ this.setState({ + > 6 │ name: 'John' + > 7 │ }); + > 8 │ } + > 9 │ }); + │ ^^^^^^^^^ + 10 │ + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +✖ Found 1 problem + +``` + +### `1: formatted` + +``` +var Hello = createReactClass({ + componentDidUpdate: function() { + foo(); + this.setState({ + name: 'John', + }); + }, +}); + +``` + +### `2` + +``` + + unknown:2:8 lint/noDidUpdateSetState ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ✖ Avoid use setState in ComponentDidUpdate + + > 2 │ class Hello extends React.Component { + > 3 │ componentDidUpdate() { + > 4 │ this.setState({ + > 5 │ name: 'John' + > 6 │ }); + > 7 │ } + > 8 │ } + │ ^^^^^^^^^ + 9 │ + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +✖ Found 1 problem + +``` + +### `2: formatted` + +``` +class Hello extends React.Component { + componentDidUpdate() { + this.setState({ + name: 'John', + }); + } +} + +``` + +### `3` + +``` + + unknown:2:8 lint/noDidUpdateSetState ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ✖ Avoid use setState in ComponentDidUpdate + + > 2 │ class Hello extends React.Component { + > 3 │ componentDidUpdate() { + > 4 │ foo(); + > 5 │ this.setState({ + > 6 │ name: 'John' + > 7 │ }); + > 8 │ } + > 9 │ } + │ ^^^^^^^^^ + 10 │ + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +✖ Found 1 problem + +``` + +### `3: formatted` + +``` +class Hello extends React.Component { + componentDidUpdate() { + foo(); + this.setState({ + name: 'John', + }); + } +} + +``` + +### `4` + +``` +✔ No known problems! + +``` + +### `4: formatted` + +``` +var Hello = createReactClass({ + componentDidUpdate: function() { + if (condition) { + this.setState({ + name: 'John', + }); + } + }, +}); + +``` + +### `5` + +``` +✔ No known problems! + +``` + +### `5: formatted` + +``` +class Hello extends React.Component { + componentDidUpdate() { + if (condition) { + this.setState({ + name: 'John', + }); + } + } +} + +``` + +### `6` + +``` +✔ No known problems! + +``` + +### `6: formatted` + +``` +var Hello = createReactClass({ + componentDidUpdate: function() { + foo(); + }, +}); + +``` diff --git a/packages/@romejs/js-compiler/lint/rules/react/noDidUpdateSetState.test.ts b/packages/@romejs/js-compiler/lint/rules/react/noDidUpdateSetState.test.ts new file mode 100644 index 00000000000..ce682da0fb4 --- /dev/null +++ b/packages/@romejs/js-compiler/lint/rules/react/noDidUpdateSetState.test.ts @@ -0,0 +1,91 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import {test} from 'rome'; +import {testLintMultiple} from '../testHelpers'; + +test( + 'no did update set state', + async (t) => { + await testLintMultiple( + t, + [ + // INVALID + ` + var Hello = createReactClass({ + componentDidUpdate: function() { + this.setState({ + name: 'John' + }); + } + }); + `, + ` + var Hello = createReactClass({ + componentDidUpdate: function() { + foo(); + this.setState({ + name: 'John' + }); + } + }); + `, + ` + class Hello extends React.Component { + componentDidUpdate() { + this.setState({ + name: 'John' + }); + } + } + `, + ` + class Hello extends React.Component { + componentDidUpdate() { + foo(); + this.setState({ + name: 'John' + }); + } + } + `, + // VALID + ` + var Hello = createReactClass({ + componentDidUpdate: function() { + if (condition) { + this.setState({ + name: 'John' + }); + } + } + }); + `, + ` + class Hello extends React.Component { + componentDidUpdate() { + if (condition) { + this.setState({ + name: 'John' + }); + } + } + } + `, + ` + var Hello = createReactClass({ + componentDidUpdate: function() { + foo(); + } + }); + `, + ], + {category: 'lint/noDidUpdateSetState'}, + ); + }, +); + diff --git a/packages/@romejs/js-compiler/lint/rules/react/noDidUpdateSetState.ts b/packages/@romejs/js-compiler/lint/rules/react/noDidUpdateSetState.ts new file mode 100644 index 00000000000..45b88de756a --- /dev/null +++ b/packages/@romejs/js-compiler/lint/rules/react/noDidUpdateSetState.ts @@ -0,0 +1,82 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { Path } from "@romejs/js-compiler"; +import { AnyNode, ObjectProperty, AnyClassMember } from "@romejs/js-ast"; +import { descriptions } from "@romejs/diagnostics"; + +function hasComponentDidUpdate(node: ObjectProperty | AnyClassMember): boolean { + return ( + node.key.type === "StaticPropertyKey" && + node.key.value.type === "Identifier" && + node.key.value.name === "componentDidUpdate" + ); +} + +function hasSetState(node: AnyNode): boolean { + if ( + node.type === "ObjectProperty" && + node.value.type === "FunctionExpression" + ) { + if (node.value.body.type === "BlockStatement") { + return node.value.body.body.some( + statement => + statement.type === "ExpressionStatement" && + statement.expression.type === "CallExpression" && + statement.expression.callee.type === "MemberExpression" && + statement.expression.callee.property.value.type === "Identifier" && + statement.expression.callee.property.value.name === "setState" + ); + } + } + if (node.type === "ClassMethod") { + if (node.body.type === "BlockStatement") { + return node.body.body.some( + statement => + statement.type === "ExpressionStatement" && + statement.expression.type === "CallExpression" && + statement.expression.callee.type === "MemberExpression" && + statement.expression.callee.property.value.type === "Identifier" && + statement.expression.callee.property.value.name === "setState" + ); + } + } + return false; +} + +function hasSetStateInComponentDidUpdate(node: AnyNode): boolean { + if (node.type === "ObjectExpression") { + return node.properties.some( + prop => + prop.type === "ObjectProperty" && + hasComponentDidUpdate(prop) && + hasSetState(prop) + ); + } + + if (node.type === "ClassDeclaration") { + return node.meta.body.some( + method => hasComponentDidUpdate(method) && hasSetState(method) + ); + } + return false; +} + +export default { + name: "noDidUpdateSetState", + enter(path: Path): AnyNode { + const { node } = path; + + if (hasSetStateInComponentDidUpdate(node)) { + path.context.addNodeDiagnostic( + node, + descriptions.LINT.NO_DID_UPDATE_SET_STATE + ); + } + return node; + } +}; From 1ad08ae8dc6060e06f6d3210d77ed6805ade3f62 Mon Sep 17 00:00:00 2001 From: Victor Hom Date: Sat, 16 May 2020 13:13:14 -0400 Subject: [PATCH 2/5] add tests for extends Component in noDidUpdateSetState --- .../rules/react/noDidUpdateSetState.test.md | 108 +++++++++++++++++- .../rules/react/noDidUpdateSetState.test.ts | 30 +++++ 2 files changed, 133 insertions(+), 5 deletions(-) diff --git a/packages/@romejs/js-compiler/lint/rules/react/noDidUpdateSetState.test.md b/packages/@romejs/js-compiler/lint/rules/react/noDidUpdateSetState.test.md index 0da21439103..f0b027c7e28 100644 --- a/packages/@romejs/js-compiler/lint/rules/react/noDidUpdateSetState.test.md +++ b/packages/@romejs/js-compiler/lint/rules/react/noDidUpdateSetState.test.md @@ -159,12 +159,88 @@ class Hello extends React.Component { ### `4` ``` -✔ No known problems! + + unknown:2:8 lint/noDidUpdateSetState ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ✖ Avoid use setState in ComponentDidUpdate + + > 2 │ class Hello extends Component { + > 3 │ componentDidUpdate() { + > 4 │ this.setState({ + > 5 │ name: 'John' + > 6 │ }); + > 7 │ } + > 8 │ } + │ ^^^^^^^^^ + 9 │ + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +✖ Found 1 problem ``` ### `4: formatted` +``` +class Hello extends Component { + componentDidUpdate() { + this.setState({ + name: 'John', + }); + } +} + +``` + +### `5` + +``` + + unknown:2:8 lint/noDidUpdateSetState ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ✖ Avoid use setState in ComponentDidUpdate + + > 2 │ class Hello extends Component { + > 3 │ componentDidUpdate() { + > 4 │ foo(); + > 5 │ this.setState({ + > 6 │ name: 'John' + > 7 │ }); + > 8 │ } + > 9 │ } + │ ^^^^^^^^^ + 10 │ + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +✖ Found 1 problem + +``` + +### `5: formatted` + +``` +class Hello extends Component { + componentDidUpdate() { + foo(); + this.setState({ + name: 'John', + }); + } +} + +``` + +### `6` + +``` +✔ No known problems! + +``` + +### `6: formatted` + ``` var Hello = createReactClass({ componentDidUpdate: function() { @@ -178,14 +254,14 @@ var Hello = createReactClass({ ``` -### `5` +### `7` ``` ✔ No known problems! ``` -### `5: formatted` +### `7: formatted` ``` class Hello extends React.Component { @@ -200,14 +276,36 @@ class Hello extends React.Component { ``` -### `6` +### `8` ``` ✔ No known problems! ``` -### `6: formatted` +### `8: formatted` + +``` +class Hello extends Component { + componentDidUpdate() { + if (condition) { + this.setState({ + name: 'John', + }); + } + } +} + +``` + +### `9` + +``` +✔ No known problems! + +``` + +### `9: formatted` ``` var Hello = createReactClass({ diff --git a/packages/@romejs/js-compiler/lint/rules/react/noDidUpdateSetState.test.ts b/packages/@romejs/js-compiler/lint/rules/react/noDidUpdateSetState.test.ts index ce682da0fb4..fd29f5a5bef 100644 --- a/packages/@romejs/js-compiler/lint/rules/react/noDidUpdateSetState.test.ts +++ b/packages/@romejs/js-compiler/lint/rules/react/noDidUpdateSetState.test.ts @@ -53,6 +53,25 @@ test( } } `, + ` + class Hello extends Component { + componentDidUpdate() { + this.setState({ + name: 'John' + }); + } + } + `, + ` + class Hello extends Component { + componentDidUpdate() { + foo(); + this.setState({ + name: 'John' + }); + } + } + `, // VALID ` var Hello = createReactClass({ @@ -77,6 +96,17 @@ test( } `, ` + class Hello extends Component { + componentDidUpdate() { + if (condition) { + this.setState({ + name: 'John' + }); + } + } + } + `, + ` var Hello = createReactClass({ componentDidUpdate: function() { foo(); From b6d2c7ad9d45290fbc2bf6793159d93b9ccd7253 Mon Sep 17 00:00:00 2001 From: Victor Hom Date: Sun, 17 May 2020 12:17:13 -0400 Subject: [PATCH 3/5] fix conflicts and apply feedback for noDidUpdateSetState --- packages/@romejs/diagnostics/categories.ts | 64 +-- packages/@romejs/diagnostics/descriptions.ts | 486 +----------------- .../@romejs/js-compiler/lint/rules/index.ts | 140 +---- .../lint/rules/react/.jsxA11yAltText.ts.swp | Bin 0 -> 12288 bytes .../rules/react/noDidUpdateSetState.test.md | 286 +++-------- .../rules/react/noDidUpdateSetState.test.ts | 71 +-- .../lint/rules/react/noDidUpdateSetState.ts | 93 +--- 7 files changed, 117 insertions(+), 1023 deletions(-) create mode 100644 packages/@romejs/js-compiler/lint/rules/react/.jsxA11yAltText.ts.swp diff --git a/packages/@romejs/diagnostics/categories.ts b/packages/@romejs/diagnostics/categories.ts index 99e017aceda..65469a193a0 100644 --- a/packages/@romejs/diagnostics/categories.ts +++ b/packages/@romejs/diagnostics/categories.ts @@ -92,8 +92,7 @@ export type DiagnosticCategoryPrefix = // EVERYTHING BELOW IS AUTOGENERATED. SEE SCRIPTS FOLDER FOR UPDATE SCRIPTS type LintDiagnosticCategory = -<<<<<<< HEAD - | "lint/camelCase" + | "lint/camelCase" | "lint/caseSingleStatement" | "lint/confusingLanguage" | "lint/defaultExportSameBasename" @@ -122,6 +121,7 @@ type LintDiagnosticCategory = | "lint/noDebugger" | "lint/noDelete" | "lint/noDeleteVars" + | "lint/noDidUpdateSetState" | "lint/noDupeArgs" | "lint/noDuplicateCase" | "lint/noDuplicateGroupNamesInRegularExpressions" @@ -156,63 +156,3 @@ type LintDiagnosticCategory = | "lint/unsafeNegation" | "lint/unusedVariables" | "lint/voidDomElementsNoChildren"; -======= - | 'lint/camelCase' - | 'lint/caseSingleStatement' - | 'lint/defaultExportSameBasename' - | 'lint/doubleEquals' - | 'lint/duplicateImportSource' - | 'lint/emptyBlocks' - | 'lint/emptyMatches' - | 'lint/getterReturn' - | 'lint/importDefaultBasename' - | 'lint/inconsiderateLanguage' - | 'lint/jsxKey' - | 'lint/jsxNoCommentText' - | 'lint/negationElse' - | 'lint/noArguments' - | 'lint/noAsyncPromiseExecutor' - | 'lint/noCatchAssign' - | 'lint/noChildrenProp' - | 'lint/noCommaOperator' - | 'lint/noCompareNegZero' - | 'lint/noCondAssign' - | 'lint/noDangerWithChildren' - | 'lint/noDebugger' - | 'lint/noDelete' - | 'lint/noDeleteVars' - | 'lint/noDidUpdateSetState' - | 'lint/noDupeArgs' - | 'lint/noDuplicateCase' - | 'lint/noDuplicateGroupNamesInRegularExpressions' - | 'lint/noDuplicateKeys' - | 'lint/noEmptyCharacterClass' - | 'lint/noExplicitAny' - | 'lint/noExtraBooleanCast' - | 'lint/noFunctionAssign' - | 'lint/noImportAssign' - | 'lint/noLabelVar' - | 'lint/noMultipleSpacesInRegularExpressionLiterals' - | 'lint/noPosixInRegularExpression' - | 'lint/noReferenceToNonExistingGroup' - | 'lint/noSetterReturn' - | 'lint/noShadowRestrictedNames' - | 'lint/noShorthandArrayType' - | 'lint/noTemplateCurlyInString' - | 'lint/noUnsafeFinally' - | 'lint/noVar' - | 'lint/preferBlockStatements' - | 'lint/preferFunctionDeclarations' - | 'lint/preferTemplate' - | 'lint/preferWhile' - | 'lint/reactInJsxScope' - | 'lint/restrictedGlobals' - | 'lint/singleVarDeclarator' - | 'lint/sortImportExportSpecifiers' - | 'lint/sparseArray' - | 'lint/stylePropObject' - | 'lint/undeclaredVariables' - | 'lint/unsafeNegation' - | 'lint/unusedVariables' - | 'lint/voidDomElementsNoChildren'; ->>>>>>> add rule for no setState in componentDidUpdate and tests diff --git a/packages/@romejs/diagnostics/descriptions.ts b/packages/@romejs/diagnostics/descriptions.ts index 3be8eaa4527..52a8d0d56d7 100644 --- a/packages/@romejs/diagnostics/descriptions.ts +++ b/packages/@romejs/diagnostics/descriptions.ts @@ -170,7 +170,6 @@ function buildJSXOpeningAdvice( } export const descriptions = createMessages({ -<<<<<<< HEAD FLAGS: { UNSUPPORTED_SHORTHANDS: `Shorthand flags are not supported`, INCORRECT_CASED_FLAG: (flag: string) => ({ @@ -291,6 +290,10 @@ export const descriptions = createMessages({ }, // @romejs/js-compiler LINT: { + NO_DID_UPDATE_SET_STATE: { + category: "lint/noDidUpdateSetState", + message: "Avoid this.setState in componentDidUpdate", + }, NO_DANGER: { category: "lint/noDanger", message: "dangerouslySetInnerHTML should be avoided", @@ -664,485 +667,6 @@ export const descriptions = createMessages({ }, ) => { let adviceMessage = ""; -======= - FLAGS: { - UNSUPPORTED_SHORTHANDS: `Shorthand flags are not supported`, - INCORRECT_CASED_FLAG: (flag: string) => ({ - message: `Incorrect cased flag name`, - advice: [ - { - type: 'log', - category: 'info', - text: markup`Use ${toKebabCase(flag)} instead`, - }, - ], - }), - INCORRECT_ARG_COUNT: (excessive: boolean, message: string) => ({ - message: excessive ? 'Too many arguments' : 'Missing arguments', - advice: [ - { - type: 'log', - category: 'info', - text: message, - }, - ], - }), - DISALLOWED_REVIEW_FLAG: (key: string) => ({ - message: `Flag ${key} is not allowed with review`, - }), - DISALLOWED_REQUEST_FLAG: (key: string) => ({ - message: `This command does not support the ${key} flag`, - }), - UNKNOWN_ACTION: (action: string) => ({ - message: `Unknown action ${action}`, - }), - NO_FILES_FOUND: (noun: undefined | string) => ({ - message: noun === undefined - ? 'No files found' - : `No files to ${noun} found`, - }), - }, - // @romejs/parser-core - PARSER_CORE: { - EXPECTED_SPACE: 'Expected no space between', - EXPECTED_EOF: 'Expected end of file', - UNEXPECTED_EOF: 'Unexpected end of file', - UNEXPECTED: (type: string) => ({ - message: markup`Unexpected ${type}`, - }), - UNEXPECTED_CHARACTER: (char: string) => ({ - message: markup`Unexpected character ${char}`, - }), - EXPECTED_TOKEN: (got: string, expected: string) => { - return { - message: markup`Expected token ${expected} but got ${got}`, - }; - }, - }, - // @romejs/codec-js-regexp - REGEX_PARSER: { - INVALID_CAPTURE_GROUP_MODIFIER: 'Invalid capture group modifier', - UNCLOSED_GROUP: 'Unclosed group', - UNOPENED_GROUP: 'Unopened group', - INVALID_QUANTIFIER_TARGET: 'Invalid target for quantifier', - UNKNOWN_REGEX_PART: 'Unknown regex part', - REVERSED_CHAR_SET_RANGE: 'Range values reversed. Start char code is greater than end char code', - UNCLOSED_CHAR_SET: 'Unclosed character set', - DUPLICATE_FLAG: 'Duplicate regular expression flag', - INVALID_FLAG: 'Invalid regular expression flag', - REVERSED_QUANTIFIER_RANGE: 'Quantifier minimum is greater than maximum', - NO_TARGET_QUANTIFIER: 'Nothing to repeat', - INVALID_NAMED_CAPTURE: 'Invalid named capture referenced', - UNCLOSED_NAMED_CAPTURE: 'Unclosed named capture', - }, - // @romejs/codec-json - JSON: { - SINGLE_QUOTE_USAGE: 'You can only use double quoted strings', - TRAILING_COMMA_VALUE: 'Trailing comma is only allowed after a value', - UNCLOSED_STRING: 'Unclosed string', - UNCLOSED_BLOCK_COMMENT: 'Unclosed block comment', - MISTAKEN_ARRAY_IDENTITY: 'Trying to use an array element as an object property. Did you mean to make an object?', - REDUNDANT_COMMA: 'Redundant comma', - EMPTY_INPUT_IN_JSON: 'Empty input', - PROPERTY_KEY_UNQUOTED_IN_JSON: 'Property keys must be quoted in JSON', - IMPLICIT_OBJECT_IN_JSON: 'Objects must be wrapped in curly braces in JSON', - COMMENTS_IN_JSON: "Comments aren't allowed in JSON", - TRAILING_COMMA_IN_JSON: "Trailing commas aren't allowed in JSON", - REGEX_IN_JSON: "Regular expressions aren't allowed in JSON", - UNKNOWN_WORD_IN_JSON: (word: string) => ({ - message: markup`${word} isn't a valid JSON word`, - }), - STRING_NEWLINES_IN_JSON: "Newlines aren't allowed in JSON, you insert a newline by escaping it like this \"\\n\"", - UNDEFINED_IN_JSON: "undefined isn't allowed in JSON, you could use null instead", - BIGINT_IN_JSON: "Bigints aren't allowed in JSON", - NUMERIC_SEPARATORS_IN_JSON: 'Numeric separators are not allowed in JSON', - }, - // @romejs/codec-semver - SEMVER: { - MISSING_MINOR_VERSION: 'A minor number is required for a version', - MISSING_PATCH_VERSION: 'A patch number is required for a version', - EXCESSIVE_VERSION_PARTS: 'Too many parts for version', - INVALID_QUANTIFIER_PART: 'Invalid version qualifier part', - WILDCARD_IN_VERSION: "Wildcard aren't allowed in a hard version", - INVALID_VERSION_NUMBER: "This isn't a valid version part, expected a number", - INVALID_RANGE: 'A semver range can only be defined with versions', - BARE_PIPE_WITHOUT_LOOSE: 'Bare pipes are only allowed in loose mode', - UNEXPECTED_WORD: (word: string) => ({ - message: markup`Unexpected word ${word}`, - }), - UNKNOWN_START: 'Unknown start of atom', - EXPECTED_VERSION: 'Unexpected value for version', - }, - V8: { - SYNTAX_ERROR: (message: string) => ({message, category: 'v8/syntaxError'}), - }, - // @romejs/core/master/commands/lint.ts - LINT_COMMAND: { - INVALID_DECISION_ACTION: (action: string) => ({ - message: markup`${action} is not a valid decision action`, - }), - INVALID_DECISION_PART_COUNT: (i: number) => ({ - message: `Segment ${i} contains an invalid number of decision parts`, - }), - }, - // @romejs/js-compiler - LINT: { - NO_DID_UPDATE_SET_STATE: { - category: 'lint/noDidUpdateSetState', - message: 'Avoid use setState in ComponentDidUpdate', - }, - IMPORT_DEFAULT_BASENAME: (prev: string, basename: string) => ({ - category: 'lint/importDefaultBasename', - message: markup`When importing the default, use the basename ${basename}`, - advice: [ - { - type: 'log', - category: 'info', - text: 'If you really meant this then use this instead', - }, - { - type: 'code', - code: markup`import {default as ${prev}}`, - }, - ], - }), - NO_COMMA_OPERATOR: { - category: 'lint/noCommaOperator', - message: 'Avoid usage of the comma operator. It can lead to easy mistakes and ambiguous code.', - advice: [ - { - type: 'log', - category: 'info', - text: 'If you want multiple expressions then break it up.', - }, - ], - }, - NEGATION_ELSE: { - category: 'lint/negationElse', - message: 'Invert the blocks when you have a negation test', - }, - STYLE_PROP_OBJECT: { - category: 'lint/stylePropObject', - message: 'style property value must be an object.', - }, - NO_DANGER_WITH_CHILDREN: { - category: 'lint/noDangerWithChildren', - message: 'Only set one of children or props.dangerouslySetInnerHTML.', - }, - PENDING_FIXES: ( - relativeFilename: string, - original: string, - formatted: string, - ) => ({ - category: 'lint/pendingFixes', - message: 'Pending formatting and recommended autofixes', - advice: [ - { - type: 'diff', - diff: stringDiff(original, formatted), - }, - ({ - type: 'action', - command: 'lint', - shortcut: 'f', - instruction: 'To apply fixes and formatting run', - noun: 'Apply fixes and format', - args: [relativeFilename], - commandFlags: { - save: true, - }, - } as DiagnosticAdviceAction), - ({ - type: 'action', - hidden: true, - command: 'lint', - shortcut: 'o', - instruction: 'To format this file without any fixes run', - noun: 'Only format', - args: [relativeFilename], - commandFlags: { - format: true, - }, - } as DiagnosticAdviceAction), - ], - }), - DUPLICATE_IMPORT_SOURCE: (seenLocation: DiagnosticLocation) => ({ - category: 'lint/duplicateImportSource', - message: 'This module has already been imported', - advice: [ - { - type: 'log', - category: 'info', - text: 'Previously imported here', - }, - { - type: 'frame', - location: seenLocation, - }, - ], - }), - NO_CHILDREN_PROP: { - category: 'lint/noChildrenProp', - message: 'children should not be passed as a prop', - }, - PREFER_BLOCK_STATEMENT: { - category: 'lint/preferBlockStatements', - message: 'Block statements are preferred in this position', - }, - PREFER_TEMPLATE: { - category: 'lint/preferTemplate', - message: 'Template literals are preferred over string concatenation', - }, - PREFER_WHILE: { - category: 'lint/preferWhile', - message: 'A while loop should be used over a for loop', - }, - REACT_IN_JSX_SCOPE: { - category: 'lint/reactInJsxScope', - message: markup`"React" must be in scope when using JSX`, - }, - REACT_JSX_VOID_DOM_ELEMENTS_NO_CHILDREN: ( - element: string, - properties: Array, - ) => ({ - category: 'lint/voidDomElementsNoChildren', - message: markup`${element} is a void element tag and must not have ${orJoin( - properties, - )}.`, - }), - REACT_JSX_NO_COMMENT_TEXT: { - category: 'lint/jsxNoCommentText', - message: 'Comments inside children should be placed in braces', - }, - REACT_JSX_KEY: (origin: string) => ({ - category: 'lint/jsxKey', - message: markup`Missing the "key" prop for element in ${origin}`, - }), - UNSAFE_NEGATION: { - category: 'lint/unsafeNegation', - message: 'Unsafe usage of negation operator in left side of binary expression', - }, - UNUSED_VARIABLES: (kind: string, name: string) => ({ - category: 'lint/unusedVariables', - message: markup`Unused ${kind} ${name}`, - }), - UNDECLARED_VARIABLES: (name: string) => ({ - category: 'lint/undeclaredVariables', - message: markup`Undeclared variable ${name}`, - }), - VARIABLE_CAMEL_CASE: (name: string, camelCaseName: string) => ({ - category: 'lint/camelCase', - message: markup`Variable ${name} should be camel cased as ${camelCaseName}`, - }), - IDENTIFIER_CAMEL_CASE: (name: string, camelCaseName: string) => ({ - category: 'lint/camelCase', - message: markup`Identifier ${name} should be camel cased as ${camelCaseName}`, - }), - CASE_SINGLE_STATEMENT: { - category: 'lint/caseSingleStatement', - message: 'A switch case should only have a single statement. If you want more then wrap it in a block.', - }, - INCONSIDERATE_LANGUAGE: ( - description: string, - word: string, - suggestion: string, - ) => ({ - category: 'lint/inconsiderateLanguage', - message: description, - advice: [ - { - type: 'log', - category: 'info', - text: markup`Instead of ${word} use ${suggestion}`, - }, - ], - }), - DOUBLE_EQUALS: { - category: 'lint/doubleEquals', - message: 'Use === instead of ==', - advice: [ - { - type: 'log', - category: 'info', - text: '== is only allowed when comparing against null', - }, - ], - }, - EMPTY_MATCHES: { - category: 'lint/emptyMatches', - message: 'The expression can return empty matches, and may match infinitely in some use cases', - }, - NEGATE_DOUBLE_EQUALS: { - category: 'lint/doubleEquals', - message: 'Use !== instead of !=', - advice: [ - { - type: 'log', - category: 'info', - text: '!= is only allowed when comparing against null', - }, - ], - }, - NO_CATCH_ASSIGN: { - category: 'lint/noCatchAssign', - message: "Don't reassign catch parameters", - }, - SPARSE_ARRAY: { - category: 'lint/sparseArray', - message: 'Your array contains an empty slot', - }, - SINGLE_VAR_DECLARATOR: { - category: 'lint/singleVarDeclarator', - message: 'Declare each variable separately', - }, - PREFER_FUNCTION_DECLARATIONS: { - category: 'lint/preferFunctionDeclarations', - message: 'Use a function declaration instead of a const function', - }, - NO_VAR: { - category: 'lint/noVar', - message: 'Variable declarations using `var` are disallowed, use `let` or `const` instead.', - }, - NO_SHORTHAND_ARRAY_TYPE: { - category: 'lint/noShorthandArrayType', - message: escapeMarkup('Use Array instead of shorthand T[]'), - }, - NO_UNSAFE_FINALLY: (type: string) => ({ - category: 'lint/noUnsafeFinally', - message: markup`Unsafe usage of ${type}.`, - }), - NO_TEMPLATE_CURLY_IN_STRING: { - category: 'lint/noTemplateCurlyInString', - message: `Unexpected template string expression.`, - }, - NO_SHADOW_RESTRICTED_NAMES: (name: string) => ({ - category: 'lint/noShadowRestrictedNames', - message: markup`Shadowing of global property ${name}`, - advice: [ - { - type: 'log', - category: 'info', - text: "Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.", - }, - ], - }), - NO_MULTIPLE_SPACES_IN_REGEX_LITERAL: (count: number) => ({ - category: 'lint/noMultipleSpacesInRegularExpressionLiterals', - message: 'Unclear multiple spaces in regular expression', - advice: [ - { - type: 'log', - category: 'info', - text: `It's hard to visually count the amount of spaces, it's clearer if you use a quantifier instead. eg / {${String( - count, - )}}/`, - }, - ], - }), - NO_LABEL_VAR: { - category: 'lint/noLabelVar', - message: 'Labels should not be variable names', - }, - NO_IMPORT_ASSIGN: (name: string) => ({ - category: 'lint/noImportAssign', - message: markup`${name} is read-only`, - }), - NO_EXTRA_BOOLEAN_CAST: { - category: 'lint/noExtraBooleanCast', - message: `Redundant double negation.`, - }, - NO_FUNCTION_ASSIGN: { - category: 'lint/noFunctionAssign', - message: 'Reassignment of function declaration', - }, - NO_EXPLICIT_ANY: { - category: 'lint/noExplicitAny', - message: 'Unexpected any. Specify a different type.', - }, - NO_EMPTY_CHAR_SET: { - category: 'lint/noEmptyCharacterClass', - message: 'Empty character classes in regular expressions are not allowed', - }, - NO_DUPLICATE_KEYS: (key: string) => ({ - category: 'lint/noDuplicateKeys', - message: markup`Duplicate key ${key}`, - }), - NO_POSIX_IN_REGULAR_EXPRESSION: { - category: 'lint/noPosixInRegularExpression', - message: 'POSIX Character Classes and Collating Sequences are not supported in ECMAscript Regular Expressions', - }, - NO_DUPLICATE_CASE: (value: string) => ({ - category: 'lint/noDuplicateCase', - message: markup`Duplicate case ${value} not allowed.`, - }), - NO_DUPE_ARGS: (name: string) => ({ - category: 'lint/noDupeArgs', - message: markup`Duplicate argument ${name} in function definition`, - }), - NO_DELETE: { - category: 'lint/noDelete', - message: `Unexpected 'delete' operator.`, - }, - NO_DELETE_VARS: { - category: 'lint/noDeleteVars', - message: 'Variables should not be deleted.', - }, - NO_DEBUGGER: { - category: 'lint/noDebugger', - message: "Unexpected 'debugger' statement", - }, - NO_COND_ASSIGN: { - category: 'lint/noCondAssign', - message: 'Cannot assign variable in loop condition', - }, - NO_COMPARE_NEG_ZERO: (op: string) => ({ - category: 'lint/noCompareNegZero', - message: `Do not use the '${op}' operator to compare against -0`, - fixable: op === '===', - }), - NO_ASYNC_PROMISE_EXECUTOR: { - category: 'lint/noAsyncPromiseExecutor', - message: 'Promise executor functions should not be async.', - }, - GETTER_RETURN: (got: string) => ({ - category: 'lint/getterReturn', - message: `Expected a 'return' at end of a getter method but got ${got}`, - }), - NO_SETTER_RETURN: { - category: 'lint/noSetterReturn', - message: `Setter cannot return a value`, - }, - EMPTY_BLOCKS: { - category: 'lint/emptyBlocks', - message: 'Empty block', - }, - NO_ARGUMENTS: { - category: 'lint/noArguments', - message: "Use the rest parameters instead of 'arguments'", - }, - DUPLICATE_REGEX_GROUP_NAME: (name: string) => ({ - category: 'lint/noDuplicateGroupNamesInRegularExpressions', - message: `Duplicate group name ${name} in regular expression`, - }), - NO_REFERENCE_TO_NON_EXISTING_GROUP: (name: string) => ({ - category: 'lint/noReferenceToNonExistingGroup', - message: `Reference to non-existent group "${name}"`, - }), - DEFAULT_EXPORT_SAME_BASENAME: ( - { - defaultName, - defaultType, - actualFilename, - correctFilename, - }: { - defaultName: string; - defaultType: string; - actualFilename: string; - correctFilename: string; - }, - ) => { - let adviceMessage = ''; ->>>>>>> add rule for no setState in componentDidUpdate and tests if (defaultName === "*default*") { adviceMessage += "The"; @@ -2146,4 +1670,4 @@ export const descriptions = createMessages({ }), RECURSIVE_CONFIG: "Recursive config", }, -}); +}); \ No newline at end of file diff --git a/packages/@romejs/js-compiler/lint/rules/index.ts b/packages/@romejs/js-compiler/lint/rules/index.ts index 6d4ebd0919e..5b543d10cfe 100644 --- a/packages/@romejs/js-compiler/lint/rules/index.ts +++ b/packages/@romejs/js-compiler/lint/rules/index.ts @@ -6,7 +6,7 @@ */ // EVERYTHING BELOW IS AUTOGENERATED. SEE SCRIPTS FOLDER FOR UPDATE SCRIPTS -<<<<<<< HEAD + import camelCase from "./regular/camelCase"; import caseSingleStatement from "./regular/caseSingleStatement"; import confusingLanguage from "./regular/confusingLanguage"; @@ -17,10 +17,10 @@ import emptyBlocks from "./regular/emptyBlocks"; import emptyMatches from "./regular/emptyMatches"; import getterReturn from "./regular/getterReturn"; import importDefaultBasename from "./regular/importDefaultBasename"; -import jsxA11YHTMLHasLang from "./react/jsxA11yHTMLHasLang"; -import jsxA11YIframeHasTitle from "./react/jsxA11yIframeHasTitle"; -import jsxA11YImgRedundantAlt from "./react/jsxA11yImgRedundantAlt"; -import jsxA11YNoTargetBlank from "./react/jsxA11yNoTargetBlank"; +import jsxA11yHTMLHasLang from "./react/jsxA11yHTMLHasLang"; +import jsxA11yIframeHasTitle from "./react/jsxA11yIframeHasTitle"; +import jsxA11yImgRedundantAlt from "./react/jsxA11yImgRedundantAlt"; +import jsxA11yNoTargetBlank from "./react/jsxA11yNoTargetBlank"; import jsxKey from "./react/jsxKey"; import jsxNoCommentText from "./react/jsxNoCommentText"; import negationElse from "./regular/negationElse"; @@ -36,6 +36,7 @@ import noDangerWithChildren from "./react/noDangerWithChildren"; import noDebugger from "./regular/noDebugger"; import noDelete from "./regular/noDelete"; import noDeleteVars from "./regular/noDeleteVars"; +import noDidUpdateSetState from "./react/noDidUpdateSetState"; import noDupeArgs from "./regular/noDupeArgs"; import noDuplicateCase from "./regular/noDuplicateCase"; import noDuplicateGroupNamesInRegularExpressions from "./regular/noDuplicateGroupNamesInRegularExpressions"; @@ -82,10 +83,10 @@ export const lintTransforms = [ emptyMatches, getterReturn, importDefaultBasename, - jsxA11YHTMLHasLang, - jsxA11YIframeHasTitle, - jsxA11YImgRedundantAlt, - jsxA11YNoTargetBlank, + jsxA11yHTMLHasLang, + jsxA11yIframeHasTitle, + jsxA11yImgRedundantAlt, + jsxA11yNoTargetBlank, jsxKey, jsxNoCommentText, negationElse, @@ -101,6 +102,7 @@ export const lintTransforms = [ noDebugger, noDelete, noDeleteVars, + noDidUpdateSetState, noDupeArgs, noDuplicateCase, noDuplicateGroupNamesInRegularExpressions, @@ -135,124 +137,4 @@ export const lintTransforms = [ unsafeNegation, unusedVariables, voidDomElementsNoChildren, -======= -import camelCase from './regular/camelCase'; -import caseSingleStatement from './regular/caseSingleStatement'; -import defaultExportSameBasename from './regular/defaultExportSameBasename'; -import doubleEquals from './regular/doubleEquals'; -import duplicateImportSource from './regular/duplicateImportSource'; -import emptyBlocks from './regular/emptyBlocks'; -import emptyMatches from './regular/emptyMatches'; -import getterReturn from './regular/getterReturn'; -import importDefaultBasename from './regular/importDefaultBasename'; -import inconsiderateLanguage from './regular/inconsiderateLanguage'; -import jsxKey from './react/jsxKey'; -import jsxNoCommentText from './react/jsxNoCommentText'; -import negationElse from './regular/negationElse'; -import noArguments from './regular/noArguments'; -import noAsyncPromiseExecutor from './regular/noAsyncPromiseExecutor'; -import noCatchAssign from './regular/noCatchAssign'; -import noChildrenProp from './react/noChildrenProp'; -import noCommaOperator from './regular/noCommaOperator'; -import noCompareNegZero from './regular/noCompareNegZero'; -import noCondAssign from './regular/noCondAssign'; -import noDangerWithChildren from './react/noDangerWithChildren'; -import noDebugger from './regular/noDebugger'; -import noDelete from './regular/noDelete'; -import noDeleteVars from './regular/noDeleteVars'; -import noDidUpdateSetState from './react/noDidUpdateSetState'; -import noDupeArgs from './regular/noDupeArgs'; -import noDuplicateCase from './regular/noDuplicateCase'; -import noDuplicateGroupNamesInRegularExpressions from './regular/noDuplicateGroupNamesInRegularExpressions'; -import noDuplicateKeys from './regular/noDuplicateKeys'; -import noEmptyCharacterClass from './regular/noEmptyCharacterClass'; -import noExplicitAny from './regular/noExplicitAny'; -import noExtraBooleanCast from './regular/noExtraBooleanCast'; -import noFunctionAssign from './regular/noFunctionAssign'; -import noImportAssign from './regular/noImportAssign'; -import noLabelVar from './regular/noLabelVar'; -import noMultipleSpacesInRegularExpressionLiterals from './regular/noMultipleSpacesInRegularExpressionLiterals'; -import noPosixInRegularExpression from './regular/noPosixInRegularExpression'; -import noReferenceToNonExistingGroup from './regular/noReferenceToNonExistingGroup'; -import noSetterReturn from './regular/noSetterReturn'; -import noShadowRestrictedNames from './regular/noShadowRestrictedNames'; -import noShorthandArrayType from './regular/noShorthandArrayType'; -import noTemplateCurlyInString from './regular/noTemplateCurlyInString'; -import noUnsafeFinally from './regular/noUnsafeFinally'; -import noVar from './regular/noVar'; -import preferBlockStatements from './regular/preferBlockStatements'; -import preferFunctionDeclarations from './regular/preferFunctionDeclarations'; -import preferTemplate from './regular/preferTemplate'; -import preferWhile from './regular/preferWhile'; -import reactInJsxScope from './react/reactInJsxScope'; -import restrictedGlobals from './regular/restrictedGlobals'; -import singleVarDeclarator from './regular/singleVarDeclarator'; -import sortImportExportSpecifiers from './regular/sortImportExportSpecifiers'; -import sparseArray from './regular/sparseArray'; -import stylePropObject from './react/stylePropObject'; -import undeclaredVariables from './regular/undeclaredVariables'; -import unsafeNegation from './regular/unsafeNegation'; -import unusedVariables from './regular/unusedVariables'; -import voidDomElementsNoChildren from './react/voidDomElementsNoChildren'; - -export const lintTransforms = [ - camelCase, - caseSingleStatement, - defaultExportSameBasename, - doubleEquals, - duplicateImportSource, - emptyBlocks, - emptyMatches, - getterReturn, - importDefaultBasename, - inconsiderateLanguage, - jsxKey, - jsxNoCommentText, - negationElse, - noArguments, - noAsyncPromiseExecutor, - noCatchAssign, - noChildrenProp, - noCommaOperator, - noCompareNegZero, - noCondAssign, - noDangerWithChildren, - noDebugger, - noDelete, - noDeleteVars, - noDidUpdateSetState, - noDupeArgs, - noDuplicateCase, - noDuplicateGroupNamesInRegularExpressions, - noDuplicateKeys, - noEmptyCharacterClass, - noExplicitAny, - noExtraBooleanCast, - noFunctionAssign, - noImportAssign, - noLabelVar, - noMultipleSpacesInRegularExpressionLiterals, - noPosixInRegularExpression, - noReferenceToNonExistingGroup, - noSetterReturn, - noShadowRestrictedNames, - noShorthandArrayType, - noTemplateCurlyInString, - noUnsafeFinally, - noVar, - preferBlockStatements, - preferFunctionDeclarations, - preferTemplate, - preferWhile, - reactInJsxScope, - restrictedGlobals, - singleVarDeclarator, - sortImportExportSpecifiers, - sparseArray, - stylePropObject, - undeclaredVariables, - unsafeNegation, - unusedVariables, - voidDomElementsNoChildren, ->>>>>>> add rule for no setState in componentDidUpdate and tests ]; diff --git a/packages/@romejs/js-compiler/lint/rules/react/.jsxA11yAltText.ts.swp b/packages/@romejs/js-compiler/lint/rules/react/.jsxA11yAltText.ts.swp new file mode 100644 index 0000000000000000000000000000000000000000..21c1b2f64c2045ab7b609c08016a9e68c14a6579 GIT binary patch literal 12288 zcmeI2O^6&t6vr!x@go`|$uW@BCXks4yFJ;ML!7wcx>;qyW{ufNh!@wI?&_IJdb&H^ zHRG zSJn0Y^{QSCTg`nZ>qqH9W1Qf6fRHP1eDchNr<`@Y9|`FRQ+h$$>!`9@T(Mm^)@k~N z!`u}uUq~CQ9`?*`hr2SY`hjSc`|%M^)+RuzETi zGrf*493E61;mT^zbx<5|W=a$;OpcE)PCBx|7o;J>6?>u!v;u2Pfv&X24sIq7?jPT$ zJm0-*gl^kmKr5gX&Dc{wt*iu6LJ|m4~~O}!A9`?eS~}iz64)@>)>_p z95@4}!EUex+_;yJU%@ZnXK)F;1zrX{Fbj5pKQ^JS-~-SDXMqP?Py^e+7Vz6WgnSHM z1p=G`bKog(3~UEC?o2&VnQ0A#ecf2jk$cyU-`_Ew~IWfF7uWJzxav1UtZH z@aLWABe(+I2TiaOYy#`Sjg5qS4X%M#z+tcv{B#E)AAyVDHLw7l1vRi0tOws=>^=vd zf)Bw}a0$Ez)VRI_^mV%`uylw}x&$Z$EFPMH@TKtF z(3q*uHjE>4r{-};=IQy#nZ|r$`cxxlt=b(;?|mlQhUvLdouy%xHH*^2g0);Pl)@~h zb}$J&hZ~O9DytR@CS@R+UCF~-U#iul_cn7vzGCgPN`;^U8xTDu=qul zO3nb~jYXf=J2);Bb)!P}>`BYxj=8ME4fTgkOia*{Q0VFo~OiF3|Jm zZ~Ydpsg5_L4Llj${<|hbr2^X0dqs!3p&#aLLTQ~*Fim) zs`u1rY4E&QX_W8<-wPzQxXofyqGU-!QU$irV@{XHfBRviLar3`jMAJ*=Eof7gWH-B z=pS>Gw?oE-XN5pjEfuR}twYGkWX7ddsvmUX5xgk3X5?n35#l^unb=*|REq;0nm#p} z4G@%UdYIzORYS0XBz>Ry5)?fU(%~4v)b-`fSRmM#!v8W%IFTUOQSEwz*wqtouy>S%Fnhm`j!tY zIUIk>8)h+8h(JnLAA|j-2YNm{MPsXYl4403%$)uCnNHuqsXCNIRwa0xMNha`-h|67 zq>+KqNq7&ugbNOxT618y_oR*Rk;a0jO4NHeeQX@-Vqe;`nia1KnLYb?hHVvc8 z?HQJ-nH)k#bwc-60iCH&P0!9vQyYiVsc@-ma~gOawi6=24$uo0sb}M<2x;hb1Cvu3 zaBirojod>MDp1%s!sKqqEvg1Jh*~>ZZzPYY?csUZ1hhcu0n%U_wFTs12}*`)Bpeg literal 0 HcmV?d00001 diff --git a/packages/@romejs/js-compiler/lint/rules/react/noDidUpdateSetState.test.md b/packages/@romejs/js-compiler/lint/rules/react/noDidUpdateSetState.test.md index f0b027c7e28..f10f4383ec5 100644 --- a/packages/@romejs/js-compiler/lint/rules/react/noDidUpdateSetState.test.md +++ b/packages/@romejs/js-compiler/lint/rules/react/noDidUpdateSetState.test.md @@ -2,25 +2,22 @@ **DO NOT MODIFY**. This file has been autogenerated. Run `rome test packages/@romejs/js-compiler/lint/rules/react/noDidUpdateSetState.test.ts --update-snapshots` to update. -## `no did update set state` +## `no this.setState in componentDidUpdate` ### `0` ``` - unknown:2:37 lint/noDidUpdateSetState ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + unknown:4:12 lint/noDidUpdateSetState ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - ✖ Avoid use setState in ComponentDidUpdate + ✖ Avoid this.setState in componentDidUpdate - > 2 │ var Hello = createReactClass({ - > 3 │ componentDidUpdate: function() { + 2 │ class Hello extends React.Component { + 3 │ componentDidUpdate() { > 4 │ this.setState({ - > 5 │ name: 'John' - > 6 │ }); - > 7 │ } - > 8 │ }); - │ ^^^^^^^^^ - 9 │ + │ ^^^^^^^^^^^^^ + 5 │ name: 'John' + 6 │ }); ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ @@ -31,13 +28,13 @@ ### `0: formatted` ``` -var Hello = createReactClass({ - componentDidUpdate: function() { - this.setState({ - name: 'John', - }); - }, -}); +class Hello extends React.Component { + componentDidUpdate() { + this.setState({ + name: "John", + }); + } +} ``` @@ -45,20 +42,16 @@ var Hello = createReactClass({ ``` - unknown:2:37 lint/noDidUpdateSetState ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + unknown:5:12 lint/noDidUpdateSetState ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - ✖ Avoid use setState in ComponentDidUpdate + ✖ Avoid this.setState in componentDidUpdate - > 2 │ var Hello = createReactClass({ - > 3 │ componentDidUpdate: function() { - > 4 │ foo(); - > 5 │ this.setState({ - > 6 │ name: 'John' - > 7 │ }); - > 8 │ } - > 9 │ }); - │ ^^^^^^^^^ - 10 │ + 3 │ componentDidUpdate() { + 4 │ foo(); + > 5 │ this.setState({ + │ ^^^^^^^^^^^^^ + 6 │ name: 'John' + 7 │ }); ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ @@ -69,14 +62,14 @@ var Hello = createReactClass({ ### `1: formatted` ``` -var Hello = createReactClass({ - componentDidUpdate: function() { - foo(); - this.setState({ - name: 'John', - }); - }, -}); +class Hello extends React.Component { + componentDidUpdate() { + foo(); + this.setState({ + name: "John", + }); + } +} ``` @@ -84,19 +77,16 @@ var Hello = createReactClass({ ``` - unknown:2:8 lint/noDidUpdateSetState ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + unknown:4:12 lint/noDidUpdateSetState ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - ✖ Avoid use setState in ComponentDidUpdate + ✖ Avoid this.setState in componentDidUpdate - > 2 │ class Hello extends React.Component { - > 3 │ componentDidUpdate() { + 2 │ class Hello extends Component { + 3 │ componentDidUpdate() { > 4 │ this.setState({ - > 5 │ name: 'John' - > 6 │ }); - > 7 │ } - > 8 │ } - │ ^^^^^^^^^ - 9 │ + │ ^^^^^^^^^^^^^ + 5 │ name: 'John' + 6 │ }); ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ @@ -107,12 +97,12 @@ var Hello = createReactClass({ ### `2: formatted` ``` -class Hello extends React.Component { - componentDidUpdate() { - this.setState({ - name: 'John', - }); - } +class Hello extends Component { + componentDidUpdate() { + this.setState({ + name: "John", + }); + } } ``` @@ -121,20 +111,16 @@ class Hello extends React.Component { ``` - unknown:2:8 lint/noDidUpdateSetState ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + unknown:5:12 lint/noDidUpdateSetState ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - ✖ Avoid use setState in ComponentDidUpdate + ✖ Avoid this.setState in componentDidUpdate - > 2 │ class Hello extends React.Component { - > 3 │ componentDidUpdate() { - > 4 │ foo(); - > 5 │ this.setState({ - > 6 │ name: 'John' - > 7 │ }); - > 8 │ } - > 9 │ } - │ ^^^^^^^^^ - 10 │ + 3 │ componentDidUpdate() { + 4 │ foo(); + > 5 │ this.setState({ + │ ^^^^^^^^^^^^^ + 6 │ name: 'John' + 7 │ }); ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ @@ -144,174 +130,36 @@ class Hello extends React.Component { ### `3: formatted` -``` -class Hello extends React.Component { - componentDidUpdate() { - foo(); - this.setState({ - name: 'John', - }); - } -} - -``` - -### `4` - -``` - - unknown:2:8 lint/noDidUpdateSetState ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - ✖ Avoid use setState in ComponentDidUpdate - - > 2 │ class Hello extends Component { - > 3 │ componentDidUpdate() { - > 4 │ this.setState({ - > 5 │ name: 'John' - > 6 │ }); - > 7 │ } - > 8 │ } - │ ^^^^^^^^^ - 9 │ - -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - -✖ Found 1 problem - -``` - -### `4: formatted` - -``` -class Hello extends Component { - componentDidUpdate() { - this.setState({ - name: 'John', - }); - } -} - -``` - -### `5` - -``` - - unknown:2:8 lint/noDidUpdateSetState ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - ✖ Avoid use setState in ComponentDidUpdate - - > 2 │ class Hello extends Component { - > 3 │ componentDidUpdate() { - > 4 │ foo(); - > 5 │ this.setState({ - > 6 │ name: 'John' - > 7 │ }); - > 8 │ } - > 9 │ } - │ ^^^^^^^^^ - 10 │ - -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - -✖ Found 1 problem - -``` - -### `5: formatted` - ``` class Hello extends Component { - componentDidUpdate() { - foo(); - this.setState({ - name: 'John', - }); - } + componentDidUpdate() { + foo(); + this.setState({ + name: "John", + }); + } } ``` -### `6` - -``` -✔ No known problems! - -``` - -### `6: formatted` - -``` -var Hello = createReactClass({ - componentDidUpdate: function() { - if (condition) { - this.setState({ - name: 'John', - }); - } - }, -}); - -``` - -### `7` +### `4` ``` ✔ No known problems! ``` -### `7: formatted` +### `4: formatted` ``` class Hello extends React.Component { - componentDidUpdate() { - if (condition) { - this.setState({ - name: 'John', - }); - } - } -} - -``` - -### `8` - -``` -✔ No known problems! - -``` - -### `8: formatted` - -``` -class Hello extends Component { - componentDidUpdate() { - if (condition) { - this.setState({ - name: 'John', - }); - } - } + componentDidUpdate() { + if (condition) { + this.setState({ + name: "John", + }); + } + } } ``` - -### `9` - -``` -✔ No known problems! - -``` - -### `9: formatted` - -``` -var Hello = createReactClass({ - componentDidUpdate: function() { - foo(); - }, -}); - -``` diff --git a/packages/@romejs/js-compiler/lint/rules/react/noDidUpdateSetState.test.ts b/packages/@romejs/js-compiler/lint/rules/react/noDidUpdateSetState.test.ts index fd29f5a5bef..65bec649b58 100644 --- a/packages/@romejs/js-compiler/lint/rules/react/noDidUpdateSetState.test.ts +++ b/packages/@romejs/js-compiler/lint/rules/react/noDidUpdateSetState.test.ts @@ -5,36 +5,17 @@ * LICENSE file in the root directory of this source tree. */ -import {test} from 'rome'; -import {testLintMultiple} from '../testHelpers'; +import {test} from "rome"; +import {testLintMultiple} from "../testHelpers"; test( - 'no did update set state', - async (t) => { - await testLintMultiple( - t, - [ + "no this.setState in componentDidUpdate", + async (t) => { + await testLintMultiple( + t, + [ // INVALID ` - var Hello = createReactClass({ - componentDidUpdate: function() { - this.setState({ - name: 'John' - }); - } - }); - `, - ` - var Hello = createReactClass({ - componentDidUpdate: function() { - foo(); - this.setState({ - name: 'John' - }); - } - }); - `, - ` class Hello extends React.Component { componentDidUpdate() { this.setState({ @@ -74,17 +55,6 @@ test( `, // VALID ` - var Hello = createReactClass({ - componentDidUpdate: function() { - if (condition) { - this.setState({ - name: 'John' - }); - } - } - }); - `, - ` class Hello extends React.Component { componentDidUpdate() { if (condition) { @@ -95,27 +65,8 @@ test( } } `, - ` - class Hello extends Component { - componentDidUpdate() { - if (condition) { - this.setState({ - name: 'John' - }); - } - } - } - `, - ` - var Hello = createReactClass({ - componentDidUpdate: function() { - foo(); - } - }); - `, - ], - {category: 'lint/noDidUpdateSetState'}, - ); - }, + ], + {category: "lint/noDidUpdateSetState"}, + ); + }, ); - diff --git a/packages/@romejs/js-compiler/lint/rules/react/noDidUpdateSetState.ts b/packages/@romejs/js-compiler/lint/rules/react/noDidUpdateSetState.ts index 45b88de756a..8684b58fa05 100644 --- a/packages/@romejs/js-compiler/lint/rules/react/noDidUpdateSetState.ts +++ b/packages/@romejs/js-compiler/lint/rules/react/noDidUpdateSetState.ts @@ -1,82 +1,31 @@ /** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ +* Copyright (c) Facebook, Inc. and its affiliates. +* +* This source code is licensed under the MIT license found in the +* LICENSE file in the root directory of this source tree. +*/ -import { Path } from "@romejs/js-compiler"; -import { AnyNode, ObjectProperty, AnyClassMember } from "@romejs/js-ast"; -import { descriptions } from "@romejs/diagnostics"; +import {Path, TransformExitResult} from "@romejs/js-compiler"; +import {descriptions} from "@romejs/diagnostics"; +import {doesNodeMatchPattern, isConditional} from "@romejs/js-ast-utils"; -function hasComponentDidUpdate(node: ObjectProperty | AnyClassMember): boolean { - return ( - node.key.type === "StaticPropertyKey" && - node.key.value.type === "Identifier" && - node.key.value.name === "componentDidUpdate" - ); +function inComponentDidUpdate(path: Path): boolean { + const func = path.findAncestry(({node}) => isConditional(node)) !== undefined + return !func && path.findAncestry(({node}) => node.type === "ClassMethod" && node.key.type === "StaticPropertyKey" && node.key.value.type === "Identifier" && node.key.value.name === "componentDidUpdate") !== undefined; } -function hasSetState(node: AnyNode): boolean { - if ( - node.type === "ObjectProperty" && - node.value.type === "FunctionExpression" - ) { - if (node.value.body.type === "BlockStatement") { - return node.value.body.body.some( - statement => - statement.type === "ExpressionStatement" && - statement.expression.type === "CallExpression" && - statement.expression.callee.type === "MemberExpression" && - statement.expression.callee.property.value.type === "Identifier" && - statement.expression.callee.property.value.name === "setState" - ); - } - } - if (node.type === "ClassMethod") { - if (node.body.type === "BlockStatement") { - return node.body.body.some( - statement => - statement.type === "ExpressionStatement" && - statement.expression.type === "CallExpression" && - statement.expression.callee.type === "MemberExpression" && - statement.expression.callee.property.value.type === "Identifier" && - statement.expression.callee.property.value.name === "setState" - ); - } - } - return false; -} - -function hasSetStateInComponentDidUpdate(node: AnyNode): boolean { - if (node.type === "ObjectExpression") { - return node.properties.some( - prop => - prop.type === "ObjectProperty" && - hasComponentDidUpdate(prop) && - hasSetState(prop) - ); - } +export default { + name: "noDidUpdateSetState", + enter(path: Path): TransformExitResult { + const {node} = path; - if (node.type === "ClassDeclaration") { - return node.meta.body.some( - method => hasComponentDidUpdate(method) && hasSetState(method) + if (doesNodeMatchPattern(node, "this.setState") && inComponentDidUpdate(path)) { + path.context.addNodeDiagnostic( + node, + descriptions.LINT.NO_DID_UPDATE_SET_STATE ); } - return false; -} -export default { - name: "noDidUpdateSetState", - enter(path: Path): AnyNode { - const { node } = path; - - if (hasSetStateInComponentDidUpdate(node)) { - path.context.addNodeDiagnostic( - node, - descriptions.LINT.NO_DID_UPDATE_SET_STATE - ); - } - return node; - } + return node; + }, }; From 4842411468704599f47f6f29d3bdb3b5106d12cb Mon Sep 17 00:00:00 2001 From: Victor Hom Date: Sun, 17 May 2020 12:27:34 -0400 Subject: [PATCH 4/5] switch names to a11y to original case --- packages/@romejs/js-compiler/lint/rules/index.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/@romejs/js-compiler/lint/rules/index.ts b/packages/@romejs/js-compiler/lint/rules/index.ts index 5b543d10cfe..d84c79f6f35 100644 --- a/packages/@romejs/js-compiler/lint/rules/index.ts +++ b/packages/@romejs/js-compiler/lint/rules/index.ts @@ -17,10 +17,10 @@ import emptyBlocks from "./regular/emptyBlocks"; import emptyMatches from "./regular/emptyMatches"; import getterReturn from "./regular/getterReturn"; import importDefaultBasename from "./regular/importDefaultBasename"; -import jsxA11yHTMLHasLang from "./react/jsxA11yHTMLHasLang"; -import jsxA11yIframeHasTitle from "./react/jsxA11yIframeHasTitle"; -import jsxA11yImgRedundantAlt from "./react/jsxA11yImgRedundantAlt"; -import jsxA11yNoTargetBlank from "./react/jsxA11yNoTargetBlank"; +import jsxA11YHTMLHasLang from "./react/jsxA11yHTMLHasLang"; +import jsxA11YIframeHasTitle from "./react/jsxA11yIframeHasTitle"; +import jsxA11YImgRedundantAlt from "./react/jsxA11yImgRedundantAlt"; +import jsxA11YNoTargetBlank from "./react/jsxA11yNoTargetBlank"; import jsxKey from "./react/jsxKey"; import jsxNoCommentText from "./react/jsxNoCommentText"; import negationElse from "./regular/negationElse"; @@ -83,10 +83,10 @@ export const lintTransforms = [ emptyMatches, getterReturn, importDefaultBasename, - jsxA11yHTMLHasLang, - jsxA11yIframeHasTitle, - jsxA11yImgRedundantAlt, - jsxA11yNoTargetBlank, + jsxA11YHTMLHasLang, + jsxA11YIframeHasTitle, + jsxA11YImgRedundantAlt, + jsxA11YNoTargetBlank, jsxKey, jsxNoCommentText, negationElse, From 1d5c86769b853ee699e260573aecf83ce50690b4 Mon Sep 17 00:00:00 2001 From: Victor Hom Date: Sun, 17 May 2020 12:31:46 -0400 Subject: [PATCH 5/5] run assert-generated and add changes --- packages/@romejs/diagnostics/categories.ts | 2 +- packages/@romejs/js-compiler/lint/rules/index.ts | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/@romejs/diagnostics/categories.ts b/packages/@romejs/diagnostics/categories.ts index 65469a193a0..39642336eeb 100644 --- a/packages/@romejs/diagnostics/categories.ts +++ b/packages/@romejs/diagnostics/categories.ts @@ -92,7 +92,7 @@ export type DiagnosticCategoryPrefix = // EVERYTHING BELOW IS AUTOGENERATED. SEE SCRIPTS FOLDER FOR UPDATE SCRIPTS type LintDiagnosticCategory = - | "lint/camelCase" + | "lint/camelCase" | "lint/caseSingleStatement" | "lint/confusingLanguage" | "lint/defaultExportSameBasename" diff --git a/packages/@romejs/js-compiler/lint/rules/index.ts b/packages/@romejs/js-compiler/lint/rules/index.ts index d84c79f6f35..6dc35ae67a3 100644 --- a/packages/@romejs/js-compiler/lint/rules/index.ts +++ b/packages/@romejs/js-compiler/lint/rules/index.ts @@ -6,7 +6,6 @@ */ // EVERYTHING BELOW IS AUTOGENERATED. SEE SCRIPTS FOLDER FOR UPDATE SCRIPTS - import camelCase from "./regular/camelCase"; import caseSingleStatement from "./regular/caseSingleStatement"; import confusingLanguage from "./regular/confusingLanguage";