diff --git a/_data/rules.yml b/_data/rules.yml index f967cd825b..2cec8c1d08 100644 --- a/_data/rules.yml +++ b/_data/rules.yml @@ -6,186 +6,230 @@ categories: enforce "for" loop update clause moving the counter in the right direction. fixable: false + hasSuggestions: false name: for-direction recommended: true - description: enforce `return` statements in getters fixable: false + hasSuggestions: false name: getter-return recommended: true - description: disallow using an async function as a Promise executor fixable: false + hasSuggestions: false name: no-async-promise-executor recommended: true - description: disallow `await` inside of loops fixable: false + hasSuggestions: false name: no-await-in-loop recommended: false - description: disallow comparing against -0 fixable: false + hasSuggestions: false name: no-compare-neg-zero recommended: true - description: disallow assignment operators in conditional expressions fixable: false + hasSuggestions: false name: no-cond-assign recommended: true - description: disallow the use of `console` fixable: false + hasSuggestions: false name: no-console recommended: false - description: disallow constant expressions in conditions fixable: false + hasSuggestions: false name: no-constant-condition recommended: true - description: disallow control characters in regular expressions fixable: false + hasSuggestions: false name: no-control-regex recommended: true - description: disallow the use of `debugger` fixable: false + hasSuggestions: false name: no-debugger recommended: true - description: disallow duplicate arguments in `function` definitions fixable: false + hasSuggestions: false name: no-dupe-args recommended: true - description: disallow duplicate conditions in if-else-if chains fixable: false + hasSuggestions: false name: no-dupe-else-if recommended: true - description: disallow duplicate keys in object literals fixable: false + hasSuggestions: false name: no-dupe-keys recommended: true - description: disallow duplicate case labels fixable: false + hasSuggestions: false name: no-duplicate-case recommended: true - description: disallow empty block statements fixable: false + hasSuggestions: false name: no-empty recommended: true - description: disallow empty character classes in regular expressions fixable: false + hasSuggestions: false name: no-empty-character-class recommended: true - description: disallow reassigning exceptions in `catch` clauses fixable: false + hasSuggestions: false name: no-ex-assign recommended: true - description: disallow unnecessary boolean casts fixable: true + hasSuggestions: false name: no-extra-boolean-cast recommended: true - description: disallow unnecessary parentheses fixable: true + hasSuggestions: false name: no-extra-parens recommended: false - description: disallow unnecessary semicolons fixable: true + hasSuggestions: false name: no-extra-semi recommended: true - description: disallow reassigning `function` declarations fixable: false + hasSuggestions: false name: no-func-assign recommended: true - description: disallow assigning to imported bindings fixable: false + hasSuggestions: false name: no-import-assign recommended: true - description: disallow variable or `function` declarations in nested blocks fixable: false + hasSuggestions: false name: no-inner-declarations recommended: true - description: disallow invalid regular expression strings in `RegExp` constructors fixable: false + hasSuggestions: false name: no-invalid-regexp recommended: true - description: disallow irregular whitespace fixable: false + hasSuggestions: false name: no-irregular-whitespace recommended: true - description: disallow literal numbers that lose precision fixable: false + hasSuggestions: false name: no-loss-of-precision recommended: false - description: >- disallow characters which are made with multiple code points in character class syntax fixable: false + hasSuggestions: false name: no-misleading-character-class recommended: true - description: disallow calling global object properties as functions fixable: false + hasSuggestions: false name: no-obj-calls recommended: true - description: disallow returning values from Promise executor functions fixable: false + hasSuggestions: false name: no-promise-executor-return recommended: false - description: disallow calling some `Object.prototype` methods directly on objects fixable: false + hasSuggestions: false name: no-prototype-builtins recommended: true - description: disallow multiple spaces in regular expressions fixable: true + hasSuggestions: false name: no-regex-spaces recommended: true - description: disallow returning values from setters fixable: false + hasSuggestions: false name: no-setter-return recommended: true - description: disallow sparse arrays fixable: false + hasSuggestions: false name: no-sparse-arrays recommended: true - description: disallow template literal placeholder syntax in regular strings fixable: false + hasSuggestions: false name: no-template-curly-in-string recommended: false - description: disallow confusing multiline expressions fixable: false + hasSuggestions: false name: no-unexpected-multiline recommended: true - description: >- disallow unreachable code after `return`, `throw`, `continue`, and `break` statements fixable: false + hasSuggestions: false name: no-unreachable recommended: true - description: disallow loops with a body that allows only one iteration fixable: false + hasSuggestions: false name: no-unreachable-loop recommended: false - description: disallow control flow statements in `finally` blocks fixable: false + hasSuggestions: false name: no-unsafe-finally recommended: true - description: disallow negating the left operand of relational operators fixable: false + hasSuggestions: true name: no-unsafe-negation recommended: true - description: >- disallow use of optional chaining in contexts where the `undefined` value is not allowed fixable: false + hasSuggestions: false name: no-unsafe-optional-chaining recommended: false - description: disallow useless backreferences in regular expressions fixable: false + hasSuggestions: false name: no-useless-backreference recommended: false - description: >- disallow assignments that can lead to race conditions due to usage of `await` or `yield` fixable: false + hasSuggestions: false name: require-atomic-updates recommended: false - description: require calls to `isNaN()` when checking for `NaN` fixable: false + hasSuggestions: false name: use-isnan recommended: true - description: enforce comparing `typeof` expressions against valid strings fixable: false + hasSuggestions: false name: valid-typeof recommended: true - description: >- @@ -195,334 +239,414 @@ categories: rules: - description: enforce getter and setter pairs in objects and classes fixable: false + hasSuggestions: false name: accessor-pairs recommended: false - description: enforce `return` statements in callbacks of array methods fixable: false + hasSuggestions: false name: array-callback-return recommended: false - description: enforce the use of variables within the scope they are defined fixable: false + hasSuggestions: false name: block-scoped-var recommended: false - description: enforce that class methods utilize `this` fixable: false + hasSuggestions: false name: class-methods-use-this recommended: false - description: enforce a maximum cyclomatic complexity allowed in a program fixable: false + hasSuggestions: false name: complexity recommended: false - description: require `return` statements to either always or never specify values fixable: false + hasSuggestions: false name: consistent-return recommended: false - description: enforce consistent brace style for all control statements fixable: true + hasSuggestions: false name: curly recommended: false - description: require `default` cases in `switch` statements fixable: false + hasSuggestions: false name: default-case recommended: false - description: enforce default clauses in switch statements to be last fixable: false + hasSuggestions: false name: default-case-last recommended: false - description: enforce default parameters to be last fixable: false + hasSuggestions: false name: default-param-last recommended: false - description: enforce consistent newlines before and after dots fixable: true + hasSuggestions: false name: dot-location recommended: false - description: enforce dot notation whenever possible fixable: true + hasSuggestions: false name: dot-notation recommended: false - description: require the use of `===` and `!==` fixable: true + hasSuggestions: false name: eqeqeq recommended: false - description: require grouped accessor pairs in object literals and classes fixable: false + hasSuggestions: false name: grouped-accessor-pairs recommended: false - description: require `for-in` loops to include an `if` statement fixable: false + hasSuggestions: false name: guard-for-in recommended: false - description: enforce a maximum number of classes per file fixable: false + hasSuggestions: false name: max-classes-per-file recommended: false - description: 'disallow the use of `alert`, `confirm`, and `prompt`' fixable: false + hasSuggestions: false name: no-alert recommended: false - description: disallow the use of `arguments.caller` or `arguments.callee` fixable: false + hasSuggestions: false name: no-caller recommended: false - description: disallow lexical declarations in case clauses fixable: false + hasSuggestions: false name: no-case-declarations recommended: true - description: disallow returning value from constructor fixable: false + hasSuggestions: false name: no-constructor-return recommended: false - description: >- disallow division operators explicitly at the beginning of regular expressions fixable: true + hasSuggestions: false name: no-div-regex recommended: false - description: disallow `else` blocks after `return` statements in `if` statements fixable: true + hasSuggestions: false name: no-else-return recommended: false - description: disallow empty functions fixable: false + hasSuggestions: false name: no-empty-function recommended: false - description: disallow empty destructuring patterns fixable: false + hasSuggestions: false name: no-empty-pattern recommended: true - description: disallow `null` comparisons without type-checking operators fixable: false + hasSuggestions: false name: no-eq-null recommended: false - description: disallow the use of `eval()` fixable: false + hasSuggestions: false name: no-eval recommended: false - description: disallow extending native types fixable: false + hasSuggestions: false name: no-extend-native recommended: false - description: disallow unnecessary calls to `.bind()` fixable: true + hasSuggestions: false name: no-extra-bind recommended: false - description: disallow unnecessary labels fixable: true + hasSuggestions: false name: no-extra-label recommended: false - description: disallow fallthrough of `case` statements fixable: false + hasSuggestions: false name: no-fallthrough recommended: true - description: disallow leading or trailing decimal points in numeric literals fixable: true + hasSuggestions: false name: no-floating-decimal recommended: false - description: disallow assignments to native objects or read-only global variables fixable: false + hasSuggestions: false name: no-global-assign recommended: true - description: disallow shorthand type conversions fixable: true + hasSuggestions: false name: no-implicit-coercion recommended: false - description: disallow declarations in the global scope fixable: false + hasSuggestions: false name: no-implicit-globals recommended: false - description: disallow the use of `eval()`-like methods fixable: false + hasSuggestions: false name: no-implied-eval recommended: false - description: disallow `this` keywords outside of classes or class-like objects fixable: false + hasSuggestions: false name: no-invalid-this recommended: false - description: disallow the use of the `__iterator__` property fixable: false + hasSuggestions: false name: no-iterator recommended: false - description: disallow labeled statements fixable: false + hasSuggestions: false name: no-labels recommended: false - description: disallow unnecessary nested blocks fixable: false + hasSuggestions: false name: no-lone-blocks recommended: false - description: >- disallow function declarations that contain unsafe references inside loop statements fixable: false + hasSuggestions: false name: no-loop-func recommended: false - description: disallow magic numbers fixable: false + hasSuggestions: false name: no-magic-numbers recommended: false - description: disallow multiple spaces fixable: true + hasSuggestions: false name: no-multi-spaces recommended: false - description: disallow multiline strings fixable: false + hasSuggestions: false name: no-multi-str recommended: false - description: disallow `new` operators outside of assignments or comparisons fixable: false + hasSuggestions: false name: no-new recommended: false - description: disallow `new` operators with the `Function` object fixable: false + hasSuggestions: false name: no-new-func recommended: false - description: >- disallow `new` operators with the `String`, `Number`, and `Boolean` objects fixable: false + hasSuggestions: false name: no-new-wrappers recommended: false - description: disallow `\8` and `\9` escape sequences in string literals fixable: false + hasSuggestions: true name: no-nonoctal-decimal-escape recommended: false - description: disallow octal literals fixable: false + hasSuggestions: false name: no-octal recommended: true - description: disallow octal escape sequences in string literals fixable: false + hasSuggestions: false name: no-octal-escape recommended: false - description: disallow reassigning `function` parameters fixable: false + hasSuggestions: false name: no-param-reassign recommended: false - description: disallow the use of the `__proto__` property fixable: false + hasSuggestions: false name: no-proto recommended: false - description: disallow variable redeclaration fixable: false + hasSuggestions: false name: no-redeclare recommended: true - description: disallow certain properties on certain objects fixable: false + hasSuggestions: false name: no-restricted-properties recommended: false - description: disallow assignment operators in `return` statements fixable: false + hasSuggestions: false name: no-return-assign recommended: false - description: disallow unnecessary `return await` fixable: false + hasSuggestions: false name: no-return-await recommended: false - description: 'disallow `javascript:` urls' fixable: false + hasSuggestions: false name: no-script-url recommended: false - description: disallow assignments where both sides are exactly the same fixable: false + hasSuggestions: false name: no-self-assign recommended: true - description: disallow comparisons where both sides are exactly the same fixable: false + hasSuggestions: false name: no-self-compare recommended: false - description: disallow comma operators fixable: false + hasSuggestions: false name: no-sequences recommended: false - description: disallow throwing literals as exceptions fixable: false + hasSuggestions: false name: no-throw-literal recommended: false - description: disallow unmodified loop conditions fixable: false + hasSuggestions: false name: no-unmodified-loop-condition recommended: false - description: disallow unused expressions fixable: false + hasSuggestions: false name: no-unused-expressions recommended: false - description: disallow unused labels fixable: true + hasSuggestions: false name: no-unused-labels recommended: true - description: disallow unnecessary calls to `.call()` and `.apply()` fixable: false + hasSuggestions: false name: no-useless-call recommended: false - description: disallow unnecessary `catch` clauses fixable: false + hasSuggestions: false name: no-useless-catch recommended: true - description: disallow unnecessary concatenation of literals or template literals fixable: false + hasSuggestions: false name: no-useless-concat recommended: false - description: disallow unnecessary escape characters fixable: false + hasSuggestions: true name: no-useless-escape recommended: true - description: disallow redundant return statements fixable: true + hasSuggestions: false name: no-useless-return recommended: false - description: disallow `void` operators fixable: false + hasSuggestions: false name: no-void recommended: false - description: disallow specified warning terms in comments fixable: false + hasSuggestions: false name: no-warning-comments recommended: false - description: disallow `with` statements fixable: false + hasSuggestions: false name: no-with recommended: true - description: enforce using named capture group in regular expression fixable: false + hasSuggestions: false name: prefer-named-capture-group recommended: false - description: require using Error objects as Promise rejection reasons fixable: false + hasSuggestions: false name: prefer-promise-reject-errors recommended: false - description: >- disallow use of the `RegExp` constructor in favor of regular expression literals fixable: false + hasSuggestions: false name: prefer-regex-literals recommended: false - description: >- enforce the consistent use of the radix argument when using `parseInt()` fixable: false + hasSuggestions: true name: radix recommended: false - description: disallow async functions which have no `await` expression fixable: false + hasSuggestions: false name: require-await recommended: false - description: enforce the use of `u` flag on RegExp fixable: false + hasSuggestions: false name: require-unicode-regexp recommended: false - description: >- require `var` declarations be placed at the top of their containing scope fixable: false + hasSuggestions: false name: vars-on-top recommended: false - description: require parentheses around immediate `function` invocations fixable: true + hasSuggestions: false name: wrap-iife recommended: false - description: require or disallow "Yoda" conditions fixable: true + hasSuggestions: false name: yoda recommended: false - description: 'These rules relate to strict mode directives:' @@ -530,6 +654,7 @@ categories: rules: - description: require or disallow strict mode directives fixable: true + hasSuggestions: false name: strict recommended: false - description: 'These rules relate to variable declarations:' @@ -537,50 +662,61 @@ categories: rules: - description: require or disallow initialization in variable declarations fixable: false + hasSuggestions: false name: init-declarations recommended: false - description: disallow deleting variables fixable: false + hasSuggestions: false name: no-delete-var recommended: true - description: disallow labels that share a name with a variable fixable: false + hasSuggestions: false name: no-label-var recommended: false - description: disallow specified global variables fixable: false + hasSuggestions: false name: no-restricted-globals recommended: false - description: >- disallow variable declarations from shadowing variables declared in the outer scope fixable: false + hasSuggestions: false name: no-shadow recommended: false - description: disallow identifiers from shadowing restricted names fixable: false + hasSuggestions: false name: no-shadow-restricted-names recommended: true - description: >- disallow the use of undeclared variables unless mentioned in `/*global */` comments fixable: false + hasSuggestions: false name: no-undef recommended: true - description: disallow initializing variables to `undefined` fixable: true + hasSuggestions: false name: no-undef-init recommended: false - description: disallow the use of `undefined` as an identifier fixable: false + hasSuggestions: false name: no-undefined recommended: false - description: disallow unused variables fixable: false + hasSuggestions: false name: no-unused-vars recommended: true - description: disallow the use of variables before they are defined fixable: false + hasSuggestions: false name: no-use-before-define recommended: false - description: >- @@ -590,396 +726,489 @@ categories: rules: - description: enforce linebreaks after opening and before closing array brackets fixable: true + hasSuggestions: false name: array-bracket-newline recommended: false - description: enforce consistent spacing inside array brackets fixable: true + hasSuggestions: false name: array-bracket-spacing recommended: false - description: enforce line breaks after each array element fixable: true + hasSuggestions: false name: array-element-newline recommended: false - description: >- disallow or enforce spaces inside of blocks after opening block and before closing block fixable: true + hasSuggestions: false name: block-spacing recommended: false - description: enforce consistent brace style for blocks fixable: true + hasSuggestions: false name: brace-style recommended: false - description: enforce camelcase naming convention fixable: false + hasSuggestions: false name: camelcase recommended: false - description: enforce or disallow capitalization of the first letter of a comment fixable: true + hasSuggestions: false name: capitalized-comments recommended: false - description: require or disallow trailing commas fixable: true + hasSuggestions: false name: comma-dangle recommended: false - description: enforce consistent spacing before and after commas fixable: true + hasSuggestions: false name: comma-spacing recommended: false - description: enforce consistent comma style fixable: true + hasSuggestions: false name: comma-style recommended: false - description: enforce consistent spacing inside computed property brackets fixable: true + hasSuggestions: false name: computed-property-spacing recommended: false - description: enforce consistent naming when capturing the current execution context fixable: false + hasSuggestions: false name: consistent-this recommended: false - description: require or disallow newline at the end of files fixable: true + hasSuggestions: false name: eol-last recommended: false - description: >- require or disallow spacing between function identifiers and their invocations fixable: true + hasSuggestions: false name: func-call-spacing recommended: false - description: >- require function names to match the name of the variable or property to which they are assigned fixable: false + hasSuggestions: false name: func-name-matching recommended: false - description: require or disallow named `function` expressions fixable: false + hasSuggestions: false name: func-names recommended: false - description: >- enforce the consistent use of either `function` declarations or expressions fixable: false + hasSuggestions: false name: func-style recommended: false - description: enforce line breaks between arguments of a function call fixable: true + hasSuggestions: false name: function-call-argument-newline recommended: false - description: enforce consistent line breaks inside function parentheses fixable: true + hasSuggestions: false name: function-paren-newline recommended: false - description: disallow specified identifiers fixable: false + hasSuggestions: false name: id-denylist recommended: false - description: enforce minimum and maximum identifier lengths fixable: false + hasSuggestions: false name: id-length recommended: false - description: require identifiers to match a specified regular expression fixable: false + hasSuggestions: false name: id-match recommended: false - description: enforce the location of arrow function bodies fixable: true + hasSuggestions: false name: implicit-arrow-linebreak recommended: false - description: enforce consistent indentation fixable: true + hasSuggestions: false name: indent recommended: false - description: >- enforce the consistent use of either double or single quotes in JSX attributes fixable: true + hasSuggestions: false name: jsx-quotes recommended: false - description: >- enforce consistent spacing between keys and values in object literal properties fixable: true + hasSuggestions: false name: key-spacing recommended: false - description: enforce consistent spacing before and after keywords fixable: true + hasSuggestions: false name: keyword-spacing recommended: false - description: enforce position of line comments fixable: false + hasSuggestions: false name: line-comment-position recommended: false - description: enforce consistent linebreak style fixable: true + hasSuggestions: false name: linebreak-style recommended: false - description: require empty lines around comments fixable: true + hasSuggestions: false name: lines-around-comment recommended: false - description: require or disallow an empty line between class members fixable: true + hasSuggestions: false name: lines-between-class-members recommended: false - description: enforce a maximum depth that blocks can be nested fixable: false + hasSuggestions: false name: max-depth recommended: false - description: enforce a maximum line length fixable: false + hasSuggestions: false name: max-len recommended: false - description: enforce a maximum number of lines per file fixable: false + hasSuggestions: false name: max-lines recommended: false - description: enforce a maximum number of lines of code in a function fixable: false + hasSuggestions: false name: max-lines-per-function recommended: false - description: enforce a maximum depth that callbacks can be nested fixable: false + hasSuggestions: false name: max-nested-callbacks recommended: false - description: enforce a maximum number of parameters in function definitions fixable: false + hasSuggestions: false name: max-params recommended: false - description: enforce a maximum number of statements allowed in function blocks fixable: false + hasSuggestions: false name: max-statements recommended: false - description: enforce a maximum number of statements allowed per line fixable: false + hasSuggestions: false name: max-statements-per-line recommended: false - description: enforce a particular style for multiline comments fixable: true + hasSuggestions: false name: multiline-comment-style recommended: false - description: enforce newlines between operands of ternary expressions fixable: true + hasSuggestions: false name: multiline-ternary recommended: false - description: require constructor names to begin with a capital letter fixable: false + hasSuggestions: false name: new-cap recommended: false - description: >- enforce or disallow parentheses when invoking a constructor with no arguments fixable: true + hasSuggestions: false name: new-parens recommended: false - description: require a newline after each call in a method chain fixable: true + hasSuggestions: false name: newline-per-chained-call recommended: false - description: disallow `Array` constructors fixable: false + hasSuggestions: false name: no-array-constructor recommended: false - description: disallow bitwise operators fixable: false + hasSuggestions: false name: no-bitwise recommended: false - description: disallow `continue` statements fixable: false + hasSuggestions: false name: no-continue recommended: false - description: disallow inline comments after code fixable: false + hasSuggestions: false name: no-inline-comments recommended: false - description: disallow `if` statements as the only statement in `else` blocks fixable: true + hasSuggestions: false name: no-lonely-if recommended: false - description: disallow mixed binary operators fixable: false + hasSuggestions: false name: no-mixed-operators recommended: false - description: disallow mixed spaces and tabs for indentation fixable: false + hasSuggestions: false name: no-mixed-spaces-and-tabs recommended: true - description: disallow use of chained assignment expressions fixable: false + hasSuggestions: false name: no-multi-assign recommended: false - description: disallow multiple empty lines fixable: true + hasSuggestions: false name: no-multiple-empty-lines recommended: false - description: disallow negated conditions fixable: false + hasSuggestions: false name: no-negated-condition recommended: false - description: disallow nested ternary expressions fixable: false + hasSuggestions: false name: no-nested-ternary recommended: false - description: disallow `Object` constructors fixable: false + hasSuggestions: false name: no-new-object recommended: false - description: disallow the unary operators `++` and `--` fixable: false + hasSuggestions: false name: no-plusplus recommended: false - description: disallow specified syntax fixable: false + hasSuggestions: false name: no-restricted-syntax recommended: false - description: disallow all tabs fixable: false + hasSuggestions: false name: no-tabs recommended: false - description: disallow ternary operators fixable: false + hasSuggestions: false name: no-ternary recommended: false - description: disallow trailing whitespace at the end of lines fixable: true + hasSuggestions: false name: no-trailing-spaces recommended: false - description: disallow dangling underscores in identifiers fixable: false + hasSuggestions: false name: no-underscore-dangle recommended: false - description: disallow ternary operators when simpler alternatives exist fixable: true + hasSuggestions: false name: no-unneeded-ternary recommended: false - description: disallow whitespace before properties fixable: true + hasSuggestions: false name: no-whitespace-before-property recommended: false - description: enforce the location of single-line statements fixable: true + hasSuggestions: false name: nonblock-statement-body-position recommended: false - description: enforce consistent line breaks after opening and before closing braces fixable: true + hasSuggestions: false name: object-curly-newline recommended: false - description: enforce consistent spacing inside braces fixable: true + hasSuggestions: false name: object-curly-spacing recommended: false - description: enforce placing object properties on separate lines fixable: true + hasSuggestions: false name: object-property-newline recommended: false - description: >- enforce variables to be declared either together or separately in functions fixable: true + hasSuggestions: false name: one-var recommended: false - description: require or disallow newlines around variable declarations fixable: true + hasSuggestions: false name: one-var-declaration-per-line recommended: false - description: require or disallow assignment operator shorthand where possible fixable: true + hasSuggestions: false name: operator-assignment recommended: false - description: enforce consistent linebreak style for operators fixable: true + hasSuggestions: false name: operator-linebreak recommended: false - description: require or disallow padding within blocks fixable: true + hasSuggestions: false name: padded-blocks recommended: false - description: require or disallow padding lines between statements fixable: true + hasSuggestions: false name: padding-line-between-statements recommended: false - description: disallow the use of `Math.pow` in favor of the `**` operator fixable: true + hasSuggestions: false name: prefer-exponentiation-operator recommended: false - description: >- disallow using Object.assign with an object literal as the first argument and prefer the use of object spread instead. fixable: true + hasSuggestions: false name: prefer-object-spread recommended: false - description: require quotes around object literal property names fixable: true + hasSuggestions: false name: quote-props recommended: false - description: >- enforce the consistent use of either backticks, double, or single quotes fixable: true + hasSuggestions: false name: quotes recommended: false - description: require or disallow semicolons instead of ASI fixable: true + hasSuggestions: false name: semi recommended: false - description: enforce consistent spacing before and after semicolons fixable: true + hasSuggestions: false name: semi-spacing recommended: false - description: enforce location of semicolons fixable: true + hasSuggestions: false name: semi-style recommended: false - description: require object keys to be sorted fixable: false + hasSuggestions: false name: sort-keys recommended: false - description: require variables within the same declaration block to be sorted fixable: true + hasSuggestions: false name: sort-vars recommended: false - description: enforce consistent spacing before blocks fixable: true + hasSuggestions: false name: space-before-blocks recommended: false - description: >- enforce consistent spacing before `function` definition opening parenthesis fixable: true + hasSuggestions: false name: space-before-function-paren recommended: false - description: enforce consistent spacing inside parentheses fixable: true + hasSuggestions: false name: space-in-parens recommended: false - description: require spacing around infix operators fixable: true + hasSuggestions: false name: space-infix-ops recommended: false - description: enforce consistent spacing before or after unary operators fixable: true + hasSuggestions: false name: space-unary-ops recommended: false - description: enforce consistent spacing after the `//` or `/*` in a comment fixable: true + hasSuggestions: false name: spaced-comment recommended: false - description: enforce spacing around colons of switch statements fixable: true + hasSuggestions: false name: switch-colon-spacing recommended: false - description: require or disallow spacing between template tags and their literals fixable: true + hasSuggestions: false name: template-tag-spacing recommended: false - description: require or disallow Unicode byte order mark (BOM) fixable: true + hasSuggestions: false name: unicode-bom recommended: false - description: require parenthesis around regex literals fixable: true + hasSuggestions: false name: wrap-regex recommended: false - description: 'These rules relate to ES6, also known as ES2015:' @@ -987,144 +1216,176 @@ categories: rules: - description: require braces around arrow function bodies fixable: true + hasSuggestions: false name: arrow-body-style recommended: false - description: require parentheses around arrow function arguments fixable: true + hasSuggestions: false name: arrow-parens recommended: false - description: >- enforce consistent spacing before and after the arrow in arrow functions fixable: true + hasSuggestions: false name: arrow-spacing recommended: false - description: require `super()` calls in constructors fixable: false + hasSuggestions: false name: constructor-super recommended: true - description: enforce consistent spacing around `*` operators in generator functions fixable: true + hasSuggestions: false name: generator-star-spacing recommended: false - description: disallow reassigning class members fixable: false + hasSuggestions: false name: no-class-assign recommended: true - description: disallow arrow functions where they could be confused with comparisons fixable: true + hasSuggestions: false name: no-confusing-arrow recommended: false - description: disallow reassigning `const` variables fixable: false + hasSuggestions: false name: no-const-assign recommended: true - description: disallow duplicate class members fixable: false + hasSuggestions: false name: no-dupe-class-members recommended: true - description: disallow duplicate module imports fixable: false + hasSuggestions: false name: no-duplicate-imports recommended: false - description: disallow `new` operators with the `Symbol` object fixable: false + hasSuggestions: false name: no-new-symbol recommended: true - description: disallow specified names in exports fixable: false + hasSuggestions: false name: no-restricted-exports recommended: false - description: disallow specified modules when loaded by `import` fixable: false + hasSuggestions: false name: no-restricted-imports recommended: false - description: disallow `this`/`super` before calling `super()` in constructors fixable: false + hasSuggestions: false name: no-this-before-super recommended: true - description: disallow unnecessary computed property keys in objects and classes fixable: true + hasSuggestions: false name: no-useless-computed-key recommended: false - description: disallow unnecessary constructors fixable: false + hasSuggestions: false name: no-useless-constructor recommended: false - description: >- disallow renaming import, export, and destructured assignments to the same name fixable: true + hasSuggestions: false name: no-useless-rename recommended: false - description: require `let` or `const` instead of `var` fixable: true + hasSuggestions: false name: no-var recommended: false - description: >- require or disallow method and property shorthand syntax for object literals fixable: true + hasSuggestions: false name: object-shorthand recommended: false - description: require using arrow functions for callbacks fixable: true + hasSuggestions: false name: prefer-arrow-callback recommended: false - description: >- require `const` declarations for variables that are never reassigned after declared fixable: true + hasSuggestions: false name: prefer-const recommended: false - description: require destructuring from arrays and/or objects fixable: true + hasSuggestions: false name: prefer-destructuring recommended: false - description: >- disallow `parseInt()` and `Number.parseInt()` in favor of binary, octal, and hexadecimal literals fixable: true + hasSuggestions: false name: prefer-numeric-literals recommended: false - description: require rest parameters instead of `arguments` fixable: false + hasSuggestions: false name: prefer-rest-params recommended: false - description: require spread operators instead of `.apply()` fixable: false + hasSuggestions: false name: prefer-spread recommended: false - description: require template literals instead of string concatenation fixable: true + hasSuggestions: false name: prefer-template recommended: false - description: require generator functions to contain `yield` fixable: false + hasSuggestions: false name: require-yield recommended: true - description: >- enforce spacing between rest and spread operators and their expressions fixable: true + hasSuggestions: false name: rest-spread-spacing recommended: false - description: enforce sorted import declarations within modules fixable: true + hasSuggestions: false name: sort-imports recommended: false - description: require symbol descriptions fixable: false + hasSuggestions: false name: symbol-description recommended: false - description: >- require or disallow spacing around embedded expressions of template strings fixable: true + hasSuggestions: false name: template-curly-spacing recommended: false - description: require or disallow spacing around the `*` in `yield*` expressions fixable: true + hasSuggestions: false name: yield-star-spacing recommended: false deprecated: diff --git a/_data/sponsors.json b/_data/sponsors.json index 86d5f73618..2a172cd1ca 100644 --- a/_data/sponsors.json +++ b/_data/sponsors.json @@ -5,7 +5,7 @@ "url": "https://automattic.com", "image": "https://images.opencollective.com/photomatt/d0ef3e1/logo.png", "monthlyDonation": 200000, - "totalDonations": 1800000, + "totalDonations": 2000000, "source": "opencollective", "tier": "platinum-sponsor" } @@ -16,7 +16,7 @@ "url": "https://nx.dev", "image": "https://images.opencollective.com/nx/0efbe42/logo.png", "monthlyDonation": 100000, - "totalDonations": 600000, + "totalDonations": 700000, "source": "opencollective", "tier": "gold-sponsor" }, @@ -25,7 +25,7 @@ "url": "https://google.com/chrome", "image": "https://images.opencollective.com/chrome/dc55bd4/logo.png", "monthlyDonation": 100000, - "totalDonations": 900000, + "totalDonations": 1000000, "source": "opencollective", "tier": "gold-sponsor" }, @@ -34,7 +34,7 @@ "url": "https://www.salesforce.com", "image": "https://images.opencollective.com/salesforce/ca8f997/logo.png", "monthlyDonation": 100000, - "totalDonations": 3933100, + "totalDonations": 4033100, "source": "opencollective", "tier": "gold-sponsor" }, @@ -43,7 +43,7 @@ "url": "https://www.airbnb.com/", "image": "https://images.opencollective.com/airbnb/d327d66/logo.png", "monthlyDonation": 100000, - "totalDonations": 3061000, + "totalDonations": 3161000, "source": "opencollective", "tier": "gold-sponsor" }, @@ -70,7 +70,7 @@ "url": "https://retool.com/", "image": "https://images.opencollective.com/retool/98ea68e/logo.png", "monthlyDonation": 50000, - "totalDonations": 300000, + "totalDonations": 350000, "source": "opencollective", "tier": "silver-sponsor" }, @@ -79,18 +79,36 @@ "url": "https://liftoff.io/", "image": "https://images.opencollective.com/liftoff/5c4fa84/logo.png", "monthlyDonation": 50000, - "totalDonations": 700000, + "totalDonations": 750000, "source": "opencollective", "tier": "silver-sponsor" } ], "bronze": [ + { + "name": "TROYPOINT", + "url": "https://troypoint.com", + "image": "https://images.opencollective.com/troypoint/080f96f/avatar.png", + "monthlyDonation": 20000, + "totalDonations": 20000, + "source": "opencollective", + "tier": "bronze-sponsor" + }, + { + "name": "Mobilen", + "url": "https://mobilen.nu", + "image": "https://images.opencollective.com/mobilen/e19860d/logo.png", + "monthlyDonation": 20000, + "totalDonations": 20000, + "source": "opencollective", + "tier": "bronze-sponsor" + }, { "name": "Anagram Solver", "url": "https://www.crosswordsolver.org/anagram-solver/", "image": "https://images.opencollective.com/anagram-solver/2666271/logo.png", "monthlyDonation": 20000, - "totalDonations": 320000, + "totalDonations": 340000, "source": "opencollective", "tier": "bronze-sponsor" }, @@ -99,7 +117,7 @@ "url": null, "image": "https://images.opencollective.com/bugsnag-stability-monitoring/c2cef36/logo.png", "monthlyDonation": 20000, - "totalDonations": 420000, + "totalDonations": 440000, "source": "opencollective", "tier": "bronze-sponsor" }, @@ -108,7 +126,7 @@ "url": "https://mixpanel.com", "image": "https://images.opencollective.com/mixpanel/cd682f7/logo.png", "monthlyDonation": 20000, - "totalDonations": 460000, + "totalDonations": 480000, "source": "opencollective", "tier": "bronze-sponsor" }, @@ -117,7 +135,7 @@ "url": "https://www.vpsserver.com", "image": "https://images.opencollective.com/vpsservercom/logo.png", "monthlyDonation": 20000, - "totalDonations": 480000, + "totalDonations": 500000, "source": "opencollective", "tier": "bronze-sponsor" }, @@ -126,16 +144,16 @@ "url": "https://icons8.com", "image": "https://images.opencollective.com/icons8/7fa1641/logo.png", "monthlyDonation": 20000, - "totalDonations": 480000, + "totalDonations": 500000, "source": "opencollective", "tier": "bronze-sponsor" }, { "name": "Discord", "url": "https://discord.com", - "image": "https://images.opencollective.com/discordapp/7e3d9a9/logo.png", + "image": "https://images.opencollective.com/discordapp/f9645d9/logo.png", "monthlyDonation": 20000, - "totalDonations": 540000, + "totalDonations": 560000, "source": "opencollective", "tier": "bronze-sponsor" }, @@ -144,7 +162,7 @@ "url": "https://themeisle.com", "image": "https://images.opencollective.com/themeisle/d5592fe/logo.png", "monthlyDonation": 20000, - "totalDonations": 560000, + "totalDonations": 580000, "source": "opencollective", "tier": "bronze-sponsor" }, @@ -153,7 +171,7 @@ "url": "https://www.firesticktricks.com", "image": "https://images.opencollective.com/fire-stick-tricks/b8fbe2c/logo.png", "monthlyDonation": 20000, - "totalDonations": 560000, + "totalDonations": 580000, "source": "opencollective", "tier": "bronze-sponsor" }, @@ -181,7 +199,7 @@ "url": "https://yannick.cr", "image": "https://images.opencollective.com/yannickcr/765f06f/avatar.png", "monthlyDonation": 10000, - "totalDonations": 250000, + "totalDonations": 260000, "source": "opencollective", "tier": "backer" }, @@ -198,7 +216,7 @@ "url": "https://www.principal.com/about-us", "image": "https://images.opencollective.com/principal/431e690/logo.png", "monthlyDonation": 5000, - "totalDonations": 60000, + "totalDonations": 65000, "source": "opencollective", "tier": null }, @@ -223,7 +241,7 @@ "url": "https://www.storis.com/", "image": "https://images.opencollective.com/storis/dfb0e13/logo.png", "monthlyDonation": 2500, - "totalDonations": 5000, + "totalDonations": 7500, "source": "opencollective", "tier": null }, @@ -232,7 +250,7 @@ "url": "https://balsa.com", "image": "https://images.opencollective.com/balsa/77de498/logo.png", "monthlyDonation": 2500, - "totalDonations": 8500, + "totalDonations": 11000, "source": "opencollective", "tier": "backer" }, @@ -241,7 +259,7 @@ "url": "https://www.neovation.com", "image": "https://images.opencollective.com/neovationcorp/30d1cf7/logo.png", "monthlyDonation": 2500, - "totalDonations": 75000, + "totalDonations": 77500, "source": "opencollective", "tier": "backer" }, @@ -276,7 +294,7 @@ "url": "https://xh.io", "image": "https://images.opencollective.com/xh/cec0963/logo.png", "monthlyDonation": 1000, - "totalDonations": 5000, + "totalDonations": 6000, "source": "opencollective", "tier": "backer" }, @@ -285,7 +303,7 @@ "url": "https://raider.io", "image": "https://images.opencollective.com/raiderio_wow/7a380a3/logo.png", "monthlyDonation": 1000, - "totalDonations": 6000, + "totalDonations": 7000, "source": "opencollective", "tier": "backer" }, @@ -294,7 +312,7 @@ "url": "https://www.simedia.com/", "image": "https://images.opencollective.com/simedia/848efc9/logo.png", "monthlyDonation": 1000, - "totalDonations": 12000, + "totalDonations": 13000, "source": "opencollective", "tier": null }, @@ -303,7 +321,7 @@ "url": null, "image": "https://images.opencollective.com/john-hamilton/avatar.png", "monthlyDonation": 1000, - "totalDonations": 13000, + "totalDonations": 14000, "source": "opencollective", "tier": "backer" }, @@ -312,7 +330,7 @@ "url": "https://http:/www.powercoder.tech", "image": "https://images.opencollective.com/john-dorlus/f6d79b4/avatar.png", "monthlyDonation": 1000, - "totalDonations": 18000, + "totalDonations": 19000, "source": "opencollective", "tier": "backer" }, @@ -321,7 +339,7 @@ "url": "https://n8n.io", "image": "https://images.opencollective.com/n8n/dca2f0c/logo.png", "monthlyDonation": 1000, - "totalDonations": 19000, + "totalDonations": 20000, "source": "opencollective", "tier": "backer" }, @@ -330,7 +348,7 @@ "url": "https://github.com/bentruyman", "image": "https://images.opencollective.com/bentruyman/9dc2d16/avatar.png", "monthlyDonation": 1000, - "totalDonations": 21000, + "totalDonations": 22000, "source": "opencollective", "tier": "backer" }, @@ -339,7 +357,7 @@ "url": "https://moxio.com", "image": "https://images.opencollective.com/moxio/9fa53c1/logo.png", "monthlyDonation": 1000, - "totalDonations": 41000, + "totalDonations": 42000, "source": "opencollective", "tier": "backer" }, @@ -348,7 +366,7 @@ "url": null, "image": "https://images.opencollective.com/kevin-partington/54f2124/avatar.png", "monthlyDonation": 1000, - "totalDonations": 26000, + "totalDonations": 27000, "source": "opencollective", "tier": "backer" }, @@ -357,7 +375,7 @@ "url": "https://benjamin.piouffle.com", "image": "https://images.opencollective.com/betree/6c68f43/avatar.png", "monthlyDonation": 1000, - "totalDonations": 29800, + "totalDonations": 30800, "source": "opencollective", "tier": "backer" }, @@ -385,6 +403,14 @@ "source": "github", "tier": "backer" }, + { + "name": "Nobutaka OSHIRO", + "image": "https://avatars.githubusercontent.com/u/3583286?u=cf4c1f3e26e13c58dd86227213feedc1d5e2984f&v=4", + "url": "https://notakaos.com", + "monthlyDonation": 1000, + "source": "github", + "tier": "backer" + }, { "name": "OpenCraft", "image": "https://avatars.githubusercontent.com/u/7414786?v=4", @@ -428,7 +454,15 @@ { "name": "cvermand", "image": "https://avatars.githubusercontent.com/u/33010418?u=92fcf1932c437d7d7909c0df3552c5efad5467d9&v=4", - "url": "http://meilisearch.com/", + "url": "https://github.com/bidoubiwa", + "monthlyDonation": 1000, + "source": "github", + "tier": "backer" + }, + { + "name": "Buttondown", + "image": "https://avatars.githubusercontent.com/u/48390753?v=4", + "url": "buttondown.email", "monthlyDonation": 1000, "source": "github", "tier": "backer" @@ -442,11 +476,30 @@ "tier": "backer" }, { - "name": "Spaceship", - "image": "https://avatars.githubusercontent.com/u/58706594?v=4", - "url": "https://spaceship.run", - "monthlyDonation": 1000, - "source": "github", + "name": "Mesh Payments", + "url": "https://meshpayments.com/", + "image": "https://images.opencollective.com/meshpayments/e216d5a/logo.png", + "monthlyDonation": 500, + "totalDonations": 500, + "source": "opencollective", + "tier": "backer" + }, + { + "name": "Cui Mingda", + "url": "https://mingda.net", + "image": "https://images.opencollective.com/cuimingda/1faca0f/avatar.png", + "monthlyDonation": 500, + "totalDonations": 500, + "source": "opencollective", + "tier": "backer" + }, + { + "name": "Toan Nguyen", + "url": null, + "image": "https://images.opencollective.com/toan-nguyen1/avatar.png", + "monthlyDonation": 500, + "totalDonations": 1000, + "source": "opencollective", "tier": "backer" }, { @@ -454,7 +507,7 @@ "url": "https://linnertmedia.de", "image": "https://images.opencollective.com/alinnert/9126453/avatar.png", "monthlyDonation": 500, - "totalDonations": 1000, + "totalDonations": 1500, "source": "opencollective", "tier": "backer" }, @@ -463,7 +516,7 @@ "url": null, "image": "https://images.opencollective.com/clement-ollivier/fb7bb09/avatar.png", "monthlyDonation": 500, - "totalDonations": 1500, + "totalDonations": 2000, "source": "opencollective", "tier": "backer" }, @@ -472,7 +525,7 @@ "url": null, "image": "https://images.opencollective.com/arnaud-drain/d7165f2/avatar.png", "monthlyDonation": 500, - "totalDonations": 2000, + "totalDonations": 2500, "source": "opencollective", "tier": "backer" }, @@ -481,7 +534,7 @@ "url": null, "image": "https://images.opencollective.com/morgane-dubus/avatar.png", "monthlyDonation": 500, - "totalDonations": 2000, + "totalDonations": 2500, "source": "opencollective", "tier": "backer" }, @@ -490,7 +543,7 @@ "url": "https://tripwire.com", "image": "https://images.opencollective.com/tripwire/7599e30/logo.png", "monthlyDonation": 500, - "totalDonations": 2500, + "totalDonations": 3000, "source": "opencollective", "tier": "backer" }, @@ -499,7 +552,7 @@ "url": "https://solverfox.dev", "image": "https://images.opencollective.com/eps1lon/4200608/avatar.png", "monthlyDonation": 500, - "totalDonations": 2500, + "totalDonations": 3000, "source": "opencollective", "tier": "backer" }, @@ -508,7 +561,7 @@ "url": "https://joealden.com", "image": "https://images.opencollective.com/joealden/44a6738/avatar.png", "monthlyDonation": 500, - "totalDonations": 2500, + "totalDonations": 3000, "source": "opencollective", "tier": "backer" }, @@ -517,7 +570,7 @@ "url": "https://batch.com", "image": "https://images.opencollective.com/batch/3ccdb8f/logo.png", "monthlyDonation": 500, - "totalDonations": 3000, + "totalDonations": 3500, "source": "opencollective", "tier": "backer" }, @@ -526,7 +579,7 @@ "url": "https://sushko.me", "image": "https://images.opencollective.com/sashasushko/5b221d8/avatar.png", "monthlyDonation": 500, - "totalDonations": 3500, + "totalDonations": 4000, "source": "opencollective", "tier": "backer" }, @@ -535,7 +588,7 @@ "url": null, "image": "https://images.opencollective.com/ayush000/avatar.png", "monthlyDonation": 500, - "totalDonations": 3500, + "totalDonations": 4000, "source": "opencollective", "tier": "backer" }, @@ -544,7 +597,7 @@ "url": "http://www.nfriedly.com", "image": "https://images.opencollective.com/nfriedly/c7be1d5/avatar.png", "monthlyDonation": 500, - "totalDonations": 5000, + "totalDonations": 5500, "source": "opencollective", "tier": "backer" }, @@ -562,7 +615,7 @@ "url": null, "image": "https://images.opencollective.com/lex-webb/e94811a/avatar.png", "monthlyDonation": 500, - "totalDonations": 5000, + "totalDonations": 5500, "source": "opencollective", "tier": "backer" }, @@ -571,7 +624,7 @@ "url": null, "image": "https://images.opencollective.com/brianpeiris/68fdb65/avatar.png", "monthlyDonation": 500, - "totalDonations": 5000, + "totalDonations": 5500, "source": "opencollective", "tier": "backer" }, @@ -580,7 +633,7 @@ "url": "https://www.quora.com/profile/Alexandre-Morgaut", "image": "https://images.opencollective.com/alexandre-morgaut/6e3c8d4/avatar.png", "monthlyDonation": 500, - "totalDonations": 13000, + "totalDonations": 13500, "source": "opencollective", "tier": "backer" }, @@ -589,7 +642,7 @@ "url": "https://www.sayyup.nl", "image": "https://images.opencollective.com/sayyup/4c61ffd/avatar.png", "monthlyDonation": 500, - "totalDonations": 5500, + "totalDonations": 6000, "source": "opencollective", "tier": "backer" }, @@ -598,7 +651,7 @@ "url": "https://justinnoel.dev", "image": "https://images.opencollective.com/justinnoel/avatar.png", "monthlyDonation": 500, - "totalDonations": 6000, + "totalDonations": 6500, "source": "opencollective", "tier": "backer" }, @@ -616,7 +669,7 @@ "url": "https://blacksheepcode.com", "image": "https://images.opencollective.com/blacksheepcode/976d69a/avatar.png", "monthlyDonation": 500, - "totalDonations": 9500, + "totalDonations": 10000, "source": "opencollective", "tier": "backer" }, @@ -625,7 +678,7 @@ "url": null, "image": "https://images.opencollective.com/touchless/8efea29/logo.png", "monthlyDonation": 500, - "totalDonations": 85000, + "totalDonations": 85500, "source": "opencollective", "tier": "backer" }, @@ -634,7 +687,7 @@ "url": "https://about.me/peterdehaan", "image": "https://images.opencollective.com/pdehaan/4437929/avatar.png", "monthlyDonation": 500, - "totalDonations": 9500, + "totalDonations": 10000, "source": "opencollective", "tier": "backer" }, @@ -643,7 +696,7 @@ "url": "https://wwjcdo.com", "image": "https://images.opencollective.com/jmcombs/22a314a/avatar.png", "monthlyDonation": 500, - "totalDonations": 10000, + "totalDonations": 10500, "source": "opencollective", "tier": "backer" }, @@ -652,7 +705,7 @@ "url": "https://matterapp.com", "image": "https://images.opencollective.com/matter_hq/ac0a719/logo.png", "monthlyDonation": 500, - "totalDonations": 12000, + "totalDonations": 12500, "source": "opencollective", "tier": "backer" }, @@ -661,7 +714,7 @@ "url": null, "image": "https://images.opencollective.com/james-sherwood-jones/avatar.png", "monthlyDonation": 500, - "totalDonations": 12500, + "totalDonations": 13000, "source": "opencollective", "tier": "backer" }, @@ -670,7 +723,7 @@ "url": "https://medium.com/@eliseumds", "image": "https://images.opencollective.com/eliseu/fe16988/avatar.png", "monthlyDonation": 500, - "totalDonations": 12500, + "totalDonations": 13000, "source": "opencollective", "tier": "backer" }, @@ -679,7 +732,7 @@ "url": null, "image": "https://images.opencollective.com/martin-desrumaux/avatar.png", "monthlyDonation": 500, - "totalDonations": 13000, + "totalDonations": 13500, "source": "opencollective", "tier": "backer" }, @@ -688,7 +741,7 @@ "url": "https://jblandry.info", "image": "https://images.opencollective.com/jblandry/e968bf5/avatar.png", "monthlyDonation": 500, - "totalDonations": 14000, + "totalDonations": 14500, "source": "opencollective", "tier": "backer" }, @@ -697,7 +750,7 @@ "url": "https://pushred.co", "image": "https://images.opencollective.com/pushred/506ad8d/avatar.png", "monthlyDonation": 500, - "totalDonations": 14500, + "totalDonations": 15000, "source": "opencollective", "tier": "backer" }, @@ -706,7 +759,7 @@ "url": "https://twitter.com/jumbleofideas", "image": "https://images.opencollective.com/aj-klein/b63b472/avatar.png", "monthlyDonation": 500, - "totalDonations": 14500, + "totalDonations": 15000, "source": "opencollective", "tier": "backer" }, @@ -715,7 +768,7 @@ "url": "https://thirdiron.com", "image": "https://images.opencollective.com/third_iron/fa6ec4d/logo.png", "monthlyDonation": 500, - "totalDonations": 15000, + "totalDonations": 15500, "source": "opencollective", "tier": "backer" }, @@ -724,7 +777,7 @@ "url": "https://kluska.cz", "image": "https://images.opencollective.com/martin-kluska/588a7ff/avatar.png", "monthlyDonation": 500, - "totalDonations": 15000, + "totalDonations": 15500, "source": "opencollective", "tier": "backer" }, @@ -733,7 +786,7 @@ "url": "https://www.maisonette.com", "image": "https://images.opencollective.com/maisonetteworld/c170bfc/logo.png", "monthlyDonation": 500, - "totalDonations": 15000, + "totalDonations": 15500, "source": "opencollective", "tier": "backer" }, @@ -742,7 +795,7 @@ "url": "https://cantremember.com", "image": "https://images.opencollective.com/cantremember/avatar.png", "monthlyDonation": 500, - "totalDonations": 15000, + "totalDonations": 15500, "source": "opencollective", "tier": "backer" }, @@ -751,7 +804,7 @@ "url": "https://korzun.com", "image": "https://images.opencollective.com/simon-korzun/cbdefdd/avatar.png", "monthlyDonation": 500, - "totalDonations": 15000, + "totalDonations": 15500, "source": "opencollective", "tier": "backer" }, @@ -760,7 +813,7 @@ "url": "https://medikoo.com", "image": "https://images.opencollective.com/medikoo/f16a7ea/avatar.png", "monthlyDonation": 500, - "totalDonations": 15000, + "totalDonations": 15500, "source": "opencollective", "tier": "backer" }, @@ -769,7 +822,7 @@ "url": "https://pymaster.tw", "image": "https://images.opencollective.com/pc035860/8fed8ae/avatar.png", "monthlyDonation": 500, - "totalDonations": 15000, + "totalDonations": 15500, "source": "opencollective", "tier": "backer" }, @@ -778,7 +831,7 @@ "url": "https://www.gavinmogan.com", "image": "https://images.opencollective.com/gavinmogan/305e987/avatar.png", "monthlyDonation": 500, - "totalDonations": 15000, + "totalDonations": 15500, "source": "opencollective", "tier": "backer" }, @@ -787,7 +840,7 @@ "url": null, "image": "https://images.opencollective.com/novascreen/ef6acf0/avatar.png", "monthlyDonation": 500, - "totalDonations": 15000, + "totalDonations": 15500, "source": "opencollective", "tier": "backer" }, @@ -796,7 +849,7 @@ "url": "https://klamp.in", "image": "https://images.opencollective.com/klamping/26de35c/avatar.png", "monthlyDonation": 500, - "totalDonations": 15000, + "totalDonations": 15500, "source": "opencollective", "tier": "backer" }, @@ -805,7 +858,7 @@ "url": "https://nubz.com", "image": "https://images.opencollective.com/nubz/logo.png", "monthlyDonation": 500, - "totalDonations": 15000, + "totalDonations": 15500, "source": "opencollective", "tier": "backer" }, @@ -814,7 +867,7 @@ "url": "https://alexeyraspopov.com", "image": "https://images.opencollective.com/alexeyraspopov/d8c7a67/avatar.png", "monthlyDonation": 500, - "totalDonations": 15000, + "totalDonations": 15500, "source": "opencollective", "tier": "backer" }, @@ -823,7 +876,7 @@ "url": null, "image": "https://images.opencollective.com/joseph-percy/avatar.png", "monthlyDonation": 500, - "totalDonations": 15000, + "totalDonations": 15500, "source": "opencollective", "tier": "backer" }, @@ -832,7 +885,7 @@ "url": "https://twitter.com/LJHarb", "image": "https://images.opencollective.com/ljharb/b75a3f8/avatar.png", "monthlyDonation": 500, - "totalDonations": 15000, + "totalDonations": 15500, "source": "opencollective", "tier": "backer" }, @@ -852,14 +905,6 @@ "source": "github", "tier": "backer" }, - { - "name": "Marcel Eichner", - "image": "https://avatars.githubusercontent.com/u/73654?u=cad7f6e133b38d6825e04625940d565cd47a4e32&v=4", - "url": "http://www.marceleichner.de", - "monthlyDonation": 500, - "source": "github", - "tier": "backer" - }, { "name": "Tsuyoshi Tokuda", "image": "https://avatars.githubusercontent.com/u/108762?v=4", @@ -900,14 +945,6 @@ "source": "github", "tier": "backer" }, - { - "name": "Justin Duke", - "image": "https://avatars.githubusercontent.com/u/461046?u=1f9a13559d572173272118d4bcbab17937178f6e&v=4", - "url": "arcana.computer", - "monthlyDonation": 500, - "source": "github", - "tier": "backer" - }, { "name": "Forrest Desjardins", "image": "https://avatars.githubusercontent.com/u/502491?u=1658efb692d4da77a8f68251b9dd8d7a3bdf7aab&v=4", @@ -972,6 +1009,14 @@ "source": "github", "tier": "backer" }, + { + "name": "Zhigang Fang", + "image": "https://avatars.githubusercontent.com/u/1057756?u=15c3cdff1c715ac27bbc63ccb8f0a1c27eeb3784&v=4", + "url": "https://reily.app", + "monthlyDonation": 500, + "source": "github", + "tier": "backer" + }, { "name": "Peter Hozák", "image": "https://avatars.githubusercontent.com/u/1087670?u=5a6738983bae1f3a10243aa603a5e9caa641d93d&v=4", @@ -989,25 +1034,25 @@ "tier": "backer" }, { - "name": "Jonny Burger", - "image": "https://avatars.githubusercontent.com/u/1629785?u=12eb94da6070d00fc924761ce06e3a428d01b7e9&v=4", - "url": "https://jonny.io", + "name": "Charles Severance", + "image": "https://avatars.githubusercontent.com/u/1197222?u=d6dc85c064736ab851c6d9e3318dcdd1be00fb2c&v=4", + "url": "http://www.dr-chuck.com/", "monthlyDonation": 500, "source": "github", "tier": "backer" }, { - "name": "Kelp", - "image": "https://avatars.githubusercontent.com/u/1680868?u=9cc8d19368770784b7b96dda1b9e7dee9503fa5a&v=4", - "url": "https://meetpet.org", + "name": "Jonny Burger", + "image": "https://avatars.githubusercontent.com/u/1629785?u=12eb94da6070d00fc924761ce06e3a428d01b7e9&v=4", + "url": "https://jonny.io", "monthlyDonation": 500, "source": "github", "tier": "backer" }, { - "name": "elzup", - "image": "https://avatars.githubusercontent.com/u/2284908?u=d136063c35917db63b91018be853e280a87f9511&v=4", - "url": "https://elzup.com", + "name": "Kelp", + "image": "https://avatars.githubusercontent.com/u/1680868?u=0a111786a32d6d31a83e803a1f0328692eb28049&v=4", + "url": "https://meetpet.org", "monthlyDonation": 500, "source": "github", "tier": "backer" @@ -1102,7 +1147,7 @@ }, { "name": "Mattia Richetto", - "image": "https://avatars.githubusercontent.com/u/6423261?u=9aaf95f3b725bd8cd62e98b0b078380b44aa52a7&v=4", + "image": "https://avatars.githubusercontent.com/u/6423261?u=2db1047889c8130effccc2366f55ec63e1124f94&v=4", "url": "https://medium.com/@mattiaerre", "monthlyDonation": 500, "source": "github", @@ -1111,7 +1156,7 @@ { "name": "Nicolas Charpentier", "image": "https://avatars.githubusercontent.com/u/7189823?u=f7558a0f6828f45f1082970880aefbeab9596d0b&v=4", - "url": "https://medium.com/@charpeni", + "url": "https://charpeni.com", "monthlyDonation": 500, "source": "github", "tier": "backer" @@ -1159,7 +1204,7 @@ { "name": "Mátyás Angyal", "image": "https://avatars.githubusercontent.com/u/9975467?u=9bfe754866a39f54746982ca47f1465885efd769&v=4", - "url": "amatyas001.github.io", + "url": "https://github.com/amatyas001", "monthlyDonation": 500, "source": "github", "tier": "backer" @@ -1214,24 +1259,24 @@ }, { "name": "Montana Mendy", - "image": "https://avatars.githubusercontent.com/u/20936398?u=4f49ffa3b8af0f9242beb0f10b945845e5ece293&v=4", + "image": "https://avatars.githubusercontent.com/u/20936398?u=4d77fdcb7d7ba27b31898615cbf4e68a4eb3a31f&v=4", "url": "https://about.travis-ci.com/team/", "monthlyDonation": 500, "source": "github", "tier": "backer" }, { - "name": "The GraphQL Guide", - "image": "https://avatars.githubusercontent.com/u/23441982?v=4", - "url": "https://graphql.guide", + "name": "Gustavo Alfaro", + "image": "https://avatars.githubusercontent.com/u/21284308?u=c16ab1206e16039c4898999d61e45220a5644ded&v=4", + "url": "https://github.com/gustavoalfaro", "monthlyDonation": 500, "source": "github", "tier": "backer" }, { - "name": "Hugh Chocart", - "image": "https://avatars.githubusercontent.com/u/24587702?u=77d38b49118964f816fbf43115e7daf699dad2ae&v=4", - "url": "hugh.sh", + "name": "The GraphQL Guide", + "image": "https://avatars.githubusercontent.com/u/23441982?v=4", + "url": "https://graphql.guide", "monthlyDonation": 500, "source": "github", "tier": "backer" @@ -1295,7 +1340,7 @@ { "name": "Michael R.", "image": "https://avatars.githubusercontent.com/u/47695475?u=16c26c488cf1cc4f03da1a9e48a47d1dbf2bd397&v=4", - "url": "https://safethishome.com", + "url": "https://rehnert.co", "monthlyDonation": 500, "source": "github", "tier": "backer" @@ -1321,7 +1366,7 @@ "url": null, "image": "https://images.opencollective.com/womcauliff/2be6f36/avatar.png", "monthlyDonation": 300, - "totalDonations": 9700, + "totalDonations": 10000, "source": "opencollective", "tier": "backer" }, @@ -1330,7 +1375,7 @@ "url": "https://ca.linkedin.com/in/sudharakap", "image": "https://images.opencollective.com/sudharaka-palamakumbura/03b6087/avatar.png", "monthlyDonation": 200, - "totalDonations": 400, + "totalDonations": 600, "source": "opencollective", "tier": null }, @@ -1339,7 +1384,7 @@ "url": "https://kostasbariotis.com", "image": "https://images.opencollective.com/konmpar/6f12288/avatar.png", "monthlyDonation": 200, - "totalDonations": 2200, + "totalDonations": 2400, "source": "opencollective", "tier": null }, @@ -1348,7 +1393,7 @@ "url": null, "image": "https://images.opencollective.com/tillsanders/1c9743b/avatar.png", "monthlyDonation": 100, - "totalDonations": 1200, + "totalDonations": 1300, "source": "opencollective", "tier": null }, @@ -1357,7 +1402,7 @@ "url": null, "image": "https://images.opencollective.com/toptalo/237a912/avatar.png", "monthlyDonation": 100, - "totalDonations": 1100, + "totalDonations": 1200, "source": "opencollective", "tier": null }, @@ -1366,7 +1411,7 @@ "url": null, "image": "https://images.opencollective.com/kristof-michiels/avatar.png", "monthlyDonation": 100, - "totalDonations": 4500, + "totalDonations": 4600, "source": "opencollective", "tier": null } diff --git a/_data/team.json b/_data/team.json index 4ee2bc13dd..31b037fc5f 100644 --- a/_data/team.json +++ b/_data/team.json @@ -162,6 +162,18 @@ } ], "committers": [ + { + "username": "brettz9", + "name": "Brett Zamir", + "website": "http://brett-zamir.me", + "avatar_url": "https://avatars.githubusercontent.com/u/20234?v=4" + }, + { + "username": "bmish", + "name": "Bryan Mishkin", + "website": "http://www.linkedin.com/in/bmish", + "avatar_url": "https://avatars.githubusercontent.com/u/698306?v=4" + }, { "username": "g-plane", "name": "Pig Fang", diff --git a/_includes/menu.liquid b/_includes/menu.liquid index 844ec4212d..1d1229f544 100644 --- a/_includes/menu.liquid +++ b/_includes/menu.liquid @@ -31,6 +31,7 @@
  • Formatters
  • Integrations
  • +
  • Migrating to v8.0.0
  • Migrating to v7.0.0
  • Migrating to v6.0.0
  • Migrating to v5.0.0
  • diff --git a/_layouts/doc.liquid b/_layouts/doc.liquid index 4885dd4e61..8722792c3c 100644 --- a/_layouts/doc.liquid +++ b/_layouts/doc.liquid @@ -28,8 +28,10 @@ | replace: '

    (recommended) ', '

    (removed) ', '

    ' | replace: '

    (fixable) ', '

    ' - | replace: '(recommended)', '' - | replace: '(fixable)', '' + | replace: '

    (hasSuggestions) ', '

    ' + | replace: '(recommended)', '' + | replace: '(fixable)', '🔧' + | replace: '(hasSuggestions)', '💡' }} diff --git a/_layouts/rule.liquid b/_layouts/rule.liquid index 1c444b445e..854f29814f 100644 --- a/_layouts/rule.liquid +++ b/_layouts/rule.liquid @@ -25,6 +25,7 @@ | replace: '

    (removed) ', '

    ' | replace: '

    (recommended) ', '

    (fixable) ', '

    ' + | replace: '

    (hasSuggestions) ', '

    ' }} diff --git a/_layouts/rules.liquid b/_layouts/rules.liquid index 692de5bc49..2c9e1175f9 100644 --- a/_layouts/rules.liquid +++ b/_layouts/rules.liquid @@ -14,8 +14,9 @@ {{ content - | replace: '(recommended)', '' - | replace: '(fixable)', '' + | replace: '(recommended)', '' + | replace: '(fixable)', '🔧' + | replace: '(hasSuggestions)', '💡' }} diff --git a/_posts/2021-07-17-eslint-v7.31.0-released.md b/_posts/2021-07-17-eslint-v7.31.0-released.md new file mode 100644 index 0000000000..a80ca0a3bc --- /dev/null +++ b/_posts/2021-07-17-eslint-v7.31.0-released.md @@ -0,0 +1,59 @@ +--- +layout: post +title: ESLint v7.31.0 released +tags: + - release + - minor +--- +# ESLint v7.31.0 released + +We just pushed ESLint v7.31.0, which is a minor release upgrade of ESLint. This release adds some new features and fixes several bugs found in the previous release. + + + + + + + + + + +## Enhancements + + +* [`a96b05f`](https://github.com/eslint/eslint/commit/a96b05f6c5649cfee112d605c91d95aa191e2f78) Update: add end location to report in [`consistent-return`](/docs/rules/consistent-return) (refs [#12334](https://github.com/eslint/eslint/issues/12334)) ([#14798](https://github.com/eslint/eslint/issues/14798)) (Nitin Kumar) +* [`ddffa8a`](https://github.com/eslint/eslint/commit/ddffa8ad58b4b124b08061e9045fdb5370cbdbe3) Update: Indicating the operator in question ([#14764](https://github.com/eslint/eslint/issues/14764)) (Paul Smith) +* [`bba714c`](https://github.com/eslint/eslint/commit/bba714c2ed813821ed288fbc07722cdde6e534fe) Update: Clarifying what changes need to be made in [no-mixed-operators](/docs/rules/no-mixed-operators) ([#14765](https://github.com/eslint/eslint/issues/14765)) (Paul Smith) + + + + + + +## Documentation + + +* [`e0e8e30`](https://github.com/eslint/eslint/commit/e0e8e308929c9c66612505f2da89043f8592eea7) Docs: update BUG_REPORT template ([#14787](https://github.com/eslint/eslint/issues/14787)) (Nitin Kumar) +* [`39115c8`](https://github.com/eslint/eslint/commit/39115c8b71d2629161359f6456f47fdbd552fddd) Docs: provide more context to [no-eq-null](/docs/rules/no-eq-null) ([#14801](https://github.com/eslint/eslint/issues/14801)) (gfyoung) +* [`9a3c73c`](https://github.com/eslint/eslint/commit/9a3c73c130d437a65f4edba0dcb63390e68cac41) Docs: fix a broken link ([#14790](https://github.com/eslint/eslint/issues/14790)) (Sam Chen) +* [`b0d22e3`](https://github.com/eslint/eslint/commit/b0d22e3eff18ea7f08189134c07cddceaec69a09) Docs: Mention benefit of providing `meta.docs.url` ([#14774](https://github.com/eslint/eslint/issues/14774)) (Bryan Mishkin) + + + + +## Dependency Upgrades + + +* [`efdbb12`](https://github.com/eslint/eslint/commit/efdbb1227019427ec2d968a8d6e9151dd8a77c35) Upgrade: @eslint/eslintrc to v0.4.3 ([#14808](https://github.com/eslint/eslint/issues/14808)) (Brandon Mills) + + + + + + +## Chores + + +* [`a6a7438`](https://github.com/eslint/eslint/commit/a6a7438502abc6a1e29ec35cfbe2058ffc0803b1) Chore: pin fs-teardown@0.1.1 ([#14771](https://github.com/eslint/eslint/issues/14771)) (Milos Djermanovic) + + diff --git a/_posts/2021-07-30-eslint-v7.32.0-released.md b/_posts/2021-07-30-eslint-v7.32.0-released.md new file mode 100644 index 0000000000..5be8811d43 --- /dev/null +++ b/_posts/2021-07-30-eslint-v7.32.0-released.md @@ -0,0 +1,63 @@ +--- +layout: post +title: ESLint v7.32.0 released +tags: + - release + - minor +--- +# ESLint v7.32.0 released + +We just pushed ESLint v7.32.0, which is a minor release upgrade of ESLint. This release adds some new features and fixes several bugs found in the previous release. + +## Highlights + +The new [`--exit-on-fatal-error` option](https://eslint.org/docs/user-guide/command-line-interface#--exit-on-fatal-error) will treat parsing errors as fatal and return exit code 2. By default, parsing errors return exit code 1 like rule violations. + +## Features + + +* [`1bfbefd`](https://github.com/eslint/eslint/commit/1bfbefdaaf19ef32df42b89a3f5d32cff1e5b831) New: Exit on fatal error (fixes [#13711](https://github.com/eslint/eslint/issues/13711)) ([#14730](https://github.com/eslint/eslint/issues/14730)) (Antonios Katopodis) + + + + +## Enhancements + + +* [`faecf56`](https://github.com/eslint/eslint/commit/faecf56cdb4146b28bfa4f1980adb41b4d3614b1) Update: change reporting location for [`curly`](/docs/rules/curly) rule (refs [#12334](https://github.com/eslint/eslint/issues/12334)) ([#14766](https://github.com/eslint/eslint/issues/14766)) (Nitin Kumar) + + + + +## Bug Fixes + + +* [`d7dc07a`](https://github.com/eslint/eslint/commit/d7dc07a15e256cee9232183165e2f6102f2c0873) Fix: ignore lines with empty elements (fixes [#12756](https://github.com/eslint/eslint/issues/12756)) ([#14837](https://github.com/eslint/eslint/issues/14837)) (Soufiane Boutahlil) + + + + +## Documentation + + +* [`d53d906`](https://github.com/eslint/eslint/commit/d53d9064b9dd0dd6a8ea39e07b16310c8364db69) Docs: Prepare data for website to indicate rules with suggestions ([#14830](https://github.com/eslint/eslint/issues/14830)) (Bryan Mishkin) +* [`d28f2ff`](https://github.com/eslint/eslint/commit/d28f2ffb986e49d6da5c1d91215580591f4cfd35) Docs: Reference eslint-config-eslint to avoid potential for staleness ([#14805](https://github.com/eslint/eslint/issues/14805)) (Brett Zamir) +* [`f9c164f`](https://github.com/eslint/eslint/commit/f9c164f7b74ca73384c8c80eed5bdbe359b44f6c) Docs: New syntax issue template ([#14826](https://github.com/eslint/eslint/issues/14826)) (Nicholas C. Zakas) +* [`ed945bd`](https://github.com/eslint/eslint/commit/ed945bd662714b1917e9de71d5b322a28be9161b) Docs: fix multiple broken links ([#14833](https://github.com/eslint/eslint/issues/14833)) (Sam Chen) +* [`6641d88`](https://github.com/eslint/eslint/commit/6641d88e17d952a8e51df5e0d3882a842d4c3f35) Docs: Update README team and sponsors (ESLint Jenkins) + + + + + + + + +## Chores + + +* [`3c78a7b`](https://github.com/eslint/eslint/commit/3c78a7bff6044fd196ae3b737983e6744c6eb7c8) Chore: Adopt `eslint-plugin/prefer-message-ids` rule internally ([#14841](https://github.com/eslint/eslint/issues/14841)) (Bryan Mishkin) +* [`ed007c8`](https://github.com/eslint/eslint/commit/ed007c82ee9d2170c87500d98303554b5f90b915) Chore: Simplify internal `no-invalid-meta` rule ([#14842](https://github.com/eslint/eslint/issues/14842)) (Bryan Mishkin) +* [`8be8a36`](https://github.com/eslint/eslint/commit/8be8a36010145dfcd31cbdd4f781a91989e3b1bd) Chore: Adopt `eslint-plugin/require-meta-docs-url` rule internally ([#14823](https://github.com/eslint/eslint/issues/14823)) (Bryan Mishkin) +* [`eba0c45`](https://github.com/eslint/eslint/commit/eba0c4595c126a91f700d5f2e8723ec3f820a830) Chore: assertions on reporting loc in [`unicode-bom`](/docs/rules/unicode-bom) (refs [#12334](https://github.com/eslint/eslint/issues/12334)) ([#14809](https://github.com/eslint/eslint/issues/14809)) (Nitin Kumar) +* [`60df44c`](https://github.com/eslint/eslint/commit/60df44c79b0f74406119c0c040a360ca84e721fc) Chore: use `actions/setup-node@v2` ([#14816](https://github.com/eslint/eslint/issues/14816)) (Nitin Kumar) diff --git a/_posts/2021-08-14-eslint-v8.0.0-beta.0-released.md b/_posts/2021-08-14-eslint-v8.0.0-beta.0-released.md new file mode 100644 index 0000000000..3d01678f6a --- /dev/null +++ b/_posts/2021-08-14-eslint-v8.0.0-beta.0-released.md @@ -0,0 +1,130 @@ +--- +layout: post +title: ESLint v8.0.0-beta.0 released +tags: + - release + - major +--- +# ESLint v8.0.0-beta.0 released + +We just pushed ESLint v8.0.0-beta.0, which is a major release upgrade of ESLint. This release adds some new features and fixes several bugs found in the previous release. This release also has some breaking changes, so please read the following closely. + + + + +## Highlights + +Most of the highlights of this release are breaking changes, and are discussed further in the [migration guide](/docs/8.0.0/user-guide/migrating-to-8.0.0). In addition, there are some new features: + +- The default parser now supports ES2022 syntax, including class fields and top-level `await`. Some rules still need to be updated, and you can follow progress on the [tracking issue](https://github.com/eslint/eslint/issues/14857). +- Autofix gained support for removing unused disable directives when using `--fix` with `--report-unused-disable-directives`. + +Since this is a beta release, it is not expected to be ready for production, but please try it and report any unexpected issues. + +### Installing + +Since this is a pre-release version, you will not automatically be upgraded by npm. You must specify the `next` tag when installing: + +``` +npm i eslint@next --save-dev +``` + +You can also specify the version directly: + +``` +npm i eslint@8.0.0-beta.0 --save-dev +``` + +### Migration Guide + +As there are a lot of changes, we've created a [migration guide](/docs/8.0.0/user-guide/migrating-to-8.0.0) describing the changes in great detail along with the steps you should take to address them. We expect that most users should be able to upgrade without any build changes, but the migration guide should be a useful resource if you encounter problems. + + + + +## Breaking Changes + + +* [`24c9f2a`](https://github.com/eslint/eslint/commit/24c9f2ac57efcd699ca69695c82e51ce5742df7b) Breaking: Strict package exports (refs [#13654](https://github.com/eslint/eslint/issues/13654)) ([#14706](https://github.com/eslint/eslint/issues/14706)) (Nicholas C. Zakas) +* [`86d31a4`](https://github.com/eslint/eslint/commit/86d31a4951e3a39e359e284f5fe336ac477369fe) Breaking: disallow SourceCode#getComments() in RuleTester (refs [#14744](https://github.com/eslint/eslint/issues/14744)) ([#14769](https://github.com/eslint/eslint/issues/14769)) (Milos Djermanovic) +* [`1d2213d`](https://github.com/eslint/eslint/commit/1d2213deb69c5901c1950bbe648aa819e7e742ed) Breaking: Fixable disable directives (fixes [#11815](https://github.com/eslint/eslint/issues/11815)) ([#14617](https://github.com/eslint/eslint/issues/14617)) (Josh Goldberg) +* [`4a7aab7`](https://github.com/eslint/eslint/commit/4a7aab7d4323ff7027eebca709d4e95a9aaa80bc) Breaking: require `meta` for fixable rules (fixes [#13349](https://github.com/eslint/eslint/issues/13349)) ([#14634](https://github.com/eslint/eslint/issues/14634)) (Milos Djermanovic) +* [`d6a761f`](https://github.com/eslint/eslint/commit/d6a761f9b6582e9f71705161be827ca303ef183f) Breaking: Require `meta.hasSuggestions` for rules with suggestions ([#14573](https://github.com/eslint/eslint/issues/14573)) (Bryan Mishkin) +* [`4c841b8`](https://github.com/eslint/eslint/commit/4c841b880b5649392a55c98ecc9af757bd213ff0) Breaking: allow all directives in line comments (fixes [#14575](https://github.com/eslint/eslint/issues/14575)) ([#14656](https://github.com/eslint/eslint/issues/14656)) (薛定谔的猫) +* [`6bd747b`](https://github.com/eslint/eslint/commit/6bd747b5b7731195224875b952a9ea61445a9938) Breaking: support new regex d flag (fixes [#14640](https://github.com/eslint/eslint/issues/14640)) ([#14653](https://github.com/eslint/eslint/issues/14653)) (Yosuke Ota) +* [`8b4f3ab`](https://github.com/eslint/eslint/commit/8b4f3abdb794feb3be31959bb44bfb0ef6318e8e) Breaking: fix [comma-dangle](/docs/rules/comma-dangle) schema (fixes [#13739](https://github.com/eslint/eslint/issues/13739)) ([#14030](https://github.com/eslint/eslint/issues/14030)) (Joakim Nilsson) +* [`b953a4e`](https://github.com/eslint/eslint/commit/b953a4ee12f120658a9ec27d1f8ca88dd3dfb599) Breaking: upgrade espree and support new class features (refs [#14343](https://github.com/eslint/eslint/issues/14343)) ([#14591](https://github.com/eslint/eslint/issues/14591)) (Toru Nagashima) +* [`8cce06c`](https://github.com/eslint/eslint/commit/8cce06cb39886902ce0d2e6882f46c3bf52fb955) Breaking: add some rules to eslint:recommended (refs [#14673](https://github.com/eslint/eslint/issues/14673)) ([#14691](https://github.com/eslint/eslint/issues/14691)) (薛定谔的猫) +* [`86bb63b`](https://github.com/eslint/eslint/commit/86bb63b370e0ff350e988a5fa228a8234abe800c) Breaking: Drop `codeframe` and `table` formatters ([#14316](https://github.com/eslint/eslint/issues/14316)) (Federico Brigante) +* [`f3cb320`](https://github.com/eslint/eslint/commit/f3cb3208c8952a6218d54658cfda85942b9fda42) Breaking: drop node v10/v13/v15 (fixes [#14023](https://github.com/eslint/eslint/issues/14023)) ([#14592](https://github.com/eslint/eslint/issues/14592)) (薛定谔的猫) + + + + + + +## Enhancements + + +* [`9052eee`](https://github.com/eslint/eslint/commit/9052eee07a459dc059cd92f657a3ae73acc95bb5) Update: check class fields in [no-extra-parens](/docs/rules/no-extra-parens) (refs [#14857](https://github.com/eslint/eslint/issues/14857)) ([#14906](https://github.com/eslint/eslint/issues/14906)) (Milos Djermanovic) + + + + +## Bug Fixes + + +* [`af96584`](https://github.com/eslint/eslint/commit/af965848c010612c3e136c367cc9b9e2e822f580) Fix: handle computed class fields in [operator-linebreak](/docs/rules/operator-linebreak) (refs [#14857](https://github.com/eslint/eslint/issues/14857)) ([#14915](https://github.com/eslint/eslint/issues/14915)) (Milos Djermanovic) +* [`a773b99`](https://github.com/eslint/eslint/commit/a773b99873965652a86bec489193dc42a8923f5f) Fix: [no-useless-computed-key](/docs/rules/no-useless-computed-key) edge cases with class fields (refs [#14857](https://github.com/eslint/eslint/issues/14857)) ([#14903](https://github.com/eslint/eslint/issues/14903)) (Milos Djermanovic) +* [`cbc43da`](https://github.com/eslint/eslint/commit/cbc43daad2ea229fb15a9198efd2bc2721dfb75f) Fix: [prefer-destructuring](/docs/rules/prefer-destructuring) PrivateIdentifier false positive (refs [#14857](https://github.com/eslint/eslint/issues/14857)) ([#14897](https://github.com/eslint/eslint/issues/14897)) (Milos Djermanovic) +* [`ccb9a91`](https://github.com/eslint/eslint/commit/ccb9a9138acd63457e004630475495954c1be6f4) Fix: [dot-notation](/docs/rules/dot-notation) false positive with private identifier (refs [#14857](https://github.com/eslint/eslint/issues/14857)) ([#14898](https://github.com/eslint/eslint/issues/14898)) (Milos Djermanovic) + + + + +## Documentation + + +* [`28fe19c`](https://github.com/eslint/eslint/commit/28fe19c4a9108111932966aa7c9f361c26601d70) Docs: Add v8.0.0 migration guide (fixes [#14856](https://github.com/eslint/eslint/issues/14856)) ([#14884](https://github.com/eslint/eslint/issues/14884)) (Nicholas C. Zakas) +* [`1f5d088`](https://github.com/eslint/eslint/commit/1f5d0889264c60dddb6fb07a3b1e43f840e84d57) Docs: add an example `Object.assign()` for rule [no-import-assign](/docs/rules/no-import-assign) ([#14916](https://github.com/eslint/eslint/issues/14916)) (薛定谔的猫) +* [`c4e5802`](https://github.com/eslint/eslint/commit/c4e58023f22381508babfc52087853b5e3965b9c) Docs: improve rule details for [`no-console`](/docs/rules/no-console) (fixes [#14793](https://github.com/eslint/eslint/issues/14793)) ([#14901](https://github.com/eslint/eslint/issues/14901)) (Nitin Kumar) +* [`5c3a470`](https://github.com/eslint/eslint/commit/5c3a47072aeb5cfda40a1eb20b43a10c5ca7aab3) Docs: add class fields in [no-multi-assign](/docs/rules/no-multi-assign) documentation (refs [#14857](https://github.com/eslint/eslint/issues/14857)) ([#14907](https://github.com/eslint/eslint/issues/14907)) (Milos Djermanovic) +* [`d234d89`](https://github.com/eslint/eslint/commit/d234d890b383837f8e4bda0f6ce1e2a348f9835e) Docs: add class fields in [func-names](/docs/rules/func-names) documentation (refs [#14857](https://github.com/eslint/eslint/issues/14857)) ([#14908](https://github.com/eslint/eslint/issues/14908)) (Milos Djermanovic) +* [`e037d61`](https://github.com/eslint/eslint/commit/e037d61a12ad17a36e05dcf65aa63fad303c79b9) Docs: Mention workaround for escaping the slash character in selectors ([#14675](https://github.com/eslint/eslint/issues/14675)) (Aria) +* [`81f03b6`](https://github.com/eslint/eslint/commit/81f03b6ad69c7f67ad6ba72e02e73266aa8f7696) Docs: Update license copyright ([#14877](https://github.com/eslint/eslint/issues/14877)) (Nicholas C. Zakas) + + + + +## Dependency Upgrades + + +* [`ec9db63`](https://github.com/eslint/eslint/commit/ec9db63e53a6605a558dcd82947d2425f89887c3) Upgrade: @eslint/eslintrc@1.0.0 ([#14865](https://github.com/eslint/eslint/issues/14865)) (Milos Djermanovic) +* [`62c6fe7`](https://github.com/eslint/eslint/commit/62c6fe7d10ff4eeebd196e143f96cfd88818393d) Upgrade: Debug 4.0.1 > 4.3.2 ([#14892](https://github.com/eslint/eslint/issues/14892)) (sandesh bafna) +* [`88db3f5`](https://github.com/eslint/eslint/commit/88db3f54988dddfbda35764ecf1ea16354c4213a) Upgrade: `js-yaml` to v4 ([#14890](https://github.com/eslint/eslint/issues/14890)) (Bryan Mishkin) +* [`ae6072b`](https://github.com/eslint/eslint/commit/ae6072b1de5c8b30ce6c58290852082439c40b30) Upgrade: `eslint-visitor-keys` to v3 ([#14902](https://github.com/eslint/eslint/issues/14902)) (Bryan Mishkin) +* [`e53d8cf`](https://github.com/eslint/eslint/commit/e53d8cf9d73bd105cf6ba4f6b5477ccc4b980939) Upgrade: `markdownlint` dev dependencies ([#14883](https://github.com/eslint/eslint/issues/14883)) (Bryan Mishkin) +* [`d66e941`](https://github.com/eslint/eslint/commit/d66e9414be60e05badb96bc3e1a55ca34636d7f8) Upgrade: @humanwhocodes/config-array to 0.6 ([#14891](https://github.com/eslint/eslint/issues/14891)) (Bryan Mishkin) + + + + +## Build Related + + +* [`b8b2d55`](https://github.com/eslint/eslint/commit/b8b2d5553b0de23e8b72ee45949650cd5f9a10d2) Build: add codeql ([#14729](https://github.com/eslint/eslint/issues/14729)) (薛定谔的猫) + + + + +## Chores + + +* [`be334f9`](https://github.com/eslint/eslint/commit/be334f9d8633e9d193dcb8b36f484547e9d3ab97) Chore: Fix Makefile call to linter.getRules() ([#14932](https://github.com/eslint/eslint/issues/14932)) (Brandon Mills) +* [`0c86b68`](https://github.com/eslint/eslint/commit/0c86b68a6e2435eb03b681b51b099b552b521adc) Chore: Replace old syntax for Array flat/flatMap ([#14614](https://github.com/eslint/eslint/issues/14614)) (Stephen Wade) +* [`6a89f3f`](https://github.com/eslint/eslint/commit/6a89f3f7b6a3edb3465952521bdf06a220515b95) Chore: ignore `yarn-error.log` and `.pnpm-debug.log` ([#14925](https://github.com/eslint/eslint/issues/14925)) (Nitin Kumar) +* [`3b6cd89`](https://github.com/eslint/eslint/commit/3b6cd8934b3640ffb6fa49b471babf07f0ad769a) Chore: Add rel/abs path tests in `no-restricted-{imports/modules}` rules ([#14910](https://github.com/eslint/eslint/issues/14910)) (Bryan Mishkin) +* [`f984515`](https://github.com/eslint/eslint/commit/f98451584a82e41f82ceacd484ea0fe90aa9ce63) Chore: add assertions on reporting location in [`semi`](/docs/rules/semi) ([#14899](https://github.com/eslint/eslint/issues/14899)) (Nitin Kumar) +* [`149230c`](https://github.com/eslint/eslint/commit/149230ce7e296c029a0b6c085216fc0360ed4c65) Chore: Specify Node 14.x for Verify Files CI job ([#14896](https://github.com/eslint/eslint/issues/14896)) (Milos Djermanovic) +* [`537cf6a`](https://github.com/eslint/eslint/commit/537cf6a0e78ee9b7167e7f8c56f4053d3fb5b2d7) Chore: update `glob-parent` (fixes [#14879](https://github.com/eslint/eslint/issues/14879))([#14887](https://github.com/eslint/eslint/issues/14887)) (Nitin Kumar) +* [`f7b4a3f`](https://github.com/eslint/eslint/commit/f7b4a3f6a44e167c71985d373f73eebd3a4d9556) Chore: update dev deps to latest ([#14624](https://github.com/eslint/eslint/issues/14624)) (薛定谔的猫) diff --git a/docs/8.0.0/README.md b/docs/8.0.0/README.md new file mode 100644 index 0000000000..8f5223a74d --- /dev/null +++ b/docs/8.0.0/README.md @@ -0,0 +1,17 @@ +# Documentation + +Welcome to our documentation pages! What would you like to view? + +## [User Guide](user-guide) + +Intended for end users of ESLint. Contains information about core rules, configuration, command line options, formatters, and integrations, +as well as guides for migrating from earlier versions of ESLint. + +## [Developer Guide](developer-guide) + +Intended for contributors to ESLint and people who wish to extend ESLint. Contains information about contributing to ESLint; creating custom +rules, configurations, plugins, and formatters; and information about our architecture and Node.js API. + +## [Maintainer Guide](maintainer-guide) + +Intended for maintainers of ESLint. diff --git a/docs/8.0.0/about/index.md b/docs/8.0.0/about/index.md new file mode 100644 index 0000000000..428d439cd3 --- /dev/null +++ b/docs/8.0.0/about/index.md @@ -0,0 +1,46 @@ +--- +title: About +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/about/index.md + +--- + + +# About + +ESLint is an open source JavaScript linting utility originally created by Nicholas C. Zakas in June 2013. Code [linting][] is a type of static analysis that is frequently used to find problematic patterns or code that doesn't adhere to certain style guidelines. There are code linters for most programming languages, and compilers sometimes incorporate linting into the compilation process. + +JavaScript, being a dynamic and loosely-typed language, is especially prone to developer error. Without the benefit of a compilation process, JavaScript code is typically executed in order to find syntax or other errors. Linting tools like ESLint allow developers to discover problems with their JavaScript code without executing it. + +The primary reason ESLint was created was to allow developers to create their own linting rules. ESLint is designed to have all rules completely pluggable. The default rules are written just like any plugin rules would be. They can all follow the same pattern, both for the rules themselves as well as tests. While ESLint will ship with some built-in rules to make it useful from the start, you'll be able to dynamically load rules at any point in time. + +ESLint is written using Node.js to provide a fast runtime environment and easy installation via [npm][]. + +[linting]: https://en.wikipedia.org/wiki/Lint_(software) +[npm]: https://npmjs.org/ + +## Philosophy + +Everything is pluggable: + +* Rule API is used both by bundled and custom rules +* Formatter API is used both by bundled and custom formatters +* Additional rules and formatters can be specified at runtime +* Rules and formatters don't have to be bundled to be used + +Every rule: + +* Is standalone +* Can be turned off or on (nothing can be deemed "too important to turn off") +* Can be set to a warning or error individually + +Additionally: + +* Rules are "agenda free" - ESLint does not promote any particular coding style +* Any bundled rules are generalizable + +The project: + +* Values documentation and clear communication +* Is as transparent as possible +* Believes in the importance of testing diff --git a/docs/8.0.0/developer-guide/README.md b/docs/8.0.0/developer-guide/README.md new file mode 100644 index 0000000000..ea19430997 --- /dev/null +++ b/docs/8.0.0/developer-guide/README.md @@ -0,0 +1,47 @@ +# Developer Guide + +This guide is intended for those who wish to: + +* Contribute code to ESLint +* Create their own rules for ESLint + +In order to work with ESLint as a developer, it's recommended that: + +* You know JavaScript, since ESLint is written in JavaScript. +* You have some familiarity with Node.js, since ESLint runs on it. +* You're comfortable with command-line programs. +* You understand unit tests and why they're important. + +If that sounds like you, then continue reading to get started. + +## Section 1: Get the [Source Code](source-code.md) + +Before you can get started, you'll need to get a copy of the ESLint source code. This section explains how to do that and a little about the source code structure. + +## Section 2: Set up a [Development Environment](development-environment.md) + +Developing for ESLint is a bit different than running it on the command line. This section shows you how to set up a development environment and get you ready to write code. + +## Section 3: Run the [Unit Tests](unit-tests.md) + +There are a lot of unit tests included with ESLint to make sure that we're keeping on top of code quality. This section explains how to run the unit tests. + +## Section 4: [Working with Rules](working-with-rules.md) + +You're finally ready to start working with rules. You may want to fix an existing rule or create a new one. This section explains how to do all of that. + +## Section 5: [Working with Plugins](working-with-plugins.md) + +You've developed library-specific rules for ESLint and you want to share it with the community. You can publish an ESLint plugin on npm. + +## Section 6: [Working with Custom Parsers](working-with-custom-parsers.md) + +If you aren't going to use the default parser of ESLint, this section explains about using custom parsers. + +## Section 7: [Node.js API](nodejs-api.md) + +If you're interested in writing a tool that uses ESLint, then you can use the Node.js API to get programmatic access to functionality. + +## Section 8: [Contributing](contributing/) + +Once you've made changes that you want to share with the community, the next step is to submit those changes back via a pull request. diff --git a/docs/8.0.0/developer-guide/architecture.md b/docs/8.0.0/developer-guide/architecture.md new file mode 100644 index 0000000000..a9d2a3e3db --- /dev/null +++ b/docs/8.0.0/developer-guide/architecture.md @@ -0,0 +1,100 @@ +--- +title: Architecture +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/developer-guide/architecture.md + +--- + + +# Architecture + +

    dependency graph
    + +At a high level, there are a few key parts to ESLint: + +* `bin/eslint.js` - this is the file that actually gets executed with the command line utility. It's a dumb wrapper that does nothing more than bootstrap ESLint, passing the command line arguments to `cli`. This is intentionally small so as not to require heavy testing. +* `lib/api.js` - this is the entry point of `require("eslint")`. This file exposes an object that contains public classes `Linter`, `CLIEngine`, `RuleTester`, and `SourceCode`. +* `lib/cli.js` - this is the heart of the ESLint CLI. It takes an array of arguments and then uses `eslint` to execute the commands. By keeping this as a separate utility, it allows others to effectively call ESLint from within another Node.js program as if it were done on the command line. The main call is `cli.execute()`. This is also the part that does all the file reading, directory traversing, input, and output. +* `lib/init/` - this module contains `--init` functionality that set up a configuration file for end users. +* `lib/cli-engine/` - this module is `CLIEngine` class that finds source code files and configuration files then does code verifying with the `Linter` class. This includes the loading logic of configuration files, parsers, plugins, and formatters. +* `lib/linter/` - this module is the core `Linter` class that does code verifying based on configuration options. This file does no file I/O and does not interact with the `console` at all. For other Node.js programs that have JavaScript text to verify, they would be able to use this interface directly. +* `lib/rule-tester/` - this module is `RuleTester` class that is a wrapper around Mocha so that rules can be unit tested. This class lets us write consistently formatted tests for each rule that is implemented and be confident that each of the rules work. The RuleTester interface was modeled after Mocha and works with Mocha's global testing methods. RuleTester can also be modified to work with other testing frameworks. +* `lib/source-code/` - this module is `SourceCode` class that is used to represent the parsed source code. It takes in source code and the Program node of the AST representing the code. +* `lib/rules/` - this contains built-in rules that verify source code. + +## The `cli` object + +The `cli` object is the API for the command line interface. Literally, the `bin/eslint.js` file simply passes arguments to the `cli` object and then sets `process.exitCode` to the returned exit code. + +The main method is `cli.execute()`, which accepts an array of strings that represent the command line options (as if `process.argv` were passed without the first two arguments). If you want to run ESLint from inside of another program and have it act like the CLI, then `cli` is the object to use. + +This object's responsibilities include: + +* Interpreting command line arguments +* Reading from the file system +* Outputting to the console +* Outputting to the filesystem +* Use a formatter +* Returning the correct exit code + +This object may not: + +* Call `process.exit()` directly +* Perform any asynchronous operations + +## The `CLIEngine` object + +The `CLIEngine` type represents the core functionality of the CLI except that it reads nothing from the command line and doesn't output anything by default. Instead, it accepts many (but not all) of the arguments that are passed into the CLI. It reads both configuration and source files as well as managing the environment that is passed into the `Linter` object. + +The main method of the `CLIEngine` is `executeOnFiles()`, which accepts an array of file and directory names to run the linter on. + +This object's responsibilities include: + +* Managing the execution environment for `Linter` +* Reading from the file system +* Reading configuration information from config files (including `.eslintrc` and `package.json`) + +This object may not: + +* Call `process.exit()` directly +* Perform any asynchronous operations +* Output to the console +* Use formatters + +## The `Linter` object + +The main method of the `Linter` object is `verify()` and accepts two arguments: the source text to verify and a configuration object (the baked configuration of the given configuration file plus command line options). The method first parses the given text with `espree` (or whatever the configured parser is) and retrieves the AST. The AST is produced with both line/column and range locations which are useful for reporting location of issues and retrieving the source text related to an AST node, respectively. + +Once the AST is available, `estraverse` is used to traverse the AST from top to bottom. At each node, the `Linter` object emits an event that has the same name as the node type (i.e., "Identifier", "WithStatement", etc.). On the way back up the subtree, an event is emitted with the AST type name and suffixed with ":exit", such as "Identifier:exit" - this allows rules to take action both on the way down and on the way up in the traversal. Each event is emitted with the appropriate AST node available. + +This object's responsibilities include: + +* Inspecting JavaScript code strings +* Creating an AST for the code +* Executing rules on the AST +* Reporting back the results of the execution + +This object may not: + +* Call `process.exit()` directly +* Perform any asynchronous operations +* Use Node.js-specific features +* Access the file system +* Call `console.log()` or any other similar method + +## Rules + +Individual rules are the most specialized part of the ESLint architecture. Rules can do very little, they are simply a set of instructions executed against an AST that is provided. They do get some context information passed in, but the primary responsibility of a rule is to inspect the AST and report warnings. + +These objects' responsibilities are: + +* Inspect the AST for specific patterns +* Reporting warnings when certain patterns are found + +These objects may not: + +* Call `process.exit()` directly +* Perform any asynchronous operations +* Use Node.js-specific features +* Access the file system +* Call `console.log()` or any other similar method diff --git a/docs/8.0.0/developer-guide/architecture/dependency.svg b/docs/8.0.0/developer-guide/architecture/dependency.svg new file mode 100644 index 0000000000..3b0c74c9b9 --- /dev/null +++ b/docs/8.0.0/developer-guide/architecture/dependency.svg @@ -0,0 +1,52 @@ +binlibeslint.jscli.jsapi.jsinitcli-enginelintersource-coderule-testerrules \ No newline at end of file diff --git a/docs/8.0.0/developer-guide/code-conventions.md b/docs/8.0.0/developer-guide/code-conventions.md new file mode 100644 index 0000000000..2166df61c2 --- /dev/null +++ b/docs/8.0.0/developer-guide/code-conventions.md @@ -0,0 +1,17 @@ +--- +title: Code Conventions +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/developer-guide/code-conventions.md + +--- + + +# Code Conventions + +Code conventions for ESLint are determined by +[eslint-config-eslint](https://www.npmjs.com/package/eslint-config-eslint). + +The rationales for the specific rules in use can be found by looking to the +project documentation for any given rule. If the rule is one of our own, see +our own [rule documentation](https://eslint.org/docs/rules/) and otherwise, see +the documentation of the plugin in which the rule can be found. diff --git a/docs/8.0.0/developer-guide/code-path-analysis.md b/docs/8.0.0/developer-guide/code-path-analysis.md new file mode 100644 index 0000000000..b5f6a1eccc --- /dev/null +++ b/docs/8.0.0/developer-guide/code-path-analysis.md @@ -0,0 +1,557 @@ +--- +title: Code Path Analysis Details +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/developer-guide/code-path-analysis.md + +--- + + +# Code Path Analysis Details + +ESLint's rules can use code paths. +The code path is execution routes of programs. +It forks/joins at such as `if` statements. + +```js +if (a && b) { + foo(); +} +bar(); +``` + +![Code Path Example](./code-path-analysis/helo.svg) + +## Objects + +Program is expressed with several code paths. +A code path is expressed with objects of two kinds: `CodePath` and `CodePathSegment`. + +### `CodePath` + +`CodePath` expresses whole of one code path. +This object exists for each function and the global. +This has references of both the initial segment and the final segments of a code path. + +`CodePath` has the following properties: + +* `id` (`string`) - A unique string. Respective rules can use `id` to save additional information for each code path. +* `initialSegment` (`CodePathSegment`) - The initial segment of this code path. +* `finalSegments` (`CodePathSegment[]`) - The final segments which includes both returned and thrown. +* `returnedSegments` (`CodePathSegment[]`) - The final segments which includes only returned. +* `thrownSegments` (`CodePathSegment[]`) - The final segments which includes only thrown. +* `currentSegments` (`CodePathSegment[]`) - Segments of the current position. +* `upper` (`CodePath|null`) - The code path of the upper function/global scope. +* `childCodePaths` (`CodePath[]`) - Code paths of functions this code path contains. + +### `CodePathSegment` + +`CodePathSegment` is a part of a code path. +A code path is expressed with plural `CodePathSegment` objects, it's similar to doubly linked list. +Difference from doubly linked list is what there are forking and merging (the next/prev are plural). + +`CodePathSegment` has the following properties: + +* `id` (`string`) - A unique string. Respective rules can use `id` to save additional information for each segment. +* `nextSegments` (`CodePathSegment[]`) - The next segments. If forking, there are two or more. If final, there is nothing. +* `prevSegments` (`CodePathSegment[]`) - The previous segments. If merging, there are two or more. If initial, there is nothing. +* `reachable` (`boolean`) - A flag which shows whether or not it's reachable. This becomes `false` when preceded by `return`, `throw`, `break`, or `continue`. + +## Events + +There are five events related to code paths, and you can define event handlers in rules. + +```js +module.exports = function(context) { + return { + /** + * This is called at the start of analyzing a code path. + * In this time, the code path object has only the initial segment. + * + * @param {CodePath} codePath - The new code path. + * @param {ASTNode} node - The current node. + * @returns {void} + */ + "onCodePathStart": function(codePath, node) { + // do something with codePath + }, + + /** + * This is called at the end of analyzing a code path. + * In this time, the code path object is complete. + * + * @param {CodePath} codePath - The completed code path. + * @param {ASTNode} node - The current node. + * @returns {void} + */ + "onCodePathEnd": function(codePath, node) { + // do something with codePath + }, + + /** + * This is called when a code path segment was created. + * It meant the code path is forked or merged. + * In this time, the segment has the previous segments and has been + * judged reachable or not. + * + * @param {CodePathSegment} segment - The new code path segment. + * @param {ASTNode} node - The current node. + * @returns {void} + */ + "onCodePathSegmentStart": function(segment, node) { + // do something with segment + }, + + /** + * This is called when a code path segment was leaved. + * In this time, the segment does not have the next segments yet. + * + * @param {CodePathSegment} segment - The leaved code path segment. + * @param {ASTNode} node - The current node. + * @returns {void} + */ + "onCodePathSegmentEnd": function(segment, node) { + // do something with segment + }, + + /** + * This is called when a code path segment was looped. + * Usually segments have each previous segments when created, + * but when looped, a segment is added as a new previous segment into a + * existing segment. + * + * @param {CodePathSegment} fromSegment - A code path segment of source. + * @param {CodePathSegment} toSegment - A code path segment of destination. + * @param {ASTNode} node - The current node. + * @returns {void} + */ + "onCodePathSegmentLoop": function(fromSegment, toSegment, node) { + // do something with segment + } + }; +}; +``` + +### About `onCodePathSegmentLoop` + +This event is always fired when the next segment has existed already. +That timing is the end of loops mainly. + +For Example 1: + +```js +while (a) { + a = foo(); +} +bar(); +``` + +1. First, the analysis advances to the end of loop. + + ![Loop Event's Example 1](./code-path-analysis/loop-event-example-while-1.svg) + +2. Second, it creates the looping path. + At this time, the next segment has existed already, so the `onCodePathSegmentStart` event is not fired. + It fires `onCodePathSegmentLoop` instead. + + ![Loop Event's Example 2](./code-path-analysis/loop-event-example-while-2.svg) + +3. Last, it advances to the end. + + ![Loop Event's Example 3](./code-path-analysis/loop-event-example-while-3.svg) + +For example 2: + +```js +for (let i = 0; i < 10; ++i) { + foo(i); +} +bar(); +``` + +1. `for` statements are more complex. + First, the analysis advances to `ForStatement.update`. + The `update` segment is hovered at first. + + ![Loop Event's Example 1](./code-path-analysis/loop-event-example-for-1.svg) + +2. Second, it advances to `ForStatement.body`. + Of course the `body` segment is preceded by the `test` segment. + It keeps the `update` segment hovering. + + ![Loop Event's Example 2](./code-path-analysis/loop-event-example-for-2.svg) + +3. Third, it creates the looping path from `body` segment to `update` segment. + At this time, the next segment has existed already, so the `onCodePathSegmentStart` event is not fired. + It fires `onCodePathSegmentLoop` instead. + + ![Loop Event's Example 3](./code-path-analysis/loop-event-example-for-3.svg) + +4. Fourth, also it creates the looping path from `update` segment to `test` segment. + At this time, the next segment has existed already, so the `onCodePathSegmentStart` event is not fired. + It fires `onCodePathSegmentLoop` instead. + + ![Loop Event's Example 4](./code-path-analysis/loop-event-example-for-4.svg) + +5. Last, it advances to the end. + + ![Loop Event's Example 5](./code-path-analysis/loop-event-example-for-5.svg) + + + +## Usage Examples + +### To check whether or not this is reachable + +```js +function isReachable(segment) { + return segment.reachable; +} + +module.exports = function(context) { + var codePathStack = []; + + return { + // Stores CodePath objects. + "onCodePathStart": function(codePath) { + codePathStack.push(codePath); + }, + "onCodePathEnd": function(codePath) { + codePathStack.pop(); + }, + + // Checks reachable or not. + "ExpressionStatement": function(node) { + var codePath = codePathStack[codePathStack.length - 1]; + + // Checks the current code path segments. + if (!codePath.currentSegments.some(isReachable)) { + context.report({message: "Unreachable!", node: node}); + } + } + }; +}; +``` + +See Also: +[no-unreachable](https://github.com/eslint/eslint/blob/master/lib/rules/no-unreachable.js), +[no-fallthrough](https://github.com/eslint/eslint/blob/master/lib/rules/no-fallthrough.js), +[consistent-return](https://github.com/eslint/eslint/blob/master/lib/rules/consistent-return.js) + +### To check state of a code path + +This example is checking whether or not the parameter `cb` is called in every path. +Instances of `CodePath` and `CodePathSegment` are shared to every rule. +So a rule must not modify those instances. +Please use a map of information instead. + +```js +function hasCb(node, context) { + if (node.type.indexOf("Function") !== -1) { + return context.getDeclaredVariables(node).some(function(v) { + return v.type === "Parameter" && v.name === "cb"; + }); + } + return false; +} + +function isCbCalled(info) { + return info.cbCalled; +} + +module.exports = function(context) { + var funcInfoStack = []; + var segmentInfoMap = Object.create(null); + + return { + // Checks `cb`. + "onCodePathStart": function(codePath, node) { + funcInfoStack.push({ + codePath: codePath, + hasCb: hasCb(node, context) + }); + }, + "onCodePathEnd": function(codePath, node) { + funcInfoStack.pop(); + + // Checks `cb` was called in every paths. + var cbCalled = codePath.finalSegments.every(function(segment) { + var info = segmentInfoMap[segment.id]; + return info.cbCalled; + }); + + if (!cbCalled) { + context.report({ + message: "`cb` should be called in every path.", + node: node + }); + } + }, + + // Manages state of code paths. + "onCodePathSegmentStart": function(segment) { + var funcInfo = funcInfoStack[funcInfoStack.length - 1]; + + // Ignores if `cb` doesn't exist. + if (!funcInfo.hasCb) { + return; + } + + // Initialize state of this path. + var info = segmentInfoMap[segment.id] = { + cbCalled: false + }; + + // If there are the previous paths, merges state. + // Checks `cb` was called in every previous path. + if (segment.prevSegments.length > 0) { + info.cbCalled = segment.prevSegments.every(isCbCalled); + } + }, + + // Checks reachable or not. + "CallExpression": function(node) { + var funcInfo = funcInfoStack[funcInfoStack.length - 1]; + + // Ignores if `cb` doesn't exist. + if (!funcInfo.hasCb) { + return; + } + + // Sets marks that `cb` was called. + var callee = node.callee; + if (callee.type === "Identifier" && callee.name === "cb") { + funcInfo.codePath.currentSegments.forEach(function(segment) { + var info = segmentInfoMap[segment.id]; + info.cbCalled = true; + }); + } + } + }; +}; +``` + +See Also: +[constructor-super](https://github.com/eslint/eslint/blob/master/lib/rules/constructor-super.js), +[no-this-before-super](https://github.com/eslint/eslint/blob/master/lib/rules/no-this-before-super.js) + +## Code Path Examples + +### Hello World + +```js +console.log("Hello world!"); +``` + +![Hello World](./code-path-analysis/example-hello-world.svg) + +### `IfStatement` + +```js +if (a) { + foo(); +} else { + bar(); +} +``` + +![`IfStatement`](./code-path-analysis/example-ifstatement.svg) + +### `IfStatement` (chain) + +```js +if (a) { + foo(); +} else if (b) { + bar(); +} else if (c) { + hoge(); +} +``` + +![`IfStatement` (chain)](./code-path-analysis/example-ifstatement-chain.svg) + +### `SwitchStatement` + +```js +switch (a) { + case 0: + foo(); + break; + + case 1: + case 2: + bar(); + // fallthrough + + case 3: + hoge(); + break; +} +``` + +![`SwitchStatement`](./code-path-analysis/example-switchstatement.svg) + +### `SwitchStatement` (has `default`) + +```js +switch (a) { + case 0: + foo(); + break; + + case 1: + case 2: + bar(); + // fallthrough + + case 3: + hoge(); + break; + + default: + fuga(); + break; +} +``` + +![`SwitchStatement` (has `default`)](./code-path-analysis/example-switchstatement-has-default.svg) + +### `TryStatement` (try-catch) + +```js +try { + foo(); + if (a) { + throw new Error(); + } + bar(); +} catch (err) { + hoge(err); +} +last(); +``` + +It creates the paths from `try` block to `catch` block at: + +* `throw` statements. +* The first throwable node (e.g. a function call) in the `try` block. +* The end of the `try` block. + +![`TryStatement` (try-catch)](./code-path-analysis/example-trystatement-try-catch.svg) + +### `TryStatement` (try-finally) + +```js +try { + foo(); + bar(); +} finally { + fuga(); +} +last(); +``` + +If there is not `catch` block, `finally` block has two current segments. +At this time, `CodePath.currentSegments.length` is `2`. +One is the normal path, and another is the leaving path (`throw` or `return`). + +![`TryStatement` (try-finally)](./code-path-analysis/example-trystatement-try-finally.svg) + +### `TryStatement` (try-catch-finally) + +```js +try { + foo(); + bar(); +} catch (err) { + hoge(err); +} finally { + fuga(); +} +last(); +``` + +![`TryStatement` (try-catch-finally)](./code-path-analysis/example-trystatement-try-catch-finally.svg) + +### `WhileStatement` + +```js +while (a) { + foo(); + if (b) { + continue; + } + bar(); +} +``` + +![`WhileStatement`](./code-path-analysis/example-whilestatement.svg) + +### `DoWhileStatement` + +```js +do { + foo(); + bar(); +} while (a); +``` + +![`DoWhileStatement`](./code-path-analysis/example-dowhilestatement.svg) + +### `ForStatement` + +```js +for (let i = 0; i < 10; ++i) { + foo(); + if (b) { + break; + } + bar(); +} +``` + +![`ForStatement`](./code-path-analysis/example-forstatement.svg) + +### `ForStatement` (for ever) + +```js +for (;;) { + foo(); +} +bar(); +``` + +![`ForStatement` (for ever)](./code-path-analysis/example-forstatement-for-ever.svg) + +### `ForInStatement` + +```js +for (let key in obj) { + foo(key); +} +``` + +![`ForInStatement`](./code-path-analysis/example-forinstatement.svg) + +### When there is a function + +```js +function foo(a) { + if (a) { + return; + } + bar(); +} + +foo(false); +``` + +It creates two code paths. + +* The global's + + ![When there is a function](./code-path-analysis/example-when-there-is-a-function-g.svg) + +* The function's + + ![When there is a function](./code-path-analysis/example-when-there-is-a-function-f.svg) diff --git a/docs/8.0.0/developer-guide/code-path-analysis/README.md b/docs/8.0.0/developer-guide/code-path-analysis/README.md new file mode 100644 index 0000000000..1c84b2e1f7 --- /dev/null +++ b/docs/8.0.0/developer-guide/code-path-analysis/README.md @@ -0,0 +1,549 @@ +# Code Path Analysis Details + +ESLint's rules can use code paths. +The code path is execution routes of programs. +It forks/joins at such as `if` statements. + +```js +if (a && b) { + foo(); +} +bar(); +``` + +![Code Path Example](./helo.svg) + +## Objects + +Program is expressed with several code paths. +A code path is expressed with objects of two kinds: `CodePath` and `CodePathSegment`. + +### `CodePath` + +`CodePath` expresses whole of one code path. +This object exists for each function and the global. +This has references of both the initial segment and the final segments of a code path. + +`CodePath` has the following properties: + +* `id` (`string`) - A unique string. Respective rules can use `id` to save additional information for each code path. +* `initialSegment` (`CodePathSegment`) - The initial segment of this code path. +* `finalSegments` (`CodePathSegment[]`) - The final segments which includes both returned and thrown. +* `returnedSegments` (`CodePathSegment[]`) - The final segments which includes only returned. +* `thrownSegments` (`CodePathSegment[]`) - The final segments which includes only thrown. +* `currentSegments` (`CodePathSegment[]`) - Segments of the current position. +* `upper` (`CodePath|null`) - The code path of the upper function/global scope. +* `childCodePaths` (`CodePath[]`) - Code paths of functions this code path contains. + +### `CodePathSegment` + +`CodePathSegment` is a part of a code path. +A code path is expressed with plural `CodePathSegment` objects, it's similar to doubly linked list. +Difference from doubly linked list is what there are forking and merging (the next/prev are plural). + +`CodePathSegment` has the following properties: + +* `id` (`string`) - A unique string. Respective rules can use `id` to save additional information for each segment. +* `nextSegments` (`CodePathSegment[]`) - The next segments. If forking, there are two or more. If final, there is nothing. +* `prevSegments` (`CodePathSegment[]`) - The previous segments. If merging, there are two or more. If initial, there is nothing. +* `reachable` (`boolean`) - A flag which shows whether or not it's reachable. This becomes `false` when preceded by `return`, `throw`, `break`, or `continue`. + +## Events + +There are five events related to code paths, and you can define event handlers in rules. + +```js +module.exports = function(context) { + return { + /** + * This is called at the start of analyzing a code path. + * In this time, the code path object has only the initial segment. + * + * @param {CodePath} codePath - The new code path. + * @param {ASTNode} node - The current node. + * @returns {void} + */ + "onCodePathStart": function(codePath, node) { + // do something with codePath + }, + + /** + * This is called at the end of analyzing a code path. + * In this time, the code path object is complete. + * + * @param {CodePath} codePath - The completed code path. + * @param {ASTNode} node - The current node. + * @returns {void} + */ + "onCodePathEnd": function(codePath, node) { + // do something with codePath + }, + + /** + * This is called when a code path segment was created. + * It meant the code path is forked or merged. + * In this time, the segment has the previous segments and has been + * judged reachable or not. + * + * @param {CodePathSegment} segment - The new code path segment. + * @param {ASTNode} node - The current node. + * @returns {void} + */ + "onCodePathSegmentStart": function(segment, node) { + // do something with segment + }, + + /** + * This is called when a code path segment was leaved. + * In this time, the segment does not have the next segments yet. + * + * @param {CodePathSegment} segment - The leaved code path segment. + * @param {ASTNode} node - The current node. + * @returns {void} + */ + "onCodePathSegmentEnd": function(segment, node) { + // do something with segment + }, + + /** + * This is called when a code path segment was looped. + * Usually segments have each previous segments when created, + * but when looped, a segment is added as a new previous segment into a + * existing segment. + * + * @param {CodePathSegment} fromSegment - A code path segment of source. + * @param {CodePathSegment} toSegment - A code path segment of destination. + * @param {ASTNode} node - The current node. + * @returns {void} + */ + "onCodePathSegmentLoop": function(fromSegment, toSegment, node) { + // do something with segment + } + }; +}; +``` + +### About `onCodePathSegmentLoop` + +This event is always fired when the next segment has existed already. +That timing is the end of loops mainly. + +For Example 1: + +```js +while (a) { + a = foo(); +} +bar(); +``` + +1. First, the analysis advances to the end of loop. + + ![Loop Event's Example 1](./loop-event-example-while-1.svg) + +2. Second, it creates the looping path. + At this time, the next segment has existed already, so the `onCodePathSegmentStart` event is not fired. + It fires `onCodePathSegmentLoop` instead. + + ![Loop Event's Example 2](./loop-event-example-while-2.svg) + +3. Last, it advances to the end. + + ![Loop Event's Example 3](./loop-event-example-while-3.svg) + +For example 2: + +```js +for (let i = 0; i < 10; ++i) { + foo(i); +} +bar(); +``` + +1. `for` statements are more complex. + First, the analysis advances to `ForStatement.update`. + The `update` segment is hovered at first. + + ![Loop Event's Example 1](./loop-event-example-for-1.svg) + +2. Second, it advances to `ForStatement.body`. + Of course the `body` segment is preceded by the `test` segment. + It keeps the `update` segment hovering. + + ![Loop Event's Example 2](./loop-event-example-for-2.svg) + +3. Third, it creates the looping path from `body` segment to `update` segment. + At this time, the next segment has existed already, so the `onCodePathSegmentStart` event is not fired. + It fires `onCodePathSegmentLoop` instead. + + ![Loop Event's Example 3](./loop-event-example-for-3.svg) + +4. Fourth, also it creates the looping path from `update` segment to `test` segment. + At this time, the next segment has existed already, so the `onCodePathSegmentStart` event is not fired. + It fires `onCodePathSegmentLoop` instead. + + ![Loop Event's Example 4](./loop-event-example-for-4.svg) + +5. Last, it advances to the end. + + ![Loop Event's Example 5](./loop-event-example-for-5.svg) + + + +## Usage Examples + +### To check whether or not this is reachable + +```js +function isReachable(segment) { + return segment.reachable; +} + +module.exports = function(context) { + var codePathStack = []; + + return { + // Stores CodePath objects. + "onCodePathStart": function(codePath) { + codePathStack.push(codePath); + }, + "onCodePathEnd": function(codePath) { + codePathStack.pop(); + }, + + // Checks reachable or not. + "ExpressionStatement": function(node) { + var codePath = codePathStack[codePathStack.length - 1]; + + // Checks the current code path segments. + if (!codePath.currentSegments.some(isReachable)) { + context.report({message: "Unreachable!", node: node}); + } + } + }; +}; +``` + +See Also: +[no-unreachable](https://github.com/eslint/eslint/blob/master/lib/rules/no-unreachable.js), +[no-fallthrough](https://github.com/eslint/eslint/blob/master/lib/rules/no-fallthrough.js), +[consistent-return](https://github.com/eslint/eslint/blob/master/lib/rules/consistent-return.js) + +### To check state of a code path + +This example is checking whether or not the parameter `cb` is called in every path. +Instances of `CodePath` and `CodePathSegment` are shared to every rule. +So a rule must not modify those instances. +Please use a map of information instead. + +```js +function hasCb(node, context) { + if (node.type.indexOf("Function") !== -1) { + return context.getDeclaredVariables(node).some(function(v) { + return v.type === "Parameter" && v.name === "cb"; + }); + } + return false; +} + +function isCbCalled(info) { + return info.cbCalled; +} + +module.exports = function(context) { + var funcInfoStack = []; + var segmentInfoMap = Object.create(null); + + return { + // Checks `cb`. + "onCodePathStart": function(codePath, node) { + funcInfoStack.push({ + codePath: codePath, + hasCb: hasCb(node, context) + }); + }, + "onCodePathEnd": function(codePath, node) { + funcInfoStack.pop(); + + // Checks `cb` was called in every paths. + var cbCalled = codePath.finalSegments.every(function(segment) { + var info = segmentInfoMap[segment.id]; + return info.cbCalled; + }); + + if (!cbCalled) { + context.report({ + message: "`cb` should be called in every path.", + node: node + }); + } + }, + + // Manages state of code paths. + "onCodePathSegmentStart": function(segment) { + var funcInfo = funcInfoStack[funcInfoStack - 1]; + + // Ignores if `cb` doesn't exist. + if (!funcInfo.hasCb) { + return; + } + + // Initialize state of this path. + var info = segmentInfoMap[segment.id] = { + cbCalled: false + }; + + // If there are the previous paths, merges state. + // Checks `cb` was called in every previous path. + if (segment.prevSegments.length > 0) { + info.cbCalled = segment.prevSegments.every(isCbCalled); + } + }, + + // Checks reachable or not. + "CallExpression": function(node) { + var funcInfo = funcInfoStack[funcInfoStack - 1]; + + // Ignores if `cb` doesn't exist. + if (!funcInfo.hasCb) { + return; + } + + // Sets marks that `cb` was called. + var callee = node.callee; + if (callee.type === "Identifier" && callee.name === "cb") { + funcInfo.codePath.currentSegments.forEach(function(segment) { + var info = segmentInfoMap[segment.id]; + info.cbCalled = true; + }); + } + } + }; +}; +``` + +See Also: +[constructor-super](https://github.com/eslint/eslint/blob/master/lib/rules/constructor-super.js), +[no-this-before-super](https://github.com/eslint/eslint/blob/master/lib/rules/no-this-before-super.js) + +## Code Path Examples + +### Hello World + +```js +console.log("Hello world!"); +``` + +![Hello World](./example-hello-world.svg) + +### `IfStatement` + +```js +if (a) { + foo(); +} else { + bar(); +} +``` + +![`IfStatement`](./example-ifstatement.svg) + +### `IfStatement` (chain) + +```js +if (a) { + foo(); +} else if (b) { + bar(); +} else if (c) { + hoge(); +} +``` + +![`IfStatement` (chain)](./example-ifstatement-chain.svg) + +### `SwitchStatement` + +```js +switch (a) { + case 0: + foo(); + break; + + case 1: + case 2: + bar(); + // fallthrough + + case 3: + hoge(); + break; +} +``` + +![`SwitchStatement`](./example-switchstatement.svg) + +### `SwitchStatement` (has `default`) + +```js +switch (a) { + case 0: + foo(); + break; + + case 1: + case 2: + bar(); + // fallthrough + + case 3: + hoge(); + break; + + default: + fuga(); + break; +} +``` + +![`SwitchStatement` (has `default`)](./example-switchstatement-has-default.svg) + +### `TryStatement` (try-catch) + +```js +try { + foo(); + if (a) { + throw new Error(); + } + bar(); +} catch (err) { + hoge(err); +} +last(); +``` + +It creates the paths from `try` block to `catch` block at: + +* `throw` statements. +* The first throwable node (e.g. a function call) in the `try` block. +* The end of the `try` block. + +![`TryStatement` (try-catch)](./example-trystatement-try-catch.svg) + +### `TryStatement` (try-finally) + +```js +try { + foo(); + bar(); +} finally { + fuga(); +} +last(); +``` + +If there is not `catch` block, `finally` block has two current segments. +At this time, `CodePath.currentSegments.length` is `2`. +One is the normal path, and another is the leaving path (`throw` or `return`). + +![`TryStatement` (try-finally)](./example-trystatement-try-finally.svg) + +### `TryStatement` (try-catch-finally) + +```js +try { + foo(); + bar(); +} catch (err) { + hoge(err); +} finally { + fuga(); +} +last(); +``` + +![`TryStatement` (try-catch-finally)](./example-trystatement-try-catch-finally.svg) + +### `WhileStatement` + +```js +while (a) { + foo(); + if (b) { + continue; + } + bar(); +} +``` + +![`WhileStatement`](./example-whilestatement.svg) + +### `DoWhileStatement` + +```js +do { + foo(); + bar(); +} while (a); +``` + +![`DoWhileStatement`](./example-dowhilestatement.svg) + +### `ForStatement` + +```js +for (let i = 0; i < 10; ++i) { + foo(); + if (b) { + break; + } + bar(); +} +``` + +![`ForStatement`](./example-forstatement.svg) + +### `ForStatement` (for ever) + +```js +for (;;) { + foo(); +} +bar(); +``` + +![`ForStatement` (for ever)](./example-forstatement-for-ever.svg) + +### `ForInStatement` + +```js +for (let key in obj) { + foo(key); +} +``` + +![`ForInStatement`](./example-forinstatement.svg) + +### When there is a function + +```js +function foo(a) { + if (a) { + return; + } + bar(); +} + +foo(false); +``` + +It creates two code paths. + +* The global's + + ![When there is a function](./example-when-there-is-a-function-g.svg) + +* The function's + + ![When there is a function](./example-when-there-is-a-function-f.svg) diff --git a/docs/8.0.0/developer-guide/code-path-analysis/example-dowhilestatement.svg b/docs/8.0.0/developer-guide/code-path-analysis/example-dowhilestatement.svg new file mode 100644 index 0000000000..4a3d5289dc --- /dev/null +++ b/docs/8.0.0/developer-guide/code-path-analysis/example-dowhilestatement.svg @@ -0,0 +1,100 @@ + + + +_anonymous_0 + +initial + + + +s1_1 + + + + + + + + + + + + + +Program +DoWhileStatement + + +initial->s1_1 + + + + +final + + + + +s1_2 + + + + + + + + + + + + + +BlockStatement +ExpressionStatement +CallExpression +Identifier (foo) +ExpressionStatement +CallExpression +Identifier (bar) +Identifier (a) + + +s1_1->s1_2 + + + + +s1_2->s1_2 + + + + +s1_3 + + + + + + + + + + + + + +DoWhileStatement:exit +Program:exit + + +s1_2->s1_3 + + + + +s1_3->final + + + + + \ No newline at end of file diff --git a/docs/8.0.0/developer-guide/code-path-analysis/example-forinstatement.svg b/docs/8.0.0/developer-guide/code-path-analysis/example-forinstatement.svg new file mode 100644 index 0000000000..00da11ecd4 --- /dev/null +++ b/docs/8.0.0/developer-guide/code-path-analysis/example-forinstatement.svg @@ -0,0 +1,148 @@ + + + +_anonymous_0 + +initial + + + +s1_1 + + + + + + + + + + + + + +Program +ForInStatement + + +initial->s1_1 + + + + +final + + + + +s1_3 + + + + + + + + + + + + + +Identifier (obj) + + +s1_1->s1_3 + + + + +s1_2 + + + + + + + + + + + + + +VariableDeclaration +VariableDeclarator +Identifier (key) + + +s1_3->s1_2 + + + + +s1_5 + + + + + + + + + + + + + +ForInStatement:exit +Program:exit + + +s1_3->s1_5 + + + + +s1_4 + + + + + + + + + + + + + +BlockStatement +ExpressionStatement +CallExpression +Identifier (foo) +Identifier (key) + + +s1_2->s1_4 + + + + +s1_4->s1_2 + + + + +s1_4->s1_5 + + + + +s1_5->final + + + + + \ No newline at end of file diff --git a/docs/8.0.0/developer-guide/code-path-analysis/example-forstatement-for-ever.svg b/docs/8.0.0/developer-guide/code-path-analysis/example-forstatement-for-ever.svg new file mode 100644 index 0000000000..b4bdb2337e --- /dev/null +++ b/docs/8.0.0/developer-guide/code-path-analysis/example-forstatement-for-ever.svg @@ -0,0 +1,63 @@ + + + +_anonymous_0 + +initial + + + +s1_1 + + + + + + + + + + + + + +Program +ForStatement + + +initial->s1_1 + + + + +s1_2 + + + + + + + + + + + + + +BlockStatement +ExpressionStatement +CallExpression +Identifier (foo) + + +s1_1->s1_2 + + + + +s1_2->s1_2 + + + + + \ No newline at end of file diff --git a/docs/8.0.0/developer-guide/code-path-analysis/example-forstatement.svg b/docs/8.0.0/developer-guide/code-path-analysis/example-forstatement.svg new file mode 100644 index 0000000000..376d91b446 --- /dev/null +++ b/docs/8.0.0/developer-guide/code-path-analysis/example-forstatement.svg @@ -0,0 +1,201 @@ + + + +_anonymous_0 + +initial + + + +s1_1 + + + + + + + + + + + + + +Program +ForStatement +VariableDeclaration +VariableDeclarator +Identifier (i) +Literal (0) + + +initial->s1_1 + + + + +final + + + + +s1_2 + + + + + + + + + + + + + +BinaryExpression +Identifier (i) +Literal (10) + + +s1_1->s1_2 + + + + +s1_3 + + + + + + + + + + + + + +BlockStatement +ExpressionStatement +CallExpression +Identifier (foo) +IfStatement +Identifier (b) + + +s1_2->s1_3 + + + + +s1_8 + + + + + + + + + + + + + +ForStatement:exit +Program:exit + + +s1_2->s1_8 + + + + +s1_5 + + + + + + + + + + + + + +BlockStatement +BreakStatement + + +s1_3->s1_5 + + + + +s1_7 + + + + + + + + + + + + + +ExpressionStatement +CallExpression +Identifier (bar) + + +s1_3->s1_7 + + + + +s1_5->s1_8 + + + + +s1_4 + + + + + + + + + + + + + +UpdateExpression +Identifier (i) + + +s1_7->s1_4 + + + + +s1_4->s1_2 + + + + +s1_8->final + + + + + \ No newline at end of file diff --git a/docs/8.0.0/developer-guide/code-path-analysis/example-hello-world.svg b/docs/8.0.0/developer-guide/code-path-analysis/example-hello-world.svg new file mode 100644 index 0000000000..26c40387cd --- /dev/null +++ b/docs/8.0.0/developer-guide/code-path-analysis/example-hello-world.svg @@ -0,0 +1,48 @@ + + + +_anonymous_0 + +initial + + + +s1_1 + + + + + + + + + + + + + +Program +ExpressionStatement +CallExpression +MemberExpression +Identifier (console) +Identifier (log) +Literal (Hello world!) + + +initial->s1_1 + + + + +final + + + + +s1_1->final + + + + + \ No newline at end of file diff --git a/docs/8.0.0/developer-guide/code-path-analysis/example-ifstatement-chain.svg b/docs/8.0.0/developer-guide/code-path-analysis/example-ifstatement-chain.svg new file mode 100644 index 0000000000..88c2b6e43d --- /dev/null +++ b/docs/8.0.0/developer-guide/code-path-analysis/example-ifstatement-chain.svg @@ -0,0 +1,203 @@ + + + +_anonymous_0 + +initial + + + +s1_1 + + + + + + + + + + + + + +Program +IfStatement +Identifier (a) + + +initial->s1_1 + + + + +final + + + + +s1_2 + + + + + + + + + + + + + +BlockStatement +ExpressionStatement +CallExpression +Identifier (foo) + + +s1_1->s1_2 + + + + +s1_3 + + + + + + + + + + + + + +IfStatement +Identifier (b) + + +s1_1->s1_3 + + + + +s1_9 + + + + + + + + + + + + + +IfStatement:exit +Program:exit + + +s1_2->s1_9 + + + + +s1_9->final + + + + +s1_4 + + + + + + + + + + + + + +BlockStatement +ExpressionStatement +CallExpression +Identifier (bar) + + +s1_3->s1_4 + + + + +s1_5 + + + + + + + + + + + + + +IfStatement +Identifier (c) + + +s1_3->s1_5 + + + + +s1_4->s1_9 + + + + +s1_5->s1_9 + + + + +s1_6 + + + + + + + + + + + + + +BlockStatement +ExpressionStatement +CallExpression +Identifier (hoge) + + +s1_5->s1_6 + + + + +s1_6->s1_9 + + + + + \ No newline at end of file diff --git a/docs/8.0.0/developer-guide/code-path-analysis/example-ifstatement.svg b/docs/8.0.0/developer-guide/code-path-analysis/example-ifstatement.svg new file mode 100644 index 0000000000..7ea670afff --- /dev/null +++ b/docs/8.0.0/developer-guide/code-path-analysis/example-ifstatement.svg @@ -0,0 +1,122 @@ + + + +_anonymous_0 + +initial + + + +s1_1 + + + + + + + + + + + + + +Program +IfStatement +Identifier (a) + + +initial->s1_1 + + + + +final + + + + +s1_2 + + + + + + + + + + + + + +BlockStatement +ExpressionStatement +CallExpression +Identifier (foo) + + +s1_1->s1_2 + + + + +s1_3 + + + + + + + + + + + + + +BlockStatement +ExpressionStatement +CallExpression +Identifier (bar) + + +s1_1->s1_3 + + + + +s1_4 + + + + + + + + + + + + + +IfStatement:exit +Program:exit + + +s1_2->s1_4 + + + + +s1_4->final + + + + +s1_3->s1_4 + + + + + \ No newline at end of file diff --git a/docs/8.0.0/developer-guide/code-path-analysis/example-switchstatement-has-default.svg b/docs/8.0.0/developer-guide/code-path-analysis/example-switchstatement-has-default.svg new file mode 100644 index 0000000000..26c45fa79a --- /dev/null +++ b/docs/8.0.0/developer-guide/code-path-analysis/example-switchstatement-has-default.svg @@ -0,0 +1,279 @@ + + + +_anonymous_0 + +initial + + + +s1_1 + + + + + + + + + + + + + +Program +SwitchStatement +Identifier (a) +SwitchCase +Literal (0) + + +initial->s1_1 + + + + +final + + + + +s1_2 + + + + + + + + + + + + + +ExpressionStatement +CallExpression +Identifier (foo) +BreakStatement + + +s1_1->s1_2 + + + + +s1_4 + + + + + + + + + + + + + +SwitchCase +Literal (1) + + +s1_1->s1_4 + + + + +s1_14 + + + + + + + + + + + + + +SwitchStatement:exit +Program:exit + + +s1_2->s1_14 + + + + +s1_7 + + + + + + + + + + + + + +ExpressionStatement +CallExpression +Identifier (bar) + + +s1_9 + + + + + + + + + + + + + +ExpressionStatement +CallExpression +Identifier (hoge) +BreakStatement + + +s1_7->s1_9 + + + + +s1_9->s1_14 + + + + +s1_12 + + + + + + + + + + + + + +ExpressionStatement +CallExpression +Identifier (fuga) +BreakStatement + + +s1_12->s1_14 + + + + +s1_14->final + + + + +s1_4->s1_7 + + + + +s1_6 + + + + + + + + + + + + + +SwitchCase +Literal (2) + + +s1_4->s1_6 + + + + +s1_6->s1_7 + + + + +s1_8 + + + + + + + + + + + + + +SwitchCase +Literal (3) + + +s1_6->s1_8 + + + + +s1_8->s1_9 + + + + +s1_11 + + + + + + + + + + + + + +SwitchCase + + +s1_8->s1_11 + + + + +s1_11->s1_12 + + + + + \ No newline at end of file diff --git a/docs/8.0.0/developer-guide/code-path-analysis/example-switchstatement.svg b/docs/8.0.0/developer-guide/code-path-analysis/example-switchstatement.svg new file mode 100644 index 0000000000..778017efdb --- /dev/null +++ b/docs/8.0.0/developer-guide/code-path-analysis/example-switchstatement.svg @@ -0,0 +1,232 @@ + + + +_anonymous_0 + +initial + + + +s1_1 + + + + + + + + + + + + + +Program +SwitchStatement +Identifier (a) +SwitchCase +Literal (0) + + +initial->s1_1 + + + + +final + + + + +s1_2 + + + + + + + + + + + + + +ExpressionStatement +CallExpression +Identifier (foo) +BreakStatement + + +s1_1->s1_2 + + + + +s1_4 + + + + + + + + + + + + + +SwitchCase +Literal (1) + + +s1_1->s1_4 + + + + +s1_11 + + + + + + + + + + + + + +SwitchStatement:exit +Program:exit + + +s1_2->s1_11 + + + + +s1_7 + + + + + + + + + + + + + +ExpressionStatement +CallExpression +Identifier (bar) + + +s1_9 + + + + + + + + + + + + + +ExpressionStatement +CallExpression +Identifier (hoge) +BreakStatement + + +s1_7->s1_9 + + + + +s1_9->s1_11 + + + + +s1_11->final + + + + +s1_4->s1_7 + + + + +s1_6 + + + + + + + + + + + + + +SwitchCase +Literal (2) + + +s1_4->s1_6 + + + + +s1_6->s1_7 + + + + +s1_8 + + + + + + + + + + + + + +SwitchCase +Literal (3) + + +s1_6->s1_8 + + + + +s1_8->s1_9 + + + + +s1_8->s1_11 + + + + + \ No newline at end of file diff --git a/docs/8.0.0/developer-guide/code-path-analysis/example-trystatement-try-catch-finally.svg b/docs/8.0.0/developer-guide/code-path-analysis/example-trystatement-try-catch-finally.svg new file mode 100644 index 0000000000..fbc0083029 --- /dev/null +++ b/docs/8.0.0/developer-guide/code-path-analysis/example-trystatement-try-catch-finally.svg @@ -0,0 +1,137 @@ + + + +_anonymous_0 + +initial + + + +s1_1 + + + + + + + + + + + + + +Program +TryStatement +BlockStatement +ExpressionStatement +CallExpression +Identifier (foo) + + +initial->s1_1 + + + + +final + + + + +s1_2 + + + + + + + + + + + + + +ExpressionStatement +CallExpression +Identifier (bar) + + +s1_1->s1_2 + + + + +s1_3 + + + + + + + + + + + + + +CatchClause +Identifier (err) +BlockStatement +ExpressionStatement +CallExpression +Identifier (hoge) +Identifier (err) + + +s1_1->s1_3 + + + + +s1_2->s1_3 + + + + +s1_4 + + + + + + + + + + + + + +BlockStatement +ExpressionStatement +CallExpression +Identifier (fuga) +ExpressionStatement +CallExpression +Identifier (last) + + +s1_2->s1_4 + + + + +s1_3->s1_4 + + + + +s1_4->final + + + + + \ No newline at end of file diff --git a/docs/8.0.0/developer-guide/code-path-analysis/example-trystatement-try-catch.svg b/docs/8.0.0/developer-guide/code-path-analysis/example-trystatement-try-catch.svg new file mode 100644 index 0000000000..c6f1879f03 --- /dev/null +++ b/docs/8.0.0/developer-guide/code-path-analysis/example-trystatement-try-catch.svg @@ -0,0 +1,186 @@ + + + +_anonymous_0 + +initial + + + +s1_1 + + + + + + + + + + + + + +Program +TryStatement +BlockStatement +ExpressionStatement +CallExpression +Identifier (foo) + + +initial->s1_1 + + + + +final + + + + +s1_2 + + + + + + + + + + + + + +IfStatement +Identifier (a) + + +s1_1->s1_2 + + + + +s1_6 + + + + + + + + + + + + + +CatchClause +Identifier (err) +BlockStatement +ExpressionStatement +CallExpression +Identifier (hoge) +Identifier (err) + + +s1_1->s1_6 + + + + +s1_3 + + + + + + + + + + + + + +BlockStatement +ThrowStatement +NewExpression +Identifier (Error) + + +s1_2->s1_3 + + + + +s1_5 + + + + + + + + + + + + + +ExpressionStatement +CallExpression +Identifier (bar) + + +s1_2->s1_5 + + + + +s1_3->s1_6 + + + + +s1_5->s1_6 + + + + +s1_7 + + + + + + + + + + + + + +ExpressionStatement +CallExpression +Identifier (last) + + +s1_5->s1_7 + + + + +s1_6->s1_7 + + + + +s1_7->final + + + + + \ No newline at end of file diff --git a/docs/8.0.0/developer-guide/code-path-analysis/example-trystatement-try-finally.svg b/docs/8.0.0/developer-guide/code-path-analysis/example-trystatement-try-finally.svg new file mode 100644 index 0000000000..8b1fb92117 --- /dev/null +++ b/docs/8.0.0/developer-guide/code-path-analysis/example-trystatement-try-finally.svg @@ -0,0 +1,139 @@ + + + +_anonymous_0 + +initial + + + +s1_1 + + + + + + + + + + + + + +Program +TryStatement +BlockStatement +ExpressionStatement +CallExpression +Identifier (foo) + + +initial->s1_1 + + + + +final + + + + +thrown + + + + +s1_2 + + + + + + + + + + + + + +ExpressionStatement +CallExpression +Identifier (bar) + + +s1_1->s1_2 + + + + +s1_4 + + + + + + + + + + + + + +BlockStatement +ExpressionStatement +CallExpression +Identifier (fuga) + + +s1_1->s1_4 + + + + +s1_3 + + + + + + + + + + + + + +BlockStatement +ExpressionStatement +CallExpression +Identifier (fuga) +ExpressionStatement +CallExpression +Identifier (last) + + +s1_2->s1_3 + + + + +s1_2->s1_4 + + + + +s1_3->final + + + + +s1_4->thrown + + + + + \ No newline at end of file diff --git a/docs/8.0.0/developer-guide/code-path-analysis/example-when-there-is-a-function-f.svg b/docs/8.0.0/developer-guide/code-path-analysis/example-when-there-is-a-function-f.svg new file mode 100644 index 0000000000..a91270022f --- /dev/null +++ b/docs/8.0.0/developer-guide/code-path-analysis/example-when-there-is-a-function-f.svg @@ -0,0 +1,99 @@ + + + +_anonymous_0 + +initial + + + +s2_1 + + + + + + + + + + + + + +FunctionDeclaration +Identifier (foo) +Identifier (a) +BlockStatement +IfStatement +Identifier (a) + + +initial->s2_1 + + + + +final + + + + +s2_2 + + + + + + + + + + + + + +BlockStatement +ReturnStatement + + +s2_1->s2_2 + + + + +s2_4 + + + + + + + + + + + + + +ExpressionStatement +CallExpression +Identifier (bar) + + +s2_1->s2_4 + + + + +s2_2->final + + + + +s2_4->final + + + + + \ No newline at end of file diff --git a/docs/8.0.0/developer-guide/code-path-analysis/example-when-there-is-a-function-g.svg b/docs/8.0.0/developer-guide/code-path-analysis/example-when-there-is-a-function-g.svg new file mode 100644 index 0000000000..7bde3ea8da --- /dev/null +++ b/docs/8.0.0/developer-guide/code-path-analysis/example-when-there-is-a-function-g.svg @@ -0,0 +1,47 @@ + + + +_anonymous_0 + +initial + + + +s1_1 + + + + + + + + + + + + + +Program +FunctionDeclaration +ExpressionStatement +CallExpression +Identifier (foo) +Literal (false) + + +initial->s1_1 + + + + +final + + + + +s1_1->final + + + + + \ No newline at end of file diff --git a/docs/8.0.0/developer-guide/code-path-analysis/example-whilestatement.svg b/docs/8.0.0/developer-guide/code-path-analysis/example-whilestatement.svg new file mode 100644 index 0000000000..d833dc08a6 --- /dev/null +++ b/docs/8.0.0/developer-guide/code-path-analysis/example-whilestatement.svg @@ -0,0 +1,172 @@ + + + +_anonymous_0 + +initial + + + +s1_1 + + + + + + + + + + + + + +Program +WhileStatement + + +initial->s1_1 + + + + +final + + + + +s1_2 + + + + + + + + + + + + + +Identifier (a) + + +s1_1->s1_2 + + + + +s1_3 + + + + + + + + + + + + + +BlockStatement +ExpressionStatement +CallExpression +Identifier (foo) +IfStatement +Identifier (b) + + +s1_2->s1_3 + + + + +s1_7 + + + + + + + + + + + + + +WhileStatement:exit +Program:exit + + +s1_2->s1_7 + + + + +s1_4 + + + + + + + + + + + + + +BlockStatement +ContinueStatement + + +s1_3->s1_4 + + + + +s1_6 + + + + + + + + + + + + + +ExpressionStatement +CallExpression +Identifier (bar) + + +s1_3->s1_6 + + + + +s1_4->s1_2 + + + + +s1_7->final + + + + +s1_6->s1_2 + + + + + \ No newline at end of file diff --git a/docs/8.0.0/developer-guide/code-path-analysis/helo.svg b/docs/8.0.0/developer-guide/code-path-analysis/helo.svg new file mode 100644 index 0000000000..e2dd9f2228 --- /dev/null +++ b/docs/8.0.0/developer-guide/code-path-analysis/helo.svg @@ -0,0 +1,113 @@ + + + +Code Path 1 +initial + + +s1_1 + + + + + + + + + + + + + +Program +IfStatement +LogicalExpression +Identifier (a) + +initial->s1_1 + + + +final + + + +s1_2 + + + + + + + + + + + + + +Identifier (b) + +s1_1->s1_2 + + + +s1_4 + + + + + + + + + + + + + +ExpressionStatement +CallExpression +Identifier (bar) + +s1_1->s1_4 + + + +s1_3 + + + + + + + + + + + + + +BlockStatement +ExpressionStatement +CallExpression +Identifier (foo) + +s1_2->s1_3 + + + +s1_2->s1_4 + + + +s1_3->s1_4 + + + +s1_4->final + + + + + \ No newline at end of file diff --git a/docs/8.0.0/developer-guide/code-path-analysis/index.md b/docs/8.0.0/developer-guide/code-path-analysis/index.md new file mode 100644 index 0000000000..8dddd34b4a --- /dev/null +++ b/docs/8.0.0/developer-guide/code-path-analysis/index.md @@ -0,0 +1,557 @@ +--- +title: Code Path Analysis Details +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/developer-guide/code-path-analysis/README.md + +--- + + +# Code Path Analysis Details + +ESLint's rules can use code paths. +The code path is execution routes of programs. +It forks/joins at such as `if` statements. + +```js +if (a && b) { + foo(); +} +bar(); +``` + +![Code Path Example](./helo.svg) + +## Objects + +Program is expressed with several code paths. +A code path is expressed with objects of two kinds: `CodePath` and `CodePathSegment`. + +### `CodePath` + +`CodePath` expresses whole of one code path. +This object exists for each function and the global. +This has references of both the initial segment and the final segments of a code path. + +`CodePath` has the following properties: + +* `id` (`string`) - A unique string. Respective rules can use `id` to save additional information for each code path. +* `initialSegment` (`CodePathSegment`) - The initial segment of this code path. +* `finalSegments` (`CodePathSegment[]`) - The final segments which includes both returned and thrown. +* `returnedSegments` (`CodePathSegment[]`) - The final segments which includes only returned. +* `thrownSegments` (`CodePathSegment[]`) - The final segments which includes only thrown. +* `currentSegments` (`CodePathSegment[]`) - Segments of the current position. +* `upper` (`CodePath|null`) - The code path of the upper function/global scope. +* `childCodePaths` (`CodePath[]`) - Code paths of functions this code path contains. + +### `CodePathSegment` + +`CodePathSegment` is a part of a code path. +A code path is expressed with plural `CodePathSegment` objects, it's similar to doubly linked list. +Difference from doubly linked list is what there are forking and merging (the next/prev are plural). + +`CodePathSegment` has the following properties: + +* `id` (`string`) - A unique string. Respective rules can use `id` to save additional information for each segment. +* `nextSegments` (`CodePathSegment[]`) - The next segments. If forking, there are two or more. If final, there is nothing. +* `prevSegments` (`CodePathSegment[]`) - The previous segments. If merging, there are two or more. If initial, there is nothing. +* `reachable` (`boolean`) - A flag which shows whether or not it's reachable. This becomes `false` when preceded by `return`, `throw`, `break`, or `continue`. + +## Events + +There are five events related to code paths, and you can define event handlers in rules. + +```js +module.exports = function(context) { + return { + /** + * This is called at the start of analyzing a code path. + * In this time, the code path object has only the initial segment. + * + * @param {CodePath} codePath - The new code path. + * @param {ASTNode} node - The current node. + * @returns {void} + */ + "onCodePathStart": function(codePath, node) { + // do something with codePath + }, + + /** + * This is called at the end of analyzing a code path. + * In this time, the code path object is complete. + * + * @param {CodePath} codePath - The completed code path. + * @param {ASTNode} node - The current node. + * @returns {void} + */ + "onCodePathEnd": function(codePath, node) { + // do something with codePath + }, + + /** + * This is called when a code path segment was created. + * It meant the code path is forked or merged. + * In this time, the segment has the previous segments and has been + * judged reachable or not. + * + * @param {CodePathSegment} segment - The new code path segment. + * @param {ASTNode} node - The current node. + * @returns {void} + */ + "onCodePathSegmentStart": function(segment, node) { + // do something with segment + }, + + /** + * This is called when a code path segment was leaved. + * In this time, the segment does not have the next segments yet. + * + * @param {CodePathSegment} segment - The leaved code path segment. + * @param {ASTNode} node - The current node. + * @returns {void} + */ + "onCodePathSegmentEnd": function(segment, node) { + // do something with segment + }, + + /** + * This is called when a code path segment was looped. + * Usually segments have each previous segments when created, + * but when looped, a segment is added as a new previous segment into a + * existing segment. + * + * @param {CodePathSegment} fromSegment - A code path segment of source. + * @param {CodePathSegment} toSegment - A code path segment of destination. + * @param {ASTNode} node - The current node. + * @returns {void} + */ + "onCodePathSegmentLoop": function(fromSegment, toSegment, node) { + // do something with segment + } + }; +}; +``` + +### About `onCodePathSegmentLoop` + +This event is always fired when the next segment has existed already. +That timing is the end of loops mainly. + +For Example 1: + +```js +while (a) { + a = foo(); +} +bar(); +``` + +1. First, the analysis advances to the end of loop. + + ![Loop Event's Example 1](./loop-event-example-while-1.svg) + +2. Second, it creates the looping path. + At this time, the next segment has existed already, so the `onCodePathSegmentStart` event is not fired. + It fires `onCodePathSegmentLoop` instead. + + ![Loop Event's Example 2](./loop-event-example-while-2.svg) + +3. Last, it advances to the end. + + ![Loop Event's Example 3](./loop-event-example-while-3.svg) + +For example 2: + +```js +for (let i = 0; i < 10; ++i) { + foo(i); +} +bar(); +``` + +1. `for` statements are more complex. + First, the analysis advances to `ForStatement.update`. + The `update` segment is hovered at first. + + ![Loop Event's Example 1](./loop-event-example-for-1.svg) + +2. Second, it advances to `ForStatement.body`. + Of course the `body` segment is preceded by the `test` segment. + It keeps the `update` segment hovering. + + ![Loop Event's Example 2](./loop-event-example-for-2.svg) + +3. Third, it creates the looping path from `body` segment to `update` segment. + At this time, the next segment has existed already, so the `onCodePathSegmentStart` event is not fired. + It fires `onCodePathSegmentLoop` instead. + + ![Loop Event's Example 3](./loop-event-example-for-3.svg) + +4. Fourth, also it creates the looping path from `update` segment to `test` segment. + At this time, the next segment has existed already, so the `onCodePathSegmentStart` event is not fired. + It fires `onCodePathSegmentLoop` instead. + + ![Loop Event's Example 4](./loop-event-example-for-4.svg) + +5. Last, it advances to the end. + + ![Loop Event's Example 5](./loop-event-example-for-5.svg) + + + +## Usage Examples + +### To check whether or not this is reachable + +```js +function isReachable(segment) { + return segment.reachable; +} + +module.exports = function(context) { + var codePathStack = []; + + return { + // Stores CodePath objects. + "onCodePathStart": function(codePath) { + codePathStack.push(codePath); + }, + "onCodePathEnd": function(codePath) { + codePathStack.pop(); + }, + + // Checks reachable or not. + "ExpressionStatement": function(node) { + var codePath = codePathStack[codePathStack.length - 1]; + + // Checks the current code path segments. + if (!codePath.currentSegments.some(isReachable)) { + context.report({message: "Unreachable!", node: node}); + } + } + }; +}; +``` + +See Also: +[no-unreachable](https://github.com/eslint/eslint/blob/master/lib/rules/no-unreachable.js), +[no-fallthrough](https://github.com/eslint/eslint/blob/master/lib/rules/no-fallthrough.js), +[consistent-return](https://github.com/eslint/eslint/blob/master/lib/rules/consistent-return.js) + +### To check state of a code path + +This example is checking whether or not the parameter `cb` is called in every path. +Instances of `CodePath` and `CodePathSegment` are shared to every rule. +So a rule must not modify those instances. +Please use a map of information instead. + +```js +function hasCb(node, context) { + if (node.type.indexOf("Function") !== -1) { + return context.getDeclaredVariables(node).some(function(v) { + return v.type === "Parameter" && v.name === "cb"; + }); + } + return false; +} + +function isCbCalled(info) { + return info.cbCalled; +} + +module.exports = function(context) { + var funcInfoStack = []; + var segmentInfoMap = Object.create(null); + + return { + // Checks `cb`. + "onCodePathStart": function(codePath, node) { + funcInfoStack.push({ + codePath: codePath, + hasCb: hasCb(node, context) + }); + }, + "onCodePathEnd": function(codePath, node) { + funcInfoStack.pop(); + + // Checks `cb` was called in every paths. + var cbCalled = codePath.finalSegments.every(function(segment) { + var info = segmentInfoMap[segment.id]; + return info.cbCalled; + }); + + if (!cbCalled) { + context.report({ + message: "`cb` should be called in every path.", + node: node + }); + } + }, + + // Manages state of code paths. + "onCodePathSegmentStart": function(segment) { + var funcInfo = funcInfoStack[funcInfoStack - 1]; + + // Ignores if `cb` doesn't exist. + if (!funcInfo.hasCb) { + return; + } + + // Initialize state of this path. + var info = segmentInfoMap[segment.id] = { + cbCalled: false + }; + + // If there are the previous paths, merges state. + // Checks `cb` was called in every previous path. + if (segment.prevSegments.length > 0) { + info.cbCalled = segment.prevSegments.every(isCbCalled); + } + }, + + // Checks reachable or not. + "CallExpression": function(node) { + var funcInfo = funcInfoStack[funcInfoStack - 1]; + + // Ignores if `cb` doesn't exist. + if (!funcInfo.hasCb) { + return; + } + + // Sets marks that `cb` was called. + var callee = node.callee; + if (callee.type === "Identifier" && callee.name === "cb") { + funcInfo.codePath.currentSegments.forEach(function(segment) { + var info = segmentInfoMap[segment.id]; + info.cbCalled = true; + }); + } + } + }; +}; +``` + +See Also: +[constructor-super](https://github.com/eslint/eslint/blob/master/lib/rules/constructor-super.js), +[no-this-before-super](https://github.com/eslint/eslint/blob/master/lib/rules/no-this-before-super.js) + +## Code Path Examples + +### Hello World + +```js +console.log("Hello world!"); +``` + +![Hello World](./example-hello-world.svg) + +### `IfStatement` + +```js +if (a) { + foo(); +} else { + bar(); +} +``` + +![`IfStatement`](./example-ifstatement.svg) + +### `IfStatement` (chain) + +```js +if (a) { + foo(); +} else if (b) { + bar(); +} else if (c) { + hoge(); +} +``` + +![`IfStatement` (chain)](./example-ifstatement-chain.svg) + +### `SwitchStatement` + +```js +switch (a) { + case 0: + foo(); + break; + + case 1: + case 2: + bar(); + // fallthrough + + case 3: + hoge(); + break; +} +``` + +![`SwitchStatement`](./example-switchstatement.svg) + +### `SwitchStatement` (has `default`) + +```js +switch (a) { + case 0: + foo(); + break; + + case 1: + case 2: + bar(); + // fallthrough + + case 3: + hoge(); + break; + + default: + fuga(); + break; +} +``` + +![`SwitchStatement` (has `default`)](./example-switchstatement-has-default.svg) + +### `TryStatement` (try-catch) + +```js +try { + foo(); + if (a) { + throw new Error(); + } + bar(); +} catch (err) { + hoge(err); +} +last(); +``` + +It creates the paths from `try` block to `catch` block at: + +* `throw` statements. +* The first throwable node (e.g. a function call) in the `try` block. +* The end of the `try` block. + +![`TryStatement` (try-catch)](./example-trystatement-try-catch.svg) + +### `TryStatement` (try-finally) + +```js +try { + foo(); + bar(); +} finally { + fuga(); +} +last(); +``` + +If there is not `catch` block, `finally` block has two current segments. +At this time, `CodePath.currentSegments.length` is `2`. +One is the normal path, and another is the leaving path (`throw` or `return`). + +![`TryStatement` (try-finally)](./example-trystatement-try-finally.svg) + +### `TryStatement` (try-catch-finally) + +```js +try { + foo(); + bar(); +} catch (err) { + hoge(err); +} finally { + fuga(); +} +last(); +``` + +![`TryStatement` (try-catch-finally)](./example-trystatement-try-catch-finally.svg) + +### `WhileStatement` + +```js +while (a) { + foo(); + if (b) { + continue; + } + bar(); +} +``` + +![`WhileStatement`](./example-whilestatement.svg) + +### `DoWhileStatement` + +```js +do { + foo(); + bar(); +} while (a); +``` + +![`DoWhileStatement`](./example-dowhilestatement.svg) + +### `ForStatement` + +```js +for (let i = 0; i < 10; ++i) { + foo(); + if (b) { + break; + } + bar(); +} +``` + +![`ForStatement`](./example-forstatement.svg) + +### `ForStatement` (for ever) + +```js +for (;;) { + foo(); +} +bar(); +``` + +![`ForStatement` (for ever)](./example-forstatement-for-ever.svg) + +### `ForInStatement` + +```js +for (let key in obj) { + foo(key); +} +``` + +![`ForInStatement`](./example-forinstatement.svg) + +### When there is a function + +```js +function foo(a) { + if (a) { + return; + } + bar(); +} + +foo(false); +``` + +It creates two code paths. + +* The global's + + ![When there is a function](./example-when-there-is-a-function-g.svg) + +* The function's + + ![When there is a function](./example-when-there-is-a-function-f.svg) diff --git a/docs/8.0.0/developer-guide/code-path-analysis/loop-event-example-for-1.svg b/docs/8.0.0/developer-guide/code-path-analysis/loop-event-example-for-1.svg new file mode 100644 index 0000000000..497554025c --- /dev/null +++ b/docs/8.0.0/developer-guide/code-path-analysis/loop-event-example-for-1.svg @@ -0,0 +1,84 @@ + + + +_anonymous_0 + +initial + + + +s1_1 + + + + + + + + + + + + + +Program +ForStatement +VariableDeclaration +VariableDeclarator +Identifier (i) +Literal (0) + + +initial->s1_1 + + + + +s1_2 + + + + + + + + + + + + + +BinaryExpression +Identifier (i) +Literal (10) + + +s1_1->s1_2 + + + + +s1_4 + + + + + + + + + + + + + +UpdateExpression +Identifier (i) + + +s1_2->s1_4 + + + + + \ No newline at end of file diff --git a/docs/8.0.0/developer-guide/code-path-analysis/loop-event-example-for-2.svg b/docs/8.0.0/developer-guide/code-path-analysis/loop-event-example-for-2.svg new file mode 100644 index 0000000000..d35bddfe18 --- /dev/null +++ b/docs/8.0.0/developer-guide/code-path-analysis/loop-event-example-for-2.svg @@ -0,0 +1,110 @@ + + + +_anonymous_0 + +initial + + + +s1_1 + + + + + + + + + + + + + +Program +ForStatement +VariableDeclaration +VariableDeclarator +Identifier (i) +Literal (0) + + +initial->s1_1 + + + + +s1_2 + + + + + + + + + + + + + +BinaryExpression +Identifier (i) +Literal (10) + + +s1_1->s1_2 + + + + +s1_3 + + + + + + + + + + + + + +BlockStatement +ExpressionStatement +CallExpression +Identifier (foo) +Identifier (i) + + +s1_2->s1_3 + + + + +s1_4 + + + + + + + + + + + + + +UpdateExpression +Identifier (i) + + +s1_2->s1_4 + + + + + \ No newline at end of file diff --git a/docs/8.0.0/developer-guide/code-path-analysis/loop-event-example-for-3.svg b/docs/8.0.0/developer-guide/code-path-analysis/loop-event-example-for-3.svg new file mode 100644 index 0000000000..a1af0e6d7e --- /dev/null +++ b/docs/8.0.0/developer-guide/code-path-analysis/loop-event-example-for-3.svg @@ -0,0 +1,115 @@ + + + +_anonymous_0 + +initial + + + +s1_1 + + + + + + + + + + + + + +Program +ForStatement +VariableDeclaration +VariableDeclarator +Identifier (i) +Literal (0) + + +initial->s1_1 + + + + +s1_2 + + + + + + + + + + + + + +BinaryExpression +Identifier (i) +Literal (10) + + +s1_1->s1_2 + + + + +s1_3 + + + + + + + + + + + + + +BlockStatement +ExpressionStatement +CallExpression +Identifier (foo) +Identifier (i) + + +s1_2->s1_3 + + + + +s1_4 + + + + + + + + + + + + + +UpdateExpression +Identifier (i) + + +s1_3->s1_4 + + + + +s1_4->s1_2 + + + + + \ No newline at end of file diff --git a/docs/8.0.0/developer-guide/code-path-analysis/loop-event-example-for-4.svg b/docs/8.0.0/developer-guide/code-path-analysis/loop-event-example-for-4.svg new file mode 100644 index 0000000000..a4ee87ec54 --- /dev/null +++ b/docs/8.0.0/developer-guide/code-path-analysis/loop-event-example-for-4.svg @@ -0,0 +1,115 @@ + + + +_anonymous_0 + +initial + + + +s1_1 + + + + + + + + + + + + + +Program +ForStatement +VariableDeclaration +VariableDeclarator +Identifier (i) +Literal (0) + + +initial->s1_1 + + + + +s1_2 + + + + + + + + + + + + + +BinaryExpression +Identifier (i) +Literal (10) + + +s1_1->s1_2 + + + + +s1_3 + + + + + + + + + + + + + +BlockStatement +ExpressionStatement +CallExpression +Identifier (foo) +Identifier (i) + + +s1_2->s1_3 + + + + +s1_4 + + + + + + + + + + + + + +UpdateExpression +Identifier (i) + + +s1_3->s1_4 + + + + +s1_4->s1_2 + + + + + \ No newline at end of file diff --git a/docs/8.0.0/developer-guide/code-path-analysis/loop-event-example-for-5.svg b/docs/8.0.0/developer-guide/code-path-analysis/loop-event-example-for-5.svg new file mode 100644 index 0000000000..cba3a010b5 --- /dev/null +++ b/docs/8.0.0/developer-guide/code-path-analysis/loop-event-example-for-5.svg @@ -0,0 +1,149 @@ + + + +_anonymous_0 + +initial + + + +s1_1 + + + + + + + + + + + + + +Program +ForStatement +VariableDeclaration +VariableDeclarator +Identifier (i) +Literal (0) + + +initial->s1_1 + + + + +final + + + + +s1_2 + + + + + + + + + + + + + +BinaryExpression +Identifier (i) +Literal (10) + + +s1_1->s1_2 + + + + +s1_3 + + + + + + + + + + + + + +BlockStatement +ExpressionStatement +CallExpression +Identifier (foo) +Identifier (i) + + +s1_2->s1_3 + + + + +s1_5 + + + + + + + + + + + + + +ExpressionStatement +CallExpression +Identifier (bar) + + +s1_2->s1_5 + + + + +s1_4 + + + + + + + + + + + + + +UpdateExpression +Identifier (i) + + +s1_3->s1_4 + + + + +s1_4->s1_2 + + + + +s1_5->final + + + + + \ No newline at end of file diff --git a/docs/8.0.0/developer-guide/code-path-analysis/loop-event-example-while-1.svg b/docs/8.0.0/developer-guide/code-path-analysis/loop-event-example-while-1.svg new file mode 100644 index 0000000000..8036529e7c --- /dev/null +++ b/docs/8.0.0/developer-guide/code-path-analysis/loop-event-example-while-1.svg @@ -0,0 +1,82 @@ + + + +_anonymous_0 + +initial + + + +s1_1 + + + + + + + + + + + + + +Program +WhileStatement + + +initial->s1_1 + + + + +s1_2 + + + + + + + + + + + + + +Identifier (a) + + +s1_1->s1_2 + + + + +s1_3 + + + + + + + + + + + + + +BlockStatement +ExpressionStatement +AssignmentExpression +Identifier (a) +CallExpression +Identifier (foo) + + +s1_2->s1_3 + + + + + \ No newline at end of file diff --git a/docs/8.0.0/developer-guide/code-path-analysis/loop-event-example-while-2.svg b/docs/8.0.0/developer-guide/code-path-analysis/loop-event-example-while-2.svg new file mode 100644 index 0000000000..63355dd815 --- /dev/null +++ b/docs/8.0.0/developer-guide/code-path-analysis/loop-event-example-while-2.svg @@ -0,0 +1,87 @@ + + + +_anonymous_0 + +initial + + + +s1_1 + + + + + + + + + + + + + +Program +WhileStatement + + +initial->s1_1 + + + + +s1_2 + + + + + + + + + + + + + +Identifier (a) + + +s1_1->s1_2 + + + + +s1_3 + + + + + + + + + + + + + +BlockStatement +ExpressionStatement +AssignmentExpression +Identifier (a) +CallExpression +Identifier (foo) + + +s1_2->s1_3 + + + + +s1_3->s1_2 + + + + + \ No newline at end of file diff --git a/docs/8.0.0/developer-guide/code-path-analysis/loop-event-example-while-3.svg b/docs/8.0.0/developer-guide/code-path-analysis/loop-event-example-while-3.svg new file mode 100644 index 0000000000..cb21c43828 --- /dev/null +++ b/docs/8.0.0/developer-guide/code-path-analysis/loop-event-example-while-3.svg @@ -0,0 +1,121 @@ + + + +_anonymous_0 + +initial + + + +s1_1 + + + + + + + + + + + + + +Program +WhileStatement + + +initial->s1_1 + + + + +final + + + + +s1_2 + + + + + + + + + + + + + +Identifier (a) + + +s1_1->s1_2 + + + + +s1_3 + + + + + + + + + + + + + +BlockStatement +ExpressionStatement +AssignmentExpression +Identifier (a) +CallExpression +Identifier (foo) + + +s1_2->s1_3 + + + + +s1_4 + + + + + + + + + + + + + +ExpressionStatement +CallExpression +Identifier (bar) + + +s1_2->s1_4 + + + + +s1_3->s1_2 + + + + +s1_4->final + + + + + \ No newline at end of file diff --git a/docs/8.0.0/developer-guide/contributing/README.md b/docs/8.0.0/developer-guide/contributing/README.md new file mode 100644 index 0000000000..e341083feb --- /dev/null +++ b/docs/8.0.0/developer-guide/contributing/README.md @@ -0,0 +1,41 @@ +# Contributing + +One of the great things about open source projects is that anyone can contribute in any number of meaningful ways. ESLint couldn't exist without the help of the many contributors it's had since the project began, and we want you to feel like you can contribute and make a difference as well. + +This guide is intended for anyone who wants to contribute to an ESLint project. Please read it carefully as it answers a lot of the questions many newcomers have when first working with our projects. + +## Read the [Code of Conduct](https://eslint.org/conduct) + +ESLint welcomes contributions from everyone and adheres to the [OpenJS Foundation Code of Conduct](https://eslint.org/conduct). We kindly request that you read over our code of conduct before contributing. + +## [Signing the CLA](https://openjsf.org/about/the-openjs-foundation-cla/) + +In order to submit code or documentation to an ESLint project, you will need to electronically sign our [Contributor License Agreement](https://cla.js.foundation/eslint/eslint). The CLA is you giving us permission to use your contribution. + +## [Bug Reporting](reporting-bugs) + +Think you found a problem? We'd love to hear about it. This section explains how to submit a bug, the type of information we need to properly verify it, and the overall process. + +## Proposing a [New Rule](new-rules.md) + +We get a lot of proposals for new rules in ESLint. This section explains how we determine which rules are accepted and what information you should provide to help us evaluate your proposal. + +## Proposing a [Rule Change](rule-changes.md) + +Want to make a change to an existing rule? This section explains the process and how we evaluate such proposals. + +## Requesting a [Change](changes.md) + +If you'd like to request a change other than a bug fix or new rule, this section explains that process. + +## Reporting a security vulnerability + +To report a security vulnerability in ESLint, please use our [HackerOne program](https://hackerone.com/eslint). + +## [Working on Issues](working-on-issues.md) + +Have some extra time and want to contribute? This section talks about the process of working on issues. + +## Submitting a [Pull Request](pull-requests.md) + +We're always looking for contributions from the community. This section explains the requirements for pull requests and the process of contributing code. diff --git a/docs/8.0.0/developer-guide/contributing/changes.md b/docs/8.0.0/developer-guide/contributing/changes.md new file mode 100644 index 0000000000..7723c089b0 --- /dev/null +++ b/docs/8.0.0/developer-guide/contributing/changes.md @@ -0,0 +1,25 @@ +--- +title: Change Requests +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/developer-guide/contributing/changes.md + +--- + + +# Change Requests + +If you'd like to request a change to ESLint, please [create a new issue](https://github.com/eslint/eslint/issues/new?template=CHANGE.md) on GitHub. Be sure to include the following information: + +1. The version of ESLint you are using. +1. The problem you want to solve. +1. Your take on the correct solution to problem. + +If you're requesting a change to a rule, it's helpful to include this information as well: + +1. What you did. +1. What you would like to happen. +1. What actually happened. + +Please include as much detail as possible to help us properly address your issue. If we need to triage issues and constantly ask people for more detail, that's time taken away from actually fixing issues. Help us be as efficient as possible by including a lot of detail in your issues. + +**Note:** If you just have a question that won't necessarily result in a change to ESLint, such as asking how something works or how to contribute, please use the [mailing list](https://groups.google.com/group/eslint) or [chat](https://eslint.org/chat) instead of filing an issue. diff --git a/docs/8.0.0/developer-guide/contributing/index.md b/docs/8.0.0/developer-guide/contributing/index.md new file mode 100644 index 0000000000..dbd4cb8b49 --- /dev/null +++ b/docs/8.0.0/developer-guide/contributing/index.md @@ -0,0 +1,49 @@ +--- +title: Contributing +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/developer-guide/contributing/README.md + +--- + + +# Contributing + +One of the great things about open source projects is that anyone can contribute in any number of meaningful ways. ESLint couldn't exist without the help of the many contributors it's had since the project began, and we want you to feel like you can contribute and make a difference as well. + +This guide is intended for anyone who wants to contribute to an ESLint project. Please read it carefully as it answers a lot of the questions many newcomers have when first working with our projects. + +## Read the [Code of Conduct](https://eslint.org/conduct) + +ESLint welcomes contributions from everyone and adheres to the [OpenJS Foundation Code of Conduct](https://eslint.org/conduct). We kindly request that you read over our code of conduct before contributing. + +## [Signing the CLA](https://openjsf.org/about/the-openjs-foundation-cla/) + +In order to submit code or documentation to an ESLint project, you will need to electronically sign our [Contributor License Agreement](https://cla.js.foundation/eslint/eslint). The CLA is you giving us permission to use your contribution. + +## [Bug Reporting](reporting-bugs) + +Think you found a problem? We'd love to hear about it. This section explains how to submit a bug, the type of information we need to properly verify it, and the overall process. + +## Proposing a [New Rule](new-rules) + +We get a lot of proposals for new rules in ESLint. This section explains how we determine which rules are accepted and what information you should provide to help us evaluate your proposal. + +## Proposing a [Rule Change](rule-changes) + +Want to make a change to an existing rule? This section explains the process and how we evaluate such proposals. + +## Requesting a [Change](changes) + +If you'd like to request a change other than a bug fix or new rule, this section explains that process. + +## Reporting a security vulnerability + +To report a security vulnerability in ESLint, please use our [HackerOne program](https://hackerone.com/eslint). + +## [Working on Issues](working-on-issues) + +Have some extra time and want to contribute? This section talks about the process of working on issues. + +## Submitting a [Pull Request](pull-requests) + +We're always looking for contributions from the community. This section explains the requirements for pull requests and the process of contributing code. diff --git a/docs/8.0.0/developer-guide/contributing/new-rules.md b/docs/8.0.0/developer-guide/contributing/new-rules.md new file mode 100644 index 0000000000..95dc6fc44c --- /dev/null +++ b/docs/8.0.0/developer-guide/contributing/new-rules.md @@ -0,0 +1,50 @@ +--- +title: New Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/developer-guide/contributing/new-rules.md + +--- + + +# New Rules + +ESLint is all about rules. For most of the project's lifetime, we've had over 200 rules, and that list continues to grow. However, we can't just accept any proposed rule because all rules need to work cohesively together. As such, we have some guidelines around which rules can be part of the ESLint core and which are better off as custom rules and plugins. + +**Note:** As of 2020, we only accept rules related to new ECMAScript features. We prefer that new rules be implemented in plugins. + +## Core Rule Guidelines + +In general, ESLint core rules must be: + +1. **Widely applicable.** The rules we distribute need to be of importance to a large number of developers. Individual preferences for uncommon patterns are not supported. +1. **Generic.** Rules cannot be so specific that users will have trouble understanding when to use them. A rule is typically too specific if describing what it does requires more than two "and"s (if a and b and c and d, then this rule warns). +1. **Atomic.** Rules must function completely on their own. Rules are expressly forbidden from knowing about the state or presence of other rules. +1. **Unique.** No two rules can produce the same warning. Overlapping rules confuse end users and there is an expectation that core ESLint rules do not overlap. +1. **Library agnostic.** Rules must be based solely on JavaScript runtime environments and not on specific libraries or frameworks. For example, core rules shouldn't only apply if you're using jQuery but we may have some rules that apply only if you're using Node.js (a runtime). +1. **No conflicts.** No rule must directly conflict with another rule. For example, if we have a rule requiring semicolons, we cannot also have a rule disallowing semicolons (which is why we have one rule, `semi`, that does both). + +Even though these are the formal criteria for inclusion, each rule is evaluated on its own basis. + +## Proposing a Rule + +If you want to propose a new rule, please see how to [create a pull request](/docs/developer-guide/contributing/pull-requests) or submit an issue by filling out a [new rule template](https://github.com/eslint/eslint/issues/new?template=NEW_RULE.md). + +We need all of this information in order to determine whether or not the rule is a good core rule candidate. + +## Accepting a Rule + +In order for a rule to be accepted in the ESLint core, it must: + +1. Fulfill all the criteria listed in the "Core Rule Guidelines" section +1. Have an ESLint team member champion inclusion of the rule +1. Be related to an ECMAScript feature that has reached stage 4 in the preceding 12 months + +Keep in mind that we have over 200 rules, and that is daunting both for end users and the ESLint team (who has to maintain them). As such, any new rules must be deemed of high importance to be considered for inclusion in ESLint. + +## Implementation is Your Responsibility + +The ESLint team doesn't implement new rules that are suggested by users because we have a limited number of people and need to focus on the overall roadmap. Once a rule is accepted, you are responsible for implementing and documenting the rule. You may, alternately, recruit another person to help you implement the rule. The ESLint team member who championed the rule is your resource to help guide you through the rest of this process. + +## Alternative: Creating Your Own Rules + +Remember that ESLint is completely pluggable, which means you can create your own rules and distribute them using plugins. We did this on purpose because we don't want to be the gatekeepers for all possible rules. Even if we don't accept a rule into the core, that doesn't mean you can't have the exact rule that you want. See the [working with rules](../working-with-rules) and [working with plugins](../working-with-plugins) documentation for more information. diff --git a/docs/8.0.0/developer-guide/contributing/pull-requests.md b/docs/8.0.0/developer-guide/contributing/pull-requests.md new file mode 100644 index 0000000000..d8f398fa8f --- /dev/null +++ b/docs/8.0.0/developer-guide/contributing/pull-requests.md @@ -0,0 +1,190 @@ +--- +title: Pull Requests +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/developer-guide/contributing/pull-requests.md + +--- + + +# Pull Requests + +If you want to contribute to an ESLint repo, please use a GitHub pull request. This is the fastest way for us to evaluate your code and to merge it into the code base. Please don't file an issue with snippets of code. Doing so means that we need to manually merge the changes in and update any appropriate tests. That decreases the likelihood that your code is going to get included in a timely manner. Please use pull requests. + +## Getting Started + +If you'd like to work on a pull request and you've never submitted code before, follow these steps: + +1. Sign our [Contributor License Agreement](https://cla.js.foundation/eslint/eslint). +1. Set up a [development environment](../development-environment). +1. If you want to implement a breaking change or a change to the core, ensure there's an issue that describes what you're doing and the issue has been accepted. You can create a new issue or just indicate you're [working on an existing issue](working-on-issues). Bug fixes, documentation changes, and other pull requests do not require an issue. + +After that, you're ready to start working on code. + +## Working with Code + +The process of submitting a pull request is fairly straightforward and generally follows the same pattern each time: + +1. [Create a new branch](#step1) +2. [Make your changes](#step2) +3. [Rebase onto upstream](#step3) +4. [Run the tests](#step4) +5. [Double check your submission](#step5) +6. [Push your changes](#step6) +7. [Submit the pull request](#step7) + +Details about each step are found below. + +### Step 1: Create a new branch + +The first step to sending a pull request is to create a new branch in your ESLint fork. Give the branch a descriptive name that describes what it is you're fixing, such as: + +``` +$ git checkout -b issue1234 +``` + +You should do all of your development for the issue in this branch. + +**Note:** Do not combine fixes for multiple issues into one branch. Use a separate branch for each issue you're working on. + +### Step 2: Make your changes + +Make the changes to the code and tests, following the [code conventions](../code-conventions) as you go. Once you have finished, commit the changes to your branch: + +``` +$ git add -A +$ git commit +``` + +Our commit message format is as follows: + +``` +Tag: Short description (fixes #1234) + +Longer description here if necessary +``` + +The first line of the commit message (the summary) must have a specific format. This format is checked by our build tools. + +The `Tag` is one of the following: + +* `Fix` - for a bug fix. +* `Update` - either for a backwards-compatible enhancement or for a rule change that adds reported problems. +* `New` - implemented a new feature. +* `Breaking` - for a backwards-incompatible enhancement or feature. +* `Docs` - changes to documentation only. +* `Build` - changes to build process only. +* `Upgrade` - for a dependency upgrade. +* `Chore` - for refactoring, adding tests, etc. (anything that isn't user-facing). + +Use the [labels of the issue you are working on](working-on-issues#issue-labels) to determine the best tag. + +The message summary should be a one-sentence description of the change, and it must be 72 characters in length or shorter. If the pull request addresses an issue, then the issue number should be mentioned at the end. If the commit doesn't completely fix the issue, then use `(refs #1234)` instead of `(fixes #1234)`. + +Here are some good commit message summary examples: + +``` +Build: Update Travis to only test Node 0.10 (refs #734) +Fix: Semi rule incorrectly flagging extra semicolon (fixes #840) +Upgrade: Esprima to 1.2, switch to using comment attachment (fixes #730) +``` + +The commit message format is important because these messages are used to create a changelog for each release. The tag and issue number help to create more consistent and useful changelogs. + +### Step 3: Rebase onto upstream + +Before you send the pull request, be sure to rebase onto the upstream source. This ensures your code is running on the latest available code. + +``` +git fetch upstream +git rebase upstream/master +``` + +### Step 4: Run the tests + +After rebasing, be sure to run all of the tests once again to make sure nothing broke: + +``` +npm test +``` + +If there are any failing tests, update your code until all tests pass. + +### Step 5: Double check your submission + +With your code ready to go, this is a good time to double-check your submission to make sure it follows our conventions. Here are the things to check: + +* Make sure your commit is formatted correctly. +* The pull request must have a description. The description should explain what you did and how its effects can be seen. +* The commit message is properly formatted. +* The change introduces no functional regression. Be sure to run `npm test` to verify your changes before submitting a pull request. +* Make separate pull requests for unrelated changes. Large pull requests with multiple unrelated changes may be closed without merging. +* All changes must be accompanied by tests, even if the feature you're working on previously had no tests. +* All user-facing changes must be accompanied by appropriate documentation. +* Follow the [Code Conventions](../code-conventions). + +### Step 6: Push your changes + +Next, push your changes to your clone: + +``` +git push origin issue1234 +``` + +If you are unable to push because some references are old, do a forced push instead: + +``` +git push -f origin issue1234 +``` + +### Step 7: Send the pull request + +Now you're ready to send the pull request. Go to your ESLint fork and then follow the [GitHub documentation](https://help.github.com/articles/creating-a-pull-request) on how to send a pull request. + +## Following Up + +Once your pull request is sent, it's time for the team to review it. As such, please make sure to: + +1. Monitor the status of the Travis CI build for your pull request. If it fails, please investigate why. We cannot merge pull requests that fail Travis for any reason. +1. Respond to comments left on the pull request from team members. Remember, we want to help you land your code, so please be receptive to our feedback. +1. We may ask you to make changes, rebase, or squash your commits. + +### Updating the Commit Message + +If your commit message is in the incorrect format, you'll be asked to update it. You can do so via: + +``` +$ git commit --amend +``` + +This will open up your editor so you can make changes. After that, you'll need to do a forced push to your branch: + +``` +$ git push origin issue1234 -f +``` + +### Updating the Code + +If we ask you to make code changes, there's no need to close the pull request and create a new one. Just go back to the branch on your fork and make your changes. Then, when you're ready, you can add your changes into the branch: + +``` +$ git add -A +$ git commit +$ git push origin issue1234 +``` + +When updating the code, it's usually better to add additional commits to your branch rather than amending the original commit, because reviewers can easily tell which changes were made in response to a particular review. When we merge pull requests, we will squash all the commits from your branch into a single commit on the `master` branch. + +### Rebasing + +If your code is out-of-date, we might ask you to rebase. That means we want you to apply your changes on top of the latest upstream code. Make sure you have set up a [development environment](../development-environment) and then you can rebase using these commands: + +``` +$ git fetch upstream +$ git rebase upstream/master +``` + +You might find that there are merge conflicts when you attempt to rebase. Please [resolve the conflicts](https://help.github.com/articles/resolving-merge-conflicts-after-a-git-rebase/) and then do a forced push to your branch: + +``` +$ git push origin issue1234 -f +``` diff --git a/docs/8.0.0/developer-guide/contributing/reporting-bugs.md b/docs/8.0.0/developer-guide/contributing/reporting-bugs.md new file mode 100644 index 0000000000..1279f8dd10 --- /dev/null +++ b/docs/8.0.0/developer-guide/contributing/reporting-bugs.md @@ -0,0 +1,15 @@ +--- +title: Reporting Bugs +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/developer-guide/contributing/reporting-bugs.md + +--- + + +# Reporting Bugs + +If you think you've found a bug in ESLint, please [create a new issue](https://github.com/eslint/eslint/issues/new) or a [pull request](/docs/developer-guide/contributing/pull-requests) on GitHub. + +Please include as much detail as possible to help us properly address your issue. If we need to triage issues and constantly ask people for more detail, that's time taken away from actually fixing issues. Help us be as efficient as possible by including a lot of detail in your issues. + +**Note:** If you just have a question that won't necessarily result in a change to ESLint, such as asking how something works or how to contribute, please use the [mailing list](https://groups.google.com/group/eslint) or [chat](https://eslint.org/chat) instead of filing an issue. diff --git a/docs/8.0.0/developer-guide/contributing/rule-changes.md b/docs/8.0.0/developer-guide/contributing/rule-changes.md new file mode 100644 index 0000000000..08a4ec1ae8 --- /dev/null +++ b/docs/8.0.0/developer-guide/contributing/rule-changes.md @@ -0,0 +1,29 @@ +--- +title: Rule Changes +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/developer-guide/contributing/rule-changes.md + +--- + + +# Rule Changes + +Occasionally, a core ESLint rule needs to be changed. This is not necessarily a bug, but rather, an enhancement that makes a rule more configurable. In those situations, we will consider making changes to rules. + +## Proposing a Rule Change + +To propose a change to an existing rule, [create a pull request](/docs/developer-guide/contributing/pull-requests) or [new issue](https://github.com/eslint/eslint/issues/new?template=RULE_CHANGE.md) and fill out the template. + +We need all of this information in order to determine whether or not the change is a good candidate for inclusion. + +## Accepting a Rule Change + +In order for a rule change to be accepted into ESLint, it must: + +1. Adhere to the [Core Rule Guidelines](new-rules#core-rule-guidelines) +1. Have an ESLint team member champion the change +1. Be important enough that rule is deemed incomplete without this change + +## Implementation is Your Responsibility + +The ESLint team doesn't implement rule changes that are suggested by users because we have a limited number of people and need to focus on the overall roadmap. Once a rule change is accepted, you are responsible for implementing and documenting it. You may, alternately, recruit another person to help you. The ESLint team member who championed the rule is your resource to help guide you through the rest of this process. diff --git a/docs/8.0.0/developer-guide/contributing/working-on-issues.md b/docs/8.0.0/developer-guide/contributing/working-on-issues.md new file mode 100644 index 0000000000..936ea57af6 --- /dev/null +++ b/docs/8.0.0/developer-guide/contributing/working-on-issues.md @@ -0,0 +1,44 @@ +--- +title: Working on Issues +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/developer-guide/contributing/working-on-issues.md + +--- + + +# Working on Issues + +Our public [issues tracker](https://github.com/eslint/eslint/issues) lists all of the things we plan on doing as well as suggestions from the community. Before starting to work on an issue, be sure you read through the rest of this page. + +## Issue Labels + +We use labels to indicate the status of issues. The most complete documentation on the labels is found in the [Maintainer Guide](https://eslint.org/docs/maintainer-guide/issues.html#when-an-issue-is-opened), but most contributors should find the information on this page sufficient. The most important questions that labels can help you, as a contributor, answer are: + +1. Is this issue available for me to work on? If you have little or no experience contributing to ESLint, the [`good first issue`](https://github.com/eslint/eslint/labels/good%20first%20issue) label marks appropriate issues. Otherwise, the [`help wanted`](https://github.com/eslint/eslint/labels/help%20wanted) label is an invitation to work on the issue. If you have more experience, you can try working on other issues labeled [`accepted`](https://github.com/eslint/eslint/labels/accepted). Conversely, issues not yet ready to work on are labeled `triage`, `evaluating`, and/or `needs bikeshedding`, and issues that cannot currently be worked on because of something else, such as a bug in a dependency, are labeled `blocked`. +1. What is this issue about? Labels describing the nature of issues include `bug`, `enhancement`, `feature`, `question`, `rule`, `documentation`, `core`, `build`, `cli`, `infrastructure`, `breaking`, and `chore`. These are documented in the [Maintainer Guide](https://eslint.org/docs/maintainer-guide/issues.html#types-of-issues). +1. What is the priority of this issue? Because we have a lot of issues, we prioritize certain issues above others. The following is the list of priorities, from highest to lowest: + + 1. **Bugs** - problems with the project are actively affecting users. We want to get these resolved as quickly as possible. + 1. **Documentation** - documentation issues are a type of bug in that they actively affect current users. As such, we want to address documentation issues as quickly as possible. + 1. **Features** - new functionality that will aid users in the future. + 1. **Enhancements** - requested improvements for existing functionality. + 1. **Other** - anything else. + + Some issues have had monetary rewards attached to them. Those are labeled `bounty`. Bounties are assigned via [BountySource](https://www.bountysource.com/teams/eslint/issues). + +## Starting Work + +If you're going to work on an issue, please add a comment to that issue saying so and indicating when you think you will complete it. It will help us to avoid duplication of effort. Some examples of good comments are: + +* "I'll take a look at this over the weekend." +* "I'm going to do this, give me two weeks." +* "Working on this" (as in, I'm working on it right now) + +If an issue has already been claimed by someone, please be respectful of that person's desire to complete the work and don't work on it unless you verify that they are no longer interested. + +If you find you can't finish the work, then simply add a comment letting people know, for example: + +* "Sorry, it looks like I don't have time to do this." +* "I thought I knew enough to fix this, but it turns out I don't." + +No one will blame you for backing out of an issue if you are unable to complete it. We just want to keep the process moving along as efficiently as possible. diff --git a/docs/8.0.0/developer-guide/development-environment.md b/docs/8.0.0/developer-guide/development-environment.md new file mode 100644 index 0000000000..c8a0f3b6e8 --- /dev/null +++ b/docs/8.0.0/developer-guide/development-environment.md @@ -0,0 +1,100 @@ +--- +title: Development Environment +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/developer-guide/development-environment.md + +--- + + +# Development Environment + +ESLint has a very lightweight development environment that makes updating code fast and easy. This is a step-by-step guide to setting up a local development environment that will let you contribute back to the project. + +## Step 1: Install Node.js + +Go to to download and install the latest stable version for your operating system. + +Most of the installers already come with [npm](https://www.npmjs.com/) but if for some reason npm doesn't work on your system, you can install it manually using the instructions on the site. + +## Step 2: Fork and checkout your own ESLint repository + +Go to and click the "Fork" button. Follow the [GitHub documentation](https://help.github.com/articles/fork-a-repo) for forking and cloning. + +Once you've cloned the repository, run `npm install` to get all the necessary dependencies: + +``` +$ cd eslint +$ npm install +``` + +You must be connected to the Internet for this step to work. You'll see a lot of utilities being downloaded. + +## Step 3: Add the upstream source + +The *upstream source* is the main ESLint repository where active development happens. While you won't have push access to upstream, you will have pull access, allowing you to pull in the latest code whenever you want. + +To add the upstream source for ESLint, run the following in your repository: + +``` +git remote add upstream git@github.com:eslint/eslint.git +``` + +Now, the remote `upstream` points to the upstream source. + +## Step 4: Install the Yeoman Generator + +[Yeoman](http://yeoman.io) is a scaffold generator that ESLint uses to help streamline development of new rules. If you don't already have Yeoman installed, you can install it via npm: + + npm install -g yo + +Then, you can install the ESLint Yeoman generator: + + npm install -g generator-eslint + +Please see the [generator documentation](https://github.com/eslint/generator-eslint) for instructions on how to use it. + +## Step 5: Run the tests + +Running the tests is the best way to ensure you have correctly set up your development environment. Make sure you're in the `eslint` directory and run: + +``` +npm test +``` + +The testing takes a few minutes to complete. If any tests fail, that likely means one or more parts of the environment setup didn't complete correctly. The upstream tests always pass. + +## Reference Information + +### Workflow + +Once you have your development environment installed, you can make and submit changes to the ESLint source files. Doing this successfully requires careful adherence to our [pull-request submission workflow](contributing/pull-requests). + +### Build Scripts + +ESLint has several build scripts that help with various parts of development. + +#### npm test + +The primary script to use is `npm test`, which does several things: + +1. Lints all JavaScript (including tests) and JSON +1. Runs all tests on Node.js +1. Checks code coverage targets +1. Generates `build/eslint.js` for use in a browser +1. Runs a subset of tests in PhantomJS + +Be sure to run this after making changes and before sending a pull request with your changes. + +**Note:** The full code coverage report is output into `/coverage`. + +#### npm run lint + +Runs just the JavaScript and JSON linting on the repository + +#### npm run webpack + +Generates `build/eslint.js`, a version of ESLint for use in the browser + +#### npm run docs + +Generates JSDoc documentation and places it into `/jsdoc`. diff --git a/docs/8.0.0/developer-guide/index.md b/docs/8.0.0/developer-guide/index.md new file mode 100644 index 0000000000..74b12beecd --- /dev/null +++ b/docs/8.0.0/developer-guide/index.md @@ -0,0 +1,55 @@ +--- +title: Developer Guide +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/developer-guide/README.md + +--- + + +# Developer Guide + +This guide is intended for those who wish to: + +* Contribute code to ESLint +* Create their own rules for ESLint + +In order to work with ESLint as a developer, it's recommended that: + +* You know JavaScript, since ESLint is written in JavaScript. +* You have some familiarity with Node.js, since ESLint runs on it. +* You're comfortable with command-line programs. +* You understand unit tests and why they're important. + +If that sounds like you, then continue reading to get started. + +## Section 1: Get the [Source Code](source-code) + +Before you can get started, you'll need to get a copy of the ESLint source code. This section explains how to do that and a little about the source code structure. + +## Section 2: Set up a [Development Environment](development-environment) + +Developing for ESLint is a bit different than running it on the command line. This section shows you how to set up a development environment and get you ready to write code. + +## Section 3: Run the [Unit Tests](unit-tests) + +There are a lot of unit tests included with ESLint to make sure that we're keeping on top of code quality. This section explains how to run the unit tests. + +## Section 4: [Working with Rules](working-with-rules) + +You're finally ready to start working with rules. You may want to fix an existing rule or create a new one. This section explains how to do all of that. + +## Section 5: [Working with Plugins](working-with-plugins) + +You've developed library-specific rules for ESLint and you want to share it with the community. You can publish an ESLint plugin on npm. + +## Section 6: [Working with Custom Parsers](working-with-custom-parsers) + +If you aren't going to use the default parser of ESLint, this section explains about using custom parsers. + +## Section 7: [Node.js API](nodejs-api) + +If you're interested in writing a tool that uses ESLint, then you can use the Node.js API to get programmatic access to functionality. + +## Section 8: [Contributing](contributing/) + +Once you've made changes that you want to share with the community, the next step is to submit those changes back via a pull request. diff --git a/docs/8.0.0/developer-guide/nodejs-api.md b/docs/8.0.0/developer-guide/nodejs-api.md new file mode 100644 index 0000000000..92ea090f0a --- /dev/null +++ b/docs/8.0.0/developer-guide/nodejs-api.md @@ -0,0 +1,923 @@ +--- +title: Node.js API +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/developer-guide/nodejs-api.md + +--- + + +# Node.js API + +While ESLint is designed to be run on the command line, it's possible to use ESLint programmatically through the Node.js API. The purpose of the Node.js API is to allow plugin and tool authors to use the ESLint functionality directly, without going through the command line interface. + +**Note:** Use undocumented parts of the API at your own risk. Only those parts that are specifically mentioned in this document are approved for use and will remain stable and reliable. Anything left undocumented is unstable and may change or be removed at any point. + +## Table of Contents + +* [ESLint] + * [constructor()][eslint-constructor] + * [lintFiles()][eslint-lintfiles] + * [lintText()][eslint-linttext] + * [getRulesMetaForResults()][eslint-getrulesmetaforresults] + * [calculateConfigForFile()][eslint-calculateconfigforfile] + * [isPathIgnored()][eslint-ispathignored] + * [loadFormatter()][eslint-loadformatter] + * [static version][eslint-version] + * [static outputFixes()][eslint-outputfixes] + * [static getErrorResults()][eslint-geterrorresults] + * [LintResult type][lintresult] + * [LintMessage type][lintmessage] + * [EditInfo type][editinfo] + * [Formatter type][formatter] +* [SourceCode](#sourcecode) + * [splitLines()](#sourcecodesplitlines) +* [Linter](#linter) + * [verify()](#linterverify) + * [verifyAndFix()](#linterverifyandfix) + * [defineRule()](#linterdefinerule) + * [defineRules()](#linterdefinerules) + * [getRules()](#lintergetrules) + * [defineParser()](#linterdefineparser) + * [version](#linterversionlinterversion) +* [RuleTester](#ruletester) + * [Customizing RuleTester](#customizing-ruletester) + +--- + +## ESLint class + +The `ESLint` class is the primary class to use in Node.js applications. + +This class depends on the Node.js `fs` module and the file system, so you cannot use it in browsers. If you want to lint code on browsers, use the [Linter](#linter) class instead. + +Here's a simple example of using the `ESLint` class: + +```js +const { ESLint } = require("eslint"); + +(async function main() { + // 1. Create an instance. + const eslint = new ESLint(); + + // 2. Lint files. + const results = await eslint.lintFiles(["lib/**/*.js"]); + + // 3. Format the results. + const formatter = await eslint.loadFormatter("stylish"); + const resultText = formatter.format(results); + + // 4. Output it. + console.log(resultText); +})().catch((error) => { + process.exitCode = 1; + console.error(error); +}); +``` + +And here is an example that autofixes lint problems: + +```js +const { ESLint } = require("eslint"); + +(async function main() { + // 1. Create an instance with the `fix` option. + const eslint = new ESLint({ fix: true }); + + // 2. Lint files. This doesn't modify target files. + const results = await eslint.lintFiles(["lib/**/*.js"]); + + // 3. Modify the files with the fixed code. + await ESLint.outputFixes(results); + + // 4. Format the results. + const formatter = await eslint.loadFormatter("stylish"); + const resultText = formatter.format(results); + + // 5. Output it. + console.log(resultText); +})().catch((error) => { + process.exitCode = 1; + console.error(error); +}); +``` + +### ◆ new ESLint(options) + +```js +const eslint = new ESLint(options); +``` + +Create a new `ESLint` instance. + +#### Parameters + +The `ESLint` constructor takes an `options` object. If you omit the `options` object then it uses default values for all options. The `options` object has the following properties. + +##### File Enumeration + +* `options.cwd` (`string`)
    + Default is `process.cwd()`. The working directory. This must be an absolute path. +* `options.errorOnUnmatchedPattern` (`boolean`)
    + Default is `true`. Unless set to `false`, the [`eslint.lintFiles()`][eslint-lintfiles] method will throw an error when no target files are found. +* `options.extensions` (`string[] | null`)
    + Default is `null`. If you pass directory paths to the [`eslint.lintFiles()`][eslint-lintfiles] method, ESLint checks the files in those directories that have the given extensions. For example, when passing the `src/` directory and `extensions` is `[".js", ".ts"]`, ESLint will lint `*.js` and `*.ts` files in `src/`. If `extensions` is `null`, ESLint checks `*.js` files and files that match `overrides[].files` patterns in your configuration.
    **Note:** This option only applies when you pass directory paths to the [`eslint.lintFiles()`][eslint-lintfiles] method. If you pass glob patterns like `lib/**/*`, ESLint will lint all files matching the glob pattern regardless of extension. +* `options.globInputPaths` (`boolean`)
    + Default is `true`. If `false` is present, the [`eslint.lintFiles()`][eslint-lintfiles] method doesn't interpret glob patterns. +* `options.ignore` (`boolean`)
    + Default is `true`. If `false` is present, the [`eslint.lintFiles()`][eslint-lintfiles] method doesn't respect `.eslintignore` files or `ignorePatterns` in your configuration. +* `options.ignorePath` (`string | null`)
    + Default is `null`. The path to a file ESLint uses instead of `$CWD/.eslintignore`. If a path is present and the file doesn't exist, this constructor will throw an error. + +##### Linting + +* `options.allowInlineConfig` (`boolean`)
    + Default is `true`. If `false` is present, ESLint suppresses directive comments in source code. If this option is `false`, it overrides the `noInlineConfig` setting in your configurations. +* `options.baseConfig` (`ConfigData | null`)
    + Default is `null`. [Configuration object], extended by all configurations used with this instance. You can use this option to define the default settings that will be used if your configuration files don't configure it. +* `options.overrideConfig` (`ConfigData | null`)
    + Default is `null`. [Configuration object], overrides all configurations used with this instance. You can use this option to define the settings that will be used even if your configuration files configure it. +* `options.overrideConfigFile` (`string | null`)
    + Default is `null`. The path to a configuration file, overrides all configurations used with this instance. The `options.overrideConfig` option is applied after this option is applied. +* `options.plugins` (`Record | null`)
    + Default is `null`. The plugin implementations that ESLint uses for the `plugins` setting of your configuration. This is a map-like object. Those keys are plugin IDs and each value is implementation. +* `options.reportUnusedDisableDirectives` (`"error" | "warn" | "off" | null`)
    + Default is `null`. The severity to report unused eslint-disable directives. If this option is a severity, it overrides the `reportUnusedDisableDirectives` setting in your configurations. +* `options.resolvePluginsRelativeTo` (`string` | `null`)
    + Default is `null`. The path to a directory where plugins should be resolved from. If `null` is present, ESLint loads plugins from the location of the configuration file that contains the plugin setting. If a path is present, ESLint loads all plugins from there. +* `options.rulePaths` (`string[]`)
    + Default is `[]`. An array of paths to directories to load custom rules from. +* `options.useEslintrc` (`boolean`)
    + Default is `true`. If `false` is present, ESLint doesn't load configuration files (`.eslintrc.*` files). Only the configuration of the constructor options is valid. + +##### Autofix + +* `options.fix` (`boolean | (message: LintMessage) => boolean`)
    + Default is `false`. If `true` is present, the [`eslint.lintFiles()`][eslint-lintfiles] and [`eslint.lintText()`][eslint-linttext] methods work in autofix mode. If a predicate function is present, the methods pass each lint message to the function, then use only the lint messages for which the function returned `true`. +* `options.fixTypes` (`("directive" | "problem" | "suggestion" | "layout")[] | null`)
    + Default is `null`. The types of the rules that the [`eslint.lintFiles()`][eslint-lintfiles] and [`eslint.lintText()`][eslint-linttext] methods use for autofix. + +##### Cache-related + +* `options.cache` (`boolean`)
    + Default is `false`. If `true` is present, the [`eslint.lintFiles()`][eslint-lintfiles] method caches lint results and uses it if each target file is not changed. Please mind that ESLint doesn't clear the cache when you upgrade ESLint plugins. In that case, you have to remove the cache file manually. The [`eslint.lintText()`][eslint-linttext] method doesn't use caches even if you pass the `options.filePath` to the method. +* `options.cacheLocation` (`string`)
    + Default is `.eslintcache`. The [`eslint.lintFiles()`][eslint-lintfiles] method writes caches into this file. +* `options.cacheStrategy` (`string`)
    + Default is `"metadata"`. Strategy for the cache to use for detecting changed files. Can be either `"metadata"` or `"content"`. + +### ◆ eslint.lintFiles(patterns) + +```js +const results = await eslint.lintFiles(patterns); +``` + +This method lints the files that match the glob patterns and then returns the results. + +#### Parameters + +* `patterns` (`string | string[]`)
    + The lint target files. This can contain any of file paths, directory paths, and glob patterns. + +#### Return Value + +* (`Promise`)
    + The promise that will be fulfilled with an array of [LintResult] objects. + +### ◆ eslint.lintText(code, options) + +```js +const results = await eslint.lintText(code, options); +``` + +This method lints the given source code text and then returns the results. + +By default, this method uses the configuration that applies to files in the current working directory (the `cwd` constructor option). If you want to use a different configuration, pass `options.filePath`, and ESLint will load the same configuration that [`eslint.lintFiles()`][eslint-lintfiles] would use for a file at `options.filePath`. + +If the `options.filePath` value is configured to be ignored, this method returns an empty array. If the `options.warnIgnored` option is set along with the `options.filePath` option, this method returns a [LintResult] object. In that case, the result may contain a warning that indicates the file was ignored. + +#### Parameters + +The second parameter `options` is omittable. + +* `code` (`string`)
    + The source code text to check. +* `options.filePath` (`string`)
    + Optional. The path to the file of the source code text. If omitted, the `result.filePath` becomes the string `""`. +* `options.warnIgnored` (`boolean`)
    + Optional. If `true` is present and the `options.filePath` is a file ESLint should ignore, this method returns a lint result contains a warning message. + +#### Return Value + +* (`Promise`)
    + The promise that will be fulfilled with an array of [LintResult] objects. This is an array (despite there being only one lint result) in order to keep the interfaces between this and the [`eslint.lintFiles()`][eslint-lintfiles] method similar. + +### ◆ eslint.getRulesMetaForResults(results) + +```js +const results = await eslint.lintFiles(patterns); +const rulesMeta = eslint.getRulesMetaForResults(results); +``` + +This method returns an object containing meta information for each rule that triggered a lint error in the given `results`. + +#### Parameters + +* `results` (`LintResult[]`)
    + An array of [LintResult] objects returned from a call to `ESLint#lintFiles()` or `ESLint#lintText()`. + +#### Return Value + +* (`Object`)
    + An object whose property names are the rule IDs from the `results` and whose property values are the rule's meta information (if available). + +### ◆ eslint.calculateConfigForFile(filePath) + +```js +const config = await eslint.calculateConfigForFile(filePath); +``` + +This method calculates the configuration for a given file, which can be useful for debugging purposes. + +* It resolves and merges `extends` and `overrides` settings into the top level configuration. +* It resolves the `parser` setting to absolute paths. +* It normalizes the `plugins` setting to align short names. (e.g., `eslint-plugin-foo` → `foo`) +* It adds the `processor` setting if a legacy file extension processor is matched. +* It doesn't interpret the `env` setting to the `globals` and `parserOptions` settings, so the result object contains the `env` setting as is. + +#### Parameters + +* `filePath` (`string`)
    + The path to the file whose configuration you would like to calculate. Directory paths are forbidden because ESLint cannot handle the `overrides` setting. + +#### Return Value + +* (`Promise`)
    + The promise that will be fulfilled with a configuration object. + +### ◆ eslint.isPathIgnored(filePath) + +```js +const isPathIgnored = await eslint.isPathIgnored(filePath); +``` + +This method checks if a given file is ignored by your configuration. + +#### Parameters + +* `filePath` (`string`)
    + The path to the file you want to check. + +#### Return Value + +* (`Promise`)
    + The promise that will be fulfilled with whether the file is ignored or not. If the file is ignored, then it will return `true`. + +### ◆ eslint.loadFormatter(nameOrPath) + +```js +const formatter = await eslint.loadFormatter(nameOrPath); +``` + +This method loads a formatter. Formatters convert lint results to a human- or machine-readable string. + +#### Parameters + +* `nameOrPath` (`string | undefined`)
    + The path to the file you want to check. The following values are allowed: + * `undefined`. In this case, loads the `"stylish"` built-in formatter. + * A name of [built-in formatters][builtin-formatters]. + * A name of [third-party formatters][thirdparty-formatters]. For examples: + * `"foo"` will load `eslint-formatter-foo`. + * `"@foo"` will load `@foo/eslint-formatter`. + * `"@foo/bar"` will load `@foo/eslint-formatter-bar`. + * A path to the file that defines a formatter. The path must contain one or more path separators (`/`) in order to distinguish if it's a path or not. For example, start with `./`. + +#### Return Value + +* (`Promise`)
    + The promise that will be fulfilled with a [Formatter] object. + +### ◆ ESLint.version + +```js +const version = ESLint.version; +``` + +The version string of ESLint. E.g. `"7.0.0"`. + +This is a static property. + +### ◆ ESLint.outputFixes(results) + +```js +await ESLint.outputFixes(results); +``` + +This method writes code modified by ESLint's autofix feature into its respective file. If any of the modified files don't exist, this method does nothing. + +This is a static method. + +#### Parameters + +* `results` (`LintResult[]`)
    + The [LintResult] objects to write. + +#### Return Value + +* (`Promise`)
    + The promise that will be fulfilled after all files are written. + +### ◆ ESLint.getErrorResults(results) + +```js +const filteredResults = ESLint.getErrorResults(results); +``` + +This method copies the given results and removes warnings. The returned value contains only errors. + +This is a static method. + +#### Parameters + +* `results` (`LintResult[]`)
    + The [LintResult] objects to filter. + +#### Return Value + +* (`LintResult[]`)
    + The filtered [LintResult] objects. + +### ◆ LintResult type + +The `LintResult` value is the information of the linting result of each file. The [`eslint.lintFiles()`][eslint-lintfiles] and [`eslint.lintText()`][eslint-linttext] methods return it. It has the following properties: + +* `filePath` (`string`)
    + The absolute path to the file of this result. This is the string `""` if the file path is unknown (when you didn't pass the `options.filePath` option to the [`eslint.lintText()`][eslint-linttext] method). +* `messages` (`LintMessage[]`)
    + The array of [LintMessage] objects. +* `fixableErrorCount` (`number`)
    + The number of errors that can be fixed automatically by the `fix` constructor option. +* `fixableWarningCount` (`number`)
    + The number of warnings that can be fixed automatically by the `fix` constructor option. +* `errorCount` (`number`)
    + The number of errors. This includes fixable errors and fatal errors. +* `fatalErrorCount` (`number`)
    + The number of fatal errors. +* `warningCount` (`number`)
    + The number of warnings. This includes fixable warnings. +* `output` (`string | undefined`)
    + The modified source code text. This property is undefined if any fixable messages didn't exist. +* `source` (`string | undefined`)
    + The original source code text. This property is undefined if any messages didn't exist or the `output` property exists. +* `usedDeprecatedRules` (`{ ruleId: string; replacedBy: string[] }[]`)
    + The information about the deprecated rules that were used to check this file. + +### ◆ LintMessage type + +The `LintMessage` value is the information of each linting error. The `messages` property of the [LintResult] type contains it. It has the following properties: + +* `ruleId` (`string` | `null`)
    + The rule name that generates this lint message. If this message is generated by the ESLint core rather than rules, this is `null`. +* `severity` (`1 | 2`)
    + The severity of this message. `1` means warning and `2` means error. +* `fatal` (`boolean | undefined`)
    + `true` if this is a fatal error unrelated to a rule, like a parsing error. +* `message` (`string`)
    + The error message. +* `line` (`number`)
    + The 1-based line number of the begin point of this message. +* `column` (`number`)
    + The 1-based column number of the begin point of this message. +* `endLine` (`number | undefined`)
    + The 1-based line number of the end point of this message. This property is undefined if this message is not a range. +* `endColumn` (`number | undefined`)
    + The 1-based column number of the end point of this message. This property is undefined if this message is not a range. +* `fix` (`EditInfo | undefined`)
    + The [EditInfo] object of autofix. This property is undefined if this message is not fixable. +* `suggestions` (`{ desc: string; fix: EditInfo }[] | undefined`)
    + The list of suggestions. Each suggestion is the pair of a description and an [EditInfo] object to fix code. API users such as editor integrations can choose one of them to fix the problem of this message. This property is undefined if this message doesn't have any suggestions. + +### ◆ EditInfo type + +The `EditInfo` value is information to edit text. The `fix` and `suggestions` properties of [LintMessage] type contain it. It has following properties: + +* `range` (`[number, number]`)
    + The pair of 0-based indices in source code text to remove. +* `text` (`string`)
    + The text to add. + +This edit information means replacing the range of the `range` property by the `text` property value. It's like `sourceCodeText.slice(0, edit.range[0]) + edit.text + sourceCodeText.slice(edit.range[1])`. Therefore, it's an add if the `range[0]` and `range[1]` property values are the same value, and it's removal if the `text` property value is empty string. + +### ◆ Formatter type + +The `Formatter` value is the object to convert the [LintResult] objects to text. The [eslint.loadFormatter()][eslint-loadformatter] method returns it. It has the following method: + +* `format` (`(results: LintResult[]) => string`)
    + The method to convert the [LintResult] objects to text. + +--- + +## SourceCode + +The `SourceCode` type represents the parsed source code that ESLint executes on. It's used internally in ESLint and is also available so that already-parsed code can be used. You can create a new instance of `SourceCode` by passing in the text string representing the code and an abstract syntax tree (AST) in [ESTree](https://github.com/estree/estree) format (including location information, range information, comments, and tokens): + +```js +const SourceCode = require("eslint").SourceCode; + +const code = new SourceCode("var foo = bar;", ast); +``` + +The `SourceCode` constructor throws an error if the AST is missing any of the required information. + +The `SourceCode` constructor strips Unicode BOM. +Please note the AST also should be parsed from stripped text. + +```js +const SourceCode = require("eslint").SourceCode; + +const code = new SourceCode("\uFEFFvar foo = bar;", ast); + +assert(code.hasBOM === true); +assert(code.text === "var foo = bar;"); +``` + +### SourceCode#splitLines() + +This is a static function on `SourceCode` that is used to split the source code text into an array of lines. + +```js +const SourceCode = require("eslint").SourceCode; + +const code = "var a = 1;\nvar b = 2;" + +// split code into an array +const codeLines = SourceCode.splitLines(code); + +/* + Value of codeLines will be + [ + "var a = 1;", + "var b = 2;" + ] + */ +``` + +--- + +## Linter + +The `Linter` object does the actual evaluation of the JavaScript code. It doesn't do any filesystem operations, it simply parses and reports on the code. In particular, the `Linter` object does not process configuration objects or files. +The `Linter` is a constructor, and you can create a new instance by passing in the options you want to use. The available options are: + +* `cwd` - Path to a directory that should be considered as the current working directory. It is accessible to rules by calling `context.getCwd()` (see [The Context Object](./working-with-rules#the-context-object)). If `cwd` is `undefined`, it will be normalized to `process.cwd()` if the global `process` object is defined (for example, in the Node.js runtime) , or `undefined` otherwise. + +For example: + +```js +const Linter = require("eslint").Linter; +const linter1 = new Linter({ cwd: 'path/to/project' }); +const linter2 = new Linter(); +``` + +In this example, rules run on `linter1` will get `path/to/project` when calling `context.getCwd()`. +Those run on `linter2` will get `process.cwd()` if the global `process` object is defined or `undefined` otherwise (e.g. on the browser https://eslint.org/demo). + +### Linter#verify + +The most important method on `Linter` is `verify()`, which initiates linting of the given text. This method accepts three arguments: + +* `code` - the source code to lint (a string or instance of `SourceCode`). +* `config` - a configuration object that has been processed and normalized by `ESLint` using eslintrc files and/or other configuration arguments. + * **Note**: If you want to lint text and have your configuration be read and processed, use [`ESLint#lintFiles()`][eslint-lintfiles] or [`ESLint#lintText()`][eslint-linttext] instead. +* `options` - (optional) Additional options for this run. + * `filename` - (optional) the filename to associate with the source code. + * `preprocess` - (optional) A function that [Processors in Plugins](/docs/developer-guide/working-with-plugins#processors-in-plugins) documentation describes as the `preprocess` method. + * `postprocess` - (optional) A function that [Processors in Plugins](/docs/developer-guide/working-with-plugins#processors-in-plugins) documentation describes as the `postprocess` method. + * `filterCodeBlock` - (optional) A function that decides which code blocks the linter should adopt. The function receives two arguments. The first argument is the virtual filename of a code block. The second argument is the text of the code block. If the function returned `true` then the linter adopts the code block. If the function was omitted, the linter adopts only `*.js` code blocks. If you provided a `filterCodeBlock` function, it overrides this default behavior, so the linter doesn't adopt `*.js` code blocks automatically. + * `disableFixes` - (optional) when set to `true`, the linter doesn't make either the `fix` or `suggestions` property of the lint result. + * `allowInlineConfig` - (optional) set to `false` to disable inline comments from changing ESLint rules. + * `reportUnusedDisableDirectives` - (optional) when set to `true`, adds reported errors for unused `eslint-disable` directives when no problems would be reported in the disabled area anyway. + +If the third argument is a string, it is interpreted as the `filename`. + +You can call `verify()` like this: + +```js +const Linter = require("eslint").Linter; +const linter = new Linter(); + +const messages = linter.verify("var foo;", { + rules: { + semi: 2 + } +}, { filename: "foo.js" }); + +// or using SourceCode + +const Linter = require("eslint").Linter, + linter = new Linter(), + SourceCode = require("eslint").SourceCode; + +const code = new SourceCode("var foo = bar;", ast); + +const messages = linter.verify(code, { + rules: { + semi: 2 + } +}, { filename: "foo.js" }); +``` + +The `verify()` method returns an array of objects containing information about the linting warnings and errors. Here's an example: + +```js +{ + fatal: false, + ruleId: "semi", + severity: 2, + line: 1, + column: 23, + message: "Expected a semicolon.", + fix: { + range: [1, 15], + text: ";" + } +} +``` + +The information available for each linting message is: + +* `column` - the column on which the error occurred. +* `fatal` - usually omitted, but will be set to true if there's a parsing error (not related to a rule). +* `line` - the line on which the error occurred. +* `message` - the message that should be output. +* `nodeType` - the node or token type that was reported with the problem. +* `ruleId` - the ID of the rule that triggered the messages (or null if `fatal` is true). +* `severity` - either 1 or 2, depending on your configuration. +* `endColumn` - the end column of the range on which the error occurred (this property is omitted if it's not range). +* `endLine` - the end line of the range on which the error occurred (this property is omitted if it's not range). +* `fix` - an object describing the fix for the problem (this property is omitted if no fix is available). +* `suggestions` - an array of objects describing possible lint fixes for editors to programmatically enable (see details in the [Working with Rules docs](./working-with-rules#providing-suggestions)). + +Linting message objects have a deprecated `source` property. This property **will be removed** from linting messages in an upcoming breaking release. If you depend on this property, you should now use the `SourceCode` instance provided by the linter. + +You can also get an instance of the `SourceCode` object used inside of `linter` by using the `getSourceCode()` method: + +```js +const Linter = require("eslint").Linter; +const linter = new Linter(); + +const messages = linter.verify("var foo = bar;", { + rules: { + semi: 2 + } +}, { filename: "foo.js" }); + +const code = linter.getSourceCode(); + +console.log(code.text); // "var foo = bar;" +``` + +In this way, you can retrieve the text and AST used for the last run of `linter.verify()`. + +### Linter#verifyAndFix() + +This method is similar to verify except that it also runs autofixing logic, similar to the `--fix` flag on the command line. The result object will contain the autofixed code, along with any remaining linting messages for the code that were not autofixed. + +```js +const Linter = require("eslint").Linter; +const linter = new Linter(); + +const messages = linter.verifyAndFix("var foo", { + rules: { + semi: 2 + } +}); +``` + +Output object from this method: + +```js +{ + fixed: true, + output: "var foo;", + messages: [] +} +``` + +The information available is: + +* `fixed` - True, if the code was fixed. +* `output` - Fixed code text (might be the same as input if no fixes were applied). +* `messages` - Collection of all messages for the given code (It has the same information as explained above under `verify` block). + +### Linter#defineRule + +Each `Linter` instance holds a map of rule names to loaded rule objects. By default, all ESLint core rules are loaded. If you want to use `Linter` with custom rules, you should use the `defineRule` method to register your rules by ID. + +```js +const Linter = require("eslint").Linter; +const linter = new Linter(); + +linter.defineRule("my-custom-rule", { + // (an ESLint rule) + + create(context) { + // ... + } +}); + +const results = linter.verify("// some source text", { rules: { "my-custom-rule": "error" } }); +``` + +### Linter#defineRules + +This is a convenience method similar to `Linter#defineRule`, except that it allows you to define many rules at once using an object. + +```js +const Linter = require("eslint").Linter; +const linter = new Linter(); + +linter.defineRules({ + "my-custom-rule": { /* an ESLint rule */ create() {} }, + "another-custom-rule": { /* an ESLint rule */ create() {} } +}); + +const results = linter.verify("// some source text", { + rules: { + "my-custom-rule": "error", + "another-custom-rule": "warn" + } +}); +``` + +### Linter#getRules + +This method returns a map of all loaded rules. + +```js +const Linter = require("eslint").Linter; +const linter = new Linter(); + +linter.getRules(); + +/* +Map { + 'accessor-pairs' => { meta: { docs: [Object], schema: [Array] }, create: [Function: create] }, + 'array-bracket-newline' => { meta: { docs: [Object], schema: [Array] }, create: [Function: create] }, + ... +} +*/ +``` + +### Linter#defineParser + +Each instance of `Linter` holds a map of custom parsers. If you want to define a parser programmatically, you can add this function +with the name of the parser as first argument and the [parser object](/docs/developer-guide/working-with-custom-parsers) as second argument. The default `"espree"` parser will already be loaded for every `Linter` instance. + +```js +const Linter = require("eslint").Linter; +const linter = new Linter(); + +linter.defineParser("my-custom-parser", { + parse(code, options) { + // ... + } +}); + +const results = linter.verify("// some source text", { parser: "my-custom-parser" }); +``` + +### Linter#version/Linter.version + +Each instance of `Linter` has a `version` property containing the semantic version number of ESLint that the `Linter` instance is from. + +```js +const Linter = require("eslint").Linter; +const linter = new Linter(); + +linter.version; // => '4.5.0' +``` + +There is also a `Linter.version` property that you can read without instantiating `Linter`: + +```js +const Linter = require("eslint").Linter; + +Linter.version; // => '4.5.0' +``` + +--- + +## RuleTester + +`eslint.RuleTester` is a utility to write tests for ESLint rules. It is used internally for the bundled rules that come with ESLint, and it can also be used by plugins. + +Example usage: + +```js +"use strict"; + +const rule = require("../../../lib/rules/my-rule"), + RuleTester = require("eslint").RuleTester; + +const ruleTester = new RuleTester(); + +ruleTester.run("my-rule", rule, { + valid: [ + { + code: "var foo = true", + options: [{ allowFoo: true }] + } + ], + + invalid: [ + { + code: "var invalidVariable = true", + errors: [{ message: "Unexpected invalid variable." }] + }, + { + code: "var invalidVariable = true", + errors: [{ message: /^Unexpected.+variable/ }] + } + ] +}); +``` + +The `RuleTester` constructor accepts an optional object argument, which can be used to specify defaults for your test cases. For example, if all of your test cases use ES2015, you can set it as a default: + +```js +const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2015 } }); +``` + +The `RuleTester#run()` method is used to run the tests. It should be passed the following arguments: + +* The name of the rule (string) +* The rule object itself (see ["working with rules"](./working-with-rules)) +* An object containing `valid` and `invalid` properties, each of which is an array containing test cases. + +A test case is an object with the following properties: + +* `code` (string, required): The source code that the rule should be run on +* `options` (array, optional): The options passed to the rule. The rule severity should not be included in this list. +* `filename` (string, optional): The filename for the given case (useful for rules that make assertions about filenames). +* `only` (boolean, optional): Run this case exclusively for debugging in supported test frameworks. + +In addition to the properties above, invalid test cases can also have the following properties: + +* `errors` (number or array, required): Asserts some properties of the errors that the rule is expected to produce when run on this code. If this is a number, asserts the number of errors produced. Otherwise, this should be a list of objects, each containing information about a single reported error. The following properties can be used for an error (all are optional): + * `message` (string/regexp): The message for the error + * `messageId` (string): The Id for the error. See [testing errors with messageId](#testing-errors-with-messageid) for details + * `data` (object): Placeholder data which can be used in combination with `messageId` + * `type` (string): The type of the reported AST node + * `line` (number): The 1-based line number of the reported location + * `column` (number): The 1-based column number of the reported location + * `endLine` (number): The 1-based line number of the end of the reported location + * `endColumn` (number): The 1-based column number of the end of the reported location + * `suggestions` (array): An array of objects with suggestion details to check. See [Testing Suggestions](#testing-suggestions) for details + + If a string is provided as an error instead of an object, the string is used to assert the `message` of the error. +* `output` (string, required if the rule fixes code): Asserts the output that will be produced when using this rule for a single pass of autofixing (e.g. with the `--fix` command line flag). If this is `null`, asserts that none of the reported problems suggest autofixes. + +Any additional properties of a test case will be passed directly to the linter as config options. For example, a test case can have a `parserOptions` property to configure parser behavior: + +```js +{ + code: "let foo;", + parserOptions: { ecmaVersion: 2015 } +} +``` + +If a valid test case only uses the `code` property, it can optionally be provided as a string containing the code, rather than an object with a `code` key. + +#### Testing errors with `messageId` + +If the rule under test uses `messageId`s, you can use `messageId` property in a test case to assert reported error's `messageId` instead of its `message`. + +```js +{ + code: "let foo;", + errors: [{ messageId: "unexpected" }] +} +``` + +For messages with placeholders, a test case can also use `data` property to additionally assert reported error's `message`. + +```js +{ + code: "let foo;", + errors: [{ messageId: "unexpected", data: { name: "foo" } }] +} +``` + +Please note that `data` in a test case does not assert `data` passed to `context.report`. Instead, it is used to form the expected message text which is then compared with the received `message`. + +#### Testing Suggestions + +Suggestions can be tested by defining a `suggestions` key on an errors object. The options to check for the suggestions are the following (all are optional): + +* `desc` (string): The suggestion `desc` value +* `messageId` (string): The suggestion `messageId` value for suggestions that use `messageId`s +* `data` (object): Placeholder data which can be used in combination with `messageId` +* `output` (string): A code string representing the result of applying the suggestion fix to the input code + +Example: + +```js +ruleTester.run("my-rule-for-no-foo", rule, { + valid: [], + invalid: [{ + code: "var foo;", + errors: [{ + suggestions: [{ + desc: "Rename identifier 'foo' to 'bar'", + output: "var bar;" + }] + }] + }] +}) +``` + +`messageId` and `data` properties in suggestion test objects work the same way as in error test objects. See [testing errors with messageId](#testing-errors-with-messageid) for details. + +```js +ruleTester.run("my-rule-for-no-foo", rule, { + valid: [], + invalid: [{ + code: "var foo;", + errors: [{ + suggestions: [{ + messageId: "renameFoo", + data: { newName: "bar" }, + output: "var bar;" + }] + }] + }] +}) +``` + +### Customizing RuleTester + +`RuleTester` depends on two functions to run tests: `describe` and `it`. These functions can come from various places: + +1. If `RuleTester.describe` and `RuleTester.it` have been set to function values, `RuleTester` will use `RuleTester.describe` and `RuleTester.it` to run tests. You can use this to customize the behavior of `RuleTester` to match a test framework that you're using. + + If `RuleTester.itOnly` has been set to a function value, `RuleTester` will call `RuleTester.itOnly` instead of `RuleTester.it` to run cases with `only: true`. If `RuleTester.itOnly` is not set but `RuleTester.it` has an `only` function property, `RuleTester` will fall back to `RuleTester.it.only`. + +2. Otherwise, if `describe` and `it` are present as globals, `RuleTester` will use `global.describe` and `global.it` to run tests and `global.it.only` to run cases with `only: true`. This allows `RuleTester` to work when using frameworks like [Mocha](https://mochajs.org/) without any additional configuration. +3. Otherwise, `RuleTester#run` will simply execute all of the tests in sequence, and will throw an error if one of them fails. This means you can simply execute a test file that calls `RuleTester.run` using `Node.js`, without needing a testing framework. + +`RuleTester#run` calls the `describe` function with two arguments: a string describing the rule, and a callback function. The callback calls the `it` function with a string describing the test case, and a test function. The test function will return successfully if the test passes, and throw an error if the test fails. The signature for `only` is the same as `it`. `RuleTester` calls either `it` or `only` for every case even when some cases have `only: true`, and the test framework is responsible for implementing test case exclusivity. (Note that this is the standard behavior for test suites when using frameworks like [Mocha](https://mochajs.org/); this information is only relevant if you plan to customize `RuleTester.describe`, `RuleTester.it`, or `RuleTester.itOnly`.) + +Example of customizing `RuleTester`: + +```js +"use strict"; + +const RuleTester = require("eslint").RuleTester, + test = require("my-test-runner"), + myRule = require("../../../lib/rules/my-rule"); + +RuleTester.describe = function(text, method) { + RuleTester.it.title = text; + return method.call(this); +}; + +RuleTester.it = function(text, method) { + test(RuleTester.it.title + ": " + text, method); +}; + +// then use RuleTester as documented + +const ruleTester = new RuleTester(); + +ruleTester.run("my-rule", myRule, { + valid: [ + // valid test cases + ], + invalid: [ + // invalid test cases + ] +}) +``` + +--- + +[configuration object]: ../user-guide/configuring +[builtin-formatters]: https://eslint.org/docs/user-guide/formatters/ +[thirdparty-formatters]: https://www.npmjs.com/search?q=eslintformatter +[eslint]: #eslint-class +[eslint-constructor]: #-new-eslintoptions +[eslint-lintfiles]: #-eslintlintfilespatterns +[eslint-linttext]: #-eslintlinttextcode-options +[eslint-getrulesmetaforresults]: #-eslintgetrulesmetaforresultsresults +[eslint-calculateconfigforfile]: #-eslintcalculateconfigforfilefilepath +[eslint-ispathignored]: #-eslintispathignoredfilepath +[eslint-loadformatter]: #-eslintloadformatternameorpath +[eslint-version]: #-eslintversion +[eslint-outputfixes]: #-eslintoutputfixesresults +[eslint-geterrorresults]: #-eslintgeterrorresultsresults +[lintresult]: #-lintresult-type +[lintmessage]: #-lintmessage-type +[editinfo]: #-editinfo-type +[formatter]: #-formatter-type +[linter]: #linter diff --git a/docs/8.0.0/developer-guide/scope-manager-interface.md b/docs/8.0.0/developer-guide/scope-manager-interface.md new file mode 100644 index 0000000000..dc805d15e1 --- /dev/null +++ b/docs/8.0.0/developer-guide/scope-manager-interface.md @@ -0,0 +1,394 @@ +--- +title: ScopeManager +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/developer-guide/scope-manager-interface.md + +--- + + +# ScopeManager + +This document was written based on the implementation of [eslint-scope](https://github.com/eslint/eslint-scope), a fork of [escope](https://github.com/estools/escope), and deprecates some members ESLint is not using. + +---- + +## ScopeManager interface + +`ScopeManager` object has all variable scopes. + +### Fields + +#### scopes + +* **Type:** `Scope[]` +* **Description:** All scopes. + +#### globalScope + +* **Type:** `Scope` +* **Description:** The root scope. + +### Methods + +#### acquire(node, inner = false) + +* **Parameters:** + * `node` (`ASTNode`) ... An AST node to get their scope. + * `inner` (`boolean`) ... If the node has multiple scope, this returns the outermost scope normally. If `inner` is `true` then this returns the innermost scope. Default is `false`. +* **Return type:** `Scope | null` +* **Description:** Get the scope of a given AST node. The gotten scope's `block` property is the node. This method never returns `function-expression-name` scope. If the node does not have their scope, this returns `null`. + +#### getDeclaredVariables(node) + +* **Parameters:** + * `node` (`ASTNode`) ... An AST node to get their variables. +* **Return type:** `Variable[]` +* **Description:** Get the variables that a given AST node defines. The gotten variables' `def[].node`/`def[].parent` property is the node. If the node does not define any variable, this returns an empty array. + +### Deprecated members + +Those members are defined but not used in ESLint. + +#### isModule() + +* **Parameters:** +* **Return type:** `boolean` +* **Description:** `true` if this program is module. + +#### isImpliedStrict() + +* **Parameters:** +* **Return type:** `boolean` +* **Description:** `true` if this program is strict mode implicitly. I.e., `options.impliedStrict === true`. + +#### isStrictModeSupported() + +* **Parameters:** +* **Return type:** `boolean` +* **Description:** `true` if this program supports strict mode. I.e., `options.ecmaVersion >= 5`. + +#### acquireAll(node) + +* **Parameters:** + * `node` (`ASTNode`) ... An AST node to get their scope. +* **Return type:** `Scope[] | null` +* **Description:** Get the scopes of a given AST node. The gotten scopes' `block` property is the node. If the node does not have their scope, this returns `null`. + +---- + +## Scope interface + +`Scope` object has all variables and references in the scope. + +### Fields + +#### type + +* **Type:** `string` +* **Description:** The type of this scope. This is one of `"block"`, `"catch"`, `"class"`, `"for"`, `"function"`, `"function-expression-name"`, `"global"`, `"module"`, `"switch"`, `"with"` + +#### isStrict + +* **Type:** `boolean` +* **Description:** `true` if this scope is strict mode. + +#### upper + +* **Type:** `Scope | null` +* **Description:** The parent scope. If this is the global scope then this property is `null`. + +#### childScopes + +* **Type:** `Scope[]` +* **Description:** The array of child scopes. This does not include grandchild scopes. + +#### variableScope + +* **Type:** `Scope` +* **Description:** The scope which hosts variables which are defined by `var` declarations. + +#### block + +* **Type:** `ASTNode` +* **Description:** The AST node which created this scope. + +#### variables + +* **Type:** `Variable[]` +* **Description:** The array of all variables which are defined on this scope. This does not include variables which are defined in child scopes. + +#### set + +* **Type:** `Map` +* **Description:** The map from variable names to variable objects. + +> I hope to rename `set` field or replace by a method. + +#### references + +* **Type:** `Reference[]` +* **Description:** The array of all references on this scope. This does not include references in child scopes. + +#### through + +* **Type:** `Reference[]` +* **Description:** The array of references which could not be resolved in this scope. + +#### functionExpressionScope + +* **Type:** `boolean` +* **Description:** `true` if this scope is `"function-expression-name"` scope. + +> I hope to deprecate `functionExpressionScope` field as replacing by `scope.type === "function-expression-name"`. + +### Deprecated members + +Those members are defined but not used in ESLint. + +#### taints + +* **Type:** `Map` +* **Description:** The map from variable names to `tainted` flag. + +#### dynamic + +* **Type:** `boolean` +* **Description:** `true` if this scope is dynamic. I.e., the type of this scope is `"global"` or `"with"`. + +#### directCallToEvalScope + +* **Type:** `boolean` +* **Description:** `true` if this scope contains `eval()` invocations. + +#### thisFound + +* **Type:** `boolean` +* **Description:** `true` if this scope contains `this`. + +#### resolve(node) + +* **Parameters:** + * `node` (`ASTNode`) ... An AST node to get their reference object. The type of the node must be `"Identifier"`. +* **Return type:** `Reference | null` +* **Description:** Returns `this.references.find(r => r.identifier === node)`. + +#### isStatic() + +* **Parameters:** +* **Return type:** `boolean` +* **Description:** Returns `!this.dynamic`. + +#### isArgumentsMaterialized() + +* **Parameters:** +* **Return type:** `boolean` +* **Description:** `true` if this is a `"function"` scope which has used `arguments` variable. + +#### isThisMaterialized() + +* **Parameters:** +* **Return type:** `boolean` +* **Description:** Returns `this.thisFound`. + +#### isUsedName(name) + +* **Parameters:** + * `name` (`string`) ... The name to check. +* **Return type:** `boolean` +* **Description:** `true` if a given name is used in variable names or reference names. + +---- + +## Variable interface + +`Variable` object is variable's information. + +### Fields + +#### name + +* **Type:** `string` +* **Description:** The name of this variable. + +#### identifiers + +* **Type:** `ASTNode[]` +* **Description:** The array of `Identifier` nodes which define this variable. If this variable is redeclared, this array includes two or more nodes. + +> I hope to deprecate `identifiers` field as replacing by `defs[].name` field. + +#### references + +* **Type:** `Reference[]` +* **Description:** The array of the references of this variable. + +#### defs + +* **Type:** `Definition[]` +* **Description:** The array of the definitions of this variable. + +### Deprecated members + +Those members are defined but not used in ESLint. + +#### tainted + +* **Type:** `boolean` +* **Description:** The `tainted` flag. (always `false`) + +#### stack + +* **Type:** `boolean` +* **Description:** The `stack` flag. (I'm not sure what this means.) + +---- + +## Reference interface + +`Reference` object is reference's information. + +### Fields + +#### identifier + +* **Type:** `ASTNode` +* **Description:** The `Identifier` node of this reference. + +#### from + +* **Type:** `Scope` +* **Description:** The `Scope` object that this reference is on. + +#### resolved + +* **Type:** `Variable | null` +* **Description:** The `Variable` object that this reference refers. If such variable was not defined, this is `null`. + +#### writeExpr + +* **Type:** `ASTNode | null` +* **Description:** The ASTNode object which is right-hand side. + +#### init + +* **Type:** `boolean` +* **Description:** `true` if this writing reference is a variable initializer or a default value. + +### Methods + +#### isWrite() + +* **Parameters:** +* **Return type:** `boolean` +* **Description:** `true` if this reference is writing. + +#### isRead() + +* **Parameters:** +* **Return type:** `boolean` +* **Description:** `true` if this reference is reading. + +#### isWriteOnly() + +* **Parameters:** +* **Return type:** `boolean` +* **Description:** `true` if this reference is writing but not reading. + +#### isReadOnly() + +* **Parameters:** +* **Return type:** `boolean` +* **Description:** `true` if this reference is reading but not writing. + +#### isReadWrite() + +* **Parameters:** +* **Return type:** `boolean` +* **Description:** `true` if this reference is reading and writing. + +### Deprecated members + +Those members are defined but not used in ESLint. + +#### tainted + +* **Type:** `boolean` +* **Description:** The `tainted` flag. (always `false`) + +#### flag + +* **Type:** `number` +* **Description:** `1` is reading, `2` is writing, `3` is reading/writing. + +#### partial + +* **Type:** `boolean` +* **Description:** The `partial` flag. + +#### isStatic() + +* **Parameters:** +* **Return type:** `boolean` +* **Description:** `true` if this reference is resolved statically. + +---- + +## Definition interface + +`Definition` object is variable definition's information. + +### Fields + +#### type + +* **Type:** `string` +* **Description:** The type of this definition. One of `"CatchClause"`, `"ClassName"`, `"FunctionName"`, `"ImplicitGlobalVariable"`, `"ImportBinding"`, `"Parameter"`, and `"Variable"`. + +#### name + +* **Type:** `ASTNode` +* **Description:** The `Identifier` node of this definition. + +#### node + +* **Type:** `ASTNode` +* **Description:** The enclosing node of the name. + +| type | node | +|:---------------------------|:-----| +| `"CatchClause"` | `CatchClause` +| `"ClassName"` | `ClassDeclaration` or `ClassExpression` +| `"FunctionName"` | `FunctionDeclaration` or `FunctionExpression` +| `"ImplicitGlobalVariable"` | `Program` +| `"ImportBinding"` | `ImportSpecifier`, `ImportDefaultSpecifier`, or `ImportNamespaceSpecifier` +| `"Parameter"` | `FunctionDeclaration`, `FunctionExpression`, or `ArrowFunctionExpression` +| `"Variable"` | `VariableDeclarator` + +#### parent + +* **Type:** `ASTNode | undefined | null` +* **Description:** The enclosing statement node of the name. + +| type | parent | +|:---------------------------|:-------| +| `"CatchClause"` | `null` +| `"ClassName"` | `null` +| `"FunctionName"` | `null` +| `"ImplicitGlobalVariable"` | `null` +| `"ImportBinding"` | `ImportDeclaration` +| `"Parameter"` | `null` +| `"Variable"` | `VariableDeclaration` + +### Deprecated members + +Those members are defined but not used in ESLint. + +#### index + +* **Type:** `number | undefined | null` +* **Description:** The index in the declaration statement. + +#### kind + +* **Type:** `string | undefined | null` +* **Description:** The kind of the declaration statement. diff --git a/docs/8.0.0/developer-guide/selectors.md b/docs/8.0.0/developer-guide/selectors.md new file mode 100644 index 0000000000..40a9650dbd --- /dev/null +++ b/docs/8.0.0/developer-guide/selectors.md @@ -0,0 +1,145 @@ +--- +title: Selectors +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/developer-guide/selectors.md + +--- + + +# Selectors + +Some rules and APIs allow the use of selectors to query an AST. This page is intended to: + +1. Explain what selectors are +1. Describe the syntax for creating selectors +1. Describe what selectors can be used for + +## What is a selector? + +A selector is a string that can be used to match nodes in an Abstract Syntax Tree (AST). This is useful for describing a particular syntax pattern in your code. + +The syntax for AST selectors is similar to the syntax for [CSS selectors](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors). If you've used CSS selectors before, the syntax for AST selectors should be easy to understand. + +The simplest selector is just a node type. A node type selector will match all nodes with the given type. For example, consider the following program: + +```js +var foo = 1; +bar.baz(); +``` + +The selector "`Identifier`" will match all `Identifier` nodes in the program. In this case, the selector will match the nodes for `foo`, `bar`, and `baz`. + +Selectors are not limited to matching against single node types. For example, the selector `VariableDeclarator > Identifier` will match all `Identifier` nodes that have a `VariableDeclarator` as a direct parent. In the program above, this will match the node for `foo`, but not the nodes for `bar` and `baz`. + +## What syntax can selectors have? + +The following selectors are supported: + +* AST node type: `ForStatement` +* wildcard (matches all nodes): `*` +* attribute existence: `[attr]` +* attribute value: `[attr="foo"]` or `[attr=123]` +* attribute regex: `[attr=/foo.*/]` (with some [known issues](#known-issues)) +* attribute conditions: `[attr!="foo"]`, `[attr>2]`, `[attr<3]`, `[attr>=2]`, or `[attr<=3]` +* nested attribute: `[attr.level2="foo"]` +* field: `FunctionDeclaration > Identifier.id` +* First or last child: `:first-child` or `:last-child` +* nth-child (no ax+b support): `:nth-child(2)` +* nth-last-child (no ax+b support): `:nth-last-child(1)` +* descendant: `FunctionExpression ReturnStatement` +* child: `UnaryExpression > Literal` +* following sibling: `VariableDeclaration ~ VariableDeclaration` +* adjacent sibling: `ArrayExpression > Literal + SpreadElement` +* negation: `:not(ForStatement)` +* matches-any: `:matches([attr] > :first-child, :last-child)` +* class of AST node: `:statement`, `:expression`, `:declaration`, `:function`, or `:pattern` + +This syntax is very powerful, and can be used to precisely select many syntactic patterns in your code. + +The examples in this section were adapted from the [esquery](https://github.com/estools/esquery) documentation. + +## What can selectors be used for? + +If you're writing custom ESLint rules, you might be interested in using selectors to examine specific parts of the AST. If you're configuring ESLint for your codebase, you might be interested in restricting particular syntax patterns with selectors. + +### Listening for selectors in rules + +When writing a custom ESLint rule, you can listen for nodes that match a particular selector as the AST is traversed. + +```js +module.exports = { + create(context) { + // ... + + return { + + // This listener will be called for all IfStatement nodes with blocks. + "IfStatement > BlockStatement": function(blockStatementNode) { + // ...your logic here + }, + + // This listener will be called for all function declarations with more than 3 parameters. + "FunctionDeclaration[params.length>3]": function(functionDeclarationNode) { + // ...your logic here + } + }; + } +}; +``` + +Adding `:exit` to the end of a selector will cause the listener to be called when the matching nodes are exited during traversal, rather than when they are entered. + +If two or more selectors match the same node, their listeners will be called in order of increasing specificity. The specificity of an AST selector is similar to the specificity of a CSS selector: + +* When comparing two selectors, the selector that contains more class selectors, attribute selectors, and pseudo-class selectors (excluding `:not()`) has higher specificity. +* If the class/attribute/pseudo-class count is tied, the selector that contains more node type selectors has higher specificity. + +If multiple selectors have equal specificity, their listeners will be called in alphabetical order for that node. + +### Restricting syntax with selectors + +With the [no-restricted-syntax](/docs/rules/no-restricted-syntax) rule, you can restrict the usage of particular syntax in your code. For example, you can use the following configuration to disallow using `if` statements that do not have block statements as their body: + +```json +{ + "rules": { + "no-restricted-syntax": ["error", "IfStatement > :not(BlockStatement).consequent"] + } +} +``` + +...or equivalently, you can use this configuration: + +```json +{ + "rules": { + "no-restricted-syntax": ["error", "IfStatement[consequent.type!='BlockStatement']"] + } +} +``` + +As another example, you can disallow calls to `require()`: + +```json +{ + "rules": { + "no-restricted-syntax": ["error", "CallExpression[callee.name='require']"] + } +} +``` + +Or you can enforce that calls to `setTimeout` always have two arguments: + +```json +{ + "rules": { + "no-restricted-syntax": ["error", "CallExpression[callee.name='setTimeout'][arguments.length!=2]"] + } +} +``` + +Using selectors in the `no-restricted-syntax` rule can give you a lot of control over problematic patterns in your codebase, without needing to write custom rules to detect each pattern. + +### Known issues + +Due to a [bug](https://github.com/estools/esquery/issues/68) in [esquery](https://github.com/estools/esquery), regular expressions that contain a forward-slash character `/` aren't properly parsed, so `[value=/some\/path/]` will be a syntax error. As a [workaround](https://github.com/estools/esquery/issues/68), you can replace the `/` character with its unicode counterpart, like so: `[value=/some\\u002Fpath/]`. diff --git a/docs/8.0.0/developer-guide/shareable-configs.md b/docs/8.0.0/developer-guide/shareable-configs.md new file mode 100644 index 0000000000..bc62fe1989 --- /dev/null +++ b/docs/8.0.0/developer-guide/shareable-configs.md @@ -0,0 +1,217 @@ +--- +title: Shareable Configs +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/developer-guide/shareable-configs.md + +--- + + +# Shareable Configs + +The configuration that you have in your `.eslintrc` file is an important part of your project, and as such, you may want to share it with other projects or people. Shareable configs allow you to publish your configuration settings on [npm](https://www.npmjs.com/) and have others download and use it in their ESLint projects. + +## Creating a Shareable Config + +Shareable configs are simply npm packages that export a configuration object. To start, [create a Node.js module](https://docs.npmjs.com/getting-started/creating-node-modules) like you normally would. Make sure the module name begins with `eslint-config-`, such as `eslint-config-myconfig`. + +npm [scoped modules](https://docs.npmjs.com/misc/scope) are also supported, by naming or prefixing the module with `@scope/eslint-config`, such as `@scope/eslint-config` or `@scope/eslint-config-myconfig`. + +Create a new `index.js` file and export an object containing your settings: + +```js +module.exports = { + + globals: { + MyGlobal: true + }, + + rules: { + semi: [2, "always"] + } + +}; +``` + +Since `index.js` is just JavaScript, you can optionally read these settings from a file or generate them dynamically. + +## Publishing a Shareable Config + +Once your shareable config is ready, you can [publish to npm](https://docs.npmjs.com/getting-started/publishing-npm-packages) to share with others. We recommend using the `eslint` and `eslintconfig` keywords so others can easily find your module. + +You should declare your dependency on ESLint in `package.json` using the [peerDependencies](https://docs.npmjs.com/files/package.json#peerdependencies) field. The recommended way to declare a dependency for future proof compatibility is with the ">=" range syntax, using the lowest required ESLint version. For example: + +``` +"peerDependencies": { + "eslint": ">= 3" +} +``` + +If your shareable config depends on a plugin, you should also specify it as a `peerDependency` (plugins will be loaded relative to the end user's project, so the end user is required to install the plugins they need). However, if your shareable config depends on a third-party parser or another shareable config, you can specify these packages as `dependencies`. + +You can also test your shareable config on your computer before publishing by linking your module globally. Type: + +```bash +npm link +``` + +Then, in your project that wants to use your shareable config, type: + +```bash +npm link eslint-config-myconfig +``` + +Be sure to replace `eslint-config-myconfig` with the actual name of your module. + +## Using a Shareable Config + +Shareable configs are designed to work with the `extends` feature of `.eslintrc` files. Instead of using a file path for the value of `extends`, use your module name. For example: + +```json +{ + "extends": "eslint-config-myconfig" +} +``` + +You can also omit the `eslint-config-` and it will be automatically assumed by ESLint: + +```json +{ + "extends": "myconfig" +} +``` + +### npm scoped modules + +npm [scoped modules](https://docs.npmjs.com/misc/scope) are also supported in a number of ways. + + +By using the module name: + +```json +{ + "extends": "@scope/eslint-config" +} +``` + +You can also omit the `eslint-config` and it will be automatically assumed by ESLint: + +```json +{ + "extends": "@scope" +} +``` + +The module name can also be customized, just note that when using [scoped modules](https://docs.npmjs.com/misc/scope) it is not possible to omit the `eslint-config-` prefix. Doing so would result in package naming conflicts, and thus in resolution errors in most of cases. For example a package named `@scope/eslint-config-myconfig` vs `@scope/myconfig`, since both are valid scoped package names, the configuration should be specified as: + +```json +{ + "extends": "@scope/eslint-config-myconfig" +} +``` + +You can override settings from the shareable config by adding them directly into your `.eslintrc` file. + +## Sharing Multiple Configs + +It's possible to share multiple configs in the same npm package. You can specify a default config for the package by following the directions in the first section. You can specify additional configs by simply adding a new file to your npm package and then referencing it from your ESLint config. + +As an example, you can create a file called `my-special-config.js` in the root of your npm package and export a config, such as: + +```js +module.exports = { + rules: { + quotes: [2, "double"] + } +}; +``` + +Then, assuming you're using the package name `eslint-config-myconfig`, you can access the additional config via: + +```json +{ + "extends": "myconfig/my-special-config" +} +``` + +When using [scoped modules](https://docs.npmjs.com/misc/scope) it is not possible to omit the `eslint-config` namespace. Doing so would result in resolution errors as explained above. Assuming the package name is `@scope/eslint-config`, the additional config can be accessed as: + +```json +{ + "extends": "@scope/eslint-config/my-special-config" +} +``` + +Note that you can leave off the `.js` from the filename. In this way, you can add as many additional configs to your package as you'd like. + +**Important:** We strongly recommend always including a default config for your plugin to avoid errors. + +## Local Config File Resolution + +If you need to make multiple configs that can extend from each other and live in different directories, you can create a single shareable config that handles this scenario. + +As an example, let's assume you're using the package name `eslint-config-myconfig` and your package looks something like this: + +```text +myconfig +├── index.js +└─┬ lib + ├── defaults.js + ├── dev.js + ├── ci.js + └─┬ ci + ├── frontend.js + ├── backend.js + └── common.js +``` + +In your `index.js` you can do something like this: + +```js +module.exports = require('./lib/ci.js'); +``` + +Now inside your package you have `/lib/defaults.js`, which contains: + +```js +module.exports = { + rules: { + 'no-console': 1 + } +}; +``` + +Inside your `/lib/ci.js` you have + +```js +module.exports = require('./ci/backend'); +``` + +Inside your `/lib/ci/common.js` + +```js +module.exports = { + rules: { + 'no-alert': 2 + }, + extends: 'myconfig/lib/defaults' +}; +``` + +Despite being in an entirely different directory, you'll see that all `extends` must use the full package path to the config file you wish to extend. + +Now inside your `/lib/ci/backend.js` + +```js +module.exports = { + rules: { + 'no-console': 1 + }, + extends: 'myconfig/lib/ci/common' +}; +``` + +In the last file, you'll once again see that to properly resolve your config, you'll need include the full package path. + +## Further Reading + +* [npm Developer Guide](https://docs.npmjs.com/misc/developers) diff --git a/docs/8.0.0/developer-guide/source-code.md b/docs/8.0.0/developer-guide/source-code.md new file mode 100644 index 0000000000..2f197587f6 --- /dev/null +++ b/docs/8.0.0/developer-guide/source-code.md @@ -0,0 +1,48 @@ +--- +title: Source Code +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/developer-guide/source-code.md + +--- + + +# Source Code + +ESLint is hosted at [GitHub](https://github.com/eslint/eslint) and uses [Git](https://git-scm.com/) for source control. In order to obtain the source code, you must first install Git on your system. Instructions for installing and setting up Git can be found at [https://help.github.com/articles/set-up-git/](https://help.github.com/articles/set-up-git/). + +If you simply want to create a local copy of the source to play with, you can clone the main repository using this command: + + git clone git://github.com/eslint/eslint.git + +If you're planning on contributing to ESLint, then it's a good idea to fork the repository. You can find instructions for forking a repository at [https://help.github.com/articles/fork-a-repo/](https://help.github.com/articles/fork-a-repo/). After forking the ESLint repository, you'll want to create a local copy of your fork. + +## Start Developing + +Before you can get started developing, you'll need to have a couple of things installed: + +* [Node.JS](https://nodejs.org) +* [npm](https://www.npmjs.com/) + +Once you have a local copy and have Node.JS and npm installed, you'll need to install the ESLint dependencies: + + cd eslint + npm install + +Now when you run `eslint`, it will be running your local copy and showing your changes. + +**Note:** It's a good idea to re-run `npm install` whenever you pull from the main repository to ensure you have the latest development dependencies. + +## Directory structure + +The ESLint directory and file structure is as follows: + +* `bin` - executable files that are available when ESLint is installed +* `conf` - default configuration information +* `docs` - documentation for the project +* `lib` - contains the source code + * `formatters` - all source files defining formatters + * `rules` - all source files defining rules +* `tests` - the main unit test folder + * `lib` - tests for the source code + * `formatters` - tests for the formatters + * `rules` - tests for the rules diff --git a/docs/8.0.0/developer-guide/unit-tests.md b/docs/8.0.0/developer-guide/unit-tests.md new file mode 100644 index 0000000000..468aa6f36b --- /dev/null +++ b/docs/8.0.0/developer-guide/unit-tests.md @@ -0,0 +1,47 @@ +--- +title: Unit Tests +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/developer-guide/unit-tests.md + +--- + + +# Unit Tests + +Most parts of ESLint have unit tests associated with them. Unit tests are written using [Mocha](https://mochajs.org/) and are required when making contributions to ESLint. You'll find all of the unit tests in the `tests` directory. + +When you first get the source code, you need to run `npm install` once initially to set ESLint for development. Once you've done that, you can run the tests via: + + npm test + +This automatically starts Mocha and runs all tests in the `tests` directory. You need only add yours and it will automatically be picked up when running tests. + +## Running Individual Tests + +If you want to quickly run just one test file, you can do so by running Mocha directly and passing in the filename. For example: + + npm run test:cli tests/lib/rules/no-wrap-func.js + +If you want to run just one or a subset of `RuleTester` test cases, add `only: true` to each test case or wrap the test case in `RuleTester.only(...)` to add it automatically: + +```js +ruleTester.run("my-rule", myRule, { + valid: [ + RuleTester.only("const valid = 42;"), + // Other valid cases + ], + invalid: [ + { + code: "const invalid = 42;", + only: true, + }, + // Other invalid cases + ] +}) +``` + +Running individual tests is useful when you're working on a specific bug and iterating on the solution. You should be sure to run `npm test` before submitting a pull request. `npm test` uses Mocha's `--forbid-only` option to prevent `only` tests from passing full test runs. + +## More Control on Unit Testing + +`npm run test:cli` is an alias of the Mocha cli in `./node_modules/.bin/mocha`. [Options](https://mochajs.org/#command-line-usage) are available to be provided to help to better control the test to run. diff --git a/docs/8.0.0/developer-guide/working-with-custom-formatters.md b/docs/8.0.0/developer-guide/working-with-custom-formatters.md new file mode 100644 index 0000000000..edf2270ad6 --- /dev/null +++ b/docs/8.0.0/developer-guide/working-with-custom-formatters.md @@ -0,0 +1,376 @@ +--- +title: Working with Custom Formatters +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/developer-guide/working-with-custom-formatters.md + +--- + + +# Working with Custom Formatters + +While ESLint has some built-in formatters available to format the linting results, it's also possible to create and distribute your own custom formatters. You can include custom formatters in your project directly or create an npm package to distribute them separately. + +Each formatter is just a function that receives a `results` object and returns a string. For example, the following is how the `json` built-in formatter is implemented: + +```js +//my-awesome-formatter.js +module.exports = function(results) { + return JSON.stringify(results, null, 2); +}; +``` + +To run ESLint with this formatter, you can use the `-f` (or `--format`) command line flag: + +```bash +eslint -f ./my-awesome-formatter.js src/ +``` + +In order to use a local file as a custom formatter, you must begin the filename with a dot (such as `./my-awesome-formatter.js` or `../formatters/my-awesome-formatter.js`). + +### The `data` Argument + +The exported function receives an optional second argument named `data`. The `data` object provides extended information related to the analysis results. Currently, the `data` object consists of a single property named `rulesMeta`. This property is a dictionary of rule metadata, keyed with `ruleId`. The value for each entry is the `meta` property from the corresponding rule object. The dictionary contains an entry for each rule that was run during the analysis. + +Here's what the `data` object would look like if one rule, `no-extra-semi`, had been run: + +```js +{ + rulesMeta: { + "no-extra-semi": { + type: "suggestion", + docs: { + description: "disallow unnecessary semicolons", + category: "Possible Errors", + recommended: true, + url: "https://eslint.org/docs/rules/no-extra-semi" + }, + fixable: "code", + schema: [], + messages: { + unexpected: "Unnecessary semicolon." + } + } + } +} +``` + +The [Using Rule metadata](#using-rule-metadata) example shows how to use the `data` object in a custom formatter. See the [Working with Rules](https://eslint.org/docs/developer-guide/working-with-rules) page for more information about rules. + +## Packaging the Custom Formatter + +Custom formatters can also be distributed through npm packages. To do so, create an npm package with a name in the format of `eslint-formatter-*`, where `*` is the name of your formatter (such as `eslint-formatter-awesome`). Projects should then install the package and can use the custom formatter with the `-f` (or `--format`) flag like this: + +```bash +eslint -f awesome src/ +``` + +Because ESLint knows to look for packages beginning with `eslint-formatter-` when the specified formatter doesn't begin with a dot, there is no need to type `eslint-formatter-` when using a packaged custom formatter. + +Tips for `package.json`: + +* The `main` entry should be the JavaScript file implementing your custom formatter. +* Add these `keywords` to help users find your formatter: + * `"eslint"` + * `"eslint-formatter"` + * `"eslintformatter"` + +See all [formatters on npm](https://www.npmjs.com/search?q=eslint-formatter); + +## The `results` Object + +The `results` object passed into a formatter is an array of objects containing the lint results for individual files. Here's some example output: + +```js +[ + { + filePath: "path/to/file.js", + messages: [ + { + ruleId: "curly", + severity: 2, + message: "Expected { after 'if' condition.", + line: 2, + column: 1, + nodeType: "IfStatement" + }, + { + ruleId: "no-process-exit", + severity: 2, + message: "Don't use process.exit(); throw an error instead.", + line: 3, + column: 1, + nodeType: "CallExpression" + } + ], + errorCount: 2, + warningCount: 0, + fixableErrorCount: 0, + fixableWarningCount: 0, + source: + "var err = doStuff();\nif (err) console.log('failed tests: ' + err);\nprocess.exit(1);\n" + }, + { + filePath: "Gruntfile.js", + messages: [], + errorCount: 0, + warningCount: 0, + fixableErrorCount: 0, + fixableWarningCount: 0 + } +] +``` + +### The `result` Object + + + +Each object in the `results` array is a `result` object. Each `result` object contains the path of the file that was linted and information about linting issues that were encountered. Here are the properties available on each `result` object: + +* **filePath**: The absolute path to the file that was linted. +* **messages**: An array of `message` objects. See below for more info about messages. +* **errorCount**: The number of errors for the given file. +* **warningCount**: The number of warnings for the given file. +* **source**: The source code for the given file. This property is omitted if this file has no errors/warnings or if the `output` property is present. +* **output**: The source code for the given file with as many fixes applied as possible. This property is omitted if no fix is available. + +### The `message` Object + +Each `message` object contains information about the ESLint rule that was triggered by some source code. The properties available on each `message` object are: + +* **ruleId**: the ID of the rule that produced the error or warning. +* **severity**: the severity of the failure, `1` for warnings and `2` for errors. +* **message**: the human readable description of the error. +* **line**: the line where the issue is located. +* **column**: the column where the issue is located. +* **nodeType**: the type of the node in the [AST](https://github.com/estree/estree/blob/master/spec.md#node-objects) + +## Examples + +### Summary formatter + +A formatter that only cares about the total count of errors and warnings will look like this: + +```javascript +module.exports = function(results) { + // accumulate the errors and warnings + var summary = results.reduce( + function(seq, current) { + seq.errors += current.errorCount; + seq.warnings += current.warningCount; + return seq; + }, + { errors: 0, warnings: 0 } + ); + + if (summary.errors > 0 || summary.warnings > 0) { + return ( + "Errors: " + + summary.errors + + ", Warnings: " + + summary.warnings + + "\n" + ); + } + + return ""; +}; +``` + +Running `eslint` with the previous custom formatter, + +```bash +eslint -f ./my-awesome-formatter.js src/ +``` + +Will produce the following output: + +```bash +Errors: 2, Warnings: 4 +``` + +### Detailed formatter + +A more complex report will look something like this: + +```javascript +module.exports = function(results, data) { + var results = results || []; + + var summary = results.reduce( + function(seq, current) { + current.messages.forEach(function(msg) { + var logMessage = { + filePath: current.filePath, + ruleId: msg.ruleId, + ruleUrl: data.rulesMeta[msg.ruleId].docs.url, + message: msg.message, + line: msg.line, + column: msg.column + }; + + if (msg.severity === 1) { + logMessage.type = "warning"; + seq.warnings.push(logMessage); + } + if (msg.severity === 2) { + logMessage.type = "error"; + seq.errors.push(logMessage); + } + }); + return seq; + }, + { + errors: [], + warnings: [] + } + ); + + if (summary.errors.length > 0 || summary.warnings.length > 0) { + var lines = summary.errors + .concat(summary.warnings) + .map(function(msg) { + return ( + "\n" + + msg.type + + " " + + msg.ruleId + (msg.ruleUrl ? " (" + msg.ruleUrl + ")" : "") + + "\n " + + msg.filePath + + ":" + + msg.line + + ":" + + msg.column + ); + }) + .join("\n"); + + return lines + "\n"; + } +}; +``` + +So running `eslint` with this custom formatter: + +```bash +eslint -f ./my-awesome-formatter.js src/ +``` + +The output will be + +```bash +error space-infix-ops (https://eslint.org/docs/rules/space-infix-ops) + src/configs/bundler.js:6:8 +error semi (https://eslint.org/docs/rules/semi) + src/configs/bundler.js:6:10 +warning no-unused-vars (https://eslint.org/docs/rules/no-unused-vars) + src/configs/bundler.js:5:6 +warning no-unused-vars (https://eslint.org/docs/rules/no-unused-vars) + src/configs/bundler.js:6:6 +warning no-shadow (https://eslint.org/docs/rules/no-shadow) + src/configs/bundler.js:65:32 +warning no-unused-vars (https://eslint.org/docs/rules/no-unused-vars) + src/configs/clean.js:3:6 +``` + +## Passing Arguments to Formatters + +While custom formatter do not receive arguments in addition to the results object, it is possible to pass additional data into formatters. + +## Using Environment Variables + +Custom formatters have access to environment variables and so can change their behavior based on environment variable data. Here's an example that uses a `AF_SKIP_WARNINGS` environment variable to determine whether or not to show warnings in the results: + +```js +module.exports = function(results) { + var skipWarnings = process.env.AF_SKIP_WARNINGS === "true"; //af stands for awesome-formatter + + var results = results || []; + var summary = results.reduce( + function(seq, current) { + current.messages.forEach(function(msg) { + var logMessage = { + filePath: current.filePath, + ruleId: msg.ruleId, + message: msg.message, + line: msg.line, + column: msg.column + }; + + if (msg.severity === 1) { + logMessage.type = "warning"; + seq.warnings.push(logMessage); + } + if (msg.severity === 2) { + logMessage.type = "error"; + seq.errors.push(logMessage); + } + }); + return seq; + }, + { + errors: [], + warnings: [] + } + ); + + if (summary.errors.length > 0 || summary.warnings.length > 0) { + var warnings = !skipWarnings ? summary.warnings : []; // skip the warnings in that case + + var lines = summary.errors + .concat(warnings) + .map(function(msg) { + return ( + "\n" + + msg.type + + " " + + msg.ruleId + + "\n " + + msg.filePath + + ":" + + msg.line + + ":" + + msg.column + ); + }) + .join("\n"); + + return lines + "\n"; + } +}; +``` + +You would run ESLint with this custom formatter and an environment variable set like this: + +```bash +AF_SKIP_WARNINGS=true eslint -f ./my-awesome-formatter.js src/ +``` + +The output would be: + +```bash +error space-infix-ops + src/configs/bundler.js:6:8 + +error semi + src/configs/bundler.js:6:10 +``` + + +### Complex Argument Passing + +If you find the custom formatter pattern doesn't provide enough options for the way you'd like to format ESLint results, the best option is to use ESLint's built-in [JSON formatter](https://eslint.org/docs/user-guide/formatters/) and pipe the output to a second program. For example: + +```bash +eslint -f json src/ | your-program-that-reads-JSON --option +``` + +In this example, the `your-program-that-reads-json` program can accept the raw JSON of ESLint results and process it before outputting its own format of the results. You can pass as many command line arguments to that program as are necessary to customize the output. + +## Note: Formatting for Terminals + +Modern terminals like [iTerm2](https://www.iterm2.com/) or [Guake](http://guake-project.org/) expect a specific results format to automatically open filenames when they are clicked. Most terminals support this format for that purpose: + +```bash +file:line:column +``` diff --git a/docs/8.0.0/developer-guide/working-with-custom-parsers.md b/docs/8.0.0/developer-guide/working-with-custom-parsers.md new file mode 100644 index 0000000000..cad255e2e1 --- /dev/null +++ b/docs/8.0.0/developer-guide/working-with-custom-parsers.md @@ -0,0 +1,81 @@ +--- +title: Working with Custom Parsers +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/developer-guide/working-with-custom-parsers.md + +--- + + +# Working with Custom Parsers + +If you want to use your own parser and provide additional capabilities for your rules, you can specify your own custom parser. If a `parseForESLint` method is exposed on the parser, this method will be used to parse the code. Otherwise, the `parse` method will be used. Both methods should take in the source code as the first argument, and an optional configuration object as the second argument (provided as `parserOptions` in a config file). The `parse` method should simply return the AST. The `parseForESLint` method should return an object that contains the required property `ast` and optional properties `services`, `scopeManager`, and `visitorKeys`. + +* `ast` should contain the AST. +* `services` can contain any parser-dependent services (such as type checkers for nodes). The value of the `services` property is available to rules as `context.parserServices`. Default is an empty object. +* `scopeManager` can be a [ScopeManager](./scope-manager-interface) object. Custom parsers can use customized scope analysis for experimental/enhancement syntaxes. Default is the `ScopeManager` object which is created by [eslint-scope](https://github.com/eslint/eslint-scope). + * Support for `scopeManager` was added in ESLint v4.14.0. ESLint versions which support `scopeManager` will provide an `eslintScopeManager: true` property in `parserOptions`, which can be used for feature detection. +* `visitorKeys` can be an object to customize AST traversal. The keys of the object are the type of AST nodes. Each value is an array of the property names which should be traversed. Default is [KEYS of `eslint-visitor-keys`](https://github.com/eslint/eslint-visitor-keys#evkkeys). + * Support for `visitorKeys` was added in ESLint v4.14.0. ESLint versions which support `visitorKeys` will provide an `eslintVisitorKeys: true` property in `parserOptions`, which can be used for feature detection. + +You can find an ESLint parser project [here](https://github.com/typescript-eslint/typescript-eslint). + +```json +{ + "parser": "./path/to/awesome-custom-parser.js" +} +``` + +```javascript +var espree = require("espree"); +// awesome-custom-parser.js +exports.parseForESLint = function(code, options) { + return { + ast: espree.parse(code, options), + services: { + foo: function() { + console.log("foo"); + } + }, + scopeManager: null, + visitorKeys: null + }; +}; + +``` + +## The AST specification + +The AST that custom parsers should create is based on [ESTree](https://github.com/estree/estree). The AST requires some additional properties about detail information of the source code. + +### All nodes: + +All nodes must have `range` property. + +* `range` (`number[]`) is an array of two numbers. Both numbers are a 0-based index which is the position in the array of source code characters. The first is the start position of the node, the second is the end position of the node. `code.slice(node.range[0], node.range[1])` must be the text of the node. This range does not include spaces/parentheses which are around the node. +* `loc` (`SourceLocation`) must not be `null`. [The `loc` property is defined as nullable by ESTree](https://github.com/estree/estree/blob/25834f7247d44d3156030f8e8a2d07644d771fdb/es5.md#node-objects), but ESLint requires this property. On the other hand, `SourceLocation#source` property can be `undefined`. ESLint does not use the `SourceLocation#source` property. + +The `parent` property of all nodes must be rewritable. ESLint sets each node's `parent` property to its parent node while traversing, before any rules have access to the AST. + +### The `Program` node: + +The `Program` node must have `tokens` and `comments` properties. Both properties are an array of the below Token interface. + +```ts +interface Token { + type: string; + loc: SourceLocation; + range: [number, number]; // See "All nodes:" section for details of `range` property. + value: string; +} +``` + +* `tokens` (`Token[]`) is the array of tokens which affect the behavior of programs. Arbitrary spaces can exist between tokens, so rules check the `Token#range` to detect spaces between tokens. This must be sorted by `Token#range[0]`. +* `comments` (`Token[]`) is the array of comment tokens. This must be sorted by `Token#range[0]`. + +The range indexes of all tokens and comments must not overlap with the range of other tokens and comments. + +### The `Literal` node: + +The `Literal` node must have `raw` property. + +* `raw` (`string`) is the source code of this literal. This is the same as `code.slice(node.range[0], node.range[1])`. diff --git a/docs/8.0.0/developer-guide/working-with-plugins.md b/docs/8.0.0/developer-guide/working-with-plugins.md new file mode 100644 index 0000000000..fe1b0ff65f --- /dev/null +++ b/docs/8.0.0/developer-guide/working-with-plugins.md @@ -0,0 +1,248 @@ +--- +title: Working with Plugins +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/developer-guide/working-with-plugins.md + +--- + + +# Working with Plugins + +Each plugin is an npm module with a name in the format of `eslint-plugin-`, such as `eslint-plugin-jquery`. You can also use scoped packages in the format of `@/eslint-plugin-` such as `@jquery/eslint-plugin-jquery` or even `@/eslint-plugin` such as `@jquery/eslint-plugin`. + +## Create a Plugin + +The easiest way to start creating a plugin is to use the [Yeoman generator](https://www.npmjs.com/package/generator-eslint). The generator will guide you through setting up the skeleton of a plugin. + +### Rules in Plugins + +Plugins can expose additional rules for use in ESLint. To do so, the plugin must export a `rules` object containing a key-value mapping of rule ID to rule. The rule ID does not have to follow any naming convention (so it can just be `dollar-sign`, for instance). + +```js +module.exports = { + rules: { + "dollar-sign": { + create: function (context) { + // rule implementation ... + } + } + } +}; +``` + +To use the rule in ESLint, you would use the unprefixed plugin name, followed by a slash, followed by the rule name. So if this plugin were named `eslint-plugin-myplugin`, then in your configuration you'd refer to the rule by the name `myplugin/dollar-sign`. Example: `"rules": {"myplugin/dollar-sign": 2}`. + +### Environments in Plugins + +Plugins can expose additional environments for use in ESLint. To do so, the plugin must export an `environments` object. The keys of the `environments` object are the names of the different environments provided and the values are the environment settings. For example: + +```js +module.exports = { + environments: { + jquery: { + globals: { + $: false + } + } + } +}; +``` + +There's a `jquery` environment defined in this plugin. To use the environment in ESLint, you would use the unprefixed plugin name, followed by a slash, followed by the environment name. So if this plugin were named `eslint-plugin-myplugin`, then you would set the environment in your configuration to be `"myplugin/jquery"`. + +Plugin environments can define the following objects: + +1. `globals` - acts the same `globals` in a configuration file. The keys are the names of the globals and the values are `true` to allow the global to be overwritten and `false` to disallow. +1. `parserOptions` - acts the same as `parserOptions` in a configuration file. + +### Processors in Plugins + +You can also create plugins that would tell ESLint how to process files other than JavaScript. In order to create a processor, the object that is exported from your module has to conform to the following interface: + +```js +module.exports = { + processors: { + "processor-name": { + // takes text of the file and filename + preprocess: function(text, filename) { + // here, you can strip out any non-JS content + // and split into multiple strings to lint + + return [ // return an array of code blocks to lint + { text: code1, filename: "0.js" }, + { text: code2, filename: "1.js" }, + ]; + }, + + // takes a Message[][] and filename + postprocess: function(messages, filename) { + // `messages` argument contains two-dimensional array of Message objects + // where each top-level array item contains array of lint messages related + // to the text that was returned in array from preprocess() method + + // you need to return a one-dimensional array of the messages you want to keep + return [].concat(...messages); + }, + + supportsAutofix: true // (optional, defaults to false) + } + } +}; +``` + +**The `preprocess` method** takes the file contents and filename as arguments, and returns an array of code blocks to lint. The code blocks will be linted separately but still be registered to the filename. + +A code block has two properties `text` and `filename`; the `text` property is the content of the block and the `filename` property is the name of the block. Name of the block can be anything, but should include the file extension, that would tell the linter how to process the current block. The linter will check [`--ext` CLI option](../user-guide/command-line-interface#--ext) to see if the current block should be linted, and resolve `overrides` configs to check how to process the current block. + +It's up to the plugin to decide if it needs to return just one part, or multiple pieces. For example in the case of processing `.html` files, you might want to return just one item in the array by combining all scripts, but for `.md` file where each JavaScript block might be independent, you can return multiple items. + +**The `postprocess` method** takes a two-dimensional array of arrays of lint messages and the filename. Each item in the input array corresponds to the part that was returned from the `preprocess` method. The `postprocess` method must adjust the locations of all errors to correspond to locations in the original, unprocessed code, and aggregate them into a single flat array and return it. + +Reported problems have the following location information: + +```typescript +{ + line: number, + column: number, + + endLine?: number, + endColumn?: number +} +``` + +By default, ESLint will not perform autofixes when a processor is used, even when the `--fix` flag is enabled on the command line. To allow ESLint to autofix code when using your processor, you should take the following additional steps: + +1. Update the `postprocess` method to additionally transform the `fix` property of reported problems. All autofixable problems will have a `fix` property, which is an object with the following schema: + + ```js + { + range: [number, number], + text: string + } + ``` + + The `range` property contains two indexes in the code, referring to the start and end location of a contiguous section of text that will be replaced. The `text` property refers to the text that will replace the given range. + + In the initial list of problems, the `fix` property will refer to a fix in the processed JavaScript. The `postprocess` method should transform the object to refer to a fix in the original, unprocessed file. + +2. Add a `supportsAutofix: true` property to the processor. + +You can have both rules and processors in a single plugin. You can also have multiple processors in one plugin. +To support multiple extensions, add each one to the `processors` element and point them to the same object. + +#### Specifying Processor in Config Files + +To use a processor, add its ID to a `processor` section in the config file. Processor ID is a concatenated string of plugin name and processor name with a slash as a separator. This can also be added to a `overrides` section of the config, to specify which processors should handle which files. + +For example: + +```yml +plugins: + - a-plugin +overrides: + - files: "*.md" + processor: a-plugin/markdown +``` + +See [Specifying Processor](../user-guide/configuring/plugins#specifying-processor) for details. + +#### File Extension-named Processor + +If a processor name starts with `.`, ESLint handles the processor as a **file extension-named processor** especially and applies the processor to the kind of files automatically. People don't need to specify the file extension-named processors in their config files. + +For example: + +```js +module.exports = { + processors: { + // This processor will be applied to `*.md` files automatically. + // Also, people can use this processor as "plugin-id/.md" explicitly. + ".md": { + preprocess(text, filename) { /* ... */ }, + postprocess(messageLists, filename) { /* ... */ } + } + } +} +``` + +### Configs in Plugins + +You can bundle configurations inside a plugin by specifying them under the `configs` key. This can be useful when you want to provide not just code style, but also some custom rules to support it. Multiple configurations are supported per plugin. Note that it is not possible to specify a default configuration for a given plugin and that users must specify in their configuration file when they want to use one. + +```js +// eslint-plugin-myPlugin + +module.exports = { + configs: { + myConfig: { + plugins: ["myPlugin"], + env: ["browser"], + rules: { + semi: "error", + "myPlugin/my-rule": "error", + "eslint-plugin-myPlugin/another-rule": "error" + } + }, + myOtherConfig: { + plugins: ["myPlugin"], + env: ["node"], + rules: { + "myPlugin/my-rule": "off", + "eslint-plugin-myPlugin/another-rule": "off", + "eslint-plugin-myPlugin/yet-another-rule": "error" + } + } + } +}; +``` + +If the example plugin above were called `eslint-plugin-myPlugin`, the `myConfig` and `myOtherConfig` configurations would then be usable by extending off of `"plugin:myPlugin/myConfig"` and `"plugin:myPlugin/myOtherConfig"`, respectively. + +```json +{ + "extends": ["plugin:myPlugin/myConfig"] +} + +``` + +**Note:** Please note that configuration will not enable any of the plugin's rules by default, and instead should be treated as a standalone config. This means that you must specify your plugin name in the `plugins` array as well as any rules you want to enable that are part of the plugin. Any plugin rules must be prefixed with the short or long plugin name. See [Configuring Plugins](../user-guide/configuring/plugins#configuring-plugins) for more information. + +### Peer Dependency + +To make clear that the plugin requires ESLint to work correctly you have to declare ESLint as a `peerDependency` in your `package.json`. +The plugin support was introduced in ESLint version `0.8.0`. Ensure the `peerDependency` points to ESLint `0.8.0` or later. + +```json +{ + "peerDependencies": { + "eslint": ">=0.8.0" + } +} +``` + +### Testing + +ESLint provides the [`RuleTester`](/docs/developer-guide/nodejs-api#ruletester) utility to make it easy to test the rules of your plugin. + +### Linting + +ESLint plugins should be linted too! It's suggested to lint your plugin with the `recommended` configurations of: + +* [eslint](https://www.npmjs.com/package/eslint) +* [eslint-plugin-eslint-plugin](https://www.npmjs.com/package/eslint-plugin-eslint-plugin) +* [eslint-plugin-node](https://www.npmjs.com/package/eslint-plugin-node) + +## Share Plugins + +In order to make your plugin available to the community you have to publish it on npm. + +Recommended keywords: + +* `eslint` +* `eslintplugin` + +Add these keywords into your `package.json` file to make it easy for others to find. + +## Further Reading + +* [npm Developer Guide](https://docs.npmjs.com/misc/developers) diff --git a/docs/8.0.0/developer-guide/working-with-rules-deprecated.md b/docs/8.0.0/developer-guide/working-with-rules-deprecated.md new file mode 100644 index 0000000000..0771847607 --- /dev/null +++ b/docs/8.0.0/developer-guide/working-with-rules-deprecated.md @@ -0,0 +1,585 @@ +--- +title: Working with Rules (Deprecated) +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/developer-guide/working-with-rules-deprecated.md + +--- + + +# Working with Rules (Deprecated) + +**Note:** This page covers the deprecated rule format for ESLint <= 2.13.1. [This is the most recent rule format](./working-with-rules). + +Each rule in ESLint has two files named with its identifier (for example, `no-extra-semi`). + +* in the `lib/rules` directory: a source file (for example, `no-extra-semi.js`) +* in the `tests/lib/rules` directory: a test file (for example, `no-extra-semi.js`) + +**Important:** If you submit a **core** rule to the ESLint repository, you **must** follow some conventions explained below. + +Here is the basic format of the source file for a rule: + +```js +/** + * @fileoverview Rule to disallow unnecessary semicolons + * @author Nicholas C. Zakas + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = function(context) { + return { + // callback functions + }; +}; + +module.exports.schema = []; // no options +``` + +## Rule Basics + +`schema` (array) specifies the [options](#options-schemas) so ESLint can prevent invalid [rule configurations](../user-guide/configuring/rules#configuring-rules) + +`create` (function) returns an object with methods that ESLint calls to "visit" nodes while traversing the abstract syntax tree (AST as defined by [ESTree](https://github.com/estree/estree)) of JavaScript code: + +* if a key is a node type, ESLint calls that **visitor** function while going **down** the tree +* if a key is a node type plus `:exit`, ESLint calls that **visitor** function while going **up** the tree +* if a key is an event name, ESLint calls that **handler** function for [code path analysis](./code-path-analysis) + +A rule can use the current node and its surrounding tree to report or fix problems. + +Here are methods for the [array-callback-return](../rules/array-callback-return) rule: + +```js +function checkLastSegment (node) { + // report problem for function if last code path segment is reachable +} + +module.exports = function(context) { + // declare the state of the rule + return { + ReturnStatement: function(node) { + // at a ReturnStatement node while going down + }, + // at a function expression node while going up: + "FunctionExpression:exit": checkLastSegment, + "ArrowFunctionExpression:exit": checkLastSegment, + onCodePathStart: function (codePath, node) { + // at the start of analyzing a code path + }, + onCodePathEnd: function(codePath, node) { + // at the end of analyzing a code path + } + }; +}; +``` + +## The Context Object + +The `context` object contains additional functionality that is helpful for rules to do their jobs. As the name implies, the `context` object contains information that is relevant to the context of the rule. The `context` object has the following properties: + +* `parserOptions` - the parser options configured for this run (more details [here](../user-guide/configuring/language-options#specifying-parser-options)). +* `id` - the rule ID. +* `options` - an array of rule options. +* `settings` - the `settings` from configuration. +* `parserPath` - the full path to the `parser` from configuration. + +Additionally, the `context` object has the following methods: + +* `getAncestors()` - returns an array of ancestor nodes based on the current traversal. +* `getDeclaredVariables(node)` - returns the declared variables on the given node. +* `getFilename()` - returns the filename associated with the source. +* `getScope()` - returns the current scope. +* `getSourceCode()` - returns a `SourceCode` object that you can use to work with the source that was passed to ESLint +* `markVariableAsUsed(name)` - marks the named variable in scope as used. This affects the [no-unused-vars](../rules/no-unused-vars) rule. +* `report(descriptor)` - reports a problem in the code. + +**Deprecated:** The following methods on the `context` object are deprecated. Please use the corresponding methods on `SourceCode` instead: + +* `getAllComments()` - returns an array of all comments in the source. Use `sourceCode.getAllComments()` instead. +* `getComments(node)` - returns the leading and trailing comments arrays for the given node. Use `sourceCode.getComments(node)` instead. +* `getFirstToken(node)` - returns the first token representing the given node. Use `sourceCode.getFirstToken(node)` instead. +* `getFirstTokens(node, count)` - returns the first `count` tokens representing the given node. Use `sourceCode.getFirstTokens(node, count)` instead. +* `getJSDocComment(node)` - returns the JSDoc comment for a given node or `null` if there is none. Use `sourceCode.getJSDocComment(node)` instead. +* `getLastToken(node)` - returns the last token representing the given node. Use `sourceCode.getLastToken(node)` instead. +* `getLastTokens(node, count)` - returns the last `count` tokens representing the given node. Use `sourceCode.getLastTokens(node, count)` instead. +* `getNodeByRangeIndex(index)` - returns the deepest node in the AST containing the given source index. Use `sourceCode.getNodeByRangeIndex(index)` instead. +* `getSource(node)` - returns the source code for the given node. Omit `node` to get the whole source. Use `sourceCode.getText(node)` instead. +* `getSourceLines()` - returns the entire source code split into an array of string lines. Use `sourceCode.lines` instead. +* `getTokenAfter(nodeOrToken)` - returns the first token after the given node or token. Use `sourceCode.getTokenAfter(nodeOrToken)` instead. +* `getTokenBefore(nodeOrToken)` - returns the first token before the given node or token. Use `sourceCode.getTokenBefore(nodeOrToken)` instead. +* `getTokenByRangeStart(index)` - returns the token whose range starts at the given index in the source. Use `sourceCode.getTokenByRangeStart(index)` instead. +* `getTokens(node)` - returns all tokens for the given node. Use `sourceCode.getTokens(node)` instead. +* `getTokensAfter(nodeOrToken, count)` - returns `count` tokens after the given node or token. Use `sourceCode.getTokensAfter(nodeOrToken, count)` instead. +* `getTokensBefore(nodeOrToken, count)` - returns `count` tokens before the given node or token. Use `sourceCode.getTokensBefore(nodeOrToken, count)` instead. +* `getTokensBetween(node1, node2)` - returns the tokens between two nodes. Use `sourceCode.getTokensBetween(node1, node2)` instead. +* `report(node, [location], message)` - reports a problem in the code. + +### context.report() + +The main method you'll use is `context.report()`, which publishes a warning or error (depending on the configuration being used). This method accepts a single argument, which is an object containing the following properties: + +* `message` - the problem message. +* `node` - (optional) the AST node related to the problem. If present and `loc` is not specified, then the starting location of the node is used as the location of the problem. +* `loc` - (optional) an object specifying the location of the problem. If both `loc` and `node` are specified, then the location is used from `loc` instead of `node`. + * `line` - the 1-based line number at which the problem occurred. + * `column` - the 0-based column number at which the problem occurred. +* `data` - (optional) placeholder data for `message`. +* `fix` - (optional) a function that applies a fix to resolve the problem. + +Note that at least one of `node` or `loc` is required. + +The simplest example is to use just `node` and `message`: + +```js +context.report({ + node: node, + message: "Unexpected identifier" +}); +``` + +The node contains all of the information necessary to figure out the line and column number of the offending text as well the source text representing the node. + +You can also use placeholders in the message and provide `data`: + +```js +{% raw %} +context.report({ + node: node, + message: "Unexpected identifier: {{ identifier }}", + data: { + identifier: node.name + } +}); +{% endraw %} +``` + +Note that leading and trailing whitespace is optional in message parameters. + +The node contains all of the information necessary to figure out the line and column number of the offending text as well the source text representing the node. + +### Applying Fixes + +If you'd like ESLint to attempt to fix the problem you're reporting, you can do so by specifying the `fix` function when using `context.report()`. The `fix` function receives a single argument, a `fixer` object, that you can use to apply a fix. For example: + +```js +context.report({ + node: node, + message: "Missing semicolon". + fix: function(fixer) { + return fixer.insertTextAfter(node, ";"); + } +}); +``` + +Here, the `fix()` function is used to insert a semicolon after the node. Note that the fix is not immediately applied and may not be applied at all if there are conflicts with other fixes. If the fix cannot be applied, then the problem message is reported as usual; if the fix can be applied, then the problem message is not reported. + +The `fixer` object has the following methods: + +* `insertTextAfter(nodeOrToken, text)` - inserts text after the given node or token +* `insertTextAfterRange(range, text)` - inserts text after the given range +* `insertTextBefore(nodeOrToken, text)` - inserts text before the given node or token +* `insertTextBeforeRange(range, text)` - inserts text before the given range +* `remove(nodeOrToken)` - removes the given node or token +* `removeRange(range)` - removes text in the given range +* `replaceText(nodeOrToken, text)` - replaces the text in the given node or token +* `replaceTextRange(range, text)` - replaces the text in the given range + +Best practices for fixes: + +1. Make fixes that are as small as possible. Anything more than a single character is risky and could prevent other, simpler fixes from being made. +1. Only make one fix per message. This is enforced because you must return the result of the fixer operation from `fix()`. +1. Fixes should not introduce clashes with other rules. You can accidentally introduce a new problem that won't be reported until ESLint is run again. Another good reason to make as small a fix as possible. + +### context.options + +Some rules require options in order to function correctly. These options appear in configuration (`.eslintrc`, command line, or in comments). For example: + +```json +{ + "quotes": [2, "double"] +} +``` + +The `quotes` rule in this example has one option, `"double"` (the `2` is the error level). You can retrieve the options for a rule by using `context.options`, which is an array containing every configured option for the rule. In this case, `context.options[0]` would contain `"double"`: + +```js +module.exports = function(context) { + + var isDouble = (context.options[0] === "double"); + + // ... +} +``` + +Since `context.options` is just an array, you can use it to determine how many options have been passed as well as retrieving the actual options themselves. Keep in mind that the error level is not part of `context.options`, as the error level cannot be known or modified from inside a rule. + +When using options, make sure that your rule has some logic defaults in case the options are not provided. + +### context.getSourceCode() + +The `SourceCode` object is the main object for getting more information about the source code being linted. You can retrieve the `SourceCode` object at any time by using the `getSourceCode()` method: + +```js +module.exports = function(context) { + + var sourceCode = context.getSourceCode(); + + // ... +} +``` + +Once you have an instance of `SourceCode`, you can use the methods on it to work with the code: + +* `getAllComments()` - returns an array of all comments in the source. +* `getComments(node)` - returns the leading and trailing comments arrays for the given node. +* `getFirstToken(node)` - returns the first token representing the given node. +* `getFirstTokens(node, count)` - returns the first `count` tokens representing the given node. +* `getJSDocComment(node)` - returns the JSDoc comment for a given node or `null` if there is none. +* `getLastToken(node)` - returns the last token representing the given node. +* `getLastTokens(node, count)` - returns the last `count` tokens representing the given node. +* `getNodeByRangeIndex(index)` - returns the deepest node in the AST containing the given source index. +* `isSpaceBetweenTokens(first, second)` - returns true if there is a whitespace character between the two tokens. +* `getText(node)` - returns the source code for the given node. Omit `node` to get the whole source. +* `getTokenAfter(nodeOrToken)` - returns the first token after the given node or token. +* `getTokenBefore(nodeOrToken)` - returns the first token before the given node or token. +* `getTokenByRangeStart(index)` - returns the token whose range starts at the given index in the source. +* `getTokens(node)` - returns all tokens for the given node. +* `getTokensAfter(nodeOrToken, count)` - returns `count` tokens after the given node or token. +* `getTokensBefore(nodeOrToken, count)` - returns `count` tokens before the given node or token. +* `getTokensBetween(node1, node2)` - returns the tokens between two nodes. + +There are also some properties you can access: + +* `hasBOM` - the flag to indicate whether or not the source code has Unicode BOM. +* `text` - the full text of the code being linted. Unicode BOM has been stripped from this text. +* `ast` - the `Program` node of the AST for the code being linted. +* `lines` - an array of lines, split according to the specification's definition of line breaks. + +You should use a `SourceCode` object whenever you need to get more information about the code being linted. + +### Options Schemas + +Rules may export a `schema` property, which is a [JSON schema](http://json-schema.org/) format description of a rule's options which will be used by ESLint to validate configuration options and prevent invalid or unexpected inputs before they are passed to the rule in `context.options`. + +There are two formats for a rule's exported `schema`. The first is a full JSON Schema object describing all possible options the rule accepts, including the rule's error level as the first argument and any optional arguments thereafter. + +However, to simplify schema creation, rules may also export an array of schemas for each optional positional argument, and ESLint will automatically validate the required error level first. For example, the `yoda` rule accepts a primary mode argument, as well as an extra options object with named properties. + +```js +// "yoda": [2, "never", { "exceptRange": true }] +module.exports.schema = [ + { + "enum": ["always", "never"] + }, + { + "type": "object", + "properties": { + "exceptRange": { + "type": "boolean" + } + }, + "additionalProperties": false + } +]; +``` + +In the preceding example, the error level is assumed to be the first argument. It is followed by the first optional argument, a string which may be either `"always"` or `"never"`. The final optional argument is an object, which may have a Boolean property named `exceptRange`. + +To learn more about JSON Schema, we recommend looking at some [examples](http://json-schema.org/examples.html) to start, and also reading [Understanding JSON Schema](http://spacetelescope.github.io/understanding-json-schema/) (a free ebook). + +### Getting the Source + +If your rule needs to get the actual JavaScript source to work with, then use the `sourceCode.getText()` method. This method works as follows: + +```js + +// get all source +var source = sourceCode.getText(); + +// get source for just this AST node +var nodeSource = sourceCode.getText(node); + +// get source for AST node plus previous two characters +var nodeSourceWithPrev = sourceCode.getText(node, 2); + +// get source for AST node plus following two characters +var nodeSourceWithFollowing = sourceCode.getText(node, 0, 2); +``` + +In this way, you can look for patterns in the JavaScript text itself when the AST isn't providing the appropriate data (such as location of commas, semicolons, parentheses, etc.). + +### Accessing comments + +If you need to access comments for a specific node you can use `sourceCode.getComments(node)`: + +```js +// the "comments" variable has a "leading" and "trailing" property containing +// its leading and trailing comments, respectively +var comments = sourceCode.getComments(node); +``` + +Keep in mind that comments are technically not a part of the AST and are only attached to it on demand, i.e. when you call `getComments()`. + +**Note:** One of the libraries adds AST node properties for comments - do not use these properties. Always use `sourceCode.getComments()` as this is the only guaranteed API for accessing comments (we will likely change how comments are handled later). + +### Accessing Code Paths + +ESLint analyzes code paths while traversing AST. +You can access that code path objects with five events related to code paths. + +[details here](./code-path-analysis) + +## Rule Unit Tests + +Each rule must have a set of unit tests submitted with it to be accepted. The test file is named the same as the source file but lives in `tests/lib/`. For example, if your rule source file is `lib/rules/foo.js` then your test file should be `tests/lib/rules/foo.js`. + +For your rule, be sure to test: + +1. All instances that should be flagged as warnings. +1. At least one pattern that should **not** be flagged as a warning. + +The basic pattern for a rule unit test file is: + +```js +/** + * @fileoverview Tests for no-with rule. + * @author Nicholas C. Zakas + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +var rule = require("../../../lib/rules/no-with"), + RuleTester = require("../../../lib/testers/rule-tester"); + +//------------------------------------------------------------------------------ +// Tests +//------------------------------------------------------------------------------ + +var ruleTester = new RuleTester(); +ruleTester.run("no-with", rule, { + valid: [ + "foo.bar()" + ], + invalid: [ + { + code: "with(foo) { bar() }", + errors: [{ message: "Unexpected use of 'with' statement.", type: "WithStatement"}] + } + ] +}); +``` + +Be sure to replace the value of `"no-with"` with your rule's ID. There are plenty of examples in the `tests/lib/rules/` directory. + +### Valid Code + +Each valid case can be either a string or an object. The object form is used when you need to specify additional global variables or arguments for the rule. For example, the following defines `window` as a global variable for code that should not trigger the rule being tested: + +```js +valid: [ + { + code: "window.alert()", + globals: [ "window" ] + } +] +``` + +You can also pass options to the rule (if it accepts them). These arguments are equivalent to how people can configure rules in their `.eslintrc` file. For example: + +```js +valid: [ + { + code: "var msg = 'Hello';", + options: [ "single" ] + } +] +``` + +The `options` property must be an array of options. This gets passed through to `context.options` in the rule. + +### Invalid Code + +Each invalid case must be an object containing the code to test and at least one message that is produced by the rule. The `errors` key specifies an array of objects, each containing a message (your rule may trigger multiple messages for the same code). You should also specify the type of AST node you expect to receive back using the `type` key. The AST node should represent the actual spot in the code where there is a problem. For example: + +```js +invalid: [ + { + code: "function doSomething() { var f; if (true) { var build = true; } f = build; }", + errors: [ + { message: "build used outside of binding context.", type: "Identifier" } + ] + } +] +``` + +In this case, the message is specific to the variable being used and the AST node type is `Identifier`. + +Similar to the valid cases, you can also specify `options` to be passed to the rule: + +```js +invalid: [ + { + code: "function doSomething() { var f; if (true) { var build = true; } f = build; }", + options: [ "double" ], + errors: [ + { message: "build used outside of binding context.", type: "Identifier" } + ] + } +] +``` + +For simpler cases where the only thing that really matters is the error message, you can also specify any `errors` as strings. You can also have some strings and some objects, if you like. + +```js +invalid: [ + { + code: "'single quotes'", + options: ["double"], + errors: ["Strings must use doublequote."] + } +] +``` + +### Specifying Parser Options + +Some tests require that a certain parser configuration must be used. This can be specified in test specifications via the `parserOptions` setting. + +For example, to set `ecmaVersion` to 6 (in order to use constructs like `for ... of`): + +```js +valid: [ + { + code: "for (x of a) doSomething();", + parserOptions: { ecmaVersion: 6 } + } +] +``` + +If you are working with ES6 modules: + +```js +valid: [ + { + code: "export default function () {};", + parserOptions: { ecmaVersion: 6, sourceType: "module" } + } +] +``` + +For non-version specific features such as JSX: + +```js +valid: [ + { + code: "var foo =
    {bar}
    ", + parserOptions: { ecmaFeatures: { jsx: true } } + } +] +``` + +The options available and the expected syntax for `parserOptions` is the same as those used in [configuration](../user-guide/configuring/language-options#specifying-parser-options). + +### Write Several Tests + +Provide as many unit tests as possible. Your pull request will never be turned down for having too many tests submitted with it! + +## Performance Testing + +To keep the linting process efficient and unobtrusive, it is useful to verify the performance impact of new rules or modifications to existing rules. + +### Overall Performance + +The `npm run perf` command gives a high-level overview of ESLint running time with default rules (`eslint:recommended`) enabled. + +```bash +$ git checkout master +Switched to branch 'master' + +$ npm run perf +CPU Speed is 2200 with multiplier 7500000 +Performance Run #1: 1394.689313ms +Performance Run #2: 1423.295351ms +Performance Run #3: 1385.09515ms +Performance Run #4: 1382.406982ms +Performance Run #5: 1409.68566ms +Performance budget ok: 1394.689313ms (limit: 3409.090909090909ms) + +$ git checkout my-rule-branch +Switched to branch 'my-rule-branch' + +$ npm run perf +CPU Speed is 2200 with multiplier 7500000 +Performance Run #1: 1443.736547ms +Performance Run #2: 1419.193291ms +Performance Run #3: 1436.018228ms +Performance Run #4: 1473.605485ms +Performance Run #5: 1457.455283ms +Performance budget ok: 1443.736547ms (limit: 3409.090909090909ms) +``` + +### Per-rule Performance + +ESLint has a built-in method to track performance of individual rules. Setting the `TIMING` environment variable will trigger the display, upon linting completion, of the ten longest-running rules, along with their individual running time and relative performance impact as a percentage of total rule processing time. + +```bash +$ TIMING=1 eslint lib +Rule | Time (ms) | Relative +:-----------------------|----------:|--------: +no-multi-spaces | 52.472 | 6.1% +camelcase | 48.684 | 5.7% +no-irregular-whitespace | 43.847 | 5.1% +valid-jsdoc | 40.346 | 4.7% +handle-callback-err | 39.153 | 4.6% +space-infix-ops | 35.444 | 4.1% +no-undefined | 25.693 | 3.0% +no-shadow | 22.759 | 2.7% +no-empty-class | 21.976 | 2.6% +semi | 19.359 | 2.3% +``` + +To test one rule explicitly, combine the `--no-eslintrc`, and `--rule` options: + +```bash +$ TIMING=1 eslint --no-eslintrc --rule "quotes: [2, 'double']" lib +Rule | Time (ms) | Relative +:------|----------:|--------: +quotes | 18.066 | 100.0% +``` + +## Rule Naming Conventions + +The rule naming conventions for ESLint are fairly simple: + +* If your rule is disallowing something, prefix it with `no-` such as `no-eval` for disallowing `eval()` and `no-debugger` for disallowing `debugger`. +* If your rule is enforcing the inclusion of something, use a short name without a special prefix. +* Keep your rule names as short as possible, use abbreviations where appropriate, and no more than four words. +* Use dashes between words. + +## Rule Acceptance Criteria + +Because rules are highly personal (and therefore very contentious), accepted rules should: + +* Not be library-specific. +* Demonstrate a possible issue that can be resolved by rewriting the code. +* Be general enough so as to apply for a large number of developers. +* Not be the opposite of an existing rule. +* Not overlap with an existing rule. + +## Runtime Rules + +The thing that makes ESLint different from other linters is the ability to define custom rules at runtime. This is perfect for rules that are specific to your project or company and wouldn't make sense for ESLint to ship with. With runtime rules, you don't have to wait for the next version of ESLint or be disappointed that your rule isn't general enough to apply to the larger JavaScript community, just write your rules and include them at runtime. + +Runtime rules are written in the same format as all other rules. Create your rule as you would any other and then follow these steps: + +1. Place all of your runtime rules in the same directory (i.e., `eslint_rules`). +2. Create a [configuration file](../user-guide/configuring/) and specify your rule ID error level under the `rules` key. Your rule will not run unless it has a value of `1` or `2` in the configuration file. +3. Run the [command line interface](../user-guide/command-line-interface) using the `--rulesdir` option to specify the location of your runtime rules. diff --git a/docs/8.0.0/developer-guide/working-with-rules.md b/docs/8.0.0/developer-guide/working-with-rules.md new file mode 100644 index 0000000000..a67cf0f91d --- /dev/null +++ b/docs/8.0.0/developer-guide/working-with-rules.md @@ -0,0 +1,757 @@ +--- +title: Working with Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/developer-guide/working-with-rules.md + +--- + + +# Working with Rules + +**Note:** This page covers the most recent rule format for ESLint >= 3.0.0. There is also a [deprecated rule format](./working-with-rules-deprecated). + +Each rule in ESLint has three files named with its identifier (for example, `no-extra-semi`). + +* in the `lib/rules` directory: a source file (for example, `no-extra-semi.js`) +* in the `tests/lib/rules` directory: a test file (for example, `no-extra-semi.js`) +* in the `docs/rules` directory: a Markdown documentation file (for example, `no-extra-semi`) + +**Important:** If you submit a **core** rule to the ESLint repository, you **must** follow some conventions explained below. + +Here is the basic format of the source file for a rule: + +```js +/** + * @fileoverview Rule to disallow unnecessary semicolons + * @author Nicholas C. Zakas + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + type: "suggestion", + + docs: { + description: "disallow unnecessary semicolons", + category: "Possible Errors", + recommended: true, + url: "https://eslint.org/docs/rules/no-extra-semi" + }, + fixable: "code", + schema: [] // no options + }, + create: function(context) { + return { + // callback functions + }; + } +}; +``` + +## Rule Basics + +The source file for a rule exports an object with the following properties. + +`meta` (object) contains metadata for the rule: + +* `type` (string) indicates the type of rule, which is one of `"problem"`, `"suggestion"`, or `"layout"`: + * `"problem"` means the rule is identifying code that either will cause an error or may cause a confusing behavior. Developers should consider this a high priority to resolve. + * `"suggestion"` means the rule is identifying something that could be done in a better way but no errors will occur if the code isn't changed. + * `"layout"` means the rule cares primarily about whitespace, semicolons, commas, and parentheses, all the parts of the program that determine how the code looks rather than how it executes. These rules work on parts of the code that aren't specified in the AST. + +* `docs` (object) is required for core rules of ESLint: + + * `description` (string) provides the short description of the rule in the [rules index](../rules/) + * `category` (string) specifies the heading under which the rule is listed in the [rules index](../rules/) + * `recommended` (boolean) is whether the `"extends": "eslint:recommended"` property in a [configuration file](../user-guide/configuring/configuration-files#extending-configuration-files) enables the rule + * `url` (string) specifies the URL at which the full documentation can be accessed (enabling code editors to provide a helpful link on highlighted rule violations) + + In a custom rule or plugin, you can omit `docs` or include any properties that you need in it. + +* `fixable` (string) is either `"code"` or `"whitespace"` if the `--fix` option on the [command line](../user-guide/command-line-interface#--fix) automatically fixes problems reported by the rule + + **Important:** the `fixable` property is mandatory for fixable rules. If this property isn't specified, ESLint will throw an error whenever the rule attempts to produce a fix. Omit the `fixable` property if the rule is not fixable. + +* `hasSuggestions` (boolean) specifies whether rules can return suggestions (defaults to `false` if omitted) + + **Important:** the `hasSuggestions` property is mandatory for rules that provide suggestions. If this property isn't set to `true`, ESLint will throw an error whenever the rule attempts to produce a suggestion. Omit the `hasSuggestions` property if the rule does not provide suggestions. + +* `schema` (array) specifies the [options](#options-schemas) so ESLint can prevent invalid [rule configurations](../user-guide/configuring/rules#configuring-rules) + +* `deprecated` (boolean) indicates whether the rule has been deprecated. You may omit the `deprecated` property if the rule has not been deprecated. + +* `replacedBy` (array) in the case of a deprecated rule, specifies replacement rule(s) + +`create` (function) returns an object with methods that ESLint calls to "visit" nodes while traversing the abstract syntax tree (AST as defined by [ESTree](https://github.com/estree/estree)) of JavaScript code: + +* if a key is a node type or a [selector](./selectors), ESLint calls that **visitor** function while going **down** the tree +* if a key is a node type or a [selector](./selectors) plus `:exit`, ESLint calls that **visitor** function while going **up** the tree +* if a key is an event name, ESLint calls that **handler** function for [code path analysis](./code-path-analysis) + +A rule can use the current node and its surrounding tree to report or fix problems. + +Here are methods for the [array-callback-return](../rules/array-callback-return) rule: + +```js +function checkLastSegment (node) { + // report problem for function if last code path segment is reachable +} + +module.exports = { + meta: { ... }, + create: function(context) { + // declare the state of the rule + return { + ReturnStatement: function(node) { + // at a ReturnStatement node while going down + }, + // at a function expression node while going up: + "FunctionExpression:exit": checkLastSegment, + "ArrowFunctionExpression:exit": checkLastSegment, + onCodePathStart: function (codePath, node) { + // at the start of analyzing a code path + }, + onCodePathEnd: function(codePath, node) { + // at the end of analyzing a code path + } + }; + } +}; +``` + +## The Context Object + +The `context` object contains additional functionality that is helpful for rules to do their jobs. As the name implies, the `context` object contains information that is relevant to the context of the rule. The `context` object has the following properties: + +* `parserOptions` - the parser options configured for this run (more details [here](../user-guide/configuring/language-options#specifying-parser-options)). +* `id` - the rule ID. +* `options` - an array of the [configured options](/docs/user-guide/configuring/rules#configuring-rules) for this rule. This array does not include the rule severity. For more information, see [here](#contextoptions). +* `settings` - the [shared settings](/docs/user-guide/configuring/configuration-files#adding-shared-settings) from configuration. +* `parserPath` - the name of the `parser` from configuration. +* `parserServices` - an object containing parser-provided services for rules. The default parser does not provide any services. However, if a rule is intended to be used with a custom parser, it could use `parserServices` to access anything provided by that parser. (For example, a TypeScript parser could provide the ability to get the computed type of a given node.) + +Additionally, the `context` object has the following methods: + +* `getAncestors()` - returns an array of the ancestors of the currently-traversed node, starting at the root of the AST and continuing through the direct parent of the current node. This array does not include the currently-traversed node itself. +* `getCwd()` - returns the `cwd` passed to [Linter](./nodejs-api#linter). It is a path to a directory that should be considered as the current working directory. +* `getDeclaredVariables(node)` - returns a list of [variables](./scope-manager-interface#variable-interface) declared by the given node. This information can be used to track references to variables. + * If the node is a `VariableDeclaration`, all variables declared in the declaration are returned. + * If the node is a `VariableDeclarator`, all variables declared in the declarator are returned. + * If the node is a `FunctionDeclaration` or `FunctionExpression`, the variable for the function name is returned, in addition to variables for the function parameters. + * If the node is an `ArrowFunctionExpression`, variables for the parameters are returned. + * If the node is a `ClassDeclaration` or a `ClassExpression`, the variable for the class name is returned. + * If the node is a `CatchClause`, the variable for the exception is returned. + * If the node is an `ImportDeclaration`, variables for all of its specifiers are returned. + * If the node is an `ImportSpecifier`, `ImportDefaultSpecifier`, or `ImportNamespaceSpecifier`, the declared variable is returned. + * Otherwise, if the node does not declare any variables, an empty array is returned. +* `getFilename()` - returns the filename associated with the source. +* `getPhysicalFilename()` - when linting a file, it returns the full path of the file on disk without any code block information. When linting text, it returns the value passed to `—stdin-filename` or `` if not specified. +* `getScope()` - returns the [scope](./scope-manager-interface#scope-interface) of the currently-traversed node. This information can be used to track references to variables. +* `getSourceCode()` - returns a [`SourceCode`](#contextgetsourcecode) object that you can use to work with the source that was passed to ESLint. +* `markVariableAsUsed(name)` - marks a variable with the given name in the current scope as used. This affects the [no-unused-vars](../rules/no-unused-vars) rule. Returns `true` if a variable with the given name was found and marked as used, otherwise `false`. +* `report(descriptor)` - reports a problem in the code (see the [dedicated section](#contextreport)). + +**Note:** Earlier versions of ESLint supported additional methods on the `context` object. Those methods were removed in the new format and should not be relied upon. + +### context.getScope() + +This method returns the scope which has the following types: + +| AST Node Type | Scope Type | +|:--------------------------|:-----------| +| `Program` | `global` | +| `FunctionDeclaration` | `function` | +| `FunctionExpression` | `function` | +| `ArrowFunctionExpression` | `function` | +| `ClassDeclaration` | `class` | +| `ClassExpression` | `class` | +| `BlockStatement` ※1 | `block` | +| `SwitchStatement` ※1 | `switch` | +| `ForStatement` ※2 | `for` | +| `ForInStatement` ※2 | `for` | +| `ForOfStatement` ※2 | `for` | +| `WithStatement` | `with` | +| `CatchClause` | `catch` | +| others | ※3 | + +**※1** Only if the configured parser provided the block-scope feature. The default parser provides the block-scope feature if `parserOptions.ecmaVersion` is not less than `6`.
    +**※2** Only if the `for` statement defines the iteration variable as a block-scoped variable (E.g., `for (let i = 0;;) {}`).
    +**※3** The scope of the closest ancestor node which has own scope. If the closest ancestor node has multiple scopes then it chooses the innermost scope (E.g., the `Program` node has a `global` scope and a `module` scope if `Program#sourceType` is `"module"`. The innermost scope is the `module` scope.). + +The returned value is a [`Scope` object](scope-manager-interface) defined by the `eslint-scope` package. The `Variable` objects of global variables have some additional properties. + +* `variable.writeable` (`boolean | undefined`) ... If `true`, this global variable can be assigned arbitrary value. If `false`, this global variable is read-only. +* `variable.eslintExplicitGlobal` (`boolean | undefined`) ... If `true`, this global variable was defined by a `/* globals */` directive comment in the source code file. +* `variable.eslintExplicitGlobalComments` (`Comment[] | undefined`) ... The array of `/* globals */` directive comments which defined this global variable in the source code file. This property is `undefined` if there are no `/* globals */` directive comments. +* `variable.eslintImplicitGlobalSetting` (`"readonly" | "writable" | undefined`) ... The configured value in config files. This can be different from `variable.writeable` if there are `/* globals */` directive comments. + +### context.report() + +The main method you'll use is `context.report()`, which publishes a warning or error (depending on the configuration being used). This method accepts a single argument, which is an object containing the following properties: + +* `message` - the problem message. +* `node` - (optional) the AST node related to the problem. If present and `loc` is not specified, then the starting location of the node is used as the location of the problem. +* `loc` - (optional) an object specifying the location of the problem. If both `loc` and `node` are specified, then the location is used from `loc` instead of `node`. + * `start` - An object of the start location. + * `line` - the 1-based line number at which the problem occurred. + * `column` - the 0-based column number at which the problem occurred. + * `end` - An object of the end location. + * `line` - the 1-based line number at which the problem occurred. + * `column` - the 0-based column number at which the problem occurred. +* `data` - (optional) [placeholder](#using-message-placeholders) data for `message`. +* `fix` - (optional) a function that applies a [fix](#applying-fixes) to resolve the problem. + +Note that at least one of `node` or `loc` is required. + +The simplest example is to use just `node` and `message`: + +```js +context.report({ + node: node, + message: "Unexpected identifier" +}); +``` + +The node contains all of the information necessary to figure out the line and column number of the offending text as well the source text representing the node. + +### Using message placeholders + +You can also use placeholders in the message and provide `data`: + +```js +{% raw %} +context.report({ + node: node, + message: "Unexpected identifier: {{ identifier }}", + data: { + identifier: node.name + } +}); +{% endraw %} +``` + +Note that leading and trailing whitespace is optional in message parameters. + +The node contains all of the information necessary to figure out the line and column number of the offending text as well the source text representing the node. + +### `messageId`s + +Instead of typing out messages in both the `context.report()` call and your tests, you can use `messageId`s instead. + +This allows you to avoid retyping error messages. It also prevents errors reported in different sections of your rule from having out-of-date messages. + +```js +{% raw %} +// in your rule +module.exports = { + meta: { + messages: { + avoidName: "Avoid using variables named '{{ name }}'" + } + }, + create(context) { + return { + Identifier(node) { + if (node.name === "foo") { + context.report({ + node, + messageId: "avoidName", + data: { + name: "foo", + } + }); + } + } + }; + } +}; + +// in the file to lint: + +var foo = 2; +// ^ error: Avoid using variables named 'foo' + +// In your tests: +var rule = require("../../../lib/rules/my-rule"); +var RuleTester = require("eslint").RuleTester; + +var ruleTester = new RuleTester(); +ruleTester.run("my-rule", rule, { + valid: ["bar", "baz"], + invalid: [ + { + code: "foo", + errors: [ + { + messageId: "avoidName" + } + ] + } + ] +}); +{% endraw %} +``` + +### Applying Fixes + +If you'd like ESLint to attempt to fix the problem you're reporting, you can do so by specifying the `fix` function when using `context.report()`. The `fix` function receives a single argument, a `fixer` object, that you can use to apply a fix. For example: + +```js +context.report({ + node: node, + message: "Missing semicolon", + fix: function(fixer) { + return fixer.insertTextAfter(node, ";"); + } +}); +``` + +Here, the `fix()` function is used to insert a semicolon after the node. Note that a fix is not immediately applied, and may not be applied at all if there are conflicts with other fixes. After applying fixes, ESLint will run all of the enabled rules again on the fixed code, potentially applying more fixes. This process will repeat up to 10 times, or until no more fixable problems are found. Afterwards, any remaining problems will be reported as usual. + +**Important:** The `meta.fixable` property is mandatory for fixable rules. ESLint will throw an error if a rule that implements `fix` functions does not [export](#rule-basics) the `meta.fixable` property. + +The `fixer` object has the following methods: + +* `insertTextAfter(nodeOrToken, text)` - inserts text after the given node or token +* `insertTextAfterRange(range, text)` - inserts text after the given range +* `insertTextBefore(nodeOrToken, text)` - inserts text before the given node or token +* `insertTextBeforeRange(range, text)` - inserts text before the given range +* `remove(nodeOrToken)` - removes the given node or token +* `removeRange(range)` - removes text in the given range +* `replaceText(nodeOrToken, text)` - replaces the text in the given node or token +* `replaceTextRange(range, text)` - replaces the text in the given range + +The above methods return a `fixing` object. +The `fix()` function can return the following values: + +* A `fixing` object. +* An array which includes `fixing` objects. +* An iterable object which enumerates `fixing` objects. Especially, the `fix()` function can be a generator. + +If you make a `fix()` function which returns multiple `fixing` objects, those `fixing` objects must not be overlapped. + +Best practices for fixes: + +1. Avoid any fixes that could change the runtime behavior of code and cause it to stop working. +1. Make fixes as small as possible. Fixes that are unnecessarily large could conflict with other fixes, and prevent them from being applied. +1. Only make one fix per message. This is enforced because you must return the result of the fixer operation from `fix()`. +1. Since all rules are run again after the initial round of fixes is applied, it's not necessary for a rule to check whether the code style of a fix will cause errors to be reported by another rule. + * For example, suppose a fixer would like to surround an object key with quotes, but it's not sure whether the user would prefer single or double quotes. + + ```js + ({ foo : 1 }) + + // should get fixed to either + + ({ 'foo': 1 }) + + // or + + ({ "foo": 1 }) + ``` + + * This fixer can just select a quote type arbitrarily. If it guesses wrong, the resulting code will be automatically reported and fixed by the [`quotes`](/docs/rules/quotes) rule. + +### Providing Suggestions + +In some cases fixes aren't appropriate to be automatically applied, for example, if a fix potentially changes functionality or if there are multiple valid ways to fix a rule depending on the implementation intent (see the best practices for [applying fixes](#applying-fixes) listed above). In these cases, there is an alternative `suggest` option on `context.report()` that allows other tools, such as editors, to expose helpers for users to manually apply a suggestion. + +In order to provide suggestions, use the `suggest` key in the report argument with an array of suggestion objects. The suggestion objects represent individual suggestions that could be applied and require either a `desc` key string that describes what applying the suggestion would do or a `messageId` key (see [below](#suggestion-messageids)), and a `fix` key that is a function defining the suggestion result. This `fix` function follows the same API as regular fixes (described above in [applying fixes](#applying-fixes)). + +```js +{% raw %} +context.report({ + node: node, + message: "Unnecessary escape character: \\{{character}}.", + data: { character }, + suggest: [ + { + desc: "Remove the `\\`. This maintains the current functionality.", + fix: function(fixer) { + return fixer.removeRange(range); + } + }, + { + desc: "Replace the `\\` with `\\\\` to include the actual backslash character.", + fix: function(fixer) { + return fixer.insertTextBeforeRange(range, "\\"); + } + } + ] +}); +{% endraw %} +``` + +**Important:** The `meta.hasSuggestions` property is mandatory for rules that provide suggestions. ESLint will throw an error if a rule attempts to produce a suggestion but does not [export](#rule-basics) this property. + +Note: Suggestions will be applied as a stand-alone change, without triggering multipass fixes. Each suggestion should focus on a singular change in the code and should not try to conform to user defined styles. For example, if a suggestion is adding a new statement into the codebase, it should not try to match correct indentation, or conform to user preferences on presence/absence of semicolons. All of those things can be corrected by multipass autofix when the user triggers it. + +Best practices for suggestions: + +1. Don't try to do too much and suggest large refactors that could introduce a lot of breaking changes. +1. As noted above, don't try to conform to user-defined styles. + +Suggestions are intended to provide fixes. ESLint will automatically remove the whole suggestion from the linting output if the suggestion's `fix` function returned `null` or an empty array/sequence. + +#### Suggestion `messageId`s + +Instead of using a `desc` key for suggestions a `messageId` can be used instead. This works the same way as `messageId`s for the overall error (see [messageIds](#messageids)). Here is an example of how to use it in a rule: + +```js +{% raw %} +module.exports = { + meta: { + messages: { + unnecessaryEscape: "Unnecessary escape character: \\{{character}}.", + removeEscape: "Remove the `\\`. This maintains the current functionality.", + escapeBackslash: "Replace the `\\` with `\\\\` to include the actual backslash character." + }, + hasSuggestions: true + }, + create: function(context) { + // ... + context.report({ + node: node, + messageId: 'unnecessaryEscape', + data: { character }, + suggest: [ + { + messageId: "removeEscape", + fix: function(fixer) { + return fixer.removeRange(range); + } + }, + { + messageId: "escapeBackslash", + fix: function(fixer) { + return fixer.insertTextBeforeRange(range, "\\"); + } + } + ] + }); + } +}; +{% endraw %} +``` + +#### Placeholders in suggestion messages + +You can also use placeholders in the suggestion message. This works the same way as placeholders for the overall error (see [using message placeholders](#using-message-placeholders)). + +Please note that you have to provide `data` on the suggestion's object. Suggestion messages cannot use properties from the overall error's `data`. + +```js +{% raw %} +module.exports = { + meta: { + messages: { + unnecessaryEscape: "Unnecessary escape character: \\{{character}}.", + removeEscape: "Remove `\\` before {{character}}.", + }, + hasSuggestions: true + }, + create: function(context) { + // ... + context.report({ + node: node, + messageId: "unnecessaryEscape", + data: { character }, // data for the unnecessaryEscape overall message + suggest: [ + { + messageId: "removeEscape", + data: { character }, // data for the removeEscape suggestion message + fix: function(fixer) { + return fixer.removeRange(range); + } + } + ] + }); + } +}; +{% endraw %} +``` + +### context.options + +Some rules require options in order to function correctly. These options appear in configuration (`.eslintrc`, command line, or in comments). For example: + +```json +{ + "quotes": ["error", "double"] +} +``` + +The `quotes` rule in this example has one option, `"double"` (the `error` is the error level). You can retrieve the options for a rule by using `context.options`, which is an array containing every configured option for the rule. In this case, `context.options[0]` would contain `"double"`: + +```js +module.exports = { + create: function(context) { + var isDouble = (context.options[0] === "double"); + + // ... + } +}; +``` + +Since `context.options` is just an array, you can use it to determine how many options have been passed as well as retrieving the actual options themselves. Keep in mind that the error level is not part of `context.options`, as the error level cannot be known or modified from inside a rule. + +When using options, make sure that your rule has some logical defaults in case the options are not provided. + +### context.getSourceCode() + +The `SourceCode` object is the main object for getting more information about the source code being linted. You can retrieve the `SourceCode` object at any time by using the `getSourceCode()` method: + +```js +module.exports = { + create: function(context) { + var sourceCode = context.getSourceCode(); + + // ... + } +}; +``` + +Once you have an instance of `SourceCode`, you can use the methods on it to work with the code: + +* `getText(node)` - returns the source code for the given node. Omit `node` to get the whole source. +* `getAllComments()` - returns an array of all comments in the source. +* `getCommentsBefore(nodeOrToken)` - returns an array of comment tokens that occur directly before the given node or token. +* `getCommentsAfter(nodeOrToken)` - returns an array of comment tokens that occur directly after the given node or token. +* `getCommentsInside(node)` - returns an array of all comment tokens inside a given node. +* `getJSDocComment(node)` - returns the JSDoc comment for a given node or `null` if there is none. +* `isSpaceBetween(nodeOrToken, nodeOrToken)` - returns true if there is a whitespace character between the two tokens or, if given a node, the last token of the first node and the first token of the second node. +* `getFirstToken(node, skipOptions)` - returns the first token representing the given node. +* `getFirstTokens(node, countOptions)` - returns the first `count` tokens representing the given node. +* `getLastToken(node, skipOptions)` - returns the last token representing the given node. +* `getLastTokens(node, countOptions)` - returns the last `count` tokens representing the given node. +* `getTokenAfter(nodeOrToken, skipOptions)` - returns the first token after the given node or token. +* `getTokensAfter(nodeOrToken, countOptions)` - returns `count` tokens after the given node or token. +* `getTokenBefore(nodeOrToken, skipOptions)` - returns the first token before the given node or token. +* `getTokensBefore(nodeOrToken, countOptions)` - returns `count` tokens before the given node or token. +* `getFirstTokenBetween(nodeOrToken1, nodeOrToken2, skipOptions)` - returns the first token between two nodes or tokens. +* `getFirstTokensBetween(nodeOrToken1, nodeOrToken2, countOptions)` - returns the first `count` tokens between two nodes or tokens. +* `getLastTokenBetween(nodeOrToken1, nodeOrToken2, skipOptions)` - returns the last token between two nodes or tokens. +* `getLastTokensBetween(nodeOrToken1, nodeOrToken2, countOptions)` - returns the last `count` tokens between two nodes or tokens. +* `getTokens(node)` - returns all tokens for the given node. +* `getTokensBetween(nodeOrToken1, nodeOrToken2)` - returns all tokens between two nodes. +* `getTokenByRangeStart(index, rangeOptions)` - returns the token whose range starts at the given index in the source. +* `getNodeByRangeIndex(index)` - returns the deepest node in the AST containing the given source index. +* `getLocFromIndex(index)` - returns an object with `line` and `column` properties, corresponding to the location of the given source index. `line` is 1-based and `column` is 0-based. +* `getIndexFromLoc(loc)` - returns the index of a given location in the source code, where `loc` is an object with a 1-based `line` key and a 0-based `column` key. +* `commentsExistBetween(nodeOrToken1, nodeOrToken2)` - returns `true` if comments exist between two nodes. + +`skipOptions` is an object which has 3 properties; `skip`, `includeComments`, and `filter`. Default is `{skip: 0, includeComments: false, filter: null}`. + +* `skip` is a positive integer, the number of skipping tokens. If `filter` option is given at the same time, it doesn't count filtered tokens as skipped. +* `includeComments` is a boolean value, the flag to include comment tokens into the result. +* `filter` is a function which gets a token as the first argument, if the function returns `false` then the result excludes the token. + +`countOptions` is an object which has 3 properties; `count`, `includeComments`, and `filter`. Default is `{count: 0, includeComments: false, filter: null}`. + +* `count` is a positive integer, the maximum number of returning tokens. +* `includeComments` is a boolean value, the flag to include comment tokens into the result. +* `filter` is a function which gets a token as the first argument, if the function returns `false` then the result excludes the token. + +`rangeOptions` is an object which has 1 property: `includeComments`. + +* `includeComments` is a boolean value, the flag to include comment tokens into the result. + +There are also some properties you can access: + +* `hasBOM` - the flag to indicate whether or not the source code has Unicode BOM. +* `text` - the full text of the code being linted. Unicode BOM has been stripped from this text. +* `ast` - the `Program` node of the AST for the code being linted. +* `scopeManager` - the [ScopeManager](./scope-manager-interface#scopemanager-interface) object of the code. +* `visitorKeys` - the visitor keys to traverse this AST. +* `lines` - an array of lines, split according to the specification's definition of line breaks. + +You should use a `SourceCode` object whenever you need to get more information about the code being linted. + +#### Deprecated + +Please note that the following methods have been deprecated and will be removed in a future version of ESLint: + +* `getComments()` - replaced by `getCommentsBefore()`, `getCommentsAfter()`, and `getCommentsInside()` +* `getTokenOrCommentBefore()` - replaced by `getTokenBefore()` with the `{ includeComments: true }` option +* `getTokenOrCommentAfter()` - replaced by `getTokenAfter()` with the `{ includeComments: true }` option +* `isSpaceBetweenTokens()` - replaced by `isSpaceBetween()` + +### Options Schemas + +Rules may export a `schema` property, which is a [JSON schema](https://json-schema.org/) format description of a rule's options which will be used by ESLint to validate configuration options and prevent invalid or unexpected inputs before they are passed to the rule in `context.options`. + +There are two formats for a rule's exported `schema`. The first is a full JSON Schema object describing all possible options the rule accepts, including the rule's error level as the first argument and any optional arguments thereafter. + +However, to simplify schema creation, rules may also export an array of schemas for each optional positional argument, and ESLint will automatically validate the required error level first. For example, the `yoda` rule accepts a primary mode argument, as well as an extra options object with named properties. + +```js +// "yoda": [2, "never", { "exceptRange": true }] +module.exports = { + meta: { + schema: [ + { + "enum": ["always", "never"] + }, + { + "type": "object", + "properties": { + "exceptRange": { + "type": "boolean" + } + }, + "additionalProperties": false + } + ] + }, +}; +``` + +In the preceding example, the error level is assumed to be the first argument. It is followed by the first optional argument, a string which may be either `"always"` or `"never"`. The final optional argument is an object, which may have a Boolean property named `exceptRange`. + +To learn more about JSON Schema, we recommend looking at some examples in [website](https://json-schema.org/learn/) to start, and also reading [Understanding JSON Schema](https://json-schema.org/understanding-json-schema/) (a free ebook). + +**Note:** Currently you need to use full JSON Schema object rather than array in case your schema has references ($ref), because in case of array format ESLint transforms this array into a single schema without updating references that makes them incorrect (they are ignored). + +### Getting the Source + +If your rule needs to get the actual JavaScript source to work with, then use the `sourceCode.getText()` method. This method works as follows: + +```js + +// get all source +var source = sourceCode.getText(); + +// get source for just this AST node +var nodeSource = sourceCode.getText(node); + +// get source for AST node plus previous two characters +var nodeSourceWithPrev = sourceCode.getText(node, 2); + +// get source for AST node plus following two characters +var nodeSourceWithFollowing = sourceCode.getText(node, 0, 2); +``` + +In this way, you can look for patterns in the JavaScript text itself when the AST isn't providing the appropriate data (such as location of commas, semicolons, parentheses, etc.). + +### Accessing Comments + +While comments are not technically part of the AST, ESLint provides a few ways for rules to access them: + +#### sourceCode.getAllComments() + +This method returns an array of all the comments found in the program. This is useful for rules that need to check all comments regardless of location. + +#### sourceCode.getCommentsBefore(), sourceCode.getCommentsAfter(), and sourceCode.getCommentsInside() + +These methods return an array of comments that appear directly before, directly after, and inside nodes, respectively. They are useful for rules that need to check comments in relation to a given node or token. + +Keep in mind that the results of this method are calculated on demand. + +#### Token traversal methods + +Finally, comments can be accessed through many of `sourceCode`'s methods using the `includeComments` option. + +### Accessing Shebangs + +Shebangs are represented by tokens of type `"Shebang"`. They are treated as comments and can be accessed by the methods outlined above. + +### Accessing Code Paths + +ESLint analyzes code paths while traversing AST. +You can access that code path objects with five events related to code paths. + +[details here](./code-path-analysis) + +## Rule Unit Tests + +Each bundled rule for ESLint core must have a set of unit tests submitted with it to be accepted. The test file is named the same as the source file but lives in `tests/lib/`. For example, if the rule source file is `lib/rules/foo.js` then the test file should be `tests/lib/rules/foo.js`. + +ESLint provides the [`RuleTester`](/docs/developer-guide/nodejs-api#ruletester) utility to make it easy to write tests for rules. + +## Performance Testing + +To keep the linting process efficient and unobtrusive, it is useful to verify the performance impact of new rules or modifications to existing rules. + +### Overall Performance + +When developing in the ESLint core repository, the `npm run perf` command gives a high-level overview of ESLint running time with all core rules enabled. + +```bash +$ git checkout master +Switched to branch 'master' + +$ npm run perf +CPU Speed is 2200 with multiplier 7500000 +Performance Run #1: 1394.689313ms +Performance Run #2: 1423.295351ms +Performance Run #3: 1385.09515ms +Performance Run #4: 1382.406982ms +Performance Run #5: 1409.68566ms +Performance budget ok: 1394.689313ms (limit: 3409.090909090909ms) + +$ git checkout my-rule-branch +Switched to branch 'my-rule-branch' + +$ npm run perf +CPU Speed is 2200 with multiplier 7500000 +Performance Run #1: 1443.736547ms +Performance Run #2: 1419.193291ms +Performance Run #3: 1436.018228ms +Performance Run #4: 1473.605485ms +Performance Run #5: 1457.455283ms +Performance budget ok: 1443.736547ms (limit: 3409.090909090909ms) +``` + +### Per-rule Performance + +ESLint has a built-in method to track performance of individual rules. Setting the `TIMING` environment variable will trigger the display, upon linting completion, of the ten longest-running rules, along with their individual running time and relative performance impact as a percentage of total rule processing time. + +```bash +$ TIMING=1 eslint lib +Rule | Time (ms) | Relative +:-----------------------|----------:|--------: +no-multi-spaces | 52.472 | 6.1% +camelcase | 48.684 | 5.7% +no-irregular-whitespace | 43.847 | 5.1% +valid-jsdoc | 40.346 | 4.7% +handle-callback-err | 39.153 | 4.6% +space-infix-ops | 35.444 | 4.1% +no-undefined | 25.693 | 3.0% +no-shadow | 22.759 | 2.7% +no-empty-class | 21.976 | 2.6% +semi | 19.359 | 2.3% +``` + +To test one rule explicitly, combine the `--no-eslintrc`, and `--rule` options: + +```bash +$ TIMING=1 eslint --no-eslintrc --rule "quotes: [2, 'double']" lib +Rule | Time (ms) | Relative +:------|----------:|--------: +quotes | 18.066 | 100.0% +``` + +To see a longer list of results (more than 10), set the environment variable to another value such as `TIMING=50` or `TIMING=all`. + +## Rule Naming Conventions + +The rule naming conventions for ESLint are fairly simple: + +* If your rule is disallowing something, prefix it with `no-` such as `no-eval` for disallowing `eval()` and `no-debugger` for disallowing `debugger`. +* If your rule is enforcing the inclusion of something, use a short name without a special prefix. +* Use dashes between words. + +## Runtime Rules + +The thing that makes ESLint different from other linters is the ability to define custom rules at runtime. This is perfect for rules that are specific to your project or company and wouldn't make sense for ESLint to ship with. With runtime rules, you don't have to wait for the next version of ESLint or be disappointed that your rule isn't general enough to apply to the larger JavaScript community, just write your rules and include them at runtime. + +Runtime rules are written in the same format as all other rules. Create your rule as you would any other and then follow these steps: + +1. Place all of your runtime rules in the same directory (e.g., `eslint_rules`). +2. Create a [configuration file](../user-guide/configuring/) and specify your rule ID error level under the `rules` key. Your rule will not run unless it has a value of `"warn"` or `"error"` in the configuration file. +3. Run the [command line interface](../user-guide/command-line-interface) using the `--rulesdir` option to specify the location of your runtime rules. diff --git a/docs/8.0.0/index.md b/docs/8.0.0/index.md new file mode 100644 index 0000000000..ae63bc113b --- /dev/null +++ b/docs/8.0.0/index.md @@ -0,0 +1,25 @@ +--- +title: Documentation +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/README.md + +--- + + +# Documentation + +Welcome to our documentation pages! What would you like to view? + +## [User Guide](user-guide) + +Intended for end users of ESLint. Contains information about core rules, configuration, command line options, formatters, and integrations, +as well as guides for migrating from earlier versions of ESLint. + +## [Developer Guide](developer-guide) + +Intended for contributors to ESLint and people who wish to extend ESLint. Contains information about contributing to ESLint; creating custom +rules, configurations, plugins, and formatters; and information about our architecture and Node.js API. + +## [Maintainer Guide](maintainer-guide) + +Intended for maintainers of ESLint. diff --git a/docs/8.0.0/maintainer-guide/README.md b/docs/8.0.0/maintainer-guide/README.md new file mode 100644 index 0000000000..941ad55994 --- /dev/null +++ b/docs/8.0.0/maintainer-guide/README.md @@ -0,0 +1,23 @@ +# Maintainer Guide + +This guide is intended for those who work as part of the ESLint project team. + +## [Managing Issues](issues.md) + +Describes how to deal with issues when they're opened, when interacting with users, and how to close them effectively. + +## [Reviewing Pull Requests](pullrequests.md) + +Describes how to review incoming pull requests. + +## [Managing Releases](releases.md) + +Describes how to do an ESLint project release. + +## [Governance](governance.md) + +Describes the governance policy for ESLint, including the rights and privileges of individuals inside the project. + +## [Working Groups](working-groups.md) + +Describes how working groups are created and how they function within the ESLint project. diff --git a/docs/8.0.0/maintainer-guide/governance.md b/docs/8.0.0/maintainer-guide/governance.md new file mode 100644 index 0000000000..618db834e9 --- /dev/null +++ b/docs/8.0.0/maintainer-guide/governance.md @@ -0,0 +1,181 @@ +--- +title: Governance +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/maintainer-guide/governance.md + +--- + + +# Governance + +ESLint is an open source project that depends on contributions from the community. Anyone may contribute to the project at any time by submitting code, participating in discussions, making suggestions, or any other contribution they see fit. This document describes how various types of contributors work within the ESLint project. + +## Roles and Responsibilities + +### Users + +Users are community members who have a need for the project. Anyone can be a User; there are no special requirements. Common User contributions include evangelizing the project (e.g., display a link on a website and raise awareness through word-of-mouth), informing developers of strengths and weaknesses from a new user perspective, or providing moral support (a "thank you" goes a long way). + +Users who continue to engage with the project and its community will often become more and more involved. Such Users may find themselves becoming Contributors, as described in the next section. + +### Contributors + +Contributors are community members who contribute in concrete ways to the project, most often in the form of code and/or documentation. Anyone can become a Contributor, and contributions can take many forms. There is no expectation of commitment to the project, no specific skill requirements, and no selection process. + +Contributors have read-only access to source code and so submit changes via pull requests. Contributor pull requests have their contribution reviewed and merged by a TSC member. TSC members and Committers work with Contributors to review their code and prepare it for merging. + +As Contributors gain experience and familiarity with the project, their profile within, and commitment to, the community will increase. At some stage, they may find themselves being nominated for committership by an existing Committer. + +### Committers + +Committers are community members who have shown that they are committed to the continued development of the project through ongoing engagement with the community. Committers are given push access to the project's GitHub repos and must abide by the project's [Contribution Guidelines](../developer-guide/contributing). + +Committers: + +* Are expected to work on public branches of the source repository and submit pull requests from that branch to the master branch. +* Are expected to delete their public branches when they are no longer necessary. +* Must submit pull requests for all changes. +* Have their work reviewed by TSC members before acceptance into the repository. +* May label and close issues (see [Managing Issues](issues.html)) +* May merge some pull requests (see [Managing Pull Requests](pullrequests.html)) + +To become a Committer: + +* One must have shown a willingness and ability to participate in the project as a team player. Typically, a potential Committer will need to show that they have an understanding of and alignment with the project, its objectives, and its strategy. +* Committers are expected to be respectful of every community member and to work collaboratively in the spirit of inclusion. +* Have submitted a minimum of 10 qualifying pull requests. What's a qualifying pull request? One that carries significant technical weight and requires little effort to accept because it's well documented and tested. + +New Committers can be nominated by any existing Committer. Once they have been nominated, there will be a vote by the TSC members. + +It is important to recognize that committership is a privilege, not a right. That privilege must be earned and once earned it can be removed by the TSC members by a standard TSC motion. However, under normal circumstances committership exists for as long as the Committer wishes to continue engaging with the project. + +A Committer who shows an above-average level of contribution to the project, particularly with respect to its strategic direction and long-term health, may be nominated to become a reviewer, described below. + +#### Process for Adding Committers + +1. Send email congratulating the new committer and confirming that they would like to accept. This should also outline the responsibilities of a committer with a link to the maintainer guide. +1. Add the GitHub user to the "ESLint Team" team +1. Add committer email to the ESLint team mailing list +1. Invite to Discord team channel +1. Tweet congratulations to the new committer from the ESLint Twitter account + +### Reviewers + +Reviewers are community members who have contributed a significant amount of time to the project through triaging of issues, fixing bugs, implementing enhancements/features, and are trusted community leaders. + +Reviewers may perform all of the duties of Committers, and also: + +* May merge external pull requests for accepted issues upon reviewing and approving the changes. +* May merge their own pull requests once they have collected the feedback they deem necessary. (No pull request should be merged without at least one Committer/Reviewer/TSC member comment stating they've looked at the code.) + +To become a Reviewer: + +* Work in a helpful and collaborative way with the community. +* Have given good feedback on others' submissions and displayed an overall understanding of the code quality standards for the project. +* Commit to being a part of the community for the long-term. +* Have submitted a minimum of 50 qualifying pull requests. + +A Committer is invited to become a Reviewer by existing Reviewers and TSC members. A nomination will result in discussion and then a decision by the TSC. + +#### Process for Adding Reviewers + +1. Add the GitHub user to the "ESLint Reviewers" GitHub team +1. Tweet congratulations to the new Reviewer from the ESLint Twitter account + +### Technical Steering Committee (TSC) + +The ESLint project is jointly governed by a Technical Steering Committee (TSC) which is responsible for high-level guidance of the project. + +The TSC has final authority over this project including: + +* Technical direction +* Project governance and process (including this policy) +* Contribution policy +* GitHub repository hosting + +TSC seats are not time-limited. The size of the TSC can not be larger than five members. This size ensures adequate coverage of important areas of expertise balanced with the ability to make decisions efficiently. + +The TSC may add additional members to the TSC by a standard TSC motion. + +A TSC member may be removed from the TSC by voluntary resignation, by a standard TSC motion, or by missing four consecutive TSC meetings. In all cases, the TSC member will revert to Reviewer status unless they prefer Alumni status. + +Changes to TSC membership should be posted in the agenda, and may be suggested as any other agenda item (see "TSC Meetings" below). + +No more than 1/3 of the TSC members may be affiliated with the same employer. If removal or resignation of a TSC member, or a change of employment by a TSC member, creates a situation where more than 1/3 of the TSC membership shares an employer, then the situation must be immediately remedied by the resignation or removal of one or more TSC members affiliated with the over-represented employer(s). + +TSC members have additional responsibilities over and above those of a Reviewer. These responsibilities ensure the smooth running of the project. TSC members are expected to review code contributions, approve changes to this document, manage the copyrights within the project outputs, and attend regular TSC meetings. + +TSC members may perform all of the duties of Reviewers, and also: + +* May release new versions of all ESLint projects. +* May participate in TSC meetings. +* May propose budget items. +* May propose new ESLint projects. + +There is no specific set of requirements or qualifications for TSC members beyond those that are expected of Reviewers. + +A Reviewer is invited to become a TSC member by existing TSC members. A nomination will result in discussion and then a decision by the TSC. + +#### Process for Adding TSC Members + +1. Add the GitHub user to the "ESLint TSC" GitHub team +1. Set the GitHub user to be have the "Owner" role for the ESLint organization +1. Send a welcome email with a link to the [maintainer guide](./) and the [npm 2FA guide](./npm-2fa). +1. Invite to the Discord TSC channel +1. Make the TSC member an admin on the ESLint team mailing list +1. Add the TSC member to the recurring TSC meeting event on Google Calendar +1. Add the TSC member as an admin to ESLint Twitter Account on Tweetdeck +1. Add the TSC member to the ESLint TSC mailing list as an "Owner" +1. Tweet congratulations to the new TSC member from the ESLint Twitter account + +#### TSC Meetings + +The TSC meets every other week in the TSC Meeting [Discord](https://eslint.org/chat) channel. The meeting is run by a designated moderator approved by the TSC. + +Items are added to the TSC agenda which are considered contentious or +are modifications of governance, contribution policy, TSC membership, +or release process. + +The intention of the agenda is not to approve or review all patches. +That should happen continuously on GitHub and be handled by the larger +group of Committers. + +Any community member, Committer, or Reviewer can ask that something be added to +the next meeting's agenda by logging a GitHub Issue. Anyone can add the item to the agenda by adding +the "tsc agenda" tag to the issue. + +Prior to each TSC meeting, the moderator will share the Agenda with +members of the TSC. TSC members can add any items they like to the +agenda at the beginning of each meeting. The moderator and the TSC +cannot veto or remove items. + +No binding votes on TSC agenda items can take place without a quorum of +TSC members present in the meeting. Quorum is achieved when more than +half of the TSC members (minus non-attending members) are present. + +The TSC may invite persons or representatives from certain projects to +participate in a non-voting capacity. + +The moderator is responsible for summarizing the discussion of each +agenda item and sending it as a pull request after the meeting. + +## Consensus Seeking Process + +The TSC follows a +[Consensus Seeking](https://en.wikipedia.org/wiki/Consensus-seeking_decision-making) +decision making model. + +When an agenda item has appeared to reach a consensus, the moderator +will ask "Does anyone object?" as a final call for dissent from the +consensus. + +If an agenda item cannot reach a consensus, a TSC member can call for +either a closing vote or a vote to table the issue to the next +meeting. The call for a vote must be approved by a majority of the TSC +or else the discussion will continue. Simple majority wins. + +---- + +This work is a derivative of [YUI Contributor Model](https://github.com/yui/yui3/wiki/Contributor-Model) and the [Node.js Project Governance Model](https://github.com/nodejs/node/blob/master/GOVERNANCE.md). + +This work is licensed under a [Creative Commons Attribution-ShareAlike 2.0 UK: England & Wales License](https://creativecommons.org/licenses/by-sa/2.0/uk/). diff --git a/docs/8.0.0/maintainer-guide/index.md b/docs/8.0.0/maintainer-guide/index.md new file mode 100644 index 0000000000..5a9cb95056 --- /dev/null +++ b/docs/8.0.0/maintainer-guide/index.md @@ -0,0 +1,31 @@ +--- +title: Maintainer Guide +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/maintainer-guide/README.md + +--- + + +# Maintainer Guide + +This guide is intended for those who work as part of the ESLint project team. + +## [Managing Issues](issues) + +Describes how to deal with issues when they're opened, when interacting with users, and how to close them effectively. + +## [Reviewing Pull Requests](pullrequests) + +Describes how to review incoming pull requests. + +## [Managing Releases](releases) + +Describes how to do an ESLint project release. + +## [Governance](governance) + +Describes the governance policy for ESLint, including the rights and privileges of individuals inside the project. + +## [Working Groups](working-groups) + +Describes how working groups are created and how they function within the ESLint project. diff --git a/docs/8.0.0/maintainer-guide/issues.md b/docs/8.0.0/maintainer-guide/issues.md new file mode 100644 index 0000000000..4ee448bdac --- /dev/null +++ b/docs/8.0.0/maintainer-guide/issues.md @@ -0,0 +1,158 @@ +--- +title: Managing Issues +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/maintainer-guide/issues.md + +--- + + +# Managing Issues + +New issues are filed frequently, and how we respond to those issues directly affects the success of the project. Being part of the project team means helping to triage and address issues as they come in so the project can continue to run smoothly. + +## Things to Keep in Mind + +1. **Be nice.** Even if the people are being rude or aggressive on an issue, as a project team member you must be the mature one in the conversation. Do your best to work with everyone no matter their style. Remember, poor wording choice can also be a sign of someone who doesn't know English very well, so be sure to consider that when trying to determine the tone of someone's message. Being rude, even when someone is being rude to you, reflects poorly on the team and the project as a whole. +1. **Be inquisitive.** Ask questions on the issue whenever something isn't clear. Don't assume you understand what's being reported if there are details missing. Whenever you are unsure, it's best to ask for more information. +1. **Not all requests are equal.** It's unlikely we'll be able to accommodate every request, so don't be afraid to say that something doesn't fit into the scope of the project or isn't practical. It's better to give such feedback if that's the case. +1. **Close when appropriate.** Don't be afraid to close issues that you don't think will be done, or when it's become clear from the conversation that there's no further work to do. Issues can always be reopened if they are closed incorrectly, so feel free to close issues when appropriate. Just be sure to leave a comment explaining why the issue is being closed (if not closed by a commit). + +## Types of Issues + +There are four primary issue categories: + +1. **Bug** - something isn't working the way it's expected to work. +1. **Enhancement** - a change to something that already exists. For instance, adding a new option to an existing rule or a bug in a rule where fixing it will result in the rule reporting more problems (in this case, use both "Bug" and "Enhancement"). +1. **Feature** - adding something that doesn't already exist. For example, adding a new rule, new formatter, or new command line flag. +1. **Question** - an inquiry about how something works that won't result in a code change. We'd prefer if people use the mailing list or chatroom for questions, but sometimes they'll open an issue. + +The first goal when evaluating an issue is to determine which category the issue falls into. + +## Triaging Process + +All of ESLint's issues, across all GitHub repositories, are managed on our [Triage Project](https://github.com/orgs/eslint/projects/2). Please use the Triage project instead of the issues list when reviewing issues to determine what to work on. The Triage project has several columns: + +* **Needs Triage** - issues that have not yet been reviewed by anyone +* **Triaging** - issues that someone has reviewed but has not been able to fully triage yet +* **Ready for Dev Team** - issues that have been triaged and have all of the information necessary for the dev team to take a look +* **Evaluating** - the dev team is evaluating these issues to determine whether to move forward or not +* **Feedback Needed** - a team member is requesting more input from the rest of the team before proceeding +* **Waiting for RFC** - the next step in the process is for an RFC to be written +* **RFC Opened** - an RFC is opened to address these issues +* **Blocked** - the issue can't move forward due to some dependency +* **Ready to Implement** - these issues have all of the details necessary to start implementation +* **PR Opened** - there is an open pull request for each of these issues +* **Completed** - the issue has been closed (either via pull request merge or by the team manually closing the issue) + +We make every attempt to automate movement between as many columns as we can, but sometimes moving issues needs to be done manually. + +### When an Issue is Opened + +When an issue is opened, it is automatically added to the "Needs Triage" column in the Triage project. These issues need to be evaluated to determine next steps. Anyone on the support team or dev team can follow these steps to properly triage issues. + +**Note:** If an issue is in the "Triaging" column, that means someone is already triaging it and you should let them finish. There's no need to comment on issues in the "Triaging" column unless someone asks for help. + +The steps for triaging an issue are: + +1. Move the issue from "Needs Triage" to "Triaging" in the Triage project +1. Check: Has all of the information in the issue template been provided? + * **No:** If information is missing from the issue template, or you can't tell what is being requested, please ask the author to provide the missing information: + * Add the "needs info" label to the issue so we know that this issue is stalled due to lack of information. + * Don't move on to other steps until the necessary information has been provided. + * If the issue author hasn't provided the necessary information after 7 days, please close the issue. The bot will add a comment stating that the issue was closed because there was information missing. + * **Yes:** + * If the issue is actually a question (rather than something the dev team needs to change), please [convert it to a discussion](https://docs.github.com/en/free-pro-team@latest/discussions/managing-discussions-for-your-community/moderating-discussions#converting-an-issue-to-a-discussion). You can continue the conversation as a discussion. + * If the issue is reporting a bug, try to reproduce the issue following the instructions in the issue. If you can reproduce the bug, please add the "repro:yes" label. (The bot will automatically remove the "repro:needed" label.) If you can't reproduce the bug, ask the author for more information about their environment or to clarify reproduction steps. + * If the issue is reporting something that works as intended, please add the "works as intended" label and close the issue. + * For all issues, please add labels describing the part of ESLint affected: + * "3rd party plugin" - related to third-party functionality (plugins, parsers, rules, etc.) + * "build" - related to commands run during a build (testing, linting, release scripts, etc.) + * "cli" - related to command line input or output, or to `CLIEngine` + * "core" - related to internal APIs + * "documentation" - related to content on eslint.org + * "infrastructure" - related to resources needed for builds or deployment (VMs, CI tools, bots, etc.) + * "rule" - related to core rules + * If you can't properly triage the issue, move the issue back to the "Needs Triage" column in the Triage project so someone else can triage it + * If you have triaged the issue, move the issue to the "Ready for Dev Team" column in the Triage project + +## Evaluation Process + +When an issue has been moved to the "Ready for Dev Team" column, any dev team member can pick up the issue to start evaluating it. + +1. Move the issue into the "Evaluating" column. +1. Next steps: + * **Bugs:** if you can verify the bug, add the "accepted" label and ask if they would like to submit a pull request. + * **New Rules:** if you are willing to champion the rule (meaning you believe it should be included in ESLint core and you will take ownership of the process for including it), add a comment saying you will champion the issue, assign the issue to yourself, and follow the [guidelines](#championing-issues) below. + * **Rule Changes:** if you are willing to champion the change and it would not be a breaking change (requiring a major version increment), add a comment saying that you will champion the issue, assign the issue to yourself, and follow the [guidelines](#championing-issues) below. + * **Breaking Changes:** if you suspect or can verify that a change would be breaking, label it as "Breaking". + * **Duplicates:** if you can verify the issue is a duplicate, add a comment mentioning the duplicate issue (such as, "Duplicate of #1234") and close the issue. +1. Regardless of the above, always leave a comment. Don't just add labels, engage with the person who opened the issue by asking a question (request more information if necessary) or stating your opinion of the issue. If it's a verified bug, ask if the user would like to submit a pull request. +1. If the issue can't be implemented because it needs an external dependency to be updated or needs to wait for another issue to be resolved, move the issue to the "Blocked" column. +1. If the issue has been accepted and an RFC is required as the next step, move the issue to the "Waiting for RFC" column and comment on the issue that an RFC is needed. + +**Note:** "Good first issue" issues are intended to help new contributors feel welcome and empowered to make a contribution to ESLint. To ensure that new contributors are given a chance to work on these issues, issues labeled "good first issue" must be open for 30 days *from the day the issue was labeled* before a team member is permitted to work on them. + +## Accepting Issues + +Issues may be labeled as "accepted" when the issue is: + +* A bug that you've been able to reproduce and verify (i.e. you're sure it's a bug) +* A new rule or rule change that you're championing and [consensus](#consensus) has been reached for its inclusion in the project + +The "accepted" label will be added to other issues by a TSC member if it's appropriate for the roadmap. + +When an issue is accepted and implementation can begin, it should be moved to the "Ready to Implement" column. + +## Championing Issues + +New rules and rule changes require a champion. As champion, it's your job to: + +* Gain [consensus](#consensus) from the ESLint team on inclusion +* Guide the rule creation process until it's complete (so only champion a rule that you have time to implement or help another contributor implement) + +Once consensus has been reached on inclusion, add the "accepted" and, optionally, "help wanted" and "good first issue" labels, as necessary. + +## Consensus + +Consensus is reached on issues when there are at least three team members who believe the change is a good idea and no one who believes the change is a bad idea. In order to indicate your support for an issue, leave a +1 reaction (thumbs up) on the original issue description in addition to any comments you might have. + +## When to Send to TSC + +If consensus cannot be reached on an issue, or an issue's progress has been stalled and it's not clear if the issue should be closed, then you can refer the issue to the TSC for resolution. To do so, add the "tsc agenda" label to the issue and add a comment including the following information: + +1. A one-paragraph summary of the discussion to this point. +2. The question you would like the TSC to answer. + +The issue will be discussed at the next TSC meeting and the resolution will be posted back to the issue. + +## Evaluating Core Features and Enhancements (TSC members only) + +In addition to the above, changes to the core (including CLI changes) that would result in a minor or major version release must be approved by the TSC by standard TSC motion. Add the label "tsc agenda" to the issue and it will be discussed at the next TSC meeting. In general, requests should meet the following criteria to be considered: + +1. The feature or enhancement is in scope for the project and should be added to the roadmap +1. Someone is committed to including the change within the next year +1. There is reasonable certainty about who will do the work + +When a suggestion is too ambitious or would take too much time to complete, it's better not to accept the proposal. Stick to small, incremental changes and lay out a roadmap of where you'd like the project to go eventually. Don't let the project get bogged down in big features that will take a long time to complete. + +**Breaking Changes:** Be on the lookout for changes that would be breaking. Issues that represent breaking changes should be labeled as "breaking". + +## When to Close an Issue + +All team members are allowed to close issues depending on how the issue has been resolved. + +Team members may close an issue **immediately** if: + +1. The issue is a duplicate of an existing issue. +1. The issue is just a question and has been answered. + +Team members may close an issue where the consensus is to not accept the issue after a waiting period (to ensure that other team members have a chance to review the issue before it is closed): + +* Wait **2 days** if the issue was opened Monday through Friday. +* Wait **3 days** if the issue was opened on Saturday or Sunday. + +In an effort to keep the issues backlog manageable, team members may also close an issue if the following conditions are met: + +* **Unaccepted**: Close after it has been open for 21 days, as these issues do not have enough support to move forward. +* **Accepted**: Close after 90 days if no one from the team or the community is willing to step forward and own the work to complete to it. +* **Help wanted:** Close after 90 days if it has not been completed. diff --git a/docs/8.0.0/maintainer-guide/pullrequests.md b/docs/8.0.0/maintainer-guide/pullrequests.md new file mode 100644 index 0000000000..6fc22dbc03 --- /dev/null +++ b/docs/8.0.0/maintainer-guide/pullrequests.md @@ -0,0 +1,102 @@ +--- +title: Reviewing Pull Requests +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/maintainer-guide/pullrequests.md + +--- + + +# Reviewing Pull Requests + +Pull requests are submitted frequently and represent our best opportunity to interact with the community. As such, it's important that pull requests are well-reviewed before being merged and that interactions on pull requests are positive. + +## Who Can Review Pull Requests? + +Anyone, both team members and the public, may leave comments on pull requests. + +## Reviewing a Pull Request + +When a pull request is opened, the bot will check the following: + +1. Has the submitter signed a CLA? +1. Is the commit message summary in the correct format? +1. Is the commit summary too long? + +The bot will add a comment specifying the problems that it finds. You do not need to look at the pull request any further until those problems have been addressed (there's no need to comment on the pull request to ask the submitter to do what the bot asked - that's why we have the bot!). + +Once the bot checks have been satisfied, you check the following: + +1. Double-check that the commit message tag ("Fix:", "New:", etc.) is correct based on the issue (or, if no issue is referenced, based on the stated problem). +1. If the pull request makes a change to core, ensure that an issue exists and the pull request references the issue in the commit message. +1. Does the code follow our conventions (including header comments, JSDoc comments, etc.)? If not, please leave that feedback and reference the conventions document. +1. For code changes: + * Are there tests that verify the change? If not, please ask for them. + * Is documentation needed for the change? If yes, please let the submitter know. +1. Are there any automated testing errors? If yes, please ask the submitter to check on them. +1. If you've reviewed the pull request and there are no outstanding issues, leave a comment "LGTM" to indicate your approval. If you would like someone else to verify the change, comment "LGTM but would like someone else to verify." + +**Note:** If you are a team member and you've left a comment on the pull request, please follow up to verify that your comments have been addressed. + +## Who Can Merge a Pull Request + +TSC members and committers may merge pull requests, depending on the contents of the pull request. + +Committers may merge a pull request if it is a non-breaking change and is: + +1. A documentation change +1. A bug fix (for either rules or core) +1. A dependency upgrade +1. Related to the build tool +1. A chore + +In addition, committers may merge any non-breaking pull request if it has been approved by at least one TSC member. + +TSC members may merge all pull requests, including those that committers may merge. + +## When to Merge a Pull Request + +We use the "Merge" button to merge requests into the repository. Before merging a pull request, verify that: + +1. All comments have been addressed +1. Any team members who made comments have verified that their concerns were addressed +1. All automated tests are passing (never merge a pull request with failing tests) + +Be sure to say thank you to the submitter before merging, especially if they put a lot of work into the pull request. + +Team members may merge a pull request immediately if it: + +1. Makes a small documentation change +1. Is a chore +1. Fixes a block of other work on the repository (build-related, test-related, dependency-related, etc.) +1. Is an important fix to get into a patch release + +Otherwise, team members should observe a waiting period before merging a pull request: + +* Wait **2 days** if the pull request was opened Monday through Friday. +* Wait **3 days** if the pull request was opened on Saturday or Sunday. + +The waiting period ensures that other team members have a chance to review the pull request before it is merged. + +If the pull request was created from a branch on the `eslint/eslint` repository (as opposed to a fork), delete the branch after merging the pull request. (GitHub will display a "Delete branch" button after the pull request is merged.) + +**Note:** You should not merge your own pull request unless you're received feedback from at least one other team member. + +## When to Close a Pull Request + +There are several times when it's appropriate to close a pull request without merging: + +1. The pull request addresses an issue that is already fixed +1. The pull request hasn't been updated in 30 days +1. The pull request submitter isn't willing to follow project guidelines. + +In any of these cases, please be sure to leave a comment stating why the pull request is being closed. + +### Example Closing Comments + +If a pull request hasn't been updated in 30 days: + +> Closing because there hasn't been activity for 30 days. If you're still interested in submitting this code, please feel free to resubmit. + +If a pull request submitter isn't willing to follow project guidelines. + +> Unfortunately, we can't accept pull requests that don't follow our guidelines. I'm going to close this pull request now, but if you'd like to resubmit following our guidelines, we'll be happy to review. diff --git a/docs/8.0.0/maintainer-guide/releases.md b/docs/8.0.0/maintainer-guide/releases.md new file mode 100644 index 0000000000..bdf08f4b9d --- /dev/null +++ b/docs/8.0.0/maintainer-guide/releases.md @@ -0,0 +1,67 @@ +--- +title: Managing Releases +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/maintainer-guide/releases.md + +--- + + +# Managing Releases + +Releases are when a project formally publishes a new version so the community can use it. There are two types of releases: + +* Regular releases that follow [semantic versioning](https://semver.org/) and are considered production-ready. +* Prereleases that are not considered production-ready and are intended to give the community a preview of upcoming changes. + +## Release Team + +A two-person release team is assigned to each scheduled release. This two-person team is responsible for: + +1. The scheduled release on Friday +1. Monitoring issues over the weekend +1. Determining if a patch release is necessary on Monday +1. Publishing the patch release (if necessary) + +The two-person team should seek input from the whole team on the Monday following a release to double-check if a patch release is necessary. + +At least one member of the release team needs to have access to [eslint's two-factor authentication for npm](./npm-2fa) in order to do a release. + +## Release Communication + +Each scheduled release should be associated with a release issue ([example](https://github.com/eslint/eslint/issues/8138)). The release issue is the source of information for the team about the status of a release. Be sure the release issue has the "release" label so that it's easy to find. + +## Process + +On the day of a scheduled release, the release team should follow these steps: + +1. Review open pull requests to see if any should be merged. In general, you can merge pull requests that: + * Have been open at least two days and have been reviewed (these are just waiting for merge). + * Important pull requests (as determined by the team). You should stop and have people review before merging if they haven't been already. + * Documentation changes. + * Small bugfixes written by a team member. +1. Log into Jenkins and schedule a build for the "ESLint Release" job. +1. Watch the console output of the build on Jenkins. At some point, the build will pause and a link will be produced with an input field for a six-digit 2FA code. +1. Enter the current six-digit 2FA code from your authenticator app. +1. Continue the build and wait for it to finish. +1. Update the release blog post with a "Highlights" section, including new rules and anything else that's important. +1. Make a release announcement in the public chatroom. +1. Make a release announcement on Twitter. +1. Make a release announcement on the release issue. Document any problems that occurred during the release, and remind the team not to merge anything other than documentation changes and bugfixes. Leave the release issue open. +1. Add the `patch release pending` label to the release issue. (When this label is present, `eslint-github-bot` will create a pending status check on non-semver-patch pull requests, to ensure that they aren't accidentally merged while a patch release is pending.) + +On the Monday following the scheduled release, the release team needs to determine if a patch release is necessary. A patch release is considered necessary if any of the following occurred since the scheduled release: + +* A regression bug is causing people's lint builds to fail when it previously passed. +* Any bug that is causing a lot of problems for users (frequently happens due to new functionality). + +The patch release decision should be made as early on Monday as possible. If a patch release is necessary, then follow the same steps as the scheduled release process. + +In rare cases, a second patch release might be necessary if the release is known to have a severe regression that hasn't been fixed by Monday. If this occurs, the release team should announce the situation on the release issue, and leave the issue open until all patch releases are complete. However, it's usually better to fix bugs for the next release cycle rather than doing a second patch release. + +After the patch release has been published (or no patch release is necessary), close the release issue and inform the team that they can start merging in semver-minor changes again. + +## Emergency Releases + +In general, we try not to do emergency releases (an emergency release is unplanned and isn't the regularly scheduled release or the anticipated patch release). Even if there is a regression, it's best to wait the weekend to see if any other problems arise so a patch release can fix as many issues as possible. + +The only real exception is if ESLint is completely unusable by most of the current users. For instance, we once pushed a release that errored for everyone because it was missing some core files. In that case, an emergency release is appropriate. diff --git a/docs/8.0.0/maintainer-guide/working-groups.md b/docs/8.0.0/maintainer-guide/working-groups.md new file mode 100644 index 0000000000..6dc44709fe --- /dev/null +++ b/docs/8.0.0/maintainer-guide/working-groups.md @@ -0,0 +1,30 @@ +--- +title: Working Groups +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/maintainer-guide/working-groups.md + +--- + + +# Working Groups + +The ESLint TSC may form working groups to focus on a specific area of the project. + +## Creating a Working Group + +Working groups are created by sending an email to the team mailing list. Each working group: + +1. Must have a GitHub team under the "ESLint Team" top-level GitHub team. (The GitHub team name should end with "WG" to distinguish it from other types of teams.) +1. Must have at least one TSC member. +1. May have any number of Committers and Reviewers. +1. Must have at least two members. + +Active working groups are listed on the [team page](https://eslint.org/team). + +## How Working Groups Work + +Each working group is responsible for its own inner working. Working groups can decide how large or small they should be (so long as there is at least two members), when and who to add or remove from the working group, and how to accomplish their objectives. + +Working groups may be temporary or permanent. + +If working groups intend to make a significant change to the ESLint project, the proposal must still be approved by the TSC. diff --git a/docs/8.0.0/rules/accessor-pairs.md b/docs/8.0.0/rules/accessor-pairs.md new file mode 100644 index 0000000000..0f4c647117 --- /dev/null +++ b/docs/8.0.0/rules/accessor-pairs.md @@ -0,0 +1,306 @@ +--- +title: accessor-pairs - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/accessor-pairs.md +rule_type: suggestion +--- + + +# Enforces getter/setter pairs in objects and classes (accessor-pairs) + +It's a common mistake in JavaScript to create an object with just a setter for a property but never have a corresponding getter defined for it. Without a getter, you cannot read the property, so it ends up not being used. + +Here are some examples: + +```js +// Bad +var o = { + set a(value) { + this.val = value; + } +}; + +// Good +var o = { + set a(value) { + this.val = value; + }, + get a() { + return this.val; + } +}; + +``` + +This rule warns if setters are defined without getters. Using an option `getWithoutSet`, it will warn if you have a getter without a setter also. + +## Rule Details + +This rule enforces a style where it requires to have a getter for every property which has a setter defined. + +By activating the option `getWithoutSet` it enforces the presence of a setter for every property which has a getter defined. + +This rule always checks object literals and property descriptors. By default, it also checks class declarations and class expressions. + +## Options + +* `setWithoutGet` set to `true` will warn for setters without getters (Default `true`). +* `getWithoutSet` set to `true` will warn for getters without setters (Default `false`). +* `enforceForClassMembers` set to `true` additionally applies this rule to class getters/setters (Default `true`). Set `enforceForClassMembers` to `false` if you want this rule to ignore class declarations and class expressions. + +### setWithoutGet + +Examples of **incorrect** code for the default `{ "setWithoutGet": true }` option: + +```js +/*eslint accessor-pairs: "error"*/ + +var o = { + set a(value) { + this.val = value; + } +}; + +var o = {d: 1}; +Object.defineProperty(o, 'c', { + set: function(value) { + this.val = value; + } +}); +``` + +Examples of **correct** code for the default `{ "setWithoutGet": true }` option: + +```js +/*eslint accessor-pairs: "error"*/ + +var o = { + set a(value) { + this.val = value; + }, + get a() { + return this.val; + } +}; + +var o = {d: 1}; +Object.defineProperty(o, 'c', { + set: function(value) { + this.val = value; + }, + get: function() { + return this.val; + } +}); + +``` + +### getWithoutSet + +Examples of **incorrect** code for the `{ "getWithoutSet": true }` option: + +```js +/*eslint accessor-pairs: ["error", { "getWithoutSet": true }]*/ + +var o = { + set a(value) { + this.val = value; + } +}; + +var o = { + get a() { + return this.val; + } +}; + +var o = {d: 1}; +Object.defineProperty(o, 'c', { + set: function(value) { + this.val = value; + } +}); + +var o = {d: 1}; +Object.defineProperty(o, 'c', { + get: function() { + return this.val; + } +}); +``` + +Examples of **correct** code for the `{ "getWithoutSet": true }` option: + +```js +/*eslint accessor-pairs: ["error", { "getWithoutSet": true }]*/ +var o = { + set a(value) { + this.val = value; + }, + get a() { + return this.val; + } +}; + +var o = {d: 1}; +Object.defineProperty(o, 'c', { + set: function(value) { + this.val = value; + }, + get: function() { + return this.val; + } +}); + +``` + +### enforceForClassMembers + +When `enforceForClassMembers` is set to `true` (default): + +* `"getWithoutSet": true` will also warn for getters without setters in classes. +* `"setWithoutGet": true` will also warn for setters without getters in classes. + +Examples of **incorrect** code for `{ "getWithoutSet": true, "enforceForClassMembers": true }`: + +```js +/*eslint accessor-pairs: ["error", { "getWithoutSet": true, "enforceForClassMembers": true }]*/ + +class Foo { + get a() { + return this.val; + } +} + +class Bar { + static get a() { + return this.val; + } +} + +const Baz = class { + get a() { + return this.val; + } + static set a(value) { + this.val = value; + } +} +``` + +Examples of **incorrect** code for `{ "setWithoutGet": true, "enforceForClassMembers": true }`: + +```js +/*eslint accessor-pairs: ["error", { "setWithoutGet": true, "enforceForClassMembers": true }]*/ + +class Foo { + set a(value) { + this.val = value; + } +} + +const Bar = class { + static set a(value) { + this.val = value; + } +} +``` + +When `enforceForClassMembers` is set to `false`, this rule ignores classes. + +Examples of **correct** code for `{ "getWithoutSet": true, "setWithoutGet": true, "enforceForClassMembers": false }`: + +```js +/*eslint accessor-pairs: ["error", { + "getWithoutSet": true, "setWithoutGet": true, "enforceForClassMembers": false +}]*/ + +class Foo { + get a() { + return this.val; + } +} + +class Bar { + static set a(value) { + this.val = value; + } +} + +const Baz = class { + static get a() { + return this.val; + } +} + +const Quux = class { + set a(value) { + this.val = value; + } +} +``` + + +## Known Limitations + +Due to the limits of static analysis, this rule does not account for possible side effects and in certain cases +might not report a missing pair for a getter/setter that has a computed key, like in the following example: + +```js +/*eslint accessor-pairs: "error"*/ + +var a = 1; + +// no warnings +var o = { + get [a++]() { + return this.val; + }, + set [a++](value) { + this.val = value; + } +}; +``` + +Also, this rule does not disallow duplicate keys in object literals and class definitions, and in certain cases with duplicate keys +might not report a missing pair for a getter/setter, like in the following example: + +```js +/*eslint accessor-pairs: "error"*/ + +// no warnings +var o = { + get a() { + return this.val; + }, + a: 1, + set a(value) { + this.val = value; + } +}; +``` + +The code above creates an object with just a setter for the property `"a"`. + +See [no-dupe-keys](no-dupe-keys) if you also want to disallow duplicate keys in object literals. + +See [no-dupe-class-members](no-dupe-class-members) if you also want to disallow duplicate names in class definitions. + +## When Not To Use It + +You can turn this rule off if you are not concerned with the simultaneous presence of setters and getters on objects. + +## Further Reading + +* [Object Setters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set) +* [Object Getters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get) +* [Working with Objects](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects) + +## Version + +This rule was introduced in ESLint 0.22.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/accessor-pairs.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/accessor-pairs.md) diff --git a/docs/8.0.0/rules/array-bracket-newline.md b/docs/8.0.0/rules/array-bracket-newline.md new file mode 100644 index 0000000000..c3c204a606 --- /dev/null +++ b/docs/8.0.0/rules/array-bracket-newline.md @@ -0,0 +1,300 @@ +--- +title: array-bracket-newline - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/array-bracket-newline.md +rule_type: layout +--- + + +# enforce line breaks after opening and before closing array brackets (array-bracket-newline) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +A number of style guides require or disallow line breaks inside of array brackets. + +## Rule Details + +This rule enforces line breaks after opening and before closing array brackets. + +## Options + +This rule has either a string option: + +* `"always"` requires line breaks inside brackets +* `"never"` disallows line breaks inside brackets +* `"consistent"` requires consistent usage of linebreaks for each pair of brackets. It reports an error if one bracket in the pair has a linebreak inside it and the other bracket does not. + +Or an object option (Requires line breaks if any of properties is satisfied. Otherwise, disallows line breaks): + +* `"multiline": true` (default) requires line breaks if there are line breaks inside elements or between elements. If this is false, this condition is disabled. +* `"minItems": null` (default) requires line breaks if the number of elements is at least the given integer. If this is 0, this condition will act the same as the option `"always"`. If this is `null` (the default), this condition is disabled. + +### always + +Examples of **incorrect** code for this rule with the `"always"` option: + +```js +/*eslint array-bracket-newline: ["error", "always"]*/ + +var a = []; +var b = [1]; +var c = [1, 2]; +var d = [1, + 2]; +var e = [function foo() { + dosomething(); +}]; +``` + +Examples of **correct** code for this rule with the `"always"` option: + +```js +/*eslint array-bracket-newline: ["error", "always"]*/ + +var a = [ +]; +var b = [ + 1 +]; +var c = [ + 1, 2 +]; +var d = [ + 1, + 2 +]; +var e = [ + function foo() { + dosomething(); + } +]; +``` + +### never + +Examples of **incorrect** code for this rule with the `"never"` option: + +```js +/*eslint array-bracket-newline: ["error", "never"]*/ + +var a = [ +]; +var b = [ + 1 +]; +var c = [ + 1, 2 +]; +var d = [ + 1, + 2 +]; +var e = [ + function foo() { + dosomething(); + } +]; +``` + +Examples of **correct** code for this rule with the `"never"` option: + +```js +/*eslint array-bracket-newline: ["error", "never"]*/ + +var a = []; +var b = [1]; +var c = [1, 2]; +var d = [1, + 2]; +var e = [function foo() { + dosomething(); +}]; +``` + +### consistent + +Examples of **incorrect** code for this rule with the `"consistent"` option: + +```js +/*eslint array-bracket-newline: ["error", "consistent"]*/ + +var a = [1 +]; +var b = [ + 1]; +var c = [function foo() { + dosomething(); +} +] +var d = [ + function foo() { + dosomething(); + }] +``` + +Examples of **correct** code for this rule with the `"consistent"` option: + +```js +/*eslint array-bracket-newline: ["error", "consistent"]*/ + +var a = []; +var b = [ +]; +var c = [1]; +var d = [ + 1 +]; +var e = [function foo() { + dosomething(); +}]; +var f = [ + function foo() { + dosomething(); + } +]; +``` + +### multiline + +Examples of **incorrect** code for this rule with the default `{ "multiline": true }` option: + +```js +/*eslint array-bracket-newline: ["error", { "multiline": true }]*/ + +var a = [ +]; +var b = [ + 1 +]; +var c = [ + 1, 2 +]; +var d = [1, + 2]; +var e = [function foo() { + dosomething(); +}]; +``` + +Examples of **correct** code for this rule with the default `{ "multiline": true }` option: + +```js +/*eslint array-bracket-newline: ["error", { "multiline": true }]*/ + +var a = []; +var b = [1]; +var c = [1, 2]; +var d = [ + 1, + 2 +]; +var e = [ + function foo() { + dosomething(); + } +]; +``` + +### minItems + +Examples of **incorrect** code for this rule with the `{ "minItems": 2 }` option: + +```js +/*eslint array-bracket-newline: ["error", { "minItems": 2 }]*/ + +var a = [ +]; +var b = [ + 1 +]; +var c = [1, 2]; +var d = [1, + 2]; +var e = [ + function foo() { + dosomething(); + } +]; +``` + +Examples of **correct** code for this rule with the `{ "minItems": 2 }` option: + +```js +/*eslint array-bracket-newline: ["error", { "minItems": 2 }]*/ + +var a = []; +var b = [1]; +var c = [ + 1, 2 +]; +var d = [ + 1, + 2 +]; +var e = [function foo() { + dosomething(); +}]; +``` + +### multiline and minItems + +Examples of **incorrect** code for this rule with the `{ "multiline": true, "minItems": 2 }` options: + +```js +/*eslint array-bracket-newline: ["error", { "multiline": true, "minItems": 2 }]*/ + +var a = [ +]; +var b = [ + 1 +]; +var c = [1, 2]; +var d = [1, + 2]; +var e = [function foo() { + dosomething(); +}]; +``` + +Examples of **correct** code for this rule with the `{ "multiline": true, "minItems": 2 }` options: + +```js +/*eslint array-bracket-newline: ["error", { "multiline": true, "minItems": 2 }]*/ + +var a = []; +var b = [1]; +var c = [ + 1, 2 +]; +var d = [ + 1, + 2 +]; +var e = [ + function foo() { + dosomething(); + } +]; +``` + + +## When Not To Use It + +If you don't want to enforce line breaks after opening and before closing array brackets, don't enable this rule. + +## Compatibility + +* **JSCS:** [validateNewlineAfterArrayElements](https://jscs-dev.github.io/rule/validateNewlineAfterArrayElements) + +## Related Rules + +* [array-bracket-spacing](array-bracket-spacing) + +## Version + +This rule was introduced in ESLint 4.0.0-alpha.1. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/array-bracket-newline.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/array-bracket-newline.md) diff --git a/docs/8.0.0/rules/array-bracket-spacing.md b/docs/8.0.0/rules/array-bracket-spacing.md new file mode 100644 index 0000000000..d8003457b6 --- /dev/null +++ b/docs/8.0.0/rules/array-bracket-spacing.md @@ -0,0 +1,242 @@ +--- +title: array-bracket-spacing - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/array-bracket-spacing.md +rule_type: layout +--- + + +# Disallow or enforce spaces inside of brackets (array-bracket-spacing) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +A number of style guides require or disallow spaces between array brackets and other tokens. This rule +applies to both array literals and destructuring assignments (ECMAScript 6). + +```js +/*eslint-env es6*/ + +var arr = [ 'foo', 'bar' ]; +var [ x, y ] = z; + +var arr = ['foo', 'bar']; +var [x,y] = z; +``` + +## Rule Details + +This rule enforces consistent spacing inside array brackets. + +## Options + +This rule has a string option: + +* `"never"` (default) disallows spaces inside array brackets +* `"always"` requires one or more spaces or newlines inside array brackets + +This rule has an object option for exceptions to the `"never"` option: + +* `"singleValue": true` requires one or more spaces or newlines inside brackets of array literals that contain a single element +* `"objectsInArrays": true` requires one or more spaces or newlines between brackets of array literals and braces of their object literal elements `[ {` or `} ]` +* `"arraysInArrays": true` requires one or more spaces or newlines between brackets of array literals and brackets of their array literal elements `[ [` or `] ]` + +This rule has an object option for exceptions to the `"always"` option: + +* `"singleValue": false` disallows spaces inside brackets of array literals that contain a single element +* `"objectsInArrays": false` disallows spaces between brackets of array literals and braces of their object literal elements `[{` or `}]` +* `"arraysInArrays": false` disallows spaces between brackets of array literals and brackets of their array literal elements `[[` or `]]` + +This rule has built-in exceptions: + +* `"never"` (and also the exceptions to the `"always"` option) allows newlines inside array brackets, because this is a common pattern +* `"always"` does not require spaces or newlines in empty array literals `[]` + +### never + +Examples of **incorrect** code for this rule with the default `"never"` option: + +```js +/*eslint array-bracket-spacing: ["error", "never"]*/ +/*eslint-env es6*/ + +var arr = [ 'foo', 'bar' ]; +var arr = ['foo', 'bar' ]; +var arr = [ ['foo'], 'bar']; +var arr = [[ 'foo' ], 'bar']; +var arr = [ 'foo', + 'bar' +]; +var [ x, y ] = z; +var [ x,y ] = z; +var [ x, ...y ] = z; +var [ ,,x, ] = z; +``` + +Examples of **correct** code for this rule with the default `"never"` option: + +```js +/*eslint array-bracket-spacing: ["error", "never"]*/ +/*eslint-env es6*/ + +var arr = []; +var arr = ['foo', 'bar', 'baz']; +var arr = [['foo'], 'bar', 'baz']; +var arr = [ + 'foo', + 'bar', + 'baz' +]; +var arr = ['foo', + 'bar' +]; +var arr = [ + 'foo', + 'bar']; + +var [x, y] = z; +var [x,y] = z; +var [x, ...y] = z; +var [,,x,] = z; +``` + +### always + +Examples of **incorrect** code for this rule with the `"always"` option: + +```js +/*eslint array-bracket-spacing: ["error", "always"]*/ +/*eslint-env es6*/ + +var arr = ['foo', 'bar']; +var arr = ['foo', 'bar' ]; +var arr = [ ['foo'], 'bar' ]; +var arr = ['foo', + 'bar' +]; +var arr = [ + 'foo', + 'bar']; + +var [x, y] = z; +var [x,y] = z; +var [x, ...y] = z; +var [,,x,] = z; +``` + +Examples of **correct** code for this rule with the `"always"` option: + +```js +/*eslint array-bracket-spacing: ["error", "always"]*/ +/*eslint-env es6*/ + +var arr = []; +var arr = [ 'foo', 'bar', 'baz' ]; +var arr = [ [ 'foo' ], 'bar', 'baz' ]; +var arr = [ 'foo', + 'bar' +]; +var arr = [ + 'foo', + 'bar' ]; +var arr = [ + 'foo', + 'bar', + 'baz' +]; + +var [ x, y ] = z; +var [ x,y ] = z; +var [ x, ...y ] = z; +var [ ,,x, ] = z; +``` + +### singleValue + +Examples of **incorrect** code for this rule with the `"always", { "singleValue": false }` options: + +```js +/*eslint array-bracket-spacing: ["error", "always", { "singleValue": false }]*/ + +var foo = [ 'foo' ]; +var foo = [ 'foo']; +var foo = ['foo' ]; +var foo = [ 1 ]; +var foo = [ 1]; +var foo = [1 ]; +var foo = [ [ 1, 2 ] ]; +var foo = [ { 'foo': 'bar' } ]; +``` + +Examples of **correct** code for this rule with the `"always", { "singleValue": false }` options: + +```js +/*eslint array-bracket-spacing: ["error", "always", { "singleValue": false }]*/ + +var foo = ['foo']; +var foo = [1]; +var foo = [[ 1, 1 ]]; +var foo = [{ 'foo': 'bar' }]; +``` + +### objectsInArrays + +Examples of **incorrect** code for this rule with the `"always", { "objectsInArrays": false }` options: + +```js +/*eslint array-bracket-spacing: ["error", "always", { "objectsInArrays": false }]*/ + +var arr = [ { 'foo': 'bar' } ]; +var arr = [ { + 'foo': 'bar' +} ] +``` + +Examples of **correct** code for this rule with the `"always", { "objectsInArrays": false }` options: + +```js +/*eslint array-bracket-spacing: ["error", "always", { "objectsInArrays": false }]*/ + +var arr = [{ 'foo': 'bar' }]; +var arr = [{ + 'foo': 'bar' +}]; +``` + +### arraysInArrays + +Examples of **incorrect** code for this rule with the `"always", { "arraysInArrays": false }` options: + +```js +/*eslint array-bracket-spacing: ["error", "always", { "arraysInArrays": false }]*/ + +var arr = [ [ 1, 2 ], 2, 3, 4 ]; +var arr = [ [ 1, 2 ], 2, [ 3, 4 ] ]; +``` + +Examples of **correct** code for this rule with the `"always", { "arraysInArrays": false }` options: + +```js +/*eslint array-bracket-spacing: ["error", "always", { "arraysInArrays": false }]*/ + +var arr = [[ 1, 2 ], 2, 3, 4 ]; +var arr = [[ 1, 2 ], 2, [ 3, 4 ]]; +``` + +## When Not To Use It + +You can turn this rule off if you are not concerned with the consistency of spacing between array brackets. + +## Related Rules + +* [space-in-parens](space-in-parens) +* [object-curly-spacing](object-curly-spacing) +* [computed-property-spacing](computed-property-spacing) + +## Version + +This rule was introduced in ESLint 0.24.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/array-bracket-spacing.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/array-bracket-spacing.md) diff --git a/docs/8.0.0/rules/array-callback-return.md b/docs/8.0.0/rules/array-callback-return.md new file mode 100644 index 0000000000..ffc94819c2 --- /dev/null +++ b/docs/8.0.0/rules/array-callback-return.md @@ -0,0 +1,171 @@ +--- +title: array-callback-return - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/array-callback-return.md +rule_type: problem +--- + + +# Enforces return statements in callbacks of array's methods (array-callback-return) + +`Array` has several methods for filtering, mapping, and folding. +If we forget to write `return` statement in a callback of those, it's probably a mistake. If you don't want to use a return or don't need the returned results, consider using [.forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) instead. + +```js +// example: convert ['a', 'b', 'c'] --> {a: 0, b: 1, c: 2} +var indexMap = myArray.reduce(function(memo, item, index) { + memo[item] = index; +}, {}); // Error: cannot set property 'b' of undefined +``` + +## Rule Details + +This rule enforces usage of `return` statement in callbacks of array's methods. +Additionally, it may also enforce the `forEach` array method callback to __not__ return a value by using the `checkForEach` option. + +This rule finds callback functions of the following methods, then checks usage of `return` statement. + +* [`Array.from`](https://www.ecma-international.org/ecma-262/6.0/#sec-array.from) +* [`Array.prototype.every`](https://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.every) +* [`Array.prototype.filter`](https://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.filter) +* [`Array.prototype.find`](https://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.find) +* [`Array.prototype.findIndex`](https://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.findindex) +* [`Array.prototype.flatMap`](https://www.ecma-international.org/ecma-262/10.0/#sec-array.prototype.flatmap) +* [`Array.prototype.forEach`](https://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.foreach) (optional, based on `checkForEach` parameter) +* [`Array.prototype.map`](https://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.map) +* [`Array.prototype.reduce`](https://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.reduce) +* [`Array.prototype.reduceRight`](https://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.reduceright) +* [`Array.prototype.some`](https://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.some) +* [`Array.prototype.sort`](https://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.sort) +* And above of typed arrays. + +Examples of **incorrect** code for this rule: + +```js +/*eslint array-callback-return: "error"*/ + +var indexMap = myArray.reduce(function(memo, item, index) { + memo[item] = index; +}, {}); + +var foo = Array.from(nodes, function(node) { + if (node.tagName === "DIV") { + return true; + } +}); + +var bar = foo.filter(function(x) { + if (x) { + return true; + } else { + return; + } +}); +``` + +Examples of **correct** code for this rule: + +```js +/*eslint array-callback-return: "error"*/ + +var indexMap = myArray.reduce(function(memo, item, index) { + memo[item] = index; + return memo; +}, {}); + +var foo = Array.from(nodes, function(node) { + if (node.tagName === "DIV") { + return true; + } + return false; +}); + +var bar = foo.map(node => node.getAttribute("id")); +``` + +## Options + +This rule accepts a configuration object with two options: + +* `"allowImplicit": false` (default) When set to `true`, allows callbacks of methods that require a return value to implicitly return `undefined` with a `return` statement containing no expression. +* `"checkForEach": false` (default) When set to `true`, rule will also report `forEach` callbacks that return a value. + +### allowImplicit + +Examples of **correct** code for the `{ "allowImplicit": true }` option: + +```js +/*eslint array-callback-return: ["error", { allowImplicit: true }]*/ +var undefAllTheThings = myArray.map(function(item) { + return; +}); +``` + +### checkForEach + +Examples of **incorrect** code for the `{ "checkForEach": true }` option: + +```js +/*eslint array-callback-return: ["error", { checkForEach: true }]*/ + +myArray.forEach(function(item) { + return handleItem(item) +}); + +myArray.forEach(function(item) { + if (item < 0) { + return x; + } + handleItem(item); +}); + +myArray.forEach(item => handleItem(item)); + +myArray.forEach(item => { + return handleItem(item); +}); +``` + +Examples of **correct** code for the `{ "checkForEach": true }` option: + +```js +/*eslint array-callback-return: ["error", { checkForEach: true }]*/ + +myArray.forEach(function(item) { + handleItem(item) +}); + +myArray.forEach(function(item) { + if (item < 0) { + return; + } + handleItem(item); +}); + +myArray.forEach(function(item) { + handleItem(item); + return; +}); + +myArray.forEach(item => { + handleItem(item); +}); +``` + + +## Known Limitations + +This rule checks callback functions of methods with the given names, *even if* the object which has the method is *not* an array. + +## When Not To Use It + +If you don't want to warn about usage of `return` statement in callbacks of array's methods, then it's safe to disable this rule. + +## Version + +This rule was introduced in ESLint 2.0.0-alpha-1. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/array-callback-return.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/array-callback-return.md) diff --git a/docs/8.0.0/rules/array-element-newline.md b/docs/8.0.0/rules/array-element-newline.md new file mode 100644 index 0000000000..accaefc7cf --- /dev/null +++ b/docs/8.0.0/rules/array-element-newline.md @@ -0,0 +1,394 @@ +--- +title: array-element-newline - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/array-element-newline.md +rule_type: layout +--- + + +# enforce line breaks between array elements (array-element-newline) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +A number of style guides require or disallow line breaks between array elements. + +## Rule Details + +This rule enforces line breaks between array elements. + +## Options + +This rule has either a string option: + +* `"always"` (default) requires line breaks between array elements +* `"never"` disallows line breaks between array elements +* `"consistent"` requires consistent usage of linebreaks between array elements + +Or an object option (Requires line breaks if any of properties is satisfied. Otherwise, disallows line breaks): + +* `"multiline": ` requires line breaks if there are line breaks inside elements. If this is false, this condition is disabled. +* `"minItems": ` requires line breaks if the number of elements is at least the given integer. If this is 0, this condition will act the same as the option `"always"`. If this is `null` (the default), this condition is disabled. + +Alternatively, different configurations can be specified for array expressions and array patterns: + +```json +{ + "array-element-newline": ["error", { + "ArrayExpression": "consistent", + "ArrayPattern": { "minItems": 3 }, + }] +} +``` + +* `"ArrayExpression"` configuration for array expressions (if unspecified, this rule will not apply to array expressions) +* `"ArrayPattern"` configuration for array patterns of destructuring assignments (if unspecified, this rule will not apply to array patterns) + +### always + +Examples of **incorrect** code for this rule with the default `"always"` option: + +```js +/*eslint array-element-newline: ["error", "always"]*/ + +var c = [1, 2]; +var d = [1, 2, 3]; +var e = [ + function foo() { + dosomething(); + }, function bar() { + dosomething(); + } +]; +``` + +Examples of **correct** code for this rule with the default `"always"` option: + +```js +/*eslint array-element-newline: ["error", "always"]*/ + +var a = []; +var b = [1]; +var c = [1, + 2]; +var d = [1, + 2, + 3]; +var e = [ + function foo() { + dosomething(); + }, + function bar() { + dosomething(); + } +]; +``` + +### never + +Examples of **incorrect** code for this rule with the `"never"` option: + +```js +/*eslint array-element-newline: ["error", "never"]*/ + +var c = [ + 1, + 2 +]; +var d = [ + 1, + 2, + 3 +]; +var e = [ + function foo() { + dosomething(); + }, + function bar() { + dosomething(); + } +]; +``` + +Examples of **correct** code for this rule with the `"never"` option: + +```js +/*eslint array-element-newline: ["error", "never"]*/ + +var a = []; +var b = [1]; +var c = [1, 2]; +var d = [1, 2, 3]; +var e = [ + function foo() { + dosomething(); + }, function bar() { + dosomething(); + } +]; +``` + +### consistent + +Examples of **incorrect** code for this rule with the `"consistent"` option: + +```js +/*eslint array-element-newline: ["error", "consistent"]*/ + +var a = [ + 1, 2, + 3 +]; +var b = [ + function foo() { + dosomething(); + }, function bar() { + dosomething(); + }, + function baz() { + dosomething(); + } +]; +``` + +Examples of **correct** code for this rule with the `"consistent"` option: + +```js +/*eslint array-element-newline: ["error", "consistent"]*/ + +var a = []; +var b = [1]; +var c = [1, 2]; +var d = [1, 2, 3]; +var e = [ + 1, + 2 +]; +var f = [ + 1, + 2, + 3 +]; +var g = [ + function foo() { + dosomething(); + }, function bar() { + dosomething(); + }, function baz() { + dosomething(); + } +]; +var h = [ + function foo() { + dosomething(); + }, + function bar() { + dosomething(); + }, + function baz() { + dosomething(); + } +]; +``` + +### multiline + +Examples of **incorrect** code for this rule with the `{ "multiline": true }` option: + +```js +/*eslint array-element-newline: ["error", { "multiline": true }]*/ + +var d = [1, + 2, 3]; +var e = [ + function foo() { + dosomething(); + }, function bar() { + dosomething(); + } +]; +``` + +Examples of **correct** code for this rule with the `{ "multiline": true }` option: + +```js +/*eslint array-element-newline: ["error", { "multiline": true }]*/ + +var a = []; +var b = [1]; +var c = [1, 2]; +var d = [1, 2, 3]; +var e = [ + function foo() { + dosomething(); + }, + function bar() { + dosomething(); + } +]; +``` + +### minItems + +Examples of **incorrect** code for this rule with the `{ "minItems": 3 }` option: + +```js +/*eslint array-element-newline: ["error", { "minItems": 3 }]*/ + +var c = [1, + 2]; +var d = [1, 2, 3]; +var e = [ + function foo() { + dosomething(); + }, + function bar() { + dosomething(); + } +]; +``` + +Examples of **correct** code for this rule with the `{ "minItems": 3 }` option: + +```js +/*eslint array-element-newline: ["error", { "minItems": 3 }]*/ + +var a = []; +var b = [1]; +var c = [1, 2]; +var d = [1, + 2, + 3]; +var e = [ + function foo() { + dosomething(); + }, function bar() { + dosomething(); + } +]; +``` + +### multiline and minItems + +Examples of **incorrect** code for this rule with the `{ "multiline": true, "minItems": 3 }` options: + +```js +/*eslint array-element-newline: ["error", { "multiline": true, "minItems": 3 }]*/ + +var c = [1, +2]; +var d = [1, 2, 3]; +var e = [ + function foo() { + dosomething(); + }, function bar() { + dosomething(); + } +]; +``` + +Examples of **correct** code for this rule with the `{ "multiline": true, "minItems": 3 }` options: + +```js +/*eslint array-element-newline: ["error", { "multiline": true, "minItems": 3 }]*/ + +var a = []; +var b = [1]; +var c = [1, 2]; +var d = [1, + 2, + 3]; +var e = [ + function foo() { + dosomething(); + }, + function bar() { + dosomething(); + } +]; +``` + +### ArrayExpression and ArrayPattern + +Examples of **incorrect** code for this rule with the `{ "ArrayExpression": "always", "ArrayPattern": "never" }` options: + +```js +/*eslint array-element-newline: ["error", { "ArrayExpression": "always", "ArrayPattern": "never" }]*/ + +var a = [1, 2]; +var b = [1, 2, 3]; +var c = [ + function foo() { + dosomething(); + }, function bar() { + dosomething(); + } +]; + +var [d, + e] = arr; +var [f, + g, + h] = arr; +var [i = function foo() { + dosomething() +}, +j = function bar() { + dosomething() +}] = arr +``` + +Examples of **correct** code for this rule with the `{ "ArrayExpression": "always", "ArrayPattern": "never" }` options: + +```js +/*eslint array-element-newline: ["error", { "ArrayExpression": "always", "ArrayPattern": "never" }]*/ + +var a = [1, + 2]; +var b = [1, + 2, + 3]; +var c = [ + function foo() { + dosomething(); + }, + function bar() { + dosomething(); + } +]; + +var [d, e] = arr +var [f, g, h] = arr +var [i = function foo() { + dosomething() +}, j = function bar() { + dosomething() +}] = arr +``` + +## When Not To Use It + +If you don't want to enforce linebreaks between array elements, don't enable this rule. + +## Compatibility + +* **JSCS:** [validateNewlineAfterArrayElements](https://jscs-dev.github.io/rule/validateNewlineAfterArrayElements) + +## Related Rules + +* [array-bracket-spacing](array-bracket-spacing) +* [array-bracket-newline](array-bracket-newline) +* [object-property-newline](object-property-newline) +* [object-curly-spacing](object-curly-spacing) +* [object-curly-newline](object-curly-newline) +* [max-statements-per-line](max-statements-per-line) +* [block-spacing](block-spacing) +* [brace-style](brace-style) + +## Version + +This rule was introduced in ESLint 4.0.0-rc.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/array-element-newline.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/array-element-newline.md) diff --git a/docs/8.0.0/rules/arrow-body-style.md b/docs/8.0.0/rules/arrow-body-style.md new file mode 100644 index 0000000000..920e531781 --- /dev/null +++ b/docs/8.0.0/rules/arrow-body-style.md @@ -0,0 +1,159 @@ +--- +title: arrow-body-style - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/arrow-body-style.md +rule_type: suggestion +--- + + +# Require braces in arrow function body (arrow-body-style) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +Arrow functions have two syntactic forms for their function bodies. They may be defined with a *block* body (denoted by curly braces) `() => { ... }` or with a single expression `() => ...`, whose value is implicitly returned. + +## Rule Details + +This rule can enforce or disallow the use of braces around arrow function body. + +## Options + +The rule takes one or two options. The first is a string, which can be: + +* `"always"` enforces braces around the function body +* `"as-needed"` enforces no braces where they can be omitted (default) +* `"never"` enforces no braces around the function body (constrains arrow functions to the role of returning an expression) + +The second one is an object for more fine-grained configuration when the first option is `"as-needed"`. Currently, the only available option is `requireReturnForObjectLiteral`, a boolean property. It's `false` by default. If set to `true`, it requires braces and an explicit return for object literals. + +```json +"arrow-body-style": ["error", "always"] +``` + +### always + +Examples of **incorrect** code for this rule with the `"always"` option: + +```js +/*eslint arrow-body-style: ["error", "always"]*/ +/*eslint-env es6*/ +let foo = () => 0; +``` + +Examples of **correct** code for this rule with the `"always"` option: + +```js +let foo = () => { + return 0; +}; +let foo = (retv, name) => { + retv[name] = true; + return retv; +}; +``` + +### as-needed + +Examples of **incorrect** code for this rule with the default `"as-needed"` option: + +```js +/*eslint arrow-body-style: ["error", "as-needed"]*/ +/*eslint-env es6*/ + +let foo = () => { + return 0; +}; +let foo = () => { + return { + bar: { + foo: 1, + bar: 2, + } + }; +}; +``` + +Examples of **correct** code for this rule with the default `"as-needed"` option: + +```js +/*eslint arrow-body-style: ["error", "as-needed"]*/ +/*eslint-env es6*/ + +let foo = () => 0; +let foo = (retv, name) => { + retv[name] = true; + return retv; +}; +let foo = () => ({ + bar: { + foo: 1, + bar: 2, + } +}); +let foo = () => { bar(); }; +let foo = () => {}; +let foo = () => { /* do nothing */ }; +let foo = () => { + // do nothing. +}; +let foo = () => ({ bar: 0 }); +``` + +#### requireReturnForObjectLiteral + +> This option is only applicable when used in conjunction with the `"as-needed"` option. + +Examples of **incorrect** code for this rule with the `{ "requireReturnForObjectLiteral": true }` option: + +```js +/*eslint arrow-body-style: ["error", "as-needed", { "requireReturnForObjectLiteral": true }]*/ +/*eslint-env es6*/ +let foo = () => ({}); +let foo = () => ({ bar: 0 }); +``` + +Examples of **correct** code for this rule with the `{ "requireReturnForObjectLiteral": true }` option: + +```js +/*eslint arrow-body-style: ["error", "as-needed", { "requireReturnForObjectLiteral": true }]*/ +/*eslint-env es6*/ + +let foo = () => {}; +let foo = () => { return { bar: 0 }; }; +``` + +### never + +Examples of **incorrect** code for this rule with the `"never"` option: + +```js +/*eslint arrow-body-style: ["error", "never"]*/ +/*eslint-env es6*/ + +let foo = () => { + return 0; +}; +let foo = (retv, name) => { + retv[name] = true; + return retv; +}; +``` + +Examples of **correct** code for this rule with the `"never"` option: + +```js +/*eslint arrow-body-style: ["error", "never"]*/ +/*eslint-env es6*/ + +let foo = () => 0; +let foo = () => ({ foo: 0 }); +``` + +## Version + +This rule was introduced in ESLint 1.8.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/arrow-body-style.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/arrow-body-style.md) diff --git a/docs/8.0.0/rules/arrow-parens.md b/docs/8.0.0/rules/arrow-parens.md new file mode 100644 index 0000000000..edea7baea5 --- /dev/null +++ b/docs/8.0.0/rules/arrow-parens.md @@ -0,0 +1,248 @@ +--- +title: arrow-parens - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/arrow-parens.md +rule_type: layout +--- + + +# Require parens in arrow function arguments (arrow-parens) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +Arrow functions can omit parentheses when they have exactly one parameter. In all other cases the parameter(s) must +be wrapped in parentheses. This rule enforces the consistent use of parentheses in arrow functions. + +## Rule Details + +This rule enforces parentheses around arrow function parameters regardless of arity. For example: + +```js +/*eslint-env es6*/ + +// Bad +a => {} + +// Good +(a) => {} +``` + +Following this style will help you find arrow functions (`=>`) which may be mistakenly included in a condition +when a comparison such as `>=` was the intent. + + +```js +/*eslint-env es6*/ + +// Bad +if (a => 2) { +} + +// Good +if (a >= 2) { +} +``` + +The rule can also be configured to discourage the use of parens when they are not required: + +```js +/*eslint-env es6*/ + +// Bad +(a) => {} + +// Good +a => {} +``` + +## Options + +This rule has a string option and an object one. + +String options are: + +* `"always"` (default) requires parens around arguments in all cases. +* `"as-needed"` enforces no parens where they can be omitted. + +Object properties for variants of the `"as-needed"` option: + +* `"requireForBlockBody": true` modifies the as-needed rule in order to require parens if the function body is in an instructions block (surrounded by braces). + +### always + +Examples of **incorrect** code for this rule with the default `"always"` option: + +```js +/*eslint arrow-parens: ["error", "always"]*/ +/*eslint-env es6*/ + +a => {}; +a => a; +a => {'\n'}; +a.then(foo => {}); +a.then(foo => a); +a(foo => { if (true) {} }); +``` + +Examples of **correct** code for this rule with the default `"always"` option: + +```js +/*eslint arrow-parens: ["error", "always"]*/ +/*eslint-env es6*/ + +() => {}; +(a) => {}; +(a) => a; +(a) => {'\n'} +a.then((foo) => {}); +a.then((foo) => { if (true) {} }); +``` + +#### If Statements + +One of the benefits of this option is that it prevents the incorrect use of arrow functions in conditionals: + +```js +/*eslint-env es6*/ + +var a = 1; +var b = 2; +// ... +if (a => b) { + console.log('bigger'); +} else { + console.log('smaller'); +} +// outputs 'bigger', not smaller as expected +``` + +The contents of the `if` statement is an arrow function, not a comparison. + +If the arrow function is intentional, it should be wrapped in parens to remove ambiguity. + +```js +/*eslint-env es6*/ + +var a = 1; +var b = 0; +// ... +if ((a) => b) { + console.log('truthy value returned'); +} else { + console.log('falsey value returned'); +} +// outputs 'truthy value returned' +``` + +The following is another example of this behavior: + +```js +/*eslint-env es6*/ + +var a = 1, b = 2, c = 3, d = 4; +var f = a => b ? c: d; +// f = ? +``` + +`f` is an arrow function which takes `a` as an argument and returns the result of `b ? c: d`. + +This should be rewritten like so: + +```js +/*eslint-env es6*/ + +var a = 1, b = 2, c = 3, d = 4; +var f = (a) => b ? c: d; +``` + +### as-needed + +Examples of **incorrect** code for this rule with the `"as-needed"` option: + +```js +/*eslint arrow-parens: ["error", "as-needed"]*/ +/*eslint-env es6*/ + +(a) => {}; +(a) => a; +(a) => {'\n'}; +a.then((foo) => {}); +a.then((foo) => a); +a((foo) => { if (true) {} }); +const f = /** @type {number} */(a) => a + a; +const g = /* comment */ (a) => a + a; +const h = (a) /* comment */ => a + a; +``` + +Examples of **correct** code for this rule with the `"as-needed"` option: + +```js +/*eslint arrow-parens: ["error", "as-needed"]*/ +/*eslint-env es6*/ + +() => {}; +a => {}; +a => a; +a => {'\n'}; +a.then(foo => {}); +a.then(foo => { if (true) {} }); +(a, b, c) => a; +(a = 10) => a; +([a, b]) => a; +({a, b}) => a; +const f = (/** @type {number} */a) => a + a; +const g = (/* comment */ a) => a + a; +const h = (a /* comment */) => a + a; +``` + +### requireForBlockBody + +Examples of **incorrect** code for the `{ "requireForBlockBody": true }` option: + +```js +/*eslint arrow-parens: [2, "as-needed", { "requireForBlockBody": true }]*/ +/*eslint-env es6*/ + +(a) => a; +a => {}; +a => {'\n'}; +a.map((x) => x * x); +a.map(x => { + return x * x; +}); +a.then(foo => {}); +``` + +Examples of **correct** code for the `{ "requireForBlockBody": true }` option: + +```js +/*eslint arrow-parens: [2, "as-needed", { "requireForBlockBody": true }]*/ +/*eslint-env es6*/ + +(a) => {}; +(a) => {'\n'}; +a => ({}); +() => {}; +a => a; +a.then((foo) => {}); +a.then((foo) => { if (true) {} }); +a((foo) => { if (true) {} }); +(a, b, c) => a; +(a = 10) => a; +([a, b]) => a; +({a, b}) => a; +``` + +## Further Reading + +* The `"as-needed", { "requireForBlockBody": true }` rule is directly inspired by the Airbnb + [JS Style Guide](https://github.com/airbnb/javascript#arrows--one-arg-parens). + +## Version + +This rule was introduced in ESLint 1.0.0-rc-1. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/arrow-parens.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/arrow-parens.md) diff --git a/docs/8.0.0/rules/arrow-spacing.md b/docs/8.0.0/rules/arrow-spacing.md new file mode 100644 index 0000000000..aa31f90925 --- /dev/null +++ b/docs/8.0.0/rules/arrow-spacing.md @@ -0,0 +1,112 @@ +--- +title: arrow-spacing - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/arrow-spacing.md +rule_type: layout +--- + + +# Require space before/after arrow function's arrow (arrow-spacing) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +This rule normalize style of spacing before/after an arrow function's arrow(`=>`). + +```js +/*eslint-env es6*/ + +// { "before": true, "after": true } +(a) => {} + +// { "before": false, "after": false } +(a)=>{} +``` + +## Rule Details + +This rule takes an object argument with `before` and `after` properties, each with a Boolean value. + +The default configuration is `{ "before": true, "after": true }`. + +`true` means there should be **one or more spaces** and `false` means **no spaces**. + +Examples of **incorrect** code for this rule with the default `{ "before": true, "after": true }` option: + +```js +/*eslint arrow-spacing: "error"*/ +/*eslint-env es6*/ + +()=> {}; +() =>{}; +(a)=> {}; +(a) =>{}; +a =>a; +a=> a; +()=> {'\n'}; +() =>{'\n'}; +``` + +Examples of **correct** code for this rule with the default `{ "before": true, "after": true }` option: + +```js +/*eslint arrow-spacing: "error"*/ +/*eslint-env es6*/ + +() => {}; +(a) => {}; +a => a; +() => {'\n'}; +``` + +Examples of **incorrect** code for this rule with the `{ "before": false, "after": false }` option: + +```js +/*eslint arrow-spacing: ["error", { "before": false, "after": false }]*/ +/*eslint-env es6*/ + +() =>{}; +(a) => {}; +()=> {'\n'}; +``` + +Examples of **correct** code for this rule with the `{ "before": false, "after": false }` option: + +```js +/*eslint arrow-spacing: ["error", { "before": false, "after": false }]*/ +/*eslint-env es6*/ + +()=>{}; +(a)=>{}; +()=>{'\n'}; +``` + +Examples of **incorrect** code for this rule with the `{ "before": false, "after": true }` option: + +```js +/*eslint arrow-spacing: ["error", { "before": false, "after": true }]*/ +/*eslint-env es6*/ + +() =>{}; +(a) => {}; +()=>{'\n'}; +``` + +Examples of **correct** code for this rule with the `{ "before": false, "after": true }` option: + +```js +/*eslint arrow-spacing: ["error", { "before": false, "after": true }]*/ +/*eslint-env es6*/ + +()=> {}; +(a)=> {}; +()=> {'\n'}; +``` + +## Version + +This rule was introduced in ESLint 1.0.0-rc-1. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/arrow-spacing.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/arrow-spacing.md) diff --git a/docs/8.0.0/rules/block-scoped-var.md b/docs/8.0.0/rules/block-scoped-var.md new file mode 100644 index 0000000000..72ffeb5f68 --- /dev/null +++ b/docs/8.0.0/rules/block-scoped-var.md @@ -0,0 +1,110 @@ +--- +title: block-scoped-var - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/block-scoped-var.md +rule_type: suggestion +--- + + +# Treat var as Block Scoped (block-scoped-var) + +The `block-scoped-var` rule generates warnings when variables are used outside of the block in which they were defined. This emulates C-style block scope. + +## Rule Details + +This rule aims to reduce the usage of variables outside of their binding context and emulate traditional block scope from other languages. This is to help newcomers to the language avoid difficult bugs with variable hoisting. + +Examples of **incorrect** code for this rule: + +```js +/*eslint block-scoped-var: "error"*/ + +function doIf() { + if (true) { + var build = true; + } + + console.log(build); +} + +function doIfElse() { + if (true) { + var build = true; + } else { + var build = false; + } +} + +function doTryCatch() { + try { + var build = 1; + } catch (e) { + var f = build; + } +} + +function doFor() { + for (var x = 1; x < 10; x++) { + var y = f(x); + } + console.log(y); +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint block-scoped-var: "error"*/ + +function doIf() { + var build; + + if (true) { + build = true; + } + + console.log(build); +} + +function doIfElse() { + var build; + + if (true) { + build = true; + } else { + build = false; + } +} + +function doTryCatch() { + var build; + var f; + + try { + build = 1; + } catch (e) { + f = build; + } +} + +function doFor() { + for (var x = 1; x < 10; x++) { + var y = f(x); + console.log(y); + } +} +``` + +## Further Reading + +* [JavaScript Scoping and Hoisting](http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html) +* [var Hoisting](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var#var_hoisting) + +## Version + +This rule was introduced in ESLint 0.1.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/block-scoped-var.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/block-scoped-var.md) diff --git a/docs/8.0.0/rules/block-spacing.md b/docs/8.0.0/rules/block-spacing.md new file mode 100644 index 0000000000..8210a28668 --- /dev/null +++ b/docs/8.0.0/rules/block-spacing.md @@ -0,0 +1,78 @@ +--- +title: block-spacing - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/block-spacing.md +rule_type: layout +--- + + +# Disallow or enforce spaces inside of blocks after opening block and before closing block (block-spacing) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +## Rule Details + +This rule enforces consistent spacing inside an open block token and the next token on the same line. This rule also enforces consistent spacing inside a close block token and previous token on the same line. + +## Options + +This rule has a string option: + +* `"always"` (default) requires one or more spaces +* `"never"` disallows spaces + +### always + +Examples of **incorrect** code for this rule with the default `"always"` option: + +```js +/*eslint block-spacing: "error"*/ + +function foo() {return true;} +if (foo) { bar = 0;} +function baz() {let i = 0; + return i; +} +``` + +Examples of **correct** code for this rule with the default `"always"` option: + +```js +/*eslint block-spacing: "error"*/ + +function foo() { return true; } +if (foo) { bar = 0; } +``` + +### never + +Examples of **incorrect** code for this rule with the `"never"` option: + +```js +/*eslint block-spacing: ["error", "never"]*/ + +function foo() { return true; } +if (foo) { bar = 0;} +``` + +Examples of **correct** code for this rule with the `"never"` option: + +```js +/*eslint block-spacing: ["error", "never"]*/ + +function foo() {return true;} +if (foo) {bar = 0;} +``` + +## When Not To Use It + +If you don't want to be notified about spacing style inside of blocks, you can safely disable this rule. + +## Version + +This rule was introduced in ESLint 1.2.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/block-spacing.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/block-spacing.md) diff --git a/docs/8.0.0/rules/brace-style.md b/docs/8.0.0/rules/brace-style.md new file mode 100644 index 0000000000..20bfe191af --- /dev/null +++ b/docs/8.0.0/rules/brace-style.md @@ -0,0 +1,344 @@ +--- +title: brace-style - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/brace-style.md +rule_type: layout +--- + + +# Require Brace Style (brace-style) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +Brace style is closely related to [indent style](https://en.wikipedia.org/wiki/Indent_style) in programming and describes the placement of braces relative to their control statement and body. There are probably a dozen, if not more, brace styles in the world. + +The *one true brace style* is one of the most common brace styles in JavaScript, in which the opening brace of a block is placed on the same line as its corresponding statement or declaration. For example: + +```js +if (foo) { + bar(); +} else { + baz(); +} +``` + +One common variant of one true brace style is called Stroustrup, in which the `else` statements in an `if-else` construct, as well as `catch` and `finally`, must be on its own line after the preceding closing brace. For example: + +```js +if (foo) { + bar(); +} +else { + baz(); +} +``` + +Another style is called [Allman](https://en.wikipedia.org/wiki/Indent_style#Allman_style), in which all the braces are expected to be on their own lines without any extra indentation. For example: + +```js +if (foo) +{ + bar(); +} +else +{ + baz(); +} +``` + +While no style is considered better than the other, most developers agree that having a consistent style throughout a project is important for its long-term maintainability. + +## Rule Details + +This rule enforces consistent brace style for blocks. + +## Options + +This rule has a string option: + +* `"1tbs"` (default) enforces one true brace style +* `"stroustrup"` enforces Stroustrup style +* `"allman"` enforces Allman style + +This rule has an object option for an exception: + +* `"allowSingleLine": true` (default `false`) allows the opening and closing braces for a block to be on the *same* line + +### 1tbs + +Examples of **incorrect** code for this rule with the default `"1tbs"` option: + +```js +/*eslint brace-style: "error"*/ + +function foo() +{ + return true; +} + +if (foo) +{ + bar(); +} + +try +{ + somethingRisky(); +} catch(e) +{ + handleError(); +} + +if (foo) { + bar(); +} +else { + baz(); +} +``` + +Examples of **correct** code for this rule with the default `"1tbs"` option: + +```js +/*eslint brace-style: "error"*/ + +function foo() { + return true; +} + +if (foo) { + bar(); +} + +if (foo) { + bar(); +} else { + baz(); +} + +try { + somethingRisky(); +} catch(e) { + handleError(); +} + +// when there are no braces, there are no problems +if (foo) bar(); +else if (baz) boom(); +``` + +Examples of **correct** code for this rule with the `"1tbs", { "allowSingleLine": true }` options: + +```js +/*eslint brace-style: ["error", "1tbs", { "allowSingleLine": true }]*/ + +function nop() { return; } + +if (foo) { bar(); } + +if (foo) { bar(); } else { baz(); } + +try { somethingRisky(); } catch(e) { handleError(); } + +if (foo) { baz(); } else { + boom(); +} + +if (foo) { baz(); } else if (bar) { + boom(); +} + +if (foo) { baz(); } else +if (bar) { + boom(); +} + +if (foo) { baz(); } else if (bar) { + boom(); +} + +try { somethingRisky(); } catch(e) { + handleError(); +} +``` + +### stroustrup + +Examples of **incorrect** code for this rule with the `"stroustrup"` option: + +```js +/*eslint brace-style: ["error", "stroustrup"]*/ + +function foo() +{ + return true; +} + +if (foo) +{ + bar(); +} + +try +{ + somethingRisky(); +} catch(e) +{ + handleError(); +} + +if (foo) { + bar(); +} else { + baz(); +} +``` + +Examples of **correct** code for this rule with the `"stroustrup"` option: + +```js +/*eslint brace-style: ["error", "stroustrup"]*/ + +function foo() { + return true; +} + +if (foo) { + bar(); +} + +if (foo) { + bar(); +} +else { + baz(); +} + +try { + somethingRisky(); +} +catch(e) { + handleError(); +} + +// when there are no braces, there are no problems +if (foo) bar(); +else if (baz) boom(); +``` + +Examples of **correct** code for this rule with the `"stroustrup", { "allowSingleLine": true }` options: + +```js +/*eslint brace-style: ["error", "stroustrup", { "allowSingleLine": true }]*/ + +function nop() { return; } + +if (foo) { bar(); } + +if (foo) { bar(); } +else { baz(); } + +try { somethingRisky(); } +catch(e) { handleError(); } +``` + +### allman + +Examples of **incorrect** code for this rule with the `"allman"` option: + +```js +/*eslint brace-style: ["error", "allman"]*/ + +function foo() { + return true; +} + +if (foo) +{ + bar(); } + +try +{ + somethingRisky(); +} catch(e) +{ + handleError(); +} + +if (foo) { + bar(); +} else { + baz(); +} +``` + +Examples of **correct** code for this rule with the `"allman"` option: + +```js +/*eslint brace-style: ["error", "allman"]*/ + +function foo() +{ + return true; +} + +if (foo) +{ + bar(); +} + +if (foo) +{ + bar(); +} +else +{ + baz(); +} + +try +{ + somethingRisky(); +} +catch(e) +{ + handleError(); +} + +// when there are no braces, there are no problems +if (foo) bar(); +else if (baz) boom(); +``` + +Examples of **correct** code for this rule with the `"allman", { "allowSingleLine": true }` options: + +```js +/*eslint brace-style: ["error", "allman", { "allowSingleLine": true }]*/ + +function nop() { return; } + +if (foo) { bar(); } + +if (foo) { bar(); } +else { baz(); } + +try { somethingRisky(); } +catch(e) { handleError(); } +``` + +## When Not To Use It + +If you don't want to enforce a particular brace style, don't enable this rule. + +## Further Reading + +* [Indent style](https://en.wikipedia.org/wiki/Indent_style) + +## Version + +This rule was introduced in ESLint 0.0.7. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/brace-style.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/brace-style.md) diff --git a/docs/8.0.0/rules/callback-return.md b/docs/8.0.0/rules/callback-return.md new file mode 100644 index 0000000000..bfe410912b --- /dev/null +++ b/docs/8.0.0/rules/callback-return.md @@ -0,0 +1,193 @@ +--- +title: callback-return - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/callback-return.md +rule_type: suggestion +--- + + +# Enforce Return After Callback (callback-return) + +This rule was **deprecated** in ESLint v7.0.0. Please use the corresponding rule in [`eslint-plugin-node`](https://github.com/mysticatea/eslint-plugin-node). + +The callback pattern is at the heart of most I/O and event-driven programming + in JavaScript. + +```js +function doSomething(err, callback) { + if (err) { + return callback(err); + } + callback(); +} +``` + +To prevent calling the callback multiple times it is important to `return` anytime the callback is triggered outside + of the main function body. Neglecting this technique often leads to issues where you do something more than once. + For example, in the case of an HTTP request, you may try to send HTTP headers more than once leading Node.js to `throw` + a `Can't render headers after they are sent to the client.` error. + +## Rule Details + +This rule is aimed at ensuring that callbacks used outside of the main function block are always part-of or immediately +preceding a `return` statement. This rule decides what is a callback based on the name of the function being called. + +## Options + +The rule takes a single option - an array of possible callback names - which may include object methods. The default callback names are `callback`, `cb`, `next`. + +### Default callback names + +Examples of **incorrect** code for this rule with the default `["callback", "cb", "next"]` option: + +```js +/*eslint callback-return: "error"*/ + +function foo(err, callback) { + if (err) { + callback(err); + } + callback(); +} +``` + +Examples of **correct** code for this rule with the default `["callback", "cb", "next"]` option: + +```js +/*eslint callback-return: "error"*/ + +function foo(err, callback) { + if (err) { + return callback(err); + } + callback(); +} +``` + +### Supplied callback names + +Examples of **incorrect** code for this rule with the option `["done", "send.error", "send.success"]`: + +```js +/*eslint callback-return: ["error", ["done", "send.error", "send.success"]]*/ + +function foo(err, done) { + if (err) { + done(err); + } + done(); +} + +function bar(err, send) { + if (err) { + send.error(err); + } + send.success(); +} +``` + +Examples of **correct** code for this rule with the option `["done", "send.error", "send.success"]`: + +```js +/*eslint callback-return: ["error", ["done", "send.error", "send.success"]]*/ + +function foo(err, done) { + if (err) { + return done(err); + } + done(); +} + +function bar(err, send) { + if (err) { + return send.error(err); + } + send.success(); +} +``` + +## Known Limitations + +Because it is difficult to understand the meaning of a program through static analysis, this rule has limitations: + +* *false negatives* when this rule reports correct code, but the program calls the callback more than one time (which is incorrect behavior) +* *false positives* when this rule reports incorrect code, but the program calls the callback only one time (which is correct behavior) + +### Passing the callback by reference + +The static analysis of this rule does not detect that the program calls the callback if it is an argument of a function (for example, `setTimeout`). + +Example of a *false negative* when this rule reports correct code: + +```js +/*eslint callback-return: "error"*/ + +function foo(err, callback) { + if (err) { + setTimeout(callback, 0); // this is bad, but WILL NOT warn + } + callback(); +} +``` + +### Triggering the callback within a nested function + +The static analysis of this rule does not detect that the program calls the callback from within a nested function or an immediately-invoked function expression (IIFE). + +Example of a *false negative* when this rule reports correct code: + +```js +/*eslint callback-return: "error"*/ + +function foo(err, callback) { + if (err) { + process.nextTick(function() { + return callback(); // this is bad, but WILL NOT warn + }); + } + callback(); +} +``` + +### If/else statements + +The static analysis of this rule does not detect that the program calls the callback only one time in each branch of an `if` statement. + +Example of a *false positive* when this rule reports incorrect code: + +```js +/*eslint callback-return: "error"*/ + +function foo(err, callback) { + if (err) { + callback(err); // this is fine, but WILL warn + } else { + callback(); // this is fine, but WILL warn + } +} +``` + +## When Not To Use It + +There are some cases where you might want to call a callback function more than once. In those cases this rule + may lead to incorrect behavior. In those cases you may want to reserve a special name for those callbacks and + not include that in the list of callbacks that trigger warnings. + + +## Further Reading + +* [The Art Of Node: Callbacks](https://github.com/maxogden/art-of-node#callbacks) +* [Nodejitsu: What are the error conventions?](https://docs.nodejitsu.com/articles/errors/what-are-the-error-conventions/) + +## Related Rules + +* [handle-callback-err](handle-callback-err) + +## Version + +This rule was introduced in ESLint 1.0.0-rc-1. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/callback-return.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/callback-return.md) diff --git a/docs/8.0.0/rules/camelcase.md b/docs/8.0.0/rules/camelcase.md new file mode 100644 index 0000000000..647771f447 --- /dev/null +++ b/docs/8.0.0/rules/camelcase.md @@ -0,0 +1,287 @@ +--- +title: camelcase - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/camelcase.md +rule_type: suggestion +--- + + +# Require CamelCase (camelcase) + +When it comes to naming variables, style guides generally fall into one of two camps: camelcase (`variableName`) and underscores (`variable_name`). This rule focuses on using the camelcase approach. If your style guide calls for camelCasing your variable names, then this rule is for you! + +## Rule Details + +This rule looks for any underscores (`_`) located within the source code. It ignores leading and trailing underscores and only checks those in the middle of a variable name. If ESLint decides that the variable is a constant (all uppercase), then no warning will be thrown. Otherwise, a warning will be thrown. This rule only flags definitions and assignments but not function calls. In case of ES6 `import` statements, this rule only targets the name of the variable that will be imported into the local module scope. + +## Options + +This rule has an object option: + +* `"properties": "always"` (default) enforces camelcase style for property names +* `"properties": "never"` does not check property names +* `"ignoreDestructuring": false` (default) enforces camelcase style for destructured identifiers +* `"ignoreDestructuring": true` does not check destructured identifiers (but still checks any use of those identifiers later in the code) +* `"ignoreImports": false` (default) enforces camelcase style for ES2015 imports +* `"ignoreImports": true` does not check ES2015 imports (but still checks any use of the imports later in the code except function arguments) +* `"ignoreGlobals": false` (default) enforces camelcase style for global variables +* `"ignoreGlobals": true` does not enforce camelcase style for global variables +* `allow` (`string[]`) list of properties to accept. Accept regex. + +### properties: "always" + +Examples of **incorrect** code for this rule with the default `{ "properties": "always" }` option: + +```js +/*eslint camelcase: "error"*/ + +import { no_camelcased } from "external-module" + +var my_favorite_color = "#112C85"; + +function do_something() { + // ... +} + +obj.do_something = function() { + // ... +}; + +function foo({ no_camelcased }) { + // ... +}; + +function foo({ isCamelcased: no_camelcased }) { + // ... +} + +function foo({ no_camelcased = 'default value' }) { + // ... +}; + +var obj = { + my_pref: 1 +}; + +var { category_id = 1 } = query; + +var { foo: no_camelcased } = bar; + +var { foo: bar_baz = 1 } = quz; +``` + +Examples of **correct** code for this rule with the default `{ "properties": "always" }` option: + +```js +/*eslint camelcase: "error"*/ + +import { no_camelcased as camelCased } from "external-module"; + +var myFavoriteColor = "#112C85"; +var _myFavoriteColor = "#112C85"; +var myFavoriteColor_ = "#112C85"; +var MY_FAVORITE_COLOR = "#112C85"; +var foo = bar.baz_boom; +var foo = { qux: bar.baz_boom }; + +obj.do_something(); +do_something(); +new do_something(); + +var { category_id: category } = query; + +function foo({ isCamelCased }) { + // ... +}; + +function foo({ isCamelCased: isAlsoCamelCased }) { + // ... +} + +function foo({ isCamelCased = 'default value' }) { + // ... +}; + +var { categoryId = 1 } = query; + +var { foo: isCamelCased } = bar; + +var { foo: isCamelCased = 1 } = quz; + +``` + +### properties: "never" + +Examples of **correct** code for this rule with the `{ "properties": "never" }` option: + +```js +/*eslint camelcase: ["error", {properties: "never"}]*/ + +var obj = { + my_pref: 1 +}; +``` + +### ignoreDestructuring: false + +Examples of **incorrect** code for this rule with the default `{ "ignoreDestructuring": false }` option: + +```js +/*eslint camelcase: "error"*/ + +var { category_id } = query; + +var { category_id = 1 } = query; + +var { category_id: category_id } = query; + +var { category_id: category_alias } = query; + +var { category_id: categoryId, ...other_props } = query; +``` + +### ignoreDestructuring: true + +Examples of **incorrect** code for this rule with the `{ "ignoreDestructuring": true }` option: + +```js +/*eslint camelcase: ["error", {ignoreDestructuring: true}]*/ + +var { category_id: category_alias } = query; + +var { category_id, ...other_props } = query; +``` + +Examples of **correct** code for this rule with the `{ "ignoreDestructuring": true }` option: + +```js +/*eslint camelcase: ["error", {ignoreDestructuring: true}]*/ + +var { category_id } = query; + +var { category_id = 1 } = query; + +var { category_id: category_id } = query; +``` + +Please note that this option applies only to identifiers inside destructuring patterns. It doesn't additionally allow any particular use of the created variables later in the code apart from the use that is already allowed by default or by other options. + +Examples of additional **incorrect** code for this rule with the `{ "ignoreDestructuring": true }` option: + +```js +/*eslint camelcase: ["error", {ignoreDestructuring: true}]*/ + +var { some_property } = obj; // allowed by {ignoreDestructuring: true} +var foo = some_property + 1; // error, ignoreDestructuring does not apply to this statement +``` + +A common use case for this option is to avoid useless renaming when the identifier is not intended to be used later in the code. + +Examples of additional **correct** code for this rule with the `{ "ignoreDestructuring": true }` option: + +```js +/*eslint camelcase: ["error", {ignoreDestructuring: true}]*/ + +var { some_property, ...rest } = obj; +// do something with 'rest', nothing with 'some_property' +``` + +Another common use case for this option is in combination with `{ "properties": "never" }`, when the identifier is intended to be used only as a property shorthand. + +Examples of additional **correct** code for this rule with the `{ "properties": "never", "ignoreDestructuring": true }` options: + +```js +/*eslint camelcase: ["error", {"properties": "never", ignoreDestructuring: true}]*/ + +var { some_property } = obj; +doSomething({ some_property }); +``` + +### ignoreImports: false + +Examples of **incorrect** code for this rule with the default `{ "ignoreImports": false }` option: + +```js +/*eslint camelcase: "error"*/ + +import { snake_cased } from 'mod'; +``` + +### ignoreImports: true + +Examples of **incorrect** code for this rule with the `{ "ignoreImports": true }` option: + +```js +/*eslint camelcase: ["error", {ignoreImports: true}]*/ + +import default_import from 'mod'; + +import * as namespaced_import from 'mod'; +``` + +Examples of **correct** code for this rule with the `{ "ignoreImports": true }` option: + +```js +/*eslint camelcase: ["error", {ignoreImports: true}]*/ + +import { snake_cased } from 'mod'; +``` + +### ignoreGlobals: false + +Examples of **incorrect** code for this rule with the default `{ "ignoreGlobals": false }` option: + +```js +/*eslint camelcase: ["error", {ignoreGlobals: false}]*/ +/* global no_camelcased */ + +const foo = no_camelcased; +``` + +### ignoreGlobals: true + +Examples of **correct** code for this rule with the `{ "ignoreGlobals": true }` option: + +```js +/*eslint camelcase: ["error", {ignoreGlobals: true}]*/ +/* global no_camelcased */ + +const foo = no_camelcased; +``` + +## allow + +Examples of **correct** code for this rule with the `allow` option: + +```js +/*eslint camelcase: ["error", {allow: ["UNSAFE_componentWillMount"]}]*/ + +function UNSAFE_componentWillMount() { + // ... +} +``` + +```js +/*eslint camelcase: ["error", {allow: ["^UNSAFE_"]}]*/ + +function UNSAFE_componentWillMount() { + // ... +} + +function UNSAFE_componentWillMount() { + // ... +} +``` + +## When Not To Use It + +If you have established coding standards using a different naming convention (separating words with underscores), turn this rule off. + +## Version + +This rule was introduced in ESLint 0.0.2. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/camelcase.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/camelcase.md) diff --git a/docs/8.0.0/rules/capitalized-comments.md b/docs/8.0.0/rules/capitalized-comments.md new file mode 100644 index 0000000000..a76f44b6c4 --- /dev/null +++ b/docs/8.0.0/rules/capitalized-comments.md @@ -0,0 +1,268 @@ +--- +title: capitalized-comments - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/capitalized-comments.md +rule_type: suggestion +--- + + +# enforce or disallow capitalization of the first letter of a comment (capitalized-comments) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +Comments are useful for leaving information for future developers. In order for that information to be useful and not distracting, it is sometimes desirable for comments to follow a particular style. One element of comment formatting styles is whether the first word of a comment should be capitalized or lowercase. + +In general, no comment style is any more or less valid than any others, but many developers would agree that a consistent style can improve a project's maintainability. + +## Rule Details + +This rule aims to enforce a consistent style of comments across your codebase, specifically by either requiring or disallowing a capitalized letter as the first word character in a comment. This rule will not issue warnings when non-cased letters are used. + +By default, this rule will require a non-lowercase letter at the beginning of comments. + +Examples of **incorrect** code for this rule: + +```js +/* eslint capitalized-comments: ["error"] */ + +// lowercase comment + +``` + +Examples of **correct** code for this rule: + +```js + +// Capitalized comment + +// 1. Non-letter at beginning of comment + +// 丈 Non-Latin character at beginning of comment + +/* eslint semi:off */ +/* eslint-env node */ +/* eslint-disable */ +/* eslint-enable */ +/* istanbul ignore next */ +/* jscs:enable */ +/* jshint asi:true */ +/* global foo */ +/* globals foo */ +/* exported myVar */ +// eslint-disable-line +// eslint-disable-next-line +// https://github.com + +``` + +### Options + +This rule has two options: a string value `"always"` or `"never"` which determines whether capitalization of the first word of a comment should be required or forbidden, and optionally an object containing more configuration parameters for the rule. + +Here are the supported object options: + +* `ignorePattern`: A string representing a regular expression pattern of words that should be ignored by this rule. If the first word of a comment matches the pattern, this rule will not report that comment. + * Note that the following words are always ignored by this rule: `["jscs", "jshint", "eslint", "istanbul", "global", "globals", "exported"]`. +* `ignoreInlineComments`: If this is `true`, the rule will not report on comments in the middle of code. By default, this is `false`. +* `ignoreConsecutiveComments`: If this is `true`, the rule will not report on a comment which violates the rule, as long as the comment immediately follows another comment. By default, this is `false`. + +Here is an example configuration: + +```json +{ + "capitalized-comments": [ + "error", + "always", + { + "ignorePattern": "pragma|ignored", + "ignoreInlineComments": true + } + ] +} +``` + +#### `"always"` + +Using the `"always"` option means that this rule will report any comments which start with a lowercase letter. This is the default configuration for this rule. + +Note that configuration comments and comments which start with URLs are never reported. + +Examples of **incorrect** code for this rule: + +```js +/* eslint capitalized-comments: ["error", "always"] */ + +// lowercase comment + +``` + +Examples of **correct** code for this rule: + +```js +/* eslint capitalized-comments: ["error", "always"] */ + +// Capitalized comment + +// 1. Non-letter at beginning of comment + +// 丈 Non-Latin character at beginning of comment + +/* eslint semi:off */ +/* eslint-env node */ +/* eslint-disable */ +/* eslint-enable */ +/* istanbul ignore next */ +/* jscs:enable */ +/* jshint asi:true */ +/* global foo */ +/* globals foo */ +/* exported myVar */ +// eslint-disable-line +// eslint-disable-next-line +// https://github.com + +``` + +#### `"never"` + +Using the `"never"` option means that this rule will report any comments which start with an uppercase letter. + +Examples of **incorrect** code with the `"never"` option: + +```js +/* eslint capitalized-comments: ["error", "never"] */ + +// Capitalized comment + +``` + +Examples of **correct** code with the `"never"` option: + +```js +/* eslint capitalized-comments: ["error", "never"] */ + +// lowercase comment + +// 1. Non-letter at beginning of comment + +// 丈 Non-Latin character at beginning of comment + +``` + +#### `ignorePattern` + +The `ignorePattern` object takes a string value, which is used as a regular expression applied to the first word of a comment. + +Examples of **correct** code with the `"ignorePattern"` option set to `"pragma"`: + +```js +/* eslint capitalized-comments: ["error", "always", { "ignorePattern": "pragma" }] */ + +function foo() { + /* pragma wrap(true) */ +} + +``` + +#### `ignoreInlineComments` + +Setting the `ignoreInlineComments` option to `true` means that comments in the middle of code (with a token on the same line as the beginning of the comment, and another token on the same line as the end of the comment) will not be reported by this rule. + +Examples of **correct** code with the `"ignoreInlineComments"` option set to `true`: + +```js +/* eslint capitalized-comments: ["error", "always", { "ignoreInlineComments": true }] */ + +function foo(/* ignored */ a) { +} + +``` + +#### `ignoreConsecutiveComments` + +If the `ignoreConsecutiveComments` option is set to `true`, then comments which otherwise violate the rule will not be reported as long as they immediately follow another comment. This can be applied more than once. + +Examples of **correct** code with `ignoreConsecutiveComments` set to `true`: + +```js +/* eslint capitalized-comments: ["error", "always", { "ignoreConsecutiveComments": true }] */ + +// This comment is valid since it has the correct capitalization. +// this comment is ignored since it follows another comment, +// and this one as well because it follows yet another comment. + +/* Here is a block comment which has the correct capitalization, */ +/* but this one is ignored due to being consecutive; */ +/* + * in fact, even if any of these are multi-line, that is fine too. + */ +``` + +Examples of **incorrect** code with `ignoreConsecutiveComments` set to `true`: + +```js +/* eslint capitalized-comments: ["error", "always", { "ignoreConsecutiveComments": true }] */ + +// this comment is invalid, but only on this line. +// this comment does NOT get reported, since it is a consecutive comment. +``` + +### Using Different Options for Line and Block Comments + +If you wish to have a different configuration for line comments and block comments, you can do so by using two different object configurations (note that the capitalization option will be enforced consistently for line and block comments): + +```json +{ + "capitalized-comments": [ + "error", + "always", + { + "line": { + "ignorePattern": "pragma|ignored", + }, + "block": { + "ignoreInlineComments": true, + "ignorePattern": "ignored" + } + } + ] +} +``` + +Examples of **incorrect** code with different line and block comment configuration: + +```js +/* eslint capitalized-comments: ["error", "always", { "block": { "ignorePattern": "blockignore" } }] */ + +// capitalized line comment, this is incorrect, blockignore does not help here +/* lowercased block comment, this is incorrect too */ + +``` + +Examples of **correct** code with different line and block comment configuration: + +```js +/* eslint capitalized-comments: ["error", "always", { "block": { "ignorePattern": "blockignore" } }] */ + +// Uppercase line comment, this is correct +/* blockignore lowercase block comment, this is correct due to ignorePattern */ + +``` + +## When Not To Use It + +This rule can be disabled if you do not care about the grammatical style of comments in your codebase. + +## Compatibility + +* **JSCS**: [requireCapitalizedComments](https://jscs-dev.github.io/rule/requireCapitalizedComments) +* **JSCS**: [disallowCapitalizedComments](https://jscs-dev.github.io/rule/disallowCapitalizedComments) + +## Version + +This rule was introduced in ESLint 3.11.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/capitalized-comments.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/capitalized-comments.md) diff --git a/docs/8.0.0/rules/class-methods-use-this.md b/docs/8.0.0/rules/class-methods-use-this.md new file mode 100644 index 0000000000..42ed703ba9 --- /dev/null +++ b/docs/8.0.0/rules/class-methods-use-this.md @@ -0,0 +1,141 @@ +--- +title: class-methods-use-this - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/class-methods-use-this.md +rule_type: suggestion +--- + + +# Enforce that class methods utilize `this` (class-methods-use-this) + +If a class method does not use `this`, it can *sometimes* be made into a static function. If you do convert the method into a static function, instances of the class that call that particular method have to be converted to a static call as well (`MyClass.callStaticMethod()`) + +It's possible to have a class method which doesn't use `this`, such as: + +```js +class A { + constructor() { + this.a = "hi"; + } + + print() { + console.log(this.a); + } + + sayHi() { + console.log("hi"); + } +} + +let a = new A(); +a.sayHi(); // => "hi" +``` + +In the example above, the `sayHi` method doesn't use `this`, so we can make it a static method: + +```js +class A { + constructor() { + this.a = "hi"; + } + + print() { + console.log(this.a); + } + + static sayHi() { + console.log("hi"); + } +} + +A.sayHi(); // => "hi" +``` + +Also note in the above examples that if you switch a method to a static method, *instances* of the class that call the static method (`let a = new A(); a.sayHi();`) have to be updated to being a static call (`A.sayHi();`) instead of having the instance of the *class* call the method + +## Rule Details + +This rule is aimed to flag class methods that do not use `this`. + +Examples of **incorrect** code for this rule: + +```js +/*eslint class-methods-use-this: "error"*/ +/*eslint-env es6*/ + +class A { + foo() { + console.log("Hello World"); /*error Expected 'this' to be used by class method 'foo'.*/ + } +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint class-methods-use-this: "error"*/ +/*eslint-env es6*/ +class A { + foo() { + this.bar = "Hello World"; // OK, this is used + } +} + +class A { + constructor() { + // OK. constructor is exempt + } +} + +class A { + static foo() { + // OK. static methods aren't expected to use this. + } +} +``` + +## Options + +### Exceptions + +``` +"class-methods-use-this": [, { "exceptMethods": [<...exceptions>] }] +``` + +The `exceptMethods` option allows you to pass an array of method names for which you would like to ignore warnings. For example, you might have a spec from an external library that requires you to overwrite a method as a regular function (and not as a static method) and does not use `this` inside the function body. In this case, you can add that method to ignore in the warnings. + +Examples of **incorrect** code for this rule when used without exceptMethods: + +```js +/*eslint class-methods-use-this: "error"*/ + +class A { + foo() { + } +} +``` + +Examples of **correct** code for this rule when used with exceptMethods: + +```js +/*eslint class-methods-use-this: ["error", { "exceptMethods": ["foo"] }] */ + +class A { + foo() { + } +} +``` + +## Further Reading + +* [Classes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes) +* [Static Methods](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static) + +## Version + +This rule was introduced in ESLint 3.4.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/class-methods-use-this.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/class-methods-use-this.md) diff --git a/docs/8.0.0/rules/comma-dangle.md b/docs/8.0.0/rules/comma-dangle.md new file mode 100644 index 0000000000..3dc37af4a8 --- /dev/null +++ b/docs/8.0.0/rules/comma-dangle.md @@ -0,0 +1,334 @@ +--- +title: comma-dangle - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/comma-dangle.md +rule_type: layout +--- + + +# require or disallow trailing commas (comma-dangle) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +Trailing commas in object literals are valid according to the ECMAScript 5 (and ECMAScript 3!) spec. However, IE8 (when not in IE8 document mode) and below will throw an error when it encounters trailing commas in JavaScript. + +```js +var foo = { + bar: "baz", + qux: "quux", +}; +``` + +Trailing commas simplify adding and removing items to objects and arrays, since only the lines you are modifying must be touched. +Another argument in favor of trailing commas is that it improves the clarity of diffs when an item is added or removed from an object or array: + +Less clear: + +```diff + var foo = { +- bar: "baz", +- qux: "quux" ++ bar: "baz" + }; +``` + +More clear: + +```diff + var foo = { + bar: "baz", +- qux: "quux", + }; +``` + +## Rule Details + +This rule enforces consistent use of trailing commas in object and array literals. + +## Options + +This rule has a string option or an object option: + +```json +{ + "comma-dangle": ["error", "never"], + // or + "comma-dangle": ["error", { + "arrays": "never", + "objects": "never", + "imports": "never", + "exports": "never", + "functions": "never" + }] +} +``` + +* `"never"` (default) disallows trailing commas +* `"always"` requires trailing commas +* `"always-multiline"` requires trailing commas when the last element or property is in a *different* line than the closing `]` or `}` and disallows trailing commas when the last element or property is on the *same* line as the closing `]` or `}` +* `"only-multiline"` allows (but does not require) trailing commas when the last element or property is in a *different* line than the closing `]` or `}` and disallows trailing commas when the last element or property is on the *same* line as the closing `]` or `}` + +You can also use an object option to configure this rule for each type of syntax. +Each of the following options can be set to `"never"`, `"always"`, `"always-multiline"`, `"only-multiline"`, or `"ignore"`. +The default for each option is `"never"` unless otherwise specified. + +* `arrays` is for array literals and array patterns of destructuring. (e.g. `let [a,] = [1,];`) +* `objects` is for object literals and object patterns of destructuring. (e.g. `let {a,} = {a: 1};`) +* `imports` is for import declarations of ES Modules. (e.g. `import {a,} from "foo";`) +* `exports` is for export declarations of ES Modules. (e.g. `export {a,};`) +* `functions` is for function declarations and function calls. (e.g. `(function(a,){ })(b,);`) + * `functions` should only be enabled when linting ECMAScript 2017 or higher. + +### never + +Examples of **incorrect** code for this rule with the default `"never"` option: + +```js +/*eslint comma-dangle: ["error", "never"]*/ + +var foo = { + bar: "baz", + qux: "quux", +}; + +var arr = [1,2,]; + +foo({ + bar: "baz", + qux: "quux", +}); +``` + +Examples of **correct** code for this rule with the default `"never"` option: + +```js +/*eslint comma-dangle: ["error", "never"]*/ + +var foo = { + bar: "baz", + qux: "quux" +}; + +var arr = [1,2]; + +foo({ + bar: "baz", + qux: "quux" +}); +``` + +### always + +Examples of **incorrect** code for this rule with the `"always"` option: + +```js +/*eslint comma-dangle: ["error", "always"]*/ + +var foo = { + bar: "baz", + qux: "quux" +}; + +var arr = [1,2]; + +foo({ + bar: "baz", + qux: "quux" +}); +``` + +Examples of **correct** code for this rule with the `"always"` option: + +```js +/*eslint comma-dangle: ["error", "always"]*/ + +var foo = { + bar: "baz", + qux: "quux", +}; + +var arr = [1,2,]; + +foo({ + bar: "baz", + qux: "quux", +}); +``` + +### always-multiline + +Examples of **incorrect** code for this rule with the `"always-multiline"` option: + +```js +/*eslint comma-dangle: ["error", "always-multiline"]*/ + +var foo = { + bar: "baz", + qux: "quux" +}; + +var foo = { bar: "baz", qux: "quux", }; + +var arr = [1,2,]; + +var arr = [1, + 2,]; + +var arr = [ + 1, + 2 +]; + +foo({ + bar: "baz", + qux: "quux" +}); +``` + +Examples of **correct** code for this rule with the `"always-multiline"` option: + +```js +/*eslint comma-dangle: ["error", "always-multiline"]*/ + +var foo = { + bar: "baz", + qux: "quux", +}; + +var foo = {bar: "baz", qux: "quux"}; +var arr = [1,2]; + +var arr = [1, + 2]; + +var arr = [ + 1, + 2, +]; + +foo({ + bar: "baz", + qux: "quux", +}); +``` + +### only-multiline + +Examples of **incorrect** code for this rule with the `"only-multiline"` option: + +```js +/*eslint comma-dangle: ["error", "only-multiline"]*/ + +var foo = { bar: "baz", qux: "quux", }; + +var arr = [1,2,]; + +var arr = [1, + 2,]; + +``` + +Examples of **correct** code for this rule with the `"only-multiline"` option: + +```js +/*eslint comma-dangle: ["error", "only-multiline"]*/ + +var foo = { + bar: "baz", + qux: "quux", +}; + +var foo = { + bar: "baz", + qux: "quux" +}; + +var foo = {bar: "baz", qux: "quux"}; +var arr = [1,2]; + +var arr = [1, + 2]; + +var arr = [ + 1, + 2, +]; + +var arr = [ + 1, + 2 +]; + +foo({ + bar: "baz", + qux: "quux", +}); + +foo({ + bar: "baz", + qux: "quux" +}); +``` + +### functions + +Examples of **incorrect** code for this rule with the `{"functions": "never"}` option: + +```js +/*eslint comma-dangle: ["error", {"functions": "never"}]*/ + +function foo(a, b,) { +} + +foo(a, b,); +new foo(a, b,); +``` + +Examples of **correct** code for this rule with the `{"functions": "never"}` option: + +```js +/*eslint comma-dangle: ["error", {"functions": "never"}]*/ + +function foo(a, b) { +} + +foo(a, b); +new foo(a, b); +``` + +Examples of **incorrect** code for this rule with the `{"functions": "always"}` option: + +```js +/*eslint comma-dangle: ["error", {"functions": "always"}]*/ + +function foo(a, b) { +} + +foo(a, b); +new foo(a, b); +``` + +Examples of **correct** code for this rule with the `{"functions": "always"}` option: + +```js +/*eslint comma-dangle: ["error", {"functions": "always"}]*/ + +function foo(a, b,) { +} + +foo(a, b,); +new foo(a, b,); +``` + +## When Not To Use It + +You can turn this rule off if you are not concerned with dangling commas. + +## Version + +This rule was introduced in ESLint 0.16.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/comma-dangle.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/comma-dangle.md) diff --git a/docs/8.0.0/rules/comma-spacing.md b/docs/8.0.0/rules/comma-spacing.md new file mode 100644 index 0000000000..f1d0d6493b --- /dev/null +++ b/docs/8.0.0/rules/comma-spacing.md @@ -0,0 +1,148 @@ +--- +title: comma-spacing - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/comma-spacing.md +rule_type: layout +--- + + +# Enforces spacing around commas (comma-spacing) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +Spacing around commas improves readability of a list of items. Although most of the style guidelines for languages prescribe adding a space after a comma and not before it, it is subjective to the preferences of a project. + +```js +var foo = 1, bar = 2; +var foo = 1 ,bar = 2; +``` + +## Rule Details + +This rule enforces consistent spacing before and after commas in variable declarations, array literals, object literals, function parameters, and sequences. + +This rule does not apply in an `ArrayExpression` or `ArrayPattern` in either of the following cases: + +* adjacent null elements +* an initial null element, to avoid conflicts with the [`array-bracket-spacing`](array-bracket-spacing) rule + +## Options + +This rule has an object option: + +* `"before": false` (default) disallows spaces before commas +* `"before": true` requires one or more spaces before commas +* `"after": true` (default) requires one or more spaces after commas +* `"after": false` disallows spaces after commas + +### after + +Examples of **incorrect** code for this rule with the default `{ "before": false, "after": true }` options: + +```js +/*eslint comma-spacing: ["error", { "before": false, "after": true }]*/ + +var foo = 1 ,bar = 2; +var arr = [1 , 2]; +var obj = {"foo": "bar" ,"baz": "qur"}; +foo(a ,b); +new Foo(a ,b); +function foo(a ,b){} +a ,b +``` + +Examples of **correct** code for this rule with the default `{ "before": false, "after": true }` options: + +```js +/*eslint comma-spacing: ["error", { "before": false, "after": true }]*/ + +var foo = 1, bar = 2 + , baz = 3; +var arr = [1, 2]; +var arr = [1,, 3] +var obj = {"foo": "bar", "baz": "qur"}; +foo(a, b); +new Foo(a, b); +function foo(a, b){} +a, b +``` + +Example of **correct** code for this rule with initial null element for the default `{ "before": false, "after": true }` options: + +```js +/*eslint comma-spacing: ["error", { "before": false, "after": true }]*/ +/*eslint array-bracket-spacing: ["error", "always"]*/ + +var arr = [ , 2, 3 ] +``` + +### before + +Examples of **incorrect** code for this rule with the `{ "before": true, "after": false }` options: + +```js +/*eslint comma-spacing: ["error", { "before": true, "after": false }]*/ + +var foo = 1, bar = 2; +var arr = [1 , 2]; +var obj = {"foo": "bar", "baz": "qur"}; +new Foo(a,b); +function foo(a,b){} +a, b +``` + +Examples of **correct** code for this rule with the `{ "before": true, "after": false }` options: + +```js +/*eslint comma-spacing: ["error", { "before": true, "after": false }]*/ + +var foo = 1 ,bar = 2 , + baz = true; +var arr = [1 ,2]; +var arr = [1 ,,3] +var obj = {"foo": "bar" ,"baz": "qur"}; +foo(a ,b); +new Foo(a ,b); +function foo(a ,b){} +a ,b +``` + +Examples of **correct** code for this rule with initial null element for the `{ "before": true, "after": false }` options: + +```js +/*eslint comma-spacing: ["error", { "before": true, "after": false }]*/ +/*eslint array-bracket-spacing: ["error", "never"]*/ + +var arr = [,2 ,3] +``` + +## When Not To Use It + +If your project will not be following a consistent comma-spacing pattern, turn this rule off. + + +## Further Reading + +* [JavaScript](http://javascript.crockford.com/code.html) +* [Dojo Style Guide](https://dojotoolkit.org/reference-guide/1.9/developer/styleguide.html) + + +## Related Rules + +* [array-bracket-spacing](array-bracket-spacing) +* [comma-style](comma-style) +* [space-in-brackets](space-in-brackets) (deprecated) +* [space-in-parens](space-in-parens) +* [space-infix-ops](space-infix-ops) +* [space-after-keywords](space-after-keywords) +* [space-unary-ops](space-unary-ops) +* [space-return-throw-case](space-return-throw-case) + +## Version + +This rule was introduced in ESLint 0.9.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/comma-spacing.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/comma-spacing.md) diff --git a/docs/8.0.0/rules/comma-style.md b/docs/8.0.0/rules/comma-style.md new file mode 100644 index 0000000000..405e9ccbd9 --- /dev/null +++ b/docs/8.0.0/rules/comma-style.md @@ -0,0 +1,190 @@ +--- +title: comma-style - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/comma-style.md +rule_type: layout +--- + + +# Comma style (comma-style) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +The Comma Style rule enforces styles for comma-separated lists. There are two comma styles primarily used in JavaScript: + +* The standard style, in which commas are placed at the end of the current line +* Comma First style, in which commas are placed at the start of the next line + +One of the justifications for using Comma First style is that it can help track missing and trailing commas. These are problematic because missing commas in variable declarations can lead to the leakage of global variables and trailing commas can lead to errors in older versions of IE. + +## Rule Details + +This rule enforce consistent comma style in array literals, object literals, and variable declarations. + +This rule does not apply in either of the following cases: + +* comma preceded and followed by linebreak (lone comma) +* single-line array literals, object literals, and variable declarations + +## Options + +This rule has a string option: + +* `"last"` (default) requires a comma after and on the same line as an array element, object property, or variable declaration +* `"first"` requires a comma before and on the same line as an array element, object property, or variable declaration + +This rule also accepts an additional `exceptions` object: + +* `"exceptions"` has properties whose names correspond to node types in the abstract syntax tree (AST) of JavaScript code: + + * `"ArrayExpression": true` ignores comma style in array literals + * `"ArrayPattern": true` ignores comma style in array patterns of destructuring + * `"ArrowFunctionExpression": true` ignores comma style in the parameters of arrow function expressions + * `"CallExpression": true` ignores comma style in the arguments of function calls + * `"FunctionDeclaration": true` ignores comma style in the parameters of function declarations + * `"FunctionExpression": true` ignores comma style in the parameters of function expressions + * `"ImportDeclaration": true` ignores comma style in the specifiers of import declarations + * `"ObjectExpression": true` ignores comma style in object literals + * `"ObjectPattern": true` ignores comma style in object patterns of destructuring + * `"VariableDeclaration": true` ignores comma style in variable declarations + * `"NewExpression": true` ignores comma style in the parameters of constructor expressions + +A way to determine the node types as defined by [ESTree](https://github.com/estree/estree) is to use [AST Explorer](https://astexplorer.net/) with the espree parser. + +### last + +Examples of **incorrect** code for this rule with the default `"last"` option: + +```js +/*eslint comma-style: ["error", "last"]*/ + +var foo = 1 +, +bar = 2; + +var foo = 1 + , bar = 2; + +var foo = ["apples" + , "oranges"]; + +function bar() { + return { + "a": 1 + ,"b:": 2 + }; +} +``` + +Examples of **correct** code for this rule with the default `"last"` option: + +```js +/*eslint comma-style: ["error", "last"]*/ + +var foo = 1, bar = 2; + +var foo = 1, + bar = 2; + +var foo = ["apples", + "oranges"]; + +function bar() { + return { + "a": 1, + "b:": 2 + }; +} +``` + +### first + +Examples of **incorrect** code for this rule with the `"first"` option: + +```js +/*eslint comma-style: ["error", "first"]*/ + +var foo = 1, + bar = 2; + +var foo = ["apples", + "oranges"]; + +function bar() { + return { + "a": 1, + "b:": 2 + }; +} +``` + +Examples of **correct** code for this rule with the `"first"` option: + +```js +/*eslint comma-style: ["error", "first"]*/ + +var foo = 1, bar = 2; + +var foo = 1 + ,bar = 2; + +var foo = ["apples" + ,"oranges"]; + +function bar() { + return { + "a": 1 + ,"b:": 2 + }; +} +``` + +### exceptions + +An example use case is to enforce comma style *only* in var statements. + +Examples of **incorrect** code for this rule with sample `"first", { "exceptions": { … } }` options: + +```js +/*eslint comma-style: ["error", "first", { "exceptions": { "ArrayExpression": true, "ObjectExpression": true } }]*/ + +var o = {}, + a = []; +``` + +Examples of **correct** code for this rule with sample `"first", { "exceptions": { … } }` options: + +```js +/*eslint comma-style: ["error", "first", { "exceptions": { "ArrayExpression": true, "ObjectExpression": true } }]*/ + +var o = {fst:1, + snd: [1, + 2]} + , a = []; +``` + +## When Not To Use It + +This rule can safely be turned off if your project does not care about enforcing a consistent comma style. + + +## Further Reading + +For more information on the Comma First style: + +* [A better coding convention for lists and object literals in JavaScript by isaacs](https://gist.github.com/isaacs/357981) +* [npm coding style guideline](https://docs.npmjs.com/misc/coding-style) + + +## Related Rules + +* [operator-linebreak](operator-linebreak) + +## Version + +This rule was introduced in ESLint 0.9.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/comma-style.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/comma-style.md) diff --git a/docs/8.0.0/rules/complexity.md b/docs/8.0.0/rules/complexity.md new file mode 100644 index 0000000000..0324f8d89f --- /dev/null +++ b/docs/8.0.0/rules/complexity.md @@ -0,0 +1,113 @@ +--- +title: complexity - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/complexity.md +rule_type: suggestion +--- + + +# Limit Cyclomatic Complexity (complexity) + +Cyclomatic complexity measures the number of linearly independent paths through a program's source code. This rule allows setting a cyclomatic complexity threshold. + +```js +function a(x) { + if (true) { + return x; // 1st path + } else if (false) { + return x+1; // 2nd path + } else { + return 4; // 3rd path + } +} +``` + +## Rule Details + +This rule is aimed at reducing code complexity by capping the amount of cyclomatic complexity allowed in a program. As such, it will warn when the cyclomatic complexity crosses the configured threshold (default is `20`). + +Examples of **incorrect** code for a maximum of 2: + +```js +/*eslint complexity: ["error", 2]*/ + +function a(x) { + if (true) { + return x; + } else if (false) { + return x+1; + } else { + return 4; // 3rd path + } +} + +function b() { + foo ||= 1; + bar &&= 1; +} +``` + +Examples of **correct** code for a maximum of 2: + +```js +/*eslint complexity: ["error", 2]*/ + +function a(x) { + if (true) { + return x; + } else { + return 4; + } +} + +function b() { + foo ||= 1; +} +``` + +## Options + +Optionally, you may specify a `max` object property: + +```json +"complexity": ["error", 2] +``` + +is equivalent to + +```json +"complexity": ["error", { "max": 2 }] +``` + +**Deprecated:** the object property `maximum` is deprecated. Please use the property `max` instead. + +## When Not To Use It + +If you can't determine an appropriate complexity limit for your code, then it's best to disable this rule. + +## Further Reading + +* [Cyclomatic Complexity](https://en.wikipedia.org/wiki/Cyclomatic_complexity) +* [Complexity Analysis of JavaScript Code](https://ariya.io/2012/12/complexity-analysis-of-javascript-code) +* [More about Complexity in JavaScript](https://craftsmanshipforsoftware.com/2015/05/25/complexity-for-javascript/) +* [About Complexity](https://web.archive.org/web/20160808115119/http://jscomplexity.org/complexity) +* [Discussion about Complexity in ESLint and more links](https://github.com/eslint/eslint/issues/4808#issuecomment-167795140) + +## Related Rules + +* [max-depth](max-depth) +* [max-len](max-len) +* [max-lines](max-lines) +* [max-lines-per-function](max-lines-per-function) +* [max-nested-callbacks](max-nested-callbacks) +* [max-params](max-params) +* [max-statements](max-statements) + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/complexity.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/complexity.md) diff --git a/docs/8.0.0/rules/computed-property-spacing.md b/docs/8.0.0/rules/computed-property-spacing.md new file mode 100644 index 0000000000..8d313765d1 --- /dev/null +++ b/docs/8.0.0/rules/computed-property-spacing.md @@ -0,0 +1,184 @@ +--- +title: computed-property-spacing - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/computed-property-spacing.md +rule_type: layout +--- + + +# Disallow or enforce spaces inside of computed properties (computed-property-spacing) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +While formatting preferences are very personal, a number of style guides require +or disallow spaces between computed properties in the following situations: + +```js +/*eslint-env es6*/ + +var obj = { prop: "value" }; +var a = "prop"; +var x = obj[a]; // computed property in object member expression + +var a = "prop"; +var obj = { + [a]: "value" // computed property key in object literal (ECMAScript 6) +}; +``` + +## Rule Details + +This rule enforces consistent spacing inside computed property brackets. + +It either requires or disallows spaces between the brackets and the values inside of them. +This rule does not apply to brackets that are separated from the adjacent value by a newline. + +## Options + +This rule has two options, a string option and an object option. + +String option: + +* `"never"` (default) disallows spaces inside computed property brackets +* `"always"` requires one or more spaces inside computed property brackets + +Object option: + +* `"enforceForClassMembers": true` (default) additionally applies this rule to class members. + +### never + +Examples of **incorrect** code for this rule with the default `"never"` option: + +```js +/*eslint computed-property-spacing: ["error", "never"]*/ +/*eslint-env es6*/ + +obj[foo ] +obj[ 'foo'] +var x = {[ b ]: a} +obj[foo[ bar ]] +``` + +Examples of **correct** code for this rule with the default `"never"` option: + +```js +/*eslint computed-property-spacing: ["error", "never"]*/ +/*eslint-env es6*/ + +obj[foo] +obj['foo'] +var x = {[b]: a} +obj[foo[bar]] +``` + +### always + +Examples of **incorrect** code for this rule with the `"always"` option: + +```js +/*eslint computed-property-spacing: ["error", "always"]*/ +/*eslint-env es6*/ + +obj[foo] +var x = {[b]: a} +obj[ foo] +obj['foo' ] +obj[foo[ bar ]] +var x = {[ b]: a} +``` + +Examples of **correct** code for this rule with the `"always"` option: + +```js +/*eslint computed-property-spacing: ["error", "always"]*/ +/*eslint-env es6*/ + +obj[ foo ] +obj[ 'foo' ] +var x = {[ b ]: a} +obj[ foo[ bar ] ] +``` + +#### enforceForClassMembers + +With `enforceForClassMembers` set to `true` (default), the rule also disallows/enforces spaces inside of computed keys of class methods, getters and setters. + +Examples of **incorrect** code for this rule with `"never"` and `{ "enforceForClassMembers": true }` (default): + +```js +/*eslint computed-property-spacing: ["error", "never", { "enforceForClassMembers": true }]*/ +/*eslint-env es6*/ + +class Foo { + [a ]() {} + get [b ]() {} + set [b ](value) {} +} + +const Bar = class { + [ a](){} + static [ b]() {} + static get [ c ]() {} + static set [ c ](value) {} +} +``` + +Examples of **correct** code for this rule with `"never"` and `{ "enforceForClassMembers": true }` (default): + +```js +/*eslint computed-property-spacing: ["error", "never", { "enforceForClassMembers": true }]*/ +/*eslint-env es6*/ + +class Foo { + [a]() {} + get [b]() {} + set [b](value) {} +} + +const Bar = class { + [a](){} + static [b]() {} + static get [c]() {} + static set [c](value) {} +} +``` + +Examples of **correct** code for this rule with `"never"` and `{ "enforceForClassMembers": false }`: + +```js +/*eslint computed-property-spacing: ["error", "never", { "enforceForClassMembers": false }]*/ +/*eslint-env es6*/ + +class Foo { + [a ]() {} + get [b ]() {} + set [b ](value) {} +} + +const Bar = class { + [ a](){} + static [ b]() {} + static get [ c ]() {} + static set [ c ](value) {} +} +``` + +## When Not To Use It + +You can turn this rule off if you are not concerned with the consistency of computed properties. + +## Related Rules + +* [array-bracket-spacing](array-bracket-spacing) +* [comma-spacing](comma-spacing) +* [space-in-parens](space-in-parens) + +## Version + +This rule was introduced in ESLint 0.23.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/computed-property-spacing.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/computed-property-spacing.md) diff --git a/docs/8.0.0/rules/consistent-return.md b/docs/8.0.0/rules/consistent-return.md new file mode 100644 index 0000000000..be9bf9bded --- /dev/null +++ b/docs/8.0.0/rules/consistent-return.md @@ -0,0 +1,162 @@ +--- +title: consistent-return - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/consistent-return.md +rule_type: suggestion +--- + + +# require `return` statements to either always or never specify values (consistent-return) + +Unlike statically-typed languages which enforce that a function returns a specified type of value, JavaScript allows different code paths in a function to return different types of values. + +A confusing aspect of JavaScript is that a function returns `undefined` if any of the following are true: + +* it does not execute a `return` statement before it exits +* it executes `return` which does not specify a value explicitly +* it executes `return undefined` +* it executes `return void` followed by an expression (for example, a function call) +* it executes `return` followed by any other expression which evaluates to `undefined` + +If any code paths in a function return a value explicitly but some code path do not return a value explicitly, it might be a typing mistake, especially in a large function. In the following example: + +* a code path through the function returns a Boolean value `true` +* another code path does not return a value explicitly, therefore returns `undefined` implicitly + +```js +function doSomething(condition) { + if (condition) { + return true; + } else { + return; + } +} +``` + +## Rule Details + +This rule requires `return` statements to either always or never specify values. This rule ignores function definitions where the name begins with an uppercase letter, because constructors (when invoked with the `new` operator) return the instantiated object implicitly if they do not return another object explicitly. + +Examples of **incorrect** code for this rule: + +```js +/*eslint consistent-return: "error"*/ + +function doSomething(condition) { + if (condition) { + return true; + } else { + return; + } +} + +function doSomething(condition) { + if (condition) { + return true; + } +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint consistent-return: "error"*/ + +function doSomething(condition) { + if (condition) { + return true; + } else { + return false; + } +} + +function Foo() { + if (!(this instanceof Foo)) { + return new Foo(); + } + + this.a = 0; +} +``` + +## Options + +This rule has an object option: + +* `"treatUndefinedAsUnspecified": false` (default) always either specify values or return `undefined` implicitly only. +* `"treatUndefinedAsUnspecified": true` always either specify values or return `undefined` explicitly or implicitly. + +### treatUndefinedAsUnspecified + +Examples of **incorrect** code for this rule with the default `{ "treatUndefinedAsUnspecified": false }` option: + +```js +/*eslint consistent-return: ["error", { "treatUndefinedAsUnspecified": false }]*/ + +function foo(callback) { + if (callback) { + return void callback(); + } + // no return statement +} + +function bar(condition) { + if (condition) { + return undefined; + } + // no return statement +} +``` + +Examples of **incorrect** code for this rule with the `{ "treatUndefinedAsUnspecified": true }` option: + +```js +/*eslint consistent-return: ["error", { "treatUndefinedAsUnspecified": true }]*/ + +function foo(callback) { + if (callback) { + return void callback(); + } + return true; +} + +function bar(condition) { + if (condition) { + return undefined; + } + return true; +} +``` + +Examples of **correct** code for this rule with the `{ "treatUndefinedAsUnspecified": true }` option: + +```js +/*eslint consistent-return: ["error", { "treatUndefinedAsUnspecified": true }]*/ + +function foo(callback) { + if (callback) { + return void callback(); + } + // no return statement +} + +function bar(condition) { + if (condition) { + return undefined; + } + // no return statement +} +``` + +## When Not To Use It + +If you want to allow functions to have different `return` behavior depending on code branching, then it is safe to disable this rule. + +## Version + +This rule was introduced in ESLint 0.4.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/consistent-return.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/consistent-return.md) diff --git a/docs/8.0.0/rules/consistent-this.md b/docs/8.0.0/rules/consistent-this.md new file mode 100644 index 0000000000..030c3f6786 --- /dev/null +++ b/docs/8.0.0/rules/consistent-this.md @@ -0,0 +1,101 @@ +--- +title: consistent-this - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/consistent-this.md +rule_type: suggestion +--- + + +# Require Consistent This (consistent-this) + +It is often necessary to capture the current execution context in order to make it available subsequently. A prominent example of this are jQuery callbacks: + +```js +var that = this; +jQuery('li').click(function (event) { + // here, "this" is the HTMLElement where the click event occurred + that.setFoo(42); +}); +``` + +There are many commonly used aliases for `this` such as `that`, `self` or `me`. It is desirable to ensure that whichever alias the team agrees upon is used consistently throughout the application. + +## Rule Details + +This rule enforces two things about variables with the designated alias names for `this`: + +* If a variable with a designated name is declared, it *must* be either initialized (in the declaration) or assigned (in the same scope as the declaration) the value `this`. +* If a variable is initialized or assigned the value `this`, the name of the variable *must* be a designated alias. + +## Options + +This rule has one or more string options: + +* designated alias names for `this` (default `"that"`) + +Examples of **incorrect** code for this rule with the default `"that"` option: + +```js +/*eslint consistent-this: ["error", "that"]*/ + +var that = 42; + +var self = this; + +that = 42; + +self = this; +``` + +Examples of **correct** code for this rule with the default `"that"` option: + +```js +/*eslint consistent-this: ["error", "that"]*/ + +var that = this; + +var self = 42; + +var self; + +that = this; + +foo.bar = this; +``` + +Examples of **incorrect** code for this rule with the default `"that"` option, if the variable is not initialized: + +```js +/*eslint consistent-this: ["error", "that"]*/ + +var that; +function f() { + that = this; +} +``` + +Examples of **correct** code for this rule with the default `"that"` option, if the variable is not initialized: + +```js +/*eslint consistent-this: ["error", "that"]*/ + +var that; +that = this; + +var foo, that; +foo = 42; +that = this; +``` + +## When Not To Use It + +If you need to capture nested context, `consistent-this` is going to be problematic. Code of that nature is usually difficult to read and maintain and you should consider refactoring it. + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/consistent-this.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/consistent-this.md) diff --git a/docs/8.0.0/rules/constructor-super.md b/docs/8.0.0/rules/constructor-super.md new file mode 100644 index 0000000000..dc24fe3825 --- /dev/null +++ b/docs/8.0.0/rules/constructor-super.md @@ -0,0 +1,79 @@ +--- +title: constructor-super - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/constructor-super.md +rule_type: problem +--- + + +# Verify calls of `super()` in constructors (constructor-super) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +Constructors of derived classes must call `super()`. +Constructors of non derived classes must not call `super()`. +If this is not observed, the JavaScript engine will raise a runtime error. + +This rule checks whether or not there is a valid `super()` call. + +## Rule Details + +This rule is aimed to flag invalid/missing `super()` calls. + +Examples of **incorrect** code for this rule: + +```js +/*eslint constructor-super: "error"*/ +/*eslint-env es6*/ + +class A { + constructor() { + super(); // This is a SyntaxError. + } +} + +class A extends B { + constructor() { } // Would throw a ReferenceError. +} + +// Classes which inherits from a non constructor are always problems. +class A extends null { + constructor() { + super(); // Would throw a TypeError. + } +} + +class A extends null { + constructor() { } // Would throw a ReferenceError. +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint constructor-super: "error"*/ +/*eslint-env es6*/ + +class A { + constructor() { } +} + +class A extends B { + constructor() { + super(); + } +} +``` + +## When Not To Use It + +If you don't want to be notified about invalid/missing `super()` callings in constructors, you can safely disable this rule. + +## Version + +This rule was introduced in ESLint 0.24.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/constructor-super.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/constructor-super.md) diff --git a/docs/8.0.0/rules/curly.md b/docs/8.0.0/rules/curly.md new file mode 100644 index 0000000000..289ec8c2e7 --- /dev/null +++ b/docs/8.0.0/rules/curly.md @@ -0,0 +1,320 @@ +--- +title: curly - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/curly.md +rule_type: suggestion +--- + + +# Require Following Curly Brace Conventions (curly) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +JavaScript allows the omission of curly braces when a block contains only one statement. However, it is considered by many to be best practice to _never_ omit curly braces around blocks, even when they are optional, because it can lead to bugs and reduces code clarity. So the following: + +```js +if (foo) foo++; +``` + +Can be rewritten as: + +```js +if (foo) { + foo++; +} +``` + +There are, however, some who prefer to only use braces when there is more than one statement to be executed. + +## Rule Details + +This rule is aimed at preventing bugs and increasing code clarity by ensuring that block statements are wrapped in curly braces. It will warn when it encounters blocks that omit curly braces. + +## Options + +### all + +Examples of **incorrect** code for the default `"all"` option: + +```js +/*eslint curly: "error"*/ + +if (foo) foo++; + +while (bar) + baz(); + +if (foo) { + baz(); +} else qux(); +``` + +Examples of **correct** code for the default `"all"` option: + +```js +/*eslint curly: "error"*/ + +if (foo) { + foo++; +} + +while (bar) { + baz(); +} + +if (foo) { + baz(); +} else { + qux(); +} +``` + +### multi + +By default, this rule warns whenever `if`, `else`, `for`, `while`, or `do` are used without block statements as their body. However, you can specify that block statements should be used only when there are multiple statements in the block and warn when there is only one statement in the block. + +Examples of **incorrect** code for the `"multi"` option: + +```js +/*eslint curly: ["error", "multi"]*/ + +if (foo) { + foo++; +} + +if (foo) bar(); +else { + foo++; +} + +while (true) { + doSomething(); +} + +for (var i=0; i < items.length; i++) { + doSomething(); +} +``` + +Examples of **correct** code for the `"multi"` option: + +```js +/*eslint curly: ["error", "multi"]*/ + +if (foo) foo++; + +else foo(); + +while (true) { + doSomething(); + doSomethingElse(); +} +``` + +### multi-line + +Alternatively, you can relax the rule to allow brace-less single-line `if`, `else if`, `else`, `for`, `while`, or `do`, while still enforcing the use of curly braces for other instances. + +Examples of **incorrect** code for the `"multi-line"` option: + +```js +/*eslint curly: ["error", "multi-line"]*/ + +if (foo) + doSomething(); +else + doSomethingElse(); + +if (foo) foo( + bar, + baz); +``` + +Examples of **correct** code for the `"multi-line"` option: + +```js +/*eslint curly: ["error", "multi-line"]*/ + +if (foo) foo++; else doSomething(); + +if (foo) foo++; +else if (bar) baz() +else doSomething(); + +do something(); +while (foo); + +while (foo + && bar) baz(); + +if (foo) { + foo++; +} + +if (foo) { foo++; } + +while (true) { + doSomething(); + doSomethingElse(); +} +``` + +### multi-or-nest + +You can use another configuration that forces brace-less `if`, `else if`, `else`, `for`, `while`, or `do` if their body contains only one single-line statement. And forces braces in all other cases. + +Examples of **incorrect** code for the `"multi-or-nest"` option: + +```js +/*eslint curly: ["error", "multi-or-nest"]*/ + +if (!foo) + foo = { + bar: baz, + qux: foo + }; + +while (true) + if(foo) + doSomething(); + else + doSomethingElse(); + +if (foo) { + foo++; +} + +while (true) { + doSomething(); +} + +for (var i = 0; foo; i++) { + doSomething(); +} +``` + +Examples of **correct** code for the `"multi-or-nest"` option: + +```js +/*eslint curly: ["error", "multi-or-nest"]*/ + +if (!foo) { + foo = { + bar: baz, + qux: foo + }; +} + +while (true) { + if(foo) + doSomething(); + else + doSomethingElse(); +} + +if (foo) + foo++; + +while (true) + doSomething(); + +for (var i = 0; foo; i++) + doSomething(); +``` + +For single-line statements preceded by a comment, braces are allowed but not required. + +Examples of additional **correct** code for the `"multi-or-nest"` option: + +```js +/*eslint curly: ["error", "multi-or-nest"]*/ + +if (foo) + // some comment + bar(); + +if (foo) { + // some comment + bar(); +} +``` + +### consistent + +When using any of the `multi*` options, you can add an option to enforce all bodies of a `if`, +`else if` and `else` chain to be with or without braces. + +Examples of **incorrect** code for the `"multi", "consistent"` options: + +```js +/*eslint curly: ["error", "multi", "consistent"]*/ + +if (foo) { + bar(); + baz(); +} else + buz(); + +if (foo) + bar(); +else if (faa) + bor(); +else { + other(); + things(); +} + +if (true) + foo(); +else { + baz(); +} + +if (foo) { + foo++; +} +``` + +Examples of **correct** code for the `"multi", "consistent"` options: + +```js +/*eslint curly: ["error", "multi", "consistent"]*/ + +if (foo) { + bar(); + baz(); +} else { + buz(); +} + +if (foo) { + bar(); +} else if (faa) { + bor(); +} else { + other(); + things(); +} + +if (true) + foo(); +else + baz(); + +if (foo) + foo++; + +``` + +## When Not To Use It + +If you have no strict conventions about when to use block statements and when not to, you can safely disable this rule. + +## Version + +This rule was introduced in ESLint 0.0.2. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/curly.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/curly.md) diff --git a/docs/8.0.0/rules/default-case-last.md b/docs/8.0.0/rules/default-case-last.md new file mode 100644 index 0000000000..913f6c7131 --- /dev/null +++ b/docs/8.0.0/rules/default-case-last.md @@ -0,0 +1,142 @@ +--- +title: default-case-last - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/default-case-last.md +rule_type: suggestion +--- + + +# Enforce default clauses in switch statements to be last (default-case-last) + +A `switch` statement can optionally have a `default` clause. + +If present, it's usually the last clause, but it doesn't need to be. It is also allowed to put the `default` clause before all `case` clauses, or anywhere between. The behavior is mostly the same as if it was the last clause. The `default` block will be still executed only if there is no match in the `case` clauses (including those defined after the `default`), but there is also the ability to "fall through" from the `default` clause to the following clause in the list. However, such flow is not common and it would be confusing to the readers. + +Even if there is no "fall through" logic, it's still unexpected to see the `default` clause before or between the `case` clauses. By convention, it is expected to be the last clause. + +If a `switch` statement should have a `default` clause, it's considered a best practice to define it as the last clause. + +## Rule Details + +This rule enforces `default` clauses in `switch` statements to be last. + +It applies only to `switch` statements that already have a `default` clause. + +This rule does not enforce the existence of `default` clauses. See [default-case](default-case) if you also want to enforce the existence of `default` clauses in `switch` statements. + +Examples of **incorrect** code for this rule: + +```js +/*eslint default-case-last: "error"*/ + +switch (foo) { + default: + bar(); + break; + case "a": + baz(); + break; +} + +switch (foo) { + case 1: + bar(); + break; + default: + baz(); + break; + case 2: + quux(); + break; +} + +switch (foo) { + case "x": + bar(); + break; + default: + case "y": + baz(); + break; +} + +switch (foo) { + default: + break; + case -1: + bar(); + break; +} + +switch (foo) { + default: + doSomethingIfNotZero(); + case 0: + doSomethingAnyway(); +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint default-case-last: "error"*/ + +switch (foo) { + case "a": + baz(); + break; + default: + bar(); + break; +} + +switch (foo) { + case 1: + bar(); + break; + case 2: + quux(); + break; + default: + baz(); + break; +} + +switch (foo) { + case "x": + bar(); + break; + case "y": + default: + baz(); + break; +} + +switch (foo) { + case -1: + bar(); + break; +} + +if (foo !== 0) { + doSomethingIfNotZero(); +} +doSomethingAnyway(); +``` + +## Further Reading + +* [MDN switch statement](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch) + +## Related Rules + +* [default-case](default-case) + +## Version + +This rule was introduced in ESLint 7.0.0-alpha.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/default-case-last.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/default-case-last.md) diff --git a/docs/8.0.0/rules/default-case.md b/docs/8.0.0/rules/default-case.md new file mode 100644 index 0000000000..9c08a6250f --- /dev/null +++ b/docs/8.0.0/rules/default-case.md @@ -0,0 +1,143 @@ +--- +title: default-case - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/default-case.md +rule_type: suggestion +--- + + +# Require Default Case in Switch Statements (default-case) + +Some code conventions require that all `switch` statements have a `default` case, even if the default case is empty, such as: + +```js +switch (foo) { + case 1: + doSomething(); + break; + + case 2: + doSomething(); + break; + + default: + // do nothing +} +``` + +The thinking is that it's better to always explicitly state what the default behavior should be so that it's clear whether or not the developer forgot to include the default behavior by mistake. + +Other code conventions allow you to skip the `default` case so long as there is a comment indicating the omission is intentional, such as: + +```js +switch (foo) { + case 1: + doSomething(); + break; + + case 2: + doSomething(); + break; + + // no default +} +``` + +Once again, the intent here is to show that the developer intended for there to be no default behavior. + +## Rule Details + +This rule aims to require `default` case in `switch` statements. You may optionally include a `// no default` after the last `case` if there is no `default` case. The comment may be in any desired case, such as `// No Default`. + +Examples of **incorrect** code for this rule: + +```js +/*eslint default-case: "error"*/ + +switch (a) { + case 1: + /* code */ + break; +} + +``` + +Examples of **correct** code for this rule: + +```js +/*eslint default-case: "error"*/ + +switch (a) { + case 1: + /* code */ + break; + + default: + /* code */ + break; +} + + +switch (a) { + case 1: + /* code */ + break; + + // no default +} + +switch (a) { + case 1: + /* code */ + break; + + // No Default +} +``` + +## Options + +This rule accepts a single options argument: + +* Set the `commentPattern` option to a regular expression string to change the default `/^no default$/i` comment test pattern + +### commentPattern + +Examples of **correct** code for the `{ "commentPattern": "^skip\\sdefault" }` option: + +```js +/*eslint default-case: ["error", { "commentPattern": "^skip\\sdefault" }]*/ + +switch(a) { + case 1: + /* code */ + break; + + // skip default +} + +switch(a) { + case 1: + /* code */ + break; + + // skip default case +} +``` + +## When Not To Use It + +If you don't want to enforce a `default` case for `switch` statements, you can safely disable this rule. + +## Related Rules + +* [no-fallthrough](no-fallthrough) + +## Version + +This rule was introduced in ESLint 0.6.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/default-case.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/default-case.md) diff --git a/docs/8.0.0/rules/default-param-last.md b/docs/8.0.0/rules/default-param-last.md new file mode 100644 index 0000000000..477a9e74f1 --- /dev/null +++ b/docs/8.0.0/rules/default-param-last.md @@ -0,0 +1,52 @@ +--- +title: default-param-last - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/default-param-last.md +rule_type: suggestion +--- + + +# enforce default parameters to be last (default-param-last) + +Putting default parameter at last allows function calls to omit optional tail arguments. + +```js +// Correct: optional argument can be omitted +function createUser(id, isAdmin = false) {} +createUser("tabby") + +// Incorrect: optional argument can **not** be omitted +function createUser(isAdmin = false, id) {} +createUser(undefined, "tabby") +``` + +## Rule Details + +This rule enforces default parameters to be the last of parameters. + +Examples of **incorrect** code for this rule: + +```js +/* eslint default-param-last: ["error"] */ + +function f(a = 0, b) {} + +function f(a, b = 0, c) {} +``` + +Examples of **correct** code for this rule: + +```js +/* eslint default-param-last: ["error"] */ + +function f(a, b = 0) {} +``` + +## Version + +This rule was introduced in ESLint 6.4.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/default-param-last.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/default-param-last.md) diff --git a/docs/8.0.0/rules/dot-location.md b/docs/8.0.0/rules/dot-location.md new file mode 100644 index 0000000000..8b29a96d31 --- /dev/null +++ b/docs/8.0.0/rules/dot-location.md @@ -0,0 +1,104 @@ +--- +title: dot-location - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/dot-location.md +rule_type: layout +--- + + +# Enforce newline before and after dot (dot-location) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +JavaScript allows you to place newlines before or after a dot in a member expression. + +Consistency in placing a newline before or after the dot can greatly increase readability. + +```js +var a = universe. + galaxy; + +var b = universe + .galaxy; +``` + +## Rule Details + +This rule aims to enforce newline consistency in member expressions. This rule prevents the use of mixed newlines around the dot in a member expression. + +## Options + +The rule takes one option, a string: + +* If it is `"object"` (default), the dot in a member expression should be on the same line as the object portion. +* If it is `"property"`, the dot in a member expression should be on the same line as the property portion. + +### object + +The default `"object"` option requires the dot to be on the same line as the object. + +Examples of **incorrect** code for the default `"object"` option: + +```js +/*eslint dot-location: ["error", "object"]*/ + +var foo = object +.property; +``` + +Examples of **correct** code for the default `"object"` option: + +```js +/*eslint dot-location: ["error", "object"]*/ + +var foo = object. +property; + +var bar = ( + object +). +property; + +var baz = object.property; +``` + +### property + +The `"property"` option requires the dot to be on the same line as the property. + +Examples of **incorrect** code for the `"property"` option: + +```js +/*eslint dot-location: ["error", "property"]*/ + +var foo = object. +property; +``` + +Examples of **correct** code for the `"property"` option: + +```js +/*eslint dot-location: ["error", "property"]*/ + +var foo = object +.property; +var bar = object.property; +``` + +## When Not To Use It + +You can turn this rule off if you are not concerned with the consistency of newlines before or after dots in member expressions. + +## Related Rules + +* [newline-after-var](newline-after-var) +* [dot-notation](dot-notation) + +## Version + +This rule was introduced in ESLint 0.21.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/dot-location.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/dot-location.md) diff --git a/docs/8.0.0/rules/dot-notation.md b/docs/8.0.0/rules/dot-notation.md new file mode 100644 index 0000000000..eec5401b3b --- /dev/null +++ b/docs/8.0.0/rules/dot-notation.md @@ -0,0 +1,99 @@ +--- +title: dot-notation - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/dot-notation.md +rule_type: suggestion +--- + + +# Require Dot Notation (dot-notation) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +In JavaScript, one can access properties using the dot notation (`foo.bar`) or square-bracket notation (`foo["bar"]`). However, the dot notation is often preferred because it is easier to read, less verbose, and works better with aggressive JavaScript minimizers. + +```js +foo["bar"]; +``` + +## Rule Details + +This rule is aimed at maintaining code consistency and improving code readability by encouraging use of the dot notation style whenever possible. As such, it will warn when it encounters an unnecessary use of square-bracket notation. + +Examples of **incorrect** code for this rule: + +```js +/*eslint dot-notation: "error"*/ + +var x = foo["bar"]; +``` + +Examples of **correct** code for this rule: + +```js +/*eslint dot-notation: "error"*/ + +var x = foo.bar; + +var x = foo[bar]; // Property name is a variable, square-bracket notation required +``` + +## Options + +This rule accepts a single options argument: + +* Set the `allowKeywords` option to `false` (default is `true`) to follow ECMAScript version 3 compatible style, avoiding dot notation for reserved word properties. +* Set the `allowPattern` option to a regular expression string to allow bracket notation for property names that match a pattern (by default, no pattern is tested). + +### allowKeywords + +Examples of **correct** code for the `{ "allowKeywords": false }` option: + +```js +/*eslint dot-notation: ["error", { "allowKeywords": false }]*/ + +var foo = { "class": "CS 101" } +var x = foo["class"]; // Property name is a reserved word, square-bracket notation required +``` + +Examples of additional **correct** code for the `{ "allowKeywords": false }` option: + +```js +/*eslint dot-notation: ["error", { "allowKeywords": false }]*/ + +class C { + #in; + foo() { + this.#in; // Dot notation is required for private identifiers + } +} +``` + +### allowPattern + +For example, when preparing data to be sent to an external API, it is often required to use property names that include underscores. If the `camelcase` rule is in effect, these [snake case](https://en.wikipedia.org/wiki/Snake_case) properties would not be allowed. By providing an `allowPattern` to the `dot-notation` rule, these snake case properties can be accessed with bracket notation. + +Examples of **correct** code for the sample `{ "allowPattern": "^[a-z]+(_[a-z]+)+$" }` option: + +```js +/*eslint camelcase: "error"*/ +/*eslint dot-notation: ["error", { "allowPattern": "^[a-z]+(_[a-z]+)+$" }]*/ + +var data = {}; +data.foo_bar = 42; + +var data = {}; +data["fooBar"] = 42; + +var data = {}; +data["foo_bar"] = 42; // no warning +``` + +## Version + +This rule was introduced in ESLint 0.0.7. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/dot-notation.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/dot-notation.md) diff --git a/docs/8.0.0/rules/eol-last.md b/docs/8.0.0/rules/eol-last.md new file mode 100644 index 0000000000..3877c2d11f --- /dev/null +++ b/docs/8.0.0/rules/eol-last.md @@ -0,0 +1,65 @@ +--- +title: eol-last - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/eol-last.md +rule_type: layout +--- + + +# require or disallow newline at the end of files (eol-last) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +Trailing newlines in non-empty files are a common UNIX idiom. Benefits of +trailing newlines include the ability to concatenate or append to files as well +as output files to the terminal without interfering with shell prompts. + +## Rule Details + +This rule enforces at least one newline (or absence thereof) at the end +of non-empty files. + +Prior to v0.16.0 this rule also enforced that there was only a single line at +the end of the file. If you still want this behavior, consider enabling +[no-multiple-empty-lines](no-multiple-empty-lines) with `maxEOF` and/or +[no-trailing-spaces](no-trailing-spaces). + +Examples of **incorrect** code for this rule: + +```js +/*eslint eol-last: ["error", "always"]*/ + +function doSmth() { + var foo = 2; +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint eol-last: ["error", "always"]*/ + +function doSmth() { + var foo = 2; +}\n +``` + +## Options + +This rule has a string option: + +* `"always"` (default) enforces that files end with a newline (LF) +* `"never"` enforces that files do not end with a newline +* `"unix"` (deprecated) is identical to "always" +* `"windows"` (deprecated) is identical to "always", but will use a CRLF character when autofixing + +**Deprecated:** The options `"unix"` and `"windows"` are deprecated. If you need to enforce a specific linebreak style, use this rule in conjunction with `linebreak-style`. + +## Version + +This rule was introduced in ESLint 0.7.1. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/eol-last.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/eol-last.md) diff --git a/docs/8.0.0/rules/eqeqeq.md b/docs/8.0.0/rules/eqeqeq.md new file mode 100644 index 0000000000..c0594ed47f --- /dev/null +++ b/docs/8.0.0/rules/eqeqeq.md @@ -0,0 +1,144 @@ +--- +title: eqeqeq - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/eqeqeq.md +rule_type: suggestion +--- + + +# Require === and !== (eqeqeq) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +It is considered good practice to use the type-safe equality operators `===` and `!==` instead of their regular counterparts `==` and `!=`. + +The reason for this is that `==` and `!=` do type coercion which follows the rather obscure [Abstract Equality Comparison Algorithm](https://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3). +For instance, the following statements are all considered `true`: + +* `[] == false` +* `[] == ![]` +* `3 == "03"` + +If one of those occurs in an innocent-looking statement such as `a == b` the actual problem is very difficult to spot. + +## Rule Details + +This rule is aimed at eliminating the type-unsafe equality operators. + +Examples of **incorrect** code for this rule: + +```js +/*eslint eqeqeq: "error"*/ + +if (x == 42) { } + +if ("" == text) { } + +if (obj.getStuff() != undefined) { } +``` + +The `--fix` option on the command line automatically fixes some problems reported by this rule. A problem is only fixed if one of the operands is a `typeof` expression, or if both operands are literals with the same type. + +## Options + +### always + +The `"always"` option (default) enforces the use of `===` and `!==` in every situation (except when you opt-in to more specific handling of `null` [see below]). + +Examples of **incorrect** code for the `"always"` option: + +```js +/*eslint eqeqeq: ["error", "always"]*/ + +a == b +foo == true +bananas != 1 +value == undefined +typeof foo == 'undefined' +'hello' != 'world' +0 == 0 +true == true +foo == null + +``` + +Examples of **correct** code for the `"always"` option: + +```js +/*eslint eqeqeq: ["error", "always"]*/ + +a === b +foo === true +bananas !== 1 +value === undefined +typeof foo === 'undefined' +'hello' !== 'world' +0 === 0 +true === true +foo === null + +``` + +This rule optionally takes a second argument, which should be an object with the following supported properties: + +* `"null"`: Customize how this rule treats `null` literals. Possible values: + * `always` (default) - Always use === or !==. + * `never` - Never use === or !== with `null`. + * `ignore` - Do not apply this rule to `null`. + +### smart + +The `"smart"` option enforces the use of `===` and `!==` except for these cases: + +* Comparing two literal values +* Evaluating the value of `typeof` +* Comparing against `null` + +Examples of **incorrect** code for the `"smart"` option: + +```js +/*eslint eqeqeq: ["error", "smart"]*/ + +// comparing two variables requires === +a == b + +// only one side is a literal +foo == true +bananas != 1 + +// comparing to undefined requires === +value == undefined +``` + +Examples of **correct** code for the `"smart"` option: + +```js +/*eslint eqeqeq: ["error", "smart"]*/ + +typeof foo == 'undefined' +'hello' != 'world' +0 == 0 +true == true +foo == null +``` + +### allow-null + +**Deprecated:** Instead of using this option use "always" and pass a "null" option property with value "ignore". This will tell ESLint to always enforce strict equality except when comparing with the `null` literal. + +```js +["error", "always", {"null": "ignore"}] +``` + +## When Not To Use It + +If you don't want to enforce a style for using equality operators, then it's safe to disable this rule. + +## Version + +This rule was introduced in ESLint 0.0.2. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/eqeqeq.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/eqeqeq.md) diff --git a/docs/8.0.0/rules/for-direction.md b/docs/8.0.0/rules/for-direction.md new file mode 100644 index 0000000000..54ca048683 --- /dev/null +++ b/docs/8.0.0/rules/for-direction.md @@ -0,0 +1,43 @@ +--- +title: for-direction - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/for-direction.md +rule_type: problem +--- + + +# Enforce "for" loop update clause moving the counter in the right direction. (for-direction) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +## Rule Details + +A `for` loop with a stop condition that can never be reached, such as one with a counter that moves in the wrong direction, will run infinitely. While there are occasions when an infinite loop is intended, the convention is to construct such loops as `while` loops. More typically, an infinite for loop is a bug. + +Examples of **incorrect** code for this rule: + +```js +/*eslint for-direction: "error"*/ +for (var i = 0; i < 10; i--) { +} + +for (var i = 10; i >= 0; i++) { +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint for-direction: "error"*/ +for (var i = 0; i < 10; i++) { +} +``` + +## Version + +This rule was introduced in ESLint 4.0.0-beta.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/for-direction.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/for-direction.md) diff --git a/docs/8.0.0/rules/func-call-spacing.md b/docs/8.0.0/rules/func-call-spacing.md new file mode 100644 index 0000000000..e26da38ef9 --- /dev/null +++ b/docs/8.0.0/rules/func-call-spacing.md @@ -0,0 +1,124 @@ +--- +title: func-call-spacing - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/func-call-spacing.md +rule_type: layout +--- + + +# require or disallow spacing between function identifiers and their invocations (func-call-spacing) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +When calling a function, developers may insert optional whitespace between the function's name and the parentheses that invoke it. The following pairs of function calls are equivalent: + +```js +alert('Hello'); +alert ('Hello'); + +console.log(42); +console.log (42); + +new Date(); +new Date (); +``` + +## Rule Details + +This rule requires or disallows spaces between the function name and the opening parenthesis that calls it. + +## options + +This rule has a string option: + +- `"never"` (default) disallows space between the function name and the opening parenthesis. +- `"always"` requires space between the function name and the opening parenthesis. + +Further, in `"always"` mode, a second object option is available that contains a single boolean `allowNewlines` property. + +### never + +Examples of **incorrect** code for this rule with the default `"never"` option: + +```js +/*eslint func-call-spacing: ["error", "never"]*/ + +fn (); + +fn +(); +``` + +Examples of **correct** code for this rule with the default `"never"` option: + +```js +/*eslint func-call-spacing: ["error", "never"]*/ + +fn(); +``` + +### always + +Examples of **incorrect** code for this rule with the `"always"` option: + +```js +/*eslint func-call-spacing: ["error", "always"]*/ + +fn(); + +fn +(); +``` + +Examples of **correct** code for this rule with the `"always"` option: + +```js +/*eslint func-call-spacing: ["error", "always"]*/ + +fn (); +``` + +#### allowNewlines + +By default, `"always"` does not allow newlines. To permit newlines when in `"always"` mode, set the `allowNewlines` option to `true`. Newlines are never required. + +Examples of **incorrect** code for this rule with `allowNewlines` option enabled: + +```js +/*eslint func-call-spacing: ["error", "always", { "allowNewlines": true }]*/ + +fn(); +``` + +Examples of **correct** code for this rule with the `allowNewlines` option enabled: + +```js +/*eslint func-call-spacing: ["error", "always", { "allowNewlines": true }]*/ + +fn (); // Newlines are never required. + +fn +(); +``` + +## When Not To Use It + +This rule can safely be turned off if your project does not care about enforcing a consistent style for spacing within function calls. + +## Related Rules + +- [no-spaced-func](no-spaced-func) (deprecated) + +## Compatibility + +- **JSCS**: [disallowSpacesInCallExpression](https://jscs-dev.github.io/rule/disallowSpacesInCallExpression) +- **JSCS**: [requireSpacesInCallExpression](https://jscs-dev.github.io/rule/requireSpacesInCallExpression) + +## Version + +This rule was introduced in ESLint 3.3.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/func-call-spacing.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/func-call-spacing.md) diff --git a/docs/8.0.0/rules/func-name-matching.md b/docs/8.0.0/rules/func-name-matching.md new file mode 100644 index 0000000000..1c66b05a94 --- /dev/null +++ b/docs/8.0.0/rules/func-name-matching.md @@ -0,0 +1,157 @@ +--- +title: func-name-matching - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/func-name-matching.md +rule_type: suggestion +--- + + +# require function names to match the name of the variable or property to which they are assigned (func-name-matching) + +## Rule Details + +This rule requires function names to match the name of the variable or property to which they are assigned. The rule will ignore property assignments where the property name is a literal that is not a valid identifier in the ECMAScript version specified in your configuration (default ES5). + +Examples of **incorrect** code for this rule: + +```js +/*eslint func-name-matching: "error"*/ + +var foo = function bar() {}; +foo = function bar() {}; +obj.foo = function bar() {}; +obj['foo'] = function bar() {}; +var obj = {foo: function bar() {}}; +({['foo']: function bar() {}}); +``` + +```js +/*eslint func-name-matching: ["error", "never"] */ + +var foo = function foo() {}; +foo = function foo() {}; +obj.foo = function foo() {}; +obj['foo'] = function foo() {}; +var obj = {foo: function foo() {}}; +({['foo']: function foo() {}}); +``` + +Examples of **correct** code for this rule: + +```js +/*eslint func-name-matching: "error"*/ +/*eslint func-name-matching: ["error", "always"]*/ // these are equivalent +/*eslint-env es6*/ + +var foo = function foo() {}; +var foo = function() {}; +var foo = () => {}; +foo = function foo() {}; + +obj.foo = function foo() {}; +obj['foo'] = function foo() {}; +obj['foo//bar'] = function foo() {}; +obj[foo] = function bar() {}; + +var obj = {foo: function foo() {}}; +var obj = {[foo]: function bar() {}}; +var obj = {'foo//bar': function foo() {}}; +var obj = {foo: function() {}}; + +obj['x' + 2] = function bar(){}; +var [ bar ] = [ function bar(){} ]; +({[foo]: function bar() {}}) + +module.exports = function foo(name) {}; +module['exports'] = function foo(name) {}; +``` + +```js +/*eslint func-name-matching: ["error", "never"] */ +/*eslint-env es6*/ + +var foo = function bar() {}; +var foo = function() {}; +var foo = () => {}; +foo = function bar() {}; + +obj.foo = function bar() {}; +obj['foo'] = function bar() {}; +obj['foo//bar'] = function foo() {}; +obj[foo] = function foo() {}; + +var obj = {foo: function bar() {}}; +var obj = {[foo]: function foo() {}}; +var obj = {'foo//bar': function foo() {}}; +var obj = {foo: function() {}}; + +obj['x' + 2] = function bar(){}; +var [ bar ] = [ function bar(){} ]; +({[foo]: function bar() {}}) + +module.exports = function foo(name) {}; +module['exports'] = function foo(name) {}; +``` + +## Options + +This rule takes an optional string of "always" or "never" (when omitted, it defaults to "always"), and an optional options object with two properties `considerPropertyDescriptor` and `includeCommonJSModuleExports`. + +### considerPropertyDescriptor + +A boolean value that defaults to `false`. If `considerPropertyDescriptor` is set to true, the check will take into account the use of `Object.create`, `Object.defineProperty`, `Object.defineProperties`, and `Reflect.defineProperty`. + +Examples of **correct** code for the `{ considerPropertyDescriptor: true }` option: + +```js +/*eslint func-name-matching: ["error", { "considerPropertyDescriptor": true }]*/ +/*eslint func-name-matching: ["error", "always", { "considerPropertyDescriptor": true }]*/ // these are equivalent +var obj = {}; +Object.create(obj, {foo:{value: function foo() {}}}); +Object.defineProperty(obj, 'bar', {value: function bar() {}}); +Object.defineProperties(obj, {baz:{value: function baz() {} }}); +Reflect.defineProperty(obj, 'foo', {value: function foo() {}}); +``` + +Examples of **incorrect** code for the `{ considerPropertyDescriptor: true }` option: + +```js +/*eslint func-name-matching: ["error", { "considerPropertyDescriptor": true }]*/ +/*eslint func-name-matching: ["error", "always", { "considerPropertyDescriptor": true }]*/ // these are equivalent +var obj = {}; +Object.create(obj, {foo:{value: function bar() {}}}); +Object.defineProperty(obj, 'bar', {value: function baz() {}}); +Object.defineProperties(obj, {baz:{value: function foo() {} }}); +Reflect.defineProperty(obj, 'foo', {value: function value() {}}); +``` + +### includeCommonJSModuleExports + +A boolean value that defaults to `false`. If `includeCommonJSModuleExports` is set to true, `module.exports` and `module["exports"]` will be checked by this rule. + +Examples of **incorrect** code for the `{ includeCommonJSModuleExports: true }` option: + +```js +/*eslint func-name-matching: ["error", { "includeCommonJSModuleExports": true }]*/ +/*eslint func-name-matching: ["error", "always", { "includeCommonJSModuleExports": true }]*/ // these are equivalent + +module.exports = function foo(name) {}; +module['exports'] = function foo(name) {}; +``` + +## When Not To Use It + +Do not use this rule if you want to allow named functions to have different names from the variable or property to which they are assigned. + +## Compatibility + +* **JSCS**: [requireMatchingFunctionName](https://jscs-dev.github.io/rule/requireMatchingFunctionName) + +## Version + +This rule was introduced in ESLint 3.8.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/func-name-matching.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/func-name-matching.md) diff --git a/docs/8.0.0/rules/func-names.md b/docs/8.0.0/rules/func-names.md new file mode 100644 index 0000000000..ec5a7660d0 --- /dev/null +++ b/docs/8.0.0/rules/func-names.md @@ -0,0 +1,234 @@ +--- +title: func-names - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/func-names.md +rule_type: suggestion +--- + + +# Require or disallow named `function` expressions (func-names) + +A pattern that's becoming more common is to give function expressions names to aid in debugging. For example: + +```js +Foo.prototype.bar = function bar() {}; +``` + +Adding the second `bar` in the above example is optional. If you leave off the function name then when the function throws an exception you are likely to get something similar to `anonymous function` in the stack trace. If you provide the optional name for a function expression then you will get the name of the function expression in the stack trace. + +## Rule Details + +This rule can enforce or disallow the use of named function expressions. + +## Options + +This rule has a string option: + +* `"always"` (default) requires function expressions to have a name +* `"as-needed"` requires function expressions to have a name, if the name isn't assigned automatically per the ECMAScript specification. +* `"never"` disallows named function expressions, except in recursive functions, where a name is needed + +This rule has an object option: + +* `"generators": "always" | "as-needed" | "never"` + * `"always"` require named generators + * `"as-needed"` require named generators if the name isn't assigned automatically per the ECMAScript specification. + * `"never"` disallow named generators where possible. + +When a value for `generators` is not provided the behavior for generator functions falls back to the base option. + +Please note that `"always"` and `"as-needed"` require function expressions and function declarations in `export default` declarations to have a name. + +### always + +Examples of **incorrect** code for this rule with the default `"always"` option: + +```js +/*eslint func-names: ["error", "always"]*/ + +Foo.prototype.bar = function() {}; + +const cat = { + meow: function() {} +} + +(function() { + // ... +}()) + +export default function() {} +``` + +Examples of **correct** code for this rule with the default `"always"` option: + +```js +/*eslint func-names: ["error", "always"]*/ + +Foo.prototype.bar = function bar() {}; + +const cat = { + meow() {} +} + +(function bar() { + // ... +}()) + +export default function foo() {} +``` + +### as-needed + +ECMAScript 6 introduced a `name` property on all functions. The value of `name` is determined by evaluating the code around the function to see if a name can be inferred. For example, a function assigned to a variable will automatically have a `name` property equal to the name of the variable. The value of `name` is then used in stack traces for easier debugging. + +Examples of **incorrect** code for this rule with the `"as-needed"` option: + +```js +/*eslint func-names: ["error", "as-needed"]*/ + +Foo.prototype.bar = function() {}; + +(function() { + // ... +}()) + +export default function() {} +``` + +Examples of **correct** code for this rule with the `"as-needed"` option: + +```js +/*eslint func-names: ["error", "as-needed"]*/ + +var bar = function() {}; + +const cat = { + meow: function() {} +} + +class C { + #bar = function() {}; + baz = function() {}; +} + +quux ??= function() {}; + +(function bar() { + // ... +}()) + +export default function foo() {} +``` + +### never + +Examples of **incorrect** code for this rule with the `"never"` option: + +```js +/*eslint func-names: ["error", "never"]*/ + +Foo.prototype.bar = function bar() {}; + +(function bar() { + // ... +}()) +``` + +Examples of **correct** code for this rule with the `"never"` option: + +```js +/*eslint func-names: ["error", "never"]*/ + +Foo.prototype.bar = function() {}; + +(function() { + // ... +}()) +``` + +### generators + +Examples of **incorrect** code for this rule with the `"always", { "generators": "as-needed" }` options: + +```js +/*eslint func-names: ["error", "always", { "generators": "as-needed" }]*/ + +(function*() { + // ... +}()) +``` + +Examples of **correct** code for this rule with the `"always", { "generators": "as-needed" }` options: + +```js +/*eslint func-names: ["error", "always", { "generators": "as-needed" }]*/ + +var foo = function*() {}; +``` + +Examples of **incorrect** code for this rule with the `"always", { "generators": "never" }` options: + +```js +/*eslint func-names: ["error", "always", { "generators": "never" }]*/ + +var foo = bar(function *baz() {}); +``` + +Examples of **correct** code for this rule with the `"always", { "generators": "never" }` options: + +```js +/*eslint func-names: ["error", "always", { "generators": "never" }]*/ + +var foo = bar(function *() {}); +``` + +Examples of **incorrect** code for this rule with the `"as-needed", { "generators": "never" }` options: + +```js +/*eslint func-names: ["error", "as-needed", { "generators": "never" }]*/ + +var foo = bar(function *baz() {}); +``` + +Examples of **correct** code for this rule with the `"as-needed", { "generators": "never" }` options: + +```js +/*eslint func-names: ["error", "as-needed", { "generators": "never" }]*/ + +var foo = bar(function *() {}); +``` + +Examples of **incorrect** code for this rule with the `"never", { "generators": "always" }` options: + +```js +/*eslint func-names: ["error", "never", { "generators": "always" }]*/ + +var foo = bar(function *() {}); +``` + +Examples of **correct** code for this rule with the `"never", { "generators": "always" }` options: + +```js +/*eslint func-names: ["error", "never", { "generators": "always" }]*/ + +var foo = bar(function *baz() {}); +``` + +## Further Reading + +* [Functions Explained](http://markdaggett.com/blog/2013/02/15/functions-explained/) +* [Function Names in ES6](http://2ality.com/2015/09/function-names-es6.html) + +## Compatibility + +* **JSCS**: [requireAnonymousFunctions](https://jscs-dev.github.io/rule/requireAnonymousFunctions) +* **JSCS**: [disallowAnonymousFunctions](https://jscs-dev.github.io/rule/disallowAnonymousFunctions) + +## Version + +This rule was introduced in ESLint 0.4.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/func-names.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/func-names.md) diff --git a/docs/8.0.0/rules/func-style.md b/docs/8.0.0/rules/func-style.md new file mode 100644 index 0000000000..a339b8b18a --- /dev/null +++ b/docs/8.0.0/rules/func-style.md @@ -0,0 +1,148 @@ +--- +title: func-style - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/func-style.md +rule_type: suggestion +--- + + +# enforce the consistent use of either `function` declarations or expressions (func-style) + +There are two ways of defining functions in JavaScript: `function` declarations and `function` expressions. Declarations contain the `function` keyword first, followed by a name and then its arguments and the function body, for example: + +```js +function doSomething() { + // ... +} +``` + +Equivalent function expressions begin with the `var` keyword, followed by a name and then the function itself, such as: + +```js +var doSomething = function() { + // ... +}; +``` + +The primary difference between `function` declarations and `function expressions` is that declarations are *hoisted* to the top of the scope in which they are defined, which allows you to write code that uses the function before its declaration. For example: + +```js +doSomething(); + +function doSomething() { + // ... +} +``` + +Although this code might seem like an error, it actually works fine because JavaScript engines hoist the `function` declarations to the top of the scope. That means this code is treated as if the declaration came before the invocation. + +For `function` expressions, you must define the function before it is used, otherwise it causes an error. Example: + +```js +doSomething(); // error! + +var doSomething = function() { + // ... +}; +``` + +In this case, `doSomething()` is undefined at the time of invocation and so causes a runtime error. + +Due to these different behaviors, it is common to have guidelines as to which style of function should be used. There is really no correct or incorrect choice here, it is just a preference. + +## Rule Details + +This rule enforces a particular type of `function` style throughout a JavaScript file, either declarations or expressions. You can specify which you prefer in the configuration. + +## Options + +This rule has a string option: + +* `"expression"` (default) requires the use of function expressions instead of function declarations +* `"declaration"` requires the use of function declarations instead of function expressions + +This rule has an object option for an exception: + +* `"allowArrowFunctions"`: `true` (default `false`) allows the use of arrow functions. This option applies only when the string option is set to `"declaration"` (arrow functions are always allowed when the string option is set to `"expression"`, regardless of this option) + +### expression + +Examples of **incorrect** code for this rule with the default `"expression"` option: + +```js +/*eslint func-style: ["error", "expression"]*/ + +function foo() { + // ... +} +``` + +Examples of **correct** code for this rule with the default `"expression"` option: + +```js +/*eslint func-style: ["error", "expression"]*/ + +var foo = function() { + // ... +}; + +var foo = () => {}; + +// allowed as allowArrowFunctions : false is applied only for declaration +``` + +### declaration + +Examples of **incorrect** code for this rule with the `"declaration"` option: + +```js +/*eslint func-style: ["error", "declaration"]*/ + +var foo = function() { + // ... +}; + +var foo = () => {}; +``` + +Examples of **correct** code for this rule with the `"declaration"` option: + +```js +/*eslint func-style: ["error", "declaration"]*/ + +function foo() { + // ... +} + +// Methods (functions assigned to objects) are not checked by this rule +SomeObject.foo = function() { + // ... +}; +``` + +### allowArrowFunctions + +Examples of additional **correct** code for this rule with the `"declaration", { "allowArrowFunctions": true }` options: + +```js +/*eslint func-style: ["error", "declaration", { "allowArrowFunctions": true }]*/ + +var foo = () => {}; +``` + +## When Not To Use It + +If you want to allow developers to each decide how they want to write functions on their own, then you can disable this rule. + +## Further Reading + +* [JavaScript Scoping and Hoisting](http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html) + +## Version + +This rule was introduced in ESLint 0.2.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/func-style.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/func-style.md) diff --git a/docs/8.0.0/rules/function-call-argument-newline.md b/docs/8.0.0/rules/function-call-argument-newline.md new file mode 100644 index 0000000000..aad45d991e --- /dev/null +++ b/docs/8.0.0/rules/function-call-argument-newline.md @@ -0,0 +1,221 @@ +--- +title: function-call-argument-newline - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/function-call-argument-newline.md +rule_type: layout +--- + + +# enforce line breaks between arguments of a function call (function-call-argument-newline) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +A number of style guides require or disallow line breaks between arguments of a function call. + +## Rule Details + +This rule enforces line breaks between arguments of a function call. + +## Options + +This rule has a string option: + +* `"always"` (default) requires line breaks between arguments +* `"never"` disallows line breaks between arguments +* `"consistent"` requires consistent usage of line breaks between arguments + + +### always + +Examples of **incorrect** code for this rule with the default `"always"` option: + +```js +/*eslint function-call-argument-newline: ["error", "always"]*/ + +foo("one", "two", "three"); + +bar("one", "two", { + one: 1, + two: 2 +}); + +baz("one", "two", (x) => { + console.log(x); +}); +``` + +Examples of **correct** code for this rule with the default `"always"` option: + +```js +/*eslint function-call-argument-newline: ["error", "always"]*/ + +foo( + "one", + "two", + "three" +); + +bar( + "one", + "two", + { one: 1, two: 2 } +); +// or +bar( + "one", + "two", + { + one: 1, + two: 2 + } +); + +baz( + "one", + "two", + (x) => { + console.log(x); + } +); +``` + + +### never + +Examples of **incorrect** code for this rule with the `"never"` option: + +```js +/*eslint function-call-argument-newline: ["error", "never"]*/ + +foo( + "one", + "two", "three" +); + +bar( + "one", + "two", { + one: 1, + two: 2 + } +); + +baz( + "one", + "two", (x) => { + console.log(x); + } +); +``` + +Examples of **correct** code for this rule with the `"never"` option: + +```js +/*eslint function-call-argument-newline: ["error", "never"]*/ + +foo("one", "two", "three"); +// or +foo( + "one", "two", "three" +); + +bar("one", "two", { one: 1, two: 2 }); +// or +bar("one", "two", { + one: 1, + two: 2 +}); + +baz("one", "two", (x) => { + console.log(x); +}); +``` + +### consistent + +Examples of **incorrect** code for this rule with the `"consistent"` option: + +```js +/*eslint function-call-argument-newline: ["error", "consistent"]*/ + +foo("one", "two", + "three"); +//or +foo("one", + "two", "three"); + +bar("one", "two", + { one: 1, two: 2} +); + +baz("one", "two", + (x) => { console.log(x); } +); +``` + +Examples of **correct** code for this rule with the `"consistent"` option: + +```js +/*eslint function-call-argument-newline: ["error", "consistent"]*/ + +foo("one", "two", "three"); +// or +foo( + "one", + "two", + "three" +); + +bar("one", "two", { + one: 1, + two: 2 +}); +// or +bar( + "one", + "two", + { one: 1, two: 2 } +); +// or +bar( + "one", + "two", + { + one: 1, + two: 2 + } +); + +baz("one", "two", (x) => { + console.log(x); +}); +// or +baz( + "one", + "two", + (x) => { + console.log(x); + } +); +``` + + +## When Not To Use It + +If you don't want to enforce line breaks between arguments, don't enable this rule. + +## Related Rules + +* [function-paren-newline](function-paren-newline) +* [func-call-spacing](func-call-spacing) +* [object-property-newline](object-property-newline) +* [array-element-newline](array-element-newline) + +## Version + +This rule was introduced in ESLint 6.2.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/function-call-argument-newline.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/function-call-argument-newline.md) diff --git a/docs/8.0.0/rules/function-paren-newline.md b/docs/8.0.0/rules/function-paren-newline.md new file mode 100644 index 0000000000..77f0b89f5f --- /dev/null +++ b/docs/8.0.0/rules/function-paren-newline.md @@ -0,0 +1,347 @@ +--- +title: function-paren-newline - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/function-paren-newline.md +rule_type: layout +--- + + +# enforce consistent line breaks inside function parentheses (function-paren-newline) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +Many style guides require or disallow newlines inside of function parentheses. + +## Rule Details + +This rule enforces consistent line breaks inside parentheses of function parameters or arguments. + +### Options + +This rule has a single option, which can either be a string or an object. + +* `"always"` requires line breaks inside all function parentheses. +* `"never"` disallows line breaks inside all function parentheses. +* `"multiline"` (default) requires linebreaks inside function parentheses if any of the parameters/arguments have a line break between them. Otherwise, it disallows linebreaks. +* `"multiline-arguments"` works like `multiline` but allows linebreaks inside function parentheses if there is only one parameter/argument. +* `"consistent"` requires consistent usage of linebreaks for each pair of parentheses. It reports an error if one parenthesis in the pair has a linebreak inside it and the other parenthesis does not. +* `{ "minItems": value }` requires linebreaks inside function parentheses if the number of parameters/arguments is at least `value`. Otherwise, it disallows linebreaks. + +Example configurations: + +```json +{ + "rules": { + "function-paren-newline": ["error", "never"] + } +} +``` + +```json +{ + "rules": { + "function-paren-newline": ["error", { "minItems": 3 }] + } +} +``` + +Examples of **incorrect** code for this rule with the `"always"` option: + +```js +/* eslint function-paren-newline: ["error", "always"] */ + +function foo(bar, baz) {} + +var foo = function(bar, baz) {}; + +var foo = (bar, baz) => {}; + +foo(bar, baz); +``` + +Examples of **correct** code for this rule with the `"always"` option: + +```js +/* eslint function-paren-newline: ["error", "always"] */ + +function foo( + bar, + baz +) {} + +var foo = function( + bar, baz +) {}; + +var foo = ( + bar, + baz +) => {}; + +foo( + bar, + baz +); +``` + +Examples of **incorrect** code for this rule with the `"never"` option: + +```js +/* eslint function-paren-newline: ["error", "never"] */ + +function foo( + bar, + baz +) {} + +var foo = function( + bar, baz +) {}; + +var foo = ( + bar, + baz +) => {}; + +foo( + bar, + baz +); +``` + +Examples of **correct** code for this rule with the `"never"` option: + +```js +/* eslint function-paren-newline: ["error", "never"] */ + +function foo(bar, baz) {} + +function foo(bar, + baz) {} + +var foo = function(bar, baz) {}; + +var foo = (bar, baz) => {}; + +foo(bar, baz); + +foo(bar, + baz); +``` + +Examples of **incorrect** code for this rule with the default `"multiline"` option: + +```js +/* eslint function-paren-newline: ["error", "multiline"] */ + +function foo(bar, + baz +) {} + +var foo = function( + bar, baz +) {}; + +var foo = ( + bar, + baz) => {}; + +foo(bar, + baz); + +foo( + function() { + return baz; + } +); +``` + +Examples of **correct** code for this rule with the default `"multiline"` option: + +```js +/* eslint function-paren-newline: ["error", "multiline"] */ + +function foo(bar, baz) {} + +var foo = function( + bar, + baz +) {}; + +var foo = (bar, baz) => {}; + +foo(bar, baz, qux); + +foo( + bar, + baz, + qux +); + +foo(function() { + return baz; +}); +``` + +Examples of **incorrect** code for this rule with the `"consistent"` option: + +```js +/* eslint function-paren-newline: ["error", "consistent"] */ + +function foo(bar, + baz +) {} + +var foo = function(bar, + baz +) {}; + +var foo = ( + bar, + baz) => {}; + +foo( + bar, + baz); + +foo( + function() { + return baz; + }); +``` + +Examples of **correct** code for this rule with the `"consistent"` option: + +```js +/* eslint function-paren-newline: ["error", "consistent"] */ + +function foo(bar, + baz) {} + +var foo = function(bar, baz) {}; + +var foo = ( + bar, + baz +) => {}; + +foo( + bar, baz +); + +foo( + function() { + return baz; + } +); +``` + +Examples of **incorrect** code for this rule with the `"multiline-arguments"` option: + +```js +/* eslint function-paren-newline: ["error", "multiline-arguments"] */ + +function foo(bar, + baz +) {} + +var foo = function(bar, + baz +) {}; + +var foo = ( + bar, + baz) => {}; + +foo( + bar, + baz); + +foo( + bar, qux, + baz +); +``` + +Examples of **correct** code for this rule with the consistent `"multiline-arguments"` option: + +```js +/* eslint function-paren-newline: ["error", "multiline-arguments"] */ + +function foo( + bar, + baz +) {} + +var foo = function(bar, baz) {}; + +var foo = ( + bar +) => {}; + +foo( + function() { + return baz; + } +); +``` + +Examples of **incorrect** code for this rule with the `{ "minItems": 3 }` option: + +```js +/* eslint function-paren-newline: ["error", { "minItems": 3 }] */ + +function foo( + bar, + baz +) {} + +function foo(bar, baz, qux) {} + +var foo = function( + bar, baz +) {}; + +var foo = (bar, + baz) => {}; + +foo(bar, + baz); +``` + +Examples of **correct** code for this rule with the `{ "minItems": 3 }` option: + +```js +/* eslint function-paren-newline: ["error", { "minItems": 3 }] */ + +function foo(bar, baz) {} + +var foo = function( + bar, + baz, + qux +) {}; + +var foo = ( + bar, baz, qux +) => {}; + +foo(bar, baz); + +foo( + bar, baz, qux +); +``` + +## When Not To Use It + +If don't want to enforce consistent linebreaks inside function parentheses, do not turn on this rule. + +## Version + +This rule was introduced in ESLint 4.6.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/function-paren-newline.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/function-paren-newline.md) diff --git a/docs/8.0.0/rules/generator-star-spacing.md b/docs/8.0.0/rules/generator-star-spacing.md new file mode 100644 index 0000000000..a903768228 --- /dev/null +++ b/docs/8.0.0/rules/generator-star-spacing.md @@ -0,0 +1,226 @@ +--- +title: generator-star-spacing - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/generator-star-spacing.md +rule_type: layout +--- + + +# Enforce spacing around the * in generator functions (generator-star-spacing) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +Generators are a new type of function in ECMAScript 6 that can return multiple values over time. +These special functions are indicated by placing an `*` after the `function` keyword. + +Here is an example of a generator function: + +```js +/*eslint-env es6*/ + +function* generator() { + yield "44"; + yield "55"; +} +``` + +This is also valid: + +```js +/*eslint-env es6*/ + +function *generator() { + yield "44"; + yield "55"; +} +``` + +This is valid as well: + +```js +/*eslint-env es6*/ + +function * generator() { + yield "44"; + yield "55"; +} +``` + +To keep a sense of consistency when using generators this rule enforces a single position for the `*`. + +## Rule Details + +This rule aims to enforce spacing around the `*` of generator functions. + +## Options + +The rule takes one option, an object, which has two keys `before` and `after` having boolean values `true` or `false`. + +* `before` enforces spacing between the `*` and the `function` keyword. + If it is `true`, a space is required, otherwise spaces are disallowed. + + In object literal shorthand methods, spacing before the `*` is not checked, as they lack a `function` keyword. + +* `after` enforces spacing between the `*` and the function name (or the opening parenthesis for anonymous generator functions). + If it is `true`, a space is required, otherwise spaces are disallowed. + +The default is `{"before": true, "after": false}`. + +An example configuration: + +```json +"generator-star-spacing": ["error", {"before": true, "after": false}] +``` + +And the option has shorthand as a string keyword: + +* `{"before": true, "after": false}` → `"before"` +* `{"before": false, "after": true}` → `"after"` +* `{"before": true, "after": true}` → `"both"` +* `{"before": false, "after": false}` → `"neither"` + +An example of shorthand configuration: + +```json +"generator-star-spacing": ["error", "after"] +``` + +Additionally, this rule allows further configurability via overrides per function type. + +* `named` provides overrides for named functions +* `anonymous` provides overrides for anonymous functions +* `method` provides overrides for class methods or property function shorthand + +An example of a configuration with overrides: + +```json +"generator-star-spacing": ["error", { + "before": false, + "after": true, + "anonymous": "neither", + "method": {"before": true, "after": true} +}] +``` + +In the example configuration above, the top level "before" and "after" options define the default behavior of +the rule, while the "anonymous" and "method" options override the default behavior. +Overrides can be either an object with "before" and "after", or a shorthand string as above. + +## Examples + +### before + +Examples of **correct** code for this rule with the `"before"` option: + +```js +/*eslint generator-star-spacing: ["error", {"before": true, "after": false}]*/ +/*eslint-env es6*/ + +function *generator() {} + +var anonymous = function *() {}; + +var shorthand = { *generator() {} }; +``` + +### after + +Examples of **correct** code for this rule with the `"after"` option: + +```js +/*eslint generator-star-spacing: ["error", {"before": false, "after": true}]*/ +/*eslint-env es6*/ + +function* generator() {} + +var anonymous = function* () {}; + +var shorthand = { * generator() {} }; +``` + +### both + +Examples of **correct** code for this rule with the `"both"` option: + +```js +/*eslint generator-star-spacing: ["error", {"before": true, "after": true}]*/ +/*eslint-env es6*/ + +function * generator() {} + +var anonymous = function * () {}; + +var shorthand = { * generator() {} }; +``` + +### neither + +Examples of **correct** code for this rule with the `"neither"` option: + +```js +/*eslint generator-star-spacing: ["error", {"before": false, "after": false}]*/ +/*eslint-env es6*/ + +function*generator() {} + +var anonymous = function*() {}; + +var shorthand = { *generator() {} }; +``` + +Examples of **incorrect** code for this rule with overrides present: + +```js +/*eslint generator-star-spacing: ["error", { + "before": false, + "after": true, + "anonymous": "neither", + "method": {"before": true, "after": true} +}]*/ +/*eslint-env es6*/ + +function * generator() {} + +var anonymous = function* () {}; + +var shorthand = { *generator() {} }; + +class Class { static* method() {} } +``` + +Examples of **correct** code for this rule with overrides present: + +```js +/*eslint generator-star-spacing: ["error", { + "before": false, + "after": true, + "anonymous": "neither", + "method": {"before": true, "after": true} +}]*/ +/*eslint-env es6*/ + +function* generator() {} + +var anonymous = function*() {}; + +var shorthand = { * generator() {} }; + +class Class { static * method() {} } +``` + +## When Not To Use It + +If your project will not be using generators or you are not concerned with spacing consistency, you do not need this rule. + +## Further Reading + +* [Understanding ES6: Generators](https://leanpub.com/understandinges6/read/#leanpub-auto-generators) + +## Version + +This rule was introduced in ESLint 0.17.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/generator-star-spacing.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/generator-star-spacing.md) diff --git a/docs/8.0.0/rules/generator-star.md b/docs/8.0.0/rules/generator-star.md new file mode 100644 index 0000000000..60feea1374 --- /dev/null +++ b/docs/8.0.0/rules/generator-star.md @@ -0,0 +1,142 @@ +--- +title: generator-star - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/generator-star.md + +--- + + +# generator-star: enforce consistent spacing around the asterisk in generator functions + +(removed) This rule was **removed** in ESLint v1.0 and **replaced** by the [generator-star-spacing](generator-star-spacing) rule. + +Generators are a new type of function in ECMAScript 6 that can return multiple values over time. +These special functions are indicated by placing an `*` after the `function` keyword. + +Here is an example of a generator function: + +```js +/*eslint-env es6*/ + +function* generator() { + yield "44"; + yield "55"; +} +``` + +This is also valid: + +```js +/*eslint-env es6*/ + +function *generator() { + yield "44"; + yield "55"; +} +``` + +This is valid as well: + +```js +/*eslint-env es6*/ + +function * generator() { + yield "44"; + yield "55"; +} +``` + +To keep a sense of consistency when using generators this rule enforces a single position for the `*`. + +## Rule Details + +This rule enforces that the `*` is either placed next to the `function` keyword or the name of the function. The single +option for this rule is a string specifying the placement of the asterisk. For this option you may pass +`"start"`, `"middle"` or `"end"`. The default is `"end"`. + +You can set the style in configuration like this: + +```json +"generator-star": ["error", "start"] +``` + +When using `"start"` this placement will be enforced: + +```js +/*eslint-env es6*/ + +function* generator() { +} +``` + +When using `"middle"` this placement will be enforced: + +```js +/*eslint-env es6*/ + +function * generator() { +} +``` + +When using `"end"` this placement will be enforced: + +```js +/*eslint-env es6*/ + +function *generator() { +} +``` + +When using the expression syntax `"start"` will be enforced here: + +```js +/*eslint-env es6*/ + +var generator = function* () { +} +``` + +When using the expression syntax `"middle"` will be enforced here: + +```js +/*eslint-env es6*/ + +var generator = function * () { +} +``` + +When using the expression syntax `"end"` will be enforced here: + +```js +/*eslint-env es6*/ + +var generator = function *() { +} +``` + +When using the expression syntax this is valid for both `"start"` and `"end"`: + +```js +/*eslint-env es6*/ + +var generator = function*() { +} +``` + +The shortened object literal syntax for generators is not affected by this rule. + +## When Not To Use It + +If your project will not be using generators you do not need this rule. + +## Further Reading + +* [Understanding ES6: Generators](https://leanpub.com/understandinges6/read/#leanpub-auto-generators) + +## Version + +This rule was introduced in ESLint 0.12.0 and removed in 1.0.0-rc-1. + +## Resources + +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/generator-star.md) diff --git a/docs/8.0.0/rules/getter-return.md b/docs/8.0.0/rules/getter-return.md new file mode 100644 index 0000000000..a8b9cfaccd --- /dev/null +++ b/docs/8.0.0/rules/getter-return.md @@ -0,0 +1,116 @@ +--- +title: getter-return - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/getter-return.md +rule_type: problem +--- + + +# Enforces that a return statement is present in property getters (getter-return) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +The get syntax binds an object property to a function that will be called when that property is looked up. It was first introduced in ECMAScript 5: + +```js + var p = { + get name(){ + return "nicholas"; + } + }; + + Object.defineProperty(p, "age", { + get: function (){ + return 17; + } + }); +``` + +Note that every `getter` is expected to return a value. + +## Rule Details + +This rule enforces that a return statement is present in property getters. + +Examples of **incorrect** code for this rule: + +```js +/*eslint getter-return: "error"*/ + +p = { + get name(){ + // no returns. + } +}; + +Object.defineProperty(p, "age", { + get: function (){ + // no returns. + } +}); + +class P{ + get name(){ + // no returns. + } +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint getter-return: "error"*/ + +p = { + get name(){ + return "nicholas"; + } +}; + +Object.defineProperty(p, "age", { + get: function (){ + return 18; + } +}); + +class P{ + get name(){ + return "nicholas"; + } +} +``` + +## Options + +This rule has an object option: + +* `"allowImplicit": false` (default) disallows implicitly returning `undefined` with a `return` statement. + +Examples of **correct** code for the `{ "allowImplicit": true }` option: + +```js +/*eslint getter-return: ["error", { allowImplicit: true }]*/ +p = { + get name(){ + return; // return undefined implicitly. + } +}; +``` + +## When Not To Use It + +If your project will not be using ES5 property getters you do not need this rule. + +## Further Reading + +* [MDN: Functions getter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get) +* [Understanding ES6: Accessor Properties](https://leanpub.com/understandinges6/read/#leanpub-auto-accessor-properties) + +## Version + +This rule was introduced in ESLint 4.2.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/getter-return.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/getter-return.md) diff --git a/docs/8.0.0/rules/global-require.md b/docs/8.0.0/rules/global-require.md new file mode 100644 index 0000000000..9eef6b3aee --- /dev/null +++ b/docs/8.0.0/rules/global-require.md @@ -0,0 +1,108 @@ +--- +title: global-require - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/global-require.md +rule_type: suggestion +--- + + +# Enforce require() on the top-level module scope (global-require) + +This rule was **deprecated** in ESLint v7.0.0. Please use the corresponding rule in [`eslint-plugin-node`](https://github.com/mysticatea/eslint-plugin-node). + +In Node.js, module dependencies are included using the `require()` function, such as: + +```js +var fs = require("fs"); +``` + +While `require()` may be called anywhere in code, some style guides prescribe that it should be called only in the top level of a module to make it easier to identify dependencies. For instance, it's arguably harder to identify dependencies when they are deeply nested inside of functions and other statements: + +```js +function foo() { + + if (condition) { + var fs = require("fs"); + } +} +``` + +Since `require()` does a synchronous load, it can cause performance problems when used in other locations. + +Further, ES6 modules mandate that `import` and `export` statements can only occur in the top level of the module's body. + +## Rule Details + +This rule requires all calls to `require()` to be at the top level of the module, similar to ES6 `import` and `export` statements, which also can occur only at the top level. + +Examples of **incorrect** code for this rule: + +```js +/*eslint global-require: "error"*/ +/*eslint-env es6*/ + +// calling require() inside of a function is not allowed +function readFile(filename, callback) { + var fs = require('fs'); + fs.readFile(filename, callback) +} + +// conditional requires like this are also not allowed +if (DEBUG) { require('debug'); } + +// a require() in a switch statement is also flagged +switch(x) { case '1': require('1'); break; } + +// you may not require() inside an arrow function body +var getModule = (name) => require(name); + +// you may not require() inside of a function body as well +function getModule(name) { return require(name); } + +// you may not require() inside of a try/catch block +try { + require(unsafeModule); +} catch(e) { + console.log(e); +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint global-require: "error"*/ + +// all these variations of require() are ok +require('x'); +var y = require('y'); +var z; +z = require('z').initialize(); + +// requiring a module and using it in a function is ok +var fs = require('fs'); +function readFile(filename, callback) { + fs.readFile(filename, callback) +} + +// you can use a ternary to determine which module to require +var logger = DEBUG ? require('dev-logger') : require('logger'); + +// if you want you can require() at the end of your module +function doSomethingA() {} +function doSomethingB() {} +var x = require("x"), + z = require("z"); +``` + +## When Not To Use It + +If you have a module that must be initialized with information that comes from the file-system or if a module is only used in very rare situations and will cause significant overhead to load it may make sense to disable the rule. If you need to `require()` an optional dependency inside of a `try`/`catch`, you can disable this rule for just that dependency using the `// eslint-disable-line global-require` comment. + +## Version + +This rule was introduced in ESLint 1.4.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/global-require.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/global-require.md) diff --git a/docs/8.0.0/rules/global-strict.md b/docs/8.0.0/rules/global-strict.md new file mode 100644 index 0000000000..f5809fa468 --- /dev/null +++ b/docs/8.0.0/rules/global-strict.md @@ -0,0 +1,77 @@ +--- +title: global-strict - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/global-strict.md + +--- + + +# global-strict: require or disallow strict mode directives in the global scope + +(removed) This rule was **removed** in ESLint v1.0 and **replaced** by the [strict](strict) rule. The `"global"` option in the new rule is most similar to the removed rule. + +Strict mode is enabled by using the following pragma in your code: + +```js +"use strict"; +``` + +When used globally, as in this example, the strict mode pragma applies to all code within a single file. This can be dangerous if you concatenate scripts together before serving them to a browser. For instance, if you have a file running in strict mode and you concatenate that file with jQuery, the strict mode now also applies to jQuery and may cause errors. + +However, if you're using Node.js, you may want to turn strict mode on globally. Files are typically not concatenated together in Node.js projects and therefore the risk of applying strict mode accidentally is minimal. Further, since every file in Node.js has its own scope, global strict mode only effects the single file in which it is placed. + +## Rule Details + +This rule requires or disallows global strict mode invoked by a `"use strict"` pragma in the global scope. + +The following pattern is under strict mode globally and is considered valid with the `"always"` option and a warning with the `"never"` option. + +```js +"use strict"; + +function foo() { + return true; +} +``` + +The following patterns apply strict mode only to functions so are valid with the `"never"` option but are problems with the `"always"` option. + +```js +function foo() { + "use strict"; + + return true; +} + +(function() { + "use strict"; + + // other code +}()); +``` + +## Options + +```json +"global-strict": ["error", "always"] +``` + +Requires that every file have a top-level `"use strict"` statement. + +```json +"global-strict": ["error", "never"] +``` + +Warns whenever `"use strict"` is used in the global scope such that it could contaminate concatenated files. + +## When Not To Use It + +When a project may use non-strict-mode code side by side with strict-mode code and the files are not concatenated, the decision to use global strict mode can be made on an individual basis, rendering this rule unnecessary. + +## Version + +This rule was introduced in ESLint 0.8.0 and removed in 1.0.0-rc-1. + +## Resources + +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/global-strict.md) diff --git a/docs/8.0.0/rules/grouped-accessor-pairs.md b/docs/8.0.0/rules/grouped-accessor-pairs.md new file mode 100644 index 0000000000..9ad7798fd7 --- /dev/null +++ b/docs/8.0.0/rules/grouped-accessor-pairs.md @@ -0,0 +1,343 @@ +--- +title: grouped-accessor-pairs - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/grouped-accessor-pairs.md +rule_type: suggestion +--- + + +# Require grouped accessor pairs in object literals and classes (grouped-accessor-pairs) + +A getter and setter for the same property don't necessarily have to be defined adjacent to each other. + +For example, the following statements would create the same object: + +```js +var o = { + get a() { + return this.val; + }, + set a(value) { + this.val = value; + }, + b: 1 +}; + +var o = { + get a() { + return this.val; + }, + b: 1, + set a(value) { + this.val = value; + } +}; +``` + +While it is allowed to define the pair for a getter or a setter anywhere in an object or class definition, it's considered a best practice to group accessor functions for the same property. + +In other words, if a property has a getter and a setter, the setter should be defined right after the getter, or vice versa. + +## Rule Details + +This rule requires grouped definitions of accessor functions for the same property in object literals, class declarations and class expressions. + +Optionally, this rule can also enforce consistent order (`getBeforeSet` or `setBeforeGet`). + +This rule does not enforce the existence of the pair for a getter or a setter. See [accessor-pairs](accessor-pairs) if you also want to enforce getter/setter pairs. + +Examples of **incorrect** code for this rule: + +```js +/*eslint grouped-accessor-pairs: "error"*/ + +var foo = { + get a() { + return this.val; + }, + b: 1, + set a(value) { + this.val = value; + } +}; + +var bar = { + set b(value) { + this.val = value; + }, + a: 1, + get b() { + return this.val; + } +} + +class Foo { + set a(value) { + this.val = value; + } + b(){} + get a() { + return this.val; + } +} + +const Bar = class { + static get a() { + return this.val; + } + b(){} + static set a(value) { + this.val = value; + } +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint grouped-accessor-pairs: "error"*/ + +var foo = { + get a() { + return this.val; + }, + set a(value) { + this.val = value; + }, + b: 1 +}; + +var bar = { + set b(value) { + this.val = value; + }, + get b() { + return this.val; + }, + a: 1 +} + +class Foo { + set a(value) { + this.val = value; + } + get a() { + return this.val; + } + b(){} +} + +const Bar = class { + static get a() { + return this.val; + } + static set a(value) { + this.val = value; + } + b(){} +} +``` + +## Options + +This rule has a string option: + +* `"anyOrder"` (default) does not enforce order. +* `"getBeforeSet"` if a property has both getter and setter, requires the getter to be defined before the setter. +* `"setBeforeGet"` if a property has both getter and setter, requires the setter to be defined before the getter. + +### getBeforeSet + +Examples of **incorrect** code for this rule with the `"getBeforeSet"` option: + +```js +/*eslint grouped-accessor-pairs: ["error", "getBeforeSet"]*/ + +var foo = { + set a(value) { + this.val = value; + }, + get a() { + return this.val; + } +}; + +class Foo { + set a(value) { + this.val = value; + } + get a() { + return this.val; + } +} + +const Bar = class { + static set a(value) { + this.val = value; + } + static get a() { + return this.val; + } +} +``` + +Examples of **correct** code for this rule with the `"getBeforeSet"` option: + +```js +/*eslint grouped-accessor-pairs: ["error", "getBeforeSet"]*/ + +var foo = { + get a() { + return this.val; + }, + set a(value) { + this.val = value; + } +}; + +class Foo { + get a() { + return this.val; + } + set a(value) { + this.val = value; + } +} + +const Bar = class { + static get a() { + return this.val; + } + static set a(value) { + this.val = value; + } +} +``` + +### setBeforeGet + +Examples of **incorrect** code for this rule with the `"setBeforeGet"` option: + +```js +/*eslint grouped-accessor-pairs: ["error", "setBeforeGet"]*/ + +var foo = { + get a() { + return this.val; + }, + set a(value) { + this.val = value; + } +}; + +class Foo { + get a() { + return this.val; + } + set a(value) { + this.val = value; + } +} + +const Bar = class { + static get a() { + return this.val; + } + static set a(value) { + this.val = value; + } +} +``` + +Examples of **correct** code for this rule with the `"setBeforeGet"` option: + +```js +/*eslint grouped-accessor-pairs: ["error", "setBeforeGet"]*/ + +var foo = { + set a(value) { + this.val = value; + }, + get a() { + return this.val; + } +}; + +class Foo { + set a(value) { + this.val = value; + } + get a() { + return this.val; + } +} + +const Bar = class { + static set a(value) { + this.val = value; + } + static get a() { + return this.val; + } +} +``` + +## Known Limitations + +Due to the limits of static analysis, this rule does not account for possible side effects and in certain cases +might require or miss to require grouping or order for getters/setters that have a computed key, like in the following example: + +```js +/*eslint grouped-accessor-pairs: "error"*/ + +var a = 1; + +// false warning (false positive) +var foo = { + get [a++]() { + return this.val; + }, + b: 1, + set [a++](value) { + this.val = value; + } +}; + +// missed warning (false negative) +var bar = { + get [++a]() { + return this.val; + }, + b: 1, + set [a](value) { + this.val = value; + } +}; +``` + +Also, this rule does not report any warnings for properties that have duplicate getters or setters. + +See [no-dupe-keys](no-dupe-keys) if you also want to disallow duplicate keys in object literals. + +See [no-dupe-class-members](no-dupe-class-members) if you also want to disallow duplicate names in class definitions. + +## Further Reading + +* [Object Setters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set) +* [Object Getters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get) +* [Classes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes) + +## Related Rules + +* [accessor-pairs](accessor-pairs) +* [no-dupe-keys](no-dupe-keys) +* [no-dupe-class-members](no-dupe-class-members) + +## Version + +This rule was introduced in ESLint 6.7.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/grouped-accessor-pairs.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/grouped-accessor-pairs.md) diff --git a/docs/8.0.0/rules/guard-for-in.md b/docs/8.0.0/rules/guard-for-in.md new file mode 100644 index 0000000000..6a00278832 --- /dev/null +++ b/docs/8.0.0/rules/guard-for-in.md @@ -0,0 +1,69 @@ +--- +title: guard-for-in - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/guard-for-in.md +rule_type: suggestion +--- + + +# Require Guarding for-in (guard-for-in) + +Looping over objects with a `for in` loop will include properties that are inherited through the prototype chain. This behavior can lead to unexpected items in your for loop. + +```js +for (key in foo) { + doSomething(key); +} +``` + +Note that simply checking `foo.hasOwnProperty(key)` is likely to cause an error in some cases; see [no-prototype-builtins](no-prototype-builtins). + +## Rule Details + +This rule is aimed at preventing unexpected behavior that could arise from using a `for in` loop without filtering the results in the loop. As such, it will warn when `for in` loops do not filter their results with an `if` statement. + +Examples of **incorrect** code for this rule: + +```js +/*eslint guard-for-in: "error"*/ + +for (key in foo) { + doSomething(key); +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint guard-for-in: "error"*/ + +for (key in foo) { + if (Object.prototype.hasOwnProperty.call(foo, key)) { + doSomething(key); + } +} + +for (key in foo) { + if ({}.hasOwnProperty.call(foo, key)) { + doSomething(key); + } +} +``` + +## Related Rules + +* [no-prototype-builtins](no-prototype-builtins) + +## Further Reading + +* [Exploring JavaScript for-in loops](https://javascriptweblog.wordpress.com/2011/01/04/exploring-javascript-for-in-loops/) +* [The pitfalls of using objects as maps in JavaScript](http://2ality.com/2012/01/objects-as-maps.html) + +## Version + +This rule was introduced in ESLint 0.0.6. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/guard-for-in.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/guard-for-in.md) diff --git a/docs/8.0.0/rules/handle-callback-err.md b/docs/8.0.0/rules/handle-callback-err.md new file mode 100644 index 0000000000..8969c86a8c --- /dev/null +++ b/docs/8.0.0/rules/handle-callback-err.md @@ -0,0 +1,100 @@ +--- +title: handle-callback-err - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/handle-callback-err.md +rule_type: suggestion +--- + + +# Enforce Callback Error Handling (handle-callback-err) + +This rule was **deprecated** in ESLint v7.0.0. Please use the corresponding rule in [`eslint-plugin-node`](https://github.com/mysticatea/eslint-plugin-node). + +In Node.js, a common pattern for dealing with asynchronous behavior is called the callback pattern. +This pattern expects an `Error` object or `null` as the first argument of the callback. +Forgetting to handle these errors can lead to some really strange behavior in your application. + +```js +function loadData (err, data) { + doSomething(); // forgot to handle error +} +``` + +## Rule Details + +This rule expects that when you're using the callback pattern in Node.js you'll handle the error. + +## Options + +The rule takes a single string option: the name of the error parameter. The default is `"err"`. + +Examples of **incorrect** code for this rule with the default `"err"` parameter name: + +```js +/*eslint handle-callback-err: "error"*/ + +function loadData (err, data) { + doSomething(); +} + +``` + +Examples of **correct** code for this rule with the default `"err"` parameter name: + +```js +/*eslint handle-callback-err: "error"*/ + +function loadData (err, data) { + if (err) { + console.log(err.stack); + } + doSomething(); +} + +function generateError (err) { + if (err) {} +} +``` + +Examples of **correct** code for this rule with a sample `"error"` parameter name: + +```js +/*eslint handle-callback-err: ["error", "error"]*/ + +function loadData (error, data) { + if (error) { + console.log(error.stack); + } + doSomething(); +} +``` + +### regular expression + +Sometimes (especially in big projects) the name of the error variable is not consistent across the project, +so you need a more flexible configuration to ensure that the rule reports all unhandled errors. + +If the configured name of the error variable begins with a `^` it is considered to be a regexp pattern. + +* If the option is `"^(err|error|anySpecificError)$"`, the rule reports unhandled errors where the parameter name can be `err`, `error` or `anySpecificError`. +* If the option is `"^.+Error$"`, the rule reports unhandled errors where the parameter name ends with `Error` (for example, `connectionError` or `validationError` will match). +* If the option is `"^.*(e|E)rr"`, the rule reports unhandled errors where the parameter name matches any string that contains `err` or `Err` (for example, `err`, `error`, `anyError`, `some_err` will match). + +## When Not To Use It + +There are cases where it may be safe for your application to ignore errors, however only ignore errors if you are +confident that some other form of monitoring will help you catch the problem. + +## Further Reading + +* [The Art Of Node: Callbacks](https://github.com/maxogden/art-of-node#callbacks) +* [Nodejitsu: What are the error conventions?](https://docs.nodejitsu.com/articles/errors/what-are-the-error-conventions/) + +## Version + +This rule was introduced in ESLint 0.4.5. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/handle-callback-err.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/handle-callback-err.md) diff --git a/docs/8.0.0/rules/id-blacklist.md b/docs/8.0.0/rules/id-blacklist.md new file mode 100644 index 0000000000..cac94a99ec --- /dev/null +++ b/docs/8.0.0/rules/id-blacklist.md @@ -0,0 +1,20 @@ +--- +title: id-blacklist - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/id-blacklist.md +rule_type: suggestion +--- + + +# disallow specified identifiers (id-blacklist) + +This rule was **deprecated** in ESLint v7.5.0 and replaced by the [id-denylist](id-denylist) rule. + +## Version + +This rule was introduced in ESLint 2.0.0-beta.2. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/id-blacklist.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/id-blacklist.md) diff --git a/docs/8.0.0/rules/id-denylist.md b/docs/8.0.0/rules/id-denylist.md new file mode 100644 index 0000000000..6e845eaea8 --- /dev/null +++ b/docs/8.0.0/rules/id-denylist.md @@ -0,0 +1,133 @@ +--- +title: id-denylist - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/id-denylist.md +rule_type: suggestion +--- + + +# disallow specified identifiers (id-denylist) + +> "There are only two hard things in Computer Science: cache invalidation and naming things." — Phil Karlton + +Generic names can lead to hard-to-decipher code. This rule allows you to specify a deny list of disallowed identifier names to avoid this practice. + +## Rule Details + +This rule disallows specified identifiers in assignments and `function` definitions. + +This rule will catch disallowed identifiers that are: + +- variable declarations +- function declarations +- object properties assigned to during object creation +- class fields +- class methods + +It will not catch disallowed identifiers that are: + +- function calls (so you can still use functions you do not have control over) +- object properties (so you can still use objects you do not have control over) + +## Options + +The rule takes one or more strings as options: the names of restricted identifiers. + +For example, to restrict the use of common generic identifiers: + +```json +{ + "id-denylist": ["error", "data", "err", "e", "cb", "callback"] +} +``` + +Examples of **incorrect** code for this rule with sample `"data", "callback"` restricted identifiers: + +```js +/*eslint id-denylist: ["error", "data", "callback"] */ + +var data = {...}; + +function callback() { + // ... +} + +element.callback = function() { + // ... +}; + +var itemSet = { + data: [...] +}; + +class Foo { + data = []; +} + +class Foo { + #data = []; +} + +class Foo { + callback( {); +} + +class Foo { + #callback( {); +} +``` + +Examples of **correct** code for this rule with sample `"data", "callback"` restricted identifiers: + +```js +/*eslint id-denylist: ["error", "data", "callback"] */ + +var encodingOptions = {...}; + +function processFileResult() { + // ... +} + +element.successHandler = function() { + // ... +}; + +var itemSet = { + entities: [...] +}; + +callback(); // all function calls are ignored + +foo.callback(); // all function calls are ignored + +foo.data; // all property names that are not assignments are ignored + +class Foo { + items = []; +} + +class Foo { + #items = []; +} + +class Foo { + method( {); +} + +class Foo { + #method( {); +} +``` + +## When Not To Use It + +You can turn this rule off if you do not want to restrict the use of certain identifiers. + +## Version + +This rule was introduced in ESLint 7.4.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/id-denylist.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/id-denylist.md) diff --git a/docs/8.0.0/rules/id-length.md b/docs/8.0.0/rules/id-length.md new file mode 100644 index 0000000000..cb9d0ff4b4 --- /dev/null +++ b/docs/8.0.0/rules/id-length.md @@ -0,0 +1,272 @@ +--- +title: id-length - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/id-length.md +rule_type: suggestion +--- + + +# enforce minimum and maximum identifier lengths (id-length) + +Very short identifier names like `e`, `x`, `_t` or very long ones like `hashGeneratorResultOutputContainerObject` can make code harder to read and potentially less maintainable. To prevent this, one may enforce a minimum and/or maximum identifier length. + +```js +var x = 5; // too short; difficult to understand its purpose without context +``` + +## Rule Details + +This rule enforces a minimum and/or maximum identifier length convention. + +## Options + +Examples of **incorrect** code for this rule with the default options: + +```js +/*eslint id-length: "error"*/ // default is minimum 2-chars ({ "min": 2 }) +/*eslint-env es6*/ + +var x = 5; +obj.e = document.body; +var foo = function (e) { }; +try { + dangerousStuff(); +} catch (e) { + // ignore as many do +} +var myObj = { a: 1 }; +(a) => { a * a }; +class x { } +class Foo { x() {} } +class Foo { #x() {} } +class Foo { x = 1 } +class Foo { #x = 1 } +function foo(...x) { } +function foo([x]) { } +var [x] = arr; +var { prop: [x]} = {}; +function foo({x}) { } +var { x } = {}; +var { prop: a} = {}; +({ prop: obj.x } = {}); +``` + +Examples of **correct** code for this rule with the default options: + +```js +/*eslint id-length: "error"*/ // default is minimum 2-chars ({ "min": 2 }) +/*eslint-env es6*/ + +var num = 5; +function _f() { return 42; } +function _func() { return 42; } +obj.el = document.body; +var foo = function (evt) { /* do stuff */ }; +try { + dangerousStuff(); +} catch (error) { + // ignore as many do +} +var myObj = { apple: 1 }; +(num) => { num * num }; +function foo(num = 0) { } +class MyClass { } +class Foo { method() {} } +class Foo { #method() {} } +class Foo { field = 1 } +class Foo { #field = 1 } +function foo(...args) { } +function foo([longName]) { } +var { prop } = {}; +var { prop: [longName] } = {}; +var [longName] = arr; +function foo({ prop }) { } +function foo({ a: prop }) { } +var { prop } = {}; +var { a: prop } = {}; +({ prop: obj.longName } = {}); +var data = { "x": 1 }; // excused because of quotes +data["y"] = 3; // excused because of calculated property access +``` + +This rule has an object option: + +* `"min"` (default: 2) enforces a minimum identifier length +* `"max"` (default: Infinity) enforces a maximum identifier length +* `"properties": always` (default) enforces identifier length convention for property names +* `"properties": never` ignores identifier length convention for property names +* `"exceptions"` allows an array of specified identifier names +* `"exceptionPatterns"` array of strings representing regular expression patterns, allows identifiers that match any of the patterns. + +### min + +Examples of **incorrect** code for this rule with the `{ "min": 4 }` option: + +```js +/*eslint id-length: ["error", { "min": 4 }]*/ +/*eslint-env es6*/ + +var val = 5; +obj.e = document.body; +function foo (e) { }; +try { + dangerousStuff(); +} catch (e) { + // ignore as many do +} +var myObj = { a: 1 }; +(val) => { val * val }; +class x { } +class Foo { x() {} } +function foo(...x) { } +var { x } = {}; +var { prop: a} = {}; +var [x] = arr; +var { prop: [x]} = {}; +({ prop: obj.x } = {}); +``` + +Examples of **correct** code for this rule with the `{ "min": 4 }` option: + +```js +/*eslint id-length: ["error", { "min": 4 }]*/ +/*eslint-env es6*/ + +var value = 5; +function func() { return 42; } +obj.element = document.body; +var foobar = function (event) { /* do stuff */ }; +try { + dangerousStuff(); +} catch (error) { + // ignore as many do +} +var myObj = { apple: 1 }; +(value) => { value * value }; +function foobar(value = 0) { } +class MyClass { } +class Foobar { method() {} } +function foobar(...args) { } +var { prop } = {}; +var [longName] = foo; +var { a: [prop] } = {}; +var { a: longName } = {}; +({ prop: obj.name } = {}); +var data = { "x": 1 }; // excused because of quotes +data["y"] = 3; // excused because of calculated property access +``` + +### max + +Examples of **incorrect** code for this rule with the `{ "max": 10 }` option: + +```js +/*eslint id-length: ["error", { "max": 10 }]*/ +/*eslint-env es6*/ + +var reallyLongVarName = 5; +function reallyLongFuncName() { return 42; } +obj.reallyLongPropName = document.body; +var foo = function (reallyLongArgName) { /* do stuff */ }; +try { + dangerousStuff(); +} catch (reallyLongErrorName) { + // ignore as many do +} +(reallyLongArgName) => { return !reallyLongArgName; }; +var [reallyLongFirstElementName] = arr; +``` + +Examples of **correct** code for this rule with the `{ "max": 10 }` option: + +```js +/*eslint id-length: ["error", { "max": 10 }]*/ +/*eslint-env es6*/ + +var varName = 5; +function funcName() { return 42; } +obj.propName = document.body; +var foo = function (arg) { /* do stuff */ }; +try { + dangerousStuff(); +} catch (error) { + // ignore as many do +} +(arg) => { return !arg; }; +var [first] = arr; +``` + +### properties + +Examples of **correct** code for this rule with the `{ "properties": "never" }` option: + +```js +/*eslint id-length: ["error", { "properties": "never" }]*/ +/*eslint-env es6*/ + +var myObj = { a: 1 }; +({ a: obj.x.y.z } = {}); +({ prop: obj.i } = {}); +``` + +### exceptions + +Examples of additional **correct** code for this rule with the `{ "exceptions": ["x"] }` option: + +```js +/*eslint id-length: ["error", { "exceptions": ["x"] }]*/ +/*eslint-env es6*/ + +var x = 5; +function x() { return 42; } +obj.x = document.body; +var foo = function (x) { /* do stuff */ }; +try { + dangerousStuff(); +} catch (x) { + // ignore as many do +} +(x) => { return x * x; }; +var [x] = arr; +const { x } = foo; +const { a: x } = foo; +``` + +### exceptionPatterns + +Examples of additional **correct** code for this rule with the `{ "exceptionPatterns": ["E|S", "[x-z]"] }` option: + +```js +/*eslint id-length: ["error", { "exceptionPatterns": ["E|S", "[x-z]"] }]*/ +/*eslint-env es6*/ + +var E = 5; +function S() { return 42; } +obj.x = document.body; +var foo = function (x) { /* do stuff */ }; +try { + dangerousStuff(); +} catch (x) { + // ignore as many do +} +(y) => {return y * y}; +var [E] = arr; +const { y } = foo; +const { a: z } = foo; +``` + +## Related Rules + +* [max-len](max-len) +* [new-cap](new-cap) +* [func-names](func-names) +* [camelcase](camelcase) + +## Version + +This rule was introduced in ESLint 1.0.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/id-length.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/id-length.md) diff --git a/docs/8.0.0/rules/id-match.md b/docs/8.0.0/rules/id-match.md new file mode 100644 index 0000000000..2b4816204a --- /dev/null +++ b/docs/8.0.0/rules/id-match.md @@ -0,0 +1,188 @@ +--- +title: id-match - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/id-match.md +rule_type: suggestion +--- + + +# require identifiers to match a specified regular expression (id-match) + +> "There are only two hard things in Computer Science: cache invalidation and naming things." — Phil Karlton + +Naming things consistently in a project is an often underestimated aspect of code creation. +When done correctly, it can save your team hours of unnecessary head scratching and misdirections. +This rule allows you to precisely define and enforce the variables and function names on your team should use. +No more limiting yourself to camelCase, snake_case, PascalCase or oHungarianNotation. Id-match has all your needs covered! + +## Rule Details + +This rule requires identifiers in assignments and `function` definitions to match a specified regular expression. + +## Options + +This rule has a string option for the specified regular expression. + +For example, to enforce a camelcase naming convention: + +```json +{ + "id-match": ["error", "^[a-z]+([A-Z][a-z]+)*$"] +} +``` + +Examples of **incorrect** code for this rule with the `"^[a-z]+([A-Z][a-z]+)*$"` option: + +```js +/*eslint id-match: ["error", "^[a-z]+([A-Z][a-z]+)*$"]*/ + +var my_favorite_color = "#112C85"; +var _myFavoriteColor = "#112C85"; +var myFavoriteColor_ = "#112C85"; +var MY_FAVORITE_COLOR = "#112C85"; +function do_something() { + // ... +} + +obj.do_something = function() { + // ... +}; + +class My_Class {} + +class myClass { + do_something() {} +} + +class myClass { + #do_something() {} +} +``` + +Examples of **correct** code for this rule with the `"^[a-z]+([A-Z][a-z]+)*$"` option: + +```js +/*eslint id-match: ["error", "^[a-z]+([A-Z][a-z]+)*$"]*/ + +var myFavoriteColor = "#112C85"; +var foo = bar.baz_boom; +var foo = { qux: bar.baz_boom }; +do_something(); +var obj = { + my_pref: 1 +}; + +class myClass {} + +class myClass { + doSomething() {} +} + +class myClass { + #doSomething() {} +} +``` + +This rule has an object option: + +* `"properties": false` (default) does not check object properties +* `"properties": true` requires object literal properties and member expression assignment properties to match the specified regular expression +* `"classFields": false` (default) does not class field names +* `"classFields": true` requires class field names to match the specified regular expression +* `"onlyDeclarations": false` (default) requires all variable names to match the specified regular expression +* `"onlyDeclarations": true` requires only `var`, `function`, and `class` declarations to match the specified regular expression +* `"ignoreDestructuring": false` (default) enforces `id-match` for destructured identifiers +* `"ignoreDestructuring": true` does not check destructured identifiers + +### properties + +Examples of **incorrect** code for this rule with the `"^[a-z]+([A-Z][a-z]+)*$", { "properties": true }` options: + +```js +/*eslint id-match: ["error", "^[a-z]+([A-Z][a-z]+)*$", { "properties": true }]*/ + +var obj = { + my_pref: 1 +}; +``` + +### classFields + +Examples of **incorrect** code for this rule with the `"^[a-z]+([A-Z][a-z]+)*$", { "classFields": true }` options: + +```js +/*eslint id-match: ["error", "^[a-z]+([A-Z][a-z]+)*$", { "properties": true }]*/ + +class myClass { + my_pref = 1; +} + +class myClass { + #my_pref = 1; +} +``` + +### onlyDeclarations + +Examples of **correct** code for this rule with the `"^[a-z]+([A-Z][a-z]+)*$", { "onlyDeclarations": true }` options: + +```js +/*eslint id-match: [2, "^[a-z]+([A-Z][a-z]+)*$", { "onlyDeclarations": true }]*/ + +do_something(__dirname); +``` + +### ignoreDestructuring: false + +Examples of **incorrect** code for this rule with the default `"^[^_]+$", { "ignoreDestructuring": false }` option: + +```js +/*eslint id-match: [2, "^[^_]+$", { "ignoreDestructuring": false }]*/ + +var { category_id } = query; + +var { category_id = 1 } = query; + +var { category_id: category_id } = query; + +var { category_id: category_alias } = query; + +var { category_id: categoryId, ...other_props } = query; +``` + +### ignoreDestructuring: true + +Examples of **incorrect** code for this rule with the `"^[^_]+$", { "ignoreDestructuring": true }` option: + +```js +/*eslint id-match: [2, "^[^_]+$", { "ignoreDestructuring": true }]*/ + +var { category_id: category_alias } = query; + +var { category_id, ...other_props } = query; +``` + +Examples of **correct** code for this rule with the `"^[^_]+$", { "ignoreDestructuring": true }` option: + +```js +/*eslint id-match: [2, "^[^_]+$", { "ignoreDestructuring": true }]*/ + +var { category_id } = query; + +var { category_id = 1 } = query; + +var { category_id: category_id } = query; +``` + +## When Not To Use It + +If you don't want to enforce any particular naming convention for all identifiers, or your naming convention is too complex to be enforced by configuring this rule, then you should not enable this rule. + +## Version + +This rule was introduced in ESLint 1.0.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/id-match.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/id-match.md) diff --git a/docs/8.0.0/rules/implicit-arrow-linebreak.md b/docs/8.0.0/rules/implicit-arrow-linebreak.md new file mode 100644 index 0000000000..49366701c9 --- /dev/null +++ b/docs/8.0.0/rules/implicit-arrow-linebreak.md @@ -0,0 +1,120 @@ +--- +title: implicit-arrow-linebreak - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/implicit-arrow-linebreak.md +rule_type: layout +--- + + +# Enforce the location of arrow function bodies with implicit returns (implicit-arrow-linebreak) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +An arrow function body can contain an implicit return as an expression instead of a block body. It can be useful to enforce a consistent location for the implicitly returned expression. + +## Rule Details + +This rule aims to enforce a consistent location for an arrow function containing an implicit return. + +See Also: + +- [`brace-style`](https://eslint.org/docs/rules/brace-style) which enforces this behavior for arrow functions with block bodies. + +### Options + +This rule accepts a string option: + +- `"beside"` (default) disallows a newline before an arrow function body. +- `"below"` requires a newline before an arrow function body. + +Examples of **incorrect** code for this rule with the default `"beside"` option: + +```js +/* eslint implicit-arrow-linebreak: ["error", "beside"] */ + +(foo) => + bar; + +(foo) => + (bar); + +(foo) => + bar => + baz; + +(foo) => +( + bar() +); +``` + +Examples of **correct** code for this rule with the default `"beside"` option: + +```js +/* eslint implicit-arrow-linebreak: ["error", "beside"] */ + +(foo) => bar; + +(foo) => (bar); + +(foo) => bar => baz; + +(foo) => ( + bar() +); + +// functions with block bodies allowed with this rule using any style +// to enforce a consistent location for this case, see the rule: `brace-style` +(foo) => { + return bar(); +} + +(foo) => +{ + return bar(); +} +``` + +Examples of **incorrect** code for this rule with the `"below"` option: + +```js +/* eslint implicit-arrow-linebreak: ["error", "below"] */ + +(foo) => bar; + +(foo) => (bar); + +(foo) => bar => baz; +``` + +Examples of **correct** code for this rule with the `"below"` option: + +```js +/* eslint implicit-arrow-linebreak: ["error", "below"] */ + + +(foo) => + bar; + +(foo) => + (bar); + +(foo) => + bar => + baz; +``` + +## When Not To Use It + +If you're not concerned about consistent locations of implicitly returned arrow function expressions, you should not turn on this rule. + +You can also disable this rule if you are using the `"always"` option for the [`arrow-body-style`](https://eslint.org/docs/rules/arrow-body-style), since this will disable the use of implicit returns in arrow functions. + +## Version + +This rule was introduced in ESLint 4.12.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/implicit-arrow-linebreak.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/implicit-arrow-linebreak.md) diff --git a/docs/8.0.0/rules/indent-legacy.md b/docs/8.0.0/rules/indent-legacy.md new file mode 100644 index 0000000000..b6b82d3c91 --- /dev/null +++ b/docs/8.0.0/rules/indent-legacy.md @@ -0,0 +1,551 @@ +--- +title: indent-legacy - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/indent-legacy.md +rule_type: layout +--- + + +# enforce consistent indentation (indent-legacy) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +ESLint 4.0.0 introduced a rewrite of the [`indent`](/docs/rules/indent) rule, which now reports more errors than it did in previous versions. To ease the process of migrating to 4.0.0, the `indent-legacy` rule was introduced as a snapshot of the `indent` rule from ESLint 3.x. If your build is failing after the upgrade to 4.0.0, you can disable `indent` and enable `indent-legacy` as a quick fix. Eventually, you should switch back to the `indent` rule to get bugfixes and improvements in future versions. + +--- + +There are several common guidelines which require specific indentation of nested blocks and statements, like: + +```js +function hello(indentSize, type) { + if (indentSize === 4 && type !== 'tab') { + console.log('Each next indentation will increase on 4 spaces'); + } +} +``` + +These are the most common scenarios recommended in different style guides: + +* Two spaces, not longer and no tabs: Google, npm, Node.js, Idiomatic, Felix +* Tabs: jQuery +* Four spaces: Crockford + +## Rule Details + +This rule enforces a consistent indentation style. The default style is `4 spaces`. + +## Options + +This rule has a mixed option: + +For example, for 2-space indentation: + +```json +{ + "indent": ["error", 2] +} +``` + +Or for tabbed indentation: + +```json +{ + "indent": ["error", "tab"] +} +``` + +Examples of **incorrect** code for this rule with the default options: + +```js +/*eslint indent: "error"*/ + +if (a) { + b=c; + function foo(d) { + e=f; + } +} +``` + +Examples of **correct** code for this rule with the default options: + +```js +/*eslint indent: "error"*/ + +if (a) { + b=c; + function foo(d) { + e=f; + } +} +``` + +This rule has an object option: + +* `"SwitchCase"` (default: 0) enforces indentation level for `case` clauses in `switch` statements +* `"VariableDeclarator"` (default: 1) enforces indentation level for `var` declarators; can also take an object to define separate rules for `var`, `let` and `const` declarations. +* `"outerIIFEBody"` (default: 1) enforces indentation level for file-level IIFEs. +* `"MemberExpression"` (off by default) enforces indentation level for multi-line property chains (except in variable declarations and assignments) +* `"FunctionDeclaration"` takes an object to define rules for function declarations. + * `parameters` (off by default) enforces indentation level for parameters in a function declaration. This can either be a number indicating indentation level, or the string `"first"` indicating that all parameters of the declaration must be aligned with the first parameter. + * `body` (default: 1) enforces indentation level for the body of a function declaration. +* `"FunctionExpression"` takes an object to define rules for function expressions. + * `parameters` (off by default) enforces indentation level for parameters in a function expression. This can either be a number indicating indentation level, or the string `"first"` indicating that all parameters of the expression must be aligned with the first parameter. + * `body` (default: 1) enforces indentation level for the body of a function expression. +* `"CallExpression"` takes an object to define rules for function call expressions. + * `arguments` (off by default) enforces indentation level for arguments in a call expression. This can either be a number indicating indentation level, or the string `"first"` indicating that all arguments of the expression must be aligned with the first argument. +* `"ArrayExpression"` (default: 1) enforces indentation level for elements in arrays. It can also be set to the string `"first"`, indicating that all the elements in the array should be aligned with the first element. +* `"ObjectExpression"` (default: 1) enforces indentation level for properties in objects. It can be set to the string `"first"`, indicating that all properties in the object should be aligned with the first property. + +Level of indentation denotes the multiple of the indent specified. Example: + +* Indent of 4 spaces with `VariableDeclarator` set to `2` will indent the multi-line variable declarations with 8 spaces. +* Indent of 2 spaces with `VariableDeclarator` set to `2` will indent the multi-line variable declarations with 4 spaces. +* Indent of 2 spaces with `VariableDeclarator` set to `{"var": 2, "let": 2, "const": 3}` will indent the multi-line variable declarations with 4 spaces for `var` and `let`, 6 spaces for `const` statements. +* Indent of tab with `VariableDeclarator` set to `2` will indent the multi-line variable declarations with 2 tabs. +* Indent of 2 spaces with `SwitchCase` set to `0` will not indent `case` clauses with respect to `switch` statements. +* Indent of 2 spaces with `SwitchCase` set to `1` will indent `case` clauses with 2 spaces with respect to `switch` statements. +* Indent of 2 spaces with `SwitchCase` set to `2` will indent `case` clauses with 4 spaces with respect to `switch` statements. +* Indent of tab with `SwitchCase` set to `2` will indent `case` clauses with 2 tabs with respect to `switch` statements. +* Indent of 2 spaces with `MemberExpression` set to `0` will indent the multi-line property chains with 0 spaces. +* Indent of 2 spaces with `MemberExpression` set to `1` will indent the multi-line property chains with 2 spaces. +* Indent of 2 spaces with `MemberExpression` set to `2` will indent the multi-line property chains with 4 spaces. +* Indent of 4 spaces with `MemberExpression` set to `0` will indent the multi-line property chains with 0 spaces. +* Indent of 4 spaces with `MemberExpression` set to `1` will indent the multi-line property chains with 4 spaces. +* Indent of 4 spaces with `MemberExpression` set to `2` will indent the multi-line property chains with 8 spaces. + +### tab + +Examples of **incorrect** code for this rule with the `"tab"` option: + +```js +/*eslint indent: ["error", "tab"]*/ + +if (a) { + b=c; +function foo(d) { + e=f; + } +} +``` + +Examples of **correct** code for this rule with the `"tab"` option: + +```js +/*eslint indent: ["error", "tab"]*/ + +if (a) { +/*tab*/b=c; +/*tab*/function foo(d) { +/*tab*//*tab*/e=f; +/*tab*/} +} +``` + +### SwitchCase + +Examples of **incorrect** code for this rule with the `2, { "SwitchCase": 1 }` options: + +```js +/*eslint indent: ["error", 2, { "SwitchCase": 1 }]*/ + +switch(a){ +case "a": + break; +case "b": + break; +} +``` + +Examples of **correct** code for this rule with the `2, { "SwitchCase": 1 }` option: + +```js +/*eslint indent: ["error", 2, { "SwitchCase": 1 }]*/ + +switch(a){ + case "a": + break; + case "b": + break; +} +``` + +### VariableDeclarator + +Examples of **incorrect** code for this rule with the `2, { "VariableDeclarator": 1 }` options: + +```js +/*eslint indent: ["error", 2, { "VariableDeclarator": 1 }]*/ +/*eslint-env es6*/ + +var a, + b, + c; +let a, + b, + c; +const a = 1, + b = 2, + c = 3; +``` + +Examples of **correct** code for this rule with the `2, { "VariableDeclarator": 1 }` options: + +```js +/*eslint indent: ["error", 2, { "VariableDeclarator": 1 }]*/ +/*eslint-env es6*/ + +var a, + b, + c; +let a, + b, + c; +const a = 1, + b = 2, + c = 3; +``` + +Examples of **correct** code for this rule with the `2, { "VariableDeclarator": 2 }` options: + +```js +/*eslint indent: ["error", 2, { "VariableDeclarator": 2 }]*/ +/*eslint-env es6*/ + +var a, + b, + c; +let a, + b, + c; +const a = 1, + b = 2, + c = 3; +``` + +Examples of **correct** code for this rule with the `2, { "VariableDeclarator": { "var": 2, "let": 2, "const": 3 } }` options: + +```js +/*eslint indent: ["error", 2, { "VariableDeclarator": { "var": 2, "let": 2, "const": 3 } }]*/ +/*eslint-env es6*/ + +var a, + b, + c; +let a, + b, + c; +const a = 1, + b = 2, + c = 3; +``` + +### outerIIFEBody + +Examples of **incorrect** code for this rule with the options `2, { "outerIIFEBody": 0 }`: + +```js +/*eslint indent: ["error", 2, { "outerIIFEBody": 0 }]*/ + +(function() { + + function foo(x) { + return x + 1; + } + +})(); + + +if(y) { +console.log('foo'); +} +``` + +Examples of **correct** code for this rule with the options `2, {"outerIIFEBody": 0}`: + +```js +/*eslint indent: ["error", 2, { "outerIIFEBody": 0 }]*/ + +(function() { + +function foo(x) { + return x + 1; +} + +})(); + + +if(y) { + console.log('foo'); +} +``` + +### MemberExpression + +Examples of **incorrect** code for this rule with the `2, { "MemberExpression": 1 }` options: + +```js +/*eslint indent: ["error", 2, { "MemberExpression": 1 }]*/ + +foo +.bar +.baz() +``` + +Examples of **correct** code for this rule with the `2, { "MemberExpression": 1 }` option: + +```js +/*eslint indent: ["error", 2, { "MemberExpression": 1 }]*/ + +foo + .bar + .baz(); + +// Any indentation is permitted in variable declarations and assignments. +var bip = aardvark.badger + .coyote; +``` + +### FunctionDeclaration + +Examples of **incorrect** code for this rule with the `2, { "FunctionDeclaration": {"body": 1, "parameters": 2} }` option: + +```js +/*eslint indent: ["error", 2, { "FunctionDeclaration": {"body": 1, "parameters": 2} }]*/ + +function foo(bar, + baz, + qux) { + qux(); +} +``` + +Examples of **correct** code for this rule with the `2, { "FunctionDeclaration": {"body": 1, "parameters": 2} }` option: + +```js +/*eslint indent: ["error", 2, { "FunctionDeclaration": {"body": 1, "parameters": 2} }]*/ + +function foo(bar, + baz, + qux) { + qux(); +} +``` + +Examples of **incorrect** code for this rule with the `2, { "FunctionDeclaration": {"parameters": "first"} }` option: + +```js +/*eslint indent: ["error", 2, {"FunctionDeclaration": {"parameters": "first"}}]*/ + +function foo(bar, baz, + qux, boop) { + qux(); +} +``` + +Examples of **correct** code for this rule with the `2, { "FunctionDeclaration": {"parameters": "first"} }` option: + +```js +/*eslint indent: ["error", 2, {"FunctionDeclaration": {"parameters": "first"}}]*/ + +function foo(bar, baz, + qux, boop) { + qux(); +} +``` + +### FunctionExpression + +Examples of **incorrect** code for this rule with the `2, { "FunctionExpression": {"body": 1, "parameters": 2} }` option: + +```js +/*eslint indent: ["error", 2, { "FunctionExpression": {"body": 1, "parameters": 2} }]*/ + +var foo = function(bar, + baz, + qux) { + qux(); +} +``` + +Examples of **correct** code for this rule with the `2, { "FunctionExpression": {"body": 1, "parameters": 2} }` option: + +```js +/*eslint indent: ["error", 2, { "FunctionExpression": {"body": 1, "parameters": 2} }]*/ + +var foo = function(bar, + baz, + qux) { + qux(); +} +``` + +Examples of **incorrect** code for this rule with the `2, { "FunctionExpression": {"parameters": "first"} }` option: + +```js +/*eslint indent: ["error", 2, {"FunctionExpression": {"parameters": "first"}}]*/ + +var foo = function(bar, baz, + qux, boop) { + qux(); +} +``` + +Examples of **correct** code for this rule with the `2, { "FunctionExpression": {"parameters": "first"} }` option: + +```js +/*eslint indent: ["error", 2, {"FunctionExpression": {"parameters": "first"}}]*/ + +var foo = function(bar, baz, + qux, boop) { + qux(); +} +``` + +### CallExpression + +Examples of **incorrect** code for this rule with the `2, { "CallExpression": {"arguments": 1} }` option: + +```js +/*eslint indent: ["error", 2, { "CallExpression": {"arguments": 1} }]*/ + +foo(bar, + baz, + qux +); +``` + +Examples of **correct** code for this rule with the `2, { "CallExpression": {"arguments": 1} }` option: + +```js +/*eslint indent: ["error", 2, { "CallExpression": {"arguments": 1} }]*/ + +foo(bar, + baz, + qux +); +``` + +Examples of **incorrect** code for this rule with the `2, { "CallExpression": {"arguments": "first"} }` option: + +```js +/*eslint indent: ["error", 2, {"CallExpression": {"arguments": "first"}}]*/ + +foo(bar, baz, + baz, boop, beep); +``` + +Examples of **correct** code for this rule with the `2, { "CallExpression": {"arguments": "first"} }` option: + +```js +/*eslint indent: ["error", 2, {"CallExpression": {"arguments": "first"}}]*/ + +foo(bar, baz, + baz, boop, beep); +``` + +### ArrayExpression + +Examples of **incorrect** code for this rule with the `2, { "ArrayExpression": 1 }` option: + +```js +/*eslint indent: ["error", 2, { "ArrayExpression": 1 }]*/ + +var foo = [ + bar, +baz, + qux +]; +``` + +Examples of **correct** code for this rule with the `2, { "ArrayExpression": 1 }` option: + +```js +/*eslint indent: ["error", 2, { "ArrayExpression": 1 }]*/ + +var foo = [ + bar, + baz, + qux +]; +``` + +Examples of **incorrect** code for this rule with the `2, { "ArrayExpression": "first" }` option: + +```js +/*eslint indent: ["error", 2, {"ArrayExpression": "first"}]*/ + +var foo = [bar, + baz, + qux +]; +``` + +Examples of **correct** code for this rule with the `2, { "ArrayExpression": "first" }` option: + +```js +/*eslint indent: ["error", 2, {"ArrayExpression": "first"}]*/ + +var foo = [bar, + baz, + qux +]; +``` + +### ObjectExpression + +Examples of **incorrect** code for this rule with the `2, { "ObjectExpression": 1 }` option: + +```js +/*eslint indent: ["error", 2, { "ObjectExpression": 1 }]*/ + +var foo = { + bar: 1, +baz: 2, + qux: 3 +}; +``` + +Examples of **correct** code for this rule with the `2, { "ObjectExpression": 1 }` option: + +```js +/*eslint indent: ["error", 2, { "ObjectExpression": 1 }]*/ + +var foo = { + bar: 1, + baz: 2, + qux: 3 +}; +``` + +Examples of **incorrect** code for this rule with the `2, { "ObjectExpression": "first" }` option: + +```js +/*eslint indent: ["error", 2, {"ObjectExpression": "first"}]*/ + +var foo = { bar: 1, + baz: 2 }; +``` + +Examples of **correct** code for this rule with the `2, { "ObjectExpression": "first" }` option: + +```js +/*eslint indent: ["error", 2, {"ObjectExpression": "first"}]*/ + +var foo = { bar: 1, + baz: 2 }; +``` + +## Compatibility + +* **JSHint**: `indent` +* **JSCS**: [validateIndentation](https://jscs-dev.github.io/rule/validateIndentation) + +## Version + +This rule was introduced in ESLint 4.0.0-alpha.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/indent-legacy.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/indent-legacy.md) diff --git a/docs/8.0.0/rules/indent.md b/docs/8.0.0/rules/indent.md new file mode 100644 index 0000000000..d2d2cc8b44 --- /dev/null +++ b/docs/8.0.0/rules/indent.md @@ -0,0 +1,816 @@ +--- +title: indent - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/indent.md +rule_type: layout +--- + + +# enforce consistent indentation (indent) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +There are several common guidelines which require specific indentation of nested blocks and statements, like: + +```js +function hello(indentSize, type) { + if (indentSize === 4 && type !== 'tab') { + console.log('Each next indentation will increase on 4 spaces'); + } +} +``` + +These are the most common scenarios recommended in different style guides: + +* Two spaces, not longer and no tabs: Google, npm, Node.js, Idiomatic, Felix +* Tabs: jQuery +* Four spaces: Crockford + +## Rule Details + +This rule enforces a consistent indentation style. The default style is `4 spaces`. + +## Options + +This rule has a mixed option: + +For example, for 2-space indentation: + +```json +{ + "indent": ["error", 2] +} +``` + +Or for tabbed indentation: + +```json +{ + "indent": ["error", "tab"] +} +``` + +Examples of **incorrect** code for this rule with the default options: + +```js +/*eslint indent: "error"*/ + +if (a) { + b=c; + function foo(d) { + e=f; + } +} +``` + +Examples of **correct** code for this rule with the default options: + +```js +/*eslint indent: "error"*/ + +if (a) { + b=c; + function foo(d) { + e=f; + } +} +``` + +This rule has an object option: + +* `"ignoredNodes"` can be used to disable indentation checking for any AST node. This accepts an array of [selectors](/docs/developer-guide/selectors). If an AST node is matched by any of the selectors, the indentation of tokens which are direct children of that node will be ignored. This can be used as an escape hatch to relax the rule if you disagree with the indentation that it enforces for a particular syntactic pattern. +* `"SwitchCase"` (default: 0) enforces indentation level for `case` clauses in `switch` statements +* `"VariableDeclarator"` (default: 1) enforces indentation level for `var` declarators; can also take an object to define separate rules for `var`, `let` and `const` declarations. It can also be `"first"`, indicating all the declarators should be aligned with the first declarator. +* `"outerIIFEBody"` (default: 1) enforces indentation level for file-level IIFEs. This can also be set to `"off"` to disable checking for file-level IIFEs. +* `"MemberExpression"` (default: 1) enforces indentation level for multi-line property chains. This can also be set to `"off"` to disable checking for MemberExpression indentation. +* `"FunctionDeclaration"` takes an object to define rules for function declarations. + * `parameters` (default: 1) enforces indentation level for parameters in a function declaration. This can either be a number indicating indentation level, or the string `"first"` indicating that all parameters of the declaration must be aligned with the first parameter. This can also be set to `"off"` to disable checking for FunctionDeclaration parameters. + * `body` (default: 1) enforces indentation level for the body of a function declaration. +* `"FunctionExpression"` takes an object to define rules for function expressions. + * `parameters` (default: 1) enforces indentation level for parameters in a function expression. This can either be a number indicating indentation level, or the string `"first"` indicating that all parameters of the expression must be aligned with the first parameter. This can also be set to `"off"` to disable checking for FunctionExpression parameters. + * `body` (default: 1) enforces indentation level for the body of a function expression. +* `"CallExpression"` takes an object to define rules for function call expressions. + * `arguments` (default: 1) enforces indentation level for arguments in a call expression. This can either be a number indicating indentation level, or the string `"first"` indicating that all arguments of the expression must be aligned with the first argument. This can also be set to `"off"` to disable checking for CallExpression arguments. +* `"ArrayExpression"` (default: 1) enforces indentation level for elements in arrays. It can also be set to the string `"first"`, indicating that all the elements in the array should be aligned with the first element. This can also be set to `"off"` to disable checking for array elements. +* `"ObjectExpression"` (default: 1) enforces indentation level for properties in objects. It can be set to the string `"first"`, indicating that all properties in the object should be aligned with the first property. This can also be set to `"off"` to disable checking for object properties. +* `"ImportDeclaration"` (default: 1) enforces indentation level for import statements. It can be set to the string `"first"`, indicating that all imported members from a module should be aligned with the first member in the list. This can also be set to `"off"` to disable checking for imported module members. +* `"flatTernaryExpressions": true` (`false` by default) requires no indentation for ternary expressions which are nested in other ternary expressions. +* `"offsetTernaryExpressions": true` (`false` by default) requires indentation for values of ternary expressions. +* `"ignoreComments"` (default: false) can be used when comments do not need to be aligned with nodes on the previous or next line. + +Level of indentation denotes the multiple of the indent specified. Example: + +* Indent of 4 spaces with `VariableDeclarator` set to `2` will indent the multi-line variable declarations with 8 spaces. +* Indent of 2 spaces with `VariableDeclarator` set to `2` will indent the multi-line variable declarations with 4 spaces. +* Indent of 2 spaces with `VariableDeclarator` set to `{"var": 2, "let": 2, "const": 3}` will indent the multi-line variable declarations with 4 spaces for `var` and `let`, 6 spaces for `const` statements. +* Indent of tab with `VariableDeclarator` set to `2` will indent the multi-line variable declarations with 2 tabs. +* Indent of 2 spaces with `SwitchCase` set to `0` will not indent `case` clauses with respect to `switch` statements. +* Indent of 2 spaces with `SwitchCase` set to `1` will indent `case` clauses with 2 spaces with respect to `switch` statements. +* Indent of 2 spaces with `SwitchCase` set to `2` will indent `case` clauses with 4 spaces with respect to `switch` statements. +* Indent of tab with `SwitchCase` set to `2` will indent `case` clauses with 2 tabs with respect to `switch` statements. +* Indent of 2 spaces with `MemberExpression` set to `0` will indent the multi-line property chains with 0 spaces. +* Indent of 2 spaces with `MemberExpression` set to `1` will indent the multi-line property chains with 2 spaces. +* Indent of 2 spaces with `MemberExpression` set to `2` will indent the multi-line property chains with 4 spaces. +* Indent of 4 spaces with `MemberExpression` set to `0` will indent the multi-line property chains with 0 spaces. +* Indent of 4 spaces with `MemberExpression` set to `1` will indent the multi-line property chains with 4 spaces. +* Indent of 4 spaces with `MemberExpression` set to `2` will indent the multi-line property chains with 8 spaces. + +### tab + +Examples of **incorrect** code for this rule with the `"tab"` option: + +```js +/*eslint indent: ["error", "tab"]*/ + +if (a) { + b=c; +function foo(d) { + e=f; + } +} +``` + +Examples of **correct** code for this rule with the `"tab"` option: + +```js +/*eslint indent: ["error", "tab"]*/ + +if (a) { +/*tab*/b=c; +/*tab*/function foo(d) { +/*tab*//*tab*/e=f; +/*tab*/} +} +``` + +### ignoredNodes + +The following configuration ignores the indentation of `ConditionalExpression` ("ternary expression") nodes: + +Examples of **correct** code for this rule with the `4, { "ignoredNodes": ["ConditionalExpression"] }` option: + +```js +/*eslint indent: ["error", 4, { "ignoredNodes": ["ConditionalExpression"] }]*/ + +var a = foo + ? bar + : baz; + +var a = foo + ? bar +: baz; +``` + +The following configuration ignores indentation in the body of IIFEs. + +Examples of **correct** code for this rule with the `4, { "ignoredNodes": ["CallExpression > FunctionExpression.callee > BlockStatement.body"] }` option: + +```js +/*eslint indent: ["error", 4, { "ignoredNodes": ["CallExpression > FunctionExpression.callee > BlockStatement.body"] }]*/ + +(function() { + +foo(); +bar(); + +}) +``` + +All AST node types can be found at [ESTree](https://github.com/estree/estree) specification. You can use [AST Explorer](https://astexplorer.net/) with the espree parser to examine AST tree of a code snippet. + +### SwitchCase + +Examples of **incorrect** code for this rule with the `2, { "SwitchCase": 1 }` options: + +```js +/*eslint indent: ["error", 2, { "SwitchCase": 1 }]*/ + +switch(a){ +case "a": + break; +case "b": + break; +} +``` + +Examples of **correct** code for this rule with the `2, { "SwitchCase": 1 }` option: + +```js +/*eslint indent: ["error", 2, { "SwitchCase": 1 }]*/ + +switch(a){ + case "a": + break; + case "b": + break; +} +``` + +### VariableDeclarator + +Examples of **incorrect** code for this rule with the `2, { "VariableDeclarator": 1 }` options: + +```js +/*eslint indent: ["error", 2, { "VariableDeclarator": 1 }]*/ +/*eslint-env es6*/ + +var a, + b, + c; +let a, + b, + c; +const a = 1, + b = 2, + c = 3; +``` + +Examples of **correct** code for this rule with the `2, { "VariableDeclarator": 1 }` options: + +```js +/*eslint indent: ["error", 2, { "VariableDeclarator": 1 }]*/ +/*eslint-env es6*/ + +var a, + b, + c; +let a, + b, + c; +const a = 1, + b = 2, + c = 3; +``` + +Examples of **correct** code for this rule with the `2, { "VariableDeclarator": 2 }` options: + +```js +/*eslint indent: ["error", 2, { "VariableDeclarator": 2 }]*/ +/*eslint-env es6*/ + +var a, + b, + c; +let a, + b, + c; +const a = 1, + b = 2, + c = 3; +``` + +Examples of **incorrect** code for this rule with the `2, { "VariableDeclarator": "first" }` options: + +```js +/*eslint indent: ["error", 2, { "VariableDeclarator": "first" }]*/ +/*eslint-env es6*/ + +var a, + b, + c; +let a, + b, + c; +const a = 1, + b = 2, + c = 3; +``` + +Examples of **correct** code for this rule with the `2, { "VariableDeclarator": "first" }` options: + +```js +/*eslint indent: ["error", 2, { "VariableDeclarator": "first" }]*/ +/*eslint-env es6*/ + +var a, + b, + c; +let a, + b, + c; +const a = 1, + b = 2, + c = 3; +``` + +Examples of **correct** code for this rule with the `2, { "VariableDeclarator": { "var": 2, "let": 2, "const": 3 } }` options: + +```js +/*eslint indent: ["error", 2, { "VariableDeclarator": { "var": 2, "let": 2, "const": 3 } }]*/ +/*eslint-env es6*/ + +var a, + b, + c; +let a, + b, + c; +const a = 1, + b = 2, + c = 3; +``` + +### outerIIFEBody + +Examples of **incorrect** code for this rule with the options `2, { "outerIIFEBody": 0 }`: + +```js +/*eslint indent: ["error", 2, { "outerIIFEBody": 0 }]*/ + +(function() { + + function foo(x) { + return x + 1; + } + +})(); + + +if (y) { +console.log('foo'); +} +``` + +Examples of **correct** code for this rule with the options `2, { "outerIIFEBody": 0 }`: + +```js +/*eslint indent: ["error", 2, { "outerIIFEBody": 0 }]*/ + +(function() { + +function foo(x) { + return x + 1; +} + +})(); + + +if (y) { + console.log('foo'); +} +``` + +Examples of **correct** code for this rule with the options `2, { "outerIIFEBody": "off" }`: + +```js +/*eslint indent: ["error", 2, { "outerIIFEBody": "off" }]*/ + +(function() { + +function foo(x) { + return x + 1; +} + +})(); + +(function() { + + function foo(x) { + return x + 1; + } + +})(); + +if (y) { + console.log('foo'); +} +``` + +### MemberExpression + +Examples of **incorrect** code for this rule with the `2, { "MemberExpression": 1 }` options: + +```js +/*eslint indent: ["error", 2, { "MemberExpression": 1 }]*/ + +foo +.bar +.baz() +``` + +Examples of **correct** code for this rule with the `2, { "MemberExpression": 1 }` option: + +```js +/*eslint indent: ["error", 2, { "MemberExpression": 1 }]*/ + +foo + .bar + .baz(); +``` + +### FunctionDeclaration + +Examples of **incorrect** code for this rule with the `2, { "FunctionDeclaration": {"body": 1, "parameters": 2} }` option: + +```js +/*eslint indent: ["error", 2, { "FunctionDeclaration": {"body": 1, "parameters": 2} }]*/ + +function foo(bar, + baz, + qux) { + qux(); +} +``` + +Examples of **correct** code for this rule with the `2, { "FunctionDeclaration": {"body": 1, "parameters": 2} }` option: + +```js +/*eslint indent: ["error", 2, { "FunctionDeclaration": {"body": 1, "parameters": 2} }]*/ + +function foo(bar, + baz, + qux) { + qux(); +} +``` + +Examples of **incorrect** code for this rule with the `2, { "FunctionDeclaration": {"parameters": "first"} }` option: + +```js +/*eslint indent: ["error", 2, {"FunctionDeclaration": {"parameters": "first"}}]*/ + +function foo(bar, baz, + qux, boop) { + qux(); +} +``` + +Examples of **correct** code for this rule with the `2, { "FunctionDeclaration": {"parameters": "first"} }` option: + +```js +/*eslint indent: ["error", 2, {"FunctionDeclaration": {"parameters": "first"}}]*/ + +function foo(bar, baz, + qux, boop) { + qux(); +} +``` + +### FunctionExpression + +Examples of **incorrect** code for this rule with the `2, { "FunctionExpression": {"body": 1, "parameters": 2} }` option: + +```js +/*eslint indent: ["error", 2, { "FunctionExpression": {"body": 1, "parameters": 2} }]*/ + +var foo = function(bar, + baz, + qux) { + qux(); +} +``` + +Examples of **correct** code for this rule with the `2, { "FunctionExpression": {"body": 1, "parameters": 2} }` option: + +```js +/*eslint indent: ["error", 2, { "FunctionExpression": {"body": 1, "parameters": 2} }]*/ + +var foo = function(bar, + baz, + qux) { + qux(); +} +``` + +Examples of **incorrect** code for this rule with the `2, { "FunctionExpression": {"parameters": "first"} }` option: + +```js +/*eslint indent: ["error", 2, {"FunctionExpression": {"parameters": "first"}}]*/ + +var foo = function(bar, baz, + qux, boop) { + qux(); +} +``` + +Examples of **correct** code for this rule with the `2, { "FunctionExpression": {"parameters": "first"} }` option: + +```js +/*eslint indent: ["error", 2, {"FunctionExpression": {"parameters": "first"}}]*/ + +var foo = function(bar, baz, + qux, boop) { + qux(); +} +``` + +### CallExpression + +Examples of **incorrect** code for this rule with the `2, { "CallExpression": {"arguments": 1} }` option: + +```js +/*eslint indent: ["error", 2, { "CallExpression": {"arguments": 1} }]*/ + +foo(bar, + baz, + qux +); +``` + +Examples of **correct** code for this rule with the `2, { "CallExpression": {"arguments": 1} }` option: + +```js +/*eslint indent: ["error", 2, { "CallExpression": {"arguments": 1} }]*/ + +foo(bar, + baz, + qux +); +``` + +Examples of **incorrect** code for this rule with the `2, { "CallExpression": {"arguments": "first"} }` option: + +```js +/*eslint indent: ["error", 2, {"CallExpression": {"arguments": "first"}}]*/ + +foo(bar, baz, + baz, boop, beep); +``` + +Examples of **correct** code for this rule with the `2, { "CallExpression": {"arguments": "first"} }` option: + +```js +/*eslint indent: ["error", 2, {"CallExpression": {"arguments": "first"}}]*/ + +foo(bar, baz, + baz, boop, beep); +``` + +### ArrayExpression + +Examples of **incorrect** code for this rule with the `2, { "ArrayExpression": 1 }` option: + +```js +/*eslint indent: ["error", 2, { "ArrayExpression": 1 }]*/ + +var foo = [ + bar, +baz, + qux +]; +``` + +Examples of **correct** code for this rule with the `2, { "ArrayExpression": 1 }` option: + +```js +/*eslint indent: ["error", 2, { "ArrayExpression": 1 }]*/ + +var foo = [ + bar, + baz, + qux +]; +``` + +Examples of **incorrect** code for this rule with the `2, { "ArrayExpression": "first" }` option: + +```js +/*eslint indent: ["error", 2, {"ArrayExpression": "first"}]*/ + +var foo = [bar, + baz, + qux +]; +``` + +Examples of **correct** code for this rule with the `2, { "ArrayExpression": "first" }` option: + +```js +/*eslint indent: ["error", 2, {"ArrayExpression": "first"}]*/ + +var foo = [bar, + baz, + qux +]; +``` + +### ObjectExpression + +Examples of **incorrect** code for this rule with the `2, { "ObjectExpression": 1 }` option: + +```js +/*eslint indent: ["error", 2, { "ObjectExpression": 1 }]*/ + +var foo = { + bar: 1, +baz: 2, + qux: 3 +}; +``` + +Examples of **correct** code for this rule with the `2, { "ObjectExpression": 1 }` option: + +```js +/*eslint indent: ["error", 2, { "ObjectExpression": 1 }]*/ + +var foo = { + bar: 1, + baz: 2, + qux: 3 +}; +``` + +Examples of **incorrect** code for this rule with the `2, { "ObjectExpression": "first" }` option: + +```js +/*eslint indent: ["error", 2, {"ObjectExpression": "first"}]*/ + +var foo = { bar: 1, + baz: 2 }; +``` + +Examples of **correct** code for this rule with the `2, { "ObjectExpression": "first" }` option: + +```js +/*eslint indent: ["error", 2, {"ObjectExpression": "first"}]*/ + +var foo = { bar: 1, + baz: 2 }; +``` + +### ImportDeclaration + +Examples of **correct** code for this rule with the `4, { "ImportDeclaration": 1 }` option (the default): + +```js +/*eslint indent: ["error", 4, { "ImportDeclaration": 1 }]*/ + +import { foo, + bar, + baz, +} from 'qux'; + +import { + foo, + bar, + baz, +} from 'qux'; +``` + +Examples of **incorrect** code for this rule with the `4, { "ImportDeclaration": "first" }` option: + +```js +/*eslint indent: ["error", 4, { "ImportDeclaration": "first" }]*/ + +import { foo, + bar, + baz, +} from 'qux'; +``` + +Examples of **correct** code for this rule with the `4, { "ImportDeclaration": "first" }` option: + +```js +/*eslint indent: ["error", 4, { "ImportDeclaration": "first" }]*/ + +import { foo, + bar, + baz, +} from 'qux'; +``` + +### flatTernaryExpressions + +Examples of **incorrect** code for this rule with the default `4, { "flatTernaryExpressions": false }` option: + +```js +/*eslint indent: ["error", 4, { "flatTernaryExpressions": false }]*/ + +var a = + foo ? bar : + baz ? qux : + boop; +``` + +Examples of **correct** code for this rule with the default `4, { "flatTernaryExpressions": false }` option: + +```js +/*eslint indent: ["error", 4, { "flatTernaryExpressions": false }]*/ + +var a = + foo ? bar : + baz ? qux : + boop; +``` + +Examples of **incorrect** code for this rule with the `4, { "flatTernaryExpressions": true }` option: + +```js +/*eslint indent: ["error", 4, { "flatTernaryExpressions": true }]*/ + +var a = + foo ? bar : + baz ? qux : + boop; +``` + +Examples of **correct** code for this rule with the `4, { "flatTernaryExpressions": true }` option: + +```js +/*eslint indent: ["error", 4, { "flatTernaryExpressions": true }]*/ + +var a = + foo ? bar : + baz ? qux : + boop; +``` + +### offsetTernaryExpressions + +Examples of **incorrect** code for this rule with the default `2, { "offsetTernaryExpressions": false }` option: + +```js +/*eslint indent: ["error", 2, { "offsetTernaryExpressions": false }]*/ + +condition + ? () => { + return true + } + : () => { + false + } +``` + +Examples of **correct** code for this rule with the default `2, { "offsetTernaryExpressions": false }` option: + +```js +/*eslint indent: ["error", 2, { "offsetTernaryExpressions": false }]*/ + +condition + ? () => { + return true + } + : condition2 + ? () => { + return true + } + : () => { + return false + } +``` + +Examples of **incorrect** code for this rule with the `2, { "offsetTernaryExpressions": true }` option: + +```js +/*eslint indent: ["error", 2, { "offsetTernaryExpressions": true }]*/ + +condition + ? () => { + return true + } + : condition2 + ? () => { + return true + } + : () => { + return false + } +``` + +Examples of **correct** code for this rule with the `2, { "offsetTernaryExpressions": true }` option: + +```js +/*eslint indent: ["error", 2, { "offsetTernaryExpressions": true }]*/ + +condition + ? () => { + return true + } + : condition2 + ? () => { + return true + } + : () => { + return false + } +``` + +### ignoreComments + +Examples of additional **correct** code for this rule with the `4, { "ignoreComments": true }` option: + +```js +/*eslint indent: ["error", 4, { "ignoreComments": true }] */ + +if (foo) { + doSomething(); + +// comment intentionally de-indented + doSomethingElse(); +} +``` + + +## Compatibility + +* **JSHint**: `indent` +* **JSCS**: [validateIndentation](https://jscs-dev.github.io/rule/validateIndentation) + +## Version + +This rule was introduced in ESLint 0.14.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/indent.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/indent.md) diff --git a/docs/8.0.0/rules/init-declarations.md b/docs/8.0.0/rules/init-declarations.md new file mode 100644 index 0000000000..49070991d9 --- /dev/null +++ b/docs/8.0.0/rules/init-declarations.md @@ -0,0 +1,148 @@ +--- +title: init-declarations - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/init-declarations.md +rule_type: suggestion +--- + + +# require or disallow initialization in variable declarations (init-declarations) + +In JavaScript, variables can be assigned during declaration, or at any point afterwards using an assignment statement. For example, in the following code, `foo` is initialized during declaration, while `bar` is initialized later. + +```js +var foo = 1; +var bar; + +if (foo) { + bar = 1; +} else { + bar = 2; +} +``` + +## Rule Details + +This rule is aimed at enforcing or eliminating variable initializations during declaration. For example, in the following code, `foo` is initialized during declaration, while `bar` is not. + +```js +var foo = 1; +var bar; + +bar = 2; +``` + +This rule aims to bring consistency to variable initializations and declarations. + +## Options + +The rule takes two options: + +1. A string which must be either `"always"` (the default), to enforce initialization at declaration, or `"never"` to disallow initialization during declaration. This rule applies to `var`, `let`, and `const` variables, however `"never"` is ignored for `const` variables, as unassigned `const`s generate a parse error. +2. An object that further controls the behavior of this rule. Currently, the only available parameter is `ignoreForLoopInit`, which indicates if initialization at declaration is allowed in `for` loops when `"never"` is set, since it is a very typical use case. + +You can configure the rule as follows: + +Variables must be initialized at declaration (default) + +```json +{ + "init-declarations": ["error", "always"], +} +``` + +Variables must not be initialized at declaration + +```json +{ + "init-declarations": ["error", "never"] +} +``` + +Variables must not be initialized at declaration, except in for loops, where it is allowed + +```json +{ + "init-declarations": ["error", "never", { "ignoreForLoopInit": true }] +} +``` + +### always + +Examples of **incorrect** code for the default `"always"` option: + +```js +/*eslint init-declarations: ["error", "always"]*/ +/*eslint-env es6*/ + +function foo() { + var bar; + let baz; +} +``` + +Examples of **correct** code for the default `"always"` option: + +```js +/*eslint init-declarations: ["error", "always"]*/ +/*eslint-env es6*/ + +function foo() { + var bar = 1; + let baz = 2; + const qux = 3; +} +``` + +### never + +Examples of **incorrect** code for the `"never"` option: + +```js +/*eslint init-declarations: ["error", "never"]*/ +/*eslint-env es6*/ + +function foo() { + var bar = 1; + let baz = 2; + + for (var i = 0; i < 1; i++) {} +} +``` + +Examples of **correct** code for the `"never"` option: + +```js +/*eslint init-declarations: ["error", "never"]*/ +/*eslint-env es6*/ + +function foo() { + var bar; + let baz; + const buzz = 1; +} +``` + +The `"never"` option ignores `const` variable initializations. + +### ignoreForLoopInit + +Examples of **correct** code for the `"never", { "ignoreForLoopInit": true }` options: + +```js +/*eslint init-declarations: ["error", "never", { "ignoreForLoopInit": true }]*/ +for (var i = 0; i < 1; i++) {} +``` + +## When Not To Use It + +When you are indifferent as to how your variables are initialized. + +## Version + +This rule was introduced in ESLint 1.0.0-rc-1. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/init-declarations.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/init-declarations.md) diff --git a/docs/8.0.0/rules/jsx-quotes.md b/docs/8.0.0/rules/jsx-quotes.md new file mode 100644 index 0000000000..434efb0cd0 --- /dev/null +++ b/docs/8.0.0/rules/jsx-quotes.md @@ -0,0 +1,92 @@ +--- +title: jsx-quotes - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/jsx-quotes.md +rule_type: layout +--- + + +# enforce the consistent use of either double or single quotes in JSX attributes (jsx-quotes) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +JSX attribute values can contain string literals, which are delimited with single or double quotes. + +```xml + + +``` + +Unlike string literals in JavaScript, string literals within JSX attributes can’t contain escaped quotes. +If you want to have e.g. a double quote within a JSX attribute value, you have to use single quotes as string delimiter. + +```xml + + +``` + +## Rule Details + +This rule enforces the consistent use of either double or single quotes in JSX attributes. + +## Options + +This rule has a string option: + +* `"prefer-double"` (default) enforces the use of double quotes for all JSX attribute values that don't contain a double quote. +* `"prefer-single"` enforces the use of single quotes for all JSX attribute values that don’t contain a single quote. + +### prefer-double + +Examples of **incorrect** code for this rule with the default `"prefer-double"` option: + +```xml +/*eslint jsx-quotes: ["error", "prefer-double"]*/ + + +``` + +Examples of **correct** code for this rule with the default `"prefer-double"` option: + +```xml +/*eslint jsx-quotes: ["error", "prefer-double"]*/ + + + +``` + +### prefer-single + +Examples of **incorrect** code for this rule with the `"prefer-single"` option: + +```xml +/*eslint jsx-quotes: ["error", "prefer-single"]*/ + + +``` + +Examples of **correct** code for this rule with the `"prefer-single"` option: + +```xml +/*eslint jsx-quotes: ["error", "prefer-single"]*/ + + + +``` + +## When Not To Use It + +You can turn this rule off if you don’t use JSX or if you aren’t concerned with a consistent usage of quotes within JSX attributes. + +## Related Rules + +* [quotes](quotes) + +## Version + +This rule was introduced in ESLint 1.4.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/jsx-quotes.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/jsx-quotes.md) diff --git a/docs/8.0.0/rules/key-spacing.md b/docs/8.0.0/rules/key-spacing.md new file mode 100644 index 0000000000..21fdebf032 --- /dev/null +++ b/docs/8.0.0/rules/key-spacing.md @@ -0,0 +1,349 @@ +--- +title: key-spacing - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/key-spacing.md +rule_type: layout +--- + + +# enforce consistent spacing between keys and values in object literal properties (key-spacing) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +This rule enforces spacing around the colon in object literal properties. It can verify each property individually, or it can ensure horizontal alignment of adjacent properties in an object literal. + +## Rule Details + +This rule enforces consistent spacing between keys and values in object literal properties. In the case of long lines, it is acceptable to add a new line wherever whitespace is allowed. + +## Options + +This rule has an object option: + +* `"beforeColon": false (default) | true` + * `false`: disallows spaces between the key and the colon in object literals. + * `true`: requires at least one space between the key and the colon in object literals. +* `"afterColon": true (default) | false` + * `true`: requires at least one space between the colon and the value in object literals. + * `false`: disallows spaces between the colon and the value in object literals. +* `"mode": "strict" (default) | "minimum"` + * `"strict"`: enforces exactly one space before or after colons in object literals. + * `"minimum"`: enforces one or more spaces before or after colons in object literals. +* `"align": "value" | "colon"` + * `"value"`: enforces horizontal alignment of values in object literals. + * `"colon"` enforces horizontal alignment of both colons and values in object literals. +* `"align"` with an object value allows for fine-grained spacing when values are being aligned in object literals. +* `"singleLine"` specifies a spacing style for single-line object literals. +* `"multiLine"` specifies a spacing style for multi-line object literals. + +Please note that you can either use the top-level options or the grouped options (`singleLine` and `multiLine`) but not both. + +### beforeColon + +Examples of **incorrect** code for this rule with the default `{ "beforeColon": false }` option: + +```js +/*eslint key-spacing: ["error", { "beforeColon": false }]*/ + +var obj = { "foo" : 42 }; +``` + +Examples of **correct** code for this rule with the default `{ "beforeColon": false }` option: + +```js +/*eslint key-spacing: ["error", { "beforeColon": false }]*/ + +var obj = { "foo": 42 }; +``` + +Examples of **incorrect** code for this rule with the `{ "beforeColon": true }` option: + +```js +/*eslint key-spacing: ["error", { "beforeColon": true }]*/ + +var obj = { "foo": 42 }; +``` + +Examples of **correct** code for this rule with the `{ "beforeColon": true }` option: + +```js +/*eslint key-spacing: ["error", { "beforeColon": true }]*/ + +var obj = { "foo" : 42 }; +``` + +### afterColon + +Examples of **incorrect** code for this rule with the default `{ "afterColon": true }` option: + +```js +/*eslint key-spacing: ["error", { "afterColon": true }]*/ + +var obj = { "foo":42 }; +``` + +Examples of **correct** code for this rule with the default `{ "afterColon": true }` option: + +```js +/*eslint key-spacing: ["error", { "afterColon": true }]*/ + +var obj = { "foo": 42 }; +``` + +Examples of **incorrect** code for this rule with the `{ "afterColon": false }` option: + +```js +/*eslint key-spacing: ["error", { "afterColon": false }]*/ + +var obj = { "foo": 42 }; +``` + +Examples of **correct** code for this rule with the `{ "afterColon": false }` option: + +```js +/*eslint key-spacing: ["error", { "afterColon": false }]*/ + +var obj = { "foo":42 }; +``` + +### mode + +Examples of **incorrect** code for this rule with the default `{ "mode": "strict" }` option: + +```js +/*eslint key-spacing: ["error", { "mode": "strict" }]*/ + +call({ + foobar: 42, + bat: 2 * 2 +}); +``` + +Examples of **correct** code for this rule with the default `{ "mode": "strict" }` option: + +```js +/*eslint key-spacing: ["error", { "mode": "strict" }]*/ + +call({ + foobar: 42, + bat: 2 * 2 +}); +``` + +Examples of **correct** code for this rule with the `{ "mode": "minimum" }` option: + +```js +/*eslint key-spacing: ["error", { "mode": "minimum" }]*/ + +call({ + foobar: 42, + bat: 2 * 2 +}); +``` + +### align + +Examples of **incorrect** code for this rule with the `{ "align": "value" }` option: + +```js +/*eslint key-spacing: ["error", { "align": "value" }]*/ + +var obj = { + a: value, + bcde: 42, + fg : foo() +}; +``` + +Examples of **correct** code for this rule with the `{ "align": "value" }` option: + +```js +/*eslint key-spacing: ["error", { "align": "value" }]*/ + +var obj = { + a: value, + bcde: 42, + + fg: foo(), + h: function() { + return this.a; + }, + ijkl: 'Non-consecutive lines form a new group' +}; + +var obj = { a: "foo", longPropertyName: "bar" }; +``` + +Examples of **incorrect** code for this rule with the `{ "align": "colon" }` option: + +```js +/*eslint key-spacing: ["error", { "align": "colon" }]*/ + +call({ + foobar: 42, + bat: 2 * 2 +}); +``` + +Examples of **correct** code for this rule with the `{ "align": "colon" }` option: + +```js +/*eslint key-spacing: ["error", { "align": "colon" }]*/ + +call({ + foobar: 42, + bat : 2 * 2 +}); +``` + +### align + +The `align` option can take additional configuration through the `beforeColon`, `afterColon`, `mode`, and `on` options. + +If `align` is defined as an object, but not all of the parameters are provided, undefined parameters will default to the following: + +```js +// Defaults +align: { + "beforeColon": false, + "afterColon": true, + "on": "colon", + "mode": "strict" +} +``` + +Examples of **correct** code for this rule with sample `{ "align": { } }` options: + +```js +/*eslint key-spacing: ["error", { + "align": { + "beforeColon": true, + "afterColon": true, + "on": "colon" + } +}]*/ + +var obj = { + "one" : 1, + "seven" : 7 +} +``` + +```js +/*eslint key-spacing: ["error", { + "align": { + "beforeColon": false, + "afterColon": false, + "on": "value" + } +}]*/ + +var obj = { + "one": 1, + "seven":7 +} +``` + +### align and multiLine + +The `multiLine` and `align` options can differ, which allows for fine-tuned control over the `key-spacing` of your files. `align` will **not** inherit from `multiLine` if `align` is configured as an object. + +`multiLine` is used any time an object literal spans multiple lines. The `align` configuration is used when there is a group of properties in the same object. For example: + +```javascript +var myObj = { + key1: 1, // uses multiLine + + key2: 2, // uses align (when defined) + key3: 3, // uses align (when defined) + + key4: 4 // uses multiLine +} + +``` + +Examples of **incorrect** code for this rule with sample `{ "align": { }, "multiLine": { } }` options: + +```js +/*eslint key-spacing: ["error", { + "multiLine": { + "beforeColon": false, + "afterColon":true + }, + "align": { + "beforeColon": true, + "afterColon": true, + "on": "colon" + } +}]*/ + +var obj = { + "myObjectFunction": function() { + // Do something + }, + "one" : 1, + "seven" : 7 +} +``` + +Examples of **correct** code for this rule with sample `{ "align": { }, "multiLine": { } }` options: + +```js +/*eslint key-spacing: ["error", { + "multiLine": { + "beforeColon": false, + "afterColon": true + + }, + "align": { + "beforeColon": true, + "afterColon": true, + "on": "colon" + } +}]*/ + +var obj = { + "myObjectFunction": function() { + // Do something + // + }, // These are two separate groups, so no alignment between `myObjectFuction` and `one` + "one" : 1, + "seven" : 7 // `one` and `seven` are in their own group, and therefore aligned +} +``` + +### singleLine and multiLine + +Examples of **correct** code for this rule with sample `{ "singleLine": { }, "multiLine": { } }` options: + +```js +/*eslint "key-spacing": [2, { + "singleLine": { + "beforeColon": false, + "afterColon": true + }, + "multiLine": { + "beforeColon": true, + "afterColon": true, + "align": "colon" + } +}]*/ +var obj = { one: 1, "two": 2, three: 3 }; +var obj2 = { + "two" : 2, + three : 3 +}; +``` + +## When Not To Use It + +If you have another convention for property spacing that might not be consistent with the available options, or if you want to permit multiple styles concurrently you can safely disable this rule. + +## Version + +This rule was introduced in ESLint 0.9.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/key-spacing.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/key-spacing.md) diff --git a/docs/8.0.0/rules/keyword-spacing.md b/docs/8.0.0/rules/keyword-spacing.md new file mode 100644 index 0000000000..27f862ba1d --- /dev/null +++ b/docs/8.0.0/rules/keyword-spacing.md @@ -0,0 +1,291 @@ +--- +title: keyword-spacing - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/keyword-spacing.md +rule_type: layout +--- + + +# enforce consistent spacing before and after keywords (keyword-spacing) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +Keywords are syntax elements of JavaScript, such as `try` and `if`. +These keywords have special meaning to the language and so often appear in a different color in code editors. +As an important part of the language, style guides often refer to the spacing that should be used around keywords. +For example, you might have a style guide that says keywords should be always surrounded by spaces, which would mean `if-else` statements must look like this: + +```js +if (foo) { + // ... +} else { + // ... +} +``` + +Of course, you could also have a style guide that disallows spaces around keywords. + +However, if you want to enforce the style of spacing between the `function` keyword and the following opening parenthesis, please refer to [space-before-function-paren](space-before-function-paren). + +## Rule Details + +This rule enforces consistent spacing around keywords and keyword-like tokens: `as` (in module declarations), `async` (of async functions), `await` (of await expressions), `break`, `case`, `catch`, `class`, `const`, `continue`, `debugger`, `default`, `delete`, `do`, `else`, `export`, `extends`, `finally`, `for`, `from` (in module declarations), `function`, `get` (of getters), `if`, `import`, `in`, `instanceof`, `let`, `new`, `of` (in for-of statements), `return`, `set` (of setters), `static`, `super`, `switch`, `this`, `throw`, `try`, `typeof`, `var`, `void`, `while`, `with`, and `yield`. This rule is designed carefully not to conflict with other spacing rules: it does not apply to spacing where other rules report problems. + +## Options + +This rule has an object option: + +* `"before": true` (default) requires at least one space before keywords +* `"before": false` disallows spaces before keywords +* `"after": true` (default) requires at least one space after keywords +* `"after": false` disallows spaces after keywords +* `"overrides"` allows overriding spacing style for specified keywords + +### before + +Examples of **incorrect** code for this rule with the default `{ "before": true }` option: + +```js +/*eslint keyword-spacing: ["error", { "before": true }]*/ + +if (foo) { + //... +}else if (bar) { + //... +}else { + //... +} +``` + +Examples of **correct** code for this rule with the default `{ "before": true }` option: + +```js +/*eslint keyword-spacing: ["error", { "before": true }]*/ +/*eslint-env es6*/ + +if (foo) { + //... +} else if (bar) { + //... +} else { + //... +} + +// Avoid conflict with `array-bracket-spacing` +let a = [this]; +let b = [function() {}]; + +// Avoid conflict with `arrow-spacing` +let a = ()=> this.foo; + +// Avoid conflict with `block-spacing` +{function foo() {}} + +// Avoid conflict with `comma-spacing` +let a = [100,this.foo, this.bar]; + +// Avoid conflict with `computed-property-spacing` +obj[this.foo] = 0; + +// Avoid conflict with `generator-star-spacing` +function *foo() {} + +// Avoid conflict with `key-spacing` +let obj = { + foo:function() {} +}; + +// Avoid conflict with `object-curly-spacing` +let obj = {foo: this}; + +// Avoid conflict with `semi-spacing` +let a = this;function foo() {} + +// Avoid conflict with `space-in-parens` +(function () {})(); + +// Avoid conflict with `space-infix-ops` +if ("foo"in {foo: 0}) {} +if (10+this.foo<= this.bar) {} + +// Avoid conflict with `jsx-curly-spacing` +let a = +``` + +Examples of **incorrect** code for this rule with the `{ "before": false }` option: + +```js +/*eslint keyword-spacing: ["error", { "before": false }]*/ + +if (foo) { + //... +} else if (bar) { + //... +} else { + //... +} +``` + +Examples of **correct** code for this rule with the `{ "before": false }` option: + +```js +/*eslint keyword-spacing: ["error", { "before": false }]*/ + +if (foo) { + //... +}else if (bar) { + //... +}else { + //... +} +``` + +### after + +Examples of **incorrect** code for this rule with the default `{ "after": true }` option: + +```js +/*eslint keyword-spacing: ["error", { "after": true }]*/ + +if(foo) { + //... +} else if(bar) { + //... +} else{ + //... +} +``` + +Examples of **correct** code for this rule with the default `{ "after": true }` option: + +```js +/*eslint keyword-spacing: ["error", { "after": true }]*/ + +if (foo) { + //... +} else if (bar) { + //... +} else { + //... +} + +// Avoid conflict with `array-bracket-spacing` +let a = [this]; + +// Avoid conflict with `arrow-spacing` +let a = ()=> this.foo; + +// Avoid conflict with `comma-spacing` +let a = [100, this.foo, this.bar]; + +// Avoid conflict with `computed-property-spacing` +obj[this.foo] = 0; + +// Avoid conflict with `generator-star-spacing` +function* foo() {} + +// Avoid conflict with `key-spacing` +let obj = { + foo:function() {} +}; + +// Avoid conflict with `func-call-spacing` +class A { + constructor() { + super(); + } +} + +// Avoid conflict with `object-curly-spacing` +let obj = {foo: this}; + +// Avoid conflict with `semi-spacing` +let a = this;function foo() {} + +// Avoid conflict with `space-before-function-paren` +function() {} + +// Avoid conflict with `space-infix-ops` +if ("foo"in{foo: 0}) {} +if (10+this.foo<= this.bar) {} + +// Avoid conflict with `space-unary-ops` +function* foo(a) { + return yield+a; +} + +// Avoid conflict with `yield-star-spacing` +function* foo(a) { + return yield* a; +} + +// Avoid conflict with `jsx-curly-spacing` +let a = +``` + +Examples of **incorrect** code for this rule with the `{ "after": false }` option: + +```js +/*eslint keyword-spacing: ["error", { "after": false }]*/ + +if (foo) { + //... +} else if (bar) { + //... +} else { + //... +} +``` + +Examples of **correct** code for this rule with the `{ "after": false }` option: + +```js +/*eslint keyword-spacing: ["error", { "after": false }]*/ + +if(foo) { + //... +} else if(bar) { + //... +} else{ + //... +} +``` + +### overrides + +Examples of **correct** code for this rule with the `{ "overrides": { "if": { "after": false }, "for": { "after": false }, "while": { "after": false } } }` option: + +```js +/*eslint keyword-spacing: ["error", { "overrides": { + "if": { "after": false }, + "for": { "after": false }, + "while": { "after": false } +} }]*/ + +if(foo) { + //... +} else if(bar) { + //... +} else { + //... +} + +for(;;); + +while(true) { + //... +} +``` + +## When Not To Use It + +If you don't want to enforce consistency on keyword spacing, then it's safe to disable this rule. + +## Version + +This rule was introduced in ESLint 2.0.0-beta.1. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/keyword-spacing.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/keyword-spacing.md) diff --git a/docs/8.0.0/rules/line-comment-position.md b/docs/8.0.0/rules/line-comment-position.md new file mode 100644 index 0000000000..f2b96dff3c --- /dev/null +++ b/docs/8.0.0/rules/line-comment-position.md @@ -0,0 +1,123 @@ +--- +title: line-comment-position - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/line-comment-position.md +rule_type: layout +--- + + +# enforce position of line comments (line-comment-position) + +Line comments can be positioned above or beside code. This rule helps teams maintain a consistent style. + +```js +// above comment +var foo = "bar"; // beside comment +``` + +## Rule Details + +This rule enforces consistent position of line comments. Block comments are not affected by this rule. By default, this rule ignores comments starting with the following words: `eslint`, `jshint`, `jslint`, `istanbul`, `global`, `exported`, `jscs`, `falls through`. + + +## Options + +This rule takes one argument, which can be a string or an object. The string settings are the same as those of the `position` property (explained below). The object option has the following properties: + +### position + +The `position` option has two settings: + +* `above` (default) enforces line comments only above code, in its own line. +* `beside` enforces line comments only at the end of code lines. + +#### position: above + +Examples of **correct** code for the `{ "position": "above" }` option: + +```js +/*eslint line-comment-position: ["error", { "position": "above" }]*/ +// valid comment +1 + 1; +``` + + +Examples of **incorrect** code for the `{ "position": "above" }` option: + +```js +/*eslint line-comment-position: ["error", { "position": "above" }]*/ +1 + 1; // invalid comment +``` + +#### position: beside + +Examples of **correct** code for the `{ "position": "beside" }` option: + +```js +/*eslint line-comment-position: ["error", { "position": "beside" }]*/ +1 + 1; // valid comment +``` + + +Examples of **incorrect** code for the `{ "position": "beside" }` option: + +```js +/*eslint line-comment-position: ["error", { "position": "beside" }]*/ +// invalid comment +1 + 1; +``` + +### ignorePattern + +By default this rule ignores comments starting with the following words: `eslint`, `jshint`, `jslint`, `istanbul`, `global`, `exported`, `jscs`, `falls through`. An alternative regular expression can be provided. + +Examples of **correct** code for the `ignorePattern` option: + +```js +/*eslint line-comment-position: ["error", { "ignorePattern": "pragma" }]*/ +1 + 1; // pragma valid comment +``` + +Examples of **incorrect** code for the `ignorePattern` option: + +```js +/*eslint line-comment-position: ["error", { "ignorePattern": "pragma" }]*/ +1 + 1; // invalid comment +``` + +### applyDefaultIgnorePatterns + +Default ignore patterns are applied even when `ignorePattern` is provided. If you want to omit default patterns, set this option to `false`. + +Examples of **correct** code for the `{ "applyDefaultIgnorePatterns": false }` option: + +```js +/*eslint line-comment-position: ["error", { "ignorePattern": "pragma", "applyDefaultIgnorePatterns": false }]*/ +1 + 1; // pragma valid comment +``` + +Examples of **incorrect** code for the `{ "applyDefaultIgnorePatterns": false }` option: + +```js +/*eslint line-comment-position: ["error", { "ignorePattern": "pragma", "applyDefaultIgnorePatterns": false }]*/ +1 + 1; // falls through +``` + +**Deprecated:** the object property `applyDefaultPatterns` is deprecated. Please use the property `applyDefaultIgnorePatterns` instead. + +## When Not To Use It + +If you aren't concerned about having different line comment styles, then you can turn off this rule. + +## Compatibility + +**JSCS**: [validateCommentPosition](https://jscs-dev.github.io/rule/validateCommentPosition) + +## Version + +This rule was introduced in ESLint 3.5.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/line-comment-position.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/line-comment-position.md) diff --git a/docs/8.0.0/rules/linebreak-style.md b/docs/8.0.0/rules/linebreak-style.md new file mode 100644 index 0000000000..55f75b3853 --- /dev/null +++ b/docs/8.0.0/rules/linebreak-style.md @@ -0,0 +1,105 @@ +--- +title: linebreak-style - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/linebreak-style.md +rule_type: layout +--- + + +# enforce consistent linebreak style (linebreak-style) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +When developing with a lot of people all having different editors, VCS applications and operating systems it may occur that +different line endings are written by either of the mentioned (might especially happen when using the windows and mac versions of SourceTree together). + +The linebreaks (new lines) used in windows operating system are usually _carriage returns_ (CR) followed by a _line feed_ (LF) making it a _carriage return line feed_ (CRLF) +whereas Linux and Unix use a simple _line feed_ (LF). The corresponding _control sequences_ are `"\n"` (for LF) and `"\r\n"` for (CRLF). + +Many versioning systems (like git and subversion) can automatically ensure the correct ending. However to cover all contingencies, you can activate this rule. + +## Rule Details + +This rule enforces consistent line endings independent of operating system, VCS, or editor used across your codebase. + +### Options + +This rule has a string option: + +* `"unix"` (default) enforces the usage of Unix line endings: `\n` for LF. +* `"windows"` enforces the usage of Windows line endings: `\r\n` for CRLF. + + +### unix + +Examples of **incorrect** code for this rule with the default `"unix"` option: + +```js +/*eslint linebreak-style: ["error", "unix"]*/ + +var a = 'a'; // \r\n + +``` + +Examples of **correct** code for this rule with the default `"unix"` option: + +```js +/*eslint linebreak-style: ["error", "unix"]*/ + +var a = 'a', // \n + b = 'b'; // \n +// \n +function foo(params) { // \n + // do stuff \n +}// \n +``` + +### windows + +Examples of **incorrect** code for this rule with the `"windows"` option: + +```js +/*eslint linebreak-style: ["error", "windows"]*/ + +var a = 'a'; // \n +``` + +Examples of **correct** code for this rule with the `"windows"` option: + +```js +/*eslint linebreak-style: ["error", "windows"]*/ + +var a = 'a', // \r\n + b = 'b'; // \r\n +// \r\n +function foo(params) { // \r\n + // do stuff \r\n +} // \r\n +``` + +## Using this rule with version control systems + +Version control systems sometimes have special behavior for linebreaks. To make it easy for developers to contribute to your codebase from different platforms, you may want to configure your VCS to handle linebreaks appropriately. + +For example, the default behavior of [git](https://git-scm.com/) on Windows systems is to convert LF linebreaks to CRLF when checking out files, but to store the linebreaks as LF when committing a change. This will cause the `linebreak-style` rule to report errors if configured with the `"unix"` setting, because the files that ESLint sees will have CRLF linebreaks. If you use git, you may want to add a line to your [`.gitattributes` file](https://git-scm.com/docs/gitattributes) to prevent git from converting linebreaks in `.js` files: + +``` +*.js text eol=lf +``` + +## When Not To Use It + +If you aren't concerned about having different line endings within your code, then you can safely turn this rule off. + +## Compatibility + +* **JSCS**: [validateLineBreaks](https://jscs-dev.github.io/rule/validateLineBreaks) + +## Version + +This rule was introduced in ESLint 0.21.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/linebreak-style.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/linebreak-style.md) diff --git a/docs/8.0.0/rules/lines-around-comment.md b/docs/8.0.0/rules/lines-around-comment.md new file mode 100644 index 0000000000..5aef9fe354 --- /dev/null +++ b/docs/8.0.0/rules/lines-around-comment.md @@ -0,0 +1,517 @@ +--- +title: lines-around-comment - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/lines-around-comment.md +rule_type: layout +--- + + +# require empty lines around comments (lines-around-comment) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +Many style guides require empty lines before or after comments. The primary goal +of these rules is to make the comments easier to read and improve readability of the code. + +## Rule Details + +This rule requires empty lines before and/or after comments. It can be enabled separately for both block (`/*`) and line (`//`) comments. This rule does not apply to comments that appear on the same line as code and does not require empty lines at the beginning or end of a file. + +## Options + +This rule has an object option: + +* `"beforeBlockComment": true` (default) requires an empty line before block comments +* `"afterBlockComment": true` requires an empty line after block comments +* `"beforeLineComment": true` requires an empty line before line comments +* `"afterLineComment": true` requires an empty line after line comments +* `"allowBlockStart": true` allows comments to appear at the start of block statements +* `"allowBlockEnd": true` allows comments to appear at the end of block statements +* `"allowObjectStart": true` allows comments to appear at the start of object literals +* `"allowObjectEnd": true` allows comments to appear at the end of object literals +* `"allowArrayStart": true` allows comments to appear at the start of array literals +* `"allowArrayEnd": true` allows comments to appear at the end of array literals +* `"allowClassStart": true` allows comments to appear at the start of classes +* `"allowClassEnd": true` allows comments to appear at the end of classes +* `"applyDefaultIgnorePatterns"` enables or disables the default comment patterns to be ignored by the rule +* `"ignorePattern"` custom patterns to be ignored by the rule + + +### beforeBlockComment + +Examples of **incorrect** code for this rule with the default `{ "beforeBlockComment": true }` option: + +```js +/*eslint lines-around-comment: ["error", { "beforeBlockComment": true }]*/ + +var night = "long"; +/* what a great and wonderful day */ +var day = "great" +``` + +Examples of **correct** code for this rule with the default `{ "beforeBlockComment": true }` option: + +```js +/*eslint lines-around-comment: ["error", { "beforeBlockComment": true }]*/ + +var night = "long"; + +/* what a great and wonderful day */ +var day = "great" +``` + +### afterBlockComment + +Examples of **incorrect** code for this rule with the `{ "afterBlockComment": true }` option: + +```js +/*eslint lines-around-comment: ["error", { "afterBlockComment": true }]*/ + +var night = "long"; + +/* what a great and wonderful day */ +var day = "great" +``` + +Examples of **correct** code for this rule with the `{ "afterBlockComment": true }` option: + +```js +/*eslint lines-around-comment: ["error", { "afterBlockComment": true }]*/ + +var night = "long"; + +/* what a great and wonderful day */ + +var day = "great" +``` + +### beforeLineComment + +Examples of **incorrect** code for this rule with the `{ "beforeLineComment": true }` option: + +```js +/*eslint lines-around-comment: ["error", { "beforeLineComment": true }]*/ + +var night = "long"; +// what a great and wonderful day +var day = "great" +``` + +Examples of **correct** code for this rule with the `{ "beforeLineComment": true }` option: + +```js +/*eslint lines-around-comment: ["error", { "beforeLineComment": true }]*/ + +var night = "long"; + +// what a great and wonderful day +var day = "great" +``` + +### afterLineComment + +Examples of **incorrect** code for this rule with the `{ "afterLineComment": true }` option: + +```js +/*eslint lines-around-comment: ["error", { "afterLineComment": true }]*/ + +var night = "long"; +// what a great and wonderful day +var day = "great" +``` + +Examples of **correct** code for this rule with the `{ "afterLineComment": true }` option: + +```js +/*eslint lines-around-comment: ["error", { "afterLineComment": true }]*/ + +var night = "long"; +// what a great and wonderful day + +var day = "great" +``` + +### allowBlockStart + +Examples of **correct** code for this rule with the `{ "beforeLineComment": true, "allowBlockStart": true }` options: + +```js +/*eslint lines-around-comment: ["error", { "beforeLineComment": true, "allowBlockStart": true }]*/ + +function foo(){ + // what a great and wonderful day + var day = "great" + return day; +} +``` + +Examples of **correct** code for this rule with the `{ "beforeBlockComment": true, "allowBlockStart": true }` options: + +```js +/*eslint lines-around-comment: ["error", { "beforeBlockComment": true, "allowBlockStart": true }]*/ + +function foo(){ + /* what a great and wonderful day */ + var day = "great" + return day; +} +``` + +### allowBlockEnd + +Examples of **correct** code for this rule with the `{ "afterLineComment": true, "allowBlockEnd": true }` option: + +```js +/*eslint lines-around-comment: ["error", { "afterLineComment": true, "allowBlockEnd": true }]*/ + +function foo(){ + var day = "great" + return day; + // what a great and wonderful day +} +``` + +Examples of **correct** code for this rule with the `{ "afterBlockComment": true, "allowBlockEnd": true }` option: + +```js +/*eslint lines-around-comment: ["error", { "afterBlockComment": true, "allowBlockEnd": true }]*/ + +function foo(){ + var day = "great" + return day; + + /* what a great and wonderful day */ +} +``` + +### allowClassStart + +Examples of **incorrect** code for this rule with the `{ "beforeLineComment": true, "allowClassStart": false }` option: + +```js +/*eslint lines-around-comment: ["error", { "beforeLineComment": true, "allowClassStart": false }]*/ + +class foo { + // what a great and wonderful day + day() {} +}; +``` + +Examples of **correct** code for this rule with the `{ "beforeLineComment": true, "allowClassStart": false }` option: + +```js +/*eslint lines-around-comment: ["error", { "beforeLineComment": true, "allowClassStart": false }]*/ + +class foo { + + // what a great and wonderful day + day() {} +}; +``` + +Examples of **correct** code for this rule with the `{ "beforeLineComment": true, "allowClassStart": true }` option: + +```js +/*eslint lines-around-comment: ["error", { "beforeLineComment": true, "allowClassStart": true }]*/ + +class foo { + // what a great and wonderful day + day() {} +}; +``` + +Examples of **incorrect** code for this rule with the `{ "beforeBlockComment": true, "allowClassStart": false }` option: + +```js +/*eslint lines-around-comment: ["error", { "beforeBlockComment": true, "allowClassStart": false }]*/ + +class foo { + /* what a great and wonderful day */ + day() {} +}; +``` + +Examples of **correct** code for this rule with the `{ "beforeBlockComment": true, "allowClassStart": false }` option: + +```js +/*eslint lines-around-comment: ["error", { "beforeBlockComment": true, "allowClassStart": false }]*/ + +class foo { + + /* what a great and wonderful day */ + day() {} +}; +``` + +Examples of **correct** code for this rule with the `{ "beforeBlockComment": true, "allowClassStart": true }` option: + +```js +/*eslint lines-around-comment: ["error", { "beforeBlockComment": true, "allowClassStart": true }]*/ + +class foo { + /* what a great and wonderful day */ + day() {} +}; +``` + +### allowClassEnd + +Examples of **correct** code for this rule with the `{ "afterLineComment": true, "allowClassEnd": true }` option: + +```js +/*eslint lines-around-comment: ["error", { "afterLineComment": true, "allowClassEnd": true }]*/ + +class foo { + day() {} + // what a great and wonderful day +}; +``` + +Examples of **correct** code for this rule with the `{ "afterBlockComment": true, "allowClassEnd": true }` option: + +```js +/*eslint lines-around-comment: ["error", { "afterBlockComment": true, "allowClassEnd": true }]*/ + +class foo { + day() {} + + /* what a great and wonderful day */ +}; +``` + +### allowObjectStart + +Examples of **correct** code for this rule with the `{ "beforeLineComment": true, "allowObjectStart": true }` option: + +```js +/*eslint lines-around-comment: ["error", { "beforeLineComment": true, "allowObjectStart": true }]*/ + +var foo = { + // what a great and wonderful day + day: "great" +}; + +const { + // what a great and wonderful day + foo: someDay +} = {foo: "great"}; + +const { + // what a great and wonderful day + day +} = {day: "great"}; +``` + +Examples of **correct** code for this rule with the `{ "beforeBlockComment": true, "allowObjectStart": true }` option: + +```js +/*eslint lines-around-comment: ["error", { "beforeBlockComment": true, "allowObjectStart": true }]*/ + +var foo = { + /* what a great and wonderful day */ + day: "great" +}; + +const { + /* what a great and wonderful day */ + foo: someDay +} = {foo: "great"}; + +const { + /* what a great and wonderful day */ + day +} = {day: "great"}; +``` + +### allowObjectEnd + +Examples of **correct** code for this rule with the `{ "afterLineComment": true, "allowObjectEnd": true }` option: + +```js +/*eslint lines-around-comment: ["error", { "afterLineComment": true, "allowObjectEnd": true }]*/ + +var foo = { + day: "great" + // what a great and wonderful day +}; + +const { + foo: someDay + // what a great and wonderful day +} = {foo: "great"}; + +const { + day + // what a great and wonderful day +} = {day: "great"}; +``` + +Examples of **correct** code for this rule with the `{ "afterBlockComment": true, "allowObjectEnd": true }` option: + +```js +/*eslint lines-around-comment: ["error", { "afterBlockComment": true, "allowObjectEnd": true }]*/ + +var foo = { + day: "great" + + /* what a great and wonderful day */ +}; + +const { + foo: someDay + + /* what a great and wonderful day */ +} = {foo: "great"}; + +const { + day + + /* what a great and wonderful day */ +} = {day: "great"}; +``` + +### allowArrayStart + +Examples of **correct** code for this rule with the `{ "beforeLineComment": true, "allowArrayStart": true }` option: + +```js +/*eslint lines-around-comment: ["error", { "beforeLineComment": true, "allowArrayStart": true }]*/ + +var day = [ + // what a great and wonderful day + "great", + "wonderful" +]; + +const [ + // what a great and wonderful day + someDay +] = ["great", "not great"]; +``` + +Examples of **correct** code for this rule with the `{ "beforeBlockComment": true, "allowArrayStart": true }` option: + +```js +/*eslint lines-around-comment: ["error", { "beforeBlockComment": true, "allowArrayStart": true }]*/ + +var day = [ + /* what a great and wonderful day */ + "great", + "wonderful" +]; + +const [ + /* what a great and wonderful day */ + someDay +] = ["great", "not great"]; +``` + +### allowArrayEnd + +Examples of **correct** code for this rule with the `{ "afterLineComment": true, "allowArrayEnd": true }` option: + +```js +/*eslint lines-around-comment: ["error", { "afterLineComment": true, "allowArrayEnd": true }]*/ + +var day = [ + "great", + "wonderful" + // what a great and wonderful day +]; + +const [ + someDay + // what a great and wonderful day +] = ["great", "not great"]; +``` + +Examples of **correct** code for this rule with the `{ "afterBlockComment": true, "allowArrayEnd": true }` option: + +```js +/*eslint lines-around-comment: ["error", { "afterBlockComment": true, "allowArrayEnd": true }]*/ + +var day = [ + "great", + "wonderful" + + /* what a great and wonderful day */ +]; + +const [ + someDay + + /* what a great and wonderful day */ +] = ["great", "not great"]; +``` + + +### ignorePattern + +By default this rule ignores comments starting with the following words: `eslint`, `jshint`, `jslint`, `istanbul`, `global`, `exported`, `jscs`. To ignore more comments in addition to the defaults, set the `ignorePattern` option to a string pattern that will be passed to the [`RegExp` constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/RegExp). + +Examples of **correct** code for the `ignorePattern` option: + +```js +/*eslint lines-around-comment: ["error"]*/ + +foo(); +/* eslint mentioned in this comment */, +bar(); + + +/*eslint lines-around-comment: ["error", { "ignorePattern": "pragma" }] */ + +foo(); +/* a valid comment using pragma in it */ +``` + +Examples of **incorrect** code for the `ignorePattern` option: + +```js +/*eslint lines-around-comment: ["error", { "ignorePattern": "pragma" }] */ + +1 + 1; +/* something else */ +``` + +### applyDefaultIgnorePatterns + +Default ignore patterns are applied even when `ignorePattern` is provided. If you want to omit default patterns, set this option to `false`. + +Examples of **correct** code for the `{ "applyDefaultIgnorePatterns": false }` option: + +```js +/*eslint lines-around-comment: ["error", { "ignorePattern": "pragma", applyDefaultIgnorePatterns: false }] */ + +foo(); +/* a valid comment using pragma in it */ +``` + +Examples of **incorrect** code for the `{ "applyDefaultIgnorePatterns": false }` option: + +```js +/*eslint lines-around-comment: ["error", { "applyDefaultIgnorePatterns": false }] */ + +foo(); +/* eslint mentioned in comment */ + +``` + + +## When Not To Use It + +Many people enjoy a terser code style and don't mind comments bumping up against code. If you fall into that category this rule is not for you. + +## Related Rules + +* [space-before-blocks](space-before-blocks) +* [spaced-comment](spaced-comment) + +## Version + +This rule was introduced in ESLint 0.22.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/lines-around-comment.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/lines-around-comment.md) diff --git a/docs/8.0.0/rules/lines-around-directive.md b/docs/8.0.0/rules/lines-around-directive.md new file mode 100644 index 0000000000..fbd133cdef --- /dev/null +++ b/docs/8.0.0/rules/lines-around-directive.md @@ -0,0 +1,341 @@ +--- +title: lines-around-directive - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/lines-around-directive.md +rule_type: layout +--- + + +# require or disallow newlines around directives (lines-around-directive) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +This rule was **deprecated** in ESLint v4.0.0 and replaced by the [padding-line-between-statements](padding-line-between-statements) rule. + +Directives are used in JavaScript to indicate to the execution environment that a script would like to opt into a feature such as `"strict mode"`. Directives are grouped together in a [directive prologue](https://www.ecma-international.org/ecma-262/7.0/#directive-prologue) at the top of either a file or function block and are applied to the scope in which they occur. + +```js +// Strict mode is invoked for the entire script +"use strict"; + +var foo; + +function bar() { + var baz; +} +``` + +```js +var foo; + +function bar() { + // Strict mode is only invoked within this function + "use strict"; + + var baz; +} +``` + +## Rule Details + +This rule requires or disallows blank newlines around directive prologues. This rule does not enforce any conventions about blank newlines between the individual directives. In addition, it does not require blank newlines before directive prologues unless they are preceded by a comment. Please use the [padded-blocks](padded-blocks) rule if this is a style you would like to enforce. + +## Options + +This rule has one option. It can either be a string or an object: + +* `"always"` (default) enforces blank newlines around directives. +* `"never"` disallows blank newlines around directives. + +or + +```js +{ + "before": "always" or "never" + "after": "always" or "never", +} +``` + +### always + +This is the default option. + +Examples of **incorrect** code for this rule with the `"always"` option: + +```js +/* eslint lines-around-directive: ["error", "always"] */ + +/* Top of file */ +"use strict"; +var foo; + +/* Top of file */ +// comment +"use strict"; +"use asm"; +var foo; + +function foo() { + "use strict"; + "use asm"; + var bar; +} + +function foo() { + // comment + "use strict"; + var bar; +} +``` + +Examples of **correct** code for this rule with the `"always"` option: + +```js +/* eslint lines-around-directive: ["error", "always"] */ + +/* Top of file */ +"use strict"; + +var foo; + +/* Top of file */ +// comment + +"use strict"; +"use asm"; + +var foo; + +function foo() { + "use strict"; + "use asm"; + + var bar; +} + +function foo() { + // comment + + "use strict"; + + var bar; +} +``` + +### never + +Examples of **incorrect** code for this rule with the `"never"` option: + +```js +/* eslint lines-around-directive: ["error", "never"] */ + +/* Top of file */ + +"use strict"; + +var foo; + + +/* Top of file */ +// comment + +"use strict"; +"use asm"; + +var foo; + + +function foo() { + "use strict"; + "use asm"; + + var bar; +} + + +function foo() { + // comment + + "use strict"; + + var bar; +} +``` + +Examples of **correct** code for this rule with the `"never"` option: + +```js +/* eslint lines-around-directive: ["error", "never"] */ + +/* Top of file */ +"use strict"; +var foo; + +/* Top of file */ +// comment +"use strict"; +"use asm"; +var foo; + +function foo() { + "use strict"; + "use asm"; + var bar; +} + +function foo() { + // comment + "use strict"; + var bar; +} +``` + +### before & after + +Examples of **incorrect** code for this rule with the `{ "before": "never", "after": "always" }` option: + +```js +/* eslint lines-around-directive: ["error", { "before": "never", "after": "always" }] */ + +/* Top of file */ + +"use strict"; +var foo; + +/* Top of file */ +// comment + +"use strict"; +"use asm"; +var foo; + +function foo() { + "use strict"; + "use asm"; + var bar; +} + +function foo() { + // comment + + "use strict"; + var bar; +} +``` + +Examples of **correct** code for this rule with the `{ "before": "never", "after": "always" }` option: + +```js +/* eslint lines-around-directive: ["error", { "before": "never", "after": "always" }] */ + +/* Top of file */ +"use strict"; + +var foo; + +/* Top of file */ +// comment +"use strict"; +"use asm"; + +var foo; + +function foo() { + "use strict"; + "use asm"; + + var bar; +} + +function foo() { + // comment + "use strict"; + + var bar; +} +``` + +Examples of **incorrect** code for this rule with the `{ "before": "always", "after": "never" }` option: + +```js +/* eslint lines-around-directive: ["error", { "before": "always", "after": "never" }] */ + +/* Top of file */ +"use strict"; + +var foo; + +/* Top of file */ +// comment +"use strict"; +"use asm"; + +var foo; + +function foo() { + "use strict"; + "use asm"; + + var bar; +} + +function foo() { + // comment + "use strict"; + + var bar; +} +``` + +Examples of **correct** code for this rule with the `{ "before": "always", "after": "never" }` option: + +```js +/* eslint lines-around-directive: ["error", { "before": "always", "after": "never" }] */ + +/* Top of file */ +"use strict"; +var foo; + +/* Top of file */ +// comment + +"use strict"; +"use asm"; +var foo; + +function foo() { + "use strict"; + "use asm"; + var bar; +} + +function foo() { + // comment + + "use strict"; + var bar; +} +``` + +## When Not To Use It + +You can safely disable this rule if you do not have any strict conventions about whether or not directive prologues should have blank newlines before or after them. + +## Related Rules + +* [lines-around-comment](lines-around-comment) +* [padded-blocks](padded-blocks) + +## Compatibility + +* **JSCS**: [requirePaddingNewLinesAfterUseStrict](https://jscs-dev.github.io/rule/requirePaddingNewLinesAfterUseStrict) +* **JSCS**: [disallowPaddingNewLinesAfterUseStrict](https://jscs-dev.github.io/rule/disallowPaddingNewLinesAfterUseStrict) + +## Version + +This rule was introduced in ESLint 3.5.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/lines-around-directive.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/lines-around-directive.md) diff --git a/docs/8.0.0/rules/lines-between-class-members.md b/docs/8.0.0/rules/lines-between-class-members.md new file mode 100644 index 0000000000..8623f058ab --- /dev/null +++ b/docs/8.0.0/rules/lines-between-class-members.md @@ -0,0 +1,129 @@ +--- +title: lines-between-class-members - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/lines-between-class-members.md +rule_type: layout +--- + + +# require or disallow an empty line between class members (lines-between-class-members) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +This rule improves readability by enforcing lines between class members. It will not check empty lines before the first member and after the last member, since that is already taken care of by padded-blocks. + +## Rule Details + +Examples of **incorrect** code for this rule: + +```js +/* eslint lines-between-class-members: ["error", "always"]*/ +class MyClass { + foo() { + //... + } + bar() { + //... + } +} +``` + +Examples of **correct** code for this rule: + +```js +/* eslint lines-between-class-members: ["error", "always"]*/ +class MyClass { + foo() { + //... + } + + bar() { + //... + } +} +``` + +### Options + +This rule has a string option and an object option. + +String option: + +* `"always"`(default) require an empty line after class members +* `"never"` disallows an empty line after class members + +Object option: + +* `"exceptAfterSingleLine": false`(default) **do not** skip checking empty lines after single-line class members +* `"exceptAfterSingleLine": true` skip checking empty lines after single-line class members + +Examples of **incorrect** code for this rule with the string option: + +```js +/* eslint lines-between-class-members: ["error", "always"]*/ +class Foo{ + bar(){} + baz(){} +} + +/* eslint lines-between-class-members: ["error", "never"]*/ +class Foo{ + bar(){} + + baz(){} +} +``` + +Examples of **correct** code for this rule with the string option: + +```js +/* eslint lines-between-class-members: ["error", "always"]*/ +class Foo{ + bar(){} + + baz(){} +} + +/* eslint lines-between-class-members: ["error", "never"]*/ +class Foo{ + bar(){} + baz(){} +} +``` + +Examples of **correct** code for this rule with the object option: + +```js +/* eslint lines-between-class-members: ["error", "always", { "exceptAfterSingleLine": true }]*/ +class Foo{ + bar(){} // single line class member + baz(){ + // multi line class member + } + + qux(){} +} +``` + +## When Not To Use It + +If you don't want to enforce empty lines between class members, you can disable this rule. + +## Related Rules + +* [padded-blocks](padded-blocks) +* [padding-line-between-statements](padding-line-between-statements) + +## Compatibility + +* [requirePaddingNewLinesAfterBlocks](https://jscs-dev.github.io/rule/requirePaddingNewLinesAfterBlocks) +* [disallowPaddingNewLinesAfterBlocks](https://jscs-dev.github.io/rule/disallowPaddingNewLinesAfterBlocks) + +## Version + +This rule was introduced in ESLint 4.9.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/lines-between-class-members.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/lines-between-class-members.md) diff --git a/docs/8.0.0/rules/max-classes-per-file.md b/docs/8.0.0/rules/max-classes-per-file.md new file mode 100644 index 0000000000..cf760d9966 --- /dev/null +++ b/docs/8.0.0/rules/max-classes-per-file.md @@ -0,0 +1,66 @@ +--- +title: max-classes-per-file - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/max-classes-per-file.md +rule_type: suggestion +--- + + +# enforce a maximum number of classes per file (max-classes-per-file) + +Files containing multiple classes can often result in a less navigable +and poorly structured codebase. Best practice is to keep each file +limited to a single responsibility. + +## Rule Details + +This rule enforces that each file may contain only a particular number +of classes and no more. + +Examples of **incorrect** code for this rule: + +```js +/*eslint max-classes-per-file: "error"*/ + +class Foo {} +class Bar {} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint max-classes-per-file: "error"*/ + +class Foo {} +``` + +## Options + +This rule has a numeric option (defaulted to 1) to specify the +maximum number of classes. + +For example: + +```json +{ + "max-classes-per-file": ["error", 1] +} +``` + +Examples of **correct** code for this rule with the numeric option set to `2`: + +```js +/* eslint max-classes-per-file: ["error", 2] */ + +class Foo {} +class Bar {} +``` + +## Version + +This rule was introduced in ESLint 5.0.0-alpha.3. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/max-classes-per-file.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/max-classes-per-file.md) diff --git a/docs/8.0.0/rules/max-depth.md b/docs/8.0.0/rules/max-depth.md new file mode 100644 index 0000000000..60aaee6ab6 --- /dev/null +++ b/docs/8.0.0/rules/max-depth.md @@ -0,0 +1,82 @@ +--- +title: max-depth - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/max-depth.md +rule_type: suggestion +--- + + +# enforce a maximum depth that blocks can be nested (max-depth) + +Many developers consider code difficult to read if blocks are nested beyond a certain depth. + +## Rule Details + +This rule enforces a maximum depth that blocks can be nested to reduce code complexity. + +## Options + +This rule has a number or object option: + +* `"max"` (default `4`) enforces a maximum depth that blocks can be nested + +**Deprecated:** The object property `maximum` is deprecated; please use the object property `max` instead. + +### max + +Examples of **incorrect** code for this rule with the default `{ "max": 4 }` option: + +```js +/*eslint max-depth: ["error", 4]*/ +/*eslint-env es6*/ + +function foo() { + for (;;) { // Nested 1 deep + while (true) { // Nested 2 deep + if (true) { // Nested 3 deep + if (true) { // Nested 4 deep + if (true) { // Nested 5 deep + } + } + } + } + } +} +``` + +Examples of **correct** code for this rule with the default `{ "max": 4 }` option: + +```js +/*eslint max-depth: ["error", 4]*/ +/*eslint-env es6*/ + +function foo() { + for (;;) { // Nested 1 deep + while (true) { // Nested 2 deep + if (true) { // Nested 3 deep + if (true) { // Nested 4 deep + } + } + } + } +} +``` + +## Related Rules + +* [complexity](complexity) +* [max-len](max-len) +* [max-lines](max-lines) +* [max-lines-per-function](max-lines-per-function) +* [max-nested-callbacks](max-nested-callbacks) +* [max-params](max-params) +* [max-statements](max-statements) + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/max-depth.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/max-depth.md) diff --git a/docs/8.0.0/rules/max-len.md b/docs/8.0.0/rules/max-len.md new file mode 100644 index 0000000000..ae2fda2017 --- /dev/null +++ b/docs/8.0.0/rules/max-len.md @@ -0,0 +1,178 @@ +--- +title: max-len - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/max-len.md +rule_type: layout +--- + + +# enforce a maximum line length (max-len) + +Very long lines of code in any language can be difficult to read. In order to aid in readability and maintainability many coders have developed a convention to limit lines of code to X number of characters (traditionally 80 characters). + +```js +var foo = { "bar": "This is a bar.", "baz": { "qux": "This is a qux" }, "difficult": "to read" }; // very long +``` + +## Rule Details + +This rule enforces a maximum line length to increase code readability and maintainability. The length of a line is defined as the number of Unicode characters in the line. + +## Options + +This rule has a number or object option: + +* `"code"` (default `80`) enforces a maximum line length +* `"tabWidth"` (default `4`) specifies the character width for tab characters +* `"comments"` enforces a maximum line length for comments; defaults to value of `code` +* `"ignorePattern"` ignores lines matching a regular expression; can only match a single line and need to be double escaped when written in YAML or JSON +* `"ignoreComments": true` ignores all trailing comments and comments on their own line +* `"ignoreTrailingComments": true` ignores only trailing comments +* `"ignoreUrls": true` ignores lines that contain a URL +* `"ignoreStrings": true` ignores lines that contain a double-quoted or single-quoted string +* `"ignoreTemplateLiterals": true` ignores lines that contain a template literal +* `"ignoreRegExpLiterals": true` ignores lines that contain a RegExp literal + +### code + +Examples of **incorrect** code for this rule with the default `{ "code": 80 }` option: + +```js +/*eslint max-len: ["error", { "code": 80 }]*/ + +var foo = { "bar": "This is a bar.", "baz": { "qux": "This is a qux" }, "difficult": "to read" }; +``` + +Examples of **correct** code for this rule with the default `{ "code": 80 }` option: + +```js +/*eslint max-len: ["error", { "code": 80 }]*/ + +var foo = { + "bar": "This is a bar.", + "baz": { "qux": "This is a qux" }, + "easier": "to read" +}; +``` + +### tabWidth + +Examples of **incorrect** code for this rule with the default `{ "tabWidth": 4 }` option: + +```js +/*eslint max-len: ["error", { "code": 80, "tabWidth": 4 }]*/ + +\t \t var foo = { "bar": "This is a bar.", "baz": { "qux": "This is a qux" } }; +``` + +Examples of **correct** code for this rule with the default `{ "tabWidth": 4 }` option: + +```js +/*eslint max-len: ["error", { "code": 80, "tabWidth": 4 }]*/ + +\t \t var foo = { +\t \t \t \t "bar": "This is a bar.", +\t \t \t \t "baz": { "qux": "This is a qux" } +\t \t }; +``` + +### comments + +Examples of **incorrect** code for this rule with the `{ "comments": 65 }` option: + +```js +/*eslint max-len: ["error", { "comments": 65 }]*/ + +/** + * This is a comment that violates the maximum line length we have specified +**/ +``` + +### ignoreComments + +Examples of **correct** code for this rule with the `{ "ignoreComments": true }` option: + +```js +/*eslint max-len: ["error", { "ignoreComments": true }]*/ + +/** + * This is a really really really really really really really really really long comment +**/ +``` + +### ignoreTrailingComments + +Examples of **correct** code for this rule with the `{ "ignoreTrailingComments": true }` option: + +```js +/*eslint max-len: ["error", { "ignoreTrailingComments": true }]*/ + +var foo = 'bar'; // This is a really really really really really really really long comment +``` + +### ignoreUrls + +Examples of **correct** code for this rule with the `{ "ignoreUrls": true }` option: + +```js +/*eslint max-len: ["error", { "ignoreUrls": true }]*/ + +var url = 'https://www.example.com/really/really/really/really/really/really/really/long'; +``` + +### ignoreStrings + +Examples of **correct** code for this rule with the `{ "ignoreStrings": true }` option: + +```js +/*eslint max-len: ["error", { "ignoreStrings": true }]*/ + +var longString = 'this is a really really really really really long string!'; +``` + +### ignoreTemplateLiterals + +Examples of **correct** code for this rule with the `{ "ignoreTemplateLiterals": true }` option: + +```js +/*eslint max-len: ["error", { "ignoreTemplateLiterals": true }]*/ + +var longTemplateLiteral = `this is a really really really really really long template literal!`; +``` + +### ignoreRegExpLiterals + +Examples of **correct** code for this rule with the `{ "ignoreRegExpLiterals": true }` option: + +```js +/*eslint max-len: ["error", { "ignoreRegExpLiterals": true }]*/ + +var longRegExpLiteral = /this is a really really really really really long regular expression!/; +``` + +### ignorePattern + +Examples of **correct** code for this rule with the `ignorePattern` option: + +```js +/*eslint max-len: ["error", { "ignorePattern": "^\\s*var\\s.+=\\s*require\\s*\\(" }]*/ + +var dep = require('really/really/really/really/really/really/really/really/long/module'); +``` + +## Related Rules + +* [complexity](complexity) +* [max-depth](max-depth) +* [max-nested-callbacks](max-nested-callbacks) +* [max-params](max-params) +* [max-statements](max-statements) + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/max-len.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/max-len.md) diff --git a/docs/8.0.0/rules/max-lines-per-function.md b/docs/8.0.0/rules/max-lines-per-function.md new file mode 100644 index 0000000000..e79dc3c189 --- /dev/null +++ b/docs/8.0.0/rules/max-lines-per-function.md @@ -0,0 +1,216 @@ +--- +title: max-lines-per-function - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/max-lines-per-function.md +rule_type: suggestion +--- + + +# enforce a maximum function length (max-lines-per-function) + +Some people consider large functions a code smell. Large functions tend to do a lot of things and can make it hard following what's going on. Many coding style guides dictate a limit of the number of lines that a function can comprise of. This rule can help enforce that style. + +## Rule Details + +This rule enforces a maximum number of lines per function, in order to aid in maintainability and reduce complexity. + +## Why not use `max-statements` or other complexity measurement rules instead? + +Nested long method chains like the below example are often broken onto separate lines for readability: + +``` +function() { + return m("div", [ + m("table", {className: "table table-striped latest-data"}, [ + m("tbody", + data.map(function(db) { + return m("tr", {key: db.dbname}, [ + m("td", {className: "dbname"}, db.dbname), + m("td", {className: "query-count"}, [ + m("span", {className: db.lastSample.countClassName}, db.lastSample.nbQueries) + ]) + ]) + }) + ) + ]) + ]) +} +``` + +* `max-statements` will only report this as 1 statement, despite being 16 lines of code. +* `complexity` will only report a complexity of 1 +* `max-nested-callbacks` will only report 1 +* `max-depth` will report a depth of 0 + +## Options + +This rule has the following options that can be specified using an object: + +* `"max"` (default `50`) enforces a maximum number of lines in a function. + +* `"skipBlankLines"` (default `false`) ignore lines made up purely of whitespace. + +* `"skipComments"` (default `false`) ignore lines containing just comments. + +* `"IIFEs"` (default `false`) include any code included in IIFEs. + +Alternatively, you may specify a single integer for the `max` option: + +```json +"max-lines-per-function": ["error", 20] +``` + +is equivalent to + +```json +"max-lines-per-function": ["error", { "max": 20 }] +``` + +### code + +Examples of **incorrect** code for this rule with a max value of `2`: + +```js +/*eslint max-lines-per-function: ["error", 2]*/ +function foo() { + var x = 0; +} +``` + +```js +/*eslint max-lines-per-function: ["error", 2]*/ +function foo() { + // a comment + var x = 0; +} +``` + +```js +/*eslint max-lines-per-function: ["error", 2]*/ +function foo() { + // a comment followed by a blank line + + var x = 0; +} +``` + +Examples of **correct** code for this rule with a max value of `3`: + +```js +/*eslint max-lines-per-function: ["error", 3]*/ +function foo() { + var x = 0; +} +``` + +```js +/*eslint max-lines-per-function: ["error", 3]*/ +function foo() { + // a comment + var x = 0; +} +``` + +```js +/*eslint max-lines-per-function: ["error", 3]*/ +function foo() { + // a comment followed by a blank line + + var x = 0; +} +``` + +### skipBlankLines + +Examples of **incorrect** code for this rule with the `{ "skipBlankLines": true }` option: + +```js +/*eslint max-lines-per-function: ["error", {"max": 2, "skipBlankLines": true}]*/ +function foo() { + + var x = 0; +} +``` + +Examples of **correct** code for this rule with the `{ "skipBlankLines": true }` option: + +```js +/*eslint max-lines-per-function: ["error", {"max": 3, "skipBlankLines": true}]*/ +function foo() { + + var x = 0; +} +``` + +### skipComments + +Examples of **incorrect** code for this rule with the `{ "skipComments": true }` option: + +```js +/*eslint max-lines-per-function: ["error", {"max": 2, "skipComments": true}]*/ +function foo() { + // a comment + var x = 0; +} +``` + +Examples of **correct** code for this rule with the `{ "skipComments": true }` option: + +```js +/*eslint max-lines-per-function: ["error", {"max": 3, "skipComments": true}]*/ +function foo() { + // a comment + var x = 0; +} +``` + +### IIFEs + +Examples of **incorrect** code for this rule with the `{ "IIFEs": true }` option: + +```js +/*eslint max-lines-per-function: ["error", {"max": 2, "IIFEs": true}]*/ +(function(){ + var x = 0; +}()); + +(() => { + var x = 0; +})(); +``` + +Examples of **correct** code for this rule with the `{ "IIFEs": true }` option: + +```js +/*eslint max-lines-per-function: ["error", {"max": 3, "IIFEs": true}]*/ +(function(){ + var x = 0; +}()); + +(() => { + var x = 0; +})(); +``` + +## When Not To Use It + +You can turn this rule off if you are not concerned with the number of lines in your functions. + +## Related Rules + +* [complexity](complexity) +* [max-depth](max-depth) +* [max-lines](max-lines) +* [max-nested-callbacks](max-nested-callbacks) +* [max-params](max-params) +* [max-statements](max-statements) +* [max-statements-per-line](max-statements-per-line) + +## Version + +This rule was introduced in ESLint 5.0.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/max-lines-per-function.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/max-lines-per-function.md) diff --git a/docs/8.0.0/rules/max-lines.md b/docs/8.0.0/rules/max-lines.md new file mode 100644 index 0000000000..f78d522786 --- /dev/null +++ b/docs/8.0.0/rules/max-lines.md @@ -0,0 +1,144 @@ +--- +title: max-lines - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/max-lines.md +rule_type: suggestion +--- + + +# enforce a maximum file length (max-lines) + +Some people consider large files a code smell. Large files tend to do a lot of things and can make it hard following what's going. While there is not an objective maximum number of lines considered acceptable in a file, most people would agree it should not be in the thousands. Recommendations usually range from 100 to 500 lines. + +## Rule Details + +This rule enforces a maximum number of lines per file, in order to aid in maintainability and reduce complexity. + +Please note that most editors show an additional empty line at the end if the file ends with a line break. This rule does not count that extra line. + +## Options + +This rule has a number or object option: + +* `"max"` (default `300`) enforces a maximum number of lines in a file + +* `"skipBlankLines": true` ignore lines made up purely of whitespace. + +* `"skipComments": true` ignore lines containing just comments + +### max + +Examples of **incorrect** code for this rule with a max value of `2`: + +```js +/*eslint max-lines: ["error", 2]*/ +var a, + b, + c; +``` + +```js +/*eslint max-lines: ["error", 2]*/ + +var a, + b,c; +``` + +```js +/*eslint max-lines: ["error", 2]*/ +// a comment +var a, + b,c; +``` + +Examples of **correct** code for this rule with a max value of `2`: + +```js +/*eslint max-lines: ["error", 2]*/ +var a, + b, c; +``` + +```js +/*eslint max-lines: ["error", 2]*/ + +var a, b, c; +``` + +```js +/*eslint max-lines: ["error", 2]*/ +// a comment +var a, b, c; +``` + +### skipBlankLines + +Examples of **incorrect** code for this rule with the `{ "skipBlankLines": true }` option: + +```js +/*eslint max-lines: ["error", {"max": 2, "skipBlankLines": true}]*/ + +var a, + b, + c; +``` + +Examples of **correct** code for this rule with the `{ "skipBlankLines": true }` option: + +```js +/*eslint max-lines: ["error", {"max": 2, "skipBlankLines": true}]*/ + +var a, + b, c; +``` + +### skipComments + +Examples of **incorrect** code for this rule with the `{ "skipComments": true }` option: + +```js +/*eslint max-lines: ["error", {"max": 2, "skipComments": true}]*/ +// a comment +var a, + b, + c; +``` + +Examples of **correct** code for this rule with the `{ "skipComments": true }` option: + +```js +/*eslint max-lines: ["error", {"max": 2, "skipComments": true}]*/ +// a comment +var a, + b, c; +``` + +## When Not To Use It + +You can turn this rule off if you are not concerned with the number of lines in your files. + +## Further reading + +* [Software Module size and file size](https://web.archive.org/web/20160725154648/http://www.mind2b.com/component/content/article/24-software-module-size-and-file-size) + +## Related Rules + +* [complexity](complexity) +* [max-depth](max-depth) +* [max-lines-per-function](max-lines-per-function) +* [max-nested-callbacks](max-nested-callbacks) +* [max-params](max-params) +* [max-statements](max-statements) + +## Compatibility + +* **JSCS**: [maximumNumberOfLines](https://jscs-dev.github.io/rule/maximumNumberOfLines) + +## Version + +This rule was introduced in ESLint 2.12.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/max-lines.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/max-lines.md) diff --git a/docs/8.0.0/rules/max-nested-callbacks.md b/docs/8.0.0/rules/max-nested-callbacks.md new file mode 100644 index 0000000000..75968f0780 --- /dev/null +++ b/docs/8.0.0/rules/max-nested-callbacks.md @@ -0,0 +1,102 @@ +--- +title: max-nested-callbacks - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/max-nested-callbacks.md +rule_type: suggestion +--- + + +# enforce a maximum depth that callbacks can be nested (max-nested-callbacks) + +Many JavaScript libraries use the callback pattern to manage asynchronous operations. A program of any complexity will most likely need to manage several asynchronous operations at various levels of concurrency. A common pitfall that is easy to fall into is nesting callbacks, which makes code more difficult to read the deeper the callbacks are nested. + +```js +foo(function () { + bar(function () { + baz(function() { + qux(function () { + + }); + }); + }); +}); +``` + +## Rule Details + +This rule enforces a maximum depth that callbacks can be nested to increase code clarity. + +## Options + +This rule has a number or object option: + +* `"max"` (default `10`) enforces a maximum depth that callbacks can be nested + +**Deprecated:** The object property `maximum` is deprecated; please use the object property `max` instead. + +### max + +Examples of **incorrect** code for this rule with the `{ "max": 3 }` option: + +```js +/*eslint max-nested-callbacks: ["error", 3]*/ + +foo1(function() { + foo2(function() { + foo3(function() { + foo4(function() { + // Do something + }); + }); + }); +}); +``` + +Examples of **correct** code for this rule with the `{ "max": 3 }` option: + +```js +/*eslint max-nested-callbacks: ["error", 3]*/ + +foo1(handleFoo1); + +function handleFoo1() { + foo2(handleFoo2); +} + +function handleFoo2() { + foo3(handleFoo3); +} + +function handleFoo3() { + foo4(handleFoo4); +} + +function handleFoo4() { + foo5(); +} +``` + +## Further Reading + +* [Control flow in Node.js](http://book.mixu.net/node/ch7.html) +* [Control Flow in Node](https://howtonode.org/control-flow) +* [Control Flow in Node Part II](https://howtonode.org/control-flow-part-ii) + +## Related Rules + +* [complexity](complexity) +* [max-depth](max-depth) +* [max-len](max-len) +* [max-lines](max-lines) +* [max-lines-per-function](max-lines-per-function) +* [max-params](max-params) +* [max-statements](max-statements) + +## Version + +This rule was introduced in ESLint 0.2.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/max-nested-callbacks.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/max-nested-callbacks.md) diff --git a/docs/8.0.0/rules/max-params.md b/docs/8.0.0/rules/max-params.md new file mode 100644 index 0000000000..7fca5e1afe --- /dev/null +++ b/docs/8.0.0/rules/max-params.md @@ -0,0 +1,80 @@ +--- +title: max-params - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/max-params.md +rule_type: suggestion +--- + + +# enforce a maximum number of parameters in function definitions (max-params) + +Functions that take numerous parameters can be difficult to read and write because it requires the memorization of what each parameter is, its type, and the order they should appear in. As a result, many coders adhere to a convention that caps the number of parameters a function can take. + +```js +function foo (bar, baz, qux, qxx) { // four parameters, may be too many + doSomething(); +} +``` + +## Rule Details + +This rule enforces a maximum number of parameters allowed in function definitions. + +## Options + +This rule has a number or object option: + +* `"max"` (default `3`) enforces a maximum number of parameters in function definitions + +**Deprecated:** The object property `maximum` is deprecated; please use the object property `max` instead. + +### max + +Examples of **incorrect** code for this rule with the default `{ "max": 3 }` option: + +```js +/*eslint max-params: ["error", 3]*/ +/*eslint-env es6*/ + +function foo (bar, baz, qux, qxx) { + doSomething(); +} + +let foo = (bar, baz, qux, qxx) => { + doSomething(); +}; +``` + +Examples of **correct** code for this rule with the default `{ "max": 3 }` option: + +```js +/*eslint max-params: ["error", 3]*/ +/*eslint-env es6*/ + +function foo (bar, baz, qux) { + doSomething(); +} + +let foo = (bar, baz, qux) => { + doSomething(); +}; +``` + +## Related Rules + +* [complexity](complexity) +* [max-depth](max-depth) +* [max-len](max-len) +* [max-lines](max-lines) +* [max-lines-per-function](max-lines-per-function) +* [max-nested-callbacks](max-nested-callbacks) +* [max-statements](max-statements) + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/max-params.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/max-params.md) diff --git a/docs/8.0.0/rules/max-statements-per-line.md b/docs/8.0.0/rules/max-statements-per-line.md new file mode 100644 index 0000000000..f8c970b40e --- /dev/null +++ b/docs/8.0.0/rules/max-statements-per-line.md @@ -0,0 +1,104 @@ +--- +title: max-statements-per-line - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/max-statements-per-line.md +rule_type: layout +--- + + +# enforce a maximum number of statements allowed per line (max-statements-per-line) + +A line of code containing too many statements can be difficult to read. Code is generally read from the top down, especially when scanning, so limiting the number of statements allowed on a single line can be very beneficial for readability and maintainability. + +```js +function foo () { var bar; if (condition) { bar = 1; } else { bar = 2; } return true; } // too many statements +``` + +## Rule Details + +This rule enforces a maximum number of statements allowed per line. + +## Options + +### max + +The "max" object property is optional (default: 1). + +Examples of **incorrect** code for this rule with the default `{ "max": 1 }` option: + +```js +/*eslint max-statements-per-line: ["error", { "max": 1 }]*/ + +var bar; var baz; +if (condition) { bar = 1; } +for (var i = 0; i < length; ++i) { bar = 1; } +switch (discriminant) { default: break; } +function foo() { bar = 1; } +var foo = function foo() { bar = 1; }; +(function foo() { bar = 1; })(); +``` + +Examples of **correct** code for this rule with the default `{ "max": 1 }` option: + +```js +/*eslint max-statements-per-line: ["error", { "max": 1 }]*/ + +var bar, baz; +if (condition) bar = 1; +for (var i = 0; i < length; ++i); +switch (discriminant) { default: } +function foo() { } +var foo = function foo() { }; +(function foo() { })(); +``` + +Examples of **incorrect** code for this rule with the `{ "max": 2 }` option: + +```js +/*eslint max-statements-per-line: ["error", { "max": 2 }]*/ + +var bar; var baz; var qux; +if (condition) { bar = 1; } else { baz = 2; } +for (var i = 0; i < length; ++i) { bar = 1; baz = 2; } +switch (discriminant) { case 'test': break; default: break; } +function foo() { bar = 1; baz = 2; } +var foo = function foo() { bar = 1; }; +(function foo() { bar = 1; baz = 2; })(); +``` + +Examples of **correct** code for this rule with the `{ "max": 2 }` option: + +```js +/*eslint max-statements-per-line: ["error", { "max": 2 }]*/ + +var bar; var baz; +if (condition) bar = 1; if (condition) baz = 2; +for (var i = 0; i < length; ++i) { bar = 1; } +switch (discriminant) { default: break; } +function foo() { bar = 1; } +var foo = function foo() { bar = 1; }; +(function foo() { var bar = 1; })(); +``` + +## When Not To Use It + +You can turn this rule off if you are not concerned with the number of statements on each line. + +## Related Rules + +* [max-depth](max-depth) +* [max-len](max-len) +* [max-lines](max-lines) +* [max-lines-per-function](max-lines-per-function) +* [max-nested-callbacks](max-nested-callbacks) +* [max-params](max-params) +* [max-statements](max-statements) + +## Version + +This rule was introduced in ESLint 2.5.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/max-statements-per-line.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/max-statements-per-line.md) diff --git a/docs/8.0.0/rules/max-statements.md b/docs/8.0.0/rules/max-statements.md new file mode 100644 index 0000000000..89fd95d513 --- /dev/null +++ b/docs/8.0.0/rules/max-statements.md @@ -0,0 +1,162 @@ +--- +title: max-statements - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/max-statements.md +rule_type: suggestion +--- + + +# enforce a maximum number of statements allowed in function blocks (max-statements) + +The `max-statements` rule allows you to specify the maximum number of statements allowed in a function. + +```js +function foo() { + var bar = 1; // one statement + var baz = 2; // two statements + var qux = 3; // three statements +} +``` + +## Rule Details + +This rule enforces a maximum number of statements allowed in function blocks. + +## Options + +This rule has a number or object option: + +* `"max"` (default `10`) enforces a maximum number of statements allows in function blocks + +**Deprecated:** The object property `maximum` is deprecated; please use the object property `max` instead. + +This rule has an object option: + +* `"ignoreTopLevelFunctions": true` ignores top-level functions + +### max + +Examples of **incorrect** code for this rule with the default `{ "max": 10 }` option: + +```js +/*eslint max-statements: ["error", 10]*/ +/*eslint-env es6*/ + +function foo() { + var foo1 = 1; + var foo2 = 2; + var foo3 = 3; + var foo4 = 4; + var foo5 = 5; + var foo6 = 6; + var foo7 = 7; + var foo8 = 8; + var foo9 = 9; + var foo10 = 10; + + var foo11 = 11; // Too many. +} + +let foo = () => { + var foo1 = 1; + var foo2 = 2; + var foo3 = 3; + var foo4 = 4; + var foo5 = 5; + var foo6 = 6; + var foo7 = 7; + var foo8 = 8; + var foo9 = 9; + var foo10 = 10; + + var foo11 = 11; // Too many. +}; +``` + +Examples of **correct** code for this rule with the default `{ "max": 10 }` option: + +```js +/*eslint max-statements: ["error", 10]*/ +/*eslint-env es6*/ + +function foo() { + var foo1 = 1; + var foo2 = 2; + var foo3 = 3; + var foo4 = 4; + var foo5 = 5; + var foo6 = 6; + var foo7 = 7; + var foo8 = 8; + var foo9 = 9; + var foo10 = 10; + return function () { + + // The number of statements in the inner function does not count toward the + // statement maximum. + + return 42; + }; +} + +let foo = () => { + var foo1 = 1; + var foo2 = 2; + var foo3 = 3; + var foo4 = 4; + var foo5 = 5; + var foo6 = 6; + var foo7 = 7; + var foo8 = 8; + var foo9 = 9; + var foo10 = 10; + return function () { + + // The number of statements in the inner function does not count toward the + // statement maximum. + + return 42; + }; +} +``` + +### ignoreTopLevelFunctions + +Examples of additional **correct** code for this rule with the `{ "max": 10 }, { "ignoreTopLevelFunctions": true }` options: + +```js +/*eslint max-statements: ["error", 10, { "ignoreTopLevelFunctions": true }]*/ + +function foo() { + var foo1 = 1; + var foo2 = 2; + var foo3 = 3; + var foo4 = 4; + var foo5 = 5; + var foo6 = 6; + var foo7 = 7; + var foo8 = 8; + var foo9 = 9; + var foo10 = 10; + var foo11 = 11; +} +``` + +## Related Rules + +* [complexity](complexity) +* [max-depth](max-depth) +* [max-len](max-len) +* [max-lines](max-lines) +* [max-lines-per-function](max-lines-per-function) +* [max-nested-callbacks](max-nested-callbacks) +* [max-params](max-params) + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/max-statements.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/max-statements.md) diff --git a/docs/8.0.0/rules/multiline-comment-style.md b/docs/8.0.0/rules/multiline-comment-style.md new file mode 100644 index 0000000000..9df606a545 --- /dev/null +++ b/docs/8.0.0/rules/multiline-comment-style.md @@ -0,0 +1,142 @@ +--- +title: multiline-comment-style - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/multiline-comment-style.md +rule_type: suggestion +--- + + +# enforce a particular style for multiline comments (multiline-comment-style) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +Many style guides require a particular style for comments that span multiple lines. For example, some style guides prefer the use of a single block comment for multiline comments, whereas other style guides prefer consecutive line comments. + +## Rule Details + +This rule aims to enforce a particular style for multiline comments. + +### Options + +This rule has a string option, which can have one of the following values: + +* `"starred-block"` (default): Disallows consecutive line comments in favor of block comments. Additionally, requires block comments to have an aligned `*` character before each line. +* `"bare-block"`: Disallows consecutive line comments in favor of block comments, and disallows block comments from having a `"*"` character before each line. +* `"separate-lines"`: Disallows block comments in favor of consecutive line comments + +The rule always ignores directive comments such as `/* eslint-disable */`. Additionally, unless the mode is `"starred-block"`, the rule ignores JSDoc comments. + +Examples of **incorrect** code for this rule with the default `"starred-block"` option: + +```js + +/* eslint multiline-comment-style: ["error", "starred-block"] */ + +// this line +// calls foo() +foo(); + +/* this line +calls foo() */ +foo(); + +/* this comment + * is missing a newline after /* + */ + +/* + * this comment + * is missing a newline at the end */ + +/* +* the star in this line should have a space before it + */ + +/* + * the star on the following line should have a space before it +*/ + +``` + +Examples of **correct** code for this rule with the default `"starred-block"` option: + +```js +/* eslint multiline-comment-style: ["error", "starred-block"] */ + +/* + * this line + * calls foo() + */ +foo(); + +// single-line comment +``` + +Examples of **incorrect** code for this rule with the `"bare-block"` option: + +```js +/* eslint multiline-comment-style: ["error", "bare-block"] */ + +// this line +// calls foo() +foo(); + +/* + * this line + * calls foo() + */ +foo(); +``` + +Examples of **correct** code for this rule with the `"bare-block"` option: + +```js +/* eslint multiline-comment-style: ["error", "bare-block"] */ + +/* this line + calls foo() */ +foo(); +``` + +Examples of **incorrect** code for this rule with the `"separate-lines"` option: + +```js + +/* eslint multiline-comment-style: ["error", "separate-lines"] */ + +/* This line +calls foo() */ +foo(); + +/* + * This line + * calls foo() + */ +foo(); + +``` + +Examples of **correct** code for this rule with the `"separate-lines"` option: + +```js +/* eslint multiline-comment-style: ["error", "separate-lines"] */ + +// This line +// calls foo() +foo(); + + +``` + +## When Not To Use It + +If you don't want to enforce a particular style for multiline comments, you can disable the rule. + +## Version + +This rule was introduced in ESLint 4.10.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/multiline-comment-style.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/multiline-comment-style.md) diff --git a/docs/8.0.0/rules/multiline-ternary.md b/docs/8.0.0/rules/multiline-ternary.md new file mode 100644 index 0000000000..05e0a95870 --- /dev/null +++ b/docs/8.0.0/rules/multiline-ternary.md @@ -0,0 +1,172 @@ +--- +title: multiline-ternary - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/multiline-ternary.md +rule_type: layout +--- + + +# Enforce or disallow newlines between operands of ternary expressions (multiline-ternary) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +JavaScript allows operands of ternary expressions to be separated by newlines, which can improve the readability of your program. + +For example: + +```js +var foo = bar > baz ? value1 : value2; +``` + +The above can be rewritten as the following to improve readability and more clearly delineate the operands: + +```js +var foo = bar > baz ? + value1 : + value2; +``` + +## Rule Details + +This rule enforces or disallows newlines between operands of a ternary expression. +Note: The location of the operators is not enforced by this rule. Please see the [operator-linebreak](operator-linebreak) rule if you are interested in enforcing the location of the operators themselves. + +## Options + +This rule has a string option: + +* `"always"` (default) enforces newlines between the operands of a ternary expression. +* `"always-multiline"` enforces newlines between the operands of a ternary expression if the expression spans multiple lines. +* `"never"` disallows newlines between the operands of a ternary expression. + +### always + +This is the default option. + +Examples of **incorrect** code for this rule with the `"always"` option: + +```js +/*eslint multiline-ternary: ["error", "always"]*/ + +foo > bar ? value1 : value2; + +foo > bar ? value : + value2; + +foo > bar ? + value : value2; +``` + +Examples of **correct** code for this rule with the `"always"` option: + +```js +/*eslint multiline-ternary: ["error", "always"]*/ + +foo > bar ? + value1 : + value2; + +foo > bar ? + (baz > qux ? + value1 : + value2) : + value3; +``` + +### always-multiline + +Examples of **incorrect** code for this rule with the `"always-multiline"` option: + +```js +/*eslint multiline-ternary: ["error", "always-multiline"]*/ + +foo > bar ? value1 : + value2; + +foo > bar ? + value1 : value2; + +foo > bar && + bar > baz ? value1 : value2; +``` + +Examples of **correct** code for this rule with the `"always-multiline"` option: + +```js +/*eslint multiline-ternary: ["error", "always-multiline"]*/ + +foo > bar ? value1 : value2; + +foo > bar ? + value1 : + value2; + +foo > bar ? + (baz > qux ? value1 : value2) : + value3; + +foo > bar ? + (baz > qux ? + value1 : + value2) : + value3; + +foo > bar && + bar > baz ? + value1 : + value2; +``` + +### never + +Examples of **incorrect** code for this rule with the `"never"` option: + +```js +/*eslint multiline-ternary: ["error", "never"]*/ + +foo > bar ? value : + value2; + +foo > bar ? + value : value2; + +foo > + bar ? + value1 : + value2; +``` + +Examples of **correct** code for this rule with the `"never"` option: + +```js +/*eslint multiline-ternary: ["error", "never"]*/ + +foo > bar ? value1 : value2; + +foo > bar ? (baz > qux ? value1 : value2) : value3; + +foo > bar ? ( + baz > qux ? value1 : value2 +) : value3; +``` + +## When Not To Use It + +You can safely disable this rule if you do not have any strict conventions about whether the operands of a ternary expression should be separated by newlines. + +## Related Rules + +* [operator-linebreak](operator-linebreak) + +## Compatibility + +* **JSCS**: [requireMultiLineTernary](https://jscs-dev.github.io/rule/requireMultiLineTernary) + +## Version + +This rule was introduced in ESLint 3.1.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/multiline-ternary.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/multiline-ternary.md) diff --git a/docs/8.0.0/rules/new-cap.md b/docs/8.0.0/rules/new-cap.md new file mode 100644 index 0000000000..581c176dca --- /dev/null +++ b/docs/8.0.0/rules/new-cap.md @@ -0,0 +1,221 @@ +--- +title: new-cap - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/new-cap.md +rule_type: suggestion +--- + + +# require constructor names to begin with a capital letter (new-cap) + +The `new` operator in JavaScript creates a new instance of a particular type of object. That type of object is represented by a constructor function. Since constructor functions are just regular functions, the only defining characteristic is that `new` is being used as part of the call. Native JavaScript functions begin with an uppercase letter to distinguish those functions that are to be used as constructors from functions that are not. Many style guides recommend following this pattern to more easily determine which functions are to be used as constructors. + +```js +var friend = new Person(); +``` + +## Rule Details + +This rule requires constructor names to begin with a capital letter. Certain built-in identifiers are exempt from this rule. These identifiers are: + +* `Array` +* `Boolean` +* `Date` +* `Error` +* `Function` +* `Number` +* `Object` +* `RegExp` +* `String` +* `Symbol` + +Examples of **correct** code for this rule: + +```js +/*eslint new-cap: "error"*/ + +function foo(arg) { + return Boolean(arg); +} +``` + +## Options + +This rule has an object option: + +* `"newIsCap": true` (default) requires all `new` operators to be called with uppercase-started functions. +* `"newIsCap": false` allows `new` operators to be called with lowercase-started or uppercase-started functions. +* `"capIsNew": true` (default) requires all uppercase-started functions to be called with `new` operators. +* `"capIsNew": false` allows uppercase-started functions to be called without `new` operators. +* `"newIsCapExceptions"` allows specified lowercase-started function names to be called with the `new` operator. +* `"newIsCapExceptionPattern"` allows any lowercase-started function names that match the specified regex pattern to be called with the `new` operator. +* `"capIsNewExceptions"` allows specified uppercase-started function names to be called without the `new` operator. +* `"capIsNewExceptionPattern"` allows any uppercase-started function names that match the specified regex pattern to be called without the `new` operator. +* `"properties": true` (default) enables checks on object properties +* `"properties": false` disables checks on object properties + +### newIsCap + +Examples of **incorrect** code for this rule with the default `{ "newIsCap": true }` option: + +```js +/*eslint new-cap: ["error", { "newIsCap": true }]*/ + +var friend = new person(); +``` + +Examples of **correct** code for this rule with the default `{ "newIsCap": true }` option: + +```js +/*eslint new-cap: ["error", { "newIsCap": true }]*/ + +var friend = new Person(); +``` + +Examples of **correct** code for this rule with the `{ "newIsCap": false }` option: + +```js +/*eslint new-cap: ["error", { "newIsCap": false }]*/ + +var friend = new person(); +``` + +### capIsNew + +Examples of **incorrect** code for this rule with the default `{ "capIsNew": true }` option: + +```js +/*eslint new-cap: ["error", { "capIsNew": true }]*/ + +var colleague = Person(); +``` + +Examples of **correct** code for this rule with the default `{ "capIsNew": true }` option: + +```js +/*eslint new-cap: ["error", { "capIsNew": true }]*/ + +var colleague = new Person(); +``` + +Examples of **correct** code for this rule with the `{ "capIsNew": false }` option: + +```js +/*eslint new-cap: ["error", { "capIsNew": false }]*/ + +var colleague = Person(); +``` + +### newIsCapExceptions + +Examples of additional **correct** code for this rule with the `{ "newIsCapExceptions": ["events"] }` option: + +```js +/*eslint new-cap: ["error", { "newIsCapExceptions": ["events"] }]*/ + +var events = require('events'); + +var emitter = new events(); +``` + +### newIsCapExceptionPattern + +Examples of additional **correct** code for this rule with the `{ "newIsCapExceptionPattern": "^person\\.." }` option: + +```js +/*eslint new-cap: ["error", { "newIsCapExceptionPattern": "^person\\.." }]*/ + +var friend = new person.acquaintance(); + +var bestFriend = new person.friend(); +``` + +Examples of additional **correct** code for this rule with the `{ "newIsCapExceptionPattern": "\\.bar$" }` option: + +```js +/*eslint new-cap: ["error", { "newIsCapExceptionPattern": "\\.bar$" }]*/ + +var friend = new person.bar(); +``` + +### capIsNewExceptions + +Examples of additional **correct** code for this rule with the `{ "capIsNewExceptions": ["Person"] }` option: + +```js +/*eslint new-cap: ["error", { "capIsNewExceptions": ["Person"] }]*/ + +function foo(arg) { + return Person(arg); +} +``` + +### capIsNewExceptionPattern + +Examples of additional **correct** code for this rule with the `{ "capIsNewExceptionPattern": "^person\\.." }` option: + +```js +/*eslint new-cap: ["error", { "capIsNewExceptionPattern": "^person\\.." }]*/ + +var friend = person.Acquaintance(); +var bestFriend = person.Friend(); +``` + +Examples of additional **correct** code for this rule with the `{ "capIsNewExceptionPattern": "\\.Bar$" }` option: + +```js +/*eslint new-cap: ["error", { "capIsNewExceptionPattern": "\\.Bar$" }]*/ + +foo.Bar(); +``` + +Examples of additional **correct** code for this rule with the `{ "capIsNewExceptionPattern": "^Foo" }` option: + +```js +/*eslint new-cap: ["error", { "capIsNewExceptionPattern": "^Foo" }]*/ + +var x = Foo(42); + +var y = Foobar(42); + +var z = Foo.Bar(42); +``` + +### properties + +Examples of **incorrect** code for this rule with the default `{ "properties": true }` option: + +```js +/*eslint new-cap: ["error", { "properties": true }]*/ + +var friend = new person.acquaintance(); +``` + +Examples of **correct** code for this rule with the default `{ "properties": true }` option: + +```js +/*eslint new-cap: ["error", { "properties": true }]*/ + +var friend = new person.Acquaintance(); +``` + +Examples of **correct** code for this rule with the `{ "properties": false }` option: + +```js +/*eslint new-cap: ["error", { "properties": false }]*/ + +var friend = new person.acquaintance(); +``` + +## When Not To Use It + +If you have conventions that don't require an uppercase letter for constructors, or don't require capitalized functions be only used as constructors, turn this rule off. + +## Version + +This rule was introduced in ESLint 0.0.3-0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/new-cap.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/new-cap.md) diff --git a/docs/8.0.0/rules/new-parens.md b/docs/8.0.0/rules/new-parens.md new file mode 100644 index 0000000000..b48c0e3000 --- /dev/null +++ b/docs/8.0.0/rules/new-parens.md @@ -0,0 +1,78 @@ +--- +title: new-parens - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/new-parens.md +rule_type: layout +--- + + +# require parentheses when invoking a constructor with no arguments (new-parens) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +JavaScript allows the omission of parentheses when invoking a function via the `new` keyword and the constructor has no arguments. However, some coders believe that omitting the parentheses is inconsistent with the rest of the language and thus makes code less clear. + +```js +var person = new Person; +``` + +## Rule Details + +This rule can enforce or disallow parentheses when invoking a constructor with no arguments using the `new` keyword. + +## Options + +This rule takes one option. + +- `"always"` enforces parenthesis after a new constructor with no arguments (default) +- `"never"` enforces no parenthesis after a new constructor with no arguments + +### always + +Examples of **incorrect** code for this rule with the `"always"` option: + +```js +/*eslint new-parens: "error"*/ + +var person = new Person; +var person = new (Person); +``` + +Examples of **correct** code for this rule with the `"always"` option: + +```js +/*eslint new-parens: "error"*/ + +var person = new Person(); +var person = new (Person)(); +``` + +### never + +Examples of **incorrect** code for this rule with the `"never"` option: + +```js +/*eslint new-parens: ["error", "never"]*/ + +var person = new Person(); +var person = new (Person)(); +``` + +Examples of **correct** code for this rule with the `"never"` option: + +```js +/*eslint new-parens: ["error", "never"]*/ + +var person = new Person; +var person = (new Person); +var person = new Person("Name"); +``` + +## Version + +This rule was introduced in ESLint 0.0.6. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/new-parens.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/new-parens.md) diff --git a/docs/8.0.0/rules/newline-after-var.md b/docs/8.0.0/rules/newline-after-var.md new file mode 100644 index 0000000000..f976839ca0 --- /dev/null +++ b/docs/8.0.0/rules/newline-after-var.md @@ -0,0 +1,161 @@ +--- +title: newline-after-var - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/newline-after-var.md +rule_type: layout +--- + + +# require or disallow an empty line after variable declarations (newline-after-var) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +This rule was **deprecated** in ESLint v4.0.0 and replaced by the [padding-line-between-statements](padding-line-between-statements) rule. + +As of today there is no consistency in separating variable declarations from the rest of the code. Some developers leave an empty line between var statements and the rest of the code like: + +```js +var foo; + +// do something with foo +``` + +Whereas others don't leave any empty newlines at all. + +```js +var foo; +// do something with foo +``` + +The problem is when these developers work together in a project. This rule enforces a coding style where empty newlines are allowed or disallowed after `var`, `let`, or `const` statements. It helps the code to look consistent across the entire project. + +## Rule Details + +This rule enforces a coding style where empty lines are required or disallowed after `var`, `let`, or `const` statements to achieve a consistent coding style across the project. + +## Options + +This rule has a string option: + +* `"always"` (default) requires an empty line after `var`, `let`, or `const` + + Comments on a line directly after var statements are treated like additional var statements. + +* `"never"` disallows empty lines after `var`, `let`, or `const` + +### always + +Examples of **incorrect** code for this rule with the default `"always"` option: + +```js +/*eslint newline-after-var: ["error", "always"]*/ +/*eslint-env es6*/ + +var greet = "hello,", + name = "world"; +console.log(greet, name); + +let greet = "hello,", + name = "world"; +console.log(greet, name); + +var greet = "hello,"; +const NAME = "world"; +console.log(greet, NAME); + +var greet = "hello,"; +var name = "world"; +// var name = require("world"); +console.log(greet, name); +``` + +Examples of **correct** code for this rule with the default `"always"` option: + +```js +/*eslint newline-after-var: ["error", "always"]*/ +/*eslint-env es6*/ + +var greet = "hello,", + name = "world"; + +console.log(greet, name); + +let greet = "hello,", + name = "world"; + +console.log(greet, name); + +var greet = "hello,"; +const NAME = "world"; + +console.log(greet, NAME); + +var greet = "hello,"; +var name = "world"; +// var name = require("world"); + +console.log(greet, name); +``` + +### never + +Examples of **incorrect** code for this rule with the `"never"` option: + +```js +/*eslint newline-after-var: ["error", "never"]*/ +/*eslint-env es6*/ + +var greet = "hello,", + name = "world"; + +console.log(greet, name); + +let greet = "hello,", + name = "world"; + +console.log(greet, name); + +var greet = "hello,"; +const NAME = "world"; + +console.log(greet, NAME); + +var greet = "hello,"; +var name = "world"; +// var name = require("world"); + +console.log(greet, name); +``` + +Examples of **correct** code for this rule with the `"never"` option: + +```js +/*eslint newline-after-var: ["error", "never"]*/ +/*eslint-env es6*/ + +var greet = "hello,", + name = "world"; +console.log(greet, name); + +let greet = "hello,", + name = "world"; +console.log(greet, name); + +var greet = "hello,"; +const NAME = "world"; +console.log(greet, NAME); + +var greet = "hello,"; +var name = "world"; +// var name = require("world"); +console.log(greet, name); +``` + +## Version + +This rule was introduced in ESLint 0.18.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/newline-after-var.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/newline-after-var.md) diff --git a/docs/8.0.0/rules/newline-before-return.md b/docs/8.0.0/rules/newline-before-return.md new file mode 100644 index 0000000000..e9bb7bc025 --- /dev/null +++ b/docs/8.0.0/rules/newline-before-return.md @@ -0,0 +1,135 @@ +--- +title: newline-before-return - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/newline-before-return.md +rule_type: layout +--- + + +# require an empty line before `return` statements (newline-before-return) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +This rule was **deprecated** in ESLint v4.0.0 and replaced by the [padding-line-between-statements](padding-line-between-statements) rule. + +There is no hard and fast rule about whether empty lines should precede `return` statements in JavaScript. However, clearly delineating where a function is returning can greatly increase the readability and clarity of the code. For example: + +```js +function foo(bar) { + var baz = 'baz'; + if (!bar) { + bar = baz; + return bar; + } + return bar; +} +``` + +Adding newlines visibly separates the return statements from the previous lines, making it clear where the function exits and what value it returns: + +```js +function foo(bar) { + var baz = 'baz'; + + if (!bar) { + bar = baz; + + return bar; + } + + return bar; +} +``` + +## Rule Details + +This rule requires an empty line before `return` statements to increase code clarity, except when the `return` is alone inside a statement group (such as an if statement). In the latter case, the `return` statement does not need to be delineated by virtue of it being alone. Comments are ignored and do not count as empty lines. + +Examples of **incorrect** code for this rule: + +```js +/*eslint newline-before-return: "error"*/ + +function foo(bar) { + if (!bar) { + return; + } + return bar; +} + +function foo(bar) { + if (!bar) { + return; + } + /* multi-line + comment */ + return bar; +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint newline-before-return: "error"*/ + +function foo() { + return; +} + +function foo() { + + return; +} + +function foo(bar) { + if (!bar) return; +} + +function foo(bar) { + if (!bar) { return }; +} + +function foo(bar) { + if (!bar) { + return; + } +} + +function foo(bar) { + if (!bar) { + return; + } + + return bar; +} + +function foo(bar) { + if (!bar) { + + return; + } +} + +function foo() { + + // comment + return; +} +``` + +## When Not To Use It + +You can safely disable this rule if you do not have any strict conventions about whitespace before `return` statements. + +## Related Rules + +* [newline-after-var](newline-after-var) + +## Version + +This rule was introduced in ESLint 2.3.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/newline-before-return.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/newline-before-return.md) diff --git a/docs/8.0.0/rules/newline-per-chained-call.md b/docs/8.0.0/rules/newline-per-chained-call.md new file mode 100644 index 0000000000..d44a91b4b5 --- /dev/null +++ b/docs/8.0.0/rules/newline-per-chained-call.md @@ -0,0 +1,137 @@ +--- +title: newline-per-chained-call - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/newline-per-chained-call.md +rule_type: layout +--- + + +# require a newline after each call in a method chain (newline-per-chained-call) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +Chained method calls on a single line without line breaks are harder to read, so some developers place a newline character after each method call in the chain to make it more readable and easy to maintain. + +Let's look at the following perfectly valid (but single line) code. + +```js +d3.select("body").selectAll("p").data([4, 8, 15, 16, 23, 42 ]).enter().append("p").text(function(d) { return "I'm number " + d + "!"; }); +``` + +However, with appropriate new lines, it becomes easy to read and understand. Look at the same code written below with line breaks after each call. + +```js +d3 + .select("body") + .selectAll("p") + .data([ + 4, + 8, + 15, + 16, + 23, + 42 + ]) + .enter() + .append("p") + .text(function (d) { + return "I'm number " + d + "!"; + }); +``` + +Another argument in favor of this style is that it improves the clarity of diffs when something in the method chain is changed: + +Less clear: + +```diff +-d3.select("body").selectAll("p").style("color", "white"); ++d3.select("body").selectAll("p").style("color", "blue"); +``` + +More clear: + +```diff +d3 + .select("body") + .selectAll("p") +- .style("color", "white"); ++ .style("color", "blue"); +``` + +## Rule Details + +This rule requires a newline after each call in a method chain or deep member access. Computed property accesses such as `instance[something]` are excluded. + +## Options + +This rule has an object option: + +* `"ignoreChainWithDepth"` (default: `2`) allows chains up to a specified depth. + +### ignoreChainWithDepth + +Examples of **incorrect** code for this rule with the default `{ "ignoreChainWithDepth": 2 }` option: + +```js +/*eslint newline-per-chained-call: ["error", { "ignoreChainWithDepth": 2 }]*/ + +_.chain({}).map(foo).filter(bar).value(); + +// Or +_.chain({}).map(foo).filter(bar); + +// Or +_ + .chain({}).map(foo) + .filter(bar); + +// Or +obj.method().method2().method3(); +``` + +Examples of **correct** code for this rule with the default `{ "ignoreChainWithDepth": 2 }` option: + +```js +/*eslint newline-per-chained-call: ["error", { "ignoreChainWithDepth": 2 }]*/ + +_ + .chain({}) + .map(foo) + .filter(bar) + .value(); + +// Or +_ + .chain({}) + .map(foo) + .filter(bar); + +// Or +_.chain({}) + .map(foo) + .filter(bar); + +// Or +obj + .prop + .method().prop; + +// Or +obj + .prop.method() + .method2() + .method3().prop; +``` + +## When Not To Use It + +If you have conflicting rules or when you are fine with chained calls on one line, you can safely turn this rule off. + +## Version + +This rule was introduced in ESLint 2.0.0-rc.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/newline-per-chained-call.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/newline-per-chained-call.md) diff --git a/docs/8.0.0/rules/no-alert.md b/docs/8.0.0/rules/no-alert.md new file mode 100644 index 0000000000..4d97bf8956 --- /dev/null +++ b/docs/8.0.0/rules/no-alert.md @@ -0,0 +1,62 @@ +--- +title: no-alert - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-alert.md +rule_type: suggestion +--- + + +# Disallow Use of Alert (no-alert) + +JavaScript's `alert`, `confirm`, and `prompt` functions are widely considered to be obtrusive as UI elements and should be replaced by a more appropriate custom UI implementation. Furthermore, `alert` is often used while debugging code, which should be removed before deployment to production. + +```js +alert("here!"); +``` + +## Rule Details + +This rule is aimed at catching debugging code that should be removed and popup UI elements that should be replaced with less obtrusive, custom UIs. As such, it will warn when it encounters `alert`, `prompt`, and `confirm` function calls which are not shadowed. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-alert: "error"*/ + +alert("here!"); + +confirm("Are you sure?"); + +prompt("What's your name?", "John Doe"); +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-alert: "error"*/ + +customAlert("Something happened!"); + +customConfirm("Are you sure?"); + +customPrompt("Who are you?"); + +function foo() { + var alert = myCustomLib.customAlert; + alert(); +} +``` + +## Related Rules + +* [no-console](no-console) +* [no-debugger](no-debugger) + +## Version + +This rule was introduced in ESLint 0.0.5. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-alert.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-alert.md) diff --git a/docs/8.0.0/rules/no-array-constructor.md b/docs/8.0.0/rules/no-array-constructor.md new file mode 100644 index 0000000000..8272ae827a --- /dev/null +++ b/docs/8.0.0/rules/no-array-constructor.md @@ -0,0 +1,60 @@ +--- +title: no-array-constructor - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-array-constructor.md +rule_type: suggestion +--- + + +# disallow `Array` constructors (no-array-constructor) + +Use of the `Array` constructor to construct a new array is generally +discouraged in favor of array literal notation because of the single-argument +pitfall and because the `Array` global may be redefined. The exception is when +the Array constructor is used to intentionally create sparse arrays of a +specified size by giving the constructor a single numeric argument. + +## Rule Details + +This rule disallows `Array` constructors. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-array-constructor: "error"*/ + +Array(0, 1, 2) + +new Array(0, 1, 2) +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-array-constructor: "error"*/ + +Array(500) + +new Array(someOtherArray.length) + +[0, 1, 2] +``` + +## When Not To Use It + +This rule enforces a nearly universal stylistic concern. That being said, this +rule may be disabled if the constructor style is preferred. + +## Related Rules + +* [no-new-object](no-new-object) +* [no-new-wrappers](no-new-wrappers) + +## Version + +This rule was introduced in ESLint 0.4.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-array-constructor.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-array-constructor.md) diff --git a/docs/8.0.0/rules/no-arrow-condition.md b/docs/8.0.0/rules/no-arrow-condition.md new file mode 100644 index 0000000000..369b6e30c7 --- /dev/null +++ b/docs/8.0.0/rules/no-arrow-condition.md @@ -0,0 +1,64 @@ +--- +title: no-arrow-condition - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-arrow-condition.md + +--- + + +# no-arrow-condition: disallow arrow functions where test conditions are expected + +(removed) This rule was **removed** in ESLint v2.0 and **replaced** by a combination of the [no-confusing-arrow](no-confusing-arrow) and [no-constant-condition](no-constant-condition) rules. + +Arrow functions (`=>`) are similar in syntax to some comparison operators (`>`, `<`, `<=`, and `>=`). This rule warns against using the arrow function syntax in places where a condition is expected. Even if the arguments of the arrow function are wrapped with parens, this rule still warns about it. + +Here's an example where the usage of `=>` is most likely a typo: + +```js +// This is probably a typo +if (a => 1) {} +// And should instead be +if (a >= 1) {} +``` + +There are also cases where the usage of `=>` can be ambiguous and should be rewritten to more clearly show the author's intent: + +```js +// The intent is not clear +var x = a => 1 ? 2 : 3 +// Did the author mean this +var x = function (a) { return a >= 1 ? 2 : 3 } +// Or this +var x = a <= 1 ? 2 : 3 +``` + +## Rule Details + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-arrow-condition: "error"*/ +/*eslint-env es6*/ + +if (a => 1) {} +while (a => 1) {} +for (var a = 1; a => 10; a++) {} +a => 1 ? 2 : 3 +(a => 1) ? 2 : 3 +var x = a => 1 ? 2 : 3 +var x = (a) => 1 ? 2 : 3 +``` + +## Related Rules + +* [arrow-parens](arrow-parens) +* [no-confusing-arrow](no-confusing-arrow) +* [no-constant-condition](no-constant-condition) + +## Version + +This rule was introduced in ESLint 1.8.0 and removed in 2.0.0-beta.3. + +## Resources + +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-arrow-condition.md) diff --git a/docs/8.0.0/rules/no-async-promise-executor.md b/docs/8.0.0/rules/no-async-promise-executor.md new file mode 100644 index 0000000000..be059b897e --- /dev/null +++ b/docs/8.0.0/rules/no-async-promise-executor.md @@ -0,0 +1,81 @@ +--- +title: no-async-promise-executor - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-async-promise-executor.md +rule_type: problem +--- + + +# disallow using an async function as a Promise executor (no-async-promise-executor) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +The `new Promise` constructor accepts an *executor* function as an argument, which has `resolve` and `reject` parameters that can be used to control the state of the created Promise. For example: + +```js +const result = new Promise(function executor(resolve, reject) { + readFile('foo.txt', function(err, result) { + if (err) { + reject(err); + } else { + resolve(result); + } + }); +}); +``` + +The executor function can also be an `async function`. However, this is usually a mistake, for a few reasons: + +* If an async executor function throws an error, the error will be lost and won't cause the newly-constructed `Promise` to reject. This could make it difficult to debug and handle some errors. +* If a Promise executor function is using `await`, this is usually a sign that it is not actually necessary to use the `new Promise` constructor, or the scope of the `new Promise` constructor can be reduced. + +## Rule Details + +This rule aims to disallow async Promise executor functions. + +Examples of **incorrect** code for this rule: + +```js +const foo = new Promise(async (resolve, reject) => { + readFile('foo.txt', function(err, result) { + if (err) { + reject(err); + } else { + resolve(result); + } + }); +}); + +const result = new Promise(async (resolve, reject) => { + resolve(await foo); +}); +``` + +Examples of **correct** code for this rule: + +```js +const foo = new Promise((resolve, reject) => { + readFile('foo.txt', function(err, result) { + if (err) { + reject(err); + } else { + resolve(result); + } + }); +}); + +const result = Promise.resolve(foo); +``` + +## When Not To Use It + +If your codebase doesn't support async function syntax, there's no need to enable this rule. + +## Version + +This rule was introduced in ESLint 5.3.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-async-promise-executor.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-async-promise-executor.md) diff --git a/docs/8.0.0/rules/no-await-in-loop.md b/docs/8.0.0/rules/no-await-in-loop.md new file mode 100644 index 0000000000..beb92f8db2 --- /dev/null +++ b/docs/8.0.0/rules/no-await-in-loop.md @@ -0,0 +1,96 @@ +--- +title: no-await-in-loop - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-await-in-loop.md +rule_type: problem +--- + + +# Disallow `await` inside of loops (no-await-in-loop) + +Performing an operation on each element of an iterable is a common task. However, performing an +`await` as part of each operation is an indication that the program is not taking full advantage of +the parallelization benefits of `async`/`await`. + +Usually, the code should be refactored to create all the promises at once, then get access to the +results using `Promise.all()`. Otherwise, each successive operation will not start until the +previous one has completed. + +Concretely, the following function should be refactored as shown: + +```js +async function foo(things) { + const results = []; + for (const thing of things) { + // Bad: each loop iteration is delayed until the entire asynchronous operation completes + results.push(await bar(thing)); + } + return baz(results); +} +``` + +```js +async function foo(things) { + const results = []; + for (const thing of things) { + // Good: all asynchronous operations are immediately started. + results.push(bar(thing)); + } + // Now that all the asynchronous operations are running, here we wait until they all complete. + return baz(await Promise.all(results)); +} +``` + +## Rule Details + +This rule disallows the use of `await` within loop bodies. + +## Examples + +Examples of **correct** code for this rule: + +```js +/*eslint no-await-in-loop: "error"*/ + +async function foo(things) { + const results = []; + for (const thing of things) { + // Good: all asynchronous operations are immediately started. + results.push(bar(thing)); + } + // Now that all the asynchronous operations are running, here we wait until they all complete. + return baz(await Promise.all(results)); +} +``` + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-await-in-loop: "error"*/ + +async function foo(things) { + const results = []; + for (const thing of things) { + // Bad: each loop iteration is delayed until the entire asynchronous operation completes + results.push(await bar(thing)); + } + return baz(results); +} +``` + +## When Not To Use It + +In many cases the iterations of a loop are not actually independent of each-other. For example, the +output of one iteration might be used as the input to another. Or, loops may be used to retry +asynchronous operations that were unsuccessful. Or, loops may be used to prevent your code from sending +an excessive amount of requests in parallel. In such cases it makes sense to use `await` within a +loop and it is recommended to disable the rule via a standard ESLint disable comment. + +## Version + +This rule was introduced in ESLint 3.12.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-await-in-loop.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-await-in-loop.md) diff --git a/docs/8.0.0/rules/no-bitwise.md b/docs/8.0.0/rules/no-bitwise.md new file mode 100644 index 0000000000..85ccbfa481 --- /dev/null +++ b/docs/8.0.0/rules/no-bitwise.md @@ -0,0 +1,103 @@ +--- +title: no-bitwise - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-bitwise.md +rule_type: suggestion +--- + + +# disallow bitwise operators (no-bitwise) + +The use of bitwise operators in JavaScript is very rare and often `&` or `|` is simply a mistyped `&&` or `||`, which will lead to unexpected behavior. + +```js +var x = y | z; +``` + +## Rule Details + +This rule disallows bitwise operators. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-bitwise: "error"*/ + +var x = y | z; + +var x = y & z; + +var x = y ^ z; + +var x = ~ z; + +var x = y << z; + +var x = y >> z; + +var x = y >>> z; + +x |= y; + +x &= y; + +x ^= y; + +x <<= y; + +x >>= y; + +x >>>= y; +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-bitwise: "error"*/ + +var x = y || z; + +var x = y && z; + +var x = y > z; + +var x = y < z; + +x += y; +``` + +## Options + +This rule has an object option: + +* `"allow"`: Allows a list of bitwise operators to be used as exceptions. +* `"int32Hint"`: Allows the use of bitwise OR in `|0` pattern for type casting. + +### allow + +Examples of **correct** code for this rule with the `{ "allow": ["~"] }` option: + +```js +/*eslint no-bitwise: ["error", { "allow": ["~"] }] */ + +~[1,2,3].indexOf(1) === -1; +``` + +### int32Hint + +Examples of **correct** code for this rule with the `{ "int32Hint": true }` option: + +```js +/*eslint no-bitwise: ["error", { "int32Hint": true }] */ + +var b = a|0; +``` + +## Version + +This rule was introduced in ESLint 0.0.2. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-bitwise.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-bitwise.md) diff --git a/docs/8.0.0/rules/no-buffer-constructor.md b/docs/8.0.0/rules/no-buffer-constructor.md new file mode 100644 index 0000000000..f69d7512ef --- /dev/null +++ b/docs/8.0.0/rules/no-buffer-constructor.md @@ -0,0 +1,60 @@ +--- +title: no-buffer-constructor - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-buffer-constructor.md +rule_type: problem +--- + + +# disallow use of the Buffer() constructor (no-buffer-constructor) + +This rule was **deprecated** in ESLint v7.0.0. Please use the corresponding rule in [`eslint-plugin-node`](https://github.com/mysticatea/eslint-plugin-node). + +In Node.js, the behavior of the `Buffer` constructor is different depending on the type of its argument. Passing an argument from user input to `Buffer()` without validating its type can lead to security vulnerabilities such as remote memory disclosure and denial of service. As a result, the `Buffer` constructor has been deprecated and should not be used. Use the producer methods `Buffer.from`, `Buffer.alloc`, and `Buffer.allocUnsafe` instead. + +## Rule Details + +This rule disallows calling and constructing the `Buffer()` constructor. + +Examples of **incorrect** code for this rule: + +```js +new Buffer(5); +new Buffer([1, 2, 3]); + +Buffer(5); +Buffer([1, 2, 3]); + +new Buffer(res.body.amount); +new Buffer(res.body.values); +``` + +Examples of **correct** code for this rule: + +```js +Buffer.alloc(5); +Buffer.allocUnsafe(5); +Buffer.from([1, 2, 3]); + +Buffer.alloc(res.body.amount); +Buffer.from(res.body.values); +``` + +## When Not To Use It + +If you don't use Node.js, or you still need to support versions of Node.js that lack methods like `Buffer.from`, then you should not enable this rule. + +## Further Reading + +* [Buffer API documentation](https://nodejs.org/api/buffer.html) +* [Let's fix Node.js Buffer API](https://github.com/ChALkeR/notes/blob/master/Lets-fix-Buffer-API.md) +* [Buffer(number) is unsafe](https://github.com/nodejs/node/issues/4660) + +## Version + +This rule was introduced in ESLint 4.0.0-alpha.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-buffer-constructor.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-buffer-constructor.md) diff --git a/docs/8.0.0/rules/no-caller.md b/docs/8.0.0/rules/no-caller.md new file mode 100644 index 0000000000..77dd16c5b0 --- /dev/null +++ b/docs/8.0.0/rules/no-caller.md @@ -0,0 +1,66 @@ +--- +title: no-caller - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-caller.md +rule_type: suggestion +--- + + +# Disallow Use of caller/callee (no-caller) + +The use of `arguments.caller` and `arguments.callee` make several code optimizations impossible. They have been deprecated in future versions of JavaScript and their use is forbidden in ECMAScript 5 while in strict mode. + +```js +function foo() { + var callee = arguments.callee; +} +``` + +## Rule Details + +This rule is aimed at discouraging the use of deprecated and sub-optimal code by disallowing the use of `arguments.caller` and `arguments.callee`. As such, it will warn when `arguments.caller` and `arguments.callee` are used. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-caller: "error"*/ + +function foo(n) { + if (n <= 0) { + return; + } + + arguments.callee(n - 1); +} + +[1,2,3,4,5].map(function(n) { + return !(n > 1) ? 1 : arguments.callee(n - 1) * n; +}); +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-caller: "error"*/ + +function foo(n) { + if (n <= 0) { + return; + } + + foo(n - 1); +} + +[1,2,3,4,5].map(function factorial(n) { + return !(n > 1) ? 1 : factorial(n - 1) * n; +}); +``` + +## Version + +This rule was introduced in ESLint 0.0.6. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-caller.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-caller.md) diff --git a/docs/8.0.0/rules/no-case-declarations.md b/docs/8.0.0/rules/no-case-declarations.md new file mode 100644 index 0000000000..cb5a050e1c --- /dev/null +++ b/docs/8.0.0/rules/no-case-declarations.md @@ -0,0 +1,94 @@ +--- +title: no-case-declarations - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-case-declarations.md +rule_type: suggestion +--- + + +# Disallow lexical declarations in case/default clauses (no-case-declarations) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +This rule disallows lexical declarations (`let`, `const`, `function` and `class`) +in `case`/`default` clauses. The reason is that the lexical declaration is visible +in the entire switch block but it only gets initialized when it is assigned, which +will only happen if the case where it is defined is reached. + +To ensure that the lexical declaration only applies to the current case clause +wrap your clauses in blocks. + +## Rule Details + +This rule aims to prevent access to uninitialized lexical bindings as well as accessing hoisted functions across case clauses. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-case-declarations: "error"*/ +/*eslint-env es6*/ + +switch (foo) { + case 1: + let x = 1; + break; + case 2: + const y = 2; + break; + case 3: + function f() {} + break; + default: + class C {} +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-case-declarations: "error"*/ +/*eslint-env es6*/ + +// Declarations outside switch-statements are valid +const a = 0; + +switch (foo) { + // The following case clauses are wrapped into blocks using brackets + case 1: { + let x = 1; + break; + } + case 2: { + const y = 2; + break; + } + case 3: { + function f() {} + break; + } + case 4: + // Declarations using var without brackets are valid due to function-scope hoisting + var z = 4; + break; + default: { + class C {} + } +} +``` + +## When Not To Use It + +If you depend on fall through behavior and want access to bindings introduced in the case block. + +## Related Rules + +* [no-fallthrough](no-fallthrough) + +## Version + +This rule was introduced in ESLint 1.9.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-case-declarations.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-case-declarations.md) diff --git a/docs/8.0.0/rules/no-catch-shadow.md b/docs/8.0.0/rules/no-catch-shadow.md new file mode 100644 index 0000000000..ad75dd842c --- /dev/null +++ b/docs/8.0.0/rules/no-catch-shadow.md @@ -0,0 +1,90 @@ +--- +title: no-catch-shadow - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-catch-shadow.md +rule_type: suggestion +--- + + +# Disallow Shadowing of Variables Inside of catch (no-catch-shadow) + +This rule was **deprecated** in ESLint v5.1.0. + +In IE 8 and earlier, the catch clause parameter can overwrite the value of a variable in the outer scope, if that variable has the same name as the catch clause parameter. + +```js +var err = "x"; + +try { + throw "problem"; +} catch (err) { + +} + +console.log(err) // err is 'problem', not 'x' +``` + +## Rule Details + +This rule is aimed at preventing unexpected behavior in your program that may arise from a bug in IE 8 and earlier, in which the catch clause parameter can leak into outer scopes. This rule will warn whenever it encounters a catch clause parameter that has the same name as a variable in an outer scope. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-catch-shadow: "error"*/ + +var err = "x"; + +try { + throw "problem"; +} catch (err) { + +} + +function err() { + // ... +}; + +try { + throw "problem"; +} catch (err) { + +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-catch-shadow: "error"*/ + +var err = "x"; + +try { + throw "problem"; +} catch (e) { + +} + +function err() { + // ... +}; + +try { + throw "problem"; +} catch (e) { + +} +``` + +## When Not To Use It + +If you do not need to support IE 8 and earlier, you should turn this rule off. + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-catch-shadow.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-catch-shadow.md) diff --git a/docs/8.0.0/rules/no-class-assign.md b/docs/8.0.0/rules/no-class-assign.md new file mode 100644 index 0000000000..fb86da59c7 --- /dev/null +++ b/docs/8.0.0/rules/no-class-assign.md @@ -0,0 +1,112 @@ +--- +title: no-class-assign - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-class-assign.md +rule_type: problem +--- + + +# Disallow modifying variables of class declarations (no-class-assign) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +`ClassDeclaration` creates a variable, and we can modify the variable. + +```js +/*eslint-env es6*/ + +class A { } +A = 0; +``` + +But the modification is a mistake in most cases. + +## Rule Details + +This rule is aimed to flag modifying variables of class declarations. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-class-assign: "error"*/ +/*eslint-env es6*/ + +class A { } +A = 0; +``` + +```js +/*eslint no-class-assign: "error"*/ +/*eslint-env es6*/ + +A = 0; +class A { } +``` + +```js +/*eslint no-class-assign: "error"*/ +/*eslint-env es6*/ + +class A { + b() { + A = 0; + } +} +``` + +```js +/*eslint no-class-assign: "error"*/ +/*eslint-env es6*/ + +let A = class A { + b() { + A = 0; + // `let A` is shadowed by the class name. + } +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-class-assign: "error"*/ +/*eslint-env es6*/ + +let A = class A { } +A = 0; // A is a variable. +``` + +```js +/*eslint no-class-assign: "error"*/ +/*eslint-env es6*/ + +let A = class { + b() { + A = 0; // A is a variable. + } +} +``` + +```js +/*eslint no-class-assign: 2*/ +/*eslint-env es6*/ + +class A { + b(A) { + A = 0; // A is a parameter. + } +} +``` + +## When Not To Use It + +If you don't want to be notified about modifying variables of class declarations, you can safely disable this rule. + +## Version + +This rule was introduced in ESLint 1.0.0-rc-1. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-class-assign.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-class-assign.md) diff --git a/docs/8.0.0/rules/no-comma-dangle.md b/docs/8.0.0/rules/no-comma-dangle.md new file mode 100644 index 0000000000..c9475cf146 --- /dev/null +++ b/docs/8.0.0/rules/no-comma-dangle.md @@ -0,0 +1,68 @@ +--- +title: no-comma-dangle - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-comma-dangle.md + +--- + + +# no-comma-dangle: disallow trailing commas in object and array literals + +(removed) This rule was **removed** in ESLint v1.0 and **replaced** by the [comma-dangle](comma-dangle) rule. + +Trailing commas in object literals are valid according to the ECMAScript 5 (and ECMAScript 3!) spec, however IE8 (when not in IE8 document mode) and below will throw an error when it encounters trailing commas in JavaScript. + +```js +var foo = { + bar: "baz", + qux: "quux", +}; +``` + +## Rule Details + +This rule is aimed at detecting trailing commas in object literals. As such, it will warn whenever it encounters a trailing comma in an object literal. + +Examples of **incorrect** code for this rule: + +```js +var foo = { + bar: "baz", + qux: "quux", +}; + +var arr = [1,2,]; + +foo({ + bar: "baz", + qux: "quux", +}); +``` + +Examples of **correct** code for this rule: + +```js +var foo = { + bar: "baz", + qux: "quux" +}; + +var arr = [1,2]; + +foo({ + bar: "baz", + qux: "quux" +}); +``` + +## When Not To Use It + +If your code will not be run in IE8 or below (a Node.js application, for example) and you'd prefer to allow trailing commas, turn this rule off. + +## Version + +This rule was introduced in ESLint 0.0.9 and removed in 1.0.0-rc-1. + +## Resources + +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-comma-dangle.md) diff --git a/docs/8.0.0/rules/no-compare-neg-zero.md b/docs/8.0.0/rules/no-compare-neg-zero.md new file mode 100644 index 0000000000..30ec42d922 --- /dev/null +++ b/docs/8.0.0/rules/no-compare-neg-zero.md @@ -0,0 +1,54 @@ +--- +title: no-compare-neg-zero - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-compare-neg-zero.md +rule_type: problem +--- + + +# disallow comparing against -0 (no-compare-neg-zero) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +## Rule Details + +The rule should warn against code that tries to compare against -0, since that will not work as intended. That is, code like x === -0 will pass for both +0 and -0. The author probably intended Object.is(x, -0). + +Examples of **incorrect** code for this rule: + +```js +/* eslint no-compare-neg-zero: "error" */ + +if (x === -0) { + // doSomething()... +} +``` + +Examples of **correct** code for this rule: + +```js +/* eslint no-compare-neg-zero: "error" */ + +if (x === 0) { + // doSomething()... +} +``` + +```js +/* eslint no-compare-neg-zero: "error" */ + +if (Object.is(x, -0)) { + // doSomething()... +} +``` + + + +## Version + +This rule was introduced in ESLint 3.17.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-compare-neg-zero.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-compare-neg-zero.md) diff --git a/docs/8.0.0/rules/no-cond-assign.md b/docs/8.0.0/rules/no-cond-assign.md new file mode 100644 index 0000000000..b9104fb822 --- /dev/null +++ b/docs/8.0.0/rules/no-cond-assign.md @@ -0,0 +1,146 @@ +--- +title: no-cond-assign - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-cond-assign.md +rule_type: problem +--- + + +# disallow assignment operators in conditional statements (no-cond-assign) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +In conditional statements, it is very easy to mistype a comparison operator (such as `==`) as an assignment operator (such as `=`). For example: + +```js +// Check the user's job title +if (user.jobTitle = "manager") { + // user.jobTitle is now incorrect +} +``` + +There are valid reasons to use assignment operators in conditional statements. However, it can be difficult to tell whether a specific assignment was intentional. + +## Rule Details + +This rule disallows ambiguous assignment operators in test conditions of `if`, `for`, `while`, and `do...while` statements. + +## Options + +This rule has a string option: + +* `"except-parens"` (default) allows assignments in test conditions *only if* they are enclosed in parentheses (for example, to allow reassigning a variable in the test of a `while` or `do...while` loop) +* `"always"` disallows all assignments in test conditions + +### except-parens + +Examples of **incorrect** code for this rule with the default `"except-parens"` option: + +```js +/*eslint no-cond-assign: "error"*/ + +// Unintentional assignment +var x; +if (x = 0) { + var b = 1; +} + +// Practical example that is similar to an error +function setHeight(someNode) { + "use strict"; + do { + someNode.height = "100px"; + } while (someNode = someNode.parentNode); +} +``` + +Examples of **correct** code for this rule with the default `"except-parens"` option: + +```js +/*eslint no-cond-assign: "error"*/ + +// Assignment replaced by comparison +var x; +if (x === 0) { + var b = 1; +} + +// Practical example that wraps the assignment in parentheses +function setHeight(someNode) { + "use strict"; + do { + someNode.height = "100px"; + } while ((someNode = someNode.parentNode)); +} + +// Practical example that wraps the assignment and tests for 'null' +function setHeight(someNode) { + "use strict"; + do { + someNode.height = "100px"; + } while ((someNode = someNode.parentNode) !== null); +} +``` + +### always + +Examples of **incorrect** code for this rule with the `"always"` option: + +```js +/*eslint no-cond-assign: ["error", "always"]*/ + +// Unintentional assignment +var x; +if (x = 0) { + var b = 1; +} + +// Practical example that is similar to an error +function setHeight(someNode) { + "use strict"; + do { + someNode.height = "100px"; + } while (someNode = someNode.parentNode); +} + +// Practical example that wraps the assignment in parentheses +function setHeight(someNode) { + "use strict"; + do { + someNode.height = "100px"; + } while ((someNode = someNode.parentNode)); +} + +// Practical example that wraps the assignment and tests for 'null' +function setHeight(someNode) { + "use strict"; + do { + someNode.height = "100px"; + } while ((someNode = someNode.parentNode) !== null); +} +``` + +Examples of **correct** code for this rule with the `"always"` option: + +```js +/*eslint no-cond-assign: ["error", "always"]*/ + +// Assignment replaced by comparison +var x; +if (x === 0) { + var b = 1; +} +``` + +## Related Rules + +* [no-extra-parens](no-extra-parens) + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-cond-assign.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-cond-assign.md) diff --git a/docs/8.0.0/rules/no-confusing-arrow.md b/docs/8.0.0/rules/no-confusing-arrow.md new file mode 100644 index 0000000000..502ebe902b --- /dev/null +++ b/docs/8.0.0/rules/no-confusing-arrow.md @@ -0,0 +1,88 @@ +--- +title: no-confusing-arrow - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-confusing-arrow.md +rule_type: suggestion +--- + + +# Disallow arrow functions where they could be confused with comparisons (no-confusing-arrow) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +Arrow functions (`=>`) are similar in syntax to some comparison operators (`>`, `<`, `<=`, and `>=`). This rule warns against using the arrow function syntax in places where it could be confused with a comparison operator. + +Here's an example where the usage of `=>` could be confusing: + +```js +// The intent is not clear +var x = a => 1 ? 2 : 3; +// Did the author mean this +var x = function (a) { return 1 ? 2 : 3 }; +// Or this +var x = a <= 1 ? 2 : 3; +``` + +## Rule Details + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-confusing-arrow: "error"*/ +/*eslint-env es6*/ + +var x = a => 1 ? 2 : 3; +var x = (a) => 1 ? 2 : 3; +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-confusing-arrow: "error"*/ +/*eslint-env es6*/ + +var x = a => (1 ? 2 : 3); +var x = (a) => (1 ? 2 : 3); +var x = a => { return 1 ? 2 : 3; }; +var x = (a) => { return 1 ? 2 : 3; }; +``` + +## Options + +This rule accepts a single options argument with the following defaults: + +```json +{ + "rules": { + "no-confusing-arrow": ["error", {"allowParens": true}] + } +} +``` + +`allowParens` is a boolean setting that can be `true`(default) or `false`: + +1. `true` relaxes the rule and accepts parenthesis as a valid "confusion-preventing" syntax. +2. `false` warns even if the expression is wrapped in parenthesis + +Examples of **incorrect** code for this rule with the `{"allowParens": false}` option: + +```js +/*eslint no-confusing-arrow: ["error", {"allowParens": false}]*/ +/*eslint-env es6*/ +var x = a => (1 ? 2 : 3); +var x = (a) => (1 ? 2 : 3); +``` + +## Related Rules + +* [no-constant-condition](no-constant-condition) +* [arrow-parens](arrow-parens) + +## Version + +This rule was introduced in ESLint 2.0.0-alpha-2. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-confusing-arrow.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-confusing-arrow.md) diff --git a/docs/8.0.0/rules/no-console.md b/docs/8.0.0/rules/no-console.md new file mode 100644 index 0000000000..7a39e2838c --- /dev/null +++ b/docs/8.0.0/rules/no-console.md @@ -0,0 +1,114 @@ +--- +title: no-console - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-console.md +rule_type: suggestion +--- + + +# disallow the use of `console` (no-console) + +In JavaScript that is designed to be executed in the browser, it's considered a best practice to avoid using methods on `console`. Such messages are considered to be for debugging purposes and therefore not suitable to ship to the client. In general, calls using `console` should be stripped before being pushed to production. + +```js +console.log("Made it here."); +console.error("That shouldn't have happened."); +``` + +## Rule Details + +This rule disallows calls or assignments to methods of the `console` object. + +Examples of **incorrect** code for this rule: + +```js +/* eslint no-console: "error" */ + +console.log("Log a debug level message."); +console.warn("Log a warn level message."); +console.error("Log an error level message."); +console.log = foo(); +``` + +Examples of **correct** code for this rule: + +```js +/* eslint no-console: "error" */ + +// custom console +Console.log("Hello world!"); +``` + +## Options + +This rule has an object option for exceptions: + +* `"allow"` has an array of strings which are allowed methods of the `console` object + +Examples of additional **correct** code for this rule with a sample `{ "allow": ["warn", "error"] }` option: + +```js +/* eslint no-console: ["error", { allow: ["warn", "error"] }] */ + +console.warn("Log a warn level message."); +console.error("Log an error level message."); +``` + +## When Not To Use It + +If you're using Node.js, however, `console` is used to output information to the user and so is not strictly used for debugging purposes. If you are developing for Node.js then you most likely do not want this rule enabled. + +Another case where you might not use this rule is if you want to enforce console calls and not console overwrites. For example: + +```js +/* eslint no-console: ["error", { allow: ["warn"] }] */ +console.error = function (message) { + throw new Error(message); +}; +``` + +With the `no-console` rule in the above example, ESLint will report an error. For the above example, you can disable the rule: + +```js +// eslint-disable-next-line no-console +console.error = function (message) { + throw new Error(message); +}; + +// or + +console.error = function (message) { // eslint-disable-line no-console + throw new Error(message); +}; +``` + +However, you might not want to manually add `eslint-disable-next-line` or `eslint-disable-line`. You can achieve the effect of only receiving errors for console calls with the `no-restricted-syntax` rule: + +```json +{ + "rules": { + "no-console": "off", + "no-restricted-syntax": [ + "error", + { + "selector": "CallExpression[callee.object.name='console'][callee.property.name!=/^(log|warn|error|info|trace)$/]", + "message": "Unexpected property on console object was called" + } + ] + } +} +``` + +## Related Rules + +* [no-alert](no-alert) +* [no-debugger](no-debugger) + +## Version + +This rule was introduced in ESLint 0.0.2. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-console.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-console.md) diff --git a/docs/8.0.0/rules/no-const-assign.md b/docs/8.0.0/rules/no-const-assign.md new file mode 100644 index 0000000000..bde0ba6df7 --- /dev/null +++ b/docs/8.0.0/rules/no-const-assign.md @@ -0,0 +1,87 @@ +--- +title: no-const-assign - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-const-assign.md +rule_type: problem +--- + + +# Disallow modifying variables that are declared using `const` (no-const-assign) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +We cannot modify variables that are declared using `const` keyword. +It will raise a runtime error. + +Under non ES2015 environment, it might be ignored merely. + +## Rule Details + +This rule is aimed to flag modifying variables that are declared using `const` keyword. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-const-assign: "error"*/ +/*eslint-env es6*/ + +const a = 0; +a = 1; +``` + +```js +/*eslint no-const-assign: "error"*/ +/*eslint-env es6*/ + +const a = 0; +a += 1; +``` + +```js +/*eslint no-const-assign: "error"*/ +/*eslint-env es6*/ + +const a = 0; +++a; +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-const-assign: "error"*/ +/*eslint-env es6*/ + +const a = 0; +console.log(a); +``` + +```js +/*eslint no-const-assign: "error"*/ +/*eslint-env es6*/ + +for (const a in [1, 2, 3]) { // `a` is re-defined (not modified) on each loop step. + console.log(a); +} +``` + +```js +/*eslint no-const-assign: "error"*/ +/*eslint-env es6*/ + +for (const a of [1, 2, 3]) { // `a` is re-defined (not modified) on each loop step. + console.log(a); +} +``` + +## When Not To Use It + +If you don't want to be notified about modifying variables that are declared using `const` keyword, you can safely disable this rule. + +## Version + +This rule was introduced in ESLint 1.0.0-rc-1. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-const-assign.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-const-assign.md) diff --git a/docs/8.0.0/rules/no-constant-condition.md b/docs/8.0.0/rules/no-constant-condition.md new file mode 100644 index 0000000000..d893c48d60 --- /dev/null +++ b/docs/8.0.0/rules/no-constant-condition.md @@ -0,0 +1,128 @@ +--- +title: no-constant-condition - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-constant-condition.md +rule_type: problem +--- + + +# disallow constant expressions in conditions (no-constant-condition) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +A constant expression (for example, a literal) as a test condition might be a typo or development trigger for a specific behavior. For example, the following code looks as if it is not ready for production. + +```js +if (false) { + doSomethingUnfinished(); +} +``` + +## Rule Details + +This rule disallows constant expressions in the test condition of: + +* `if`, `for`, `while`, or `do...while` statement +* `?:` ternary expression + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-constant-condition: "error"*/ + +if (false) { + doSomethingUnfinished(); +} + +if (void x) { + doSomethingUnfinished(); +} + +if (x &&= false) { + doSomethingNever(); +} + +if (x ||= true) { + doSomethingAlways(); +} + +for (;-2;) { + doSomethingForever(); +} + +while (typeof x) { + doSomethingForever(); +} + +do { + doSomethingForever(); +} while (x = -1); + +var result = 0 ? a : b; +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-constant-condition: "error"*/ + +if (x === 0) { + doSomething(); +} + +for (;;) { + doSomethingForever(); +} + +while (typeof x === "undefined") { + doSomething(); +} + +do { + doSomething(); +} while (x); + +var result = x !== 0 ? a : b; +``` + +## Options + +### checkLoops + +Set to `true` by default. Setting this option to `false` allows constant expressions in loops. + +Examples of **correct** code for when `checkLoops` is `false`: + +```js +/*eslint no-constant-condition: ["error", { "checkLoops": false }]*/ + +while (true) { + doSomething(); + if (condition()) { + break; + } +}; + +for (;true;) { + doSomething(); + if (condition()) { + break; + } +}; + +do { + doSomething(); + if (condition()) { + break; + } +} while (true) +``` + +## Version + +This rule was introduced in ESLint 0.4.1. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-constant-condition.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-constant-condition.md) diff --git a/docs/8.0.0/rules/no-constructor-return.md b/docs/8.0.0/rules/no-constructor-return.md new file mode 100644 index 0000000000..f4aab6e1c3 --- /dev/null +++ b/docs/8.0.0/rules/no-constructor-return.md @@ -0,0 +1,67 @@ +--- +title: no-constructor-return - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-constructor-return.md +rule_type: problem +--- + + +# Disallow returning value in constructor (no-constructor-return) + +In JavaScript, returning a value in the constructor of a class may be a mistake. Forbidding this pattern prevents mistakes resulting from unfamiliarity with the language or a copy-paste error. + +## Rule Details + +This rule disallows return statements in the constructor of a class. Note that returning nothing with flow control is allowed. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-constructor-return: "error"*/ + +class A { + constructor(a) { + this.a = a; + return a; + } +} + +class B { + constructor(f) { + if (!f) { + return 'falsy'; + } + } +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-constructor-return: "error"*/ + +class C { + constructor(c) { + this.c = c; + } +} + +class D { + constructor(f) { + if (!f) { + return; // Flow control. + } + + f(); + } +} +``` + +## Version + +This rule was introduced in ESLint 6.7.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-constructor-return.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-constructor-return.md) diff --git a/docs/8.0.0/rules/no-continue.md b/docs/8.0.0/rules/no-continue.md new file mode 100644 index 0000000000..37a2f8174a --- /dev/null +++ b/docs/8.0.0/rules/no-continue.md @@ -0,0 +1,88 @@ +--- +title: no-continue - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-continue.md +rule_type: suggestion +--- + + +# disallow `continue` statements (no-continue) + +The `continue` statement terminates execution of the statements in the current iteration of the current or labeled loop, and continues execution of the loop with the next iteration. When used incorrectly it makes code less testable, less readable and less maintainable. Structured control flow statements such as `if` should be used instead. + +```js +var sum = 0, + i; + +for(i = 0; i < 10; i++) { + if(i >= 5) { + continue; + } + + a += i; +} +``` + +## Rule Details + +This rule disallows `continue` statements. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-continue: "error"*/ + +var sum = 0, + i; + +for(i = 0; i < 10; i++) { + if(i >= 5) { + continue; + } + + a += i; +} +``` + +```js +/*eslint no-continue: "error"*/ + +var sum = 0, + i; + +labeledLoop: for(i = 0; i < 10; i++) { + if(i >= 5) { + continue labeledLoop; + } + + a += i; +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-continue: "error"*/ + +var sum = 0, + i; + +for(i = 0; i < 10; i++) { + if(i < 5) { + a += i; + } +} +``` + +## Compatibility + +* **JSLint**: `continue` + +## Version + +This rule was introduced in ESLint 0.19.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-continue.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-continue.md) diff --git a/docs/8.0.0/rules/no-control-regex.md b/docs/8.0.0/rules/no-control-regex.md new file mode 100644 index 0000000000..64fcfe5099 --- /dev/null +++ b/docs/8.0.0/rules/no-control-regex.md @@ -0,0 +1,53 @@ +--- +title: no-control-regex - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-control-regex.md +rule_type: problem +--- + + +# disallow control characters in regular expressions (no-control-regex) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +Control characters are special, invisible characters in the ASCII range 0-31. These characters are rarely used in JavaScript strings so a regular expression containing these characters is most likely a mistake. + +## Rule Details + +This rule disallows control characters in regular expressions. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-control-regex: "error"*/ + +var pattern1 = /\x1f/; +var pattern2 = new RegExp("\x1f"); +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-control-regex: "error"*/ + +var pattern1 = /\x20/; +var pattern2 = new RegExp("\x20"); +``` + +## When Not To Use It + +If you need to use control character pattern matching, then you should turn this rule off. + +## Related Rules + +* [no-div-regex](no-div-regex) +* [no-regex-spaces](no-regex-spaces) + +## Version + +This rule was introduced in ESLint 0.1.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-control-regex.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-control-regex.md) diff --git a/docs/8.0.0/rules/no-debugger.md b/docs/8.0.0/rules/no-debugger.md new file mode 100644 index 0000000000..2d33b8d68b --- /dev/null +++ b/docs/8.0.0/rules/no-debugger.md @@ -0,0 +1,60 @@ +--- +title: no-debugger - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-debugger.md +rule_type: problem +--- + + +# disallow the use of `debugger` (no-debugger) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +The `debugger` statement is used to tell the executing JavaScript environment to stop execution and start up a debugger at the current point in the code. This has fallen out of favor as a good practice with the advent of modern debugging and development tools. Production code should definitely not contain `debugger`, as it will cause the browser to stop executing code and open an appropriate debugger. + +## Rule Details + +This rule disallows `debugger` statements. + +Example of **incorrect** code for this rule: + +```js +/*eslint no-debugger: "error"*/ + +function isTruthy(x) { + debugger; + return Boolean(x); +} +``` + +Example of **correct** code for this rule: + +```js +/*eslint no-debugger: "error"*/ + +function isTruthy(x) { + return Boolean(x); // set a breakpoint at this line +} +``` + +## When Not To Use It + +If your code is still very much in development and don't want to worry about stripping `debugger` statements, then turn this rule off. You'll generally want to turn it back on when testing code prior to deployment. + +## Further Reading + +* [Debugger](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/debugger) + +## Related Rules + +* [no-alert](no-alert) +* [no-console](no-console) + +## Version + +This rule was introduced in ESLint 0.0.2. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-debugger.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-debugger.md) diff --git a/docs/8.0.0/rules/no-delete-var.md b/docs/8.0.0/rules/no-delete-var.md new file mode 100644 index 0000000000..ea2f050182 --- /dev/null +++ b/docs/8.0.0/rules/no-delete-var.md @@ -0,0 +1,37 @@ +--- +title: no-delete-var - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-delete-var.md +rule_type: suggestion +--- + + +# disallow deleting variables (no-delete-var) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +The purpose of the `delete` operator is to remove a property from an object. Using the `delete` operator on a variable might lead to unexpected behavior. + +## Rule Details + +This rule disallows the use of the `delete` operator on variables. + +If ESLint parses code in strict mode, the parser (instead of this rule) reports the error. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-delete-var: "error"*/ + +var x; +delete x; +``` + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-delete-var.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-delete-var.md) diff --git a/docs/8.0.0/rules/no-div-regex.md b/docs/8.0.0/rules/no-div-regex.md new file mode 100644 index 0000000000..82f3d0f5e9 --- /dev/null +++ b/docs/8.0.0/rules/no-div-regex.md @@ -0,0 +1,51 @@ +--- +title: no-div-regex - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-div-regex.md +rule_type: suggestion +--- + + +# Disallow Regular Expressions That Look Like Division (no-div-regex) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +Require regex literals to escape division operators. + +```js +function bar() { return /=foo/; } +``` + +## Rule Details + +This is used to disambiguate the division operator to not confuse users. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-div-regex: "error"*/ + +function bar() { return /=foo/; } +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-div-regex: "error"*/ + +function bar() { return /[=]foo/; } +``` + +## Related Rules + +* [no-control-regex](no-control-regex) +* [no-regex-spaces](no-regex-spaces) + +## Version + +This rule was introduced in ESLint 0.1.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-div-regex.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-div-regex.md) diff --git a/docs/8.0.0/rules/no-dupe-args.md b/docs/8.0.0/rules/no-dupe-args.md new file mode 100644 index 0000000000..e6047038cb --- /dev/null +++ b/docs/8.0.0/rules/no-dupe-args.md @@ -0,0 +1,56 @@ +--- +title: no-dupe-args - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-dupe-args.md +rule_type: problem +--- + + +# disallow duplicate arguments in `function` definitions (no-dupe-args) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +If more than one parameter has the same name in a function definition, the last occurrence "shadows" the preceding occurrences. A duplicated name might be a typing error. + +## Rule Details + +This rule disallows duplicate parameter names in function declarations or expressions. It does not apply to arrow functions or class methods, because the parser reports the error. + +If ESLint parses code in strict mode, the parser (instead of this rule) reports the error. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-dupe-args: "error"*/ + +function foo(a, b, a) { + console.log("value of the second a:", a); +} + +var bar = function (a, b, a) { + console.log("value of the second a:", a); +}; +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-dupe-args: "error"*/ + +function foo(a, b, c) { + console.log(a, b, c); +} + +var bar = function (a, b, c) { + console.log(a, b, c); +}; +``` + +## Version + +This rule was introduced in ESLint 0.16.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-dupe-args.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-dupe-args.md) diff --git a/docs/8.0.0/rules/no-dupe-class-members.md b/docs/8.0.0/rules/no-dupe-class-members.md new file mode 100644 index 0000000000..899bc1f03f --- /dev/null +++ b/docs/8.0.0/rules/no-dupe-class-members.md @@ -0,0 +1,93 @@ +--- +title: no-dupe-class-members - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-dupe-class-members.md +rule_type: problem +--- + + +# Disallow duplicate name in class members (no-dupe-class-members) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +If there are declarations of the same name in class members, the last declaration overwrites other declarations silently. +It can cause unexpected behaviors. + +```js +/*eslint-env es6*/ + +class Foo { + bar() { console.log("hello"); } + bar() { console.log("goodbye"); } +} + +var foo = new Foo(); +foo.bar(); // goodbye +``` + +## Rule Details + +This rule is aimed to flag the use of duplicate names in class members. + +## Examples + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-dupe-class-members: "error"*/ +/*eslint-env es6*/ + +class Foo { + bar() { } + bar() { } +} + +class Foo { + bar() { } + get bar() { } +} + +class Foo { + static bar() { } + static bar() { } +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-dupe-class-members: "error"*/ +/*eslint-env es6*/ + +class Foo { + bar() { } + qux() { } +} + +class Foo { + get bar() { } + set bar(value) { } +} + +class Foo { + static bar() { } + bar() { } +} +``` + +## When Not To Use It + +This rule should not be used in ES3/5 environments. + +In ES2015 (ES6) or later, if you don't want to be notified about duplicate names in class members, you can safely disable this rule. + +It's also safe to disable this rule when using TypeScript because TypeScript's compiler already checks for duplicate function implementations. + +## Version + +This rule was introduced in ESLint 1.2.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-dupe-class-members.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-dupe-class-members.md) diff --git a/docs/8.0.0/rules/no-dupe-else-if.md b/docs/8.0.0/rules/no-dupe-else-if.md new file mode 100644 index 0000000000..1c5b305a43 --- /dev/null +++ b/docs/8.0.0/rules/no-dupe-else-if.md @@ -0,0 +1,197 @@ +--- +title: no-dupe-else-if - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-dupe-else-if.md +rule_type: problem +--- + + +# Disallow duplicate conditions in `if-else-if` chains (no-dupe-else-if) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +`if-else-if` chains are commonly used when there is a need to execute only one branch (or at most one branch) out of several possible branches, based on certain conditions. + +```js +if (a) { + foo(); +} else if (b) { + bar(); +} else if (c) { + baz(); +} +``` + +Two identical test conditions in the same chain are almost always a mistake in the code. Unless there are side effects in the expressions, a duplicate will evaluate to the same `true` or `false` value as the identical expression earlier in the chain, meaning that its branch can never execute. + +```js +if (a) { + foo(); +} else if (b) { + bar(); +} else if (b) { + baz(); +} +``` + +In the above example, `baz()` can never execute. Obviously, `baz()` could be executed only when `b` evaluates to `true`, but in that case `bar()` would be executed instead, since it's earlier in the chain. + +## Rule Details + +This rule disallows duplicate conditions in the same `if-else-if` chain. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-dupe-else-if: "error"*/ + +if (isSomething(x)) { + foo(); +} else if (isSomething(x)) { + bar(); +} + +if (a) { + foo(); +} else if (b) { + bar(); +} else if (c && d) { + baz(); +} else if (c && d) { + quux(); +} else { + quuux(); +} + +if (n === 1) { + foo(); +} else if (n === 2) { + bar(); +} else if (n === 3) { + baz(); +} else if (n === 2) { + quux(); +} else if (n === 5) { + quuux(); +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-dupe-else-if: "error"*/ + +if (isSomething(x)) { + foo(); +} else if (isSomethingElse(x)) { + bar(); +} + +if (a) { + foo(); +} else if (b) { + bar(); +} else if (c && d) { + baz(); +} else if (c && e) { + quux(); +} else { + quuux(); +} + +if (n === 1) { + foo(); +} else if (n === 2) { + bar(); +} else if (n === 3) { + baz(); +} else if (n === 4) { + quux(); +} else if (n === 5) { + quuux(); +} +``` + +This rule can also detect some cases where the conditions are not identical, but the branch can never execute due to the logic of `||` and `&&` operators. + +Examples of additional **incorrect** code for this rule: + +```js +/*eslint no-dupe-else-if: "error"*/ + +if (a || b) { + foo(); +} else if (a) { + bar(); +} + +if (a) { + foo(); +} else if (b) { + bar(); +} else if (a || b) { + baz(); +} + +if (a) { + foo(); +} else if (a && b) { + bar(); +} + +if (a && b) { + foo(); +} else if (a && b && c) { + bar(); +} + +if (a || b) { + foo(); +} else if (b && c) { + bar(); +} + +if (a) { + foo(); +} else if (b && c) { + bar(); +} else if (d && (c && e && b || a)) { + baz(); +} +``` + +Please note that this rule does not compare conditions from the chain with conditions inside statements, and will not warn in the cases such as follows: + +```js +if (a) { + if (a) { + foo(); + } +} + +if (a) { + foo(); +} else { + if (a) { + bar(); + } +} +``` + +## When Not To Use It + +In rare cases where you really need identical test conditions in the same chain, which necessarily means that the expressions in the chain are causing and relying on side effects, you will have to turn this rule off. + +## Related Rules + +* [no-duplicate-case](no-duplicate-case) +* [no-lonely-if](no-lonely-if) + +## Version + +This rule was introduced in ESLint 6.7.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-dupe-else-if.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-dupe-else-if.md) diff --git a/docs/8.0.0/rules/no-dupe-keys.md b/docs/8.0.0/rules/no-dupe-keys.md new file mode 100644 index 0000000000..7a3e95e824 --- /dev/null +++ b/docs/8.0.0/rules/no-dupe-keys.md @@ -0,0 +1,65 @@ +--- +title: no-dupe-keys - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-dupe-keys.md +rule_type: problem +--- + + +# disallow duplicate keys in object literals (no-dupe-keys) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +Multiple properties with the same key in object literals can cause unexpected behavior in your application. + +```js +var foo = { + bar: "baz", + bar: "qux" +}; +``` + +## Rule Details + +This rule disallows duplicate keys in object literals. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-dupe-keys: "error"*/ + +var foo = { + bar: "baz", + bar: "qux" +}; + +var foo = { + "bar": "baz", + bar: "qux" +}; + +var foo = { + 0x1: "baz", + 1: "qux" +}; +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-dupe-keys: "error"*/ + +var foo = { + bar: "baz", + quxx: "qux" +}; +``` + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-dupe-keys.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-dupe-keys.md) diff --git a/docs/8.0.0/rules/no-duplicate-case.md b/docs/8.0.0/rules/no-duplicate-case.md new file mode 100644 index 0000000000..f16b675904 --- /dev/null +++ b/docs/8.0.0/rules/no-duplicate-case.md @@ -0,0 +1,110 @@ +--- +title: no-duplicate-case - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-duplicate-case.md +rule_type: problem +--- + + +# Rule to disallow a duplicate case label (no-duplicate-case) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +If a `switch` statement has duplicate test expressions in `case` clauses, it is likely that a programmer copied a `case` clause but forgot to change the test expression. + +## Rule Details + +This rule disallows duplicate test expressions in `case` clauses of `switch` statements. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-duplicate-case: "error"*/ + +var a = 1, + one = 1; + +switch (a) { + case 1: + break; + case 2: + break; + case 1: // duplicate test expression + break; + default: + break; +} + +switch (a) { + case one: + break; + case 2: + break; + case one: // duplicate test expression + break; + default: + break; +} + +switch (a) { + case "1": + break; + case "2": + break; + case "1": // duplicate test expression + break; + default: + break; +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-duplicate-case: "error"*/ + +var a = 1, + one = 1; + +switch (a) { + case 1: + break; + case 2: + break; + case 3: + break; + default: + break; +} + +switch (a) { + case one: + break; + case 2: + break; + case 3: + break; + default: + break; +} + +switch (a) { + case "1": + break; + case "2": + break; + case "3": + break; + default: + break; +} +``` + +## Version + +This rule was introduced in ESLint 0.17.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-duplicate-case.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-duplicate-case.md) diff --git a/docs/8.0.0/rules/no-duplicate-imports.md b/docs/8.0.0/rules/no-duplicate-imports.md new file mode 100644 index 0000000000..31d108933d --- /dev/null +++ b/docs/8.0.0/rules/no-duplicate-imports.md @@ -0,0 +1,101 @@ +--- +title: no-duplicate-imports - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-duplicate-imports.md +rule_type: problem +--- + + +# Disallow duplicate imports (no-duplicate-imports) + +Using a single `import` statement per module will make the code clearer because you can see everything being imported from that module on one line. + +In the following example the `module` import on line 1 is repeated on line 3. These can be combined to make the list of imports more succinct. + +```js +import { merge } from 'module'; +import something from 'another-module'; +import { find } from 'module'; +``` + +## Rule Details + +This rule requires that all imports from a single module that can be merged exist in a single `import` statement. + +Example of **incorrect** code for this rule: + +```js +/*eslint no-duplicate-imports: "error"*/ + +import { merge } from 'module'; +import something from 'another-module'; +import { find } from 'module'; +``` + +Example of **correct** code for this rule: + +```js +/*eslint no-duplicate-imports: "error"*/ + +import { merge, find } from 'module'; +import something from 'another-module'; +``` + +Example of **correct** code for this rule: + +```js +/*eslint no-duplicate-imports: "error"*/ + +// not mergeable +import { merge } from 'module'; +import * as something from 'module'; +``` + +## Options + +This rule takes one optional argument, an object with a single key, `includeExports` which is a `boolean`. It defaults to `false`. + +If re-exporting from an imported module, you should add the imports to the `import`-statement, and export that directly, not use `export ... from`. + +Example of **incorrect** code for this rule with the `{ "includeExports": true }` option: + +```js +/*eslint no-duplicate-imports: ["error", { "includeExports": true }]*/ + +import { merge } from 'module'; + +export { find } from 'module'; +``` + +Example of **correct** code for this rule with the `{ "includeExports": true }` option: + +```js +/*eslint no-duplicate-imports: ["error", { "includeExports": true }]*/ + +import { merge, find } from 'module'; + +export { find }; +``` + +Example of **correct** code for this rule with the `{ "includeExports": true }` option: + +```js +/*eslint no-duplicate-imports: ["error", { "includeExports": true }]*/ + +import { merge, find } from 'module'; + +// cannot be merged with the above import +export * as something from 'module'; + +// cannot be written differently +export * from 'module'; +``` + +## Version + +This rule was introduced in ESLint 2.5.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-duplicate-imports.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-duplicate-imports.md) diff --git a/docs/8.0.0/rules/no-else-return.md b/docs/8.0.0/rules/no-else-return.md new file mode 100644 index 0000000000..8317041d38 --- /dev/null +++ b/docs/8.0.0/rules/no-else-return.md @@ -0,0 +1,176 @@ +--- +title: no-else-return - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-else-return.md +rule_type: suggestion +--- + + +# Disallow return before else (no-else-return) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +If an `if` block contains a `return` statement, the `else` block becomes unnecessary. Its contents can be placed outside of the block. + +```js +function foo() { + if (x) { + return y; + } else { + return z; + } +} +``` + +## Rule Details + +This rule is aimed at highlighting an unnecessary block of code following an `if` containing a return statement. As such, it will warn when it encounters an `else` following a chain of `if`s, all of them containing a `return` statement. + +## Options + +This rule has an object option: + +* `allowElseIf: true` (default) allows `else if` blocks after a return +* `allowElseIf: false` disallows `else if` blocks after a return + +### `allowElseIf: true` + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-else-return: "error"*/ + +function foo() { + if (x) { + return y; + } else { + return z; + } +} + +function foo() { + if (x) { + return y; + } else if (z) { + return w; + } else { + return t; + } +} + +function foo() { + if (x) { + return y; + } else { + var t = "foo"; + } + + return t; +} + +function foo() { + if (error) { + return 'It failed'; + } else { + if (loading) { + return "It's still loading"; + } + } +} + +// Two warnings for nested occurrences +function foo() { + if (x) { + if (y) { + return y; + } else { + return x; + } + } else { + return z; + } +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-else-return: "error"*/ + +function foo() { + if (x) { + return y; + } + + return z; +} + +function foo() { + if (x) { + return y; + } else if (z) { + var t = "foo"; + } else { + return w; + } +} + +function foo() { + if (x) { + if (z) { + return y; + } + } else { + return z; + } +} + +function foo() { + if (error) { + return 'It failed'; + } else if (loading) { + return "It's still loading"; + } +} +``` + +### `allowElseIf: false` + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-else-return: ["error", {allowElseIf: false}]*/ + +function foo() { + if (error) { + return 'It failed'; + } else if (loading) { + return "It's still loading"; + } +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-else-return: ["error", {allowElseIf: false}]*/ + +function foo() { + if (error) { + return 'It failed'; + } + + if (loading) { + return "It's still loading"; + } +} +``` + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-else-return.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-else-return.md) diff --git a/docs/8.0.0/rules/no-empty-character-class.md b/docs/8.0.0/rules/no-empty-character-class.md new file mode 100644 index 0000000000..296ad29cbf --- /dev/null +++ b/docs/8.0.0/rules/no-empty-character-class.md @@ -0,0 +1,63 @@ +--- +title: no-empty-character-class - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-empty-character-class.md +rule_type: problem +--- + + +# disallow empty character classes in regular expressions (no-empty-character-class) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +Because empty character classes in regular expressions do not match anything, they might be typing mistakes. + +```js +var foo = /^abc[]/; +``` + +## Rule Details + +This rule disallows empty character classes in regular expressions. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-empty-character-class: "error"*/ + +/^abc[]/.test("abcdefg"); // false +"abcdefg".match(/^abc[]/); // null +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-empty-character-class: "error"*/ + +/^abc/.test("abcdefg"); // true +"abcdefg".match(/^abc/); // ["abc"] + +/^abc[a-z]/.test("abcdefg"); // true +"abcdefg".match(/^abc[a-z]/); // ["abcd"] +``` + +## Known Limitations + +This rule does not report empty character classes in the string argument of calls to the `RegExp` constructor. + +Example of a *false negative* when this rule reports correct code: + +```js +/*eslint no-empty-character-class: "error"*/ + +var abcNeverMatches = new RegExp("^abc[]"); +``` + +## Version + +This rule was introduced in ESLint 0.22.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-empty-character-class.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-empty-character-class.md) diff --git a/docs/8.0.0/rules/no-empty-class.md b/docs/8.0.0/rules/no-empty-class.md new file mode 100644 index 0000000000..44d0ea0d51 --- /dev/null +++ b/docs/8.0.0/rules/no-empty-class.md @@ -0,0 +1,49 @@ +--- +title: no-empty-class - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-empty-class.md + +--- + + +# no-empty-class: disallow empty character classes in regular expressions + +(removed) This rule was **removed** in ESLint v1.0 and **replaced** by the [no-empty-character-class](no-empty-character-class) rule. + +Empty character classes in regular expressions do not match anything and can result in code that may not work as intended. + +```js +var foo = /^abc[]/; +``` + +## Rule Details + +This rule is aimed at highlighting possible typos and unexpected behavior in regular expressions which may arise from the use of empty character classes. + +Examples of **incorrect** code for this rule: + +```js +var foo = /^abc[]/; + +/^abc[]/.test(foo); + +bar.match(/^abc[]/); +``` + +Examples of **correct** code for this rule: + +```js +var foo = /^abc/; + +var foo = /^abc[a-z]/; + +var bar = new RegExp("^abc[]"); +``` + +## Version + +This rule was introduced in ESLint 0.0.9 and removed in 1.0.0-rc-1. + +## Resources + +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-empty-class.md) diff --git a/docs/8.0.0/rules/no-empty-function.md b/docs/8.0.0/rules/no-empty-function.md new file mode 100644 index 0000000000..4b49b84010 --- /dev/null +++ b/docs/8.0.0/rules/no-empty-function.md @@ -0,0 +1,364 @@ +--- +title: no-empty-function - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-empty-function.md +rule_type: suggestion +--- + + +# Disallow empty functions (no-empty-function) + +Empty functions can reduce readability because readers need to guess whether it's intentional or not. +So writing a clear comment for empty functions is a good practice. + +```js +function foo() { + // do nothing. +} +``` + +Especially, the empty block of arrow functions might be confusing developers. +It's very similar to an empty object literal. + +```js +list.map(() => {}); // This is a block, would return undefined. +list.map(() => ({})); // This is an empty object. +``` + +## Rule Details + +This rule is aimed at eliminating empty functions. +A function will not be considered a problem if it contains a comment. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-empty-function: "error"*/ +/*eslint-env es6*/ + +function foo() {} + +var foo = function() {}; + +var foo = () => {}; + +function* foo() {} + +var foo = function*() {}; + +var obj = { + foo: function() {}, + + foo: function*() {}, + + foo() {}, + + *foo() {}, + + get foo() {}, + + set foo(value) {} +}; + +class A { + constructor() {} + + foo() {} + + *foo() {} + + get foo() {} + + set foo(value) {} + + static foo() {} + + static *foo() {} + + static get foo() {} + + static set foo(value) {} +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-empty-function: "error"*/ +/*eslint-env es6*/ + +function foo() { + // do nothing. +} + +var foo = function() { + // any clear comments. +}; + +var foo = () => { + bar(); +}; + +function* foo() { + // do nothing. +} + +var foo = function*() { + // do nothing. +}; + +var obj = { + foo: function() { + // do nothing. + }, + + foo: function*() { + // do nothing. + }, + + foo() { + // do nothing. + }, + + *foo() { + // do nothing. + }, + + get foo() { + // do nothing. + }, + + set foo(value) { + // do nothing. + } +}; + +class A { + constructor() { + // do nothing. + } + + foo() { + // do nothing. + } + + *foo() { + // do nothing. + } + + get foo() { + // do nothing. + } + + set foo(value) { + // do nothing. + } + + static foo() { + // do nothing. + } + + static *foo() { + // do nothing. + } + + static get foo() { + // do nothing. + } + + static set foo(value) { + // do nothing. + } +} +``` + +## Options + +This rule has an option to allow specific kinds of functions to be empty. + +* `allow` (`string[]`) - A list of kind to allow empty functions. List items are some of the following strings. An empty array (`[]`) by default. + * `"functions"` - Normal functions. + * `"arrowFunctions"` - Arrow functions. + * `"generatorFunctions"` - Generator functions. + * `"methods"` - Class methods and method shorthands of object literals. + * `"generatorMethods"` - Class methods and method shorthands of object literals with generator. + * `"getters"` - Getters. + * `"setters"` - Setters. + * `"constructors"` - Class constructors. + * `"asyncFunctions"` - Async functions. + * `"asyncMethods"` - Async class methods and method shorthands of object literals. + +#### allow: functions + +Examples of **correct** code for the `{ "allow": ["functions"] }` option: + +```js +/*eslint no-empty-function: ["error", { "allow": ["functions"] }]*/ + +function foo() {} + +var foo = function() {}; + +var obj = { + foo: function() {} +}; +``` + +#### allow: arrowFunctions + +Examples of **correct** code for the `{ "allow": ["arrowFunctions"] }` option: + +```js +/*eslint no-empty-function: ["error", { "allow": ["arrowFunctions"] }]*/ +/*eslint-env es6*/ + +var foo = () => {}; +``` + +#### allow: generatorFunctions + +Examples of **correct** code for the `{ "allow": ["generatorFunctions"] }` option: + +```js +/*eslint no-empty-function: ["error", { "allow": ["generatorFunctions"] }]*/ +/*eslint-env es6*/ + +function* foo() {} + +var foo = function*() {}; + +var obj = { + foo: function*() {} +}; +``` + +#### allow: methods + +Examples of **correct** code for the `{ "allow": ["methods"] }` option: + +```js +/*eslint no-empty-function: ["error", { "allow": ["methods"] }]*/ +/*eslint-env es6*/ + +var obj = { + foo() {} +}; + +class A { + foo() {} + static foo() {} +} +``` + +#### allow: generatorMethods + +Examples of **correct** code for the `{ "allow": ["generatorMethods"] }` option: + +```js +/*eslint no-empty-function: ["error", { "allow": ["generatorMethods"] }]*/ +/*eslint-env es6*/ + +var obj = { + *foo() {} +}; + +class A { + *foo() {} + static *foo() {} +} +``` + +#### allow: getters + +Examples of **correct** code for the `{ "allow": ["getters"] }` option: + +```js +/*eslint no-empty-function: ["error", { "allow": ["getters"] }]*/ +/*eslint-env es6*/ + +var obj = { + get foo() {} +}; + +class A { + get foo() {} + static get foo() {} +} +``` + +#### allow: setters + +Examples of **correct** code for the `{ "allow": ["setters"] }` option: + +```js +/*eslint no-empty-function: ["error", { "allow": ["setters"] }]*/ +/*eslint-env es6*/ + +var obj = { + set foo(value) {} +}; + +class A { + set foo(value) {} + static set foo(value) {} +} +``` + +#### allow: constructors + +Examples of **correct** code for the `{ "allow": ["constructors"] }` option: + +```js +/*eslint no-empty-function: ["error", { "allow": ["constructors"] }]*/ +/*eslint-env es6*/ + +class A { + constructor() {} +} +``` + +#### allow: asyncFunctions + +Examples of **correct** code for the `{ "allow": ["asyncFunctions"] }` options: + +```js +/*eslint no-empty-function: ["error", { "allow": ["asyncFunctions"] }]*/ +/*eslint-env es2017*/ + +async function a(){} +``` + +#### allow: asyncMethods + +Examples of **correct** code for the `{ "allow": ["asyncMethods"] }` options: + +```js +/*eslint no-empty-function: ["error", { "allow": ["asyncMethods"] }]*/ +/*eslint-env es2017*/ + +var obj = { + async foo() {} +}; + +class A { + async foo() {} + static async foo() {} +} +``` + +## When Not To Use It + +If you don't want to be notified about empty functions, then it's safe to disable this rule. + +## Related Rules + +* [no-empty](./no-empty) + +## Version + +This rule was introduced in ESLint 2.0.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-empty-function.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-empty-function.md) diff --git a/docs/8.0.0/rules/no-empty-label.md b/docs/8.0.0/rules/no-empty-label.md new file mode 100644 index 0000000000..061f810fb7 --- /dev/null +++ b/docs/8.0.0/rules/no-empty-label.md @@ -0,0 +1,56 @@ +--- +title: no-empty-label - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-empty-label.md + +--- + + +# no-empty-label: disallow labels for anything other than loops and switches + +(removed) This rule was **removed** in ESLint v2.0 and **replaced** by the [no-labels](no-labels) rule. + +Labeled statements are only used in conjunction with labeled break and continue statements. ECMAScript has no goto statement. + + +## Rule Details + +This error occurs when a label is used to mark a statement that is not an iteration or switch + +Example of **incorrect** code for this rule: + +```js +/*eslint no-empty-label: "error"*/ + +labeled: +var x = 10; +``` + +Example of **correct** code for this rule: + +```js +/*eslint no-empty-label: "error"*/ + +labeled: +for (var i=10; i; i--) { + // ... +} +``` + +## When Not To Use It + +If you don't want to be notified about usage of labels, then it's safe to disable this rule. + +## Related Rules + +* [no-labels](./no-labels) +* [no-label-var](./no-label-var) +* [no-unused-labels](./no-unused-labels) + +## Version + +This rule was introduced in ESLint 0.0.9 and removed in 2.0.0-rc.0. + +## Resources + +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-empty-label.md) diff --git a/docs/8.0.0/rules/no-empty-pattern.md b/docs/8.0.0/rules/no-empty-pattern.md new file mode 100644 index 0000000000..309d255991 --- /dev/null +++ b/docs/8.0.0/rules/no-empty-pattern.md @@ -0,0 +1,73 @@ +--- +title: no-empty-pattern - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-empty-pattern.md +rule_type: problem +--- + + +# Disallow empty destructuring patterns (no-empty-pattern) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +When using destructuring, it's possible to create a pattern that has no effect. This happens when empty curly braces are used to the right of an embedded object destructuring pattern, such as: + +```js +// doesn't create any variables +var {a: {}} = foo; +``` + +In this code, no new variables are created because `a` is just a location helper while the `{}` is expected to contain the variables to create, such as: + +```js +// creates variable b +var {a: { b }} = foo; +``` + +In many cases, the empty object pattern is a mistake where the author intended to use a default value instead, such as: + +```js +// creates variable a +var {a = {}} = foo; +``` + +The difference between these two patterns is subtle, especially because the problematic empty pattern looks just like an object literal. + +## Rule Details + +This rule aims to flag any empty patterns in destructured objects and arrays, and as such, will report a problem whenever one is encountered. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-empty-pattern: "error"*/ + +var {} = foo; +var [] = foo; +var {a: {}} = foo; +var {a: []} = foo; +function foo({}) {} +function foo([]) {} +function foo({a: {}}) {} +function foo({a: []}) {} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-empty-pattern: "error"*/ + +var {a = {}} = foo; +var {a = []} = foo; +function foo({a = {}}) {} +function foo({a = []}) {} +``` + +## Version + +This rule was introduced in ESLint 1.7.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-empty-pattern.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-empty-pattern.md) diff --git a/docs/8.0.0/rules/no-empty.md b/docs/8.0.0/rules/no-empty.md new file mode 100644 index 0000000000..f364675e01 --- /dev/null +++ b/docs/8.0.0/rules/no-empty.md @@ -0,0 +1,108 @@ +--- +title: no-empty - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-empty.md +rule_type: suggestion +--- + + +# disallow empty block statements (no-empty) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +Empty block statements, while not technically errors, usually occur due to refactoring that wasn't completed. They can cause confusion when reading code. + +## Rule Details + +This rule disallows empty block statements. This rule ignores block statements which contain a comment (for example, in an empty `catch` or `finally` block of a `try` statement to indicate that execution should continue regardless of errors). + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-empty: "error"*/ + +if (foo) { +} + +while (foo) { +} + +switch(foo) { +} + +try { + doSomething(); +} catch(ex) { + +} finally { + +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-empty: "error"*/ + +if (foo) { + // empty +} + +while (foo) { + /* empty */ +} + +try { + doSomething(); +} catch (ex) { + // continue regardless of error +} + +try { + doSomething(); +} finally { + /* continue regardless of error */ +} +``` + +## Options + +This rule has an object option for exceptions: + +* `"allowEmptyCatch": true` allows empty `catch` clauses (that is, which do not contain a comment) + +### allowEmptyCatch + +Examples of additional **correct** code for this rule with the `{ "allowEmptyCatch": true }` option: + +```js +/* eslint no-empty: ["error", { "allowEmptyCatch": true }] */ +try { + doSomething(); +} catch (ex) {} + +try { + doSomething(); +} +catch (ex) {} +finally { + /* continue regardless of error */ +} +``` + +## When Not To Use It + +If you intentionally use empty block statements then you can disable this rule. + +## Related Rules + +* [no-empty-function](./no-empty-function) + +## Version + +This rule was introduced in ESLint 0.0.2. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-empty.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-empty.md) diff --git a/docs/8.0.0/rules/no-eq-null.md b/docs/8.0.0/rules/no-eq-null.md new file mode 100644 index 0000000000..4d0c86de9a --- /dev/null +++ b/docs/8.0.0/rules/no-eq-null.md @@ -0,0 +1,66 @@ +--- +title: no-eq-null - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-eq-null.md +rule_type: suggestion +--- + + +# Disallow Null Comparisons (no-eq-null) + +Comparing to `null` without a type-checking operator (`==` or `!=`), can have unintended results as the comparison will evaluate to true when comparing to not just a `null`, but also an `undefined` value. + +```js +if (foo == null) { + bar(); +} +``` + +## Rule Details + +The `no-eq-null` rule aims reduce potential bug and unwanted behavior by ensuring that comparisons to `null` only match `null`, and not also `undefined`. As such it will flag comparisons to null when using `==` and `!=`. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-eq-null: "error"*/ + +if (foo == null) { + bar(); +} + +while (qux != null) { + baz(); +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-eq-null: "error"*/ + +if (foo === null) { + bar(); +} + +while (qux !== null) { + baz(); +} +``` + +## Compatibility + +* **JSHint**: This rule corresponds to `eqnull` rule of JSHint. + +## When Not To Use It + +If you want to enforce type-checking operations in general, use the more powerful [eqeqeq](./eqeqeq) instead. + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-eq-null.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-eq-null.md) diff --git a/docs/8.0.0/rules/no-eval.md b/docs/8.0.0/rules/no-eval.md new file mode 100644 index 0000000000..a76c17a7da --- /dev/null +++ b/docs/8.0.0/rules/no-eval.md @@ -0,0 +1,164 @@ +--- +title: no-eval - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-eval.md +rule_type: suggestion +--- + + +# Disallow eval() (no-eval) + +JavaScript's `eval()` function is potentially dangerous and is often misused. Using `eval()` on untrusted code can open a program up to several different injection attacks. The use of `eval()` in most contexts can be substituted for a better, alternative approach to a problem. + +```js +var obj = { x: "foo" }, + key = "x", + value = eval("obj." + key); +``` + +## Rule Details + +This rule is aimed at preventing potentially dangerous, unnecessary, and slow code by disallowing the use of the `eval()` function. As such, it will warn whenever the `eval()` function is used. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-eval: "error"*/ + +var obj = { x: "foo" }, + key = "x", + value = eval("obj." + key); + +(0, eval)("var a = 0"); + +var foo = eval; +foo("var a = 0"); + +// This `this` is the global object. +this.eval("var a = 0"); +``` + +Example of additional **incorrect** code for this rule when `browser` environment is set to `true`: + +```js +/*eslint no-eval: "error"*/ +/*eslint-env browser*/ + +window.eval("var a = 0"); +``` + +Example of additional **incorrect** code for this rule when `node` environment is set to `true`: + +```js +/*eslint no-eval: "error"*/ +/*eslint-env node*/ + +global.eval("var a = 0"); +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-eval: "error"*/ +/*eslint-env es6*/ + +var obj = { x: "foo" }, + key = "x", + value = obj[key]; + +class A { + foo() { + // This is a user-defined method. + this.eval("var a = 0"); + } + + eval() { + } +} +``` + +## Options + +This rule has an option to allow indirect calls to `eval`. +Indirect calls to `eval` are less dangerous than direct calls to `eval` because they cannot dynamically change the scope. Because of this, they also will not negatively impact performance to the degree of direct `eval`. + +```js +{ + "no-eval": ["error", {"allowIndirect": true}] // default is false +} +``` + +Example of **incorrect** code for this rule with the `{"allowIndirect": true}` option: + +```js +/*eslint no-eval: "error"*/ + +var obj = { x: "foo" }, + key = "x", + value = eval("obj." + key); +``` + +Examples of **correct** code for this rule with the `{"allowIndirect": true}` option: + +```js +/*eslint no-eval: "error"*/ + +(0, eval)("var a = 0"); + +var foo = eval; +foo("var a = 0"); + +this.eval("var a = 0"); +``` + +```js +/*eslint no-eval: "error"*/ +/*eslint-env browser*/ + +window.eval("var a = 0"); +``` + +```js +/*eslint no-eval: "error"*/ +/*eslint-env node*/ + +global.eval("var a = 0"); +``` + +## Known Limitations + +* This rule is warning every `eval()` even if the `eval` is not global's. + This behavior is in order to detect calls of direct `eval`. Such as: + + ```js + module.exports = function(eval) { + // If the value of this `eval` is built-in `eval` function, this is a + // call of direct `eval`. + eval("var a = 0"); + }; + ``` + +* This rule cannot catch renaming the global object. Such as: + + ```js + var foo = window; + foo.eval("var a = 0"); + ``` + +## Further Reading + +* [Eval is Evil, Part One](https://blogs.msdn.com/b/ericlippert/archive/2003/11/01/53329.aspx) +* [How evil is eval](https://javascriptweblog.wordpress.com/2010/04/19/how-evil-is-eval/) + +## Related Rules + +* [no-implied-eval](no-implied-eval) + +## Version + +This rule was introduced in ESLint 0.0.2. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-eval.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-eval.md) diff --git a/docs/8.0.0/rules/no-ex-assign.md b/docs/8.0.0/rules/no-ex-assign.md new file mode 100644 index 0000000000..837bebfb04 --- /dev/null +++ b/docs/8.0.0/rules/no-ex-assign.md @@ -0,0 +1,55 @@ +--- +title: no-ex-assign - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-ex-assign.md +rule_type: problem +--- + + +# disallow reassigning exceptions in `catch` clauses (no-ex-assign) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +If a `catch` clause in a `try` statement accidentally (or purposely) assigns another value to the exception parameter, it impossible to refer to the error from that point on. +Since there is no `arguments` object to offer alternative access to this data, assignment of the parameter is absolutely destructive. + +## Rule Details + +This rule disallows reassigning exceptions in `catch` clauses. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-ex-assign: "error"*/ + +try { + // code +} catch (e) { + e = 10; +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-ex-assign: "error"*/ + +try { + // code +} catch (e) { + var foo = 10; +} +``` + +## Further Reading + +* [The "catch" with try...catch](https://bocoup.com/blog/the-catch-with-try-catch) by Ben Alman explains how the exception identifier can leak into the outer scope in IE 6-8 + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-ex-assign.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-ex-assign.md) diff --git a/docs/8.0.0/rules/no-extend-native.md b/docs/8.0.0/rules/no-extend-native.md new file mode 100644 index 0000000000..896318a222 --- /dev/null +++ b/docs/8.0.0/rules/no-extend-native.md @@ -0,0 +1,92 @@ +--- +title: no-extend-native - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-extend-native.md +rule_type: suggestion +--- + + +# Disallow Extending of Native Objects (no-extend-native) + +In JavaScript, you can extend any object, including builtin or "native" objects. Sometimes people change the behavior of these native objects in ways that break the assumptions made about them in other parts of the code. + +For example here we are overriding a builtin method that will then affect all Objects, even other builtins. + +```js +// seems harmless +Object.prototype.extra = 55; + +// loop through some userIds +var users = { + "123": "Stan", + "456": "David" +}; + +// not what you'd expect +for (var id in users) { + console.log(id); // "123", "456", "extra" +} +``` + +A common suggestion to avoid this problem would be to wrap the inside of the `for` loop with `users.hasOwnProperty(id)`. However, if this rule is strictly enforced throughout your codebase you won't need to take that step. + +## Rule Details + +Disallows directly modifying the prototype of builtin objects. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-extend-native: "error"*/ + +Object.prototype.a = "a"; +Object.defineProperty(Array.prototype, "times", { value: 999 }); +``` + +## Options + +This rule accepts an `exceptions` option, which can be used to specify a list of builtins for which extensions will be allowed. + +### exceptions + +Examples of **correct** code for the sample `{ "exceptions": ["Object"] }` option: + +```js +/*eslint no-extend-native: ["error", { "exceptions": ["Object"] }]*/ + +Object.prototype.a = "a"; +``` + +## Known Limitations + +This rule *does not* report any of the following less obvious approaches to modify the prototype of builtin objects: + +```js +var x = Object; +x.prototype.thing = a; + +eval("Array.prototype.forEach = 'muhahaha'"); + +with(Array) { + prototype.thing = 'thing'; +}; + +window.Function.prototype.bind = 'tight'; +``` + +## When Not To Use It + +You may want to disable this rule when working with polyfills that try to patch older versions of JavaScript with the latest spec, such as those that might `Function.prototype.bind` or `Array.prototype.forEach` in a future-friendly way. + +## Related Rules + +* [no-global-assign](no-global-assign) + +## Version + +This rule was introduced in ESLint 0.1.4. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-extend-native.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-extend-native.md) diff --git a/docs/8.0.0/rules/no-extra-bind.md b/docs/8.0.0/rules/no-extra-bind.md new file mode 100644 index 0000000000..36a375e9b9 --- /dev/null +++ b/docs/8.0.0/rules/no-extra-bind.md @@ -0,0 +1,105 @@ +--- +title: no-extra-bind - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-extra-bind.md +rule_type: suggestion +--- + + +# Disallow unnecessary function binding (no-extra-bind) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +The `bind()` method is used to create functions with specific `this` values and, optionally, binds arguments to specific values. When used to specify the value of `this`, it's important that the function actually uses `this` in its function body. For example: + +```js +var boundGetName = (function getName() { + return this.name; +}).bind({ name: "ESLint" }); + +console.log(boundGetName()); // "ESLint" +``` + +This code is an example of a good use of `bind()` for setting the value of `this`. + +Sometimes during the course of code maintenance, the `this` value is removed from the function body. In that case, you can end up with a call to `bind()` that doesn't accomplish anything: + +```js +// useless bind +var boundGetName = (function getName() { + return "ESLint"; +}).bind({ name: "ESLint" }); + +console.log(boundGetName()); // "ESLint" +``` + +In this code, the reference to `this` has been removed but `bind()` is still used. In this case, the `bind()` is unnecessary overhead (and a performance hit) and can be safely removed. + +## Rule Details + +This rule is aimed at avoiding the unnecessary use of `bind()` and as such will warn whenever an immediately-invoked function expression (IIFE) is using `bind()` and doesn't have an appropriate `this` value. This rule won't flag usage of `bind()` that includes function argument binding. + +**Note:** Arrow functions can never have their `this` value set using `bind()`. This rule flags all uses of `bind()` with arrow functions as a problem + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-extra-bind: "error"*/ +/*eslint-env es6*/ + +var x = function () { + foo(); +}.bind(bar); + +var x = (() => { + foo(); +}).bind(bar); + +var x = (() => { + this.foo(); +}).bind(bar); + +var x = function () { + (function () { + this.foo(); + }()); +}.bind(bar); + +var x = function () { + function foo() { + this.bar(); + } +}.bind(baz); +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-extra-bind: "error"*/ + +var x = function () { + this.foo(); +}.bind(bar); + +var x = function (a) { + return a + 1; +}.bind(foo, bar); +``` + +## When Not To Use It + +If you are not concerned about unnecessary calls to `bind()`, you can safely disable this rule. + +## Further Reading + +* [Function.prototype.bind](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) +* [Understanding JavaScript's Function.prototype.bind](https://www.smashingmagazine.com/2014/01/understanding-javascript-function-prototype-bind/) + +## Version + +This rule was introduced in ESLint 0.8.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-extra-bind.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-extra-bind.md) diff --git a/docs/8.0.0/rules/no-extra-boolean-cast.md b/docs/8.0.0/rules/no-extra-boolean-cast.md new file mode 100644 index 0000000000..3c69abbc6d --- /dev/null +++ b/docs/8.0.0/rules/no-extra-boolean-cast.md @@ -0,0 +1,145 @@ +--- +title: no-extra-boolean-cast - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-extra-boolean-cast.md +rule_type: suggestion +--- + + +# disallow unnecessary boolean casts (no-extra-boolean-cast) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +In contexts such as an `if` statement's test where the result of the expression will already be coerced to a Boolean, casting to a Boolean via double negation (`!!`) or a `Boolean` call is unnecessary. For example, these `if` statements are equivalent: + +```js +if (!!foo) { + // ... +} + +if (Boolean(foo)) { + // ... +} + +if (foo) { + // ... +} +``` + +## Rule Details + +This rule disallows unnecessary boolean casts. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-extra-boolean-cast: "error"*/ + +var foo = !!!bar; + +var foo = !!bar ? baz : bat; + +var foo = Boolean(!!bar); + +var foo = new Boolean(!!bar); + +if (!!foo) { + // ... +} + +if (Boolean(foo)) { + // ... +} + +while (!!foo) { + // ... +} + +do { + // ... +} while (Boolean(foo)); + +for (; !!foo; ) { + // ... +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-extra-boolean-cast: "error"*/ + +var foo = !!bar; +var foo = Boolean(bar); + +function foo() { + return !!bar; +} + +var foo = bar ? !!baz : !!bat; +``` + +## Options + +This rule has an object option: + +* `"enforceForLogicalOperands"` when set to `true`, in addition to checking default contexts, checks whether the extra boolean cast is contained within a logical expression. Default is `false`, meaning that this rule by default does not warn about extra booleans cast inside logical expression. + +### enforceForLogicalOperands + +Examples of **incorrect** code for this rule with `"enforceForLogicalOperands"` option set to `true`: + +```js +/*eslint no-extra-boolean-cast: ["error", {"enforceForLogicalOperands": true}]*/ + +if (!!foo || bar) { + //... +} + +while (!!foo && bar) { + //... +} + +if ((!!foo || bar) && baz) { + //... +} + +foo && Boolean(bar) ? baz : bat + +var foo = new Boolean(!!bar || baz) +``` + +Examples of **correct** code for this rule with `"enforceForLogicalOperands"` option set to `true`: + +```js +/*eslint no-extra-boolean-cast: ["error", {"enforceForLogicalOperands": true}]*/ + +if (foo || bar) { + //... +} + +while (foo && bar) { + //... +} + +if ((foo || bar) && baz) { + //... +} + +foo && bar ? baz : bat + +var foo = new Boolean(bar || baz) + +var foo = !!bar || baz; +``` + +## Version + +This rule was introduced in ESLint 0.4.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-extra-boolean-cast.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-extra-boolean-cast.md) diff --git a/docs/8.0.0/rules/no-extra-label.md b/docs/8.0.0/rules/no-extra-label.md new file mode 100644 index 0000000000..c81cac2dbd --- /dev/null +++ b/docs/8.0.0/rules/no-extra-label.md @@ -0,0 +1,101 @@ +--- +title: no-extra-label - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-extra-label.md +rule_type: suggestion +--- + + +# Disallow Unnecessary Labels (no-extra-label) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +If a loop contains no nested loops or switches, labeling the loop is unnecessary. + +```js +A: while (a) { + break A; +} +``` + +You can achieve the same result by removing the label and using `break` or `continue` without a label. +Probably those labels would confuse developers because they expect labels to jump to further. + +## Rule Details + +This rule is aimed at eliminating unnecessary labels. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-extra-label: "error"*/ + +A: while (a) { + break A; +} + +B: for (let i = 0; i < 10; ++i) { + break B; +} + +C: switch (a) { + case 0: + break C; +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-extra-label: "error"*/ + +while (a) { + break; +} + +for (let i = 0; i < 10; ++i) { + break; +} + +switch (a) { + case 0: + break; +} + +A: { + break A; +} + +B: while (a) { + while (b) { + break B; + } +} + +C: switch (a) { + case 0: + while (b) { + break C; + } + break; +} +``` + +## When Not To Use It + +If you don't want to be notified about usage of labels, then it's safe to disable this rule. + +## Related Rules + +* [no-labels](./no-labels) +* [no-label-var](./no-label-var) +* [no-unused-labels](./no-unused-labels) + +## Version + +This rule was introduced in ESLint 2.0.0-rc.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-extra-label.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-extra-label.md) diff --git a/docs/8.0.0/rules/no-extra-parens.md b/docs/8.0.0/rules/no-extra-parens.md new file mode 100644 index 0000000000..8c615ff76c --- /dev/null +++ b/docs/8.0.0/rules/no-extra-parens.md @@ -0,0 +1,319 @@ +--- +title: no-extra-parens - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-extra-parens.md +rule_type: layout +--- + + +# disallow unnecessary parentheses (no-extra-parens) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +This rule restricts the use of parentheses to only where they are necessary. + +## Rule Details + +This rule always ignores extra parentheses around the following: + +* RegExp literals such as `(/abc/).test(var)` to avoid conflicts with the [wrap-regex](wrap-regex) rule +* immediately-invoked function expressions (also known as IIFEs) such as `var x = (function () {})();` and `var x = (function () {}());` to avoid conflicts with the [wrap-iife](wrap-iife) rule +* arrow function arguments to avoid conflicts with the [arrow-parens](arrow-parens) rule + +## Options + +This rule has a string option: + +* `"all"` (default) disallows unnecessary parentheses around *any* expression +* `"functions"` disallows unnecessary parentheses *only* around function expressions + +This rule has an object option for exceptions to the `"all"` option: + +* `"conditionalAssign": false` allows extra parentheses around assignments in conditional test expressions +* `"returnAssign": false` allows extra parentheses around assignments in `return` statements +* `"nestedBinaryExpressions": false` allows extra parentheses in nested binary expressions +* `"ignoreJSX": "none|all|multi-line|single-line"` allows extra parentheses around no/all/multi-line/single-line JSX components. Defaults to `none`. +* `"enforceForArrowConditionals": false` allows extra parentheses around ternary expressions which are the body of an arrow function +* `"enforceForSequenceExpressions": false` allows extra parentheses around sequence expressions +* `"enforceForNewInMemberExpressions": false` allows extra parentheses around `new` expressions in member expressions +* `"enforceForFunctionPrototypeMethods": false` allows extra parentheses around immediate `.call` and `.apply` method calls on function expressions and around function expressions in the same context. + +### all + +Examples of **incorrect** code for this rule with the default `"all"` option: + +```js +/* eslint no-extra-parens: "error" */ + +a = (b * c); + +(a * b) + c; + +for (a in (b, c)); + +for (a in (b)); + +for (a of (b)); + +typeof (a); + +(function(){} ? a() : b()); + +class A { + [(x)] = 1; +} + +class B { + x = (y + z); +} +``` + +Examples of **correct** code for this rule with the default `"all"` option: + +```js +/* eslint no-extra-parens: "error" */ + +(0).toString(); + +(Object.prototype.toString.call()); + +({}.toString.call()); + +(function(){}) ? a() : b(); + +(/^a$/).test(x); + +for (a of (b, c)); + +for (a of b); + +for (a in b, c); + +for (a in b); + +class A { + [x] = 1; +} + +class B { + x = y + z; +} +``` + +### conditionalAssign + +Examples of **correct** code for this rule with the `"all"` and `{ "conditionalAssign": false }` options: + +```js +/* eslint no-extra-parens: ["error", "all", { "conditionalAssign": false }] */ + +while ((foo = bar())) {} + +if ((foo = bar())) {} + +do; while ((foo = bar())) + +for (;(a = b);); +``` + +### returnAssign + +Examples of **correct** code for this rule with the `"all"` and `{ "returnAssign": false }` options: + +```js +/* eslint no-extra-parens: ["error", "all", { "returnAssign": false }] */ + +function a(b) { + return (b = 1); +} + +function a(b) { + return b ? (c = d) : (c = e); +} + +b => (b = 1); + +b => b ? (c = d) : (c = e); +``` + +### nestedBinaryExpressions + +Examples of **correct** code for this rule with the `"all"` and `{ "nestedBinaryExpressions": false }` options: + +```js +/* eslint no-extra-parens: ["error", "all", { "nestedBinaryExpressions": false }] */ + +x = a || (b && c); +x = a + (b * c); +x = (a * b) / c; +``` + +### ignoreJSX + +Examples of **correct** code for this rule with the `all` and `{ "ignoreJSX": "all" }` options: + +```js +/* eslint no-extra-parens: ["error", "all", { ignoreJSX: "all" }] */ +const Component = (
    ) +const Component = ( +
    +) +``` + +Examples of **incorrect** code for this rule with the `all` and `{ "ignoreJSX": "multi-line" }` options: + +```js +/* eslint no-extra-parens: ["error", "all", { ignoreJSX: "multi-line" }] */ +const Component = (
    ) +const Component = (

    ) +``` + +Examples of **correct** code for this rule with the `all` and `{ "ignoreJSX": "multi-line" }` options: + +```js +/* eslint no-extra-parens: ["error", "all", { ignoreJSX: "multi-line" }] */ +const Component = ( +
    +

    +

    +) +const Component = ( +
    +) +``` + +Examples of **incorrect** code for this rule with the `all` and `{ "ignoreJSX": "single-line" }` options: + +```js +/* eslint no-extra-parens: ["error", "all", { ignoreJSX: "single-line" }] */ +const Component = ( +
    +

    +

    +) +const Component = ( +
    +) +``` + +Examples of **correct** code for this rule with the `all` and `{ "ignoreJSX": "single-line" }` options: + +```js +/* eslint no-extra-parens: ["error", "all", { ignoreJSX: "single-line" }] */ +const Component = (
    ) +const Component = (

    ) +``` + +### enforceForArrowConditionals + +Examples of **correct** code for this rule with the `"all"` and `{ "enforceForArrowConditionals": false }` options: + +```js +/* eslint no-extra-parens: ["error", "all", { "enforceForArrowConditionals": false }] */ + +const b = a => 1 ? 2 : 3; +const d = c => (1 ? 2 : 3); +``` + +### enforceForSequenceExpressions + +Examples of **correct** code for this rule with the `"all"` and `{ "enforceForSequenceExpressions": false }` options: + +```js +/* eslint no-extra-parens: ["error", "all", { "enforceForSequenceExpressions": false }] */ + +(a, b); + +if ((val = foo(), val < 10)) {} + +while ((val = foo(), val < 10)); +``` + +### enforceForNewInMemberExpressions + +Examples of **correct** code for this rule with the `"all"` and `{ "enforceForNewInMemberExpressions": false }` options: + +```js +/* eslint no-extra-parens: ["error", "all", { "enforceForNewInMemberExpressions": false }] */ + +const foo = (new Bar()).baz; + +const quux = (new Bar())[baz]; + +(new Bar()).doSomething(); +``` + +### enforceForFunctionPrototypeMethods + +Examples of **correct** code for this rule with the `"all"` and `{ "enforceForFunctionPrototypeMethods": false }` options: + +```js +/* eslint no-extra-parens: ["error", "all", { "enforceForFunctionPrototypeMethods": false }] */ + +const foo = (function () {}).call(); + +const bar = (function () {}).apply(); + +const baz = (function () {}.call()); + +const quux = (function () {}.apply()); +``` + +### functions + +Examples of **incorrect** code for this rule with the `"functions"` option: + +```js +/* eslint no-extra-parens: ["error", "functions"] */ + +((function foo() {}))(); + +var y = (function () {return 1;}); +``` + +Examples of **correct** code for this rule with the `"functions"` option: + +```js +/* eslint no-extra-parens: ["error", "functions"] */ + +(0).toString(); + +(Object.prototype.toString.call()); + +({}.toString.call()); + +(function(){} ? a() : b()); + +(/^a$/).test(x); + +a = (b * c); + +(a * b) + c; + +typeof (a); +``` + +## Further Reading + +* [MDN: Operator Precedence](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence) + +## Related Rules + +* [arrow-parens](arrow-parens) +* [no-cond-assign](no-cond-assign) +* [no-return-assign](no-return-assign) + +## Version + +This rule was introduced in ESLint 0.1.4. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-extra-parens.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-extra-parens.md) diff --git a/docs/8.0.0/rules/no-extra-semi.md b/docs/8.0.0/rules/no-extra-semi.md new file mode 100644 index 0000000000..975950a18d --- /dev/null +++ b/docs/8.0.0/rules/no-extra-semi.md @@ -0,0 +1,63 @@ +--- +title: no-extra-semi - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-extra-semi.md +rule_type: suggestion +--- + + +# disallow unnecessary semicolons (no-extra-semi) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +Typing mistakes and misunderstandings about where semicolons are required can lead to semicolons that are unnecessary. While not technically an error, extra semicolons can cause confusion when reading code. + +## Rule Details + +This rule disallows unnecessary semicolons. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-extra-semi: "error"*/ + +var x = 5;; + +function foo() { + // code +}; + +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-extra-semi: "error"*/ + +var x = 5; + +var foo = function() { + // code +}; + +``` + +## When Not To Use It + +If you intentionally use extra semicolons then you can disable this rule. + +## Related Rules + +* [semi](semi) +* [semi-spacing](semi-spacing) + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-extra-semi.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-extra-semi.md) diff --git a/docs/8.0.0/rules/no-extra-strict.md b/docs/8.0.0/rules/no-extra-strict.md new file mode 100644 index 0000000000..ea1e5079e3 --- /dev/null +++ b/docs/8.0.0/rules/no-extra-strict.md @@ -0,0 +1,66 @@ +--- +title: no-extra-strict - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-extra-strict.md + +--- + + +# no-extra-strict: disallow strict mode directives when already in strict mode + +(removed) This rule was **removed** in ESLint v1.0 and **replaced** by the [strict](strict) rule. The `"global"` or `"function"` options in the new rule are similar to the removed rule. + +The `"use strict";` directive applies to the scope in which it appears and all inner scopes contained within that scope. Therefore, using the `"use strict";` directive in one of these inner scopes is unnecessary. + +```js +"use strict"; + +(function () { + "use strict"; + var foo = true; +}()); +``` + +## Rule Details + +This rule is aimed at preventing unnecessary `"use strict";` directives. As such, it will warn when it encounters a `"use strict";` directive when already in strict mode. + +Example of **incorrect** code for this rule: + +```js +"use strict"; + +(function () { + "use strict"; + var foo = true; +}()); +``` + +Examples of **correct** code for this rule: + +```js +"use strict"; + +(function () { + var foo = true; +}()); +``` + +```js +(function () { + "use strict"; + var foo = true; +}()); +``` + +## Further Reading + +* [The ECMAScript 5 Annotated Specification - Strict Mode](https://es5.github.io/#C) + +## Version + +This rule was introduced in ESLint 0.3.0 and removed in 1.0.0-rc-1. + +## Resources + +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-extra-strict.md) diff --git a/docs/8.0.0/rules/no-fallthrough.md b/docs/8.0.0/rules/no-fallthrough.md new file mode 100644 index 0000000000..f095647cb1 --- /dev/null +++ b/docs/8.0.0/rules/no-fallthrough.md @@ -0,0 +1,210 @@ +--- +title: no-fallthrough - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-fallthrough.md +rule_type: problem +--- + + +# Disallow Case Statement Fallthrough (no-fallthrough) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +The `switch` statement in JavaScript is one of the more error-prone constructs of the language thanks in part to the ability to "fall through" from one `case` to the next. For example: + +```js +switch(foo) { + case 1: + doSomething(); + + case 2: + doSomethingElse(); +} +``` + +In this example, if `foo` is `1`, then execution will flow through both cases, as the first falls through to the second. You can prevent this by using `break`, as in this example: + +```js +switch(foo) { + case 1: + doSomething(); + break; + + case 2: + doSomethingElse(); +} +``` + +That works fine when you don't want a fallthrough, but what if the fallthrough is intentional, there is no way to indicate that in the language. It's considered a best practice to always indicate when a fallthrough is intentional using a comment which matches the `/falls?\s?through/i` regular expression: + +```js +switch(foo) { + case 1: + doSomething(); + // falls through + + case 2: + doSomethingElse(); +} + +switch(foo) { + case 1: + doSomething(); + // fall through + + case 2: + doSomethingElse(); +} + +switch(foo) { + case 1: + doSomething(); + // fallsthrough + + case 2: + doSomethingElse(); +} + +switch(foo) { + case 1: { + doSomething(); + // falls through + } + + case 2: { + doSomethingElse(); + } +} +``` + +In this example, there is no confusion as to the expected behavior. It is clear that the first case is meant to fall through to the second case. + +## Rule Details + +This rule is aimed at eliminating unintentional fallthrough of one case to the other. As such, it flags any fallthrough scenarios that are not marked by a comment. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-fallthrough: "error"*/ + +switch(foo) { + case 1: + doSomething(); + + case 2: + doSomething(); +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-fallthrough: "error"*/ + +switch(foo) { + case 1: + doSomething(); + break; + + case 2: + doSomething(); +} + +function bar(foo) { + switch(foo) { + case 1: + doSomething(); + return; + + case 2: + doSomething(); + } +} + +switch(foo) { + case 1: + doSomething(); + throw new Error("Boo!"); + + case 2: + doSomething(); +} + +switch(foo) { + case 1: + case 2: + doSomething(); +} + +switch(foo) { + case 1: + doSomething(); + // falls through + + case 2: + doSomething(); +} + +switch(foo) { + case 1: { + doSomething(); + // falls through + } + + case 2: { + doSomethingElse(); + } +} +``` + +Note that the last `case` statement in these examples does not cause a warning because there is nothing to fall through into. + +## Options + +This rule accepts a single options argument: + +* Set the `commentPattern` option to a regular expression string to change the test for intentional fallthrough comment + +### commentPattern + +Examples of **correct** code for the `{ "commentPattern": "break[\\s\\w]*omitted" }` option: + +```js +/*eslint no-fallthrough: ["error", { "commentPattern": "break[\\s\\w]*omitted" }]*/ + +switch(foo) { + case 1: + doSomething(); + // break omitted + + case 2: + doSomething(); +} + +switch(foo) { + case 1: + doSomething(); + // caution: break is omitted intentionally + + default: + doSomething(); +} +``` + +## When Not To Use It + +If you don't want to enforce that each `case` statement should end with a `throw`, `return`, `break`, or comment, then you can safely turn this rule off. + +## Related Rules + +* [default-case](default-case) + +## Version + +This rule was introduced in ESLint 0.0.7. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-fallthrough.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-fallthrough.md) diff --git a/docs/8.0.0/rules/no-floating-decimal.md b/docs/8.0.0/rules/no-floating-decimal.md new file mode 100644 index 0000000000..a23d0b43b1 --- /dev/null +++ b/docs/8.0.0/rules/no-floating-decimal.md @@ -0,0 +1,62 @@ +--- +title: no-floating-decimal - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-floating-decimal.md +rule_type: suggestion +--- + + +# Disallow Floating Decimals (no-floating-decimal) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +Float values in JavaScript contain a decimal point, and there is no requirement that the decimal point be preceded or followed by a number. For example, the following are all valid JavaScript numbers: + +```js +var num = .5; +var num = 2.; +var num = -.7; +``` + +Although not a syntax error, this format for numbers can make it difficult to distinguish between true decimal numbers and the dot operator. For this reason, some recommend that you should always include a number before and after a decimal point to make it clear the intent is to create a decimal number. + +## Rule Details + +This rule is aimed at eliminating floating decimal points and will warn whenever a numeric value has a decimal point but is missing a number either before or after it. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-floating-decimal: "error"*/ + +var num = .5; +var num = 2.; +var num = -.7; +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-floating-decimal: "error"*/ + +var num = 0.5; +var num = 2.0; +var num = -0.7; +``` + +## When Not To Use It + +If you aren't concerned about misinterpreting floating decimal point values, then you can safely turn this rule off. + +## Compatibility + +* **JSHint**: W008, W047 + +## Version + +This rule was introduced in ESLint 0.0.6. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-floating-decimal.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-floating-decimal.md) diff --git a/docs/8.0.0/rules/no-func-assign.md b/docs/8.0.0/rules/no-func-assign.md new file mode 100644 index 0000000000..63f5456bae --- /dev/null +++ b/docs/8.0.0/rules/no-func-assign.md @@ -0,0 +1,74 @@ +--- +title: no-func-assign - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-func-assign.md +rule_type: problem +--- + + +# disallow reassigning `function` declarations (no-func-assign) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +JavaScript functions can be written as a FunctionDeclaration `function foo() { ... }` or as a FunctionExpression `var foo = function() { ... };`. While a JavaScript interpreter might tolerate it, overwriting/reassigning a function written as a FunctionDeclaration is often indicative of a mistake or issue. + +```js +function foo() {} +foo = bar; +``` + +## Rule Details + +This rule disallows reassigning `function` declarations. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-func-assign: "error"*/ + +function foo() {} +foo = bar; + +function foo() { + foo = bar; +} + +var a = function hello() { + hello = 123; +}; +``` + +Examples of **incorrect** code for this rule, unlike the corresponding rule in JSHint: + +```js +/*eslint no-func-assign: "error"*/ + +foo = bar; +function foo() {} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-func-assign: "error"*/ + +var foo = function () {} +foo = bar; + +function foo(foo) { // `foo` is shadowed. + foo = bar; +} + +function foo() { + var foo = bar; // `foo` is shadowed. +} +``` + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-func-assign.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-func-assign.md) diff --git a/docs/8.0.0/rules/no-global-assign.md b/docs/8.0.0/rules/no-global-assign.md new file mode 100644 index 0000000000..2762827c4e --- /dev/null +++ b/docs/8.0.0/rules/no-global-assign.md @@ -0,0 +1,108 @@ +--- +title: no-global-assign - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-global-assign.md +rule_type: suggestion +--- + + +# Disallow assignment to native objects or read-only global variables (no-global-assign) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +JavaScript environments contain a number of built-in global variables, such as `window` in browsers and `process` in Node.js. In almost all cases, you don't want to assign a value to these global variables as doing so could result in losing access to important functionality. For example, you probably don't want to do this in browser code: + +```js +window = {}; +``` + +While examples such as `window` are obvious, there are often hundreds of built-in global objects provided by JavaScript environments. It can be hard to know if you're assigning to a global variable or not. + +## Rule Details + +This rule disallows modifications to read-only global variables. + +ESLint has the capability to configure global variables as read-only. + +* [Specifying Environments](../user-guide/configuring#specifying-environments) +* [Specifying Globals](../user-guide/configuring#specifying-globals) + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-global-assign: "error"*/ + +Object = null +undefined = 1 +``` + +```js +/*eslint no-global-assign: "error"*/ +/*eslint-env browser*/ + +window = {} +length = 1 +top = 1 +``` + +```js +/*eslint no-global-assign: "error"*/ +/*global a:readonly*/ + +a = 1 +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-global-assign: "error"*/ + +a = 1 +var b = 1 +b = 2 +``` + +```js +/*eslint no-global-assign: "error"*/ +/*eslint-env browser*/ + +onload = function() {} +``` + +```js +/*eslint no-global-assign: "error"*/ +/*global a:writable*/ + +a = 1 +``` + +## Options + +This rule accepts an `exceptions` option, which can be used to specify a list of builtins for which reassignments will be allowed: + +```json +{ + "rules": { + "no-global-assign": ["error", {"exceptions": ["Object"]}] + } +} +``` + +## When Not To Use It + +If you are trying to override one of the native objects. + +## Related Rules + +* [no-extend-native](no-extend-native) +* [no-redeclare](no-redeclare) +* [no-shadow](no-shadow) + +## Version + +This rule was introduced in ESLint 3.3.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-global-assign.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-global-assign.md) diff --git a/docs/8.0.0/rules/no-implicit-coercion.md b/docs/8.0.0/rules/no-implicit-coercion.md new file mode 100644 index 0000000000..ad0734c0de --- /dev/null +++ b/docs/8.0.0/rules/no-implicit-coercion.md @@ -0,0 +1,180 @@ +--- +title: no-implicit-coercion - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-implicit-coercion.md +rule_type: suggestion +--- + + +# Disallow the type conversion with shorter notations. (no-implicit-coercion) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +In JavaScript, there are a lot of different ways to convert value types. +Some of them might be hard to read and understand. + +Such as: + +```js +var b = !!foo; +var b = ~foo.indexOf("."); +var n = +foo; +var n = 1 * foo; +var s = "" + foo; +foo += ``; +``` + +Those can be replaced with the following code: + +```js +var b = Boolean(foo); +var b = foo.indexOf(".") !== -1; +var n = Number(foo); +var n = Number(foo); +var s = String(foo); +foo = String(foo); +``` + +## Rule Details + +This rule is aimed to flag shorter notations for the type conversion, then suggest a more self-explanatory notation. + +## Options + +This rule has three main options and one override option to allow some coercions as required. + +- `"boolean"` (`true` by default) - When this is `true`, this rule warns shorter type conversions for `boolean` type. +- `"number"` (`true` by default) - When this is `true`, this rule warns shorter type conversions for `number` type. +- `"string"` (`true` by default) - When this is `true`, this rule warns shorter type conversions for `string` type. +- `"disallowTemplateShorthand"` (`false` by default) - When this is `true`, this rule warns `string` type conversions using `${expression}` form. +- `"allow"` (`empty` by default) - Each entry in this array can be one of `~`, `!!`, `+` or `*` that are to be allowed. + +Note that operator `+` in `allow` list would allow `+foo` (number coercion) as well as `"" + foo` (string coercion). + +### boolean + +Examples of **incorrect** code for the default `{ "boolean": true }` option: + +```js +/*eslint no-implicit-coercion: "error"*/ + +var b = !!foo; +var b = ~foo.indexOf("."); +// bitwise not is incorrect only with `indexOf`/`lastIndexOf` method calling. +``` + +Examples of **correct** code for the default `{ "boolean": true }` option: + +```js +/*eslint no-implicit-coercion: "error"*/ + +var b = Boolean(foo); +var b = foo.indexOf(".") !== -1; + +var n = ~foo; // This is a just bitwise not. +``` + +### number + +Examples of **incorrect** code for the default `{ "number": true }` option: + +```js +/*eslint no-implicit-coercion: "error"*/ + +var n = +foo; +var n = 1 * foo; +``` + +Examples of **correct** code for the default `{ "number": true }` option: + +```js +/*eslint no-implicit-coercion: "error"*/ + +var n = Number(foo); +var n = parseFloat(foo); +var n = parseInt(foo, 10); +``` + +### string + +Examples of **incorrect** code for the default `{ "string": true }` option: + +```js +/*eslint no-implicit-coercion: "error"*/ + +var s = "" + foo; +var s = `` + foo; +foo += ""; +foo += ``; +``` + +Examples of **correct** code for the default `{ "string": true }` option: + +```js +/*eslint no-implicit-coercion: "error"*/ + +var s = String(foo); +foo = String(foo); +``` + +### disallowTemplateShorthand + +This option is **not** affected by the `string` option. + +Examples of **incorrect** code for the `{ "disallowTemplateShorthand": true }` option: + +```js +/*eslint no-implicit-coercion: ["error", { "disallowTemplateShorthand": true }]*/ + +var s = `${foo}`; +``` + +Examples of **correct** code for the `{ "disallowTemplateShorthand": true }` option: + +```js +/*eslint no-implicit-coercion: ["error", { "disallowTemplateShorthand": true }]*/ + +var s = String(foo); + +var s = `a${foo}`; + +var s = `${foo}b`; + +var s = `${foo}${bar}`; + +var s = tag`${foo}`; +``` + +Examples of **correct** code for the default `{ "disallowTemplateShorthand": false }` option: + +```js +/*eslint no-implicit-coercion: ["error", { "disallowTemplateShorthand": false }]*/ + +var s = `${foo}`; +``` + +### allow + +Using `allow` list, we can override and allow specific operators. + +Examples of **correct** code for the sample `{ "allow": ["!!", "~"] }` option: + +```js +/*eslint no-implicit-coercion: [2, { "allow": ["!!", "~"] } ]*/ + +var b = !!foo; +var b = ~foo.indexOf("."); +``` + +## When Not To Use It + +If you don't want to be notified about shorter notations for the type conversion, you can safely disable this rule. + +## Version + +This rule was introduced in ESLint 1.0.0-rc-2. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-implicit-coercion.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-implicit-coercion.md) diff --git a/docs/8.0.0/rules/no-implicit-globals.md b/docs/8.0.0/rules/no-implicit-globals.md new file mode 100644 index 0000000000..5f22b67d11 --- /dev/null +++ b/docs/8.0.0/rules/no-implicit-globals.md @@ -0,0 +1,243 @@ +--- +title: no-implicit-globals - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-implicit-globals.md +rule_type: suggestion +--- + + +# Disallow declarations in the global scope (no-implicit-globals) + +It is the best practice to avoid 'polluting' the global scope with variables that are intended to be local to the script. + +Global variables created from a script can produce name collisions with global variables created from another script, which will +usually lead to runtime errors or unexpected behavior. + +This rule disallows the following: + +* Declarations that create one or more variables in the global scope. +* Global variable leaks. +* Redeclarations of read-only global variables and assignments to read-only global variables. + +There is an explicit way to create a global variable when needed, by assigning to a property of the global object. + +This rule is mostly useful for browser scripts. Top-level declarations in ES modules and CommonJS modules create module-scoped +variables. ES modules also have implicit `strict` mode, which prevents global variable leaks. + +By default, this rule does not check `const`, `let` and `class` declarations. + +This rule has an object option with one option: + +* Set `"lexicalBindings"` to `true` if you want this rule to check `const`, `let` and `class` declarations as well. + +## Rule Details + +### `var` and `function` declarations + +When working with browser scripts, developers often forget that variable and function declarations at the top-level scope become global variables on the `window` object. As opposed to modules which have their own scope. Globals should be explicitly assigned to `window` or `self` if that is the intent. Otherwise variables intended to be local to the script should be wrapped in an IIFE. + +This rule disallows `var` and `function` declarations at the top-level script scope. This does not apply to ES and CommonJS modules since they have a module scope. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-implicit-globals: "error"*/ + +var foo = 1; + +function bar() {} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-implicit-globals: "error"*/ + +// explicitly set on window +window.foo = 1; +window.bar = function() {}; + +// intended to be scope to this file +(function() { + var foo = 1; + + function bar() {} +})(); +``` + +Examples of **correct** code for this rule with `"parserOptions": { "sourceType": "module" }` in the ESLint configuration: + +```js +/*eslint no-implicit-globals: "error"*/ + +// foo and bar are local to module +var foo = 1; +function bar() {} +``` + +### Global variable leaks + +When the code is not in `strict` mode, an assignment to an undeclared variable creates +a new global variable. This will happen even is the code is in a function. + +This does not apply to ES modules since the module code is implicitly in `strict` mode. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-implicit-globals: "error"*/ + +foo = 1; + +Bar.prototype.baz = function () { + a = 1; // Intended to be this.a = 1; +}; +``` + +### Read-only global variables + +This rule also disallows redeclarations of read-only global variables and assignments to read-only global variables. + +A read-only global variable can be a built-in ES global (e.g. `Array`), an environment specific global +(e.g. `window` in the browser environment), or a global variable defined as `readonly` in the configuration file +or in a `/*global */` comment. + +* [Specifying Environments](../user-guide/configuring#specifying-environments) +* [Specifying Globals](../user-guide/configuring#specifying-globals) + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-implicit-globals: "error"*/ + +/*global foo:readonly*/ + +foo = 1; + +Array = []; +var Object; +``` + +### `const`, `let` and `class` declarations + +Lexical declarations `const` and `let`, as well as `class` declarations, create variables that are block-scoped. + +However, when declared in the top-level of a browser script these variables are not 'script-scoped'. +They are actually created in the global scope and could produce name collisions with +`var`, `const` and `let` variables and `function` and `class` declarations from other scripts. +This does not apply to ES and CommonJS modules. + +If the variable is intended to be local to the script, wrap the code with a block or with an immediately-invoked function expression (IIFE). + +Examples of **correct** code for this rule with `"lexicalBindings"` option set to `false` (default): + +```js +/*eslint no-implicit-globals: ["error", {"lexicalBindings": false}]*/ + +const foo = 1; + +let baz; + +class Bar {} +``` + +Examples of **incorrect** code for this rule with `"lexicalBindings"` option set to `true`: + +```js +/*eslint no-implicit-globals: ["error", {"lexicalBindings": true}]*/ + +const foo = 1; + +let baz; + +class Bar {} +``` + +Examples of **correct** code for this rule with `"lexicalBindings"` option set to `true`: + +```js +/*eslint no-implicit-globals: ["error", {"lexicalBindings": true}]*/ + +{ + const foo = 1; + let baz; + class Bar {} +} + +(function() { + const foo = 1; + let baz; + class Bar {} +}()); +``` + +If you intend to create a global `const` or `let` variable or a global `class` declaration, to be used from other scripts, +be aware that there are certain differences when compared to the traditional methods, which are `var` declarations and assigning to a property of the global `window` object: + +* Lexically declared variables cannot be conditionally created. A script cannot check for the existence of +a variable and then create a new one. `var` variables are also always created, but redeclarations do not +cause runtime exceptions. +* Lexically declared variables do not create properties on the global object, which is what a consuming script might expect. +* Lexically declared variables are shadowing properties of the global object, which might produce errors if a +consuming script is using both the variable and the property. +* Lexically declared variables can produce a permanent Temporal Dead Zone (TDZ) if the initialization throws an exception. +Even the `typeof` check is not safe from TDZ reference exceptions. + +Examples of **incorrect** code for this rule with `"lexicalBindings"` option set to `true`: + +```js +/*eslint no-implicit-globals: ["error", {"lexicalBindings": true}]*/ + +const MyGlobalFunction = (function() { + const a = 1; + let b = 2; + return function() { + return a + b; + } +}()); +``` + +Examples of **correct** code for this rule with `"lexicalBindings"` option set to `true`: + +```js +/*eslint no-implicit-globals: ["error", {"lexicalBindings": true}]*/ + +window.MyGlobalFunction = (function() { + const a = 1; + let b = 2; + return function() { + return a + b; + } +}()); +``` + +## When Not To Use It + +In the case of a browser script, if you want to be able to explicitly declare variables and functions in the global scope, +and your code is in strict mode or you don't want this rule to warn you about undeclared variables, +and you also don't want this rule to warn you about read-only globals, you can disable this rule. + +In the case of a CommonJS module, if your code is in strict mode or you don't want this rule to warn you about undeclared variables, +and you also don't want this rule to warn you about the read-only globals, you can disable this rule. + +In the case of an ES module, if you don't want this rule to warn you about the read-only globals you can disable this rule. + +## Further Reading + +* [Immediately-Invoked Function Expression (IIFE)](http://benalman.com/news/2010/11/immediately-invoked-function-expression/) +* [ReferenceError: assignment to undeclared variable](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Undeclared_var) +* [Temporal Dead Zone](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let#Temporal_dead_zone) + +## Related Rules + +* [no-undef](no-undef) +* [no-global-assign](no-global-assign) + +## Version + +This rule was introduced in ESLint 2.0.0-alpha-1. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-implicit-globals.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-implicit-globals.md) diff --git a/docs/8.0.0/rules/no-implied-eval.md b/docs/8.0.0/rules/no-implied-eval.md new file mode 100644 index 0000000000..c37a59df36 --- /dev/null +++ b/docs/8.0.0/rules/no-implied-eval.md @@ -0,0 +1,80 @@ +--- +title: no-implied-eval - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-implied-eval.md +rule_type: suggestion +--- + + +# Disallow Implied eval() (no-implied-eval) + +It's considered a good practice to avoid using `eval()` in JavaScript. There are security and performance implications involved with doing so, which is why many linters (including ESLint) recommend disallowing `eval()`. However, there are some other ways to pass a string and have it interpreted as JavaScript code that have similar concerns. + +The first is using `setTimeout()`, `setInterval()` or `execScript()` (Internet Explorer only), all of which can accept a string of JavaScript code as their first argument. For example: + +```js +setTimeout("alert('Hi!');", 100); +``` + +This is considered an implied `eval()` because a string of JavaScript code is + passed in to be interpreted. The same can be done with `setInterval()` and `execScript()`. Both interpret the JavaScript code in the global scope. For both `setTimeout()` and `setInterval()`, the first argument can also be a function, and that is considered safer and is more performant: + +```js +setTimeout(function() { + alert("Hi!"); +}, 100); +``` + +The best practice is to always use a function for the first argument of `setTimeout()` and `setInterval()` (and avoid `execScript()`). + + +## Rule Details + +This rule aims to eliminate implied `eval()` through the use of `setTimeout()`, `setInterval()` or `execScript()`. As such, it will warn when either function is used with a string as the first argument. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-implied-eval: "error"*/ + +setTimeout("alert('Hi!');", 100); + +setInterval("alert('Hi!');", 100); + +execScript("alert('Hi!')"); + +window.setTimeout("count = 5", 10); + +window.setInterval("foo = bar", 10); +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-implied-eval: "error"*/ + +setTimeout(function() { + alert("Hi!"); +}, 100); + +setInterval(function() { + alert("Hi!"); +}, 100); +``` + +## When Not To Use It + +If you want to allow `setTimeout()` and `setInterval()` with string arguments, then you can safely disable this rule. + +## Related Rules + +* [no-eval](no-eval) + +## Version + +This rule was introduced in ESLint 0.0.7. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-implied-eval.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-implied-eval.md) diff --git a/docs/8.0.0/rules/no-import-assign.md b/docs/8.0.0/rules/no-import-assign.md new file mode 100644 index 0000000000..f42533cd13 --- /dev/null +++ b/docs/8.0.0/rules/no-import-assign.md @@ -0,0 +1,65 @@ +--- +title: no-import-assign - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-import-assign.md +rule_type: problem +--- + + +# disallow assigning to imported bindings (no-import-assign) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +The updates of imported bindings by ES Modules cause runtime errors. + +## Rule Details + +This rule warns the assignments, increments, and decrements of imported bindings. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-import-assign: "error"*/ + +import mod, { named } from "./mod.mjs" +import * as mod_ns from "./mod.mjs" + +mod = 1 // ERROR: 'mod' is readonly. +named = 2 // ERROR: 'named' is readonly. +mod_ns.named = 3 // ERROR: The members of 'mod_ns' are readonly. +mod_ns = {} // ERROR: 'mod_ns' is readonly. +// Can't extend 'mod_ns' +Object.assign(mod_ns, { foo: "foo" }) // ERROR: The members of 'mod_ns' are readonly. +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-import-assign: "error"*/ + +import mod, { named } from "./mod.mjs" +import * as mod_ns from "./mod.mjs" + +mod.prop = 1 +named.prop = 2 +mod_ns.named.prop = 3 + +// Known Limitation +function test(obj) { + obj.named = 4 // Not errored because 'obj' is not namespace objects. +} +test(mod_ns) // Not errored because it doesn't know that 'test' updates the member of the argument. +``` + +## When Not To Use It + +If you don't want to be notified about modifying imported bindings, you can disable this rule. + +## Version + +This rule was introduced in ESLint 6.4.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-import-assign.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-import-assign.md) diff --git a/docs/8.0.0/rules/no-inline-comments.md b/docs/8.0.0/rules/no-inline-comments.md new file mode 100644 index 0000000000..b78c39516a --- /dev/null +++ b/docs/8.0.0/rules/no-inline-comments.md @@ -0,0 +1,128 @@ +--- +title: no-inline-comments - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-inline-comments.md +rule_type: suggestion +--- + + +# disallow inline comments after code (no-inline-comments) + +Some style guides disallow comments on the same line as code. Code can become difficult to read if comments immediately follow the code on the same line. +On the other hand, it is sometimes faster and more obvious to put comments immediately following code. + +## Rule Details + +This rule disallows comments on the same line as code. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-inline-comments: "error"*/ + +var a = 1; // declaring a to 1 + +function getRandomNumber(){ + return 4; // chosen by fair dice roll. + // guaranteed to be random. +} + +/* A block comment before code */ var b = 2; + +var c = 3; /* A block comment after code */ +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-inline-comments: "error"*/ + +// This is a comment above a line of code +var foo = 5; + +var bar = 5; +//This is a comment below a line of code +``` + +### JSX exception + +Comments inside the curly braces in JSX are allowed to be on the same line as the braces, but only if they are not on the same line with other code, and the braces do not enclose an actual expression. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-inline-comments: "error"*/ + +var foo =
    { /* On the same line with other code */ }

    Some heading

    ; + +var bar = ( +
    + { // These braces are not just for the comment, so it can't be on the same line + baz + } +
    +); +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-inline-comments: "error"*/ + +var foo = ( +
    + {/* These braces are just for this comment and there is nothing else on this line */} +

    Some heading

    +
    +) + +var bar = ( +
    + { + // There is nothing else on this line + baz + } +
    +); + +var quux = ( +
    + {/* + Multiline + comment + */} +

    Some heading

    +
    +) +``` + +## Options + +### ignorePattern + +To make this rule ignore specific comments, set the `ignorePattern` option to a string pattern that will be passed to the [`RegExp` constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/RegExp). + +Examples of **correct** code for the `ignorePattern` option: + +```js +/*eslint no-inline-comments: ["error", { "ignorePattern": "webpackChunkName:\\s.+" }]*/ + +import(/* webpackChunkName: "my-chunk-name" */ './locale/en'); +``` + +Examples of **incorrect** code for the `ignorePattern` option: + +```js +/*eslint no-inline-comments: ["error", { "ignorePattern": "something" }] */ + +var foo = 4; // other thing +``` + +## Version + +This rule was introduced in ESLint 0.10.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-inline-comments.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-inline-comments.md) diff --git a/docs/8.0.0/rules/no-inner-declarations.md b/docs/8.0.0/rules/no-inner-declarations.md new file mode 100644 index 0000000000..b4c4508de5 --- /dev/null +++ b/docs/8.0.0/rules/no-inner-declarations.md @@ -0,0 +1,172 @@ +--- +title: no-inner-declarations - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-inner-declarations.md +rule_type: problem +--- + + +# disallow variable or `function` declarations in nested blocks (no-inner-declarations) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +In JavaScript, prior to ES6, a function declaration is only allowed in the first level of a program or the body of another function, though parsers sometimes [erroneously accept them elsewhere](https://code.google.com/p/esprima/issues/detail?id=422). This only applies to function declarations; named or anonymous function expressions can occur anywhere an expression is permitted. + +```js +// Good +function doSomething() { } + +// Bad +if (test) { + function doSomethingElse () { } +} + +function anotherThing() { + var fn; + + if (test) { + + // Good + fn = function expression() { }; + + // Bad + function declaration() { } + } +} +``` + +A variable declaration is permitted anywhere a statement can go, even nested deeply inside other blocks. This is often undesirable due to variable hoisting, and moving declarations to the root of the program or function body can increase clarity. Note that [block bindings](https://leanpub.com/understandinges6/read#leanpub-auto-block-bindings) (`let`, `const`) are not hoisted and therefore they are not affected by this rule. + +```js +/*eslint-env es6*/ + +// Good +var foo = 42; + +// Good +if (foo) { + let bar1; +} + +// Bad +while (test) { + var bar2; +} + +function doSomething() { + // Good + var baz = true; + + // Bad + if (baz) { + var quux; + } +} +``` + +## Rule Details + +This rule requires that function declarations and, optionally, variable declarations be in the root of a program or the body of a function. + +## Options + +This rule has a string option: + +* `"functions"` (default) disallows `function` declarations in nested blocks +* `"both"` disallows `function` and `var` declarations in nested blocks + +### functions + +Examples of **incorrect** code for this rule with the default `"functions"` option: + +```js +/*eslint no-inner-declarations: "error"*/ + +if (test) { + function doSomething() { } +} + +function doSomethingElse() { + if (test) { + function doAnotherThing() { } + } +} + +if (foo) function f(){} +``` + +Examples of **correct** code for this rule with the default `"functions"` option: + +```js +/*eslint no-inner-declarations: "error"*/ + +function doSomething() { } + +function doSomethingElse() { + function doAnotherThing() { } +} + +if (test) { + asyncCall(id, function (err, data) { }); +} + +var fn; +if (test) { + fn = function fnExpression() { }; +} + +if (foo) var a; +``` + +### both + +Examples of **incorrect** code for this rule with the `"both"` option: + +```js +/*eslint no-inner-declarations: ["error", "both"]*/ + +if (test) { + var foo = 42; +} + +function doAnotherThing() { + if (test) { + var bar = 81; + } +} + + +if (foo) var a; + +if (foo) function f(){} +``` + +Examples of **correct** code for this rule with the `"both"` option: + +```js +/*eslint no-inner-declarations: ["error", "both"]*/ +/*eslint-env es6*/ + +var bar = 42; + +if (test) { + let baz = 43; +} + +function doAnotherThing() { + var baz = 81; +} +``` + +## When Not To Use It + +The function declaration portion rule will be rendered obsolete when [block-scoped functions](https://bugzilla.mozilla.org/show_bug.cgi?id=585536) land in ES6, but until then, it should be left on to enforce valid constructions. Disable checking variable declarations when using [block-scoped-var](block-scoped-var) or if declaring variables in nested blocks is acceptable despite hoisting. + +## Version + +This rule was introduced in ESLint 0.6.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-inner-declarations.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-inner-declarations.md) diff --git a/docs/8.0.0/rules/no-invalid-regexp.md b/docs/8.0.0/rules/no-invalid-regexp.md new file mode 100644 index 0000000000..02c5b4eec8 --- /dev/null +++ b/docs/8.0.0/rules/no-invalid-regexp.md @@ -0,0 +1,76 @@ +--- +title: no-invalid-regexp - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-invalid-regexp.md +rule_type: problem +--- + + +# disallow invalid regular expression strings in `RegExp` constructors (no-invalid-regexp) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +An invalid pattern in a regular expression literal is a `SyntaxError` when the code is parsed, but an invalid string in `RegExp` constructors throws a `SyntaxError` only when the code is executed. + +## Rule Details + +This rule disallows invalid regular expression strings in `RegExp` constructors. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-invalid-regexp: "error"*/ + +RegExp('[') + +RegExp('.', 'z') + +new RegExp('\\') +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-invalid-regexp: "error"*/ + +RegExp('.') + +new RegExp + +this.RegExp('[') +``` + +Please note that this rule validates regular expressions per the latest ECMAScript specification, regardless of your parser settings. + +If you want to allow additional constructor flags for any reason, you can specify them using the `allowConstructorFlags` option. These flags will then be ignored by the rule. + +## Options + +This rule has an object option for exceptions: + +* `"allowConstructorFlags"` is an array of flags + +### allowConstructorFlags + +Examples of **correct** code for this rule with the `{ "allowConstructorFlags": ["a", "z"] }` option: + +```js +/*eslint no-invalid-regexp: ["error", { "allowConstructorFlags": ["a", "z"] }]*/ + +new RegExp('.', 'a') + +new RegExp('.', 'az') +``` + +## Further Reading + +* [Annotated ES5 §7.8.5 - Regular Expression Literals](https://es5.github.io/#x7.8.5) + +## Version + +This rule was introduced in ESLint 0.1.4. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-invalid-regexp.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-invalid-regexp.md) diff --git a/docs/8.0.0/rules/no-invalid-this.md b/docs/8.0.0/rules/no-invalid-this.md new file mode 100644 index 0000000000..7c57438040 --- /dev/null +++ b/docs/8.0.0/rules/no-invalid-this.md @@ -0,0 +1,268 @@ +--- +title: no-invalid-this - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-invalid-this.md +rule_type: suggestion +--- + + +# Disallow `this` keywords outside of classes or class-like objects. (no-invalid-this) + +Under the strict mode, `this` keywords outside of classes or class-like objects might be `undefined` and raise a `TypeError`. + +## Rule Details + +This rule aims to flag usage of `this` keywords outside of classes or class-like objects. + +Basically, this rule checks whether or not a function containing `this` keyword is a constructor or a method. + +This rule judges from following conditions whether or not the function is a constructor: + +* The name of the function starts with uppercase. +* The function is assigned to a variable which starts with an uppercase letter. +* The function is a constructor of ES2015 Classes. + +This rule judges from following conditions whether or not the function is a method: + +* The function is on an object literal. +* The function is assigned to a property. +* The function is a method/getter/setter of ES2015 Classes. (excepts static methods) + +And this rule allows `this` keywords in functions below: + +* The `call/apply/bind` method of the function is called directly. +* The function is a callback of array methods (such as `.forEach()`) if `thisArg` is given. +* The function has `@this` tag in its JSDoc comment. + +Otherwise are considered problems. + +This rule applies **only** in strict mode. +With `"parserOptions": { "sourceType": "module" }` in the ESLint configuration, your code is in strict mode even without a `"use strict"` directive. + +Examples of **incorrect** code for this rule in strict mode: + +```js +/*eslint no-invalid-this: "error"*/ +/*eslint-env es6*/ + +"use strict"; + +this.a = 0; +baz(() => this); + +(function() { + this.a = 0; + baz(() => this); +})(); + +function foo() { + this.a = 0; + baz(() => this); +} + +var foo = function() { + this.a = 0; + baz(() => this); +}; + +foo(function() { + this.a = 0; + baz(() => this); +}); + +obj.foo = () => { + // `this` of arrow functions is the outer scope's. + this.a = 0; +}; + +var obj = { + aaa: function() { + return function foo() { + // There is in a method `aaa`, but `foo` is not a method. + this.a = 0; + baz(() => this); + }; + } +}; + +foo.forEach(function() { + this.a = 0; + baz(() => this); +}); +``` + +Examples of **correct** code for this rule in strict mode: + +```js +/*eslint no-invalid-this: "error"*/ +/*eslint-env es6*/ + +"use strict"; + +function Foo() { + // OK, this is in a legacy style constructor. + this.a = 0; + baz(() => this); +} + +class Foo { + constructor() { + // OK, this is in a constructor. + this.a = 0; + baz(() => this); + } +} + +var obj = { + foo: function foo() { + // OK, this is in a method (this function is on object literal). + this.a = 0; + } +}; + +var obj = { + foo() { + // OK, this is in a method (this function is on object literal). + this.a = 0; + } +}; + +var obj = { + get foo() { + // OK, this is in a method (this function is on object literal). + return this.a; + } +}; + +var obj = Object.create(null, { + foo: {value: function foo() { + // OK, this is in a method (this function is on object literal). + this.a = 0; + }} +}); + +Object.defineProperty(obj, "foo", { + value: function foo() { + // OK, this is in a method (this function is on object literal). + this.a = 0; + } +}); + +Object.defineProperties(obj, { + foo: {value: function foo() { + // OK, this is in a method (this function is on object literal). + this.a = 0; + }} +}); + +function Foo() { + this.foo = function foo() { + // OK, this is in a method (this function assigns to a property). + this.a = 0; + baz(() => this); + }; +} + +obj.foo = function foo() { + // OK, this is in a method (this function assigns to a property). + this.a = 0; +}; + +Foo.prototype.foo = function foo() { + // OK, this is in a method (this function assigns to a property). + this.a = 0; +}; + +class Foo { + foo() { + // OK, this is in a method. + this.a = 0; + baz(() => this); + } + + static foo() { + // OK, this is in a method (static methods also have valid this). + this.a = 0; + baz(() => this); + } +} + +var foo = (function foo() { + // OK, the `bind` method of this function is called directly. + this.a = 0; +}).bind(obj); + +foo.forEach(function() { + // OK, `thisArg` of `.forEach()` is given. + this.a = 0; + baz(() => this); +}, thisArg); + +/** @this Foo */ +function foo() { + // OK, this function has a `@this` tag in its JSDoc comment. + this.a = 0; +} +``` + +## Options + +This rule has an object option, with one option: + +* `"capIsConstructor": false` (default `true`) disables the assumption that a function which name starts with an uppercase is a constructor. + +### capIsConstructor + +By default, this rule always allows the use of `this` in functions which name starts with an uppercase and anonymous functions that are assigned to a variable which name starts with an uppercase, assuming that those functions are used as constructor functions. + +Set `"capIsConstructor"` to `false` if you want those functions to be treated as 'regular' functions. + +Examples of **incorrect** code for this rule with `"capIsConstructor"` option set to `false`: + +```js +/*eslint no-invalid-this: ["error", { "capIsConstructor": false }]*/ + +"use strict"; + +function Foo() { + this.a = 0; +} + +var bar = function Foo() { + this.a = 0; +} + +var Bar = function() { + this.a = 0; +}; + +Baz = function() { + this.a = 0; +}; +``` + +Examples of **correct** code for this rule with `"capIsConstructor"` option set to `false`: + +```js +/*eslint no-invalid-this: ["error", { "capIsConstructor": false }]*/ + +"use strict"; + +obj.Foo = function Foo() { + // OK, this is in a method. + this.a = 0; +}; +``` + +## When Not To Use It + +If you don't want to be notified about usage of `this` keyword outside of classes or class-like objects, you can safely disable this rule. + +## Version + +This rule was introduced in ESLint 1.0.0-rc-2. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-invalid-this.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-invalid-this.md) diff --git a/docs/8.0.0/rules/no-irregular-whitespace.md b/docs/8.0.0/rules/no-irregular-whitespace.md new file mode 100644 index 0000000000..016ff124bf --- /dev/null +++ b/docs/8.0.0/rules/no-irregular-whitespace.md @@ -0,0 +1,191 @@ +--- +title: no-irregular-whitespace - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-irregular-whitespace.md +rule_type: problem +--- + + +# disallow irregular whitespace (no-irregular-whitespace) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +Invalid or irregular whitespace causes issues with ECMAScript 5 parsers and also makes code harder to debug in a similar nature to mixed tabs and spaces. + +Various whitespace characters can be inputted by programmers by mistake for example from copying or keyboard shortcuts. Pressing Alt + Space on macOS adds in a non breaking space character for example. + +A simple fix for this problem could be to rewrite the offending line from scratch. This might also be a problem introduced by the text editor: if rewriting the line does not fix it, try using a different editor. + +Known issues these spaces cause: + +* Zero Width Space + * Is NOT considered a separator for tokens and is often parsed as an `Unexpected token ILLEGAL` + * Is NOT shown in modern browsers making code repository software expected to resolve the visualization +* Line Separator + * Is NOT a valid character within JSON which would cause parse errors + +## Rule Details + +This rule is aimed at catching invalid whitespace that is not a normal tab and space. Some of these characters may cause issues in modern browsers and others will be a debugging issue to spot. + +This rule disallows the following characters except where the options allow: + + \u000B - Line Tabulation (\v) - + \u000C - Form Feed (\f) - + \u00A0 - No-Break Space - + \u0085 - Next Line + \u1680 - Ogham Space Mark + \u180E - Mongolian Vowel Separator - + \ufeff - Zero Width No-Break Space - + \u2000 - En Quad + \u2001 - Em Quad + \u2002 - En Space - + \u2003 - Em Space - + \u2004 - Tree-Per-Em + \u2005 - Four-Per-Em + \u2006 - Six-Per-Em + \u2007 - Figure Space + \u2008 - Punctuation Space - + \u2009 - Thin Space + \u200A - Hair Space + \u200B - Zero Width Space - + \u2028 - Line Separator + \u2029 - Paragraph Separator + \u202F - Narrow No-Break Space + \u205f - Medium Mathematical Space + \u3000 - Ideographic Space + +## Options + +This rule has an object option for exceptions: + +* `"skipStrings": true` (default) allows any whitespace characters in string literals +* `"skipComments": true` allows any whitespace characters in comments +* `"skipRegExps": true` allows any whitespace characters in regular expression literals +* `"skipTemplates": true` allows any whitespace characters in template literals + +### skipStrings + +Examples of **incorrect** code for this rule with the default `{ "skipStrings": true }` option: + +```js +/*eslint no-irregular-whitespace: "error"*/ + +function thing() /**/{ + return 'test'; +} + +function thing( /**/){ + return 'test'; +} + +function thing /**/(){ + return 'test'; +} + +function thing᠎/**/(){ + return 'test'; +} + +function thing() { + return 'test'; /**/ +} + +function thing() { + return 'test'; /**/ +} + +function thing() { + // Description : some descriptive text +} + +/* +Description : some descriptive text +*/ + +function thing() { + return / regexp/; +} + +/*eslint-env es6*/ +function thing() { + return `template string`; +} +``` + +Examples of **correct** code for this rule with the default `{ "skipStrings": true }` option: + +```js +/*eslint no-irregular-whitespace: "error"*/ + +function thing() { + return ' thing'; +} + +function thing() { + return '​thing'; +} + +function thing() { + return 'th ing'; +} +``` + +### skipComments + +Examples of additional **correct** code for this rule with the `{ "skipComments": true }` option: + +```js +/*eslint no-irregular-whitespace: ["error", { "skipComments": true }]*/ + +function thing() { + // Description : some descriptive text +} + +/* +Description : some descriptive text +*/ +``` + +### skipRegExps + +Examples of additional **correct** code for this rule with the `{ "skipRegExps": true }` option: + +```js +/*eslint no-irregular-whitespace: ["error", { "skipRegExps": true }]*/ + +function thing() { + return / regexp/; +} +``` + +### skipTemplates + +Examples of additional **correct** code for this rule with the `{ "skipTemplates": true }` option: + +```js +/*eslint no-irregular-whitespace: ["error", { "skipTemplates": true }]*/ +/*eslint-env es6*/ + +function thing() { + return `template string`; +} +``` + +## When Not To Use It + +If you decide that you wish to use whitespace other than tabs and spaces outside of strings in your application. + +## Further Reading + +* [ECMA whitespace](https://es5.github.io/#x7.2) +* [JSON whitespace issues](http://timelessrepo.com/json-isnt-a-javascript-subset) + +## Version + +This rule was introduced in ESLint 0.9.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-irregular-whitespace.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-irregular-whitespace.md) diff --git a/docs/8.0.0/rules/no-iterator.md b/docs/8.0.0/rules/no-iterator.md new file mode 100644 index 0000000000..8ecaa4ab1d --- /dev/null +++ b/docs/8.0.0/rules/no-iterator.md @@ -0,0 +1,61 @@ +--- +title: no-iterator - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-iterator.md +rule_type: suggestion +--- + + +# Disallow Iterator (no-iterator) + +The `__iterator__` property was a SpiderMonkey extension to JavaScript that could be used to create custom iterators that are compatible with JavaScript's `for in` and `for each` constructs. However, this property is now obsolete, so it should not be used. Here's an example of how this used to work: + +```js +Foo.prototype.__iterator__ = function() { + return new FooIterator(this); +} +``` + +You should use ECMAScript 6 iterators and generators instead. + +## Rule Details + +This rule is aimed at preventing errors that may arise from using the `__iterator__` property, which is not implemented in several browsers. As such, it will warn whenever it encounters the `__iterator__` property. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-iterator: "error"*/ + +Foo.prototype.__iterator__ = function() { + return new FooIterator(this); +}; + +foo.__iterator__ = function () {}; + +foo["__iterator__"] = function () {}; + +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-iterator: "error"*/ + +var __iterator__ = foo; // Not using the `__iterator__` property. +``` + +## Further Reading + +* [MDN - Iterators and Generators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators) +* [ECMAScript 6 compatibility table - Iterators](https://kangax.github.io/es5-compat-table/es6/#Iterators) +* [Deprecated and Obsolete Features](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Deprecated_and_obsolete_features#Object_methods) + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-iterator.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-iterator.md) diff --git a/docs/8.0.0/rules/no-label-var.md b/docs/8.0.0/rules/no-label-var.md new file mode 100644 index 0000000000..3f0ba99a73 --- /dev/null +++ b/docs/8.0.0/rules/no-label-var.md @@ -0,0 +1,65 @@ +--- +title: no-label-var - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-label-var.md +rule_type: suggestion +--- + + +# Disallow Labels That Are Variables Names (no-label-var) + +## Rule Details + +This rule aims to create clearer code by disallowing the bad practice of creating a label that shares a name with a variable that is in scope. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-label-var: "error"*/ + +var x = foo; +function bar() { +x: + for (;;) { + break x; + } +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-label-var: "error"*/ + +// The variable that has the same name as the label is not in scope. + +function foo() { + var q = t; +} + +function bar() { +q: + for(;;) { + break q; + } +} +``` + +## When Not To Use It + +If you don't want to be notified about usage of labels, then it's safe to disable this rule. + +## Related Rules + +* [no-extra-label](./no-extra-label) +* [no-labels](./no-labels) +* [no-unused-labels](./no-unused-labels) + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-label-var.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-label-var.md) diff --git a/docs/8.0.0/rules/no-labels.md b/docs/8.0.0/rules/no-labels.md new file mode 100644 index 0000000000..78ef37109e --- /dev/null +++ b/docs/8.0.0/rules/no-labels.md @@ -0,0 +1,140 @@ +--- +title: no-labels - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-labels.md +rule_type: suggestion +--- + + +# Disallow Labeled Statements (no-labels) + +Labeled statements in JavaScript are used in conjunction with `break` and `continue` to control flow around multiple loops. For example: + +```js +outer: + while (true) { + + while (true) { + break outer; + } + } +``` + +The `break outer` statement ensures that this code will not result in an infinite loop because control is returned to the next statement after the `outer` label was applied. If this statement was changed to be just `break`, control would flow back to the outer `while` statement and an infinite loop would result. + +While convenient in some cases, labels tend to be used only rarely and are frowned upon by some as a remedial form of flow control that is more error prone and harder to understand. + +## Rule Details + +This rule aims to eliminate the use of labeled statements in JavaScript. It will warn whenever a labeled statement is encountered and whenever `break` or `continue` are used with a label. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-labels: "error"*/ + +label: + while(true) { + // ... + } + +label: + while(true) { + break label; + } + +label: + while(true) { + continue label; + } + +label: + switch (a) { + case 0: + break label; + } + +label: + { + break label; + } + +label: + if (a) { + break label; + } +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-labels: "error"*/ + +var f = { + label: "foo" +}; + +while (true) { + break; +} + +while (true) { + continue; +} +``` + +## Options + +The options allow labels with loop or switch statements: + +* `"allowLoop"` (`boolean`, default is `false`) - If this option was set `true`, this rule ignores labels which are sticking to loop statements. +* `"allowSwitch"` (`boolean`, default is `false`) - If this option was set `true`, this rule ignores labels which are sticking to switch statements. + +Actually labeled statements in JavaScript can be used with other than loop and switch statements. +However, this way is ultra rare, not well-known, so this would be confusing developers. + +### allowLoop + +Examples of **correct** code for the `{ "allowLoop": true }` option: + +```js +/*eslint no-labels: ["error", { "allowLoop": true }]*/ + +label: + while (true) { + break label; + } +``` + +### allowSwitch + +Examples of **correct** code for the `{ "allowSwitch": true }` option: + +```js +/*eslint no-labels: ["error", { "allowSwitch": true }]*/ + +label: + switch (a) { + case 0: + break label; + } +``` + +## When Not To Use It + +If you need to use labeled statements everywhere, then you can safely disable this rule. + +## Related Rules + +* [no-extra-label](./no-extra-label) +* [no-label-var](./no-label-var) +* [no-unused-labels](./no-unused-labels) + +## Version + +This rule was introduced in ESLint 0.4.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-labels.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-labels.md) diff --git a/docs/8.0.0/rules/no-lone-blocks.md b/docs/8.0.0/rules/no-lone-blocks.md new file mode 100644 index 0000000000..cf1ee79389 --- /dev/null +++ b/docs/8.0.0/rules/no-lone-blocks.md @@ -0,0 +1,111 @@ +--- +title: no-lone-blocks - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-lone-blocks.md +rule_type: suggestion +--- + + +# Disallow Unnecessary Nested Blocks (no-lone-blocks) + +In JavaScript, prior to ES6, standalone code blocks delimited by curly braces do not create a new scope and have no use. For example, these curly braces do nothing to `foo`: + +```js +{ + var foo = bar(); +} +``` + +In ES6, code blocks may create a new scope if a block-level binding (`let` and `const`), a class declaration or a function declaration (in strict mode) are present. A block is not considered redundant in these cases. + +## Rule Details + +This rule aims to eliminate unnecessary and potentially confusing blocks at the top level of a script or within other blocks. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-lone-blocks: "error"*/ + +{} + +if (foo) { + bar(); + { + baz(); + } +} + +function bar() { + { + baz(); + } +} + +{ + function foo() {} +} + +{ + aLabel: { + } +} +``` + +Examples of **correct** code for this rule with ES6 environment: + +```js +/*eslint no-lone-blocks: "error"*/ +/*eslint-env es6*/ + +while (foo) { + bar(); +} + +if (foo) { + if (bar) { + baz(); + } +} + +function bar() { + baz(); +} + +{ + let x = 1; +} + +{ + const y = 1; +} + +{ + class Foo {} +} + +aLabel: { +} +``` + +Examples of **correct** code for this rule with ES6 environment and strict mode via `"parserOptions": { "sourceType": "module" }` in the ESLint configuration or `"use strict"` directive in the code: + +```js +/*eslint no-lone-blocks: "error"*/ +/*eslint-env es6*/ + +"use strict"; + +{ + function foo() {} +} +``` + +## Version + +This rule was introduced in ESLint 0.4.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-lone-blocks.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-lone-blocks.md) diff --git a/docs/8.0.0/rules/no-lonely-if.md b/docs/8.0.0/rules/no-lonely-if.md new file mode 100644 index 0000000000..7b3c3b521e --- /dev/null +++ b/docs/8.0.0/rules/no-lonely-if.md @@ -0,0 +1,103 @@ +--- +title: no-lonely-if - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-lonely-if.md +rule_type: suggestion +--- + + +# disallow `if` statements as the only statement in `else` blocks (no-lonely-if) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +If an `if` statement is the only statement in the `else` block, it is often clearer to use an `else if` form. + +```js +if (foo) { + // ... +} else { + if (bar) { + // ... + } +} +``` + +should be rewritten as + +```js +if (foo) { + // ... +} else if (bar) { + // ... +} +``` + +## Rule Details + +This rule disallows `if` statements as the only statement in `else` blocks. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-lonely-if: "error"*/ + +if (condition) { + // ... +} else { + if (anotherCondition) { + // ... + } +} + +if (condition) { + // ... +} else { + if (anotherCondition) { + // ... + } else { + // ... + } +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-lonely-if: "error"*/ + +if (condition) { + // ... +} else if (anotherCondition) { + // ... +} + +if (condition) { + // ... +} else if (anotherCondition) { + // ... +} else { + // ... +} + +if (condition) { + // ... +} else { + if (anotherCondition) { + // ... + } + doSomething(); +} +``` + +## When Not To Use It + +Disable this rule if the code is clearer without requiring the `else if` form. + +## Version + +This rule was introduced in ESLint 0.6.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-lonely-if.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-lonely-if.md) diff --git a/docs/8.0.0/rules/no-loop-func.md b/docs/8.0.0/rules/no-loop-func.md new file mode 100644 index 0000000000..d6a967dd1a --- /dev/null +++ b/docs/8.0.0/rules/no-loop-func.md @@ -0,0 +1,115 @@ +--- +title: no-loop-func - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-loop-func.md +rule_type: suggestion +--- + + +# Disallow Functions in Loops (no-loop-func) + +Writing functions within loops tends to result in errors due to the way the function creates a closure around the loop. For example: + +```js +for (var i = 0; i < 10; i++) { + funcs[i] = function() { + return i; + }; +} +``` + +In this case, you would expect each function created within the loop to return a different number. In reality, each function returns 10, because that was the last value of `i` in the scope. + +`let` or `const` mitigate this problem. + +```js +/*eslint-env es6*/ + +for (let i = 0; i < 10; i++) { + funcs[i] = function() { + return i; + }; +} +``` + +In this case, each function created within the loop returns a different number as expected. + + +## Rule Details + +This error is raised to highlight a piece of code that may not work as you expect it to and could also indicate a misunderstanding of how the language works. Your code may run without any problems if you do not fix this error, but in some situations it could behave unexpectedly. + +This rule disallows any function within a loop that contains unsafe references (e.g. to modified variables from the outer scope). + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-loop-func: "error"*/ +/*eslint-env es6*/ + +for (var i=10; i; i--) { + (function() { return i; })(); +} + +while(i) { + var a = function() { return i; }; + a(); +} + +do { + function a() { return i; }; + a(); +} while (i); + +let foo = 0; +for (let i = 0; i < 10; ++i) { + //Bad, `foo` is not in the loop-block's scope and `foo` is modified in/after the loop + setTimeout(() => console.log(foo)); + foo += 1; +} + +for (let i = 0; i < 10; ++i) { + //Bad, `foo` is not in the loop-block's scope and `foo` is modified in/after the loop + setTimeout(() => console.log(foo)); +} +foo = 100; +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-loop-func: "error"*/ +/*eslint-env es6*/ + +var a = function() {}; + +for (var i=10; i; i--) { + a(); +} + +for (var i=10; i; i--) { + var a = function() {}; // OK, no references to variables in the outer scopes. + a(); +} + +for (let i=10; i; i--) { + var a = function() { return i; }; // OK, all references are referring to block scoped variables in the loop. + a(); +} + +var foo = 100; +for (let i=10; i; i--) { + var a = function() { return foo; }; // OK, all references are referring to never modified variables. + a(); +} +//... no modifications of foo after this loop ... +``` + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-loop-func.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-loop-func.md) diff --git a/docs/8.0.0/rules/no-loss-of-precision.md b/docs/8.0.0/rules/no-loss-of-precision.md new file mode 100644 index 0000000000..391a742211 --- /dev/null +++ b/docs/8.0.0/rules/no-loss-of-precision.md @@ -0,0 +1,53 @@ +--- +title: no-loss-of-precision - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-loss-of-precision.md +rule_type: problem +--- + + +# Disallow Number Literals That Lose Precision (no-loss-of-precision) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +This rule would disallow the use of number literals that immediately lose precision at runtime when converted to a JS `Number` due to 64-bit floating-point rounding. + +## Rule Details + +In JS, `Number`s are stored as double-precision floating-point numbers according to the [IEEE 754 standard](https://en.wikipedia.org/wiki/IEEE_754). Because of this, numbers can only retain accuracy up to a certain amount of digits. If the programmer enters additional digits, those digits will be lost in the conversion to the `Number` type and will result in unexpected behavior. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-loss-of-precision: "error"*/ + +const x = 9007199254740993 +const x = 5123000000000000000000000000001 +const x = 1230000000000000000000000.0 +const x = .1230000000000000000000000 +const x = 0X20000000000001 +const x = 0X2_000000000_0001; +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-loss-of-precision: "error"*/ + +const x = 12345 +const x = 123.456 +const x = 123e34 +const x = 12300000000000000000000000 +const x = 0x1FFFFFFFFFFFFF +const x = 9007199254740991 +const x = 9007_1992547409_91 +``` + +## Version + +This rule was introduced in ESLint 7.1.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-loss-of-precision.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-loss-of-precision.md) diff --git a/docs/8.0.0/rules/no-magic-numbers.md b/docs/8.0.0/rules/no-magic-numbers.md new file mode 100644 index 0000000000..3ac358632e --- /dev/null +++ b/docs/8.0.0/rules/no-magic-numbers.md @@ -0,0 +1,214 @@ +--- +title: no-magic-numbers - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-magic-numbers.md +rule_type: suggestion +--- + + +# Disallow Magic Numbers (no-magic-numbers) + +'Magic numbers' are numbers that occur multiple times in code without an explicit meaning. +They should preferably be replaced by named constants. + +```js +var now = Date.now(), + inOneHour = now + (60 * 60 * 1000); +``` + +## Rule Details + +The `no-magic-numbers` rule aims to make code more readable and refactoring easier by ensuring that special numbers +are declared as constants to make their meaning explicit. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-magic-numbers: "error"*/ + +var dutyFreePrice = 100, + finalPrice = dutyFreePrice + (dutyFreePrice * 0.25); +``` + +```js +/*eslint no-magic-numbers: "error"*/ + +var data = ['foo', 'bar', 'baz']; + +var dataLast = data[2]; +``` + +```js +/*eslint no-magic-numbers: "error"*/ + +var SECONDS; + +SECONDS = 60; +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-magic-numbers: "error"*/ + +var TAX = 0.25; + +var dutyFreePrice = 100, + finalPrice = dutyFreePrice + (dutyFreePrice * TAX); +``` + +## Options + +### ignore + +An array of numbers to ignore. It's set to `[]` by default. +If provided, it must be an `Array`. + +The array can contain values of `number` and `string` types. +If it's a string, the text must be parsed as `bigint` literal (e.g., `"100n"`). + +Examples of **correct** code for the sample `{ "ignore": [1] }` option: + +```js +/*eslint no-magic-numbers: ["error", { "ignore": [1] }]*/ + +var data = ['foo', 'bar', 'baz']; +var dataLast = data.length && data[data.length - 1]; +``` + +Examples of **correct** code for the sample `{ "ignore": ["1n"] }` option: + +```js +/*eslint no-magic-numbers: ["error", { "ignore": ["1n"] }]*/ + +foo(1n); +``` + +### ignoreArrayIndexes + +A boolean to specify if numbers used in the context of array indexes (e.g., `data[2]`) are considered okay. `false` by default. + +This option allows only valid array indexes: numbers that will be coerced to one of `"0"`, `"1"`, `"2"` ... `"4294967294"`. + +Arrays are objects, so they can have property names such as `"-1"` or `"2.5"`. However, those are just "normal" object properties that don't represent array elements. They don't influence the array's `length`, and they are ignored by array methods like `.map` or `.forEach`. + +Additionally, since the maximum [array length](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length) is 232 - 1, all values above 232 - 2 also represent just normal property names and are thus not considered to be array indexes. + +Examples of **correct** code for the `{ "ignoreArrayIndexes": true }` option: + +```js +/*eslint no-magic-numbers: ["error", { "ignoreArrayIndexes": true }]*/ + +var item = data[2]; + +data[100] = a; + +f(data[0]); + +a = data[-0]; // same as data[0], -0 will be coerced to "0" + +a = data[0xAB]; + +a = data[5.6e1]; + +a = data[10n]; // same as data[10], 10n will be coerced to "10" + +a = data[4294967294]; // max array index +``` + +Examples of **incorrect** code for the `{ "ignoreArrayIndexes": true }` option: + +```js +/*eslint no-magic-numbers: ["error", { "ignoreArrayIndexes": true }]*/ + +f(2); // not used as array index + +a = data[-1]; + +a = data[2.5]; + +a = data[5.67e1]; + +a = data[-10n]; + +a = data[4294967295]; // above the max array index + +a = data[1e500]; // same as data["Infinity"] +``` + +### ignoreDefaultValues + +A boolean to specify if numbers used in default value assignments are considered okay. `false` by default. + +Examples of **correct** code for the `{ "ignoreDefaultValues": true }` option: + +```js +/*eslint no-magic-numbers: ["error", { "ignoreDefaultValues": true }]*/ + +const { tax = 0.25 } = accountancy; + +function mapParallel(concurrency = 3) { /***/ } +``` + +```js +/*eslint no-magic-numbers: ["error", { "ignoreDefaultValues": true }]*/ + +let head; +[head = 100] = [] +``` + +### enforceConst + +A boolean to specify if we should check for the const keyword in variable declaration of numbers. `false` by default. + +Examples of **incorrect** code for the `{ "enforceConst": true }` option: + +```js +/*eslint no-magic-numbers: ["error", { "enforceConst": true }]*/ + +var TAX = 0.25; + +var dutyFreePrice = 100, + finalPrice = dutyFreePrice + (dutyFreePrice * TAX); +``` + +### detectObjects + +A boolean to specify if we should detect numbers when setting object properties for example. `false` by default. + +Examples of **incorrect** code for the `{ "detectObjects": true }` option: + +```js +/*eslint no-magic-numbers: ["error", { "detectObjects": true }]*/ + +var magic = { + tax: 0.25 +}; + +var dutyFreePrice = 100, + finalPrice = dutyFreePrice + (dutyFreePrice * magic.tax); +``` + +Examples of **correct** code for the `{ "detectObjects": true }` option: + +```js +/*eslint no-magic-numbers: ["error", { "detectObjects": true }]*/ + +var TAX = 0.25; + +var magic = { + tax: TAX +}; + +var dutyFreePrice = 100, + finalPrice = dutyFreePrice + (dutyFreePrice * magic.tax); +``` + +## Version + +This rule was introduced in ESLint 1.7.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-magic-numbers.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-magic-numbers.md) diff --git a/docs/8.0.0/rules/no-misleading-character-class.md b/docs/8.0.0/rules/no-misleading-character-class.md new file mode 100644 index 0000000000..6e0585faf0 --- /dev/null +++ b/docs/8.0.0/rules/no-misleading-character-class.md @@ -0,0 +1,92 @@ +--- +title: no-misleading-character-class - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-misleading-character-class.md +rule_type: problem +--- + + +# Disallow characters which are made with multiple code points in character class syntax (no-misleading-character-class) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +Unicode includes the characters which are made with multiple code points. +RegExp character class syntax (`/[abc]/`) cannot handle characters which are made by multiple code points as a character; those characters will be dissolved to each code point. For example, `❇️` is made by `❇` (`U+2747`) and VARIATION SELECTOR-16 (`U+FE0F`). If this character is in RegExp character class, it will match to either `❇` (`U+2747`) or VARIATION SELECTOR-16 (`U+FE0F`) rather than `❇️`. + +This rule reports the regular expressions which include multiple code point characters in character class syntax. This rule considers the following characters as multiple code point characters. + +**A character with combining characters:** + +The combining characters are characters which belong to one of `Mc`, `Me`, and `Mn` [Unicode general categories](http://www.unicode.org/L2/L1999/UnicodeData.html#General%20Category). + +```js +/^[Á]$/u.test("Á") //→ false +/^[❇️]$/u.test("❇️") //→ false +``` + +**A character with Emoji modifiers:** + +```js +/^[👶🏻]$/u.test("👶🏻") //→ false +/^[👶🏽]$/u.test("👶🏽") //→ false +``` + +**A pair of regional indicator symbols:** + +```js +/^[🇯🇵]$/u.test("🇯🇵") //→ false +``` + +**Characters that ZWJ joins:** + +```js +/^[👨‍👩‍👦]$/u.test("👨‍👩‍👦") //→ false +``` + +**A surrogate pair without Unicode flag:** + +```js +/^[👍]$/.test("👍") //→ false + +// Surrogate pair is OK if with u flag. +/^[👍]$/u.test("👍") //→ true +``` + +## Rule Details + +This rule reports the regular expressions which include multiple code point characters in character class syntax. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-misleading-character-class: error */ + +/^[Á]$/u +/^[❇️]$/u +/^[👶🏻]$/u +/^[🇯🇵]$/u +/^[👨‍👩‍👦]$/u +/^[👍]$/ +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-misleading-character-class: error */ + +/^[abc]$/ +/^[👍]$/u +``` + +## When Not To Use It + +You can turn this rule off if you don't want to check RegExp character class syntax for multiple code point characters. + +## Version + +This rule was introduced in ESLint 5.3.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-misleading-character-class.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-misleading-character-class.md) diff --git a/docs/8.0.0/rules/no-mixed-operators.md b/docs/8.0.0/rules/no-mixed-operators.md new file mode 100644 index 0000000000..d1b056302b --- /dev/null +++ b/docs/8.0.0/rules/no-mixed-operators.md @@ -0,0 +1,211 @@ +--- +title: no-mixed-operators - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-mixed-operators.md +rule_type: suggestion +--- + + +# Disallow mixes of different operators (no-mixed-operators) + +Enclosing complex expressions by parentheses clarifies the developer's intention, which makes the code more readable. +This rule warns when different operators are used consecutively without parentheses in an expression. + +```js +var foo = a && b || c || d; /*BAD: Unexpected mix of '&&' and '||'.*/ +var foo = a && b ? c : d; /*BAD: Unexpected mix of '&&' and '?:'.*/ +var foo = (a && b) ? c : d; /*GOOD*/ +var foo = (a && b) || c || d; /*GOOD*/ +var foo = a && (b || c || d); /*GOOD*/ +``` + +**Note:** +It is expected for this rule to emit one error for each mixed operator in a pair. As a result, for each two consecutive mixed operators used, a distinct error will be displayed, pointing to where the specific operator that breaks the rule is used: + +```js +var foo = a && b || c || d; +``` + +will generate + +```sh +1:13 Unexpected mix of '&&' and '||'. (no-mixed-operators) +1:18 Unexpected mix of '&&' and '||'. (no-mixed-operators) +``` + +```js +var foo = a && b ? c : d; +``` + +will generate + +```sh +1:13 Unexpected mix of '&&' and '?:'. (no-mixed-operators) +1:18 Unexpected mix of '&&' and '?:'. (no-mixed-operators) +``` + + +## Rule Details + +This rule checks `BinaryExpression`, `LogicalExpression` and `ConditionalExpression`. + +This rule may conflict with [no-extra-parens](no-extra-parens) rule. +If you use both this and [no-extra-parens](no-extra-parens) rule together, you need to use the `nestedBinaryExpressions` option of [no-extra-parens](no-extra-parens) rule. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-mixed-operators: "error"*/ + +var foo = a && b < 0 || c > 0 || d + 1 === 0; +var foo = a + b * c; +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-mixed-operators: "error"*/ + +var foo = a || b || c; +var foo = a && b && c; +var foo = (a && b < 0) || c > 0 || d + 1 === 0; +var foo = a && (b < 0 || c > 0 || d + 1 === 0); +var foo = a + (b * c); +var foo = (a + b) * c; +``` + +## Options + +```json +{ + "no-mixed-operators": [ + "error", + { + "groups": [ + ["+", "-", "*", "/", "%", "**"], + ["&", "|", "^", "~", "<<", ">>", ">>>"], + ["==", "!=", "===", "!==", ">", ">=", "<", "<="], + ["&&", "||"], + ["in", "instanceof"] + ], + "allowSamePrecedence": true + } + ] +} +``` + +This rule has 2 options. + +* `groups` (`string[][]`) - specifies operator groups to be checked. The `groups` option is a list of groups, and a group is a list of binary operators. Default operator groups are defined as arithmetic, bitwise, comparison, logical, and relational operators. Note: Ternary operator(?:) can be part of any group and by default is allowed to be mixed with other operators. + +* `allowSamePrecedence` (`boolean`) - specifies whether to allow mixed operators if they are of equal precedence. Default is `true`. + +### groups + +The following operators can be used in `groups` option: + +* Arithmetic Operators: `"+"`, `"-"`, `"*"`, `"/"`, `"%"`, `"**"` +* Bitwise Operators: `"&"`, `"|"`, `"^"`, `"~"`, `"<<"`, `">>"`, `">>>"` +* Comparison Operators: `"=="`, `"!="`, `"==="`, `"!=="`, `">"`, `">="`, `"<"`, `"<="` +* Logical Operators: `"&&"`, `"||"` +* Coalesce Operator: `"??"` +* Relational Operators: `"in"`, `"instanceof"` +* Ternary Operator: `?:` + +Now, consider the following group configuration: `{"groups": [["&", "|", "^", "~", "<<", ">>", ">>>"], ["&&", "||"]]}`. +There are 2 groups specified in this configuration: bitwise operators and logical operators. +This rule checks if the operators belong to the same group only. +In this case, this rule checks if bitwise operators and logical operators are mixed, but ignores all other operators. + +Examples of **incorrect** code for this rule with `{"groups": [["&", "|", "^", "~", "<<", ">>", ">>>"], ["&&", "||"]]}` option: + +```js +/*eslint no-mixed-operators: ["error", {"groups": [["&", "|", "^", "~", "<<", ">>", ">>>"], ["&&", "||"]]}]*/ + +var foo = a && b < 0 || c > 0 || d + 1 === 0; +var foo = a & b | c; +``` + +```js +/*eslint no-mixed-operators: ["error", {"groups": [["&&", "||", "?:"]]}]*/ + +var foo = a || b ? c : d; + +var bar = a ? b || c : d; + +var baz = a ? b : c || d; +``` + +Examples of **correct** code for this rule with `{"groups": [["&", "|", "^", "~", "<<", ">>", ">>>"], ["&&", "||"]]}` option: + +```js +/*eslint no-mixed-operators: ["error", {"groups": [["&", "|", "^", "~", "<<", ">>", ">>>"], ["&&", "||"]]}]*/ + +var foo = a || b > 0 || c + 1 === 0; +var foo = a && b > 0 && c + 1 === 0; +var foo = (a && b < 0) || c > 0 || d + 1 === 0; +var foo = a && (b < 0 || c > 0 || d + 1 === 0); +var foo = (a & b) | c; +var foo = a & (b | c); +var foo = a + b * c; +var foo = a + (b * c); +var foo = (a + b) * c; +``` + +```js +/*eslint no-mixed-operators: ["error", {"groups": [["&&", "||", "?:"]]}]*/ + +var foo = (a || b) ? c : d; +var foo = a || (b ? c : d); + +var bar = a ? (b || c) : d; + +var baz = a ? b : (c || d); +var baz = (a ? b : c) || d; +``` + +### allowSamePrecedence + +Examples of **correct** code for this rule with `{"allowSamePrecedence": true}` option: + +```js +/*eslint no-mixed-operators: ["error", {"allowSamePrecedence": true}]*/ + +// + and - have the same precedence. +var foo = a + b - c; +``` + +Examples of **incorrect** code for this rule with `{"allowSamePrecedence": false}` option: + +```js +/*eslint no-mixed-operators: ["error", {"allowSamePrecedence": false}]*/ + +// + and - have the same precedence. +var foo = a + b - c; +``` + +Examples of **correct** code for this rule with `{"allowSamePrecedence": false}` option: + +```js +/*eslint no-mixed-operators: ["error", {"allowSamePrecedence": false}]*/ + +// + and - have the same precedence. +var foo = (a + b) - c; +``` + +## When Not To Use It + +If you don't want to be notified about mixed operators, then it's safe to disable this rule. + +## Related Rules + +* [no-extra-parens](no-extra-parens) + +## Version + +This rule was introduced in ESLint 2.12.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-mixed-operators.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-mixed-operators.md) diff --git a/docs/8.0.0/rules/no-mixed-requires.md b/docs/8.0.0/rules/no-mixed-requires.md new file mode 100644 index 0000000000..9600406487 --- /dev/null +++ b/docs/8.0.0/rules/no-mixed-requires.md @@ -0,0 +1,143 @@ +--- +title: no-mixed-requires - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-mixed-requires.md +rule_type: suggestion +--- + + +# disallow `require` calls to be mixed with regular variable declarations (no-mixed-requires) + +This rule was **deprecated** in ESLint v7.0.0. Please use the corresponding rule in [`eslint-plugin-node`](https://github.com/mysticatea/eslint-plugin-node). + +In the Node.js community it is often customary to separate initializations with calls to `require` modules from other variable declarations, sometimes also grouping them by the type of module. This rule helps you enforce this convention. + +## Rule Details + +When this rule is enabled, each `var` statement must satisfy the following conditions: + +* either none or all variable declarations must be require declarations (default) +* all require declarations must be of the same type (grouping) + +This rule distinguishes between six kinds of variable declaration types: + +* `core`: declaration of a required [core module][1] +* `file`: declaration of a required [file module][2] +* `module`: declaration of a required module from the [node_modules folder][3] +* `computed`: declaration of a required module whose type could not be determined (either because it is computed or because require was called without an argument) +* `uninitialized`: a declaration that is not initialized +* `other`: any other kind of declaration + +In this document, the first four types are summed up under the term *require declaration*. + +```js +var fs = require('fs'), // "core" \ + async = require('async'), // "module" |- these are "require declaration"s + foo = require('./foo'), // "file" | + bar = require(getName()), // "computed" / + baz = 42, // "other" + bam; // "uninitialized" +``` + +## Options + +This rule can have an object literal option whose two properties have `false` values by default. + +Configuring this rule with one boolean option `true` is deprecated. + +Examples of **incorrect** code for this rule with the default `{ "grouping": false, "allowCall": false }` options: + +```js +/*eslint no-mixed-requires: "error"*/ + +var fs = require('fs'), + i = 0; + +var async = require('async'), + debug = require('diagnostics').someFunction('my-module'), + eslint = require('eslint'); +``` + +Examples of **correct** code for this rule with the default `{ "grouping": false, "allowCall": false }` options: + +```js +/*eslint no-mixed-requires: "error"*/ + +// only require declarations (grouping off) +var eventEmitter = require('events').EventEmitter, + myUtils = require('./utils'), + util = require('util'), + bar = require(getBarModuleName()); + +// only non-require declarations +var foo = 42, + bar = 'baz'; + +// always valid regardless of grouping because all declarations are of the same type +var foo = require('foo' + VERSION), + bar = require(getBarModuleName()), + baz = require(); +``` + +### grouping + +Examples of **incorrect** code for this rule with the `{ "grouping": true }` option: + +```js +/*eslint no-mixed-requires: ["error", { "grouping": true }]*/ + +// invalid because of mixed types "core" and "module" +var fs = require('fs'), + async = require('async'); + +// invalid because of mixed types "file" and "unknown" +var foo = require('foo'), + bar = require(getBarModuleName()); +``` + +### allowCall + +Examples of **incorrect** code for this rule with the `{ "allowCall": true }` option: + +```js +/*eslint no-mixed-requires: ["error", { "allowCall": true }]*/ + +var async = require('async'), + debug = require('diagnostics').someFunction('my-module'), /* allowCall doesn't allow calling any function */ + eslint = require('eslint'); +``` + +Examples of **correct** code for this rule with the `{ "allowCall": true }` option: + +```js +/*eslint no-mixed-requires: ["error", { "allowCall": true }]*/ + +var async = require('async'), + debug = require('diagnostics')('my-module'), + eslint = require('eslint'); +``` + +## Known Limitations + +* The implementation is not aware of any local functions with the name `require` that may shadow Node.js' global `require`. + +* Internally, the list of core modules is retrieved via `require("repl")._builtinLibs`. If you use different versions of Node.js for ESLint and your application, the list of core modules for each version may be different. + The above mentioned `_builtinLibs` property became available in 0.8, for earlier versions a hardcoded list of module names is used as a fallback. If your version of Node.js is older than 0.6 that list may be inaccurate. + +## When Not To Use It + +If you use a pattern such as [UMD][4] where the `require`d modules are not loaded in variable declarations, this rule will obviously do nothing for you. + +[1]: https://nodejs.org/api/modules.html#modules_core_modules +[2]: https://nodejs.org/api/modules.html#modules_file_modules +[3]: https://nodejs.org/api/modules.html#modules_loading_from_node_modules_folders +[4]: https://github.com/umdjs/umd + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-mixed-requires.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-mixed-requires.md) diff --git a/docs/8.0.0/rules/no-mixed-spaces-and-tabs.md b/docs/8.0.0/rules/no-mixed-spaces-and-tabs.md new file mode 100644 index 0000000000..de61c1c6ec --- /dev/null +++ b/docs/8.0.0/rules/no-mixed-spaces-and-tabs.md @@ -0,0 +1,84 @@ +--- +title: no-mixed-spaces-and-tabs - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-mixed-spaces-and-tabs.md +rule_type: layout +--- + + +# disallow mixed spaces and tabs for indentation (no-mixed-spaces-and-tabs) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +Most code conventions require either tabs or spaces be used for indentation. As such, it's usually an error if a single line of code is indented with both tabs and spaces. + +## Rule Details + +This rule disallows mixed spaces and tabs for indentation. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-mixed-spaces-and-tabs: "error"*/ + +function add(x, y) { +// --->..return x + y; + + return x + y; +} + +function main() { +// --->var x = 5, +// --->....y = 7; + + var x = 5, + y = 7; +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-mixed-spaces-and-tabs: "error"*/ + +function add(x, y) { +// --->return x + y; + return x + y; +} +``` + +## Options + +This rule has a string option. + +* `"smart-tabs"` allows mixed tabs and spaces when the spaces are used for alignment. + +### smart-tabs + +Examples of **correct** code for this rule with the `"smart-tabs"` option: + +```js +/*eslint no-mixed-spaces-and-tabs: ["error", "smart-tabs"]*/ + +function main() { +// --->var x = 5, +// --->....y = 7; + + var x = 5, + y = 7; +} +``` + + +## Further Reading + +* [Smart Tabs](https://www.emacswiki.org/emacs/SmartTabs) + +## Version + +This rule was introduced in ESLint 0.7.1. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-mixed-spaces-and-tabs.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-mixed-spaces-and-tabs.md) diff --git a/docs/8.0.0/rules/no-multi-assign.md b/docs/8.0.0/rules/no-multi-assign.md new file mode 100644 index 0000000000..3739ab8052 --- /dev/null +++ b/docs/8.0.0/rules/no-multi-assign.md @@ -0,0 +1,116 @@ +--- +title: no-multi-assign - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-multi-assign.md +rule_type: suggestion +--- + + +# Disallow Use of Chained Assignment Expressions (no-multi-assign) + +Chaining the assignment of variables can lead to unexpected results and be difficult to read. + +```js +(function() { + const foo = bar = 0; // Did you mean `foo = bar == 0`? + bar = 1; // This will not fail since `bar` is not constant. +})(); +console.log(bar); // This will output 1 since `bar` is not scoped. +``` + +## Rule Details + +This rule disallows using multiple assignments within a single statement. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-multi-assign: "error"*/ + +var a = b = c = 5; + +const foo = bar = "baz"; + +let a = + b = + c; + +class Foo { + a = b = 10; +} + +a = b = "quux"; +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-multi-assign: "error"*/ + +var a = 5; +var b = 5; +var c = 5; + +const foo = "baz"; +const bar = "baz"; + +let a = c; +let b = c; + +class Foo { + a = 10; + b = 10; +} + +a = "quux"; +b = "quux"; +``` + +## Options + +This rule has an object option: + +* `"ignoreNonDeclaration"`: When set to `true`, the rule allows chains that don't include initializing a variable in a declaration or initializing a class field. Default is `false`. + +### ignoreNonDeclaration + +Examples of **correct** code for the `{ "ignoreNonDeclaration": true }` option: + +```js +/*eslint no-multi-assign: ["error", { "ignoreNonDeclaration": true }]*/ + +let a; +let b; +a = b = "baz"; + +const x = {}; +const y = {}; +x.one = y.one = 1; +``` + +Examples of **incorrect** code for the `{ "ignoreNonDeclaration": true }` option: + +```js +/*eslint no-multi-assign: ["error", { "ignoreNonDeclaration": true }]*/ + +let a = b = "baz"; + +const foo = bar = 1; + +class Foo { + a = b = 10; +} +``` + +## Related Rules + +* [max-statements-per-line](max-statements-per-line) + +## Version + +This rule was introduced in ESLint 3.14.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-multi-assign.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-multi-assign.md) diff --git a/docs/8.0.0/rules/no-multi-spaces.md b/docs/8.0.0/rules/no-multi-spaces.md new file mode 100644 index 0000000000..421b3aa757 --- /dev/null +++ b/docs/8.0.0/rules/no-multi-spaces.md @@ -0,0 +1,190 @@ +--- +title: no-multi-spaces - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-multi-spaces.md +rule_type: layout +--- + + +# Disallow multiple spaces (no-multi-spaces) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +Multiple spaces in a row that are not used for indentation are typically mistakes. For example: + +```js + +if(foo === "bar") {} + +``` + +It's hard to tell, but there are two spaces between `foo` and `===`. Multiple spaces such as this are generally frowned upon in favor of single spaces: + +```js + +if(foo === "bar") {} + +``` + +## Rule Details + +This rule aims to disallow multiple whitespace around logical expressions, conditional expressions, declarations, array elements, object properties, sequences and function parameters. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-multi-spaces: "error"*/ + +var a = 1; + +if(foo === "bar") {} + +a << b + +var arr = [1, 2]; + +a ? b: c +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-multi-spaces: "error"*/ + +var a = 1; + +if(foo === "bar") {} + +a << b + +var arr = [1, 2]; + +a ? b: c +``` + +## Options + +This rule's configuration consists of an object with the following properties: + +* `"ignoreEOLComments": true` (defaults to `false`) ignores multiple spaces before comments that occur at the end of lines +* `"exceptions": { "Property": true }` (`"Property"` is the only node specified by default) specifies nodes to ignore + +### ignoreEOLComments + +Examples of **incorrect** code for this rule with the `{ "ignoreEOLComments": false }` (default) option: + +```js +/*eslint no-multi-spaces: ["error", { ignoreEOLComments: false }]*/ + +var x = 5; // comment +var x = 5; /* multiline + * comment + */ +``` + +Examples of **correct** code for this rule with the `{ "ignoreEOLComments": false }` (default) option: + +```js +/*eslint no-multi-spaces: ["error", { ignoreEOLComments: false }]*/ + +var x = 5; // comment +var x = 5; /* multiline + * comment + */ +``` + +Examples of **correct** code for this rule with the `{ "ignoreEOLComments": true }` option: + +```js +/*eslint no-multi-spaces: ["error", { ignoreEOLComments: true }]*/ + +var x = 5; // comment +var x = 5; // comment +var x = 5; /* multiline + * comment + */ +var x = 5; /* multiline + * comment + */ +``` + +### exceptions + +To avoid contradictions with other rules that require multiple spaces, this rule has an `exceptions` option to ignore certain nodes. + +This option is an object that expects property names to be AST node types as defined by [ESTree](https://github.com/estree/estree). The easiest way to determine the node types for `exceptions` is to use [AST Explorer](https://astexplorer.net/) with the espree parser. + +Only the `Property` node type is ignored by default, because for the [key-spacing](key-spacing) rule some alignment options require multiple spaces in properties of object literals. + +Examples of **correct** code for the default `"exceptions": { "Property": true }` option: + +```js +/*eslint no-multi-spaces: "error"*/ +/*eslint key-spacing: ["error", { align: "value" }]*/ + +var obj = { + first: "first", + second: "second" +}; +``` + +Examples of **incorrect** code for the `"exceptions": { "Property": false }` option: + +```js +/*eslint no-multi-spaces: ["error", { exceptions: { "Property": false } }]*/ +/*eslint key-spacing: ["error", { align: "value" }]*/ + +var obj = { + first: "first", + second: "second" +}; +``` + +Examples of **correct** code for the `"exceptions": { "BinaryExpression": true }` option: + +```js +/*eslint no-multi-spaces: ["error", { exceptions: { "BinaryExpression": true } }]*/ + +var a = 1 * 2; +``` + +Examples of **correct** code for the `"exceptions": { "VariableDeclarator": true }` option: + +```js +/*eslint no-multi-spaces: ["error", { exceptions: { "VariableDeclarator": true } }]*/ + +var someVar = 'foo'; +var someOtherVar = 'barBaz'; +``` + +Examples of **correct** code for the `"exceptions": { "ImportDeclaration": true }` option: + +```js +/*eslint no-multi-spaces: ["error", { exceptions: { "ImportDeclaration": true } }]*/ + +import mod from 'mod'; +import someOtherMod from 'some-other-mod'; +``` + +## When Not To Use It + +If you don't want to check and disallow multiple spaces, then you should turn this rule off. + +## Related Rules + +* [key-spacing](key-spacing) +* [space-infix-ops](space-infix-ops) +* [space-in-brackets](space-in-brackets) (deprecated) +* [space-in-parens](space-in-parens) +* [space-after-keywords](space-after-keywords) +* [space-unary-ops](space-unary-ops) +* [space-return-throw-case](space-return-throw-case) + +## Version + +This rule was introduced in ESLint 0.9.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-multi-spaces.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-multi-spaces.md) diff --git a/docs/8.0.0/rules/no-multi-str.md b/docs/8.0.0/rules/no-multi-str.md new file mode 100644 index 0000000000..de3f14cdc9 --- /dev/null +++ b/docs/8.0.0/rules/no-multi-str.md @@ -0,0 +1,51 @@ +--- +title: no-multi-str - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-multi-str.md +rule_type: suggestion +--- + + +# Disallow Multiline Strings (no-multi-str) + +It's possible to create multiline strings in JavaScript by using a slash before a newline, such as: + +```js +var x = "Line 1 \ + Line 2"; +``` + +Some consider this to be a bad practice as it was an undocumented feature of JavaScript that was only formalized later. + +## Rule Details + +This rule is aimed at preventing the use of multiline strings. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-multi-str: "error"*/ + +var x = "some very \ +long text"; +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-multi-str: "error"*/ + +var x = "some very long text"; + +var x = "some very " + + "long text"; +``` + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-multi-str.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-multi-str.md) diff --git a/docs/8.0.0/rules/no-multiple-empty-lines.md b/docs/8.0.0/rules/no-multiple-empty-lines.md new file mode 100644 index 0000000000..13d316fb15 --- /dev/null +++ b/docs/8.0.0/rules/no-multiple-empty-lines.md @@ -0,0 +1,141 @@ +--- +title: no-multiple-empty-lines - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-multiple-empty-lines.md +rule_type: layout +--- + + +# disallow multiple empty lines (no-multiple-empty-lines) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +Some developers prefer to have multiple blank lines removed, while others feel that it helps improve readability. Whitespace is useful for separating logical sections of code, but excess whitespace takes up more of the screen. + +## Rule Details + +This rule aims to reduce the scrolling required when reading through your code. It will warn when the maximum amount of empty lines has been exceeded. + +## Options + +This rule has an object option: + +- `"max"` (default: `2`) enforces a maximum number of consecutive empty lines. +- `"maxEOF"` enforces a maximum number of consecutive empty lines at the end of files. +- `"maxBOF"` enforces a maximum number of consecutive empty lines at the beginning of files. + +### max + +Examples of **incorrect** code for this rule with the default `{ "max": 2 }` option: + +```js +/*eslint no-multiple-empty-lines: "error"*/ + +var foo = 5; + + + +var bar = 3; +``` + +Examples of **correct** code for this rule with the default `{ "max": 2 }` option: + +```js +/*eslint no-multiple-empty-lines: "error"*/ + +var foo = 5; + + +var bar = 3; +``` + +### maxEOF + +Examples of **incorrect** code for this rule with the `{ max: 2, maxEOF: 0 }` options: + +```js +/*eslint no-multiple-empty-lines: ["error", { "max": 2, "maxEOF": 0 }]*/ + +var foo = 5; + + +var bar = 3; + + +``` + +Examples of **correct** code for this rule with the `{ max: 2, maxEOF: 0 }` options: + +```js +/*eslint no-multiple-empty-lines: ["error", { "max": 2, "maxEOF": 0 }]*/ + +var foo = 5; + + +var bar = 3; +``` + +**Note**: Although this ensures zero empty lines at the EOF, most editors will still show one empty line at the end if the file ends with a line break, as illustrated below. There is no empty line at the end of a file after the last `\n`, although editors may show an additional line. A true additional line would be represented by `\n\n`. + +**Incorrect**: + +``` +1 /*eslint no-multiple-empty-lines: ["error", { "max": 2, "maxEOF": 0 }]*/⏎ +2 ⏎ +3 var foo = 5;⏎ +4 ⏎ +5 ⏎ +6 var bar = 3;⏎ +7 ⏎ +8 +``` + +**Correct**: + +``` +1 /*eslint no-multiple-empty-lines: ["error", { "max": 2, "maxEOF": 0 }]*/⏎ +2 ⏎ +3 var foo = 5;⏎ +4 ⏎ +5 ⏎ +6 var bar = 3;⏎ +7 +``` + +### maxBOF + +Examples of **incorrect** code for this rule with the `{ max: 2, maxBOF: 1 }` options: + +```js +/*eslint no-multiple-empty-lines: ["error", { "max": 2, "maxBOF": 1 }]*/ + + +var foo = 5; + + +var bar = 3; +``` + +Examples of **correct** code for this rule with the `{ max: 2, maxBOF: 1 }` options: + +```js +/*eslint no-multiple-empty-lines: ["error", { "max": 2, "maxBOF": 1}]*/ + +var foo = 5; + + +var bar = 3; +``` + +## When Not To Use It + +If you do not care about extra blank lines, turn this off. + +## Version + +This rule was introduced in ESLint 0.9.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-multiple-empty-lines.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-multiple-empty-lines.md) diff --git a/docs/8.0.0/rules/no-native-reassign.md b/docs/8.0.0/rules/no-native-reassign.md new file mode 100644 index 0000000000..51d9fecda5 --- /dev/null +++ b/docs/8.0.0/rules/no-native-reassign.md @@ -0,0 +1,108 @@ +--- +title: no-native-reassign - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-native-reassign.md +rule_type: suggestion +--- + + +# Disallow Reassignment of Native Objects (no-native-reassign) + +This rule was **deprecated** in ESLint v3.3.0 and replaced by the [no-global-assign](no-global-assign) rule. + +JavaScript environments contain a number of built-in global variables, such as `window` in browsers and `process` in Node.js. In almost all cases, you don't want to assign a value to these global variables as doing so could result in losing access to important functionality. For example, you probably don't want to do this in browser code: + +```js +window = {}; +``` + +While examples such as `window` are obvious, there are often hundreds of built-in global objects provided by JavaScript environments. It can be hard to know if you're assigning to a global variable or not. + +## Rule Details + +This rule disallows modifications to read-only global variables. + +ESLint has the capability to configure global variables as read-only. + +* [Specifying Environments](../user-guide/configuring#specifying-environments) +* [Specifying Globals](../user-guide/configuring#specifying-globals) + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-native-reassign: "error"*/ + +Object = null +undefined = 1 +``` + +```js +/*eslint no-native-reassign: "error"*/ +/*eslint-env browser*/ + +window = {} +length = 1 +top = 1 +``` + +```js +/*eslint no-native-reassign: "error"*/ +/*global a:readonly*/ + +a = 1 +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-native-reassign: "error"*/ + +a = 1 +var b = 1 +b = 2 +``` + +```js +/*eslint no-native-reassign: "error"*/ +/*eslint-env browser*/ + +onload = function() {} +``` + +```js +/*eslint no-native-reassign: "error"*/ +/*global a:writable*/ + +a = 1 +``` + +## Options + +This rule accepts an `exceptions` option, which can be used to specify a list of builtins for which reassignments will be allowed: + +```json +{ + "rules": { + "no-native-reassign": ["error", {"exceptions": ["Object"]}] + } +} +``` + +## When Not To Use It + +If you are trying to override one of the native objects. + +## Related Rules + +* [no-extend-native](no-extend-native) +* [no-redeclare](no-redeclare) +* [no-shadow](no-shadow) + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-native-reassign.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-native-reassign.md) diff --git a/docs/8.0.0/rules/no-negated-condition.md b/docs/8.0.0/rules/no-negated-condition.md new file mode 100644 index 0000000000..24af24d34b --- /dev/null +++ b/docs/8.0.0/rules/no-negated-condition.md @@ -0,0 +1,75 @@ +--- +title: no-negated-condition - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-negated-condition.md +rule_type: suggestion +--- + + +# disallow negated conditions (no-negated-condition) + +Negated conditions are more difficult to understand. Code can be made more readable by inverting the condition instead. + +## Rule Details + +This rule disallows negated conditions in either of the following: + +* `if` statements which have an `else` branch +* ternary expressions + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-negated-condition: "error"*/ + +if (!a) { + doSomething(); +} else { + doSomethingElse(); +} + +if (a != b) { + doSomething(); +} else { + doSomethingElse(); +} + +if (a !== b) { + doSomething(); +} else { + doSomethingElse(); +} + +!a ? c : b +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-negated-condition: "error"*/ + +if (!a) { + doSomething(); +} + +if (!a) { + doSomething(); +} else if (b) { + doSomething(); +} + +if (a != b) { + doSomething(); +} + +a ? b : c +``` + +## Version + +This rule was introduced in ESLint 1.6.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-negated-condition.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-negated-condition.md) diff --git a/docs/8.0.0/rules/no-negated-in-lhs.md b/docs/8.0.0/rules/no-negated-in-lhs.md new file mode 100644 index 0000000000..231211d29e --- /dev/null +++ b/docs/8.0.0/rules/no-negated-in-lhs.md @@ -0,0 +1,58 @@ +--- +title: no-negated-in-lhs - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-negated-in-lhs.md +rule_type: problem +--- + + +# disallow negating the left operand in `in` expressions (no-negated-in-lhs) + +This rule was **deprecated** in ESLint v3.3.0 and replaced by the [no-unsafe-negation](no-unsafe-negation) rule. + +## Rule Details + +Just as developers might type `-a + b` when they mean `-(a + b)` for the negative of a sum, they might type `!key in object` by mistake when they almost certainly mean `!(key in object)` to test that a key is not in an object. + +## Rule Details + +This rule disallows negating the left operand in `in` expressions. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-negated-in-lhs: "error"*/ + +if(!key in object) { + // operator precedence makes it equivalent to (!key) in object + // and type conversion makes it equivalent to (key ? "false" : "true") in object +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-negated-in-lhs: "error"*/ + +if(!(key in object)) { + // key is not in object +} + +if(('' + !key) in object) { + // make operator precedence and type conversion explicit + // in a rare situation when that is the intended meaning +} +``` + +## When Not To Use It + +Never. + +## Version + +This rule was introduced in ESLint 0.1.2. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-negated-in-lhs.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-negated-in-lhs.md) diff --git a/docs/8.0.0/rules/no-nested-ternary.md b/docs/8.0.0/rules/no-nested-ternary.md new file mode 100644 index 0000000000..fe4d18337e --- /dev/null +++ b/docs/8.0.0/rules/no-nested-ternary.md @@ -0,0 +1,61 @@ +--- +title: no-nested-ternary - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-nested-ternary.md +rule_type: suggestion +--- + + +# disallow nested ternary expressions (no-nested-ternary) + +Nesting ternary expressions can make code more difficult to understand. + +```js +var foo = bar ? baz : qux === quxx ? bing : bam; +``` + +## Rule Details + +The `no-nested-ternary` rule disallows nested ternary expressions. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-nested-ternary: "error"*/ + +var thing = foo ? bar : baz === qux ? quxx : foobar; + +foo ? baz === qux ? quxx() : foobar() : bar(); +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-nested-ternary: "error"*/ + +var thing = foo ? bar : foobar; + +var thing; + +if (foo) { + thing = bar; +} else if (baz === qux) { + thing = quxx; +} else { + thing = foobar; +} +``` + +## Related Rules + +* [no-ternary](no-ternary) +* [no-unneeded-ternary](no-unneeded-ternary) + +## Version + +This rule was introduced in ESLint 0.2.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-nested-ternary.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-nested-ternary.md) diff --git a/docs/8.0.0/rules/no-new-func.md b/docs/8.0.0/rules/no-new-func.md new file mode 100644 index 0000000000..2c7586404b --- /dev/null +++ b/docs/8.0.0/rules/no-new-func.md @@ -0,0 +1,53 @@ +--- +title: no-new-func - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-new-func.md +rule_type: suggestion +--- + + +# Disallow Function Constructor (no-new-func) + +It's possible to create functions in JavaScript using the `Function` constructor, such as: + +```js +var x = new Function("a", "b", "return a + b"); +``` + +This is considered by many to be a bad practice due to the difficulty in debugging and reading these types of functions. + +## Rule Details + +This error is raised to highlight the use of a bad practice. By passing a string to the Function constructor, you are requiring the engine to parse that string much in the way it has to when you call the `eval` function. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-new-func: "error"*/ + +var x = new Function("a", "b", "return a + b"); +var x = Function("a", "b", "return a + b"); +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-new-func: "error"*/ + +var x = function (a, b) { + return a + b; +}; +``` + +## When Not To Use It + +In more advanced cases where you really need to use the `Function` constructor. + +## Version + +This rule was introduced in ESLint 0.0.7. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-new-func.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-new-func.md) diff --git a/docs/8.0.0/rules/no-new-object.md b/docs/8.0.0/rules/no-new-object.md new file mode 100644 index 0000000000..c8db874519 --- /dev/null +++ b/docs/8.0.0/rules/no-new-object.md @@ -0,0 +1,70 @@ +--- +title: no-new-object - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-new-object.md +rule_type: suggestion +--- + + +# disallow `Object` constructors (no-new-object) + +The `Object` constructor is used to create new generic objects in JavaScript, such as: + +```js +var myObject = new Object(); +``` + +However, this is no different from using the more concise object literal syntax: + +```js +var myObject = {}; +``` + +For this reason, many prefer to always use the object literal syntax and never use the `Object` constructor. + +While there are no performance differences between the two approaches, the byte savings and conciseness of the object literal form is what has made it the de facto way of creating new objects. + +## Rule Details + +This rule disallows `Object` constructors. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-new-object: "error"*/ + +var myObject = new Object(); + +new Object(); +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-new-object: "error"*/ + +var myObject = new CustomObject(); + +var myObject = {}; + +var Object = function Object() {}; +new Object(); +``` + +## When Not To Use It + +If you wish to allow the use of the `Object` constructor, you can safely turn this rule off. + +## Related Rules + +* [no-array-constructor](no-array-constructor) +* [no-new-wrappers](no-new-wrappers) + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-new-object.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-new-object.md) diff --git a/docs/8.0.0/rules/no-new-require.md b/docs/8.0.0/rules/no-new-require.md new file mode 100644 index 0000000000..c1e49a13cd --- /dev/null +++ b/docs/8.0.0/rules/no-new-require.md @@ -0,0 +1,65 @@ +--- +title: no-new-require - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-new-require.md +rule_type: suggestion +--- + + +# Disallow new require (no-new-require) + +This rule was **deprecated** in ESLint v7.0.0. Please use the corresponding rule in [`eslint-plugin-node`](https://github.com/mysticatea/eslint-plugin-node). + +The `require` function is used to include modules that exist in separate files, such as: + +```js +var appHeader = require('app-header'); +``` + +Some modules return a constructor which can potentially lead to code such as: + +```js +var appHeader = new require('app-header'); +``` + +Unfortunately, this introduces a high potential for confusion since the code author likely meant to write: + +```js +var appHeader = new (require('app-header')); +``` + +For this reason, it is usually best to disallow this particular expression. + +## Rule Details + +This rule aims to eliminate use of the `new require` expression. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-new-require: "error"*/ + +var appHeader = new require('app-header'); +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-new-require: "error"*/ + +var AppHeader = require('app-header'); +var appHeader = new AppHeader(); +``` + +## When Not To Use It + +If you are using a custom implementation of `require` and your code will never be used in projects where a standard `require` (CommonJS, Node.js, AMD) is expected, you can safely turn this rule off. + +## Version + +This rule was introduced in ESLint 0.6.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-new-require.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-new-require.md) diff --git a/docs/8.0.0/rules/no-new-symbol.md b/docs/8.0.0/rules/no-new-symbol.md new file mode 100644 index 0000000000..5f0f1935cd --- /dev/null +++ b/docs/8.0.0/rules/no-new-symbol.md @@ -0,0 +1,67 @@ +--- +title: no-new-symbol - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-new-symbol.md +rule_type: problem +--- + + +# Disallow Symbol Constructor (no-new-symbol) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +`Symbol` is not intended to be used with the `new` operator, but to be called as a function. + +```js +var foo = new Symbol("foo"); +``` + +This throws a `TypeError` exception. + +## Rule Details + +This rule is aimed at preventing the accidental calling of `Symbol` with the `new` operator. + +## Examples + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-new-symbol: "error"*/ +/*eslint-env es6*/ + +var foo = new Symbol('foo'); +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-new-symbol: "error"*/ +/*eslint-env es6*/ + +var foo = Symbol('foo'); + + +// Ignores shadowed Symbol. +function bar(Symbol) { + const baz = new Symbol("baz"); +} + +``` + +## When Not To Use It + +This rule should not be used in ES3/5 environments. + +## Further Reading + +* [Symbol Objects specification](https://www.ecma-international.org/ecma-262/6.0/#sec-symbol-objects) + +## Version + +This rule was introduced in ESLint 2.0.0-beta.1. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-new-symbol.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-new-symbol.md) diff --git a/docs/8.0.0/rules/no-new-wrappers.md b/docs/8.0.0/rules/no-new-wrappers.md new file mode 100644 index 0000000000..b1c8e85d97 --- /dev/null +++ b/docs/8.0.0/rules/no-new-wrappers.md @@ -0,0 +1,95 @@ +--- +title: no-new-wrappers - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-new-wrappers.md +rule_type: suggestion +--- + + +# Disallow Primitive Wrapper Instances (no-new-wrappers) + +There are three primitive types in JavaScript that have wrapper objects: string, number, and boolean. These are represented by the constructors `String`, `Number`, and `Boolean`, respectively. The primitive wrapper types are used whenever one of these primitive values is read, providing them with object-like capabilities such as methods. Behind the scenes, an object of the associated wrapper type is created and then destroyed, which is why you can call methods on primitive values, such as: + +```js +var text = "Hello world".substring(2); +``` + +Behind the scenes in this example, a `String` object is constructed. The `substring()` method exists on `String.prototype` and so is accessible to the string instance. + +It's also possible to manually create a new wrapper instance: + +```js +var stringObject = new String("Hello world"); +var numberObject = new Number(33); +var booleanObject = new Boolean(false); +``` + +Although possible, there aren't any good reasons to use these primitive wrappers as constructors. They tend to confuse other developers more than anything else because they seem like they should act as primitives, but they do not. For example: + +```js +var stringObject = new String("Hello world"); +console.log(typeof stringObject); // "object" + +var text = "Hello world"; +console.log(typeof text); // "string" + +var booleanObject = new Boolean(false); +if (booleanObject) { // all objects are truthy! + console.log("This executes"); +} +``` + +The first problem is that primitive wrapper objects are, in fact, objects. That means `typeof` will return `"object"` instead of `"string"`, `"number"`, or `"boolean"`. The second problem comes with boolean objects. Every object is truthy, that means an instance of `Boolean` always resolves to `true` even when its actual value is `false`. + +For these reasons, it's considered a best practice to avoid using primitive wrapper types with `new`. + +## Rule Details + +This rule aims to eliminate the use of `String`, `Number`, and `Boolean` with the `new` operator. As such, it warns whenever it sees `new String`, `new Number`, or `new Boolean`. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-new-wrappers: "error"*/ + +var stringObject = new String("Hello world"); +var numberObject = new Number(33); +var booleanObject = new Boolean(false); + +var stringObject = new String; +var numberObject = new Number; +var booleanObject = new Boolean; +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-new-wrappers: "error"*/ + +var text = String(someValue); +var num = Number(someValue); + +var object = new MyString(); +``` + +## When Not To Use It + +If you want to allow the use of primitive wrapper objects, then you can safely disable this rule. + +## Further Reading + +* [Wrapper objects](https://www.inkling.com/read/javascript-definitive-guide-david-flanagan-6th/chapter-3/wrapper-objects) + +## Related Rules + +* [no-array-constructor](no-array-constructor) +* [no-new-object](no-new-object) + +## Version + +This rule was introduced in ESLint 0.0.6. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-new-wrappers.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-new-wrappers.md) diff --git a/docs/8.0.0/rules/no-new.md b/docs/8.0.0/rules/no-new.md new file mode 100644 index 0000000000..84868be3d0 --- /dev/null +++ b/docs/8.0.0/rules/no-new.md @@ -0,0 +1,54 @@ +--- +title: no-new - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-new.md +rule_type: suggestion +--- + + +# Disallow new For Side Effects (no-new) + +The goal of using `new` with a constructor is typically to create an object of a particular type and store that object in a variable, such as: + +```js +var person = new Person(); +``` + +It's less common to use `new` and not store the result, such as: + +```js +new Person(); +``` + +In this case, the created object is thrown away because its reference isn't stored anywhere, and in many cases, this means that the constructor should be replaced with a function that doesn't require `new` to be used. + +## Rule Details + +This rule is aimed at maintaining consistency and convention by disallowing constructor calls using the `new` keyword that do not assign the resulting object to a variable. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-new: "error"*/ + +new Thing(); +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-new: "error"*/ + +var thing = new Thing(); + +Thing(); +``` + +## Version + +This rule was introduced in ESLint 0.0.7. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-new.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-new.md) diff --git a/docs/8.0.0/rules/no-nonoctal-decimal-escape.md b/docs/8.0.0/rules/no-nonoctal-decimal-escape.md new file mode 100644 index 0000000000..2b13f3f097 --- /dev/null +++ b/docs/8.0.0/rules/no-nonoctal-decimal-escape.md @@ -0,0 +1,83 @@ +--- +title: no-nonoctal-decimal-escape - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-nonoctal-decimal-escape.md +rule_type: suggestion +--- + + +# Disallow `\8` and `\9` escape sequences in string literals (no-nonoctal-decimal-escape) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +(hasSuggestions) Some problems reported by this rule are manually fixable by editor [suggestions](../developer-guide/working-with-rules#providing-suggestions). + +Although not being specified in the language until ECMAScript 2021, `\8` and `\9` escape sequences in string literals were allowed in most JavaScript engines, and treated as "useless" escapes: + +```js +"\8" === "8"; // true +"\9" === "9"; // true +``` + +Since ECMAScript 2021, these escape sequences are specified as [non-octal decimal escape sequences](https://tc39.es/ecma262/#prod-annexB-NonOctalDecimalEscapeSequence), retaining the same behavior. + +Nevertheless, the ECMAScript specification treats `\8` and `\9` in string literals as a legacy feature. This syntax is optional if the ECMAScript host is not a web browser. Browsers still have to support it, but only in non-strict mode. + +Regardless of your targeted environment, these escape sequences shouldn't be used when writing new code. + +## Rule Details + +This rule disallows `\8` and `\9` escape sequences in string literals. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-nonoctal-decimal-escape: "error"*/ + +"\8"; + +"\9"; + +var foo = "w\8less"; + +var bar = "December 1\9"; + +var baz = "Don't use \8 and \9 escapes."; + +var quux = "\0\8"; +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-nonoctal-decimal-escape: "error"*/ + +"8"; + +"9"; + +var foo = "w8less"; + +var bar = "December 19"; + +var baz = "Don't use \\8 and \\9 escapes."; + +var quux = "\0\u0038"; +``` + +## Further Reading + +* [NonOctalDecimalEscapeSequence](https://tc39.es/ecma262/#prod-annexB-NonOctalDecimalEscapeSequence) in ECMAScript specification + +## Related Rules + +* [no-octal-escape](no-octal-escape) + +## Version + +This rule was introduced in ESLint 7.14.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-nonoctal-decimal-escape.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-nonoctal-decimal-escape.md) diff --git a/docs/8.0.0/rules/no-obj-calls.md b/docs/8.0.0/rules/no-obj-calls.md new file mode 100644 index 0000000000..45377fa521 --- /dev/null +++ b/docs/8.0.0/rules/no-obj-calls.md @@ -0,0 +1,84 @@ +--- +title: no-obj-calls - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-obj-calls.md +rule_type: problem +--- + + +# disallow calling global object properties as functions (no-obj-calls) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +ECMAScript provides several global objects that are intended to be used as-is. Some of these objects look as if they could be constructors due their capitalization (such as `Math` and `JSON`) but will throw an error if you try to execute them as functions. + +The [ECMAScript 5 specification](https://es5.github.io/#x15.8) makes it clear that both `Math` and `JSON` cannot be invoked: + +> The Math object does not have a `[[Call]]` internal property; it is not possible to invoke the Math object as a function. + +The [ECMAScript 2015 specification](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-reflect-object) makes it clear that `Reflect` cannot be invoked: + +> The Reflect object also does not have a `[[Call]]` internal method; it is not possible to invoke the Reflect object as a function. + +And the [ECMAScript 2017 specification](https://www.ecma-international.org/ecma-262/8.0/index.html#sec-atomics-object) makes it clear that `Atomics` cannot be invoked: + +> The Atomics object does not have a `[[Call]]` internal method; it is not possible to invoke the Atomics object as a function. + +## Rule Details + +This rule disallows calling the `Math`, `JSON`, `Reflect` and `Atomics` objects as functions. + +This rule also disallows using these objects as constructors with the `new` operator. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-obj-calls: "error"*/ +/*eslint-env es2017*/ + +var math = Math(); + +var newMath = new Math(); + +var json = JSON(); + +var newJSON = new JSON(); + +var reflect = Reflect(); + +var newReflect = new Reflect(); + +var atomics = Atomics(); + +var newAtomics = new Atomics(); +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-obj-calls: "error"*/ +/*eslint-env es2017*/ + +function area(r) { + return Math.PI * r * r; +} + +var object = JSON.parse("{}"); + +var value = Reflect.get({ x: 1, y: 2 }, "x"); + +var first = Atomics.load(foo, 0); +``` + +## Further Reading + +* [The Math Object](https://es5.github.io/#x15.8) + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-obj-calls.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-obj-calls.md) diff --git a/docs/8.0.0/rules/no-octal-escape.md b/docs/8.0.0/rules/no-octal-escape.md new file mode 100644 index 0000000000..7c742838e1 --- /dev/null +++ b/docs/8.0.0/rules/no-octal-escape.md @@ -0,0 +1,48 @@ +--- +title: no-octal-escape - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-octal-escape.md +rule_type: suggestion +--- + + +# disallow octal escape sequences in string literals (no-octal-escape) + +As of the ECMAScript 5 specification, octal escape sequences in string literals are deprecated and should not be used. Unicode escape sequences should be used instead. + +```js +var foo = "Copyright \251"; +``` + +## Rule Details + +This rule disallows octal escape sequences in string literals. + +If ESLint parses code in strict mode, the parser (instead of this rule) reports the error. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-octal-escape: "error"*/ + +var foo = "Copyright \251"; +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-octal-escape: "error"*/ + +var foo = "Copyright \u00A9"; // unicode + +var foo = "Copyright \xA9"; // hexadecimal +``` + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-octal-escape.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-octal-escape.md) diff --git a/docs/8.0.0/rules/no-octal.md b/docs/8.0.0/rules/no-octal.md new file mode 100644 index 0000000000..bc51541b9f --- /dev/null +++ b/docs/8.0.0/rules/no-octal.md @@ -0,0 +1,55 @@ +--- +title: no-octal - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-octal.md +rule_type: suggestion +--- + + +# disallow octal literals (no-octal) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +Octal literals are numerals that begin with a leading zero, such as: + +```js +var num = 071; // 57 +``` + +Because the leading zero which identifies an octal literal has been a source of confusion and error in JavaScript code, ECMAScript 5 deprecates the use of octal numeric literals. + +## Rule Details + +The rule disallows octal literals. + +If ESLint parses code in strict mode, the parser (instead of this rule) reports the error. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-octal: "error"*/ + +var num = 071; +var result = 5 + 07; +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-octal: "error"*/ + +var num = "071"; +``` + +## Compatibility + +* **JSHint**: W115 + +## Version + +This rule was introduced in ESLint 0.0.6. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-octal.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-octal.md) diff --git a/docs/8.0.0/rules/no-param-reassign.md b/docs/8.0.0/rules/no-param-reassign.md new file mode 100644 index 0000000000..3c12a0ba35 --- /dev/null +++ b/docs/8.0.0/rules/no-param-reassign.md @@ -0,0 +1,177 @@ +--- +title: no-param-reassign - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-param-reassign.md +rule_type: suggestion +--- + + +# Disallow Reassignment of Function Parameters (no-param-reassign) + +Assignment to variables declared as function parameters can be misleading and lead to confusing behavior, as modifying function parameters will also mutate the `arguments` object. Often, assignment to function parameters is unintended and indicative of a mistake or programmer error. + +This rule can be also configured to fail when function parameters are modified. Side effects on parameters can cause counter-intuitive execution flow and make errors difficult to track down. + +## Rule Details + +This rule aims to prevent unintended behavior caused by modification or reassignment of function parameters. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-param-reassign: "error"*/ + +function foo(bar) { + bar = 13; +} + +function foo(bar) { + bar++; +} + +function foo(bar) { + for (bar in baz) {} +} + +function foo(bar) { + for (bar of baz) {} +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-param-reassign: "error"*/ + +function foo(bar) { + var baz = bar; +} +``` + +## Options + +This rule takes one option, an object, with a boolean property `"props"`, and arrays `"ignorePropertyModificationsFor"` and `"ignorePropertyModificationsForRegex"`. `"props"` is `false` by default. If `"props"` is set to `true`, this rule warns against the modification of parameter properties unless they're included in `"ignorePropertyModificationsFor"` or `"ignorePropertyModificationsForRegex"`, which is an empty array by default. + +### props + +Examples of **correct** code for the default `{ "props": false }` option: + +```js +/*eslint no-param-reassign: ["error", { "props": false }]*/ + +function foo(bar) { + bar.prop = "value"; +} + +function foo(bar) { + delete bar.aaa; +} + +function foo(bar) { + bar.aaa++; +} + +function foo(bar) { + for (bar.aaa in baz) {} +} + +function foo(bar) { + for (bar.aaa of baz) {} +} +``` + +Examples of **incorrect** code for the `{ "props": true }` option: + +```js +/*eslint no-param-reassign: ["error", { "props": true }]*/ + +function foo(bar) { + bar.prop = "value"; +} + +function foo(bar) { + delete bar.aaa; +} + +function foo(bar) { + bar.aaa++; +} + +function foo(bar) { + for (bar.aaa in baz) {} +} + +function foo(bar) { + for (bar.aaa of baz) {} +} +``` + +Examples of **correct** code for the `{ "props": true }` option with `"ignorePropertyModificationsFor"` set: + +```js +/*eslint no-param-reassign: ["error", { "props": true, "ignorePropertyModificationsFor": ["bar"] }]*/ + +function foo(bar) { + bar.prop = "value"; +} + +function foo(bar) { + delete bar.aaa; +} + +function foo(bar) { + bar.aaa++; +} + +function foo(bar) { + for (bar.aaa in baz) {} +} + +function foo(bar) { + for (bar.aaa of baz) {} +} +``` + +Examples of **correct** code for the `{ "props": true }` option with `"ignorePropertyModificationsForRegex"` set: + +```js +/*eslint no-param-reassign: ["error", { "props": true, "ignorePropertyModificationsForRegex": ["^bar"] }]*/ + +function foo(barVar) { + barVar.prop = "value"; +} + +function foo(barrito) { + delete barrito.aaa; +} + +function foo(bar_) { + bar_.aaa++; +} + +function foo(barBaz) { + for (barBaz.aaa in baz) {} +} + +function foo(barBaz) { + for (barBaz.aaa of baz) {} +} +``` + + +## When Not To Use It + +If you want to allow assignment to function parameters, then you can safely disable this rule. + +## Further Reading + +* [JavaScript: Don’t Reassign Your Function Arguments](https://spin.atomicobject.com/2011/04/10/javascript-don-t-reassign-your-function-arguments/) + +## Version + +This rule was introduced in ESLint 0.18.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-param-reassign.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-param-reassign.md) diff --git a/docs/8.0.0/rules/no-path-concat.md b/docs/8.0.0/rules/no-path-concat.md new file mode 100644 index 0000000000..b6fb983b8b --- /dev/null +++ b/docs/8.0.0/rules/no-path-concat.md @@ -0,0 +1,69 @@ +--- +title: no-path-concat - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-path-concat.md +rule_type: suggestion +--- + + +# Disallow string concatenation when using `__dirname` and `__filename` (no-path-concat) + +This rule was **deprecated** in ESLint v7.0.0. Please use the corresponding rule in [`eslint-plugin-node`](https://github.com/mysticatea/eslint-plugin-node). + +In Node.js, the `__dirname` and `__filename` global variables contain the directory path and the file path of the currently executing script file, respectively. Sometimes, developers try to use these variables to create paths to other files, such as: + +```js +var fullPath = __dirname + "/foo.js"; +``` + +However, there are a few problems with this. First, you can't be sure what type of system the script is running on. Node.js can be run on any computer, including Windows, which uses a different path separator. It's very easy, therefore, to create an invalid path using string concatenation and assuming Unix-style separators. There's also the possibility of having double separators, or otherwise ending up with an invalid path. + +In order to avoid any confusion as to how to create the correct path, Node.js provides the `path` module. This module uses system-specific information to always return the correct value. So you can rewrite the previous example as: + +```js +var fullPath = path.join(__dirname, "foo.js"); +``` + +This example doesn't need to include separators as `path.join()` will do it in the most appropriate manner. Alternately, you can use `path.resolve()` to retrieve the fully-qualified path: + +```js +var fullPath = path.resolve(__dirname, "foo.js"); +``` + +Both `path.join()` and `path.resolve()` are suitable replacements for string concatenation wherever file or directory paths are being created. + +## Rule Details + +This rule aims to prevent string concatenation of directory paths in Node.js + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-path-concat: "error"*/ + +var fullPath = __dirname + "/foo.js"; + +var fullPath = __filename + "/foo.js"; + +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-path-concat: "error"*/ + +var fullPath = dirname + "/foo.js"; +``` + +## When Not To Use It + +If you want to allow string concatenation of path names. + +## Version + +This rule was introduced in ESLint 0.4.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-path-concat.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-path-concat.md) diff --git a/docs/8.0.0/rules/no-plusplus.md b/docs/8.0.0/rules/no-plusplus.md new file mode 100644 index 0000000000..fd93326c61 --- /dev/null +++ b/docs/8.0.0/rules/no-plusplus.md @@ -0,0 +1,117 @@ +--- +title: no-plusplus - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-plusplus.md +rule_type: suggestion +--- + + +# disallow the unary operators `++` and `--` (no-plusplus) + +Because the unary `++` and `--` operators are subject to automatic semicolon insertion, differences in whitespace can change semantics of source code. + +```js +var i = 10; +var j = 20; + +i ++ +j +// i = 11, j = 20 +``` + +```js +var i = 10; +var j = 20; + +i +++ +j +// i = 10, j = 21 +``` + +## Rule Details + +This rule disallows the unary operators `++` and `--`. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-plusplus: "error"*/ + +var foo = 0; +foo++; + +var bar = 42; +bar--; + +for (i = 0; i < l; i++) { + return; +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-plusplus: "error"*/ + +var foo = 0; +foo += 1; + +var bar = 42; +bar -= 1; + +for (i = 0; i < l; i += 1) { + return; +} +``` + +## Options + +This rule has an object option. + +* `"allowForLoopAfterthoughts": true` allows unary operators `++` and `--` in the afterthought (final expression) of a `for` loop. + +### allowForLoopAfterthoughts + +Examples of **correct** code for this rule with the `{ "allowForLoopAfterthoughts": true }` option: + +```js +/*eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }]*/ + +for (i = 0; i < l; i++) { + doSomething(i); +} + +for (i = l; i >= 0; i--) { + doSomething(i); +} + +for (i = 0, j = l; i < l; i++, j--) { + doSomething(i, j); +} +``` + +Examples of **incorrect** code for this rule with the `{ "allowForLoopAfterthoughts": true }` option: + +```js +/*eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }]*/ + +for (i = 0; i < l; j = i++) { + doSomething(i, j); +} + +for (i = l; i--;) { + doSomething(i); +} + +for (i = 0; i < l;) i++; +``` + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-plusplus.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-plusplus.md) diff --git a/docs/8.0.0/rules/no-process-env.md b/docs/8.0.0/rules/no-process-env.md new file mode 100644 index 0000000000..99e53711f5 --- /dev/null +++ b/docs/8.0.0/rules/no-process-env.md @@ -0,0 +1,58 @@ +--- +title: no-process-env - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-process-env.md +rule_type: suggestion +--- + + +# Disallow process.env (no-process-env) + +This rule was **deprecated** in ESLint v7.0.0. Please use the corresponding rule in [`eslint-plugin-node`](https://github.com/mysticatea/eslint-plugin-node). + +The `process.env` object in Node.js is used to store deployment/configuration parameters. Littering it through out a project could lead to maintenance issues as it's another kind of global dependency. As such, it could lead to merge conflicts in a multi-user setup and deployment issues in a multi-server setup. Instead, one of the best practices is to define all those parameters in a single configuration/settings file which could be accessed throughout the project. + + +## Rule Details + +This rule is aimed at discouraging use of `process.env` to avoid global dependencies. As such, it will warn whenever `process.env` is used. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-process-env: "error"*/ + +if(process.env.NODE_ENV === "development") { + //... +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-process-env: "error"*/ + +var config = require("./config"); + +if(config.env === "development") { + //... +} +``` + +## When Not To Use It + +If you prefer to use `process.env` throughout your project to retrieve values from environment variables, then you can safely disable this rule. + +## Further Reading + +* [How to store Node.js deployment settings/configuration files? - Stack Overflow](https://stackoverflow.com/questions/5869216/how-to-store-node-js-deployment-settings-configuration-files) +* [Storing Node.js application config data - Ben Hall's blog](https://blog.benhall.me.uk/2012/02/storing-application-config-data-in/) + +## Version + +This rule was introduced in ESLint 0.9.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-process-env.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-process-env.md) diff --git a/docs/8.0.0/rules/no-process-exit.md b/docs/8.0.0/rules/no-process-exit.md new file mode 100644 index 0000000000..0aa57a7451 --- /dev/null +++ b/docs/8.0.0/rules/no-process-exit.md @@ -0,0 +1,67 @@ +--- +title: no-process-exit - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-process-exit.md +rule_type: suggestion +--- + + +# Disallow process.exit() (no-process-exit) + +This rule was **deprecated** in ESLint v7.0.0. Please use the corresponding rule in [`eslint-plugin-node`](https://github.com/mysticatea/eslint-plugin-node). + +The `process.exit()` method in Node.js is used to immediately stop the Node.js process and exit. This is a dangerous operation because it can occur in any method at any point in time, potentially stopping a Node.js application completely when an error occurs. For example: + +```js +if (somethingBadHappened) { + console.error("Something bad happened!"); + process.exit(1); +} +``` + +This code could appear in any module and will stop the entire application when `somethingBadHappened` is truthy. This doesn't give the application any chance to respond to the error. It's usually better to throw an error and allow the application to handle it appropriately: + +```js +if (somethingBadHappened) { + throw new Error("Something bad happened!"); +} +``` + +By throwing an error in this way, other parts of the application have an opportunity to handle the error rather than stopping the application altogether. If the error bubbles all the way up to the process without being handled, then the process will exit and a non-zero exit code will returned, so the end result is the same. + +If you are using `process.exit()` only for specifying the exit code, you can set [`process.exitCode`](https://nodejs.org/api/process.html#process_process_exitcode) (introduced in Node.js 0.11.8) instead. + +## Rule Details + +This rule aims to prevent the use of `process.exit()` in Node.js JavaScript. As such, it warns whenever `process.exit()` is found in code. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-process-exit: "error"*/ + +process.exit(1); +process.exit(0); +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-process-exit: "error"*/ + +Process.exit(); +var exit = process.exit; +``` + +## When Not To Use It + +There may be a part of a Node.js application that is responsible for determining the correct exit code to return upon exiting. In that case, you should turn this rule off to allow proper handling of the exit code. + +## Version + +This rule was introduced in ESLint 0.4.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-process-exit.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-process-exit.md) diff --git a/docs/8.0.0/rules/no-promise-executor-return.md b/docs/8.0.0/rules/no-promise-executor-return.md new file mode 100644 index 0000000000..0286e13257 --- /dev/null +++ b/docs/8.0.0/rules/no-promise-executor-return.md @@ -0,0 +1,113 @@ +--- +title: no-promise-executor-return - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-promise-executor-return.md +rule_type: problem +--- + + +# Disallow returning values from Promise executor functions (no-promise-executor-return) + +The `new Promise` constructor accepts a single argument, called an *executor*. + +```js +const myPromise = new Promise(function executor(resolve, reject) { + readFile('foo.txt', function(err, result) { + if (err) { + reject(err); + } else { + resolve(result); + } + }); +}); +``` + +The executor function usually initiates some asynchronous operation. Once it is finished, the executor should call `resolve` with the result, or `reject` if an error occurred. + +The return value of the executor is ignored. Returning a value from an executor function is a possible error because the returned value cannot be used and it doesn't affect the promise in any way. + +## Rule Details + +This rule disallows returning values from Promise executor functions. + +Only `return` without a value is allowed, as it's a control flow statement. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-promise-executor-return: "error"*/ + +new Promise((resolve, reject) => { + if (someCondition) { + return defaultResult; + } + getSomething((err, result) => { + if (err) { + reject(err); + } else { + resolve(result); + } + }); +}); + +new Promise((resolve, reject) => getSomething((err, data) => { + if (err) { + reject(err); + } else { + resolve(data); + } +})); + +new Promise(() => { + return 1; +}); +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-promise-executor-return: "error"*/ + +new Promise((resolve, reject) => { + if (someCondition) { + resolve(defaultResult); + return; + } + getSomething((err, result) => { + if (err) { + reject(err); + } else { + resolve(result); + } + }); +}); + +new Promise((resolve, reject) => { + getSomething((err, data) => { + if (err) { + reject(err); + } else { + resolve(data); + } + }); +}); + +Promise.resolve(1); +``` + +## Further Reading + +* [MDN Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) + +## Related Rules + +* [no-async-promise-executor](no-async-promise-executor) + +## Version + +This rule was introduced in ESLint 7.3.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-promise-executor-return.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-promise-executor-return.md) diff --git a/docs/8.0.0/rules/no-proto.md b/docs/8.0.0/rules/no-proto.md new file mode 100644 index 0000000000..2bf325d117 --- /dev/null +++ b/docs/8.0.0/rules/no-proto.md @@ -0,0 +1,59 @@ +--- +title: no-proto - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-proto.md +rule_type: suggestion +--- + + +# Disallow Use of `__proto__` (no-proto) + +`__proto__` property has been deprecated as of ECMAScript 3.1 and shouldn't be used in the code. Use `Object.getPrototypeOf` and `Object.setPrototypeOf` instead. + +## Rule Details + +When an object is created with the `new` operator, `__proto__` is set to the original "prototype" property of the object's constructor function. `Object.getPrototypeOf` is the preferred method of getting the object's prototype. To change an object's prototype, use `Object.setPrototypeOf`. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-proto: "error"*/ + +var a = obj.__proto__; + +var a = obj["__proto__"]; + +obj.__proto__ = b; + +obj["__proto__"] = b; +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-proto: "error"*/ + +var a = Object.getPrototypeOf(obj); + +Object.setPrototypeOf(obj, b); + +var c = { __proto__: a }; +``` + +## When Not To Use It + +You might want to turn this rule off if you need to support legacy browsers which implement the +`__proto__` property but not `Object.getPrototypeOf` or `Object.setPrototypeOf`. + +## Further Reading + +* [Object.getPrototypeOf](http://ejohn.org/blog/objectgetprototypeof/) + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-proto.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-proto.md) diff --git a/docs/8.0.0/rules/no-prototype-builtins.md b/docs/8.0.0/rules/no-prototype-builtins.md new file mode 100644 index 0000000000..7885314742 --- /dev/null +++ b/docs/8.0.0/rules/no-prototype-builtins.md @@ -0,0 +1,58 @@ +--- +title: no-prototype-builtins - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-prototype-builtins.md +rule_type: problem +--- + + +# Disallow use of Object.prototypes builtins directly (no-prototype-builtins) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +In ECMAScript 5.1, `Object.create` was added, which enables the creation of objects with a specified `[[Prototype]]`. `Object.create(null)` is a common pattern used to create objects that will be used as a Map. This can lead to errors when it is assumed that objects will have properties from `Object.prototype`. This rule prevents calling some `Object.prototype` methods directly from an object. + +Additionally, objects can have properties that shadow the builtins on `Object.prototype`, potentially causing unintended behavior or denial-of-service security vulnerabilities. For example, it would be unsafe for a webserver to parse JSON input from a client and call `hasOwnProperty` directly on the resulting object, because a malicious client could send a JSON value like `{"hasOwnProperty": 1}` and cause the server to crash. + +To avoid subtle bugs like this, it's better to always call these methods from `Object.prototype`. For example, `foo.hasOwnProperty("bar")` should be replaced with `Object.prototype.hasOwnProperty.call(foo, "bar")`. + +## Rule Details + +This rule disallows calling some `Object.prototype` methods directly on object instances. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-prototype-builtins: "error"*/ + +var hasBarProperty = foo.hasOwnProperty("bar"); + +var isPrototypeOfBar = foo.isPrototypeOf(bar); + +var barIsEnumerable = foo.propertyIsEnumerable("bar"); +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-prototype-builtins: "error"*/ + +var hasBarProperty = Object.prototype.hasOwnProperty.call(foo, "bar"); + +var isPrototypeOfBar = Object.prototype.isPrototypeOf.call(foo, bar); + +var barIsEnumerable = {}.propertyIsEnumerable.call(foo, "bar"); +``` + +## When Not To Use It + +You may want to turn this rule off if your code only touches objects with hardcoded keys, and you will never use an object that shadows an `Object.prototype` method or which does not inherit from `Object.prototype`. + +## Version + +This rule was introduced in ESLint 2.11.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-prototype-builtins.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-prototype-builtins.md) diff --git a/docs/8.0.0/rules/no-redeclare.md b/docs/8.0.0/rules/no-redeclare.md new file mode 100644 index 0000000000..5c01f1a8fd --- /dev/null +++ b/docs/8.0.0/rules/no-redeclare.md @@ -0,0 +1,79 @@ +--- +title: no-redeclare - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-redeclare.md +rule_type: suggestion +--- + + +# disallow variable redeclaration (no-redeclare) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +In JavaScript, it's possible to redeclare the same variable name using `var`. This can lead to confusion as to where the variable is actually declared and initialized. + +## Rule Details + +This rule is aimed at eliminating variables that have multiple declarations in the same scope. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-redeclare: "error"*/ + +var a = 3; +var a = 10; +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-redeclare: "error"*/ + +var a = 3; +// ... +a = 10; +``` + +## Options + +This rule takes one optional argument, an object with a boolean property `"builtinGlobals"`. It defaults to `true`. +If set to `true`, this rule also checks redeclaration of built-in globals, such as `Object`, `Array`, `Number`... + +### builtinGlobals + +The `"builtinGlobals"` option will check for redeclaration of built-in globals in global scope. + +Examples of **incorrect** code for the `{ "builtinGlobals": true }` option: + +```js +/*eslint no-redeclare: ["error", { "builtinGlobals": true }]*/ + +var Object = 0; +``` + +Examples of **incorrect** code for the `{ "builtinGlobals": true }` option and the `browser` environment: + +```js +/*eslint no-redeclare: ["error", { "builtinGlobals": true }]*/ +/*eslint-env browser*/ + +var top = 0; +``` + +The `browser` environment has many built-in global variables (for example, `top`). Some of built-in global variables cannot be redeclared. + +Note that when using the `node` or `commonjs` environments (or `ecmaFeatures.globalReturn`, if using the default parser), the top scope of a program is not actually the global scope, but rather a "module" scope. When this is the case, declaring a variable named after a builtin global is not a redeclaration, but rather a shadowing of the global variable. In that case, the [`no-shadow`](no-shadow) rule with the `"builtinGlobals"` option should be used. + +## Related Rules + +* [no-shadow](no-shadow) + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-redeclare.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-redeclare.md) diff --git a/docs/8.0.0/rules/no-regex-spaces.md b/docs/8.0.0/rules/no-regex-spaces.md new file mode 100644 index 0000000000..2b227d58b7 --- /dev/null +++ b/docs/8.0.0/rules/no-regex-spaces.md @@ -0,0 +1,67 @@ +--- +title: no-regex-spaces - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-regex-spaces.md +rule_type: suggestion +--- + + +# disallow multiple spaces in regular expression literals (no-regex-spaces) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +Regular expressions can be very complex and difficult to understand, which is why it's important to keep them as simple as possible in order to avoid mistakes. One of the more error-prone things you can do with a regular expression is to use more than one space, such as: + +```js +var re = /foo bar/; +``` + +In this regular expression, it's very hard to tell how many spaces are intended to be matched. It's better to use only one space and then specify how many spaces are expected, such as: + +```js +var re = /foo {3}bar/; +``` + +Now it is very clear that three spaces are expected to be matched. + +## Rule Details + +This rule disallows multiple spaces in regular expression literals. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-regex-spaces: "error"*/ + +var re = /foo bar/; +var re = new RegExp("foo bar"); +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-regex-spaces: "error"*/ + +var re = /foo {3}bar/; +var re = new RegExp("foo {3}bar"); +``` + +## When Not To Use It + +If you want to allow multiple spaces in a regular expression, then you can safely turn this rule off. + +## Related Rules + +* [no-div-regex](no-div-regex) +* [no-control-regex](no-control-regex) + +## Version + +This rule was introduced in ESLint 0.4.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-regex-spaces.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-regex-spaces.md) diff --git a/docs/8.0.0/rules/no-reserved-keys.md b/docs/8.0.0/rules/no-reserved-keys.md new file mode 100644 index 0000000000..d26204f1aa --- /dev/null +++ b/docs/8.0.0/rules/no-reserved-keys.md @@ -0,0 +1,69 @@ +--- +title: no-reserved-keys - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-reserved-keys.md + +--- + + +# no-reserved-keys: disallow unquoted reserved words as property names in object literals + +(removed) This rule was **removed** in ESLint v1.0 and **replaced** by the [quote-props](quote-props) rule. + +ECMAScript 3 described as series of keywords and reserved words, such as `if` and `public`, that are used or intended to be used for a core language feature. The specification also indicated that these keywords and reserved words could not be used as object property names without being enclosed in strings. An error occurs in an ECMAScript 3 environment when you use a keyword or reserved word in an object literal. For example: + +```js +var values = { + enum: ["red", "blue", "green"] // throws an error in ECMAScript 3 +} +``` + +In this code, `enum` is used as an object key and will throw an error in an ECMAScript 3 environment (such as Internet Explorer 8). + +ECMAScript 5 loosened the restriction such that keywords and reserved words can be used as object keys without causing an error. However, any code that needs to run in ECMAScript 3 still needs to avoid using keywords and reserved words as keys. + +## Rule Details + +This rule is aimed at eliminating the use of ECMAScript 3 keywords and reserved words as object literal keys. As such, it warns whenever an object key would throw an error in an ECMAScript 3 environment. + +Examples of **incorrect** code for this rule: + +```js +var superman = { + class: "Superhero", + private: "Clark Kent" +}; + +var values = { + enum: ["red", "blue", "green"] +}; +``` + +Examples of **correct** code for this rule: + +```js +var superman = { + "class": "Superhero", + "private": "Clark Kent" +}; + +var values = { + "enum": ["red", "blue", "green"] +}; +``` + +## When Not To Use It + +If your code is only going to be executed in an ECMAScript 5 or higher environment, then you can safely leave this rule off. + +## Further Reading + +* [Reserved words as property names](https://kangax.github.io/compat-table/es5/#Reserved_words_as_property_names) + +## Version + +This rule was introduced in ESLint 0.8.0 and removed in 1.0.0. + +## Resources + +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-reserved-keys.md) diff --git a/docs/8.0.0/rules/no-restricted-exports.md b/docs/8.0.0/rules/no-restricted-exports.md new file mode 100644 index 0000000000..2d8984b97b --- /dev/null +++ b/docs/8.0.0/rules/no-restricted-exports.md @@ -0,0 +1,123 @@ +--- +title: no-restricted-exports - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-restricted-exports.md +rule_type: suggestion +--- + + +# Disallow specified names in exports (no-restricted-exports) + +In a project, certain names may be disallowed from being used as exported names for various reasons. + +## Rule Details + +This rule disallows specified names from being used as exported names. + +## Options + +By default, this rule doesn't disallow any names. Only the names you specify in the configuration will be disallowed. + +This rule has an object option: + +* `"restrictedNamedExports"` is an array of strings, where each string is a name to be restricted. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-restricted-exports: ["error", { + "restrictedNamedExports": ["foo", "bar", "Baz", "a", "b", "c", "d"] +}]*/ + +export const foo = 1; + +export function bar() {} + +export class Baz {} + +const a = {}; +export { a }; + +function someFunction() {} +export { someFunction as b }; + +export { c } from 'some_module'; + +export { something as d } from 'some_module'; +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-restricted-exports: ["error", { + "restrictedNamedExports": ["foo", "bar", "Baz", "a", "b", "c", "d"] +}]*/ + +export const quux = 1; + +export function myFunction() {} + +export class MyClass {} + +const a = {}; +export { a as myObject }; + +function someFunction() {} +export { someFunction }; + +export { c as someName } from 'some_module'; + +export { something } from 'some_module'; +``` + +### Default exports + +By design, this rule doesn't disallow `export default` declarations. If you configure `"default"` as a restricted name, that restriction will apply only to named export declarations. + +Examples of additional **incorrect** code for this rule: + +```js +/*eslint no-restricted-exports: ["error", { "restrictedNamedExports": ["default"] }]*/ + +function foo() {} + +export { foo as default }; +``` + +```js +/*eslint no-restricted-exports: ["error", { "restrictedNamedExports": ["default"] }]*/ + +export { default } from 'some_module'; +``` + +Examples of additional **correct** code for this rule: + +```js +/*eslint no-restricted-exports: ["error", { "restrictedNamedExports": ["default", "foo"] }]*/ + +export default function foo() {} +``` + +## Known Limitations + +This rule doesn't inspect the content of source modules in re-export declarations. In particular, if you are re-exporting everything from another module's export, that export may include a restricted name. This rule cannot detect such cases. + +```js + +//----- some_module.js ----- +export function foo() {} + +//----- my_module.js ----- +/*eslint no-restricted-exports: ["error", { "restrictedNamedExports": ["foo"] }]*/ + +export * from 'some_module'; // allowed, although this declaration exports "foo" from my_module +``` + +## Version + +This rule was introduced in ESLint 7.0.0-alpha.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-restricted-exports.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-restricted-exports.md) diff --git a/docs/8.0.0/rules/no-restricted-globals.md b/docs/8.0.0/rules/no-restricted-globals.md new file mode 100644 index 0000000000..e421b5ff4e --- /dev/null +++ b/docs/8.0.0/rules/no-restricted-globals.md @@ -0,0 +1,107 @@ +--- +title: no-restricted-globals - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-restricted-globals.md +rule_type: suggestion +--- + + +# Disallow specific global variables (no-restricted-globals) + +Disallowing usage of specific global variables can be useful if you want to allow a set of global +variables by enabling an environment, but still want to disallow some of those. + +For instance, early Internet Explorer versions exposed the current DOM event as a global variable +`event`, but using this variable has been considered as a bad practice for a long time. Restricting +this will make sure this variable isn't used in browser code. + +## Rule Details + +This rule allows you to specify global variable names that you don't want to use in your application. + +## Options + +This rule takes a list of strings, where each string is a global to be restricted: + +```json +{ + "rules": { + "no-restricted-globals": ["error", "event", "fdescribe"] + } +} +``` + +Alternatively, the rule also accepts objects, where the global name and an optional custom message are specified: + +```json +{ + "rules": { + "no-restricted-globals": [ + "error", + { + "name": "event", + "message": "Use local parameter instead." + }, + { + "name": "fdescribe", + "message": "Do not commit fdescribe. Use describe instead." + } + ] + } +} +``` + +Examples of **incorrect** code for sample `"event", "fdescribe"` global variable names: + +```js +/*global event, fdescribe*/ +/*eslint no-restricted-globals: ["error", "event", "fdescribe"]*/ + +function onClick() { + console.log(event); +} + +fdescribe("foo", function() { +}); +``` + +Examples of **correct** code for a sample `"event"` global variable name: + +```js +/*global event*/ +/*eslint no-restricted-globals: ["error", "event"]*/ + +import event from "event-module"; +``` + +```js +/*global event*/ +/*eslint no-restricted-globals: ["error", "event"]*/ + +var event = 1; +``` + +Examples of **incorrect** code for a sample `"event"` global variable name, along with a custom error message: + +```js +/*global event*/ +/* eslint no-restricted-globals: ["error", { name: "event", message: "Use local parameter instead." }] */ + +function onClick() { + console.log(event); // Unexpected global variable 'event'. Use local parameter instead. +} +``` + +## Related Rules + +* [no-restricted-properties](no-restricted-properties) +* [no-restricted-syntax](no-restricted-syntax) + +## Version + +This rule was introduced in ESLint 2.3.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-restricted-globals.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-restricted-globals.md) diff --git a/docs/8.0.0/rules/no-restricted-imports.md b/docs/8.0.0/rules/no-restricted-imports.md new file mode 100644 index 0000000000..7703eea647 --- /dev/null +++ b/docs/8.0.0/rules/no-restricted-imports.md @@ -0,0 +1,236 @@ +--- +title: no-restricted-imports - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-restricted-imports.md +rule_type: suggestion +--- + + +# Disallow specific imports (no-restricted-imports) + +Imports are an ES6/ES2015 standard for making the functionality of other modules available in your current module. In CommonJS this is implemented through the `require()` call which makes this ESLint rule roughly equivalent to its CommonJS counterpart `no-restricted-modules`. + +Why would you want to restrict imports? + +* Some imports might not make sense in a particular environment. For example, Node.js' `fs` module would not make sense in an environment that didn't have a file system. + +* Some modules provide similar or identical functionality, think `lodash` and `underscore`. Your project may have standardized on a module. You want to make sure that the other alternatives are not being used as this would unnecessarily bloat the project and provide a higher maintenance cost of two dependencies when one would suffice. + +## Rule Details + +This rule allows you to specify imports that you don't want to use in your application. + +It applies to static imports only, not dynamic ones. + +## Options + +The syntax to specify restricted imports looks like this: + +```json +"no-restricted-imports": ["error", "import1", "import2"] +``` + +or like this: + +```json +"no-restricted-imports": ["error", { "paths": ["import1", "import2"] }] +``` + +When using the object form, you can also specify an array of gitignore-style patterns: + +```json +"no-restricted-imports": ["error", { + "paths": ["import1", "import2"], + "patterns": ["import1/private/*", "import2/*", "!import2/good"] +}] +``` + +You may also specify a custom message for any paths you want to restrict as follows: + +```json +"no-restricted-imports": ["error", { + "name": "import-foo", + "message": "Please use import-bar instead." +}, { + "name": "import-baz", + "message": "Please use import-quux instead." +}] +``` + +or like this: + +```json +"no-restricted-imports": ["error", { + "paths": [{ + "name": "import-foo", + "message": "Please use import-bar instead." + }, { + "name": "import-baz", + "message": "Please use import-quux instead." + }] +}] +``` + +or like this if you need to restrict only certain imports from a module: + +```json +"no-restricted-imports": ["error", { + "paths": [{ + "name": "import-foo", + "importNames": ["Bar"], + "message": "Please use Bar from /import-bar/baz/ instead." + }] +}] +``` + +or like this if you want to apply a custom message to pattern matches: + +```json +"no-restricted-imports": ["error", { + "patterns": [{ + "group": ["import1/private/*"], + "message": "usage of import1 private modules not allowed." + }, { + "group": ["import2/*", "!import2/good"], + "message": "import2 is deprecated, except the modules in import2/good." + }] +}] +``` + +The custom message will be appended to the default error message. + +To restrict the use of all Node.js core imports (via https://github.com/nodejs/node/tree/master/lib): + +```json + "no-restricted-imports": ["error", + "assert","buffer","child_process","cluster","crypto","dgram","dns","domain","events","freelist","fs","http","https","module","net","os","path","punycode","querystring","readline","repl","smalloc","stream","string_decoder","sys","timers","tls","tracing","tty","url","util","vm","zlib" + ], +``` + +## Examples + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-restricted-imports: ["error", "fs"]*/ + +import fs from 'fs'; +``` + +```js +/*eslint no-restricted-imports: ["error", "fs"]*/ + +export { fs } from 'fs'; +``` + +```js +/*eslint no-restricted-imports: ["error", "fs"]*/ + +export * from 'fs'; +``` + +```js +/*eslint no-restricted-imports: ["error", { "paths": ["cluster"] }]*/ + +import cluster from 'cluster'; +``` + +```js +/*eslint no-restricted-imports: ["error", { "patterns": ["lodash/*"] }]*/ + +import pick from 'lodash/pick'; +``` + +```js +/*eslint no-restricted-imports: ["error", { paths: [{ + name: "foo", + importNames: ["default"], + message: "Please use the default import from '/bar/baz/' instead." +}]}]*/ + +import DisallowedObject from "foo"; +``` + +```js +/*eslint no-restricted-imports: ["error", { paths: [{ + name: "foo", + importNames: ["DisallowedObject"], + message: "Please import 'DisallowedObject' from '/bar/baz/' instead." +}]}]*/ + +import { DisallowedObject as AllowedObject } from "foo"; +``` + +```js +/*eslint no-restricted-imports: ["error", { paths: [{ + name: "foo", + importNames: ["DisallowedObject"], + message: "Please import 'DisallowedObject' from '/bar/baz/' instead." +}]}]*/ + +import * as Foo from "foo"; +``` + +```js +/*eslint no-restricted-imports: ["error", { patterns: [{ + group: ["lodash/*"], + message: "Please use the default import from 'lodash' instead." +}]}]*/ + +import pick from 'lodash/pick'; +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-restricted-imports: ["error", "fs"]*/ + +import crypto from 'crypto'; +export { foo } from "bar"; +``` + +```js +/*eslint no-restricted-imports: ["error", { "paths": ["fs"], "patterns": ["eslint/*"] }]*/ + +import crypto from 'crypto'; +import eslint from 'eslint'; +export * from "path"; +``` + +```js +/*eslint no-restricted-imports: ["error", { paths: [{ name: "foo", importNames: ["DisallowedObject"] }] }]*/ + +import DisallowedObject from "foo" +``` + +```js +/*eslint no-restricted-imports: ["error", { paths: [{ + name: "foo", + importNames: ["DisallowedObject"], + message: "Please import 'DisallowedObject' from '/bar/baz/' instead." +}]}]*/ + +import { AllowedObject as DisallowedObject } from "foo"; +``` + +```js +/*eslint no-restricted-imports: ["error", { patterns: [{ + group: ["lodash/*"], + message: "Please use the default import from 'lodash' instead." +}]}]*/ + +import lodash from 'lodash'; +``` + +## When Not To Use It + +Don't use this rule or don't include a module in the list for this rule if you want to be able to import a module in your project without an ESLint error or warning. + +## Version + +This rule was introduced in ESLint 2.0.0-alpha-1. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-restricted-imports.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-restricted-imports.md) diff --git a/docs/8.0.0/rules/no-restricted-modules.md b/docs/8.0.0/rules/no-restricted-modules.md new file mode 100644 index 0000000000..2a2108d90c --- /dev/null +++ b/docs/8.0.0/rules/no-restricted-modules.md @@ -0,0 +1,127 @@ +--- +title: no-restricted-modules - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-restricted-modules.md +rule_type: suggestion +--- + + +# Disallow Node.js modules (no-restricted-modules) + +This rule was **deprecated** in ESLint v7.0.0. Please use the corresponding rule in [`eslint-plugin-node`](https://github.com/mysticatea/eslint-plugin-node). + +A module in Node.js is a simple or complex functionality organized in a JavaScript file which can be reused throughout the Node.js +application. The keyword `require` is used in Node.js/CommonJS to import modules into an application. This way you can have dynamic loading where the loaded module name isn't predefined /static, or where you conditionally load a module only if it's "truly required". + +Why would you want to restrict a module? + +Disallowing usage of specific Node.js modules can be useful if you want to limit the available methods a developer can use. For example, you can block usage of the `fs` module if you want to disallow file system access. + +## Rule Details + +This rule allows you to specify modules that you don’t want to use in your application. + +## Options + +The rule takes one or more strings as options: the names of restricted modules. + +```json +"no-restricted-modules": ["error", "foo-module", "bar-module"] +``` + +It can also take an object with lists of `paths` and gitignore-style `patterns` strings. + +```json +"no-restricted-modules": ["error", { "paths": ["foo-module", "bar-module"] }] +``` + +```json +"no-restricted-modules": ["error", { + "paths": ["foo-module", "bar-module"], + "patterns": ["foo-module/private/*", "bar-module/*","!baz-module/good"] +}] +``` + +You may also specify a custom message for any paths you want to restrict as follows: + +```json +"no-restricted-modules": ["error", { + "name": "foo-module", + "message": "Please use bar-module instead." + } +] +``` + +or like this: + +```json +"no-restricted-modules": ["error",{ +"paths":[{ + "name": "foo-module", + "message": "Please use bar-module instead." + }] +}] +``` + +The custom message will be appended to the default error message. Please note that you may not specify custom error messages for restricted patterns as a particular module may match more than one pattern. + + +To restrict the use of all Node.js core modules (via https://github.com/nodejs/node/tree/master/lib): + +```json +{ + "no-restricted-modules": ["error", + "assert","buffer","child_process","cluster","crypto","dgram","dns","domain","events","freelist","fs","http","https","module","net","os","path","punycode","querystring","readline","repl","smalloc","stream","string_decoder","sys","timers","tls","tracing","tty","url","util","vm","zlib" + ] +} +``` + +## Examples + +Examples of **incorrect** code for this rule with sample `"fs", "cluster", "lodash"` restricted modules: + +```js +/*eslint no-restricted-modules: ["error", "fs", "cluster"]*/ + +var fs = require('fs'); +var cluster = require('cluster'); +``` + +```js +/*eslint no-restricted-modules: ["error", {"paths": ["cluster"] }]*/ + +var cluster = require('cluster'); +``` + +```js +/*eslint no-restricted-modules: ["error", { "patterns": ["lodash/*"] }]*/ + +var pick = require('lodash/pick'); +``` + +Examples of **correct** code for this rule with sample `"fs", "cluster", "lodash"` restricted modules: + +```js +/*eslint no-restricted-modules: ["error", "fs", "cluster"]*/ + +var crypto = require('crypto'); +``` + +```js +/*eslint no-restricted-modules: ["error", { + "paths": ["fs", "cluster"], + "patterns": ["lodash/*", "!lodash/pick"] +}]*/ + +var crypto = require('crypto'); +var pick = require('lodash/pick'); +``` + +## Version + +This rule was introduced in ESLint 0.6.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-restricted-modules.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-restricted-modules.md) diff --git a/docs/8.0.0/rules/no-restricted-properties.md b/docs/8.0.0/rules/no-restricted-properties.md new file mode 100644 index 0000000000..6b598e9e95 --- /dev/null +++ b/docs/8.0.0/rules/no-restricted-properties.md @@ -0,0 +1,142 @@ +--- +title: no-restricted-properties - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-restricted-properties.md +rule_type: suggestion +--- + + +# disallow certain object properties (no-restricted-properties) + +Certain properties on objects may be disallowed in a codebase. This is useful for deprecating an API or restricting usage of a module's methods. For example, you may want to disallow using `describe.only` when using Mocha or telling people to use `Object.assign` instead of `_.extend`. + + +## Rule Details + +This rule looks for accessing a given property key on a given object name, either when reading the property's value or invoking it as a function. You may specify an optional message to indicate an alternative API or a reason for the restriction. + +### Options + +This rule takes a list of objects, where the object name and property names are specified: + +```json +{ + "rules": { + "no-restricted-properties": [2, { + "object": "disallowedObjectName", + "property": "disallowedPropertyName" + }] + } +} +``` + +Multiple object/property values can be disallowed, and you can specify an optional message: + +```json +{ + "rules": { + "no-restricted-properties": [2, { + "object": "disallowedObjectName", + "property": "disallowedPropertyName" + }, { + "object": "disallowedObjectName", + "property": "anotherDisallowedPropertyName", + "message": "Please use allowedObjectName.allowedPropertyName." + }] + } +} +``` + +If the object name is omitted, the property is disallowed for all objects: + +```json +{ + "rules": { + "no-restricted-properties": [2, { + "property": "__defineGetter__", + "message": "Please use Object.defineProperty instead." + }] + } +} +``` + +If the property name is omitted, accessing any property of the given object is disallowed: + +```json +{ + "rules": { + "no-restricted-properties": [2, { + "object": "require", + "message": "Please call require() directly." + }] + } +} +``` + +Examples of **incorrect** code for this rule: + +```js +/* eslint no-restricted-properties: [2, { + "object": "disallowedObjectName", + "property": "disallowedPropertyName" +}] */ + +var example = disallowedObjectName.disallowedPropertyName; /*error Disallowed object property: disallowedObjectName.disallowedPropertyName.*/ + +disallowedObjectName.disallowedPropertyName(); /*error Disallowed object property: disallowedObjectName.disallowedPropertyName.*/ +``` + +```js +/* eslint no-restricted-properties: [2, { + "property": "__defineGetter__" +}] */ + +foo.__defineGetter__(bar, baz); +``` + +```js +/* eslint no-restricted-properties: [2, { + "object": "require" +}] */ + +require.resolve('foo'); +``` + +Examples of **correct** code for this rule: + +```js +/* eslint no-restricted-properties: [2, { + "object": "disallowedObjectName", + "property": "disallowedPropertyName" +}] */ + +var example = disallowedObjectName.somePropertyName; + +allowedObjectName.disallowedPropertyName(); +``` + +```js +/* eslint no-restricted-properties: [2, { + "object": "require" +}] */ + +require('foo'); +``` + +## When Not To Use It + +If you don't have any object/property combinations to restrict, you should not use this rule. + +## Related Rules + +* [no-restricted-globals](no-restricted-globals) +* [no-restricted-syntax](no-restricted-syntax) + +## Version + +This rule was introduced in ESLint 3.5.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-restricted-properties.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-restricted-properties.md) diff --git a/docs/8.0.0/rules/no-restricted-syntax.md b/docs/8.0.0/rules/no-restricted-syntax.md new file mode 100644 index 0000000000..24d9ec3649 --- /dev/null +++ b/docs/8.0.0/rules/no-restricted-syntax.md @@ -0,0 +1,101 @@ +--- +title: no-restricted-syntax - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-restricted-syntax.md +rule_type: suggestion +--- + + +# disallow specified syntax (no-restricted-syntax) + +JavaScript has a lot of language features, and not everyone likes all of them. As a result, some projects choose to disallow the use of certain language features altogether. For instance, you might decide to disallow the use of `try-catch` or `class`, or you might decide to disallow the use of the `in` operator. + +Rather than creating separate rules for every language feature you want to turn off, this rule allows you to configure the syntax elements you want to restrict use of. These elements are represented by their [ESTree](https://github.com/estree/estree) node types. For example, a function declaration is represented by `FunctionDeclaration` and the `with` statement is represented by `WithStatement`. You may find the full list of AST node names you can use [on GitHub](https://github.com/eslint/espree/blob/master/lib/ast-node-types.js) and use [AST Explorer](https://astexplorer.net/) with the espree parser to see what type of nodes your code consists of. + +You can also specify [AST selectors](../developer-guide/selectors) to restrict, allowing much more precise control over syntax patterns. + +## Rule Details + +This rule disallows specified (that is, user-defined) syntax. + +## Options + +This rule takes a list of strings, where each string is an AST selector: + +```json +{ + "rules": { + "no-restricted-syntax": ["error", "FunctionExpression", "WithStatement", "BinaryExpression[operator='in']"] + } +} +``` + +Alternatively, the rule also accepts objects, where the selector and an optional custom message are specified: + +```json +{ + "rules": { + "no-restricted-syntax": [ + "error", + { + "selector": "FunctionExpression", + "message": "Function expressions are not allowed." + }, + { + "selector": "CallExpression[callee.name='setTimeout'][arguments.length!=2]", + "message": "setTimeout must always be invoked with two arguments." + } + ] + } +} +``` + +If a custom message is specified with the `message` property, ESLint will use that message when reporting occurrences of the syntax specified in the `selector` property. + +The string and object formats can be freely mixed in the configuration as needed. + +Examples of **incorrect** code for this rule with the `"FunctionExpression", "WithStatement", BinaryExpression[operator='in']` options: + +```js +/* eslint no-restricted-syntax: ["error", "FunctionExpression", "WithStatement", "BinaryExpression[operator='in']"] */ + +with (me) { + dontMess(); +} + +var doSomething = function () {}; + +foo in bar; +``` + +Examples of **correct** code for this rule with the `"FunctionExpression", "WithStatement", BinaryExpression[operator='in']` options: + +```js +/* eslint no-restricted-syntax: ["error", "FunctionExpression", "WithStatement", "BinaryExpression[operator='in']"] */ + +me.dontMess(); + +function doSomething() {}; + +foo instanceof bar; +``` + +## When Not To Use It + +If you don't want to restrict your code from using any JavaScript features or syntax, you should not use this rule. + +## Related Rules + +* [no-alert](no-alert) +* [no-console](no-console) +* [no-debugger](no-debugger) +* [no-restricted-properties](no-restricted-properties) + +## Version + +This rule was introduced in ESLint 1.4.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-restricted-syntax.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-restricted-syntax.md) diff --git a/docs/8.0.0/rules/no-return-assign.md b/docs/8.0.0/rules/no-return-assign.md new file mode 100644 index 0000000000..5b7b2b7545 --- /dev/null +++ b/docs/8.0.0/rules/no-return-assign.md @@ -0,0 +1,135 @@ +--- +title: no-return-assign - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-return-assign.md +rule_type: suggestion +--- + + +# Disallow Assignment in return Statement (no-return-assign) + +One of the interesting, and sometimes confusing, aspects of JavaScript is that assignment can happen at almost any point. Because of this, an errant equals sign can end up causing assignment when the true intent was to do a comparison. This is especially true when using a `return` statement. For example: + +```js +function doSomething() { + return foo = bar + 2; +} +``` + +It is difficult to tell the intent of the `return` statement here. It's possible that the function is meant to return the result of `bar + 2`, but then why is it assigning to `foo`? It's also possible that the intent was to use a comparison operator such as `==` and that this code is an error. + +Because of this ambiguity, it's considered a best practice to not use assignment in `return` statements. + +## Rule Details + +This rule aims to eliminate assignments from `return` statements. As such, it will warn whenever an assignment is found as part of `return`. + +## Options + +The rule takes one option, a string, which must contain one of the following values: + +* `except-parens` (default): Disallow assignments unless they are enclosed in parentheses. +* `always`: Disallow all assignments. + +### except-parens + +This is the default option. +It disallows assignments unless they are enclosed in parentheses. + +Examples of **incorrect** code for the default `"except-parens"` option: + +```js +/*eslint no-return-assign: "error"*/ + +function doSomething() { + return foo = bar + 2; +} + +function doSomething() { + return foo += 2; +} + +const foo = (a, b) => a = b + +const bar = (a, b, c) => (a = b, c == b) + +function doSomething() { + return foo = bar && foo > 0; +} +``` + +Examples of **correct** code for the default `"except-parens"` option: + +```js +/*eslint no-return-assign: "error"*/ + +function doSomething() { + return foo == bar + 2; +} + +function doSomething() { + return foo === bar + 2; +} + +function doSomething() { + return (foo = bar + 2); +} + +const foo = (a, b) => (a = b) + +const bar = (a, b, c) => ((a = b), c == b) + +function doSomething() { + return (foo = bar) && foo > 0; +} +``` + +### always + +This option disallows all assignments in `return` statements. +All assignments are treated as problems. + +Examples of **incorrect** code for the `"always"` option: + +```js +/*eslint no-return-assign: ["error", "always"]*/ + +function doSomething() { + return foo = bar + 2; +} + +function doSomething() { + return foo += 2; +} + +function doSomething() { + return (foo = bar + 2); +} +``` + +Examples of **correct** code for the `"always"` option: + +```js +/*eslint no-return-assign: ["error", "always"]*/ + +function doSomething() { + return foo == bar + 2; +} + +function doSomething() { + return foo === bar + 2; +} +``` + +## When Not To Use It + +If you want to allow the use of assignment operators in a `return` statement, then you can safely disable this rule. + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-return-assign.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-return-assign.md) diff --git a/docs/8.0.0/rules/no-return-await.md b/docs/8.0.0/rules/no-return-await.md new file mode 100644 index 0000000000..7901f4ad21 --- /dev/null +++ b/docs/8.0.0/rules/no-return-await.md @@ -0,0 +1,78 @@ +--- +title: no-return-await - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-return-await.md +rule_type: suggestion +--- + + +# Disallows unnecessary `return await` (no-return-await) + +Using `return await` inside an `async function` keeps the current function in the call stack until the Promise that is being awaited has resolved, at the cost of an extra microtask before resolving the outer Promise. `return await` can also be used in a try/catch statement to catch errors from another function that returns a Promise. + +You can avoid the extra microtask by not awaiting the return value, with the trade off of the function no longer being a part of the stack trace if an error is thrown asynchronously from the Promise being returned. This can make debugging more difficult. + +## Rule Details + +This rule aims to prevent a likely common performance hazard due to a lack of understanding of the semantics of `async function`. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-return-await: "error"*/ + +async function foo() { + return await bar(); +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-return-await: "error"*/ + +async function foo() { + return bar(); +} + +async function foo() { + await bar(); + return; +} + +// This is essentially the same as `return await bar();`, but the rule checks only `await` in `return` statements +async function foo() { + const x = await bar(); + return x; +} + +// In this example the `await` is necessary to be able to catch errors thrown from `bar()` +async function foo() { + try { + return await bar(); + } catch (error) {} +} +``` + +## When Not To Use It + +There are a few reasons you might want to turn this rule off: + +- If you want to use `await` to denote a value that is a thenable +- If you do not want the performance benefit of avoiding `return await` +- If you want the functions to show up in stack traces (useful for debugging purposes) + +## Further Reading + +[`async function` on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) + +[`await vs return vs return await` by Jake Archibald](https://jakearchibald.com/2017/await-vs-return-vs-return-await/) + +## Version + +This rule was introduced in ESLint 3.10.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-return-await.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-return-await.md) diff --git a/docs/8.0.0/rules/no-script-url.md b/docs/8.0.0/rules/no-script-url.md new file mode 100644 index 0000000000..f4cb51b15c --- /dev/null +++ b/docs/8.0.0/rules/no-script-url.md @@ -0,0 +1,40 @@ +--- +title: no-script-url - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-script-url.md +rule_type: suggestion +--- + + +# Disallow Script URLs (no-script-url) + +Using `javascript:` URLs is considered by some as a form of `eval`. Code passed in `javascript:` URLs has to be parsed and evaluated by the browser in the same way that `eval` is processed. + +## Rule Details + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-script-url: "error"*/ + +location.href = "javascript:void(0)"; + +location.href = `javascript:void(0)`; +``` + +## Compatibility + +* **JSHint**: This rule corresponds to `scripturl` rule of JSHint. + +## Further Reading + +* [What is the matter with script-targeted URLs?](https://stackoverflow.com/questions/13497971/what-is-the-matter-with-script-targeted-urls) + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-script-url.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-script-url.md) diff --git a/docs/8.0.0/rules/no-self-assign.md b/docs/8.0.0/rules/no-self-assign.md new file mode 100644 index 0000000000..7b77ce3e7f --- /dev/null +++ b/docs/8.0.0/rules/no-self-assign.md @@ -0,0 +1,105 @@ +--- +title: no-self-assign - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-self-assign.md +rule_type: problem +--- + + +# Disallow Self Assignment (no-self-assign) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +Self assignments have no effect, so probably those are an error due to incomplete refactoring. +Those indicate that what you should do is still remaining. + +```js +foo = foo; +[bar, baz] = [bar, qiz]; +``` + +## Rule Details + +This rule is aimed at eliminating self assignments. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-self-assign: "error"*/ + +foo = foo; + +[a, b] = [a, b]; + +[a, ...b] = [x, ...b]; + +({a, b} = {a, x}); +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-self-assign: "error"*/ + +foo = bar; +[a, b] = [b, a]; + +// This pattern is warned by the `no-use-before-define` rule. +let foo = foo; + +// The default values have an effect. +[foo = 1] = [foo]; + +// non-self-assignments with properties. +obj.a = obj.b; +obj.a.b = obj.c.b; +obj.a.b = obj.a.c; +obj[a] = obj["a"]; + +// This ignores if there is a function call. +obj.a().b = obj.a().b; +a().b = a().b; + +// Known limitation: this does not support computed properties except single literal or single identifier. +obj[a + b] = obj[a + b]; +obj["a" + "b"] = obj["a" + "b"]; +``` + +## Options + +This rule has the option to check properties as well. + +```json +{ + "no-self-assign": ["error", {"props": true}] +} +``` + +- `props` - if this is `true`, `no-self-assign` rule warns self-assignments of properties. Default is `true`. + +### props + +Examples of **correct** code with the `{ "props": false }` option: + +```js +/*eslint no-self-assign: ["error", {"props": false}]*/ + +// self-assignments with properties. +obj.a = obj.a; +obj.a.b = obj.a.b; +obj["a"] = obj["a"]; +obj[a] = obj[a]; +``` + +## When Not To Use It + +If you don't want to notify about self assignments, then it's safe to disable this rule. + +## Version + +This rule was introduced in ESLint 2.0.0-rc.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-self-assign.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-self-assign.md) diff --git a/docs/8.0.0/rules/no-self-compare.md b/docs/8.0.0/rules/no-self-compare.md new file mode 100644 index 0000000000..eda9faf2fd --- /dev/null +++ b/docs/8.0.0/rules/no-self-compare.md @@ -0,0 +1,37 @@ +--- +title: no-self-compare - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-self-compare.md +rule_type: problem +--- + + +# Disallow Self Compare (no-self-compare) + +Comparing a variable against itself is usually an error, either a typo or refactoring error. It is confusing to the reader and may potentially introduce a runtime error. + +The only time you would compare a variable against itself is when you are testing for `NaN`. However, it is far more appropriate to use `typeof x === 'number' && isNaN(x)` or the [Number.isNaN ES2015 function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN) for that use case rather than leaving the reader of the code to determine the intent of self comparison. + +## Rule Details + +This error is raised to highlight a potentially confusing and potentially pointless piece of code. There are almost no situations in which you would need to compare something to itself. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-self-compare: "error"*/ + +var x = 10; +if (x === x) { + x = 20; +} +``` + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-self-compare.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-self-compare.md) diff --git a/docs/8.0.0/rules/no-sequences.md b/docs/8.0.0/rules/no-sequences.md new file mode 100644 index 0000000000..10549ab753 --- /dev/null +++ b/docs/8.0.0/rules/no-sequences.md @@ -0,0 +1,160 @@ +--- +title: no-sequences - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-sequences.md +rule_type: suggestion +--- + + +# Disallow Use of the Comma Operator (no-sequences) + +The comma operator includes multiple expressions where only one is expected. It evaluates each operand from left to right and returns the value of the last operand. However, this frequently obscures side effects, and its use is often an accident. Here are some examples of sequences: + +```js +var a = (3, 5); // a = 5 + +a = b += 5, a + b; + +while (a = next(), a && a.length); + +(0, eval)("doSomething();"); +``` + +## Rule Details + +This rule forbids the use of the comma operator, with the following exceptions: + +* In the initialization or update portions of a `for` statement. +* By default, if the expression sequence is explicitly wrapped in parentheses. This exception can be removed with the `allowInParentheses` option. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-sequences: "error"*/ + +foo = doSomething(), val; + +0, eval("doSomething();"); + +do {} while (doSomething(), !!test); + +for (; doSomething(), !!test; ); + +if (doSomething(), !!test); + +switch (val = foo(), val) {} + +while (val = foo(), val < 42); + +with (doSomething(), val) {} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-sequences: "error"*/ + +foo = (doSomething(), val); + +(0, eval)("doSomething();"); + +do {} while ((doSomething(), !!test)); + +for (i = 0, j = 10; i < j; i++, j--); + +if ((doSomething(), !!test)); + +switch ((val = foo(), val)) {} + +while ((val = foo(), val < 42)); + +with ((doSomething(), val)) {} +``` + +### Note about arrow function bodies + +If an arrow function body is a statement rather than a block, and that statement contains a sequence, you need to use double parentheses around the statement to indicate that the sequence is intentional. + +Examples of **incorrect** code for arrow functions: + +```js +/*eslint no-sequences: "error"*/ +const foo = (val) => (console.log('bar'), val); + +const foo = () => ((bar = 123), 10); + +const foo = () => { return (bar = 123), 10 } +``` + +Examples of **correct** code for arrow functions: + +```js +/*eslint no-sequences: "error"*/ +const foo = (val) => ((console.log('bar'), val)); + +const foo = () => (((bar = 123), 10)); + +const foo = () => { return ((bar = 123), 10) } +``` + +## Options + +This rule takes one option, an object, with the following properties: + +* `"allowInParentheses"`: If set to `true` (default), this rule allows expression sequences that are explicitly wrapped in parentheses. + +### allowInParentheses + +Examples of **incorrect** code for this rule with the `{ "allowInParentheses": false }` option: + +```js +/*eslint no-sequences: ["error", { "allowInParentheses": false }]*/ + +foo = (doSomething(), val); + +(0, eval)("doSomething();"); + +do {} while ((doSomething(), !!test)); + +for (; (doSomething(), !!test); ); + +if ((doSomething(), !!test)); + +switch ((val = foo(), val)) {} + +while ((val = foo(), val < 42)); + +with ((doSomething(), val)) {} + +const foo = (val) => ((console.log('bar'), val)); +``` + +Examples of **correct** code for this rule with the `{ "allowInParentheses": false }` option: + +```js +/*eslint no-sequences: ["error", { "allowInParentheses": false }]*/ + +for (i = 0, j = 10; i < j; i++, j--); +``` + +## When Not To Use It + +Disable this rule if sequence expressions with the comma operator are acceptable. +Another case is where you might want to report all usages of the comma operator, even in a for loop. You can achieve this using rule `no-restricted-syntax`: + +```js +{ + "rules": { + "no-restricted-syntax": ["error", "SequenceExpression"] + } +} +``` + +## Version + +This rule was introduced in ESLint 0.5.1. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-sequences.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-sequences.md) diff --git a/docs/8.0.0/rules/no-setter-return.md b/docs/8.0.0/rules/no-setter-return.md new file mode 100644 index 0000000000..c0a8cd6a0d --- /dev/null +++ b/docs/8.0.0/rules/no-setter-return.md @@ -0,0 +1,120 @@ +--- +title: no-setter-return - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-setter-return.md +rule_type: problem +--- + + +# Disallow returning values from setters (no-setter-return) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +Setters cannot return values. + +While returning a value from a setter does not produce an error, the returned value is being ignored. Therefore, returning a value from a setter is either unnecessary or a possible error, since the returned value cannot be used. + +## Rule Details + +This rule disallows returning values from setters and reports `return` statements in setter functions. + +Only `return` without a value is allowed, as it's a control flow statement. + +This rule checks setters in: + +* Object literals. +* Class declarations and class expressions. +* Property descriptors in `Object.create`, `Object.defineProperty`, `Object.defineProperties`, and `Reflect.defineProperty` methods of the global objects. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-setter-return: "error"*/ + +var foo = { + set a(value) { + this.val = value; + return value; + } +}; + +class Foo { + set a(value) { + this.val = value * 2; + return this.val; + } +} + +const Bar = class { + static set a(value) { + if (value < 0) { + this.val = 0; + return 0; + } + this.val = value; + } +}; + +Object.defineProperty(foo, "bar", { + set(value) { + if (value < 0) { + return false; + } + this.val = value; + } +}); +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-setter-return: "error"*/ + +var foo = { + set a(value) { + this.val = value; + } +}; + +class Foo { + set a(value) { + this.val = value * 2; + } +} + +const Bar = class { + static set a(value) { + if (value < 0) { + this.val = 0; + return; + } + this.val = value; + } +}; + +Object.defineProperty(foo, "bar", { + set(value) { + if (value < 0) { + throw new Error("Negative value."); + } + this.val = value; + } +}); +``` + +## Further Reading + +* [MDN setter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set) + +## Related Rules + +* [getter-return](getter-return) + +## Version + +This rule was introduced in ESLint 6.7.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-setter-return.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-setter-return.md) diff --git a/docs/8.0.0/rules/no-shadow-restricted-names.md b/docs/8.0.0/rules/no-shadow-restricted-names.md new file mode 100644 index 0000000000..e44e85c7a3 --- /dev/null +++ b/docs/8.0.0/rules/no-shadow-restricted-names.md @@ -0,0 +1,66 @@ +--- +title: no-shadow-restricted-names - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-shadow-restricted-names.md +rule_type: suggestion +--- + + +# Disallow Shadowing of Restricted Names (no-shadow-restricted-names) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +ES5 §15.1.1 Value Properties of the Global Object (`NaN`, `Infinity`, `undefined`) as well as strict mode restricted identifiers `eval` and `arguments` are considered to be restricted names in JavaScript. Defining them to mean something else can have unintended consequences and confuse others reading the code. For example, there's nothing preventing you from writing: + +```js +var undefined = "foo"; +``` + +Then any code used within the same scope would not get the global `undefined`, but rather the local version with a very different meaning. + +## Rule Details + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-shadow-restricted-names: "error"*/ + +function NaN(){} + +!function(Infinity){}; + +var undefined = 5; + +try {} catch(eval){} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-shadow-restricted-names: "error"*/ + +var Object; + +function f(a, b){} + +// Exception: `undefined` may be shadowed if the variable is never assigned a value. +var undefined; +``` + +## Further Reading + +* [Annotated ES5 - §15.1.1](https://es5.github.io/#x15.1.1) +* [Annotated ES5 - Annex C](https://es5.github.io/#C) + +## Related Rules + +* [no-shadow](no-shadow) + +## Version + +This rule was introduced in ESLint 0.1.4. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-shadow-restricted-names.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-shadow-restricted-names.md) diff --git a/docs/8.0.0/rules/no-shadow.md b/docs/8.0.0/rules/no-shadow.md new file mode 100644 index 0000000000..6c6df6554b --- /dev/null +++ b/docs/8.0.0/rules/no-shadow.md @@ -0,0 +1,190 @@ +--- +title: no-shadow - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-shadow.md +rule_type: suggestion +--- + + +# disallow variable declarations from shadowing variables declared in the outer scope (no-shadow) + +Shadowing is the process by which a local variable shares the same name as a variable in its containing scope. For example: + +```js +var a = 3; +function b() { + var a = 10; +} +``` + +In this case, the variable `a` inside of `b()` is shadowing the variable `a` in the global scope. This can cause confusion while reading the code and it's impossible to access the global variable. + +## Rule Details + +This rule aims to eliminate shadowed variable declarations. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-shadow: "error"*/ +/*eslint-env es6*/ + +var a = 3; +function b() { + var a = 10; +} + +var b = function () { + var a = 10; +} + +function b(a) { + a = 10; +} +b(a); + +if (true) { + let a = 5; +} +``` + +## Options + +This rule takes one option, an object, with properties `"builtinGlobals"`, `"hoist"` and `"allow"`. + +```json +{ + "no-shadow": ["error", { "builtinGlobals": false, "hoist": "functions", "allow": [] }] +} +``` + +### builtinGlobals + +The `builtinGlobals` option is `false` by default. +If it is `true`, the rule prevents shadowing of built-in global variables: `Object`, `Array`, `Number`, and so on. + +Examples of **incorrect** code for the `{ "builtinGlobals": true }` option: + +```js +/*eslint no-shadow: ["error", { "builtinGlobals": true }]*/ + +function foo() { + var Object = 0; +} +``` + +### hoist + +The `hoist` option has three settings: + +* `functions` (by default) - reports shadowing before the outer functions are defined. +* `all` - reports all shadowing before the outer variables/functions are defined. +* `never` - never report shadowing before the outer variables/functions are defined. + +#### hoist: functions + +Examples of **incorrect** code for the default `{ "hoist": "functions" }` option: + +```js +/*eslint no-shadow: ["error", { "hoist": "functions" }]*/ +/*eslint-env es6*/ + +if (true) { + let b = 6; +} + +function b() {} +``` + +Although `let b` in the `if` statement is before the *function* declaration in the outer scope, it is incorrect. + +Examples of **correct** code for the default `{ "hoist": "functions" }` option: + +```js +/*eslint no-shadow: ["error", { "hoist": "functions" }]*/ +/*eslint-env es6*/ + +if (true) { + let a = 3; +} + +let a = 5; +``` + +Because `let a` in the `if` statement is before the *variable* declaration in the outer scope, it is correct. + +#### hoist: all + +Examples of **incorrect** code for the `{ "hoist": "all" }` option: + +```js +/*eslint no-shadow: ["error", { "hoist": "all" }]*/ +/*eslint-env es6*/ + +if (true) { + let a = 3; + let b = 6; +} + +let a = 5; +function b() {} +``` + +#### hoist: never + +Examples of **correct** code for the `{ "hoist": "never" }` option: + +```js +/*eslint no-shadow: ["error", { "hoist": "never" }]*/ +/*eslint-env es6*/ + +if (true) { + let a = 3; + let b = 6; +} + +let a = 5; +function b() {} +``` + +Because `let a` and `let b` in the `if` statement are before the declarations in the outer scope, they are correct. + +### allow + +The `allow` option is an array of identifier names for which shadowing is allowed. For example, `"resolve"`, `"reject"`, `"done"`, `"cb"`. + +Examples of **correct** code for the `{ "allow": ["done"] }` option: + +```js +/*eslint no-shadow: ["error", { "allow": ["done"] }]*/ +/*eslint-env es6*/ + +import async from 'async'; + +function foo(done) { + async.map([1, 2], function (e, done) { + done(null, e * 2) + }, done); +} + +foo(function (err, result) { + console.log({ err, result }); +}); +``` + +## Further Reading + +* [Variable Shadowing](https://en.wikipedia.org/wiki/Variable_shadowing) + +## Related Rules + +* [no-shadow-restricted-names](no-shadow-restricted-names) + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-shadow.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-shadow.md) diff --git a/docs/8.0.0/rules/no-space-before-semi.md b/docs/8.0.0/rules/no-space-before-semi.md new file mode 100644 index 0000000000..5a95a6dff2 --- /dev/null +++ b/docs/8.0.0/rules/no-space-before-semi.md @@ -0,0 +1,59 @@ +--- +title: no-space-before-semi - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-space-before-semi.md + +--- + + +# no-space-before-semi: disallow spaces before semicolons + +(removed) This rule was **removed** in ESLint v1.0 and **replaced** by the [semi-spacing](semi-spacing) rule. + +JavaScript allows for placing unnecessary spaces between an expression and the closing semicolon. + +Space issues can also cause code to look inconsistent and harder to read. + +```js +var thing = function () { + var test = 12 ; +} ; +``` + +## Rule Details + +This rule prevents the use of spaces before a semicolon in expressions. + +Examples of **incorrect** code for this rule: + +```js +var foo = "bar" ; + +var foo = function() {} ; + +var foo = function() { +} ; + +var foo = 1 + 2 ; +``` + +Examples of **correct** code for this rule: + +```js +;(function(){}()); + +var foo = "bar"; +``` + +## Related Rules + +* [semi](semi) +* [no-extra-semi](no-extra-semi) + +## Version + +This rule was introduced in ESLint 0.4.3 and removed in 1.0.0-rc-1. + +## Resources + +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-space-before-semi.md) diff --git a/docs/8.0.0/rules/no-spaced-func.md b/docs/8.0.0/rules/no-spaced-func.md new file mode 100644 index 0000000000..c15f3f7569 --- /dev/null +++ b/docs/8.0.0/rules/no-spaced-func.md @@ -0,0 +1,47 @@ +--- +title: no-spaced-func - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-spaced-func.md +rule_type: layout +--- + + +# disallow spacing between function identifiers and their applications (no-spaced-func) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +This rule was **deprecated** in ESLint v3.3.0 and replaced by the [func-call-spacing](func-call-spacing) rule. + +While it's possible to have whitespace between the name of a function and the parentheses that execute it, such patterns tend to look more like errors. + +## Rule Details + +This rule disallows spacing between function identifiers and their applications. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-spaced-func: "error"*/ + +fn () + +fn +() +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-spaced-func: "error"*/ + +fn() +``` + +## Version + +This rule was introduced in ESLint 0.1.2. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-spaced-func.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-spaced-func.md) diff --git a/docs/8.0.0/rules/no-sparse-arrays.md b/docs/8.0.0/rules/no-sparse-arrays.md new file mode 100644 index 0000000000..bc6af1a77d --- /dev/null +++ b/docs/8.0.0/rules/no-sparse-arrays.md @@ -0,0 +1,69 @@ +--- +title: no-sparse-arrays - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-sparse-arrays.md +rule_type: problem +--- + + +# disallow sparse arrays (no-sparse-arrays) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +Sparse arrays contain empty slots, most frequently due to multiple commas being used in an array literal, such as: + +```js +var items = [,,]; +``` + +While the `items` array in this example has a `length` of 2, there are actually no values in `items[0]` or `items[1]`. The fact that the array literal is valid with only commas inside, coupled with the `length` being set and actual item values not being set, make sparse arrays confusing for many developers. Consider the following: + +```js +var colors = [ "red",, "blue" ]; +``` + +In this example, the `colors` array has a `length` of 3. But did the developer intend for there to be an empty spot in the middle of the array? Or is it a typo? + +The confusion around sparse arrays defined in this manner is enough that it's recommended to avoid using them unless you are certain that they are useful in your code. + +## Rule Details + +This rule disallows sparse array literals which have "holes" where commas are not preceded by elements. It does not apply to a trailing comma following the last element. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-sparse-arrays: "error"*/ + +var items = [,]; +var colors = [ "red",, "blue" ]; +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-sparse-arrays: "error"*/ + +var items = []; +var items = new Array(23); + +// trailing comma (after the last element) is not a problem +var colors = [ "red", "blue", ]; +``` + +## When Not To Use It + +If you want to use sparse arrays, then it is safe to disable this rule. + +## Further Reading + +* [Inconsistent array literals](https://www.nczonline.net/blog/2007/09/09/inconsistent-array-literals/) + +## Version + +This rule was introduced in ESLint 0.4.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-sparse-arrays.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-sparse-arrays.md) diff --git a/docs/8.0.0/rules/no-sync.md b/docs/8.0.0/rules/no-sync.md new file mode 100644 index 0000000000..3b9df6ccfa --- /dev/null +++ b/docs/8.0.0/rules/no-sync.md @@ -0,0 +1,78 @@ +--- +title: no-sync - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-sync.md +rule_type: suggestion +--- + + +# Disallow Synchronous Methods (no-sync) + +This rule was **deprecated** in ESLint v7.0.0. Please use the corresponding rule in [`eslint-plugin-node`](https://github.com/mysticatea/eslint-plugin-node). + +In Node.js, most I/O is done through asynchronous methods. However, there are often synchronous versions of the asynchronous methods. For example, `fs.exists()` and `fs.existsSync()`. In some contexts, using synchronous operations is okay (if, as with ESLint, you are writing a command line utility). However, in other contexts the use of synchronous operations is considered a bad practice that should be avoided. For example, if you are running a high-travel web server on Node.js, you should consider carefully if you want to allow any synchronous operations that could lock up the server. + +## Rule Details + +This rule is aimed at preventing synchronous methods from being called in Node.js. It looks specifically for the method suffix "`Sync`" (as is the convention with Node.js operations). + +## Options + +This rule has an optional object option `{ allowAtRootLevel: }`, which determines whether synchronous methods should be allowed at the top level of a file, outside of any functions. This option defaults to `false`. + +Examples of **incorrect** code for this rule with the default `{ allowAtRootLevel: false }` option: + +```js +/*eslint no-sync: "error"*/ + +fs.existsSync(somePath); + +function foo() { + var contents = fs.readFileSync(somePath).toString(); +} +``` + +Examples of **correct** code for this rule with the default `{ allowAtRootLevel: false }` option: + +```js +/*eslint no-sync: "error"*/ + +obj.sync(); + +async(function() { + // ... +}); +``` + +Examples of **incorrect** code for this rule with the `{ allowAtRootLevel: true }` option + +```js +/*eslint no-sync: ["error", { allowAtRootLevel: true }]*/ + +function foo() { + var contents = fs.readFileSync(somePath).toString(); +} + +var bar = baz => fs.readFileSync(qux); +``` + +Examples of **correct** code for this rule with the `{ allowAtRootLevel: true }` option + +```js +/*eslint no-sync: ["error", { allowAtRootLevel: true }]*/ + +fs.readFileSync(somePath).toString(); +``` + +## When Not To Use It + +If you want to allow synchronous operations in your script, do not enable this rule. + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-sync.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-sync.md) diff --git a/docs/8.0.0/rules/no-tabs.md b/docs/8.0.0/rules/no-tabs.md new file mode 100644 index 0000000000..3c758f162c --- /dev/null +++ b/docs/8.0.0/rules/no-tabs.md @@ -0,0 +1,78 @@ +--- +title: no-tabs - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-tabs.md +rule_type: layout +--- + + +# disallow all tabs (no-tabs) + +Some style guides don't allow the use of tab characters at all, including within comments. + +## Rule Details + +This rule looks for tabs anywhere inside a file: code, comments or anything else. + +Examples of **incorrect** code for this rule: + +```js +var a \t= 2; + +/** +* \t\t it's a test function +*/ +function test(){} + +var x = 1; // \t test +``` + +Examples of **correct** code for this rule: + +```js +var a = 2; + +/** +* it's a test function +*/ +function test(){} + +var x = 1; // test +``` + +### Options + +This rule has an optional object option with the following properties: + +* `allowIndentationTabs` (default: false): If this is set to true, then the rule will not report tabs used for indentation. + +#### allowIndentationTabs + +Examples of **correct** code for this rule with the `allowIndentationTabs: true` option: + +```js +/* eslint no-tabs: ["error", { allowIndentationTabs: true }] */ + +function test() { +\tdoSomething(); +} + +\t// comment with leading indentation tab +``` + +## When Not To Use It + +If you have established a standard where having tabs is fine, then you can disable this rule. + +## Compatibility + +* **JSCS**: [disallowTabs](https://jscs-dev.github.io/rule/disallowTabs) + +## Version + +This rule was introduced in ESLint 3.2.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-tabs.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-tabs.md) diff --git a/docs/8.0.0/rules/no-template-curly-in-string.md b/docs/8.0.0/rules/no-template-curly-in-string.md new file mode 100644 index 0000000000..18c0ea15da --- /dev/null +++ b/docs/8.0.0/rules/no-template-curly-in-string.md @@ -0,0 +1,50 @@ +--- +title: no-template-curly-in-string - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-template-curly-in-string.md +rule_type: problem +--- + + +# Disallow template literal placeholder syntax in regular strings (no-template-curly-in-string) + +ECMAScript 6 allows programmers to create strings containing variable or expressions using template literals, instead of string concatenation, by writing expressions like `${variable}` between two backtick quotes (\`). It can be easy to use the wrong quotes when wanting to use template literals, by writing `"${variable}"`, and end up with the literal value `"${variable}"` instead of a string containing the value of the injected expressions. + + +## Rule Details + +This rule aims to warn when a regular string contains what looks like a template literal placeholder. It will warn when it finds a string containing the template literal placeholder (`${something}`) that uses either `"` or `'` for the quotes. + +## Examples + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-template-curly-in-string: "error"*/ +"Hello ${name}!"; +'Hello ${name}!'; +"Time: ${12 * 60 * 60 * 1000}"; +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-template-curly-in-string: "error"*/ +`Hello ${name}!`; +`Time: ${12 * 60 * 60 * 1000}`; + +templateFunction`Hello ${name}`; +``` + +## When Not To Use It + +This rule should not be used in ES3/5 environments. + +## Version + +This rule was introduced in ESLint 3.3.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-template-curly-in-string.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-template-curly-in-string.md) diff --git a/docs/8.0.0/rules/no-ternary.md b/docs/8.0.0/rules/no-ternary.md new file mode 100644 index 0000000000..9d72034c61 --- /dev/null +++ b/docs/8.0.0/rules/no-ternary.md @@ -0,0 +1,67 @@ +--- +title: no-ternary - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-ternary.md +rule_type: suggestion +--- + + +# disallow ternary operators (no-ternary) + +The ternary operator is used to conditionally assign a value to a variable. Some believe that the use of ternary operators leads to unclear code. + +```js +var foo = isBar ? baz : qux; +``` + +## Rule Details + +This rule disallows ternary operators. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-ternary: "error"*/ + +var foo = isBar ? baz : qux; + +function quux() { + return foo ? bar() : baz(); +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-ternary: "error"*/ + +var foo; + +if (isBar) { + foo = baz; +} else { + foo = qux; +} + +function quux() { + if (foo) { + return bar(); + } else { + return baz(); + } +} +``` + +## Related Rules + +* [no-nested-ternary](no-nested-ternary) +* [no-unneeded-ternary](no-unneeded-ternary) + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-ternary.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-ternary.md) diff --git a/docs/8.0.0/rules/no-this-before-super.md b/docs/8.0.0/rules/no-this-before-super.md new file mode 100644 index 0000000000..a26cb72f41 --- /dev/null +++ b/docs/8.0.0/rules/no-this-before-super.md @@ -0,0 +1,94 @@ +--- +title: no-this-before-super - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-this-before-super.md +rule_type: problem +--- + + +# Disallow use of `this`/`super` before calling `super()` in constructors. (no-this-before-super) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +In the constructor of derived classes, if `this`/`super` are used before `super()` calls, it raises a reference error. + +This rule checks `this`/`super` keywords in constructors, then reports those that are before `super()`. + +## Rule Details + +This rule is aimed to flag `this`/`super` keywords before `super()` callings. + +## Examples + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-this-before-super: "error"*/ +/*eslint-env es6*/ + +class A extends B { + constructor() { + this.a = 0; + super(); + } +} + +class A extends B { + constructor() { + this.foo(); + super(); + } +} + +class A extends B { + constructor() { + super.foo(); + super(); + } +} + +class A extends B { + constructor() { + super(this.foo()); + } +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-this-before-super: "error"*/ +/*eslint-env es6*/ + +class A { + constructor() { + this.a = 0; // OK, this class doesn't have an `extends` clause. + } +} + +class A extends B { + constructor() { + super(); + this.a = 0; // OK, this is after `super()`. + } +} + +class A extends B { + foo() { + this.a = 0; // OK. this is not in a constructor. + } +} +``` + +## When Not To Use It + +If you don't want to be notified about using `this`/`super` before `super()` in constructors, you can safely disable this rule. + +## Version + +This rule was introduced in ESLint 0.24.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-this-before-super.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-this-before-super.md) diff --git a/docs/8.0.0/rules/no-throw-literal.md b/docs/8.0.0/rules/no-throw-literal.md new file mode 100644 index 0000000000..fed26cb0e8 --- /dev/null +++ b/docs/8.0.0/rules/no-throw-literal.md @@ -0,0 +1,94 @@ +--- +title: no-throw-literal - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-throw-literal.md +rule_type: suggestion +--- + + +# Restrict what can be thrown as an exception (no-throw-literal) + +It is considered good practice to only `throw` the `Error` object itself or an object using the `Error` object as base objects for user-defined exceptions. +The fundamental benefit of `Error` objects is that they automatically keep track of where they were built and originated. + +This rule restricts what can be thrown as an exception. When it was first created, it only prevented literals from being thrown (hence the name), but it has now been expanded to only allow expressions which have a possibility of being an `Error` object. + +## Rule Details + +This rule is aimed at maintaining consistency when throwing exception by disallowing to throw literals and other expressions which cannot possibly be an `Error` object. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-throw-literal: "error"*/ +/*eslint-env es6*/ + +throw "error"; + +throw 0; + +throw undefined; + +throw null; + +var err = new Error(); +throw "an " + err; +// err is recast to a string literal + +var err = new Error(); +throw `${err}` + +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-throw-literal: "error"*/ + +throw new Error(); + +throw new Error("error"); + +var e = new Error("error"); +throw e; + +try { + throw new Error("error"); +} catch (e) { + throw e; +} +``` + +## Known Limitations + +Due to the limits of static analysis, this rule cannot guarantee that you will only throw `Error` objects. + +Examples of **correct** code for this rule, but which do not throw an `Error` object: + +```js +/*eslint no-throw-literal: "error"*/ + +var err = "error"; +throw err; + +function foo(bar) { + console.log(bar); +} +throw foo("error"); + +throw new String("error"); + +var foo = { + bar: "error" +}; +throw foo.bar; +``` + +## Version + +This rule was introduced in ESLint 0.15.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-throw-literal.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-throw-literal.md) diff --git a/docs/8.0.0/rules/no-trailing-spaces.md b/docs/8.0.0/rules/no-trailing-spaces.md new file mode 100644 index 0000000000..a409356da8 --- /dev/null +++ b/docs/8.0.0/rules/no-trailing-spaces.md @@ -0,0 +1,82 @@ +--- +title: no-trailing-spaces - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-trailing-spaces.md +rule_type: layout +--- + + +# disallow trailing whitespace at the end of lines (no-trailing-spaces) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +Sometimes in the course of editing files, you can end up with extra whitespace at the end of lines. These whitespace differences can be picked up by source control systems and flagged as diffs, causing frustration for developers. While this extra whitespace causes no functional issues, many code conventions require that trailing spaces be removed before check-in. + +## Rule Details + +This rule disallows trailing whitespace (spaces, tabs, and other Unicode whitespace characters) at the end of lines. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-trailing-spaces: "error"*/ + +var foo = 0;//••••• +var baz = 5;//•• +//••••• +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-trailing-spaces: "error"*/ + +var foo = 0; +var baz = 5; +``` + +## Options + +This rule has an object option: + +* `"skipBlankLines": false` (default) disallows trailing whitespace on empty lines +* `"skipBlankLines": true` allows trailing whitespace on empty lines +* `"ignoreComments": false` (default) disallows trailing whitespace in comment blocks +* `"ignoreComments": true` allows trailing whitespace in comment blocks + +### skipBlankLines + +Examples of **correct** code for this rule with the `{ "skipBlankLines": true }` option: + +```js +/*eslint no-trailing-spaces: ["error", { "skipBlankLines": true }]*/ + +var foo = 0; +var baz = 5; +//••••• +``` + +### ignoreComments + +Examples of **correct** code for this rule with the `{ "ignoreComments": true }` option: + +```js +/*eslint no-trailing-spaces: ["error", { "ignoreComments": true }]*/ + +//foo• +//••••• +/** + *•baz + *•• + *•bar + */ +``` + +## Version + +This rule was introduced in ESLint 0.7.1. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-trailing-spaces.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-trailing-spaces.md) diff --git a/docs/8.0.0/rules/no-undef-init.md b/docs/8.0.0/rules/no-undef-init.md new file mode 100644 index 0000000000..7a1cd2f036 --- /dev/null +++ b/docs/8.0.0/rules/no-undef-init.md @@ -0,0 +1,130 @@ +--- +title: no-undef-init - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-undef-init.md +rule_type: suggestion +--- + + +# Disallow Initializing to undefined (no-undef-init) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +In JavaScript, a variable that is declared and not initialized to any value automatically gets the value of `undefined`. For example: + +```js +var foo; + +console.log(foo === undefined); // true +``` + +It's therefore unnecessary to initialize a variable to `undefined`, such as: + +```js +var foo = undefined; +``` + +It's considered a best practice to avoid initializing variables to `undefined`. + + +## Rule Details + +This rule aims to eliminate variable declarations that initialize to `undefined`. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-undef-init: "error"*/ +/*eslint-env es6*/ + +var foo = undefined; +let bar = undefined; +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-undef-init: "error"*/ +/*eslint-env es6*/ + +var foo; +let bar; +const baz = undefined; +``` + +## When Not To Use It + +There is one situation where initializing to `undefined` behaves differently than omitting the initialization, and that's when a `var` declaration occurs inside of a loop. For example: + +Example of **incorrect** code for this rule: + +```js +for (i = 0; i < 10; i++) { + var x = undefined; + console.log(x); + x = i; +} +``` + +In this case, the `var x` is hoisted out of the loop, effectively creating: + +```js +var x; + +for (i = 0; i < 10; i++) { + x = undefined; + console.log(x); + x = i; +} +``` + +If you were to remove the initialization, then the behavior of the loop changes: + +```js +for (i = 0; i < 10; i++) { + var x; + console.log(x); + x = i; +} +``` + +This code is equivalent to: + +```js +var x; + +for (i = 0; i < 10; i++) { + console.log(x); + x = i; +} +``` + +This produces a different outcome than defining `var x = undefined` in the loop, as `x` is no longer reset to `undefined` each time through the loop. + +If you're using such an initialization inside of a loop, then you should disable this rule. + +Example of **correct** code for this rule, because it is disabled on a specific line: + +```js +/*eslint no-undef-init: "error"*/ + +for (i = 0; i < 10; i++) { + var x = undefined; // eslint-disable-line no-undef-init + console.log(x); + x = i; +} +``` + +## Related Rules + +* [no-undefined](no-undefined) +* [no-void](no-void) + +## Version + +This rule was introduced in ESLint 0.0.6. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-undef-init.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-undef-init.md) diff --git a/docs/8.0.0/rules/no-undef.md b/docs/8.0.0/rules/no-undef.md new file mode 100644 index 0000000000..703f345bfd --- /dev/null +++ b/docs/8.0.0/rules/no-undef.md @@ -0,0 +1,130 @@ +--- +title: no-undef - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-undef.md +rule_type: problem +--- + + +# Disallow Undeclared Variables (no-undef) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +This rule can help you locate potential ReferenceErrors resulting from misspellings of variable and parameter names, or accidental implicit globals (for example, from forgetting the `var` keyword in a `for` loop initializer). + +## Rule Details + +Any reference to an undeclared variable causes a warning, unless the variable is explicitly mentioned in a `/*global ...*/` comment, or specified in the [`globals` key in the configuration file](https://eslint.org/docs/user-guide/configuring#specifying-globals). A common use case for these is if you intentionally use globals that are defined elsewhere (e.g. in a script sourced from HTML). + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-undef: "error"*/ + +var foo = someFunction(); +var bar = a + 1; +``` + +Examples of **correct** code for this rule with `global` declaration: + +```js +/*global someFunction, a*/ +/*eslint no-undef: "error"*/ + +var foo = someFunction(); +var bar = a + 1; +``` + +Note that this rule does not disallow assignments to read-only global variables. +See [no-global-assign](no-global-assign) if you also want to disallow those assignments. + +This rule also does not disallow redeclarations of global variables. +See [no-redeclare](no-redeclare) if you also want to disallow those redeclarations. + +## Options + +* `typeof` set to true will warn for variables used inside typeof check (Default false). + +### typeof + +Examples of **correct** code for the default `{ "typeof": false }` option: + +```js +/*eslint no-undef: "error"*/ + +if (typeof UndefinedIdentifier === "undefined") { + // do something ... +} +``` + +You can use this option if you want to prevent `typeof` check on a variable which has not been declared. + +Examples of **incorrect** code for the `{ "typeof": true }` option: + +```js +/*eslint no-undef: ["error", { "typeof": true }] */ + +if(typeof a === "string"){} +``` + +Examples of **correct** code for the `{ "typeof": true }` option with `global` declaration: + +```js +/*global a*/ +/*eslint no-undef: ["error", { "typeof": true }] */ + +if(typeof a === "string"){} +``` + +## Environments + +For convenience, ESLint provides shortcuts that pre-define global variables exposed by popular libraries and runtime environments. This rule supports these environments, as listed in [Specifying Environments](../user-guide/configuring/language-options#specifying-environments). A few examples are given below. + +### browser + +Examples of **correct** code for this rule with `browser` environment: + +```js +/*eslint no-undef: "error"*/ +/*eslint-env browser*/ + +setTimeout(function() { + alert("Hello"); +}); +``` + +### Node.js + +Examples of **correct** code for this rule with `node` environment: + +```js +/*eslint no-undef: "error"*/ +/*eslint-env node*/ + +var fs = require("fs"); +module.exports = function() { + console.log(fs); +}; +``` + +## When Not To Use It + +If explicit declaration of global variables is not to your taste. + +## Compatibility + +This rule provides compatibility with treatment of global variables in [JSHint](http://jshint.com/) and [JSLint](http://www.jslint.com). + +## Related Rules + +* [no-global-assign](no-global-assign) +* [no-redeclare](no-redeclare) + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-undef.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-undef.md) diff --git a/docs/8.0.0/rules/no-undefined.md b/docs/8.0.0/rules/no-undefined.md new file mode 100644 index 0000000000..753fb6e63a --- /dev/null +++ b/docs/8.0.0/rules/no-undefined.md @@ -0,0 +1,96 @@ +--- +title: no-undefined - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-undefined.md +rule_type: suggestion +--- + + +# Disallow Use of `undefined` Variable (no-undefined) + +The `undefined` variable in JavaScript is actually a property of the global object. As such, in ECMAScript 3 it was possible to overwrite the value of `undefined`. While ECMAScript 5 disallows overwriting `undefined`, it's still possible to shadow `undefined`, such as: + +```js +function doSomething(data) { + var undefined = "hi"; + + // doesn't do what you think it does + if (data === undefined) { + // ... + } + +} +``` + +Because `undefined` can be overwritten or shadowed, reading `undefined` can give an unexpected value. (This is not the case for `null`, which is a keyword that always produces the same value.) To guard against this, you can avoid all uses of `undefined`, which is what some style guides recommend and what this rule enforces. Those style guides then also recommend: + +* Variables that should be `undefined` are simply left uninitialized. (All uninitialized variables automatically get the value of `undefined` in JavaScript.) +* Checking if a value is `undefined` should be done with `typeof`. +* Using the `void` operator to generate the value of `undefined` if necessary. + +As an alternative, you can use the [no-global-assign](no-global-assign) and [no-shadow-restricted-names](no-shadow-restricted-names) rules to prevent `undefined` from being shadowed or assigned a different value. This ensures that `undefined` will always hold its original, expected value. + + +## Rule Details + +This rule aims to eliminate the use of `undefined`, and as such, generates a warning whenever it is used. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-undefined: "error"*/ + +var foo = undefined; + +var undefined = "foo"; + +if (foo === undefined) { + // ... +} + +function foo(undefined) { + // ... +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-undefined: "error"*/ + +var foo = void 0; + +var Undefined = "foo"; + +if (typeof foo === "undefined") { + // ... +} + +global.undefined = "foo"; +``` + +## When Not To Use It + +If you want to allow the use of `undefined` in your code, then you can safely turn this rule off. + +## Further Reading + +* [undefined - JavaScript \| MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined) +* [Understanding JavaScript’s ‘undefined’ \| JavaScript, JavaScript...](https://javascriptweblog.wordpress.com/2010/08/16/understanding-undefined-and-preventing-referenceerrors/) +* [ECMA262 edition 5.1 §15.1.1.3: undefined](https://es5.github.io/#x15.1.1.3) + +## Related Rules + +* [no-undef-init](no-undef-init) +* [no-void](no-void) +* [no-shadow-restricted-names](no-shadow-restricted-names) +* [no-global-assign](no-global-assign) + +## Version + +This rule was introduced in ESLint 0.7.1. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-undefined.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-undefined.md) diff --git a/docs/8.0.0/rules/no-underscore-dangle.md b/docs/8.0.0/rules/no-underscore-dangle.md new file mode 100644 index 0000000000..b42506d3f1 --- /dev/null +++ b/docs/8.0.0/rules/no-underscore-dangle.md @@ -0,0 +1,159 @@ +--- +title: no-underscore-dangle - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-underscore-dangle.md +rule_type: suggestion +--- + + +# disallow dangling underscores in identifiers (no-underscore-dangle) + +As far as naming conventions for identifiers go, dangling underscores may be the most polarizing in JavaScript. Dangling underscores are underscores at either the beginning or end of an identifier, such as: + +```js +var _foo; +``` + +There is actually a long history of using dangling underscores to indicate "private" members of objects in JavaScript (though JavaScript doesn't have truly private members, this convention served as a warning). This began with SpiderMonkey adding nonstandard methods such as `__defineGetter__()`. The intent with the underscores was to make it obvious that this method was special in some way. Since that time, using a single underscore prefix has become popular as a way to indicate "private" members of objects. + +Whether or not you choose to allow dangling underscores in identifiers is purely a convention and has no effect on performance, readability, or complexity. It's purely a preference. + +## Rule Details + +This rule disallows dangling underscores in identifiers. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-underscore-dangle: "error"*/ + +var foo_; +var __proto__ = {}; +foo._bar(); +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-underscore-dangle: "error"*/ + +var _ = require('underscore'); +var obj = _.contains(items, item); +obj.__proto__ = {}; +var file = __filename; +function foo(_bar) {}; +const foo = { onClick(_bar) {} }; +const foo = (_bar) => {}; +``` + +## Options + +This rule has an object option: + +- `"allow"` allows specified identifiers to have dangling underscores +- `"allowAfterThis": false` (default) disallows dangling underscores in members of the `this` object +- `"allowAfterSuper": false` (default) disallows dangling underscores in members of the `super` object +- `"allowAfterThisConstructor": false` (default) disallows dangling underscores in members of the `this.constructor` object +- `"enforceInMethodNames": false` (default) allows dangling underscores in method names +- `"allowFunctionParams": true` (default) allows dangling underscores in function parameter names + +### allow + +Examples of additional **correct** code for this rule with the `{ "allow": ["foo_", "_bar"] }` option: + +```js +/*eslint no-underscore-dangle: ["error", { "allow": ["foo_", "_bar"] }]*/ + +var foo_; +foo._bar(); +``` + +### allowAfterThis + +Examples of **correct** code for this rule with the `{ "allowAfterThis": true }` option: + +```js +/*eslint no-underscore-dangle: ["error", { "allowAfterThis": true }]*/ + +var a = this.foo_; +this._bar(); +``` + +### allowAfterSuper + +Examples of **correct** code for this rule with the `{ "allowAfterSuper": true }` option: + +```js +/*eslint no-underscore-dangle: ["error", { "allowAfterSuper": true }]*/ + +var a = super.foo_; +super._bar(); +``` + +### allowAfterThisConstructor + +Examples of **correct** code for this rule with the `{ "allowAfterThisConstructor": true }` option: + +```js +/*eslint no-underscore-dangle: ["error", { "allowAfterThisConstructor": true }]*/ + +var a = this.constructor.foo_; +this.constructor._bar(); +``` + +### enforceInMethodNames + +Examples of **incorrect** code for this rule with the `{ "enforceInMethodNames": true }` option: + +```js +/*eslint no-underscore-dangle: ["error", { "enforceInMethodNames": true }]*/ + +class Foo { + _bar() {} +} + +class Foo { + bar_() {} +} + +const o = { + _bar() {} +}; + +const o = { + bar_() = {} +}; +``` + +### allowFunctionParams + +Examples of **incorrect** code for this rule with the `{ "allowFunctionParams": false }` option: + +```js +/*eslint no-underscore-dangle: ["error", { "allowFunctionParams": false }]*/ + +function foo (_bar) {} +function foo (_bar = 0) {} +function foo (..._bar) {} + +const foo = function onClick (_bar) {} +const foo = function onClick (_bar = 0) {} +const foo = function onClick (..._bar) {} + +const foo = (_bar) => {}; +const foo = (_bar = 0) => {}; +const foo = (..._bar) => {}; +``` + +## When Not To Use It + +If you want to allow dangling underscores in identifiers, then you can safely turn this rule off. + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-underscore-dangle.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-underscore-dangle.md) diff --git a/docs/8.0.0/rules/no-unexpected-multiline.md b/docs/8.0.0/rules/no-unexpected-multiline.md new file mode 100644 index 0000000000..9a681ffc98 --- /dev/null +++ b/docs/8.0.0/rules/no-unexpected-multiline.md @@ -0,0 +1,93 @@ +--- +title: no-unexpected-multiline - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-unexpected-multiline.md +rule_type: problem +--- + + +# disallow confusing multiline expressions (no-unexpected-multiline) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +Semicolons are usually optional in JavaScript, because of automatic semicolon insertion (ASI). You can require or disallow semicolons with the [semi](./semi) rule. + +The rules for ASI are relatively straightforward: As once described by Isaac Schlueter, a newline character always ends a statement, just like a semicolon, **except** where one of the following is true: + +* The statement has an unclosed paren, array literal, or object literal or ends in some other way that is not a valid way to end a statement. (For instance, ending with `.` or `,`.) +* The line is `--` or `++` (in which case it will decrement/increment the next token.) +* It is a `for()`, `while()`, `do`, `if()`, or `else`, and there is no `{` +* The next line starts with `[`, `(`, `+`, `*`, `/`, `-`, `,`, `.`, or some other binary operator that can only be found between two tokens in a single expression. + +In the exceptions where a newline does **not** end a statement, a typing mistake to omit a semicolon causes two unrelated consecutive lines to be interpreted as one expression. Especially for a coding style without semicolons, readers might overlook the mistake. Although syntactically correct, the code might throw exceptions when it is executed. + +## Rule Details + +This rule disallows confusing multiline expressions where a newline looks like it is ending a statement, but is not. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-unexpected-multiline: "error"*/ + +var foo = bar +(1 || 2).baz(); + +var hello = 'world' +[1, 2, 3].forEach(addNumber); + +let x = function() {} +`hello` + +let x = function() {} +x +`hello` + +let x = foo +/regex/g.test(bar) +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-unexpected-multiline: "error"*/ + +var foo = bar; +(1 || 2).baz(); + +var foo = bar +;(1 || 2).baz() + +var hello = 'world'; +[1, 2, 3].forEach(addNumber); + +var hello = 'world' +void [1, 2, 3].forEach(addNumber); + +let x = function() {}; +`hello` + +let tag = function() {} +tag `hello` +``` + +## When Not To Use It + +You can turn this rule off if you are confident that you will not accidentally introduce code like this. + +Note that the patterns considered problems are **not** flagged by the [semi](semi) rule. + +## Related Rules + +* [func-call-spacing](func-call-spacing) +* [semi](semi) +* [space-unary-ops](space-unary-ops) + +## Version + +This rule was introduced in ESLint 0.24.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-unexpected-multiline.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-unexpected-multiline.md) diff --git a/docs/8.0.0/rules/no-unmodified-loop-condition.md b/docs/8.0.0/rules/no-unmodified-loop-condition.md new file mode 100644 index 0000000000..d54c5ec9e4 --- /dev/null +++ b/docs/8.0.0/rules/no-unmodified-loop-condition.md @@ -0,0 +1,107 @@ +--- +title: no-unmodified-loop-condition - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-unmodified-loop-condition.md +rule_type: problem +--- + + +# Disallow unmodified conditions of loops (no-unmodified-loop-condition) + +Variables in a loop condition often are modified in the loop. +If not, it's possibly a mistake. + +```js +while (node) { + doSomething(node); +} +``` + +```js +while (node) { + doSomething(node); + node = node.parent; +} +``` + +## Rule Details + +This rule finds references which are inside of loop conditions, then checks the +variables of those references are modified in the loop. + +If a reference is inside of a binary expression or a ternary expression, this rule checks the result of +the expression instead. +If a reference is inside of a dynamic expression (e.g. `CallExpression`, +`YieldExpression`, ...), this rule ignores it. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-unmodified-loop-condition: "error"*/ + +var node = something; + +while (node) { + doSomething(node); +} +node = other; + +for (var j = 0; j < items.length; ++i) { + doSomething(items[j]); +} + +while (node !== root) { + doSomething(node); +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-unmodified-loop-condition: "error"*/ + +while (node) { + doSomething(node); + node = node.parent; +} + +for (var j = 0; j < items.length; ++j) { + doSomething(items[j]); +} + +// OK, the result of this binary expression is changed in this loop. +while (node !== root) { + doSomething(node); + node = node.parent; +} + +// OK, the result of this ternary expression is changed in this loop. +while (node ? A : B) { + doSomething(node); + node = node.parent; +} + +// A property might be a getter which has side effect... +// Or "doSomething" can modify "obj.foo". +while (obj.foo) { + doSomething(obj); +} + +// A function call can return various values. +while (check(obj)) { + doSomething(obj); +} +``` + +## When Not To Use It + +If you don't want to notified about references inside of loop conditions, then it's safe to disable this rule. + +## Version + +This rule was introduced in ESLint 2.0.0-alpha-2. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-unmodified-loop-condition.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-unmodified-loop-condition.md) diff --git a/docs/8.0.0/rules/no-unneeded-ternary.md b/docs/8.0.0/rules/no-unneeded-ternary.md new file mode 100644 index 0000000000..31333df225 --- /dev/null +++ b/docs/8.0.0/rules/no-unneeded-ternary.md @@ -0,0 +1,111 @@ +--- +title: no-unneeded-ternary - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-unneeded-ternary.md +rule_type: suggestion +--- + + +# disallow ternary operators when simpler alternatives exist (no-unneeded-ternary) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +It's a common mistake in JavaScript to use a conditional expression to select between two Boolean values instead of using ! to convert the test to a Boolean. +Here are some examples: + +```js +// Bad +var isYes = answer === 1 ? true : false; + +// Good +var isYes = answer === 1; + + +// Bad +var isNo = answer === 1 ? false : true; + +// Good +var isNo = answer !== 1; +``` + +Another common mistake is using a single variable as both the conditional test and the consequent. In such cases, the logical `OR` can be used to provide the same functionality. +Here is an example: + +```js +// Bad +foo(bar ? bar : 1); + +// Good +foo(bar || 1); +``` + +## Rule Details + +This rule disallow ternary operators when simpler alternatives exist. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-unneeded-ternary: "error"*/ + +var a = x === 2 ? true : false; + +var a = x ? true : false; +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-unneeded-ternary: "error"*/ + +var a = x === 2 ? "Yes" : "No"; + +var a = x !== false; + +var a = x ? "Yes" : "No"; + +var a = x ? y : x; + +f(x ? x : 1); // default assignment - would be disallowed if defaultAssignment option set to false. See option details below. +``` + +## Options + +This rule has an object option: + +* `"defaultAssignment": true` (default) allows the conditional expression as a default assignment pattern +* `"defaultAssignment": false` disallows the conditional expression as a default assignment pattern + +### defaultAssignment + +When set to `true`, which it is by default, The defaultAssignment option allows expressions of the form `x ? x : expr` (where `x` is any identifier and `expr` is any expression). + +Examples of additional **incorrect** code for this rule with the `{ "defaultAssignment": false }` option: + +```js +/*eslint no-unneeded-ternary: ["error", { "defaultAssignment": false }]*/ + +var a = x ? x : 1; + +f(x ? x : 1); +``` + +Note that `defaultAssignment: false` still allows expressions of the form `x ? expr : x` (where the identifier is on the right hand side of the ternary). + +## When Not To Use It + +You can turn this rule off if you are not concerned with unnecessary complexity in conditional expressions. + +## Related Rules + +* [no-ternary](no-ternary) +* [no-nested-ternary](no-nested-ternary) + +## Version + +This rule was introduced in ESLint 0.21.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-unneeded-ternary.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-unneeded-ternary.md) diff --git a/docs/8.0.0/rules/no-unreachable-loop.md b/docs/8.0.0/rules/no-unreachable-loop.md new file mode 100644 index 0000000000..112c13d43c --- /dev/null +++ b/docs/8.0.0/rules/no-unreachable-loop.md @@ -0,0 +1,207 @@ +--- +title: no-unreachable-loop - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-unreachable-loop.md +rule_type: problem +--- + + +# Disallow loops with a body that allows only one iteration (no-unreachable-loop) + +A loop that can never reach the second iteration is a possible error in the code. + +```js +for (let i = 0; i < arr.length; i++) { + if (arr[i].name === myName) { + doSomething(arr[i]); + // break was supposed to be here + } + break; +} +``` + +In rare cases where only one iteration (or at most one iteration) is intended behavior, the code should be refactored to use `if` conditionals instead of `while`, `do-while` and `for` loops. It's considered a best practice to avoid using loop constructs for such cases. + +## Rule Details + +This rule aims to detect and disallow loops that can have at most one iteration, by performing static code path analysis on loop bodies. + +In particular, this rule will disallow a loop with a body that exits the loop in all code paths. If all code paths in the loop's body will end with either a `break`, `return` or a `throw` statement, the second iteration of such loop is certainly unreachable, regardless of the loop's condition. + +This rule checks `while`, `do-while`, `for`, `for-in` and `for-of` loops. You can optionally disable checks for each of these constructs. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-unreachable-loop: "error"*/ + +while (foo) { + doSomething(foo); + foo = foo.parent; + break; +} + +function verifyList(head) { + let item = head; + do { + if (verify(item)) { + return true; + } else { + return false; + } + } while (item); +} + +function findSomething(arr) { + for (var i = 0; i < arr.length; i++) { + if (isSomething(arr[i])) { + return arr[i]; + } else { + throw new Error("Doesn't exist."); + } + } +} + +for (key in obj) { + if (key.startsWith("_")) { + break; + } + firstKey = key; + firstValue = obj[key]; + break; +} + +for (foo of bar) { + if (foo.id === id) { + doSomething(foo); + } + break; +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-unreachable-loop: "error"*/ + +while (foo) { + doSomething(foo); + foo = foo.parent; +} + +function verifyList(head) { + let item = head; + do { + if (verify(item)) { + item = item.next; + } else { + return false; + } + } while (item); + + return true; +} + +function findSomething(arr) { + for (var i = 0; i < arr.length; i++) { + if (isSomething(arr[i])) { + return arr[i]; + } + } + throw new Error("Doesn't exist."); +} + +for (key in obj) { + if (key.startsWith("_")) { + continue; + } + firstKey = key; + firstValue = obj[key]; + break; +} + +for (foo of bar) { + if (foo.id === id) { + doSomething(foo); + break; + } +} +``` + +Please note that this rule is not designed to check loop conditions, and will not warn in cases such as the following examples. + +Examples of additional **correct** code for this rule: + +```js +/*eslint no-unreachable-loop: "error"*/ + +do { + doSomething(); +} while (false) + +for (let i = 0; i < 1; i++) { + doSomething(i); +} + +for (const a of [1]) { + doSomething(a); +} +``` + +## Options + +This rule has an object option, with one option: + +* `"ignore"` - an optional array of loop types that will be ignored by this rule. + +## ignore + +You can specify up to 5 different elements in the `"ignore"` array: + +* `"WhileStatement"` - to ignore all `while` loops. +* `"DoWhileStatement"` - to ignore all `do-while` loops. +* `"ForStatement"` - to ignore all `for` loops (does not apply to `for-in` and `for-of` loops). +* `"ForInStatement"` - to ignore all `for-in` loops. +* `"ForOfStatement"` - to ignore all `for-of` loops. + +Examples of **correct** code for this rule with the `"ignore"` option: + +```js +/*eslint no-unreachable-loop: ["error", { "ignore": ["ForInStatement", "ForOfStatement"] }]*/ + +for (var key in obj) { + hasEnumerableProperties = true; + break; +} + +for (const a of b) break; +``` + +## Known Limitations + +Static code path analysis, in general, does not evaluate conditions. Due to this fact, this rule might miss reporting cases such as the following: + +```js +for (let i = 0; i < 10; i++) { + doSomething(i); + if (true) { + break; + } +} +``` + +## Related Rules + +* [no-unreachable](no-unreachable) +* [no-constant-condition](no-constant-condition) +* [no-unmodified-loop-condition](no-unmodified-loop-condition) +* [for-direction](for-direction) + +## Version + +This rule was introduced in ESLint 7.3.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-unreachable-loop.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-unreachable-loop.md) diff --git a/docs/8.0.0/rules/no-unreachable.md b/docs/8.0.0/rules/no-unreachable.md new file mode 100644 index 0000000000..f911c94ee4 --- /dev/null +++ b/docs/8.0.0/rules/no-unreachable.md @@ -0,0 +1,94 @@ +--- +title: no-unreachable - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-unreachable.md +rule_type: problem +--- + + +# disallow unreachable code after `return`, `throw`, `continue`, and `break` statements (no-unreachable) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +Because the `return`, `throw`, `break`, and `continue` statements unconditionally exit a block of code, any statements after them cannot be executed. Unreachable statements are usually a mistake. + +```js +function fn() { + x = 1; + return x; + x = 3; // this will never execute +} +``` + +## Rule Details + +This rule disallows unreachable code after `return`, `throw`, `continue`, and `break` statements. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-unreachable: "error"*/ + +function foo() { + return true; + console.log("done"); +} + +function bar() { + throw new Error("Oops!"); + console.log("done"); +} + +while(value) { + break; + console.log("done"); +} + +throw new Error("Oops!"); +console.log("done"); + +function baz() { + if (Math.random() < 0.5) { + return; + } else { + throw new Error(); + } + console.log("done"); +} + +for (;;) {} +console.log("done"); +``` + +Examples of **correct** code for this rule, because of JavaScript function and variable hoisting: + +```js +/*eslint no-unreachable: "error"*/ + +function foo() { + return bar(); + function bar() { + return 1; + } +} + +function bar() { + return x; + var x; +} + +switch (foo) { + case 1: + break; + var x; +} +``` + +## Version + +This rule was introduced in ESLint 0.0.6. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-unreachable.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-unreachable.md) diff --git a/docs/8.0.0/rules/no-unsafe-finally.md b/docs/8.0.0/rules/no-unsafe-finally.md new file mode 100644 index 0000000000..e5be94259e --- /dev/null +++ b/docs/8.0.0/rules/no-unsafe-finally.md @@ -0,0 +1,163 @@ +--- +title: no-unsafe-finally - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-unsafe-finally.md +rule_type: problem +--- + + +# disallow control flow statements in `finally` blocks (no-unsafe-finally) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +JavaScript suspends the control flow statements of `try` and `catch` blocks until the execution of `finally` block finishes. So, when `return`, `throw`, `break`, or `continue` is used in `finally`, control flow statements inside `try` and `catch` are overwritten, which is considered as unexpected behavior. Such as: + +```js +// We expect this function to return 1; +(() => { + try { + return 1; // 1 is returned but suspended until finally block ends + } catch(err) { + return 2; + } finally { + return 3; // 3 is returned before 1, which we did not expect + } +})(); + +// > 3 +``` + +```js +// We expect this function to throw an error, then return +(() => { + try { + throw new Error("Try"); // error is thrown but suspended until finally block ends + } finally { + return 3; // 3 is returned before the error is thrown, which we did not expect + } +})(); + +// > 3 +``` + +```js +// We expect this function to throw Try(...) error from the catch block +(() => { + try { + throw new Error("Try") + } catch(err) { + throw err; // The error thrown from try block is caught and rethrown + } finally { + throw new Error("Finally"); // Finally(...) is thrown, which we did not expect + } +})(); + +// > Uncaught Error: Finally(...) +``` + +```js +// We expect this function to return 0 from try block. +(() => { + label: try { + return 0; // 0 is returned but suspended until finally block ends + } finally { + break label; // It breaks out the try-finally block, before 0 is returned. + } + return 1; +})(); + +// > 1 +``` + +## Rule Details + +This rule disallows `return`, `throw`, `break`, and `continue` statements inside `finally` blocks. It allows indirect usages, such as in `function` or `class` definitions. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-unsafe-finally: "error"*/ +let foo = function() { + try { + return 1; + } catch(err) { + return 2; + } finally { + return 3; + } +}; +``` + +```js +/*eslint no-unsafe-finally: "error"*/ +let foo = function() { + try { + return 1; + } catch(err) { + return 2; + } finally { + throw new Error; + } +}; +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-unsafe-finally: "error"*/ +let foo = function() { + try { + return 1; + } catch(err) { + return 2; + } finally { + console.log("hola!"); + } +}; +``` + +```js +/*eslint no-unsafe-finally: "error"*/ +let foo = function() { + try { + return 1; + } catch(err) { + return 2; + } finally { + let a = function() { + return "hola!"; + } + } +}; +``` + +```js +/*eslint no-unsafe-finally: "error"*/ +let foo = function(a) { + try { + return 1; + } catch(err) { + return 2; + } finally { + switch(a) { + case 1: { + console.log("hola!") + break; + } + } + } +}; +``` + +## When Not To Use It + +If you want to allow control flow operations in `finally` blocks, you can turn this rule off. + +## Version + +This rule was introduced in ESLint 2.9.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-unsafe-finally.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-unsafe-finally.md) diff --git a/docs/8.0.0/rules/no-unsafe-negation.md b/docs/8.0.0/rules/no-unsafe-negation.md new file mode 100644 index 0000000000..a268cd82c8 --- /dev/null +++ b/docs/8.0.0/rules/no-unsafe-negation.md @@ -0,0 +1,128 @@ +--- +title: no-unsafe-negation - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-unsafe-negation.md +rule_type: problem +--- + + +# disallow negating the left operand of relational operators (no-unsafe-negation) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +(hasSuggestions) Some problems reported by this rule are manually fixable by editor [suggestions](../developer-guide/working-with-rules#providing-suggestions). + +Just as developers might type `-a + b` when they mean `-(a + b)` for the negative of a sum, they might type `!key in object` by mistake when they almost certainly mean `!(key in object)` to test that a key is not in an object. `!obj instanceof Ctor` is similar. + +## Rule Details + +This rule disallows negating the left operand of the following relational operators: + +- [`in` operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in). +- [`instanceof` operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof). + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-unsafe-negation: "error"*/ + +if (!key in object) { + // operator precedence makes it equivalent to (!key) in object + // and type conversion makes it equivalent to (key ? "false" : "true") in object +} + +if (!obj instanceof Ctor) { + // operator precedence makes it equivalent to (!obj) instanceof Ctor + // and it equivalent to always false since boolean values are not objects. +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-unsafe-negation: "error"*/ + +if (!(key in object)) { + // key is not in object +} + +if (!(obj instanceof Ctor)) { + // obj is not an instance of Ctor +} +``` + +### Exception + +For rare situations when negating the left operand is intended, this rule allows an exception. +If the whole negation is explicitly wrapped in parentheses, the rule will not report a problem. + +Examples of **correct** code for this rule: + +```js +/*eslint no-unsafe-negation: "error"*/ + +if ((!foo) in object) { + // allowed, because the negation is explicitly wrapped in parentheses + // it is equivalent to (foo ? "false" : "true") in object + // this is allowed as an exception for rare situations when that is the intended meaning +} + +if(("" + !foo) in object) { + // you can also make the intention more explicit, with type conversion +} +``` + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-unsafe-negation: "error"*/ + +if (!(foo) in object) { + // this is not an allowed exception +} +``` + +## Options + +This rule has an object option: + +- `"enforceForOrderingRelations": false` (default) allows negation of the left-hand side of ordering relational operators (`<`, `>`, `<=`, `>=`) +- `"enforceForOrderingRelations": true` disallows negation of the left-hand side of ordering relational operators + +### enforceForOrderingRelations + +With this option set to `true` the rule is additionally enforced for: + +- `<` operator. +- `>` operator. +- `<=` operator. +- `>=` operator. + +The purpose is to avoid expressions such as `! a < b` (which is equivalent to `(a ? 0 : 1) < b`) when what is really intended is `!(a < b)`. + +Examples of additional **incorrect** code for this rule with the `{ "enforceForOrderingRelations": true }` option: + +```js +/*eslint no-unsafe-negation: ["error", { "enforceForOrderingRelations": true }]*/ + +if (! a < b) {} + +while (! a > b) {} + +foo = ! a <= b; + +foo = ! a >= b; +``` + +## When Not To Use It + +If you don't want to notify unsafe logical negations, then it's safe to disable this rule. + +## Version + +This rule was introduced in ESLint 3.3.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-unsafe-negation.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-unsafe-negation.md) diff --git a/docs/8.0.0/rules/no-unsafe-optional-chaining.md b/docs/8.0.0/rules/no-unsafe-optional-chaining.md new file mode 100644 index 0000000000..289a7d47b3 --- /dev/null +++ b/docs/8.0.0/rules/no-unsafe-optional-chaining.md @@ -0,0 +1,174 @@ +--- +title: no-unsafe-optional-chaining - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-unsafe-optional-chaining.md +rule_type: problem +--- + + +# disallow use of optional chaining in contexts where the `undefined` value is not allowed (no-unsafe-optional-chaining) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +The optional chaining (`?.`) expression can short-circuit with a return value of `undefined`. Therefore, treating an evaluated optional chaining expression as a function, object, number, etc., can cause TypeError or unexpected results. For example: + +```js +var obj = undefined; + +1 in obj?.foo; // TypeError +with (obj?.foo); // TypeError +for (bar of obj?.foo); // TypeError +bar instanceof obj?.foo; // TypeError +const { bar } = obj?.foo; // TypeError +``` + +Also, parentheses limit the scope of short-circuiting in chains. For example: + +```js +var obj = undefined; + +(obj?.foo)(); // TypeError +(obj?.foo).bar; // TypeError +``` + +## Rule Details + +This rule aims to detect some cases where the use of optional chaining doesn't prevent runtime errors. In particular, it flags optional chaining expressions in positions where short-circuiting to `undefined` causes throwing a TypeError afterward. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-unsafe-optional-chaining: "error"*/ + +(obj?.foo)(); + +(obj?.foo).bar; + +(foo?.()).bar; + +(foo?.()).bar(); + +(obj?.foo ?? obj?.bar)(); + +(foo || obj?.foo)(); + +(obj?.foo && foo)(); + +(foo ? obj?.foo : bar)(); + +(foo, obj?.bar).baz; + +(obj?.foo)`template`; + +new (obj?.foo)(); + +[...obj?.foo]; + +bar(...obj?.foo); + +1 in obj?.foo; + +bar instanceof obj?.foo; + +for (bar of obj?.foo); + +const { bar } = obj?.foo; + +[{ bar } = obj?.foo] = []; + +with (obj?.foo); + +class A extends obj?.foo {} + +var a = class A extends obj?.foo {}; + +async function foo () { + const { bar } = await obj?.foo; + (await obj?.foo)(); + (await obj?.foo).bar; +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-unsafe-optional-chaining: "error"*/ + +(obj?.foo)?.(); + +obj?.foo(); + +(obj?.foo ?? bar)(); + +obj?.foo.bar; + +obj.foo?.bar; + +foo?.()?.bar; + +(obj?.foo ?? bar)`template`; + +new (obj?.foo ?? bar)(); + +var baz = {...obj?.foo}; + +const { bar } = obj?.foo || baz; + +async function foo () { + const { bar } = await obj?.foo || baz; + (await obj?.foo)?.(); + (await obj?.foo)?.bar; +} +``` + +## Options + +This rule has an object option: + +- `disallowArithmeticOperators`: Disallow arithmetic operations on optional chaining expressions (Default `false`). If this is `true`, this rule warns arithmetic operations on optional chaining expressions, which possibly result in `NaN`. + +### disallowArithmeticOperators + +With this option set to `true` the rule is enforced for: + +- Unary operators: `-`, `+` +- Arithmetic operators: `+`, `-`, `/`, `*`, `%`, `**` +- Assignment operators: `+=`, `-=`, `/=`, `*=`, `%=`, `**=` + +Examples of additional **incorrect** code for this rule with the `{ "disallowArithmeticOperators": true }` option: + +```js +/*eslint no-unsafe-optional-chaining: ["error", { "disallowArithmeticOperators": true }]*/ + ++obj?.foo; +-obj?.foo; + +obj?.foo + bar; +obj?.foo - bar; +obj?.foo / bar; +obj?.foo * bar; +obj?.foo % bar; +obj?.foo ** bar; + +baz += obj?.foo; +baz -= obj?.foo; +baz /= obj?.foo; +baz *= obj?.foo; +baz %= obj?.foo; +baz **= obj?.foo; + +async function foo () { + +await obj?.foo; + await obj?.foo + bar; + baz += await obj?.foo; +} +``` + +## Version + +This rule was introduced in ESLint 7.15.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-unsafe-optional-chaining.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-unsafe-optional-chaining.md) diff --git a/docs/8.0.0/rules/no-unused-expressions.md b/docs/8.0.0/rules/no-unused-expressions.md new file mode 100644 index 0000000000..4baebe0f58 --- /dev/null +++ b/docs/8.0.0/rules/no-unused-expressions.md @@ -0,0 +1,205 @@ +--- +title: no-unused-expressions - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-unused-expressions.md +rule_type: suggestion +--- + + +# Disallow Unused Expressions (no-unused-expressions) + +An unused expression which has no effect on the state of the program indicates a logic error. + +For example, `n + 1;` is not a syntax error, but it might be a typing mistake where a programmer meant an assignment statement `n += 1;` instead. Sometimes, such unused expressions may be eliminated by some build tools in production environment, which possibly breaks application logic. + +## Rule Details + +This rule aims to eliminate unused expressions which have no effect on the state of the program. + +This rule does not apply to function calls or constructor calls with the `new` operator, because they could have *side effects* on the state of the program. + +```js +var i = 0; +function increment() { i += 1; } +increment(); // return value is unused, but i changed as a side effect + +var nThings = 0; +function Thing() { nThings += 1; } +new Thing(); // constructed object is unused, but nThings changed as a side effect +``` + +This rule does not apply to directives (which are in the form of literal string expressions such as `"use strict";` at the beginning of a script, module, or function). + +Sequence expressions (those using a comma, such as `a = 1, b = 2`) are always considered unused unless their return value is assigned or used in a condition evaluation, or a function call is made with the sequence expression value. + +## Options + +This rule, in its default state, does not require any arguments. If you would like to enable one or more of the following you may pass an object with the options set as follows: + +* `allowShortCircuit` set to `true` will allow you to use short circuit evaluations in your expressions (Default: `false`). +* `allowTernary` set to `true` will enable you to use ternary operators in your expressions similarly to short circuit evaluations (Default: `false`). +* `allowTaggedTemplates` set to `true` will enable you to use tagged template literals in your expressions (Default: `false`). +* `enforceForJSX` set to `true` will flag unused JSX element expressions (Default: `false`). + +These options allow unused expressions *only if all* of the code paths either directly change the state (for example, assignment statement) or could have *side effects* (for example, function call). + +Examples of **incorrect** code for the default `{ "allowShortCircuit": false, "allowTernary": false }` options: + +```js +/*eslint no-unused-expressions: "error"*/ + +0 + +if(0) 0 + +{0} + +f(0), {} + +a && b() + +a, b() + +c = a, b; + +a() && function namedFunctionInExpressionContext () {f();} + +(function anIncompleteIIFE () {}); + +injectGlobal`body{ color: red; }` + +``` + +Note that one or more string expression statements (with or without semi-colons) will only be considered as unused if they are not in the beginning of a script, module, or function (alone and uninterrupted by other statements). Otherwise, they will be treated as part of a "directive prologue", a section potentially usable by JavaScript engines. This includes "strict mode" directives. + +```js +"use strict"; +"use asm" +"use stricter"; +"use babel" +"any other strings like this in the prologue"; +``` + +Examples of **correct** code for the default `{ "allowShortCircuit": false, "allowTernary": false }` options: + +```js +/*eslint no-unused-expressions: "error"*/ + +{} // In this context, this is a block statement, not an object literal + +{myLabel: someVar} // In this context, this is a block statement with a label and expression, not an object literal + +function namedFunctionDeclaration () {} + +(function aGenuineIIFE () {}()); + +f() + +a = 0 + +new C + +delete a.b + +void a +``` + +### allowShortCircuit + +Examples of **incorrect** code for the `{ "allowShortCircuit": true }` option: + +```js +/*eslint no-unused-expressions: ["error", { "allowShortCircuit": true }]*/ + +a || b +``` + +Examples of **correct** code for the `{ "allowShortCircuit": true }` option: + +```js +/*eslint no-unused-expressions: ["error", { "allowShortCircuit": true }]*/ + +a && b() +a() || (b = c) +``` + +### allowTernary + +Examples of **incorrect** code for the `{ "allowTernary": true }` option: + +```js +/*eslint no-unused-expressions: ["error", { "allowTernary": true }]*/ + +a ? b : 0 +a ? b : c() +``` + +Examples of **correct** code for the `{ "allowTernary": true }` option: + +```js +/*eslint no-unused-expressions: ["error", { "allowTernary": true }]*/ + +a ? b() : c() +a ? (b = c) : d() +``` + +### allowShortCircuit and allowTernary + +Examples of **correct** code for the `{ "allowShortCircuit": true, "allowTernary": true }` options: + +```js +/*eslint no-unused-expressions: ["error", { "allowShortCircuit": true, "allowTernary": true }]*/ + +a ? b() || (c = d) : e() +``` + +### allowTaggedTemplates + +Examples of **incorrect** code for the `{ "allowTaggedTemplates": true }` option: + +```js +/*eslint no-unused-expressions: ["error", { "allowTaggedTemplates": true }]*/ + +`some untagged template string`; +``` + +Examples of **correct** code for the `{ "allowTaggedTemplates": true }` option: + +```js +/*eslint no-unused-expressions: ["error", { "allowTaggedTemplates": true }]*/ + +tag`some tagged template string`; +``` + +### enforceForJSX + +JSX is most-commonly used in the React ecosystem, where it is compiled to `React.createElement` expressions. Though free from side-effects, these calls are not automatically flagged by the `no-unused-expression` rule. If you're using React, or any other side-effect-free JSX pragma, this option can be enabled to flag these expressions. + +Examples of **incorrect** code for the `{ "enforceForJSX": true }` option: + +```jsx +/*eslint no-unused-expressions: ["error", { "enforceForJSX": true }]*/ + +; + +<>; +``` + +Examples of **correct** code for the `{ "enforceForJSX": true }` option: + +```jsx +/*eslint no-unused-expressions: ["error", { "enforceForJSX": true }]*/ + +var myComponentPartial = ; + +var myFragment = <>; +``` + +## Version + +This rule was introduced in ESLint 0.1.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-unused-expressions.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-unused-expressions.md) diff --git a/docs/8.0.0/rules/no-unused-labels.md b/docs/8.0.0/rules/no-unused-labels.md new file mode 100644 index 0000000000..2481cea8ee --- /dev/null +++ b/docs/8.0.0/rules/no-unused-labels.md @@ -0,0 +1,89 @@ +--- +title: no-unused-labels - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-unused-labels.md +rule_type: suggestion +--- + + +# Disallow Unused Labels (no-unused-labels) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +Labels that are declared and not used anywhere in the code are most likely an error due to incomplete refactoring. + +```js +OUTER_LOOP: +for (const student of students) { + if (checkScores(student.scores)) { + continue; + } + doSomething(student); +} +``` + +In this case, probably removing `OUTER_LOOP:` had been forgotten. +Such labels take up space in the code and can lead to confusion by readers. + +## Rule Details + +This rule is aimed at eliminating unused labels. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-unused-labels: "error"*/ + +A: var foo = 0; + +B: { + foo(); +} + +C: +for (let i = 0; i < 10; ++i) { + foo(); +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-unused-labels: "error"*/ + +A: { + if (foo()) { + break A; + } + bar(); +} + +B: +for (let i = 0; i < 10; ++i) { + if (foo()) { + break B; + } + bar(); +} +``` + +## When Not To Use It + +If you don't want to be notified about unused labels, then it's safe to disable this rule. + +## Related Rules + +* [no-extra-label](./no-extra-label) +* [no-labels](./no-labels) +* [no-label-var](./no-label-var) + +## Version + +This rule was introduced in ESLint 2.0.0-rc.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-unused-labels.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-unused-labels.md) diff --git a/docs/8.0.0/rules/no-unused-vars.md b/docs/8.0.0/rules/no-unused-vars.md new file mode 100644 index 0000000000..d37603b655 --- /dev/null +++ b/docs/8.0.0/rules/no-unused-vars.md @@ -0,0 +1,322 @@ +--- +title: no-unused-vars - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-unused-vars.md +rule_type: problem +--- + + +# Disallow Unused Variables (no-unused-vars) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +Variables that are declared and not used anywhere in the code are most likely an error due to incomplete refactoring. Such variables take up space in the code and can lead to confusion by readers. + +## Rule Details + +This rule is aimed at eliminating unused variables, functions, and function parameters. + +A variable `foo` is considered to be used if any of the following are true: + +* It is called (`foo()`) or constructed (`new foo()`) +* It is read (`var bar = foo`) +* It is passed into a function as an argument (`doSomething(foo)`) +* It is read inside of a function that is passed to another function (`doSomething(function() { foo(); })`) + +A variable is *not* considered to be used if it is only ever declared (`var foo = 5`) or assigned to (`foo = 7`). + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-unused-vars: "error"*/ +/*global some_unused_var*/ + +// It checks variables you have defined as global +some_unused_var = 42; + +var x; + +// Write-only variables are not considered as used. +var y = 10; +y = 5; + +// A read for a modification of itself is not considered as used. +var z = 0; +z = z + 1; + +// By default, unused arguments cause warnings. +(function(foo) { + return 5; +})(); + +// Unused recursive functions also cause warnings. +function fact(n) { + if (n < 2) return 1; + return n * fact(n - 1); +} + +// When a function definition destructures an array, unused entries from the array also cause warnings. +function getY([x, y]) { + return y; +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-unused-vars: "error"*/ + +var x = 10; +alert(x); + +// foo is considered used here +myFunc(function foo() { + // ... +}.bind(this)); + +(function(foo) { + return foo; +})(); + +var myFunc; +myFunc = setTimeout(function() { + // myFunc is considered used + myFunc(); +}, 50); + +// Only the second argument from the destructured array is used. +function getY([, y]) { + return y; +} +``` + +### exported + +In environments outside of CommonJS or ECMAScript modules, you may use `var` to create a global variable that may be used by other scripts. You can use the comment `/* exported variableName */` or `// exported variableName` to indicate that this variable is being exported and therefore should not be considered unused. + +Note that the comment has no effect for any of the following: + +* when the environment is `node` or `commonjs` +* when `parserOptions.sourceType` is `module` +* when `ecmaFeatures.globalReturn` is `true` + +Examples of **correct** code for `exported` operation: + +```js +/* exported global_var */ + +var global_var = 42; +``` + +```js +// exported global_var + +var global_var = 42; +``` + +## Options + +This rule takes one argument which can be a string or an object. The string settings are the same as those of the `vars` property (explained below). + +By default this rule is enabled with `all` option for variables and `after-used` for arguments. + +```json +{ + "rules": { + "no-unused-vars": ["error", { "vars": "all", "args": "after-used", "ignoreRestSiblings": false }] + } +} +``` + +### vars + +The `vars` option has two settings: + +* `all` checks all variables for usage, including those in the global scope. This is the default setting. +* `local` checks only that locally-declared variables are used but will allow global variables to be unused. + +#### vars: local + +Examples of **correct** code for the `{ "vars": "local" }` option: + +```js +/*eslint no-unused-vars: ["error", { "vars": "local" }]*/ +/*global some_unused_var */ + +some_unused_var = 42; +``` + +### varsIgnorePattern + +The `varsIgnorePattern` option specifies exceptions not to check for usage: variables whose names match a regexp pattern. For example, variables whose names contain `ignored` or `Ignored`. + +Examples of **correct** code for the `{ "varsIgnorePattern": "[iI]gnored" }` option: + +```js +/*eslint no-unused-vars: ["error", { "varsIgnorePattern": "[iI]gnored" }]*/ + +var firstVarIgnored = 1; +var secondVar = 2; +console.log(secondVar); +``` + +### args + +The `args` option has three settings: + +* `after-used` - unused positional arguments that occur before the last used argument will not be checked, but all named arguments and all positional arguments after the last used argument will be checked. +* `all` - all named arguments must be used. +* `none` - do not check arguments. + +#### args: after-used + +Examples of **incorrect** code for the default `{ "args": "after-used" }` option: + +```js +/*eslint no-unused-vars: ["error", { "args": "after-used" }]*/ + +// 2 errors, for the parameters after the last used parameter (bar) +// "baz" is defined but never used +// "qux" is defined but never used +(function(foo, bar, baz, qux) { + return bar; +})(); +``` + +Examples of **correct** code for the default `{ "args": "after-used" }` option: + +```js +/*eslint no-unused-vars: ["error", {"args": "after-used"}]*/ + +(function(foo, bar, baz, qux) { + return qux; +})(); +``` + +#### args: all + +Examples of **incorrect** code for the `{ "args": "all" }` option: + +```js +/*eslint no-unused-vars: ["error", { "args": "all" }]*/ + +// 2 errors +// "foo" is defined but never used +// "baz" is defined but never used +(function(foo, bar, baz) { + return bar; +})(); +``` + +#### args: none + +Examples of **correct** code for the `{ "args": "none" }` option: + +```js +/*eslint no-unused-vars: ["error", { "args": "none" }]*/ + +(function(foo, bar, baz) { + return bar; +})(); +``` + +### ignoreRestSiblings + +The `ignoreRestSiblings` option is a boolean (default: `false`). Using a [Rest Property](https://github.com/tc39/proposal-object-rest-spread) it is possible to "omit" properties from an object, but by default the sibling properties are marked as "unused". With this option enabled the rest property's siblings are ignored. + +Examples of **correct** code for the `{ "ignoreRestSiblings": true }` option: + +```js +/*eslint no-unused-vars: ["error", { "ignoreRestSiblings": true }]*/ +// 'foo' and 'bar' were ignored because they have a rest property sibling. +var { foo, ...coords } = data; + +var bar; +({ bar, ...coords } = data); +``` + +### argsIgnorePattern + +The `argsIgnorePattern` option specifies exceptions not to check for usage: arguments whose names match a regexp pattern. For example, variables whose names begin with an underscore. + +Examples of **correct** code for the `{ "argsIgnorePattern": "^_" }` option: + +```js +/*eslint no-unused-vars: ["error", { "argsIgnorePattern": "^_" }]*/ + +function foo(x, _y) { + return x + 1; +} +foo(); +``` + +### caughtErrors + +The `caughtErrors` option is used for `catch` block arguments validation. + +It has two settings: + +* `none` - do not check error objects. This is the default setting. +* `all` - all named arguments must be used. + +#### caughtErrors: none + +Not specifying this rule is equivalent of assigning it to `none`. + +Examples of **correct** code for the `{ "caughtErrors": "none" }` option: + +```js +/*eslint no-unused-vars: ["error", { "caughtErrors": "none" }]*/ + +try { + //... +} catch (err) { + console.error("errors"); +} +``` + +#### caughtErrors: all + +Examples of **incorrect** code for the `{ "caughtErrors": "all" }` option: + +```js +/*eslint no-unused-vars: ["error", { "caughtErrors": "all" }]*/ + +// 1 error +// "err" is defined but never used +try { + //... +} catch (err) { + console.error("errors"); +} +``` + +### caughtErrorsIgnorePattern + +The `caughtErrorsIgnorePattern` option specifies exceptions not to check for usage: catch arguments whose names match a regexp pattern. For example, variables whose names begin with a string 'ignore'. + +Examples of **correct** code for the `{ "caughtErrorsIgnorePattern": "^ignore" }` option: + +```js +/*eslint no-unused-vars: ["error", { "caughtErrorsIgnorePattern": "^ignore" }]*/ + +try { + //... +} catch (ignoreErr) { + console.error("errors"); +} +``` + + +## When Not To Use It + +If you don't want to be notified about unused variables or function arguments, you can safely turn this rule off. + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-unused-vars.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-unused-vars.md) diff --git a/docs/8.0.0/rules/no-use-before-define.md b/docs/8.0.0/rules/no-use-before-define.md new file mode 100644 index 0000000000..3c40ddd08f --- /dev/null +++ b/docs/8.0.0/rules/no-use-before-define.md @@ -0,0 +1,178 @@ +--- +title: no-use-before-define - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-use-before-define.md +rule_type: problem +--- + + +# Disallow Early Use (no-use-before-define) + +In JavaScript, prior to ES6, variable and function declarations are hoisted to the top of a scope, so it's possible to use identifiers before their formal declarations in code. This can be confusing and some believe it is best to always declare variables and functions before using them. + +In ES6, block-level bindings (`let` and `const`) introduce a "temporal dead zone" where a `ReferenceError` will be thrown with any attempt to access the variable before its declaration. + +## Rule Details + +This rule will warn when it encounters a reference to an identifier that has not yet been declared. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-use-before-define: "error"*/ +/*eslint-env es6*/ + +alert(a); +var a = 10; + +f(); +function f() {} + +function g() { + return b; +} +var b = 1; + +{ + alert(c); + let c = 1; +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-use-before-define: "error"*/ +/*eslint-env es6*/ + +var a; +a = 10; +alert(a); + +function f() {} +f(1); + +var b = 1; +function g() { + return b; +} + +{ + let c; + c++; +} +``` + +## Options + +```json +{ + "no-use-before-define": ["error", { "functions": true, "classes": true }] +} +``` + +* `functions` (`boolean`) - + The flag which shows whether or not this rule checks function declarations. + If this is `true`, this rule warns every reference to a function before the function declaration. + Otherwise, ignores those references. + Function declarations are hoisted, so it's safe. + Default is `true`. +* `classes` (`boolean`) - + The flag which shows whether or not this rule checks class declarations of upper scopes. + If this is `true`, this rule warns every reference to a class before the class declaration. + Otherwise, ignores those references if the declaration is in upper function scopes. + Class declarations are not hoisted, so it might be danger. + Default is `true`. +* `variables` (`boolean`) - + This flag determines whether or not the rule checks variable declarations in upper scopes. + If this is `true`, the rule warns every reference to a variable before the variable declaration. + Otherwise, the rule ignores a reference if the declaration is in an upper scope, while still reporting the reference if it's in the same scope as the declaration. + Default is `true`. + +This rule accepts `"nofunc"` string as an option. +`"nofunc"` is the same as `{ "functions": false, "classes": true, "variables": true }`. + +### functions + +Examples of **correct** code for the `{ "functions": false }` option: + +```js +/*eslint no-use-before-define: ["error", { "functions": false }]*/ + +f(); +function f() {} +``` + +This option allows references to function declarations. For function expressions and arrow functions, please see the [`variables`](#variables) option. + +### classes + +Examples of **incorrect** code for the `{ "classes": false }` option: + +```js +/*eslint no-use-before-define: ["error", { "classes": false }]*/ +/*eslint-env es6*/ + +new A(); +class A { +} +``` + +Examples of **correct** code for the `{ "classes": false }` option: + +```js +/*eslint no-use-before-define: ["error", { "classes": false }]*/ +/*eslint-env es6*/ + +function foo() { + return new A(); +} + +class A { +} +``` + +### variables + +Examples of **incorrect** code for the `{ "variables": false }` option: + +```js +/*eslint no-use-before-define: ["error", { "variables": false }]*/ + +console.log(foo); +var foo = 1; + +f(); +const f = () => {}; + +g(); +const g = function() {}; +``` + +Examples of **correct** code for the `{ "variables": false }` option: + +```js +/*eslint no-use-before-define: ["error", { "variables": false }]*/ + +function baz() { + console.log(foo); +} +var foo = 1; + +const a = () => f(); +function b() { return f(); } +const c = function() { return f(); } +const f = () => {}; + +const e = function() { return g(); } +const g = function() {} +``` + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-use-before-define.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-use-before-define.md) diff --git a/docs/8.0.0/rules/no-useless-backreference.md b/docs/8.0.0/rules/no-useless-backreference.md new file mode 100644 index 0000000000..66fb0e82c9 --- /dev/null +++ b/docs/8.0.0/rules/no-useless-backreference.md @@ -0,0 +1,149 @@ +--- +title: no-useless-backreference - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-useless-backreference.md +rule_type: problem +--- + + +# Disallow useless backreferences in regular expressions (no-useless-backreference) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +In JavaScript regular expressions, it's syntactically valid to define a backreference to a group that belongs to another alternative part of the pattern, a backreference to a group that appears after the backreference, a backreference to a group that contains that backreference, or a backreference to a group that is inside a negative lookaround. However, by the specification, in any of these cases the backreference always ends up matching only zero-length (the empty string), regardless of the context in which the backreference and the group appear. + +Backreferences that always successfully match zero-length and cannot match anything else are useless. They are basically ignored and can be removed without changing the behavior of the regular expression. + +```js +var regex = /^(?:(a)|\1b)$/; + +regex.test("a"); // true +regex.test("b"); // true! +regex.test("ab"); // false + +var equivalentRegex = /^(?:(a)|b)$/; + +equivalentRegex.test("a"); // true +equivalentRegex.test("b"); // true +equivalentRegex.test("ab"); // false +``` + +Useless backreference is a possible error in the code. It usually indicates that the regular expression does not work as intended. + +## Rule Details + +This rule aims to detect and disallow the following backreferences in regular expression: + +* Backreference to a group that is in another alternative, e.g., `/(a)|\1b/`. In such constructed regular expression, the backreference is expected to match what's been captured in, at that point, a non-participating group. +* Backreference to a group that appears later in the pattern, e.g., `/\1(a)/`. The group hasn't captured anything yet, and ECMAScript doesn't support forward references. Inside lookbehinds, which match backward, the opposite applies and this rule disallows backreference to a group that appears before in the same lookbehind, e.g., `/(?<=(a)\1)b/`. +* Backreference to a group from within the same group, e.g., `/(\1)/`. Similar to the previous, the group hasn't captured anything yet, and ECMAScript doesn't support nested references. +* Backreference to a group that is in a negative lookaround, if the backreference isn't in the same negative lookaround, e.g., `/a(?!(b)).\1/`. A negative lookaround (lookahead or lookbehind) succeeds only if its pattern cannot match, meaning that the group has failed. + +By the ECMAScript specification, all backreferences listed above are valid, always succeed to match zero-length, and cannot match anything else. Consequently, they don't produce parsing or runtime errors, but also don't affect the behavior of their regular expressions. They are syntactically valid but useless. + +This might be surprising to developers coming from other languages where some of these backreferences can be used in a meaningful way. + +```js +// in some other languages, this pattern would successfully match "aab" + +/^(?:(a)(?=a)|\1b)+$/.test("aab"); // false +``` + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-useless-backreference: "error"*/ + +/^(?:(a)|\1b)$/; // reference to (a) into another alternative + +/^(?:(a)|b(?:c|\1))$/; // reference to (a) into another alternative + +/^(?:a|b(?:(c)|\1))$/; // reference to (c) into another alternative + +/\1(a)/; // forward reference to (a) + +RegExp('(a)\\2(b)'); // forward reference to (b) + +/(?:a)(b)\2(c)/; // forward reference to (c) + +/\k(?a)/; // forward reference to (?a) + +/(?<=(a)\1)b/; // backward reference to (a) from within the same lookbehind + +/(?(.)b\1)/; // nested reference to (?(.)b\1) + +/a(?!(b)).\1/; // reference to (b) into a negative lookahead + +/(?a)\k/; // reference to (?a) + +/(?<=\1(a))b/; // reference to (a), correctly before the group as they're in the same lookbehind + +/(?<=(a))b\1/; // reference to (a), correctly after the group as the backreference isn't in the lookbehind + +new RegExp('(.)\\1'); // reference to (.) + +/^(?:(a)\1)$/; // reference to (a) + +/^((a)\2)$/; // reference to (a) + +/a(?(.)b\2)/; // reference to (.) + +/a(?!(b|c)\1)./; // reference to (b|c), correct as it's from within the same negative lookahead + +/(? + +# Disallow unnecessary `.call()` and `.apply()`. (no-useless-call) + +The function invocation can be written by `Function.prototype.call()` and `Function.prototype.apply()`. +But `Function.prototype.call()` and `Function.prototype.apply()` are slower than the normal function invocation. + +## Rule Details + +This rule is aimed to flag usage of `Function.prototype.call()` and `Function.prototype.apply()` that can be replaced with the normal function invocation. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-useless-call: "error"*/ + +// These are same as `foo(1, 2, 3);` +foo.call(undefined, 1, 2, 3); +foo.apply(undefined, [1, 2, 3]); +foo.call(null, 1, 2, 3); +foo.apply(null, [1, 2, 3]); + +// These are same as `obj.foo(1, 2, 3);` +obj.foo.call(obj, 1, 2, 3); +obj.foo.apply(obj, [1, 2, 3]); +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-useless-call: "error"*/ + +// The `this` binding is different. +foo.call(obj, 1, 2, 3); +foo.apply(obj, [1, 2, 3]); +obj.foo.call(null, 1, 2, 3); +obj.foo.apply(null, [1, 2, 3]); +obj.foo.call(otherObj, 1, 2, 3); +obj.foo.apply(otherObj, [1, 2, 3]); + +// The argument list is variadic. +// Those are warned by the `prefer-spread` rule. +foo.apply(undefined, args); +foo.apply(null, args); +obj.foo.apply(obj, args); +``` + +## Known Limitations + +This rule compares code statically to check whether or not `thisArg` is changed. +So if the code about `thisArg` is a dynamic expression, this rule cannot judge correctly. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-useless-call: "error"*/ + +a[i++].foo.call(a[i++], 1, 2, 3); +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-useless-call: "error"*/ + +a[++i].foo.call(a[i], 1, 2, 3); +``` + +## When Not To Use It + +If you don't want to be notified about unnecessary `.call()` and `.apply()`, you can safely disable this rule. + +## Related Rules + +* [prefer-spread](prefer-spread) + +## Version + +This rule was introduced in ESLint 1.0.0-rc-1. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-useless-call.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-useless-call.md) diff --git a/docs/8.0.0/rules/no-useless-catch.md b/docs/8.0.0/rules/no-useless-catch.md new file mode 100644 index 0000000000..c2e987ed8b --- /dev/null +++ b/docs/8.0.0/rules/no-useless-catch.md @@ -0,0 +1,75 @@ +--- +title: no-useless-catch - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-useless-catch.md +rule_type: suggestion +--- + + +# Disallow unnecessary catch clauses (no-useless-catch) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +A `catch` clause that only rethrows the original error is redundant, and has no effect on the runtime behavior of the program. These redundant clauses can be a source of confusion and code bloat, so it's better to disallow these unnecessary `catch` clauses. + +## Rule Details + +This rule reports `catch` clauses that only `throw` the caught error. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-useless-catch: "error"*/ + +try { + doSomethingThatMightThrow(); +} catch (e) { + throw e; +} + +try { + doSomethingThatMightThrow(); +} catch (e) { + throw e; +} finally { + cleanUp(); +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-useless-catch: "error"*/ + +try { + doSomethingThatMightThrow(); +} catch (e) { + doSomethingBeforeRethrow(); + throw e; +} + +try { + doSomethingThatMightThrow(); +} catch (e) { + handleError(e); +} + +try { + doSomethingThatMightThrow(); +} finally { + cleanUp(); +} +``` + +## When Not To Use It + +If you don't want to be notified about unnecessary catch clauses, you can safely disable this rule. + +## Version + +This rule was introduced in ESLint 5.11.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-useless-catch.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-useless-catch.md) diff --git a/docs/8.0.0/rules/no-useless-computed-key.md b/docs/8.0.0/rules/no-useless-computed-key.md new file mode 100644 index 0000000000..5c23fe378a --- /dev/null +++ b/docs/8.0.0/rules/no-useless-computed-key.md @@ -0,0 +1,145 @@ +--- +title: no-useless-computed-key - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-useless-computed-key.md +rule_type: suggestion +--- + + +# Disallow unnecessary computed property keys in objects and classes (no-useless-computed-key) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +It's unnecessary to use computed properties with literals such as: + +```js +var foo = {["a"]: "b"}; +``` + +The code can be rewritten as: + +```js +var foo = {"a": "b"}; +``` + +## Rule Details + +This rule disallows unnecessary usage of computed property keys. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-useless-computed-key: "error"*/ + +var a = { ['0']: 0 }; +var a = { ['0+1,234']: 0 }; +var a = { [0]: 0 }; +var a = { ['x']: 0 }; +var a = { ['x']() {} }; +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-useless-computed-key: "error"*/ + +var c = { 'a': 0 }; +var c = { 0: 0 }; +var a = { x() {} }; +var c = { a: 0 }; +var c = { '0+1,234': 0 }; +``` + +Examples of additional **correct** code for this rule: + +```js +/*eslint no-useless-computed-key: "error"*/ + +var c = { + "__proto__": foo, // defines object's prototype + + ["__proto__"]: bar // defines a property named "__proto__" +}; +``` + +## Options + +This rule has an object option: + +* `enforceForClassMembers` set to `true` additionally applies this rule to class members (Default `false`). + +### enforceForClassMembers + +By default, this rule does not check class declarations and class expressions, +as the default value for `enforceForClassMembers` is `false`. + +When `enforceForClassMembers` is set to `true`, the rule will also disallow unnecessary computed keys inside of class fields, class methods, class getters, and class setters. + +Examples of **incorrect** code for this rule with the `{ "enforceForClassMembers": true }` option: + +```js +/*eslint no-useless-computed-key: ["error", { "enforceForClassMembers": true }]*/ + +class Foo { + ["foo"] = "bar"; + + [0]() {} + ['a']() {} + get ['b']() {} + set ['c'](value) {} + + static ["foo"] = "bar"; + + static ['a']() {} +} +``` + +Examples of **correct** code for this rule with the `{ "enforceForClassMembers": true }` option: + +```js +/*eslint no-useless-computed-key: ["error", { "enforceForClassMembers": true }]*/ + +class Foo { + "foo" = "bar"; + + 0() {} + 'a'() {} + get 'b'() {} + set 'c'(value) {} + + static "foo" = "bar"; + + static 'a'() {} +} +``` + +Examples of additional **correct** code for this rule with the `{ "enforceForClassMembers": true }` option: + +```js +/*eslint no-useless-computed-key: ["error", { "enforceForClassMembers": true }]*/ + +class Foo { + ["constructor"]; // instance field named "constructor" + + "constructor"() {} // the constructor of this class + + ["constructor"]() {} // method named "constructor" + + static ["constructor"]; // static field named "constructor" + + static ["prototype"]; // runtime error, it would be a parsing error without `[]` +} +``` + +## When Not To Use It + +If you don't want to be notified about unnecessary computed property keys, you can safely disable this rule. + +## Version + +This rule was introduced in ESLint 2.9.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-useless-computed-key.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-useless-computed-key.md) diff --git a/docs/8.0.0/rules/no-useless-concat.md b/docs/8.0.0/rules/no-useless-concat.md new file mode 100644 index 0000000000..0ae5d19460 --- /dev/null +++ b/docs/8.0.0/rules/no-useless-concat.md @@ -0,0 +1,68 @@ +--- +title: no-useless-concat - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-useless-concat.md +rule_type: suggestion +--- + + +# Disallow unnecessary concatenation of strings (no-useless-concat) + +It's unnecessary to concatenate two strings together, such as: + +```js +var foo = "a" + "b"; +``` + +This code is likely the result of refactoring where a variable was removed from the concatenation (such as `"a" + b + "b"`). In such a case, the concatenation isn't important and the code can be rewritten as: + +```js +var foo = "ab"; +``` + +## Rule Details + +This rule aims to flag the concatenation of 2 literals when they could be combined into a single literal. Literals can be strings or template literals. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-useless-concat: "error"*/ +/*eslint-env es6*/ + +var a = `some` + `string`; + +// these are the same as "10" +var a = '1' + '0'; +var a = '1' + `0`; +var a = `1` + '0'; +var a = `1` + `0`; +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-useless-concat: "error"*/ + +// when a non string is included +var c = a + b; +var c = '1' + a; +var a = 1 + '1'; +var c = 1 - 2; +// when the string concatenation is multiline +var c = "foo" + + "bar"; +``` + +## When Not To Use It + +If you don't want to be notified about unnecessary string concatenation, you can safely disable this rule. + +## Version + +This rule was introduced in ESLint 1.3.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-useless-concat.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-useless-concat.md) diff --git a/docs/8.0.0/rules/no-useless-constructor.md b/docs/8.0.0/rules/no-useless-constructor.md new file mode 100644 index 0000000000..cd13d16046 --- /dev/null +++ b/docs/8.0.0/rules/no-useless-constructor.md @@ -0,0 +1,88 @@ +--- +title: no-useless-constructor - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-useless-constructor.md +rule_type: suggestion +--- + + +# Disallow unnecessary constructor (no-useless-constructor) + +ES2015 provides a default class constructor if one is not specified. As such, it is unnecessary to provide an empty constructor or one that simply delegates into its parent class, as in the following examples: + +```js +class A { + constructor () { + } +} + +class B extends A { + constructor (value) { + super(value); + } +} +``` + +## Rule Details + +This rule flags class constructors that can be safely removed without changing how the class works. + +## Examples + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-useless-constructor: "error"*/ +/*eslint-env es6*/ + +class A { + constructor () { + } +} + +class B extends A { + constructor (...args) { + super(...args); + } +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-useless-constructor: "error"*/ + +class A { } + +class A { + constructor () { + doSomething(); + } +} + +class B extends A { + constructor() { + super('foo'); + } +} + +class B extends A { + constructor() { + super(); + doSomething(); + } +} +``` + +## When Not To Use It + +If you don't want to be notified about unnecessary constructors, you can safely disable this rule. + +## Version + +This rule was introduced in ESLint 2.0.0-beta.1. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-useless-constructor.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-useless-constructor.md) diff --git a/docs/8.0.0/rules/no-useless-escape.md b/docs/8.0.0/rules/no-useless-escape.md new file mode 100644 index 0000000000..1bbe0e4655 --- /dev/null +++ b/docs/8.0.0/rules/no-useless-escape.md @@ -0,0 +1,75 @@ +--- +title: no-useless-escape - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-useless-escape.md +rule_type: suggestion +--- + + +# Disallow unnecessary escape usage (no-useless-escape) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +(hasSuggestions) Some problems reported by this rule are manually fixable by editor [suggestions](../developer-guide/working-with-rules#providing-suggestions). + +Escaping non-special characters in strings, template literals, and regular expressions doesn't have any effect, as demonstrated in the following example: + +```js +let foo = "hol\a"; // > foo = "hola" +let bar = `${foo}\!`; // > bar = "hola!" +let baz = /\:/ // same functionality with /:/ +``` + +## Rule Details + +This rule flags escapes that can be safely removed without changing behavior. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-useless-escape: "error"*/ + +"\'"; +'\"'; +"\#"; +"\e"; +`\"`; +`\"${foo}\"`; +`\#{foo}`; +/\!/; +/\@/; + +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-useless-escape: "error"*/ + +"\""; +'\''; +"\x12"; +"\u00a9"; +"\371"; +"xs\u2111"; +`\``; +`\${${foo}}`; +`$\{${foo}}`; +/\\/g; +/\t/g; +/\w\$\*\^\./; + +``` + +## When Not To Use It + +If you don't want to be notified about unnecessary escapes, you can safely disable this rule. + +## Version + +This rule was introduced in ESLint 2.5.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-useless-escape.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-useless-escape.md) diff --git a/docs/8.0.0/rules/no-useless-rename.md b/docs/8.0.0/rules/no-useless-rename.md new file mode 100644 index 0000000000..6e596f53b4 --- /dev/null +++ b/docs/8.0.0/rules/no-useless-rename.md @@ -0,0 +1,143 @@ +--- +title: no-useless-rename - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-useless-rename.md +rule_type: suggestion +--- + + +# Disallow renaming import, export, and destructured assignments to the same name (no-useless-rename) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +ES2015 allows for the renaming of references in import and export statements as well as destructuring assignments. This gives programmers a concise syntax for performing these operations while renaming these references: + +```js +import { foo as bar } from "baz"; +export { foo as bar }; +let { foo: bar } = baz; +``` + +With this syntax, it is possible to rename a reference to the same name. This is a completely redundant operation, as this is the same as not renaming at all. For example, this: + +```js +import { foo as foo } from "bar"; +export { foo as foo }; +let { foo: foo } = bar; +``` + +is the same as: + +```js +import { foo } from "bar"; +export { foo }; +let { foo } = bar; +``` + +## Rule Details + +This rule disallows the renaming of import, export, and destructured assignments to the same name. + +See Also: + +- [`object-shorthand`](https://eslint.org/docs/rules/object-shorthand) which can enforce this behavior for properties in object literals. + +## Options + +This rule allows for more fine-grained control with the following options: + +- `ignoreImport`: When set to `true`, this rule does not check imports +- `ignoreExport`: When set to `true`, this rule does not check exports +- `ignoreDestructuring`: When set to `true`, this rule does not check destructuring assignments + +By default, all options are set to `false`: + +```json +"no-useless-rename": ["error", { + "ignoreDestructuring": false, + "ignoreImport": false, + "ignoreExport": false +}] +``` + +Examples of **incorrect** code for this rule by default: + +```js +/*eslint no-useless-rename: "error"*/ + +import { foo as foo } from "bar"; +export { foo as foo }; +export { foo as foo } from "bar"; +let { foo: foo } = bar; +let { 'foo': foo } = bar; +function foo({ bar: bar }) {} +({ foo: foo }) => {} +``` + +Examples of **correct** code for this rule by default: + +```js +/*eslint no-useless-rename: "error"*/ + +import * as foo from "foo"; +import { foo } from "bar"; +import { foo as bar } from "baz"; + +export { foo }; +export { foo as bar }; +export { foo as bar } from "foo"; + +let { foo } = bar; +let { foo: bar } = baz; +let { [foo]: foo } = bar; + +function foo({ bar }) {} +function foo({ bar: baz }) {} + +({ foo }) => {} +({ foo: bar }) => {} +``` + +Examples of **correct** code for this rule with `{ ignoreImport: true }`: + +```js +/*eslint no-useless-rename: ["error", { ignoreImport: true }]*/ + +import { foo as foo } from "bar"; +``` + +Examples of **correct** code for this rule with `{ ignoreExport: true }`: + +```js +/*eslint no-useless-rename: ["error", { ignoreExport: true }]*/ + +export { foo as foo }; +export { foo as foo } from "bar"; +``` + +Examples of **correct** code for this rule with `{ ignoreDestructuring: true }`: + +```js +/*eslint no-useless-rename: ["error", { ignoreDestructuring: true }]*/ + +let { foo: foo } = bar; +function foo({ bar: bar }) {} +({ foo: foo }) => {} +``` + +## When Not To Use It + +You can safely disable this rule if you do not care about redundantly renaming import, export, and destructuring assignments. + +## Compatibility + +- **JSCS**: [disallowIdenticalDestructuringNames](https://jscs-dev.github.io/rule/disallowIdenticalDestructuringNames) + +## Version + +This rule was introduced in ESLint 2.11.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-useless-rename.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-useless-rename.md) diff --git a/docs/8.0.0/rules/no-useless-return.md b/docs/8.0.0/rules/no-useless-return.md new file mode 100644 index 0000000000..60504d70c5 --- /dev/null +++ b/docs/8.0.0/rules/no-useless-return.md @@ -0,0 +1,102 @@ +--- +title: no-useless-return - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-useless-return.md +rule_type: suggestion +--- + + +# Disallow redundant return statements (no-useless-return) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +A `return;` statement with nothing after it is redundant, and has no effect on the runtime behavior of a function. This can be confusing, so it's better to disallow these redundant statements. + +## Rule Details + +This rule aims to report redundant `return` statements. + +Examples of **incorrect** code for this rule: + +```js +/* eslint no-useless-return: "error" */ + +function foo() { return; } + +function foo() { + doSomething(); + return; +} + +function foo() { + if (condition) { + bar(); + return; + } else { + baz(); + } +} + +function foo() { + switch (bar) { + case 1: + doSomething(); + default: + doSomethingElse(); + return; + } +} + +``` + +Examples of **correct** code for this rule: + +```js +/* eslint no-useless-return: "error" */ + +function foo() { return 5; } + +function foo() { + return doSomething(); +} + +function foo() { + if (condition) { + bar(); + return; + } else { + baz(); + } + qux(); +} + +function foo() { + switch (bar) { + case 1: + doSomething(); + return; + default: + doSomethingElse(); + } +} + +function foo() { + for (const foo of bar) { + return; + } +} + +``` + +## When Not To Use It + +If you don't care about disallowing redundant return statements, you can turn off this rule. + +## Version + +This rule was introduced in ESLint 3.9.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-useless-return.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-useless-return.md) diff --git a/docs/8.0.0/rules/no-var.md b/docs/8.0.0/rules/no-var.md new file mode 100644 index 0000000000..97d5aae990 --- /dev/null +++ b/docs/8.0.0/rules/no-var.md @@ -0,0 +1,67 @@ +--- +title: no-var - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-var.md +rule_type: suggestion +--- + + +# require `let` or `const` instead of `var` (no-var) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +ECMAScript 6 allows programmers to create variables with block scope instead of function scope using the `let` +and `const` keywords. Block scope is common in many other programming languages and helps programmers avoid mistakes +such as: + +```js +var count = people.length; +var enoughFood = count > sandwiches.length; + +if (enoughFood) { + var count = sandwiches.length; // accidentally overriding the count variable + console.log("We have " + count + " sandwiches for everyone. Plenty for all!"); +} + +// our count variable is no longer accurate +console.log("We have " + count + " people and " + sandwiches.length + " sandwiches!"); +``` + +## Rule Details + +This rule is aimed at discouraging the use of `var` and encouraging the use of `const` or `let` instead. + +## Examples + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-var: "error"*/ + +var x = "y"; +var CONFIG = {}; +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-var: "error"*/ +/*eslint-env es6*/ + +let x = "y"; +const CONFIG = {}; +``` + +## When Not To Use It + +In addition to non-ES6 environments, existing JavaScript projects that are beginning to introduce ES6 into their +codebase may not want to apply this rule if the cost of migrating from `var` to `let` is too costly. + +## Version + +This rule was introduced in ESLint 0.12.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-var.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-var.md) diff --git a/docs/8.0.0/rules/no-void.md b/docs/8.0.0/rules/no-void.md new file mode 100644 index 0000000000..cd2668a0f5 --- /dev/null +++ b/docs/8.0.0/rules/no-void.md @@ -0,0 +1,124 @@ +--- +title: no-void - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-void.md +rule_type: suggestion +--- + + +# Disallow use of the void operator. (no-void) + +The `void` operator takes an operand and returns `undefined`: `void expression` will evaluate `expression` and return `undefined`. It can be used to ignore any side effects `expression` may produce: + +The common case of using `void` operator is to get a "pure" `undefined` value as prior to ES5 the `undefined` variable was mutable: + +```js +// will always return undefined +(function(){ + return void 0; +})(); + +// will return 1 in ES3 and undefined in ES5+ +(function(){ + undefined = 1; + return undefined; +})(); + +// will throw TypeError in ES5+ +(function(){ + 'use strict'; + undefined = 1; +})(); +``` + +Another common case is to minify code as `void 0` is shorter than `undefined`: + +```js +foo = void 0; +foo = undefined; +``` + +When used with IIFE (immediately-invoked function expression), `void` can be used to force the function keyword to be treated as an expression instead of a declaration: + +```js +var foo = 1; +void function(){ foo = 1; }() // will assign foo a value of 1 ++function(){ foo = 1; }() // same as above +``` + +``` +function(){ foo = 1; }() // will throw SyntaxError +``` + +Some code styles prohibit `void` operator, marking it as non-obvious and hard to read. + +## Rule Details + +This rule aims to eliminate use of void operator. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-void: "error"*/ + +void foo +void someFunction(); + +var foo = void bar(); +function baz() { + return void 0; +} +``` + +## Options + +This rule has an object option: + +* `allowAsStatement` set to `true` allows the void operator to be used as a statement (Default `false`). + +### allowAsStatement + +When `allowAsStatement` is set to true, the rule will not error on cases that the void operator is used as a statement, i.e. when it's not used in an expression position, like in a variable assignment or a function return. + +Examples of **incorrect** code for `{ "allowAsStatement": true }`: + +```js +/*eslint no-void: ["error", { "allowAsStatement": true }]*/ + +var foo = void bar(); +function baz() { + return void 0; +} +``` + +Examples of **correct** code for `{ "allowAsStatement": true }`: + +```js +/*eslint no-void: ["error", { "allowAsStatement": true }]*/ + +void foo; +void someFunction(); +``` + +## When Not To Use It + +If you intentionally use the `void` operator then you can disable this rule. + +## Further Reading + +* [Mozilla Developer Network](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/void) +* [Bad Parts: Appendix B - JavaScript: The Good Parts by Douglas Crockford](https://oreilly.com/javascript/excerpts/javascript-good-parts/bad-parts.html) + +## Related Rules + +* [no-undef-init](no-undef-init) +* [no-undefined](no-undefined) + +## Version + +This rule was introduced in ESLint 0.8.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-void.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-void.md) diff --git a/docs/8.0.0/rules/no-warning-comments.md b/docs/8.0.0/rules/no-warning-comments.md new file mode 100644 index 0000000000..66e9a6bdc0 --- /dev/null +++ b/docs/8.0.0/rules/no-warning-comments.md @@ -0,0 +1,102 @@ +--- +title: no-warning-comments - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-warning-comments.md +rule_type: suggestion +--- + + +# Disallow Warning Comments (no-warning-comments) + +Developers often add comments to code which is not complete or needs review. Most likely you want to fix or review the code, and then remove the comment, before you consider the code to be production ready. + +```js +// TODO: do something +// FIXME: this is not a good idea +``` + +## Rule Details + +This rule reports comments that include any of the predefined terms specified in its configuration. + +## Options + +This rule has an options object literal: + +* `"terms"`: optional array of terms to match. Defaults to `["todo", "fixme", "xxx"]`. Terms are matched case-insensitive and as whole words: `fix` would match `FIX` but not `fixing`. Terms can consist of multiple words: `really bad idea`. +* `"location"`: optional string that configures where in your comments to check for matches. Defaults to `"start"`. The other value is match `anywhere` in comments. + +Example of **incorrect** code for the default `{ "terms": ["todo", "fixme", "xxx"], "location": "start" }` options: + +```js +/*eslint no-warning-comments: "error"*/ + +function callback(err, results) { + if (err) { + console.error(err); + return; + } + // TODO +} +``` + +Example of **correct** code for the default `{ "terms": ["todo", "fixme", "xxx"], "location": "start" }` options: + +```js +/*eslint no-warning-comments: "error"*/ + +function callback(err, results) { + if (err) { + console.error(err); + return; + } + // NOT READY FOR PRIME TIME + // but too bad, it is not a predefined warning term +} +``` + +### terms and location + +Examples of **incorrect** code for the `{ "terms": ["todo", "fixme", "any other term"], "location": "anywhere" }` options: + +```js +/*eslint no-warning-comments: ["error", { "terms": ["todo", "fixme", "any other term"], "location": "anywhere" }]*/ + +// TODO: this +// todo: this too +// Even this: TODO +/* /* + * The same goes for this TODO comment + * Or a fixme + * as well as any other term + */ +``` + +Examples of **correct** code for the `{ "terms": ["todo", "fixme", "any other term"], "location": "anywhere" }` options: + +```js +/*eslint no-warning-comments: ["error", { "terms": ["todo", "fixme", "any other term"], "location": "anywhere" }]*/ + +// This is to do +// even not any other term +// any other terminal +/* + * The same goes for block comments + * with any other interesting term + * or fix me this + */ +``` + +## When Not To Use It + +* If you have a large code base that was not developed with a policy to not use such warning terms, you might get hundreds of warnings / errors which might be counter-productive if you can't fix all of them (e.g. if you don't get the time to do it) as you might overlook other warnings / errors or get used to many of them and don't pay attention on it anymore. +* Same reason as the point above: You shouldn't configure terms that are used very often (e.g. central parts of the native language used in your comments). + +## Version + +This rule was introduced in ESLint 0.4.4. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-warning-comments.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-warning-comments.md) diff --git a/docs/8.0.0/rules/no-whitespace-before-property.md b/docs/8.0.0/rules/no-whitespace-before-property.md new file mode 100644 index 0000000000..ddcc45e7fe --- /dev/null +++ b/docs/8.0.0/rules/no-whitespace-before-property.md @@ -0,0 +1,86 @@ +--- +title: no-whitespace-before-property - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-whitespace-before-property.md +rule_type: layout +--- + + +# disallow whitespace before properties (no-whitespace-before-property) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +JavaScript allows whitespace between objects and their properties. However, inconsistent spacing can make code harder to read and can lead to errors. + +```js +foo. bar .baz . quz +``` + +## Rule Details + +This rule disallows whitespace around the dot or before the opening bracket before properties of objects if they are on the same line. This rule allows whitespace when the object and property are on separate lines, as it is common to add newlines to longer chains of properties: + +```js +foo + .bar() + .baz() + .qux() +``` + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-whitespace-before-property: "error"*/ + +foo [bar] + +foo. bar + +foo .bar + +foo. bar. baz + +foo. bar() + .baz() + +foo + .bar(). baz() +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-whitespace-before-property: "error"*/ + +foo.bar + +foo[bar] + +foo[ bar ] + +foo.bar.baz + +foo + .bar().baz() + +foo + .bar() + .baz() + +foo. + bar(). + baz() +``` + +## When Not To Use It + +Turn this rule off if you do not care about allowing whitespace around the dot or before the opening bracket before properties of objects if they are on the same line. + +## Version + +This rule was introduced in ESLint 2.0.0-beta.1. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-whitespace-before-property.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-whitespace-before-property.md) diff --git a/docs/8.0.0/rules/no-with.md b/docs/8.0.0/rules/no-with.md new file mode 100644 index 0000000000..ad64d534c1 --- /dev/null +++ b/docs/8.0.0/rules/no-with.md @@ -0,0 +1,55 @@ +--- +title: no-with - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-with.md +rule_type: suggestion +--- + + +# disallow `with` statements (no-with) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +The `with` statement is potentially problematic because it adds members of an object to the current scope, making it impossible to tell what a variable inside the block actually refers to. + +## Rule Details + +This rule disallows `with` statements. + +If ESLint parses code in strict mode, the parser (instead of this rule) reports the error. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-with: "error"*/ + +with (point) { + r = Math.sqrt(x * x + y * y); // is r a member of point? +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-with: "error"*/ +/*eslint-env es6*/ + +const r = ({x, y}) => Math.sqrt(x * x + y * y); +``` + +## When Not To Use It + +If you intentionally use `with` statements then you can disable this rule. + +## Further Reading + +* [with Statement Considered Harmful](https://yuiblog.com/blog/2006/04/11/with-statement-considered-harmful/) + +## Version + +This rule was introduced in ESLint 0.0.2. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/no-with.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-with.md) diff --git a/docs/8.0.0/rules/no-wrap-func.md b/docs/8.0.0/rules/no-wrap-func.md new file mode 100644 index 0000000000..3f3b570f80 --- /dev/null +++ b/docs/8.0.0/rules/no-wrap-func.md @@ -0,0 +1,50 @@ +--- +title: no-wrap-func - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/no-wrap-func.md + +--- + + +# no-wrap-func: disallow unnecessary parentheses around function expressions + +(removed) This rule was **removed** in ESLint v1.0 and **replaced** by the [no-extra-parens](no-extra-parens) rule. The `"functions"` option in the new rule is equivalent to the removed rule. + + +Although it's possible to wrap functions in parentheses, this can be confusing when the code also contains immediately-invoked function expressions (IIFEs) since parentheses are often used to make this distinction. For example: + +```js +var foo = (function() { + // IIFE +}()); + +var bar = (function() { + // not an IIFE +}); +``` + +## Rule Details + +This rule will raise a warning when it encounters a function expression wrapped in parentheses with no following invoking parentheses. + +Example of **incorrect** code for this rule: + +```js +var a = (function() {/*...*/}); +``` + +Examples of **correct** code for this rule: + +```js +var a = function() {/*...*/}; + +(function() {/*...*/})(); +``` + +## Version + +This rule was introduced in ESLint 0.0.9 and removed in 1.0.0-rc-1. + +## Resources + +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/no-wrap-func.md) diff --git a/docs/8.0.0/rules/nonblock-statement-body-position.md b/docs/8.0.0/rules/nonblock-statement-body-position.md new file mode 100644 index 0000000000..86bd85c89f --- /dev/null +++ b/docs/8.0.0/rules/nonblock-statement-body-position.md @@ -0,0 +1,177 @@ +--- +title: nonblock-statement-body-position - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/nonblock-statement-body-position.md +rule_type: layout +--- + + +# enforce the location of single-line statements (nonblock-statement-body-position) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +When writing `if`, `else`, `while`, `do-while`, and `for` statements, the body can be a single statement instead of a block. It can be useful to enforce a consistent location for these single statements. + +For example, some developers avoid writing code like this: + +```js +if (foo) + bar(); +``` + +If another developer attempts to add `baz();` to the `if` statement, they might mistakenly change the code to + +```js +if (foo) + bar(); + baz(); // this line is not in the `if` statement! +``` + +To avoid this issue, one might require all single-line `if` statements to appear directly after the conditional, without a linebreak: + +```js +if (foo) bar(); +``` + +## Rule Details + +This rule aims to enforce a consistent location for single-line statements. + +Note that this rule does not enforce the usage of single-line statements in general. If you would like to disallow single-line statements, use the [`curly`](/docs/rules/curly) rule instead. + +### Options + +This rule accepts a string option: + +* `"beside"` (default) disallows a newline before a single-line statement. +* `"below"` requires a newline before a single-line statement. +* `"any"` does not enforce the position of a single-line statement. + +Additionally, the rule accepts an optional object option with an `"overrides"` key. This can be used to specify a location for particular statements that override the default. For example: + +* `"beside", { "overrides": { "while": "below" } }` requires all single-line statements to appear on the same line as their parent, unless the parent is a `while` statement, in which case the single-line statement must not be on the same line. +* `"below", { "overrides": { "do": "any" } }` disallows all single-line statements from appearing on the same line as their parent, unless the parent is a `do-while` statement, in which case the position of the single-line statement is not enforced. + +Examples of **incorrect** code for this rule with the default `"beside"` option: + +```js +/* eslint nonblock-statement-body-position: ["error", "beside"] */ + +if (foo) + bar(); +else + baz(); + +while (foo) + bar(); + +for (let i = 1; i < foo; i++) + bar(); + +do + bar(); +while (foo) + +``` + +Examples of **correct** code for this rule with the default `"beside"` option: + +```js +/* eslint nonblock-statement-body-position: ["error", "beside"] */ + +if (foo) bar(); +else baz(); + +while (foo) bar(); + +for (let i = 1; i < foo; i++) bar(); + +do bar(); while (foo) + +if (foo) { // block statements are always allowed with this rule + bar(); +} else { + baz(); +} +``` + +Examples of **incorrect** code for this rule with the `"below"` option: + +```js +/* eslint nonblock-statement-body-position: ["error", "below"] */ + +if (foo) bar(); +else baz(); + +while (foo) bar(); + +for (let i = 1; i < foo; i++) bar(); + +do bar(); while (foo) +``` + +Examples of **correct** code for this rule with the `"below"` option: + +```js +/* eslint nonblock-statement-body-position: ["error", "below"] */ + +if (foo) + bar(); +else + baz(); + +while (foo) + bar(); + +for (let i = 1; i < foo; i++) + bar(); + +do + bar(); +while (foo) + +if (foo) { + // Although the second `if` statement is on the same line as the `else`, this is a very common + // pattern, so it's not checked by this rule. +} else if (bar) { +} +``` + +Examples of **incorrect** code for this rule with the `"beside", { "overrides": { "while": "below" } }` rule: + +```js +/* eslint nonblock-statement-body-position: ["error", "beside", { "overrides": { "while": "below" } }] */ + +if (foo) + bar(); + +while (foo) bar(); +``` + +Examples of **correct** code for this rule with the `"beside", { "overrides": { "while": "below" } }` rule: + +```js +/* eslint nonblock-statement-body-position: ["error", "beside", { "overrides": { "while": "below" } }] */ + +if (foo) bar(); + +while (foo) + bar(); +``` + +## When Not To Use It + +If you're not concerned about consistent locations of single-line statements, you should not turn on this rule. You can also disable this rule if you're using the `"all"` option for the [`curly`](/docs/rules/curly) rule, because this will disallow single-line statements entirely. + +## Further Reading + +* JSCS: [requireNewlineBeforeSingleStatementsInIf](https://jscs-dev.github.io/rule/requireNewlineBeforeSingleStatementsInIf) + +## Version + +This rule was introduced in ESLint 3.17.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/nonblock-statement-body-position.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/nonblock-statement-body-position.md) diff --git a/docs/8.0.0/rules/object-curly-newline.md b/docs/8.0.0/rules/object-curly-newline.md new file mode 100644 index 0000000000..85922ce535 --- /dev/null +++ b/docs/8.0.0/rules/object-curly-newline.md @@ -0,0 +1,567 @@ +--- +title: object-curly-newline - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/object-curly-newline.md +rule_type: layout +--- + + +# enforce consistent line breaks after opening and before closing braces (object-curly-newline) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +A number of style guides require or disallow line breaks inside of object braces and other tokens. + +## Rule Details + +This rule requires or disallows a line break between `{` and its following token, and between `}` and its preceding token of object literals or destructuring assignments. + +## Options + +This rule has either a string option: + +* `"always"` requires line breaks after opening and before closing braces +* `"never"` disallows line breaks after opening and before closing braces + +Or an object option: + +* `"multiline": true` requires line breaks if there are line breaks inside properties or between properties. Otherwise, it disallows line breaks. +* `"minProperties"` requires line breaks if the number of properties is at least the given integer. By default, an error will also be reported if an object contains linebreaks and has fewer properties than the given integer. However, the second behavior is disabled if the `consistent` option is set to `true` +* `"consistent": true` (default) requires that either both curly braces, or neither, directly enclose newlines. Note that enabling this option will also change the behavior of the `minProperties` option. (See `minProperties` above for more information) + +You can specify different options for object literals, destructuring assignments, and named imports and exports: + +```json +{ + "object-curly-newline": ["error", { + "ObjectExpression": "always", + "ObjectPattern": { "multiline": true }, + "ImportDeclaration": "never", + "ExportDeclaration": { "multiline": true, "minProperties": 3 } + }] +} +``` + +* `"ObjectExpression"` configuration for object literals +* `"ObjectPattern"` configuration for object patterns of destructuring assignments +* `"ImportDeclaration"` configuration for named imports +* `"ExportDeclaration"` configuration for named exports + +### always + +Examples of **incorrect** code for this rule with the `"always"` option: + +```js +/*eslint object-curly-newline: ["error", "always"]*/ +/*eslint-env es6*/ + +let a = {}; +let b = {foo: 1}; +let c = {foo: 1, bar: 2}; +let d = {foo: 1, + bar: 2}; +let e = {foo() { + dosomething(); +}}; + +let {} = obj; +let {f} = obj; +let {g, h} = obj; +let {i, + j} = obj; +let {k = function() { + dosomething(); +}} = obj; +``` + +Examples of **correct** code for this rule with the `"always"` option: + +```js +/*eslint object-curly-newline: ["error", "always"]*/ +/*eslint-env es6*/ + +let a = { +}; +let b = { + foo: 1 +}; +let c = { + foo: 1, bar: 2 +}; +let d = { + foo: 1, + bar: 2 +}; +let e = { + foo: function() { + dosomething(); + } +}; + +let { +} = obj; +let { + f +} = obj; +let { + g, h +} = obj; +let { + i, + j +} = obj; +let { + k = function() { + dosomething(); + } +} = obj; +``` + +### never + +Examples of **incorrect** code for this rule with the `"never"` option: + +```js +/*eslint object-curly-newline: ["error", "never"]*/ +/*eslint-env es6*/ + +let a = { +}; +let b = { + foo: 1 +}; +let c = { + foo: 1, bar: 2 +}; +let d = { + foo: 1, + bar: 2 +}; +let e = { + foo: function() { + dosomething(); + } +}; + +let { +} = obj; +let { + f +} = obj; +let { + g, h +} = obj; +let { + i, + j +} = obj; +let { + k = function() { + dosomething(); + } +} = obj; +``` + +Examples of **correct** code for this rule with the `"never"` option: + +```js +/*eslint object-curly-newline: ["error", "never"]*/ +/*eslint-env es6*/ + +let a = {}; +let b = {foo: 1}; +let c = {foo: 1, bar: 2}; +let d = {foo: 1, + bar: 2}; +let e = {foo: function() { + dosomething(); +}}; + +let {} = obj; +let {f} = obj; +let {g, h} = obj; +let {i, + j} = obj; +let {k = function() { + dosomething(); +}} = obj; +``` + +### multiline + +Examples of **incorrect** code for this rule with the `{ "multiline": true }` option: + +```js +/*eslint object-curly-newline: ["error", { "multiline": true }]*/ +/*eslint-env es6*/ + +let a = { +}; +let b = { + foo: 1 +}; +let c = { + foo: 1, bar: 2 +}; +let d = {foo: 1, + bar: 2}; +let e = {foo: function() { + dosomething(); +}}; + +let { +} = obj; +let { + f +} = obj; +let { + g, h +} = obj; +let {i, + j} = obj; +let {k = function() { + dosomething(); +}} = obj; +``` + +Examples of **correct** code for this rule with the `{ "multiline": true }` option: + +```js +/*eslint object-curly-newline: ["error", { "multiline": true }]*/ +/*eslint-env es6*/ + +let a = {}; +let b = {foo: 1}; +let c = {foo: 1, bar: 2}; +let d = { + foo: 1, + bar: 2 +}; +let e = { + foo: function() { + dosomething(); + } +}; + +let {} = obj; +let {f} = obj; +let {g, h} = obj; +let { + i, + j +} = obj; +let { + k = function() { + dosomething(); + } +} = obj; +``` + +### minProperties + +Examples of **incorrect** code for this rule with the `{ "minProperties": 2 }` option: + +```js +/*eslint object-curly-newline: ["error", { "minProperties": 2 }]*/ +/*eslint-env es6*/ + +let a = { +}; +let b = { + foo: 1 +}; +let c = {foo: 1, bar: 2}; +let d = {foo: 1, + bar: 2}; +let e = { + foo: function() { + dosomething(); + } +}; + +let { +} = obj; +let { + f +} = obj; +let {g, h} = obj; +let {i, + j} = obj; +let { + k = function() { + dosomething(); + } +} = obj; +``` + +Examples of **correct** code for this rule with the `{ "minProperties": 2 }` option: + +```js +/*eslint object-curly-newline: ["error", { "minProperties": 2 }]*/ +/*eslint-env es6*/ + +let a = {}; +let b = {foo: 1}; +let c = { + foo: 1, bar: 2 +}; +let d = { + foo: 1, + bar: 2 +}; +let e = {foo: function() { + dosomething(); +}}; + +let {} = obj; +let {f} = obj; +let { + g, h +} = obj; +let { + i, + j +} = obj; +let {k = function() { + dosomething(); +}} = obj; +``` + +### consistent + +Examples of **incorrect** code for this rule with the default `{ "consistent": true }` option: + +```js +/*eslint object-curly-newline: ["error", { "consistent": true }]*/ +/*eslint-env es6*/ + +let a = {foo: 1 +}; +let b = { + foo: 1}; +let c = {foo: 1, bar: 2 +}; +let d = { + foo: 1, bar: 2}; +let e = {foo: function() { + dosomething(); + } +}; +let f = { + foo: function() { + dosomething();}}; + +let {g +} = obj; +let { + h} = obj; +let {i, j +} = obj; +let {k, l +} = obj; +let { + m, n} = obj; +let { + o, p} = obj; +let {q = function() { + dosomething(); + } +} = obj; +let { + r = function() { + dosomething(); + }} = obj; +``` + +Examples of **correct** code for this rule with the default `{ "consistent": true }` option: + +```js +/*eslint object-curly-newline: ["error", { "consistent": true }]*/ +/*eslint-env es6*/ + + +let empty1 = {}; +let empty2 = { +}; +let a = {foo: 1}; +let b = { + foo: 1 +}; +let c = { + foo: 1, bar: 2 +}; +let d = { + foo: 1, + bar: 2 +}; +let e = {foo: function() {dosomething();}}; +let f = { + foo: function() { + dosomething(); + } +}; + +let {} = obj; +let { +} = obj; +let {g} = obj; +let { + h +} = obj; +let {i, j} = obj; +let { + k, l +} = obj; +let {m, + n} = obj; +let { + o, + p +} = obj; +let {q = function() {dosomething();}} = obj; +let { + r = function() { + dosomething(); + } +} = obj; +``` + +### ObjectExpression and ObjectPattern + +Examples of **incorrect** code for this rule with the `{ "ObjectExpression": "always", "ObjectPattern": "never" }` options: + +```js +/*eslint object-curly-newline: ["error", { "ObjectExpression": "always", "ObjectPattern": "never" }]*/ +/*eslint-env es6*/ + +let a = {}; +let b = {foo: 1}; +let c = {foo: 1, bar: 2}; +let d = {foo: 1, + bar: 2}; +let e = {foo: function() { + dosomething(); +}}; + +let { +} = obj; +let { + f +} = obj; +let { + g, h +} = obj; +let { + i, + j +} = obj; +let { + k = function() { + dosomething(); + } +} = obj; +``` + +Examples of **correct** code for this rule with the `{ "ObjectExpression": "always", "ObjectPattern": "never" }` options: + +```js +/*eslint object-curly-newline: ["error", { "ObjectExpression": "always", "ObjectPattern": "never" }]*/ +/*eslint-env es6*/ + +let a = { +}; +let b = { + foo: 1 +}; +let c = { + foo: 1, bar: 2 +}; +let d = { + foo: 1, + bar: 2 +}; +let e = { + foo: function() { + dosomething(); + } +}; + +let {} = obj; +let {f} = obj; +let {g, h} = obj; +let {i, + j} = obj; +let {k = function() { + dosomething(); +}} = obj; +``` + +### ImportDeclaration and ExportDeclaration + +Examples of **incorrect** code for this rule with the `{ "ImportDeclaration": "always", "ExportDeclaration": "never" }` options: + +```js +/*eslint object-curly-newline: ["error", { "ImportDeclaration": "always", "ExportDeclaration": "never" }]*/ +/*eslint-env es6*/ + +import {foo, bar} from 'foo-bar'; +import {foo as f, bar} from 'foo-bar'; +import {foo, + bar} from 'foo-bar'; + +export { + foo, + bar +}; +export { + foo as f, + bar +} from 'foo-bar'; +``` + +Examples of **correct** code for this rule with the `{ "ImportDeclaration": "always", "ExportDeclaration": "never" }` options: + +```js +/*eslint object-curly-newline: ["error", { "ImportDeclaration": "always", "ExportDeclaration": "never" }]*/ +/*eslint-env es6*/ + +import { + foo, + bar +} from 'foo-bar'; +import { + foo, bar +} from 'foo-bar'; +import { + foo as f, + bar +} from 'foo-bar'; + +export { foo, bar } from 'foo-bar'; +export { foo as f, bar } from 'foo-bar'; +``` + +## Compatibility + +* **JSCS**: [requirePaddingNewLinesInObjects](https://jscs-dev.github.io/rule/requirePaddingNewLinesInObjects) +* **JSCS**: [disallowPaddingNewLinesInObjects](https://jscs-dev.github.io/rule/disallowPaddingNewLinesInObjects) + +## When Not To Use It + +If you don't want to enforce consistent line breaks after opening and before closing braces, then it's safe to disable this rule. + +## Related Rules + +* [comma-spacing](comma-spacing) +* [key-spacing](key-spacing) +* [object-curly-spacing](object-curly-spacing) +* [object-property-newline](object-property-newline) + +## Version + +This rule was introduced in ESLint 2.12.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/object-curly-newline.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/object-curly-newline.md) diff --git a/docs/8.0.0/rules/object-curly-spacing.md b/docs/8.0.0/rules/object-curly-spacing.md new file mode 100644 index 0000000000..cacaf4bf78 --- /dev/null +++ b/docs/8.0.0/rules/object-curly-spacing.md @@ -0,0 +1,175 @@ +--- +title: object-curly-spacing - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/object-curly-spacing.md +rule_type: layout +--- + + +# enforce consistent spacing inside braces (object-curly-spacing) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +While formatting preferences are very personal, a number of style guides require +or disallow spaces between curly braces in the following situations: + +```js +// simple object literals +var obj = { foo: "bar" }; + +// nested object literals +var obj = { foo: { zoo: "bar" } }; + +// destructuring assignment (EcmaScript 6) +var { x, y } = y; + +// import/export declarations (EcmaScript 6) +import { foo } from "bar"; +export { foo }; +``` + +## Rule Details + +This rule enforces consistent spacing inside braces of object literals, destructuring assignments, and import/export specifiers. + +## Options + +This rule has two options, a string option and an object option. + +String option: + +* `"never"` (default) disallows spacing inside of braces +* `"always"` requires spacing inside of braces (except `{}`) + +Object option: + +* `"arraysInObjects": true` requires spacing inside of braces of objects beginning and/or ending with an array element (applies when the first option is set to `never`) +* `"arraysInObjects": false` disallows spacing inside of braces of objects beginning and/or ending with an array element (applies when the first option is set to `always`) +* `"objectsInObjects": true` requires spacing inside of braces of objects beginning and/or ending with an object element (applies when the first option is set to `never`) +* `"objectsInObjects": false` disallows spacing inside of braces of objects beginning and/or ending with an object element (applies when the first option is set to `always`) + +### never + +Examples of **incorrect** code for this rule with the default `"never"` option: + +```js +/*eslint object-curly-spacing: ["error", "never"]*/ + +var obj = { 'foo': 'bar' }; +var obj = {'foo': 'bar' }; +var obj = { baz: {'foo': 'qux'}, bar}; +var obj = {baz: { 'foo': 'qux'}, bar}; +var {x } = y; +import { foo } from 'bar'; +``` + +Examples of **correct** code for this rule with the default `"never"` option: + +```js +/*eslint object-curly-spacing: ["error", "never"]*/ + +var obj = {'foo': 'bar'}; +var obj = {'foo': {'bar': 'baz'}, 'qux': 'quxx'}; +var obj = { + 'foo': 'bar' +}; +var obj = {'foo': 'bar' +}; +var obj = { + 'foo':'bar'}; +var obj = {}; +var {x} = y; +import {foo} from 'bar'; +``` + +### always + +Examples of **incorrect** code for this rule with the `"always"` option: + +```js +/*eslint object-curly-spacing: ["error", "always"]*/ + +var obj = {'foo': 'bar'}; +var obj = {'foo': 'bar' }; +var obj = { baz: {'foo': 'qux'}, bar}; +var obj = {baz: { 'foo': 'qux' }, bar}; +var obj = {'foo': 'bar' +}; +var obj = { + 'foo':'bar'}; +var {x} = y; +import {foo } from 'bar'; +``` + +Examples of **correct** code for this rule with the `"always"` option: + +```js +/*eslint object-curly-spacing: ["error", "always"]*/ + +var obj = {}; +var obj = { 'foo': 'bar' }; +var obj = { 'foo': { 'bar': 'baz' }, 'qux': 'quxx' }; +var obj = { + 'foo': 'bar' +}; +var { x } = y; +import { foo } from 'bar'; +``` + +#### arraysInObjects + +Examples of additional **correct** code for this rule with the `"never", { "arraysInObjects": true }` options: + +```js +/*eslint object-curly-spacing: ["error", "never", { "arraysInObjects": true }]*/ + +var obj = {"foo": [ 1, 2 ] }; +var obj = {"foo": [ "baz", "bar" ] }; +``` + +Examples of additional **correct** code for this rule with the `"always", { "arraysInObjects": false }` options: + +```js +/*eslint object-curly-spacing: ["error", "always", { "arraysInObjects": false }]*/ + +var obj = { "foo": [ 1, 2 ]}; +var obj = { "foo": [ "baz", "bar" ]}; +``` + +#### objectsInObjects + +Examples of additional **correct** code for this rule with the `"never", { "objectsInObjects": true }` options: + +```js +/*eslint object-curly-spacing: ["error", "never", { "objectsInObjects": true }]*/ + +var obj = {"foo": {"baz": 1, "bar": 2} }; +``` + +Examples of additional **correct** code for this rule with the `"always", { "objectsInObjects": false }` options: + +```js +/*eslint object-curly-spacing: ["error", "always", { "objectsInObjects": false }]*/ + +var obj = { "foo": { "baz": 1, "bar": 2 }}; +``` + +## When Not To Use It + +You can turn this rule off if you are not concerned with the consistency of spacing between curly braces. + +## Related Rules + +* [array-bracket-spacing](array-bracket-spacing) +* [comma-spacing](comma-spacing) +* [computed-property-spacing](computed-property-spacing) +* [space-in-parens](space-in-parens) + +## Version + +This rule was introduced in ESLint 0.22.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/object-curly-spacing.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/object-curly-spacing.md) diff --git a/docs/8.0.0/rules/object-property-newline.md b/docs/8.0.0/rules/object-property-newline.md new file mode 100644 index 0000000000..ef1c1b1ea5 --- /dev/null +++ b/docs/8.0.0/rules/object-property-newline.md @@ -0,0 +1,289 @@ +--- +title: object-property-newline - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/object-property-newline.md +rule_type: layout +--- + + +# enforce placing object properties on separate lines (object-property-newline) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +This rule permits you to restrict the locations of property specifications in object literals. You may prohibit any part of any property specification from appearing on the same line as any part of any other property specification. You may make this prohibition absolute, or, by invoking an object option, you may allow an exception, permitting an object literal to have all parts of all of its property specifications on a single line. + +## Rule Details + +### Motivations + +This rule makes it possible to ensure, as some style guides require, that property specifications appear on separate lines for better readability. For example, you can prohibit all of these: + +```js +const newObject = {a: 1, b: [2, {a: 3, b: 4}]}; +const newObject = { + a: 1, b: [2, {a: 3, b: 4}] +}; +const newObject = { + a: 1, + b: [2, {a: 3, b: 4}] +}; +const newObject = { + a: 1, + b: [ + 2, + {a: 3, b: 4} + ] +}; + +``` + +Instead of those, you can comply with the rule by writing + +```js +const newObject = { + a: 1, + b: [2, { + a: 3, + b: 4 + }] +}; +``` + +or + +```js +const newObject = { + a: 1, + b: [ + 2, + { + a: 3, + b: 4 + } + ] +}; +``` + +Another benefit of this rule is specificity of diffs when a property is changed: + +```diff +// More specific + var obj = { + foo: "foo", +- bar: "bar", ++ bar: "bazz", + baz: "baz" + }; +``` + +```diff +// Less specific +-var obj = { foo: "foo", bar: "bar", baz: "baz" }; ++var obj = { foo: "foo", bar: "bazz", baz: "baz" }; +``` + +### Optional Exception + +The rule offers one object option, `allowAllPropertiesOnSameLine` (a deprecated synonym is `allowMultiplePropertiesPerLine`). If you set it to `true`, object literals such as the first two above, with all property specifications on the same line, will be permitted, but one like + +```js +const newObject = { + a: 'a.m.', b: 'p.m.', + c: 'daylight saving time' +}; + +``` + +will be prohibited, because two properties, but not all properties, appear on the same line. + +### Notations + +This rule applies equally to all property specifications, regardless of notation, including: + +- `a: 1` (ES5) +- `a` (ES2015 shorthand property) +- ``[`prop${a}`]`` (ES2015 computed property name) + +Thus, the rule (without the object option) prohibits both of these: + +```js +const newObject = { + a: 1, [ + process.argv[4] + ]: '01' +}; +const newObject = { + a: 1, [process.argv[4]]: '01' +}; +``` + +(This behavior differs from that of the JSCS rule cited below, which does not treat the leading `[` of a computed property name as part of that property specification. The JSCS rule prohibits the second of these formats but permits the first.) + +### Multiline Properties + +The rule prohibits the colocation on any line of at least 1 character of one property specification with at least 1 character of any other property specification. For example, the rule prohibits + +```js +const newObject = {a: [ + 'Officiële website van de Europese Unie', + 'Официален уебсайт на Европейския съюз' +], b: 2}; +``` + +because 1 character of the specification of `a` (i.e. the trailing `]` of its value) is on the same line as the specification of `b`. + +The optional exception does not excuse this case, because the entire collection of property specifications spans 4 lines, not 1. + +### Inter-property Delimiters + +The comma and any whitespace that delimit property specifications are not considered parts of them. Therefore, the rule permits both of these formats: + +```js +const newFunction = multiplier => ({ + a: 2 * multiplier, + b: 4 * multiplier, + c: 8 * multiplier +}); +const newFunction = multiplier => ({ + a: 2 * multiplier + , b: 4 * multiplier + , c: 8 * multiplier +}); +``` + +(This behavior differs from that of the JSCS rule cited below, which permits the first but prohibits the second format.) + +### --fix + +If this rule is invoked with the command-line `--fix` option, object literals that violate the rule are generally modified to comply with it. The modification in each case is to move a property specification to the next line whenever there is part or all of a previous property specification on the same line. For example, + +```js +const newObject = { + a: 'a.m.', b: 'p.m.', + c: 'daylight saving time' +}; +``` + +is converted to + +```js +const newObject = { + a: 'a.m.', +b: 'p.m.', + c: 'daylight saving time' +}; +``` + +The modification does not depend on whether the object option is set to `true`. In other words, ESLint never collects all the property specifications onto a single line, even when the object option would permit that. + +ESLint does not correct a violation of this rule if a comment immediately precedes the second or subsequent property specification on a line, since ESLint cannot determine which line to put the comment onto. + +As illustrated above, the `--fix` option, applied to this rule, does not comply with other rules, such as `indent`, but, if those other rules are also in effect, the option applies them, too. + +## Examples + +Examples of **incorrect** code for this rule, with no object option or with `allowAllPropertiesOnSameLine` set to `false`: + +```js +/*eslint object-property-newline: "error"*/ + +const obj0 = { foo: "foo", bar: "bar", baz: "baz" }; + +const obj1 = { + foo: "foo", bar: "bar", baz: "baz" +}; + +const obj2 = { + foo: "foo", bar: "bar", + baz: "baz" +}; + +const obj3 = { + [process.argv[3] ? "foo" : "bar"]: 0, baz: [ + 1, + 2, + 4, + 8 + ] +}; + +const a = "antidisestablishmentarianistically"; +const b = "yugoslavyalılaştırabildiklerimizdenmişsiniz"; +const obj4 = {a, b}; + +const domain = process.argv[4]; +const obj5 = { + foo: "foo", [ + domain.includes(":") ? "complexdomain" : "simpledomain" +]: true}; +``` + +Examples of **correct** code for this rule, with no object option or with `allowAllPropertiesOnSameLine` set to `false`: + +```js +/*eslint object-property-newline: "error"*/ + +const obj1 = { + foo: "foo", + bar: "bar", + baz: "baz" +}; + +const obj2 = { + foo: "foo" + , bar: "bar" + , baz: "baz" +}; + +const user = process.argv[2]; +const obj3 = { + user, + [process.argv[3] ? "foo" : "bar"]: 0, + baz: [ + 1, + 2, + 4, + 8 + ] +}; +``` + +Examples of additional **correct** code for this rule with the `{ "allowAllPropertiesOnSameLine": true }` option: + +```js +/*eslint object-property-newline: ["error", { "allowAllPropertiesOnSameLine": true }]*/ + +const obj = { foo: "foo", bar: "bar", baz: "baz" }; + +const obj2 = { + foo: "foo", bar: "bar", baz: "baz" +}; +const user = process.argv[2]; +const obj3 = { + user, [process.argv[3] ? "foo" : "bar"]: 0, baz: [1, 2, 4, 8] +}; +``` + +## When Not To Use It + +You can turn this rule off if you want to decide, case-by-case, whether to place property specifications on separate lines. + +## Compatibility + +- **JSCS**: This rule provides partial compatibility with [requireObjectKeysOnNewLine](https://jscs-dev.github.io/rule/requireObjectKeysOnNewLine). + +## Related Rules + +- [brace-style](brace-style) +- [comma-dangle](comma-dangle) +- [key-spacing](key-spacing) +- [object-curly-spacing](object-curly-spacing) + +## Version + +This rule was introduced in ESLint 2.10.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/object-property-newline.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/object-property-newline.md) diff --git a/docs/8.0.0/rules/object-shorthand.md b/docs/8.0.0/rules/object-shorthand.md new file mode 100644 index 0000000000..e86014a51d --- /dev/null +++ b/docs/8.0.0/rules/object-shorthand.md @@ -0,0 +1,271 @@ +--- +title: object-shorthand - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/object-shorthand.md +rule_type: suggestion +--- + + +# Require Object Literal Shorthand Syntax (object-shorthand) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +ECMAScript 6 provides a concise form for defining object literal methods and properties. This +syntax can make defining complex object literals much cleaner. + +Here are a few common examples using the ES5 syntax: + +```js +// properties +var foo = { + x: x, + y: y, + z: z, +}; + +// methods +var foo = { + a: function() {}, + b: function() {} +}; +``` + +Now here are ES6 equivalents: + +```js +/*eslint-env es6*/ + +// properties +var foo = {x, y, z}; + +// methods +var foo = { + a() {}, + b() {} +}; +``` + +## Rule Details + +This rule enforces the use of the shorthand syntax. This applies +to all methods (including generators) defined in object literals and any +properties defined where the key name matches name of the assigned variable. + +Each of the following properties would warn: + + +```js +/*eslint object-shorthand: "error"*/ +/*eslint-env es6*/ + +var foo = { + w: function() {}, + x: function *() {}, + [y]: function() {}, + z: z +}; +``` + +In that case the expected syntax would have been: + +```js +/*eslint object-shorthand: "error"*/ +/*eslint-env es6*/ + +var foo = { + w() {}, + *x() {}, + [y]() {}, + z +}; +``` + +This rule does not flag arrow functions inside of object literals. +The following will *not* warn: + +```js +/*eslint object-shorthand: "error"*/ +/*eslint-env es6*/ + +var foo = { + x: (y) => y +}; +``` + +See Also: + +- [`no-useless-rename`](https://eslint.org/docs/rules/no-useless-rename) which disallows renaming import, export, and destructured assignments to the same name. + +## Options + +The rule takes an option which specifies when it should be applied. It can be set to one of the following values: + +- `"always"` (default) expects that the shorthand will be used whenever possible. +- `"methods"` ensures the method shorthand is used (also applies to generators). +- `"properties"` ensures the property shorthand is used (where the key and variable name match). +- `"never"` ensures that no property or method shorthand is used in any object literal. +- `"consistent"` ensures that either all shorthand or all long-form will be used in an object literal. +- `"consistent-as-needed"` ensures that either all shorthand or all long-form will be used in an object literal, but ensures all shorthand whenever possible. + +You can set the option in configuration like this: + +```json +{ + "object-shorthand": ["error", "always"] +} +``` + +Additionally, the rule takes an optional object configuration: + +- `"avoidQuotes": true` indicates that long-form syntax is preferred whenever the object key is a string literal (default: `false`). Note that this option can only be enabled when the string option is set to `"always"`, `"methods"`, or `"properties"`. +- `"ignoreConstructors": true` can be used to prevent the rule from reporting errors for constructor functions. (By default, the rule treats constructors the same way as other functions.) Note that this option can only be enabled when the string option is set to `"always"` or `"methods"`. +- `"avoidExplicitReturnArrows": true` indicates that methods are preferred over explicit-return arrow functions for function properties. (By default, the rule allows either of these.) Note that this option can only be enabled when the string option is set to `"always"` or `"methods"`. + +### `avoidQuotes` + +```json +{ + "object-shorthand": ["error", "always", { "avoidQuotes": true }] +} +``` + +Example of **incorrect** code for this rule with the `"always", { "avoidQuotes": true }` option: + +```js +/*eslint object-shorthand: ["error", "always", { "avoidQuotes": true }]*/ +/*eslint-env es6*/ + +var foo = { + "bar-baz"() {} +}; +``` + +Example of **correct** code for this rule with the `"always", { "avoidQuotes": true }` option: + +```js +/*eslint object-shorthand: ["error", "always", { "avoidQuotes": true }]*/ +/*eslint-env es6*/ + +var foo = { + "bar-baz": function() {}, + "qux": qux +}; +``` + +### `ignoreConstructors` + +```json +{ + "object-shorthand": ["error", "always", { "ignoreConstructors": true }] +} +``` + +Example of **correct** code for this rule with the `"always", { "ignoreConstructors": true }` option: + +```js +/*eslint object-shorthand: ["error", "always", { "ignoreConstructors": true }]*/ +/*eslint-env es6*/ + +var foo = { + ConstructorFunction: function() {} +}; +``` + +### `avoidExplicitReturnArrows` + +```json +{ + "object-shorthand": ["error", "always", { "avoidExplicitReturnArrows": true }] +} +``` + +Example of **incorrect** code for this rule with the `"always", { "avoidExplicitReturnArrows": true }` option: + +```js +/*eslint object-shorthand: ["error", "always", { "avoidExplicitReturnArrows": true }]*/ +/*eslint-env es6*/ + +var foo = { + foo: (bar, baz) => { + return bar + baz; + }, + + qux: (foobar) => { + return foobar * 2; + } +}; +``` + +Example of **correct** code for this rule with the `"always", { "avoidExplicitReturnArrows": true }` option: + +```js +/*eslint object-shorthand: ["error", "always", { "avoidExplicitReturnArrows": true }]*/ +/*eslint-env es6*/ + +var foo = { + foo(bar, baz) { + return bar + baz; + }, + + qux: foobar => foobar * 2 +}; +``` + +Example of **incorrect** code for this rule with the `"consistent"` option: + +```js +/*eslint object-shorthand: [2, "consistent"]*/ +/*eslint-env es6*/ + +var foo = { + a, + b: "foo", +}; +``` + +Examples of **correct** code for this rule with the `"consistent"` option: + +```js +/*eslint object-shorthand: [2, "consistent"]*/ +/*eslint-env es6*/ + +var foo = { + a: a, + b: "foo" +}; + +var bar = { + a, + b, +}; +``` + +Example of **incorrect** code with the `"consistent-as-needed"` option, which is very similar to `"consistent"`: + +```js +/*eslint object-shorthand: [2, "consistent-as-needed"]*/ +/*eslint-env es6*/ + +var foo = { + a: a, + b: b, +}; +``` + +## When Not To Use It + +Anyone not yet in an ES6 environment would not want to apply this rule. Others may find the terseness of the shorthand +syntax harder to read and may not want to encourage it with this rule. + +## Further Reading + +[Object initializer - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer) + +## Version + +This rule was introduced in ESLint 0.20.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/object-shorthand.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/object-shorthand.md) diff --git a/docs/8.0.0/rules/one-var-declaration-per-line.md b/docs/8.0.0/rules/one-var-declaration-per-line.md new file mode 100644 index 0000000000..dad39f9017 --- /dev/null +++ b/docs/8.0.0/rules/one-var-declaration-per-line.md @@ -0,0 +1,108 @@ +--- +title: one-var-declaration-per-line - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/one-var-declaration-per-line.md +rule_type: suggestion +--- + + +# require or disallow newlines around variable declarations (one-var-declaration-per-line) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +Some developers declare multiple var statements on the same line: + +```js +var foo, bar, baz; +``` + +Others prefer to declare one var per line. + +```js +var foo, + bar, + baz; +``` + +Keeping to one of these styles across a project's codebase can help with maintaining code consistency. + +## Rule Details + +This rule enforces a consistent newlines around variable declarations. This rule ignores variable declarations inside `for` loop conditionals. + +## Options + +This rule has a single string option: + +* `"initializations"` (default) enforces a newline around variable initializations +* `"always"` enforces a newline around variable declarations + +### initializations + +Examples of **incorrect** code for this rule with the default `"initializations"` option: + +```js +/*eslint one-var-declaration-per-line: ["error", "initializations"]*/ +/*eslint-env es6*/ + +var a, b, c = 0; + +let a, + b = 0, c; +``` + +Examples of **correct** code for this rule with the default `"initializations"` option: + +```js +/*eslint one-var-declaration-per-line: ["error", "initializations"]*/ +/*eslint-env es6*/ + +var a, b; + +let a, + b; + +let a, + b = 0; +``` + +### always + +Examples of **incorrect** code for this rule with the `"always"` option: + +```js +/*eslint one-var-declaration-per-line: ["error", "always"]*/ +/*eslint-env es6*/ + +var a, b; + +let a, b = 0; + +const a = 0, b = 0; +``` + +Examples of **correct** code for this rule with the `"always"` option: + +```js +/*eslint one-var-declaration-per-line: ["error", "always"]*/ +/*eslint-env es6*/ + +var a, + b; + +let a, + b = 0; +``` + +## Related Rules + +* [one-var](one-var) + +## Version + +This rule was introduced in ESLint 2.0.0-beta.3. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/one-var-declaration-per-line.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/one-var-declaration-per-line.md) diff --git a/docs/8.0.0/rules/one-var.md b/docs/8.0.0/rules/one-var.md new file mode 100644 index 0000000000..aae2a0e2ac --- /dev/null +++ b/docs/8.0.0/rules/one-var.md @@ -0,0 +1,561 @@ +--- +title: one-var - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/one-var.md +rule_type: suggestion +--- + + +# enforce variables to be declared either together or separately in functions (one-var) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +Variables can be declared at any point in JavaScript code using `var`, `let`, or `const`. There are many styles and preferences related to the declaration of variables, and one of those is deciding on how many variable declarations should be allowed in a single function. + +There are two schools of thought in this regard: + +1. There should be just one variable declaration for all variables in the function. That declaration typically appears at the top of the function. +1. You should use one variable declaration for each variable you want to define. + +For instance: + +```js +// one variable declaration per function +function foo() { + var bar, baz; +} + +// multiple variable declarations per function +function foo() { + var bar; + var baz; +} +``` + +The single-declaration school of thought is based in pre-ECMAScript 6 behaviors, where there was no such thing as block scope, only function scope. Since all `var` statements are hoisted to the top of the function anyway, some believe that declaring all variables in a single declaration at the top of the function removes confusion around scoping rules. + +## Rule Details + +This rule enforces variables to be declared either together or separately per function ( for `var`) or block (for `let` and `const`) scope. + +## Options + +This rule has one option, which can be a string option or an object option. + +String option: + +* `"always"` (default) requires one variable declaration per scope +* `"never"` requires multiple variable declarations per scope +* `"consecutive"` allows multiple variable declarations per scope but requires consecutive variable declarations to be combined into a single declaration + +Object option: + +* `"var": "always"` requires one `var` declaration per function +* `"var": "never"` requires multiple `var` declarations per function +* `"var": "consecutive"` requires consecutive `var` declarations to be a single declaration +* `"let": "always"` requires one `let` declaration per block +* `"let": "never"` requires multiple `let` declarations per block +* `"let": "consecutive"` requires consecutive `let` declarations to be a single declaration +* `"const": "always"` requires one `const` declaration per block +* `"const": "never"` requires multiple `const` declarations per block +* `"const": "consecutive"` requires consecutive `const` declarations to be a single declaration +* `"separateRequires": true` enforces `requires` to be separate from declarations + +Alternate object option: + +* `"initialized": "always"` requires one variable declaration for initialized variables per scope +* `"initialized": "never"` requires multiple variable declarations for initialized variables per scope +* `"initialized": "consecutive"` requires consecutive variable declarations for initialized variables to be a single declaration +* `"uninitialized": "always"` requires one variable declaration for uninitialized variables per scope +* `"uninitialized": "never"` requires multiple variable declarations for uninitialized variables per scope +* `"uninitialized": "consecutive"` requires consecutive variable declarations for uninitialized variables to be a single declaration + +### always + +Examples of **incorrect** code for this rule with the default `"always"` option: + +```js +/*eslint one-var: ["error", "always"]*/ +/*eslint-env es6*/ + +function foo() { + var bar; + var baz; + let qux; + let norf; +} + +function foo(){ + const bar = false; + const baz = true; + let qux; + let norf; +} + +function foo() { + var bar; + + if (baz) { + var qux = true; + } +} +``` + +Examples of **correct** code for this rule with the default `"always"` option: + +```js +/*eslint one-var: ["error", "always"]*/ +/*eslint-env es6*/ + +function foo() { + var bar, + baz; + let qux, + norf; +} + +function foo(){ + const bar = true, + baz = false; + let qux, + norf; +} + +function foo() { + var bar, + qux; + + if (baz) { + qux = true; + } +} + +function foo(){ + let bar; + + if (baz) { + let qux; + } +} +``` + +### never + +Examples of **incorrect** code for this rule with the `"never"` option: + +```js +/*eslint one-var: ["error", "never"]*/ +/*eslint-env es6*/ + +function foo() { + var bar, + baz; + const bar = true, + baz = false; +} + +function foo() { + var bar, + qux; + + if (baz) { + qux = true; + } +} + +function foo(){ + let bar = true, + baz = false; +} +``` + +Examples of **correct** code for this rule with the `"never"` option: + +```js +/*eslint one-var: ["error", "never"]*/ +/*eslint-env es6*/ + +function foo() { + var bar; + var baz; +} + +function foo() { + var bar; + + if (baz) { + var qux = true; + } +} + +function foo() { + let bar; + + if (baz) { + let qux = true; + } +} +``` + +### consecutive + +Examples of **incorrect** code for this rule with the `"consecutive"` option: + +```js +/*eslint one-var: ["error", "consecutive"]*/ +/*eslint-env es6*/ + +function foo() { + var bar; + var baz; +} + +function foo(){ + var bar = 1; + var baz = 2; + + qux(); + + var qux = 3; + var quux; +} +``` + +Examples of **correct** code for this rule with the `"consecutive"` option: + +```js +/*eslint one-var: ["error", "consecutive"]*/ +/*eslint-env es6*/ + + +function foo() { + var bar, + baz; +} + +function foo(){ + var bar = 1, + baz = 2; + + qux(); + + var qux = 3, + quux; +} +``` + +### var, let, and const + +Examples of **incorrect** code for this rule with the `{ var: "always", let: "never", const: "never" }` option: + +```js +/*eslint one-var: ["error", { var: "always", let: "never", const: "never" }]*/ +/*eslint-env es6*/ + +function foo() { + var bar; + var baz; + let qux, + norf; +} + +function foo() { + const bar = 1, + baz = 2; + let qux, + norf; +} +``` + +Examples of **correct** code for this rule with the `{ var: "always", let: "never", const: "never" }` option: + +```js +/*eslint one-var: ["error", { var: "always", let: "never", const: "never" }]*/ +/*eslint-env es6*/ + +function foo() { + var bar, + baz; + let qux; + let norf; +} + +function foo() { + const bar = 1; + const baz = 2; + let qux; + let norf; +} +``` + +Examples of **incorrect** code for this rule with the `{ var: "never" }` option: + +```js +/*eslint one-var: ["error", { var: "never" }]*/ +/*eslint-env es6*/ + +function foo() { + var bar, + baz; +} +``` + +Examples of **correct** code for this rule with the `{ var: "never" }` option: + +```js +/*eslint one-var: ["error", { var: "never" }]*/ +/*eslint-env es6*/ + +function foo() { + var bar, + baz; + const bar = 1; // `const` and `let` declarations are ignored if they are not specified + const baz = 2; + let qux; + let norf; +} +``` + +Examples of **incorrect** code for this rule with the `{ separateRequires: true }` option: + +```js +/*eslint one-var: ["error", { separateRequires: true, var: "always" }]*/ +/*eslint-env node*/ + +var foo = require("foo"), + bar = "bar"; +``` + +Examples of **correct** code for this rule with the `{ separateRequires: true }` option: + +```js +/*eslint one-var: ["error", { separateRequires: true, var: "always" }]*/ +/*eslint-env node*/ + +var foo = require("foo"); +var bar = "bar"; +``` + +```js +var foo = require("foo"), + bar = require("bar"); +``` + +Examples of **incorrect** code for this rule with the `{ var: "never", let: "consecutive", const: "consecutive" }` option: + +```js +/*eslint one-var: ["error", { var: "never", let: "consecutive", const: "consecutive" }]*/ +/*eslint-env es6*/ + +function foo() { + let a, + b; + let c; + + var d, + e; +} + +function foo() { + const a = 1, + b = 2; + const c = 3; + + var d, + e; +} +``` + +Examples of **correct** code for this rule with the `{ var: "never", let: "consecutive", const: "consecutive" }` option: + +```js +/*eslint one-var: ["error", { var: "never", let: "consecutive", const: "consecutive" }]*/ +/*eslint-env es6*/ + +function foo() { + let a, + b; + + var d; + var e; + + let f; +} + +function foo() { + const a = 1, + b = 2; + + var c; + var d; + + const e = 3; +} +``` + +Examples of **incorrect** code for this rule with the `{ var: "consecutive" }` option: + +```js +/*eslint one-var: ["error", { var: "consecutive" }]*/ +/*eslint-env es6*/ + +function foo() { + var a; + var b; +} +``` + +Examples of **correct** code for this rule with the `{ var: "consecutive" }` option: + +```js +/*eslint one-var: ["error", { var: "consecutive" }]*/ +/*eslint-env es6*/ + +function foo() { + var a, + b; + const c = 1; // `const` and `let` declarations are ignored if they are not specified + const d = 2; + let e; + let f; +} +``` + +### initialized and uninitialized + +Examples of **incorrect** code for this rule with the `{ "initialized": "always", "uninitialized": "never" }` option: + +```js +/*eslint one-var: ["error", { "initialized": "always", "uninitialized": "never" }]*/ +/*eslint-env es6*/ + +function foo() { + var a, b, c; + var foo = true; + var bar = false; +} +``` + +Examples of **correct** code for this rule with the `{ "initialized": "always", "uninitialized": "never" }` option: + +```js +/*eslint one-var: ["error", { "initialized": "always", "uninitialized": "never" }]*/ + +function foo() { + var a; + var b; + var c; + var foo = true, + bar = false; +} + +for (let z of foo) { + doSomething(z); +} + +let z; +for (z of foo) { + doSomething(z); +} +``` + +Examples of **incorrect** code for this rule with the `{ "initialized": "never" }` option: + +```js +/*eslint one-var: ["error", { "initialized": "never" }]*/ +/*eslint-env es6*/ + +function foo() { + var foo = true, + bar = false; +} +``` + +Examples of **correct** code for this rule with the `{ "initialized": "never" }` option: + +```js +/*eslint one-var: ["error", { "initialized": "never" }]*/ + +function foo() { + var foo = true; + var bar = false; + var a, b, c; // Uninitialized variables are ignored +} +``` + +Examples of **incorrect** code for this rule with the `{ "initialized": "consecutive", "uninitialized": "never" }` option: + +```js +/*eslint one-var: ["error", { "initialized": "consecutive", "uninitialized": "never" }]*/ + +function foo() { + var a = 1; + var b = 2; + var c, + d; + var e = 3; + var f = 4; +} +``` + +Examples of **correct** code for this rule with the `{ "initialized": "consecutive", "uninitialized": "never" }` option: + +```js +/*eslint one-var: ["error", { "initialized": "consecutive", "uninitialized": "never" }]*/ + +function foo() { + var a = 1, + b = 2; + var c; + var d; + var e = 3, + f = 4; +} +``` + +Examples of **incorrect** code for this rule with the `{ "initialized": "consecutive" }` option: + +```js +/*eslint one-var: ["error", { "initialized": "consecutive" }]*/ + +function foo() { + var a = 1; + var b = 2; + + foo(); + + var c = 3; + var d = 4; +} +``` + +Examples of **correct** code for this rule with the `{ "initialized": "consecutive" }` option: + +```js +/*eslint one-var: ["error", { "initialized": "consecutive" }]*/ + +function foo() { + var a = 1, + b = 2; + + foo(); + + var c = 3, + d = 4; +} +``` + +## Compatibility + +* **JSHint**: This rule maps to the `onevar` JSHint rule, but allows `let` and `const` to be configured separately. +* **JSCS**: This rule roughly maps to [disallowMultipleVarDecl](https://jscs-dev.github.io/rule/disallowMultipleVarDecl). +* **JSCS**: This rule option `separateRequires` roughly maps to [requireMultipleVarDecl](https://jscs-dev.github.io/rule/requireMultipleVarDecl). + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/one-var.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/one-var.md) diff --git a/docs/8.0.0/rules/operator-assignment.md b/docs/8.0.0/rules/operator-assignment.md new file mode 100644 index 0000000000..b08500d78c --- /dev/null +++ b/docs/8.0.0/rules/operator-assignment.md @@ -0,0 +1,103 @@ +--- +title: operator-assignment - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/operator-assignment.md +rule_type: suggestion +--- + + +# require or disallow assignment operator shorthand where possible (operator-assignment) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +JavaScript provides shorthand operators that combine variable assignment and some simple mathematical operations. For example, `x = x + 4` can be shortened to `x += 4`. The supported shorthand forms are as follows: + +```text + Shorthand | Separate +-----------|------------ + x += y | x = x + y + x -= y | x = x - y + x *= y | x = x * y + x /= y | x = x / y + x %= y | x = x % y + x **= y | x = x ** y + x <<= y | x = x << y + x >>= y | x = x >> y + x >>>= y | x = x >>> y + x &= y | x = x & y + x ^= y | x = x ^ y + x |= y | x = x | y +``` + +## Rule Details + +This rule requires or disallows assignment operator shorthand where possible. + +The rule applies to the operators listed in the above table. It does not report the logical assignment operators `&&=`, `||=`, and `??=` because their short-circuiting behavior is different from the other assignment operators. + +## Options + +This rule has a single string option: + +* `"always"` (default) requires assignment operator shorthand where possible +* `"never"` disallows assignment operator shorthand + +### always + +Examples of **incorrect** code for this rule with the default `"always"` option: + +```js +/*eslint operator-assignment: ["error", "always"]*/ + +x = x + y; +x = y * x; +x[0] = x[0] / y; +x.y = x.y << z; +``` + +Examples of **correct** code for this rule with the default `"always"` option: + +```js +/*eslint operator-assignment: ["error", "always"]*/ + +x = y; +x += y; +x = y * z; +x = (x * y) * z; +x[0] /= y; +x[foo()] = x[foo()] % 2; +x = y + x; // `+` is not always commutative (e.g. x = "abc") +``` + +### never + +Examples of **incorrect** code for this rule with the `"never"` option: + +```js +/*eslint operator-assignment: ["error", "never"]*/ + +x *= y; +x ^= (y + z) / foo(); +``` + +Examples of **correct** code for this rule with the `"never"` option: + +```js +/*eslint operator-assignment: ["error", "never"]*/ + +x = x + y; +x.y = x.y / a.b; +``` + +## When Not To Use It + +Use of operator assignment shorthand is a stylistic choice. Leaving this rule turned off would allow developers to choose which style is more readable on a case-by-case basis. + +## Version + +This rule was introduced in ESLint 0.10.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/operator-assignment.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/operator-assignment.md) diff --git a/docs/8.0.0/rules/operator-linebreak.md b/docs/8.0.0/rules/operator-linebreak.md new file mode 100644 index 0000000000..5669545a8e --- /dev/null +++ b/docs/8.0.0/rules/operator-linebreak.md @@ -0,0 +1,355 @@ +--- +title: operator-linebreak - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/operator-linebreak.md +rule_type: layout +--- + + +# enforce consistent linebreak style for operators (operator-linebreak) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +When a statement is too long to fit on a single line, line breaks are generally inserted next to the operators separating expressions. The first style coming to mind would be to place the operator at the end of the line, following the English punctuation rules. + +```js +var fullHeight = borderTop + + innerHeight + + borderBottom; +``` + +Some developers find that placing operators at the beginning of the line makes the code more readable. + +```js +var fullHeight = borderTop + + innerHeight + + borderBottom; +``` + +## Rule Details + +This rule enforces a consistent linebreak style for operators. + +## Options + +This rule has two options, a string option and an object option. + +String option: + +* `"after"` requires linebreaks to be placed after the operator +* `"before"` requires linebreaks to be placed before the operator +* `"none"` disallows linebreaks on either side of the operator + +Object option: + +* `"overrides"` overrides the global setting for specified operators + +The default configuration is `"after", { "overrides": { "?": "before", ":": "before" } }` + +### after + +Examples of **incorrect** code for this rule with the `"after"` option: + +```js +/*eslint operator-linebreak: ["error", "after"]*/ + +foo = 1 ++ +2; + +foo = 1 + + 2; + +foo + = 5; + +if (someCondition + || otherCondition) { +} + +answer = everything + ? 42 + : foo; + +class Foo { + a + = 1; + [b] + = 2; + [c + ] + = 3; +} +``` + +Examples of **correct** code for this rule with the `"after"` option: + +```js +/*eslint operator-linebreak: ["error", "after"]*/ + +foo = 1 + 2; + +foo = 1 + + 2; + +foo = + 5; + +if (someCondition || + otherCondition) { +} + +answer = everything ? + 42 : + foo; + +class Foo { + a = + 1; + [b] = + 2; + [c + ] = + 3; + d = 4; +} +``` + +### before + +Examples of **incorrect** code for this rule with the `"before"` option: + +```js +/*eslint operator-linebreak: ["error", "before"]*/ + +foo = 1 + + 2; + +foo = + 5; + +if (someCondition || + otherCondition) { +} + +answer = everything ? + 42 : + foo; + +class Foo { + a = + 1; + [b] = + 2; + [c + ] = + 3; +} +``` + +Examples of **correct** code for this rule with the `"before"` option: + +```js +/*eslint operator-linebreak: ["error", "before"]*/ + +foo = 1 + 2; + +foo = 1 + + 2; + +foo + = 5; + +if (someCondition + || otherCondition) { +} + +answer = everything + ? 42 + : foo; + +class Foo { + a + = 1; + [b] + = 2; + [c + ] + = 3; + d = 4; +} +``` + +### none + +Examples of **incorrect** code for this rule with the `"none"` option: + +```js +/*eslint operator-linebreak: ["error", "none"]*/ + +foo = 1 + + 2; + +foo = 1 + + 2; + +if (someCondition || + otherCondition) { +} + +if (someCondition + || otherCondition) { +} + +answer = everything + ? 42 + : foo; + +answer = everything ? + 42 : + foo; + +class Foo { + a = + 1; + [b] = + 2; + [c + ] = + 3; + d + = 4; + [e] + = 5; + [f + ] + = 6; +} +``` + +Examples of **correct** code for this rule with the `"none"` option: + +```js +/*eslint operator-linebreak: ["error", "none"]*/ + +foo = 1 + 2; + +foo = 5; + +if (someCondition || otherCondition) { +} + +answer = everything ? 42 : foo; + +class Foo { + a = 1; + [b] = 2; + [c + ] = 3; + d = 4; + [e] = 5; + [f + ] = 6; +} +``` + +### overrides + +Examples of additional **incorrect** code for this rule with the `{ "overrides": { "+=": "before" } }` option: + +```js +/*eslint operator-linebreak: ["error", "after", { "overrides": { "+=": "before" } }]*/ + +var thing = 'thing'; +thing += + 's'; +``` + +Examples of additional **correct** code for this rule with the `{ "overrides": { "+=": "before" } }` option: + +```js +/*eslint operator-linebreak: ["error", "after", { "overrides": { "+=": "before" } }]*/ + +var thing = 'thing'; +thing + += 's'; +``` + +Examples of additional **correct** code for this rule with the `{ "overrides": { "?": "ignore", ":": "ignore" } }` option: + +```js +/*eslint operator-linebreak: ["error", "after", { "overrides": { "?": "ignore", ":": "ignore" } }]*/ + +answer = everything ? + 42 + : foo; + +answer = everything + ? + 42 + : + foo; +``` + +Examples of **incorrect** code for this rule with the default `"after", { "overrides": { "?": "before", ":": "before" } }` option: + +```js +/*eslint operator-linebreak: ["error", "after", { "overrides": { "?": "before", ":": "before" } }]*/ + +foo = 1 ++ +2; + +foo = 1 + + 2; + +foo + = 5; + +if (someCondition + || otherCondition) { +} + +answer = everything ? + 42 : + foo; +``` + +Examples of **correct** code for this rule with the default `"after", { "overrides": { "?": "before", ":": "before" } }` option: + +```js +/*eslint operator-linebreak: ["error", "after", { "overrides": { "?": "before", ":": "before" } }]*/ + +foo = 1 + 2; + +foo = 1 + + 2; + +foo = + 5; + +if (someCondition || + otherCondition) { +} + +answer = everything + ? 42 + : foo; +``` + +## When Not To Use It + +If your project will not be using a common operator line break style, turn this rule off. + +## Related Rules + +* [comma-style](comma-style) + +## Version + +This rule was introduced in ESLint 0.19.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/operator-linebreak.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/operator-linebreak.md) diff --git a/docs/8.0.0/rules/padded-blocks.md b/docs/8.0.0/rules/padded-blocks.md new file mode 100644 index 0000000000..30ab61d534 --- /dev/null +++ b/docs/8.0.0/rules/padded-blocks.md @@ -0,0 +1,418 @@ +--- +title: padded-blocks - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/padded-blocks.md +rule_type: layout +--- + + +# require or disallow padding within blocks (padded-blocks) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +Some style guides require block statements to start and end with blank lines. The goal is +to improve readability by visually separating the block content and the surrounding code. + +```js +if (a) { + + b(); + +} +``` + +Since it's good to have a consistent code style, you should either always write +padded blocks or never do it. + +## Rule Details + +This rule enforces consistent empty line padding within blocks. + +## Options + +This rule has two options, the first one can be a string option or an object option. +The second one is an object option, it can allow exceptions. + +### First option + +String option: + +* `"always"` (default) requires empty lines at the beginning and ending of block statements and classes +* `"never"` disallows empty lines at the beginning and ending of block statements and classes + +Object option: + +* `"blocks"` require or disallow padding within block statements +* `"classes"` require or disallow padding within classes +* `"switches"` require or disallow padding within `switch` statements + +### Second option + +* `"allowSingleLineBlocks": true` allows single-line blocks + +### always + +Examples of **incorrect** code for this rule with the default `"always"` option: + +```js +/*eslint padded-blocks: ["error", "always"]*/ + +if (a) { + b(); +} + +if (a) { b(); } + +if (a) +{ + b(); +} + +if (a) { + b(); + +} + +if (a) { + // comment + b(); + +} +``` + +Examples of **correct** code for this rule with the default `"always"` option: + +```js +/*eslint padded-blocks: ["error", "always"]*/ + +if (a) { + + b(); + +} + +if (a) +{ + + b(); + +} + +if (a) { + + // comment + b(); + +} +``` + +### never + +Examples of **incorrect** code for this rule with the `"never"` option: + +```js +/*eslint padded-blocks: ["error", "never"]*/ + +if (a) { + + b(); + +} + +if (a) +{ + + b(); + +} + +if (a) { + + b(); +} + +if (a) { + b(); + +} +``` + +Examples of **correct** code for this rule with the `"never"` option: + +```js +/*eslint padded-blocks: ["error", "never"]*/ + +if (a) { + b(); +} + +if (a) +{ + b(); +} +``` + +### blocks + +Examples of **incorrect** code for this rule with the `{ "blocks": "always" }` option: + +```js +/*eslint padded-blocks: ["error", { "blocks": "always" }]*/ + +if (a) { + b(); +} + +if (a) { b(); } + +if (a) +{ + b(); +} + +if (a) { + + b(); +} + +if (a) { + b(); + +} + +if (a) { + // comment + b(); + +} +``` + +Examples of **correct** code for this rule with the `{ "blocks": "always" }` option: + +```js +/*eslint padded-blocks: ["error", { "blocks": "always" }]*/ + +if (a) { + + b(); + +} + +if (a) +{ + + b(); + +} + +if (a) { + + // comment + b(); + +} +``` + +Examples of **incorrect** code for this rule with the `{ "blocks": "never" }` option: + +```js +/*eslint padded-blocks: ["error", { "blocks": "never" }]*/ + +if (a) { + + b(); + +} + +if (a) +{ + + b(); + +} + +if (a) { + + b(); +} + +if (a) { + b(); + +} +``` + +Examples of **correct** code for this rule with the `{ "blocks": "never" }` option: + +```js +/*eslint padded-blocks: ["error", { "blocks": "never" }]*/ + +if (a) { + b(); +} + +if (a) +{ + b(); +} +``` + +### classes + +Examples of **incorrect** code for this rule with the `{ "classes": "always" }` option: + +```js +/*eslint padded-blocks: ["error", { "classes": "always" }]*/ + +class A { + constructor(){ + } +} +``` + +Examples of **correct** code for this rule with the `{ "classes": "always" }` option: + +```js +/*eslint padded-blocks: ["error", { "classes": "always" }]*/ + +class A { + + constructor(){ + } + +} +``` + +Examples of **incorrect** code for this rule with the `{ "classes": "never" }` option: + +```js +/*eslint padded-blocks: ["error", { "classes": "never" }]*/ + +class A { + + constructor(){ + } + +} +``` + +Examples of **correct** code for this rule with the `{ "classes": "never" }` option: + +```js +/*eslint padded-blocks: ["error", { "classes": "never" }]*/ + +class A { + constructor(){ + } +} +``` + +### switches + +Examples of **incorrect** code for this rule with the `{ "switches": "always" }` option: + +```js +/*eslint padded-blocks: ["error", { "switches": "always" }]*/ + +switch (a) { + case 0: foo(); +} +``` + +Examples of **correct** code for this rule with the `{ "switches": "always" }` option: + +```js +/*eslint padded-blocks: ["error", { "switches": "always" }]*/ + +switch (a) { + + case 0: foo(); + +} + +if (a) { + b(); +} +``` + +Examples of **incorrect** code for this rule with the `{ "switches": "never" }` option: + +```js +/*eslint padded-blocks: ["error", { "switches": "never" }]*/ + +switch (a) { + + case 0: foo(); + +} +``` + +Examples of **correct** code for this rule with the `{ "switches": "never" }` option: + +```js +/*eslint padded-blocks: ["error", { "switches": "never" }]*/ + +switch (a) { + case 0: foo(); +} + +if (a) { + + b(); + +} +``` + +### always + allowSingleLineBlocks + +Examples of **incorrect** code for this rule with the `"always", {"allowSingleLineBlocks": true}` options: + +```js +/*eslint padded-blocks: ["error", "always", { allowSingleLineBlocks: true }]*/ + +if (a) { + b(); +} + +if (a) { + + b(); +} + +if (a) { + b(); + +} +``` + +Examples of **correct** code for this rule with the `"always", {"allowSingleLineBlocks": true}` options: + +```js +/*eslint padded-blocks: ["error", "always", { allowSingleLineBlocks: true }]*/ + +if (a) { b(); } + +if (a) { + + b(); + +} +``` + +## When Not To Use It + +You can turn this rule off if you are not concerned with the consistency of padding within blocks. + +## Related Rules + +* [lines-between-class-members](lines-between-class-members) +* [padding-line-between-statements](padding-line-between-statements) + +## Version + +This rule was introduced in ESLint 0.9.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/padded-blocks.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/padded-blocks.md) diff --git a/docs/8.0.0/rules/padding-line-between-statements.md b/docs/8.0.0/rules/padding-line-between-statements.md new file mode 100644 index 0000000000..99f1fadd36 --- /dev/null +++ b/docs/8.0.0/rules/padding-line-between-statements.md @@ -0,0 +1,310 @@ +--- +title: padding-line-between-statements - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/padding-line-between-statements.md +rule_type: layout +--- + + +# Require or disallow padding lines between statements (padding-line-between-statements) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +This rule requires or disallows blank lines between the given 2 kinds of statements. +Properly blank lines help developers to understand the code. + +For example, the following configuration requires a blank line between a variable declaration and a `return` statement. + +```js +/*eslint padding-line-between-statements: [ + "error", + { blankLine: "always", prev: "var", next: "return" } +]*/ + +function foo() { + var a = 1; + + return a; +} +``` + +## Rule Details + +This rule does nothing if no configurations are provided. + +A configuration is an object which has 3 properties; `blankLine`, `prev` and `next`. For example, `{ blankLine: "always", prev: "var", next: "return" }` means "one or more blank lines are required between a variable declaration and a `return` statement." +You can supply any number of configurations. If a statement pair matches multiple configurations, the last matched configuration will be used. + +```json +{ + "padding-line-between-statements": [ + "error", + { "blankLine": LINEBREAK_TYPE, "prev": STATEMENT_TYPE, "next": STATEMENT_TYPE }, + { "blankLine": LINEBREAK_TYPE, "prev": STATEMENT_TYPE, "next": STATEMENT_TYPE }, + { "blankLine": LINEBREAK_TYPE, "prev": STATEMENT_TYPE, "next": STATEMENT_TYPE }, + { "blankLine": LINEBREAK_TYPE, "prev": STATEMENT_TYPE, "next": STATEMENT_TYPE }, + ... + ] +} +``` + +- `LINEBREAK_TYPE` is one of the following. + - `"any"` just ignores the statement pair. + - `"never"` disallows blank lines. + - `"always"` requires one or more blank lines. Note it does not count lines that comments exist as blank lines. + +- `STATEMENT_TYPE` is one of the following, or an array of the following. + - `"*"` is wildcard. This matches any statements. + - `"block"` is lonely blocks. + - `"block-like"` is block like statements. This matches statements that the last token is the closing brace of blocks; e.g. `{ }`, `if (a) { }`, and `while (a) { }`. Also matches immediately invoked function expression statements. + - `"break"` is `break` statements. + - `"case"` is `case` clauses in `switch` statements. + - `"cjs-export"` is `export` statements of CommonJS; e.g. `module.exports = 0`, `module.exports.foo = 1`, and `exports.foo = 2`. This is a special case of assignment. + - `"cjs-import"` is `import` statements of CommonJS; e.g. `const foo = require("foo")`. This is a special case of variable declarations. + - `"class"` is `class` declarations. + - `"const"` is `const` variable declarations, both single-line and multiline. + - `"continue"` is `continue` statements. + - `"debugger"` is `debugger` statements. + - `"default"` is `default` clauses in `switch` statements. + - `"directive"` is directive prologues. This matches directives; e.g. `"use strict"`. + - `"do"` is `do-while` statements. This matches all statements that the first token is `do` keyword. + - `"empty"` is empty statements. + - `"export"` is `export` declarations. + - `"expression"` is expression statements. + - `"for"` is `for` loop families. This matches all statements that the first token is `for` keyword. + - `"function"` is function declarations. + - `"if"` is `if` statements. + - `"iife"` is immediately invoked function expression statements. This matches calls on a function expression, optionally prefixed with a unary operator. + - `"import"` is `import` declarations. + - `"let"` is `let` variable declarations, both single-line and multiline. + - `"multiline-block-like"` is block like statements. This is the same as `block-like` type, but only if the block is multiline. + - `"multiline-const"` is multiline `const` variable declarations. + - `"multiline-expression"` is expression statements. This is the same as `expression` type, but only if the statement is multiline. + - `"multiline-let"` is multiline `let` variable declarations. + - `"multiline-var"` is multiline `var` variable declarations. + - `"return"` is `return` statements. + - `"singleline-const"` is single-line `const` variable declarations. + - `"singleline-let"` is single-line `let` variable declarations. + - `"singleline-var"` is single-line `var` variable declarations. + - `"switch"` is `switch` statements. + - `"throw"` is `throw` statements. + - `"try"` is `try` statements. + - `"var"` is `var` variable declarations, both single-line and multiline. + - `"while"` is `while` loop statements. + - `"with"` is `with` statements. + +## Examples + +This configuration would require blank lines before all `return` statements, like the [newline-before-return] rule. + +Examples of **incorrect** code for the `[{ blankLine: "always", prev: "*", next: "return" }]` configuration: + +```js +/*eslint padding-line-between-statements: [ + "error", + { blankLine: "always", prev: "*", next: "return" } +]*/ + +function foo() { + bar(); + return; +} +``` + +Examples of **correct** code for the `[{ blankLine: "always", prev: "*", next: "return" }]` configuration: + +```js +/*eslint padding-line-between-statements: [ + "error", + { blankLine: "always", prev: "*", next: "return" } +]*/ + +function foo() { + bar(); + + return; +} + +function foo() { + return; +} +``` + +---- + +This configuration would require blank lines after every sequence of variable declarations, like the [newline-after-var] rule. + +Examples of **incorrect** code for the `[{ blankLine: "always", prev: ["const", "let", "var"], next: "*"}, { blankLine: "any", prev: ["const", "let", "var"], next: ["const", "let", "var"]}]` configuration: + +```js +/*eslint padding-line-between-statements: [ + "error", + { blankLine: "always", prev: ["const", "let", "var"], next: "*"}, + { blankLine: "any", prev: ["const", "let", "var"], next: ["const", "let", "var"]} +]*/ + +function foo() { + var a = 0; + bar(); +} + +function foo() { + let a = 0; + bar(); +} + +function foo() { + const a = 0; + bar(); +} +``` + +Examples of **correct** code for the `[{ blankLine: "always", prev: ["const", "let", "var"], next: "*"}, { blankLine: "any", prev: ["const", "let", "var"], next: ["const", "let", "var"]}]` configuration: + +```js +/*eslint padding-line-between-statements: [ + "error", + { blankLine: "always", prev: ["const", "let", "var"], next: "*"}, + { blankLine: "any", prev: ["const", "let", "var"], next: ["const", "let", "var"]} +]*/ + +function foo() { + var a = 0; + var b = 0; + + bar(); +} + +function foo() { + let a = 0; + const b = 0; + + bar(); +} + +function foo() { + const a = 0; + const b = 0; + + bar(); +} +``` + +---- + +This configuration would require blank lines after all directive prologues, like the [lines-around-directive] rule. + +Examples of **incorrect** code for the `[{ blankLine: "always", prev: "directive", next: "*" }, { blankLine: "any", prev: "directive", next: "directive" }]` configuration: + +```js +/*eslint padding-line-between-statements: [ + "error", + { blankLine: "always", prev: "directive", next: "*" }, + { blankLine: "any", prev: "directive", next: "directive" } +]*/ + +"use strict"; +foo(); +``` + +Examples of **correct** code for the `[{ blankLine: "always", prev: "directive", next: "*" }, { blankLine: "any", prev: "directive", next: "directive" }]` configuration: + +```js +/*eslint padding-line-between-statements: [ + "error", + { blankLine: "always", prev: "directive", next: "*" }, + { blankLine: "any", prev: "directive", next: "directive" } +]*/ + +"use strict"; +"use asm"; + +foo(); +``` + +---- + +This configuration would require blank lines between clauses in `switch` statements. + +Examples of **incorrect** code for the `[{ blankLine: "always", prev: ["case", "default"], next: "*" }]` configuration: + +```js +/*eslint padding-line-between-statements: [ + "error", + { blankLine: "always", prev: ["case", "default"], next: "*" } +]*/ + +switch (foo) { + case 1: + bar(); + break; + case 2: + case 3: + baz(); + break; + default: + quux(); +} +``` + +Examples of **correct** code for the `[{ blankLine: "always", prev: ["case", "default"], next: "*" }]` configuration: + +```js +/*eslint padding-line-between-statements: [ + "error", + { blankLine: "always", prev: ["case", "default"], next: "*" } +]*/ + +switch (foo) { + case 1: + bar(); + break; + + case 2: + + case 3: + baz(); + break; + + default: + quux(); +} +``` + +## Compatibility + +- **JSCS:** [requirePaddingNewLineAfterVariableDeclaration] +- **JSCS:** [requirePaddingNewLinesAfterBlocks] +- **JSCS:** [disallowPaddingNewLinesAfterBlocks] +- **JSCS:** [requirePaddingNewLinesAfterUseStrict] +- **JSCS:** [disallowPaddingNewLinesAfterUseStrict] +- **JSCS:** [requirePaddingNewLinesBeforeExport] +- **JSCS:** [disallowPaddingNewLinesBeforeExport] +- **JSCS:** [requirePaddingNewlinesBeforeKeywords] +- **JSCS:** [disallowPaddingNewlinesBeforeKeywords] + +## When Not To Use It + +If you don't want to notify warnings about linebreaks, then it's safe to disable this rule. + +[lines-around-directive]: https://eslint.org/docs/rules/lines-around-directive +[newline-after-var]: https://eslint.org/docs/rules/newline-after-var +[newline-before-return]: https://eslint.org/docs/rules/newline-before-return +[requirePaddingNewLineAfterVariableDeclaration]: https://jscs-dev.github.io/rule/requirePaddingNewLineAfterVariableDeclaration +[requirePaddingNewLinesAfterBlocks]: https://jscs-dev.github.io/rule/requirePaddingNewLinesAfterBlocks +[disallowPaddingNewLinesAfterBlocks]: https://jscs-dev.github.io/rule/disallowPaddingNewLinesAfterBlocks +[requirePaddingNewLinesAfterUseStrict]: https://jscs-dev.github.io/rule/requirePaddingNewLinesAfterUseStrict +[disallowPaddingNewLinesAfterUseStrict]: https://jscs-dev.github.io/rule/disallowPaddingNewLinesAfterUseStrict +[requirePaddingNewLinesBeforeExport]: https://jscs-dev.github.io/rule/requirePaddingNewLinesBeforeExport +[disallowPaddingNewLinesBeforeExport]: https://jscs-dev.github.io/rule/disallowPaddingNewLinesBeforeExport +[requirePaddingNewlinesBeforeKeywords]: https://jscs-dev.github.io/rule/requirePaddingNewlinesBeforeKeywords +[disallowPaddingNewlinesBeforeKeywords]: https://jscs-dev.github.io/rule/disallowPaddingNewlinesBeforeKeywords + +## Version + +This rule was introduced in ESLint 4.0.0-beta.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/padding-line-between-statements.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/padding-line-between-statements.md) diff --git a/docs/8.0.0/rules/prefer-arrow-callback.md b/docs/8.0.0/rules/prefer-arrow-callback.md new file mode 100644 index 0000000000..ac10b7e04f --- /dev/null +++ b/docs/8.0.0/rules/prefer-arrow-callback.md @@ -0,0 +1,119 @@ +--- +title: prefer-arrow-callback - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/prefer-arrow-callback.md +rule_type: suggestion +--- + + +# Require using arrow functions for callbacks (prefer-arrow-callback) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +Arrow functions can be an attractive alternative to function expressions for callbacks or function arguments. + +For example, arrow functions are automatically bound to their surrounding scope/context. This provides an alternative to the pre-ES6 standard of explicitly binding function expressions to achieve similar behavior. + +Additionally, arrow functions are: + +- less verbose, and easier to reason about. + +- bound lexically regardless of where or when they are invoked. + +## Rule Details + +This rule locates function expressions used as callbacks or function arguments. An error will be produced for any that could be replaced by an arrow function without changing the result. + +The following examples **will** be flagged: + +```js +/* eslint prefer-arrow-callback: "error" */ + +foo(function(a) { return a; }); // ERROR +// prefer: foo(a => a) + +foo(function() { return this.a; }.bind(this)); // ERROR +// prefer: foo(() => this.a) +``` + +Instances where an arrow function would not produce identical results will be ignored. + +The following examples **will not** be flagged: + +```js +/* eslint prefer-arrow-callback: "error" */ +/* eslint-env es6 */ + +// arrow function callback +foo(a => a); // OK + +// generator as callback +foo(function*() { yield; }); // OK + +// function expression not used as callback or function argument +var foo = function foo(a) { return a; }; // OK + +// unbound function expression callback +foo(function() { return this.a; }); // OK + +// recursive named function callback +foo(function bar(n) { return n && n + bar(n - 1); }); // OK +``` + +## Options + +Access further control over this rule's behavior via an options object. + +Default: `{ allowNamedFunctions: false, allowUnboundThis: true }` + +### allowNamedFunctions + +By default `{ "allowNamedFunctions": false }`, this `boolean` option prohibits using named functions as callbacks or function arguments. + +Changing this value to `true` will reverse this option's behavior by allowing use of named functions without restriction. + +`{ "allowNamedFunctions": true }` **will not** flag the following example: + +```js +/* eslint prefer-arrow-callback: [ "error", { "allowNamedFunctions": true } ] */ + +foo(function bar() {}); +``` + +### allowUnboundThis + +By default `{ "allowUnboundThis": true }`, this `boolean` option allows function expressions containing `this` to be used as callbacks, as long as the function in question has not been explicitly bound. + +When set to `false` this option prohibits the use of function expressions as callbacks or function arguments entirely, without exception. + +`{ "allowUnboundThis": false }` **will** flag the following examples: + +```js +/* eslint prefer-arrow-callback: [ "error", { "allowUnboundThis": false } ] */ +/* eslint-env es6 */ + +foo(function() { this.a; }); + +foo(function() { (() => this); }); + +someArray.map(function(item) { return this.doSomething(item); }, someObject); +``` + +## When Not To Use It + +- In environments that have not yet adopted ES6 language features (ES3/5). + +- In ES6+ environments that allow the use of function expressions when describing callbacks or function arguments. + +## Further Reading + +- [More on ES6 arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) + +## Version + +This rule was introduced in ESLint 1.2.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/prefer-arrow-callback.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/prefer-arrow-callback.md) diff --git a/docs/8.0.0/rules/prefer-const.md b/docs/8.0.0/rules/prefer-const.md new file mode 100644 index 0000000000..ea9fafc8e1 --- /dev/null +++ b/docs/8.0.0/rules/prefer-const.md @@ -0,0 +1,224 @@ +--- +title: prefer-const - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/prefer-const.md +rule_type: suggestion +--- + + +# Suggest using `const` (prefer-const) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +If a variable is never reassigned, using the `const` declaration is better. + +`const` declaration tells readers, "this variable is never reassigned," reducing cognitive load and improving maintainability. + +## Rule Details + +This rule is aimed at flagging variables that are declared using `let` keyword, but never reassigned after the initial assignment. + +Examples of **incorrect** code for this rule: + +```js +/*eslint prefer-const: "error"*/ +/*eslint-env es6*/ + +// it's initialized and never reassigned. +let a = 3; +console.log(a); + +let a; +a = 0; +console.log(a); + +// `i` is redefined (not reassigned) on each loop step. +for (let i in [1, 2, 3]) { + console.log(i); +} + +// `a` is redefined (not reassigned) on each loop step. +for (let a of [1, 2, 3]) { + console.log(a); +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint prefer-const: "error"*/ +/*eslint-env es6*/ + +// using const. +const a = 0; + +// it's never initialized. +let a; +console.log(a); + +// it's reassigned after initialized. +let a; +a = 0; +a = 1; +console.log(a); + +// it's initialized in a different block from the declaration. +let a; +if (true) { + a = 0; +} +console.log(a); + +// it's initialized at a place that we cannot write a variable declaration. +let a; +if (true) a = 0; +console.log(a); + +// `i` gets a new binding each iteration +for (const i in [1, 2, 3]) { + console.log(i); +} + +// `a` gets a new binding each iteration +for (const a of [1, 2, 3]) { + console.log(a); +} + +// `end` is never reassigned, but we cannot separate the declarations without modifying the scope. +for (let i = 0, end = 10; i < end; ++i) { + console.log(a); +} + +// `predicate` is only assigned once but cannot be separately declared as `const` +let predicate; +[object.type, predicate] = foo(); + +// `a` is only assigned once but cannot be separately declared as `const` +let a; +const b = {}; +({ a, c: b.c } = func()); + +// suggest to use `no-var` rule. +var b = 3; +console.log(b); +``` + +## Options + +```json +{ + "prefer-const": ["error", { + "destructuring": "any", + "ignoreReadBeforeAssign": false + }] +} +``` + +### destructuring + +The kind of the way to address variables in destructuring. +There are 2 values: + +* `"any"` (default) - If any variables in destructuring should be `const`, this rule warns for those variables. +* `"all"` - If all variables in destructuring should be `const`, this rule warns the variables. Otherwise, ignores them. + +Examples of **incorrect** code for the default `{"destructuring": "any"}` option: + +```js +/*eslint prefer-const: "error"*/ +/*eslint-env es6*/ + +let {a, b} = obj; /*error 'b' is never reassigned, use 'const' instead.*/ +a = a + 1; +``` + +Examples of **correct** code for the default `{"destructuring": "any"}` option: + +```js +/*eslint prefer-const: "error"*/ +/*eslint-env es6*/ + +// using const. +const {a: a0, b} = obj; +const a = a0 + 1; + +// all variables are reassigned. +let {a, b} = obj; +a = a + 1; +b = b + 1; +``` + +Examples of **incorrect** code for the `{"destructuring": "all"}` option: + +```js +/*eslint prefer-const: ["error", {"destructuring": "all"}]*/ +/*eslint-env es6*/ + +// all of `a` and `b` should be const, so those are warned. +let {a, b} = obj; /*error 'a' is never reassigned, use 'const' instead. + 'b' is never reassigned, use 'const' instead.*/ +``` + +Examples of **correct** code for the `{"destructuring": "all"}` option: + +```js +/*eslint prefer-const: ["error", {"destructuring": "all"}]*/ +/*eslint-env es6*/ + +// 'b' is never reassigned, but all of `a` and `b` should not be const, so those are ignored. +let {a, b} = obj; +a = a + 1; +``` + +### ignoreReadBeforeAssign + +This is an option to avoid conflicting with `no-use-before-define` rule (without `"nofunc"` option). +If `true` is specified, this rule will ignore variables that are read between the declaration and the first assignment. +Default is `false`. + +Examples of **correct** code for the `{"ignoreReadBeforeAssign": true}` option: + +```js +/*eslint prefer-const: ["error", {"ignoreReadBeforeAssign": true}]*/ +/*eslint-env es6*/ + +let timer; +function initialize() { + if (foo()) { + clearInterval(timer); + } +} +timer = setInterval(initialize, 100); +``` + +Examples of **correct** code for the default `{"ignoreReadBeforeAssign": false}` option: + +```js +/*eslint prefer-const: ["error", {"ignoreReadBeforeAssign": false}]*/ +/*eslint-env es6*/ + +const timer = setInterval(initialize, 100); +function initialize() { + if (foo()) { + clearInterval(timer); + } +} +``` + +## When Not To Use It + +If you don't want to be notified about variables that are never reassigned after initial assignment, you can safely disable this rule. + +## Related Rules + +* [no-var](no-var) +* [no-use-before-define](no-use-before-define) + +## Version + +This rule was introduced in ESLint 0.23.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/prefer-const.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/prefer-const.md) diff --git a/docs/8.0.0/rules/prefer-destructuring.md b/docs/8.0.0/rules/prefer-destructuring.md new file mode 100644 index 0000000000..7b865ed4a0 --- /dev/null +++ b/docs/8.0.0/rules/prefer-destructuring.md @@ -0,0 +1,207 @@ +--- +title: prefer-destructuring - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/prefer-destructuring.md +rule_type: suggestion +--- + + +# Prefer destructuring from arrays and objects (prefer-destructuring) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +With JavaScript ES6, a new syntax was added for creating variables from an array index or object property, called [destructuring](#further-reading). This rule enforces usage of destructuring instead of accessing a property through a member expression. + +## Rule Details + +### Options + +This rule takes two sets of configuration objects. The first object parameter determines what types of destructuring the rule applies to. + +The two properties, `array` and `object`, can be used to turn on or off the destructuring requirement for each of those types independently. By default, both are true. + +Alternatively, you can use separate configurations for different assignment types. It accepts 2 other keys instead of `array` and `object`. + +One key is `VariableDeclarator` and the other is `AssignmentExpression`, which can be used to control the destructuring requirement for each of those types independently. Each property accepts an object that accepts two properties, `array` and `object`, which can be used to control the destructuring requirement for each of `array` and `object` independently for variable declarations and assignment expressions. By default, `array` and `object` are set to true for both `VariableDeclarator` and `AssignmentExpression`. + +The rule has a second object with a single key, `enforceForRenamedProperties`, which determines whether the `object` destructuring applies to renamed variables. + +**Note**: It is not possible to determine if a variable will be referring to an object or an array at runtime. This rule therefore guesses the assignment type by checking whether the key being accessed is an integer. This can lead to the following possibly confusing situations: + +- Accessing an object property whose key is an integer will fall under the category `array` destructuring. +- Accessing an array element through a computed index will fall under the category `object` destructuring. + +The `--fix` option on the command line fixes only problems reported in variable declarations, and among them only those that fall under the category `object` destructuring. Furthermore, the name of the declared variable has to be the same as the name used for non-computed member access in the initializer. For example, `var foo = object.foo` can be automatically fixed by this rule. Problems that involve computed member access (e.g., `var foo = object[foo]`) or renamed properties (e.g., `var foo = object.bar`) are not automatically fixed. + +Examples of **incorrect** code for this rule: + +```javascript +// With `array` enabled +var foo = array[0]; + +// With `object` enabled +var foo = object.foo; +var foo = object['foo']; +``` + +Examples of **correct** code for this rule: + +```javascript +// With `array` enabled +var [ foo ] = array; +var foo = array[someIndex]; + +// With `object` enabled +var { foo } = object; + +var foo = object.bar; + +let foo; +({ foo } = object); +``` + +Examples of **incorrect** code when `enforceForRenamedProperties` is enabled: + +```javascript +var foo = object.bar; +``` + +Examples of **correct** code when `enforceForRenamedProperties` is enabled: + +```javascript +var { bar: foo } = object; +``` + +Examples of additional **correct** code when `enforceForRenamedProperties` is enabled: + +```javascript +class C { + #x; + foo() { + const bar = this.#x; // private identifiers are not allowed in destructuring + } +} +``` + +An example configuration, with the defaults `array` and `object` filled in, looks like this: + +```json +{ + "rules": { + "prefer-destructuring": ["error", { + "array": true, + "object": true + }, { + "enforceForRenamedProperties": false + }] + } +} +``` + +The two properties, `array` and `object`, which can be used to turn on or off the destructuring requirement for each of those types independently. By default, both are true. + +For example, the following configuration enforces only object destructuring, but not array destructuring: + +```json +{ + "rules": { + "prefer-destructuring": ["error", {"object": true, "array": false}] + } +} +``` + +An example configuration, with the defaults `VariableDeclarator` and `AssignmentExpression` filled in, looks like this: + +```json +{ + "rules": { + "prefer-destructuring": ["error", { + "VariableDeclarator": { + "array": false, + "object": true + }, + "AssignmentExpression": { + "array": true, + "object": true + } + }, { + "enforceForRenamedProperties": false + }] + } +} +``` + +The two properties, `VariableDeclarator` and `AssignmentExpression`, which can be used to turn on or off the destructuring requirement for `array` and `object`. By default, all values are true. + +For example, the following configuration enforces object destructuring in variable declarations and enforces array destructuring in assignment expressions. + +```json +{ + "rules": { + "prefer-destructuring": ["error", { + "VariableDeclarator": { + "array": false, + "object": true + }, + "AssignmentExpression": { + "array": true, + "object": false + } + }, { + "enforceForRenamedProperties": false + }] + } +} + +``` + +Examples of **correct** code when object destructuring in `VariableDeclarator` is enforced: + +```javascript +/* eslint prefer-destructuring: ["error", {VariableDeclarator: {object: true}}] */ +var {bar: foo} = object; +``` + +Examples of **correct** code when array destructuring in `AssignmentExpression` is enforced: + +```javascript +/* eslint prefer-destructuring: ["error", {AssignmentExpression: {array: true}}] */ +[bar] = array; +``` + +## When Not To Use It + +If you want to be able to access array indices or object properties directly, you can either configure the rule to your tastes or disable the rule entirely. + +Additionally, if you intend to access large array indices directly, like: + +```javascript +var foo = array[100]; +``` + +Then the `array` part of this rule is not recommended, as destructuring does not match this use case very well. + +Or for non-iterable 'array-like' objects: + +```javascript +var $ = require('jquery'); +var foo = $('body')[0]; +var [bar] = $('body'); // fails with a TypeError +``` + + +## Further Reading + +If you want to learn more about destructuring, check out the links below: + +- [Destructuring Assignment (MDN)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) +- [Destructuring and parameter handling in ECMAScript 6 (2ality blog)](http://2ality.com/2015/01/es6-destructuring.html) + +## Version + +This rule was introduced in ESLint 3.13.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/prefer-destructuring.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/prefer-destructuring.md) diff --git a/docs/8.0.0/rules/prefer-exponentiation-operator.md b/docs/8.0.0/rules/prefer-exponentiation-operator.md new file mode 100644 index 0000000000..21d245936b --- /dev/null +++ b/docs/8.0.0/rules/prefer-exponentiation-operator.md @@ -0,0 +1,65 @@ +--- +title: prefer-exponentiation-operator - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/prefer-exponentiation-operator.md +rule_type: suggestion +--- + + +# Disallow the use of `Math.pow` in favor of the `**` operator (prefer-exponentiation-operator) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +Introduced in ES2016, the infix exponentiation operator `**` is an alternative for the standard `Math.pow` function. + +Infix notation is considered to be more readable and thus more preferable than the function notation. + +## Rule Details + +This rule disallows calls to `Math.pow` and suggests using the `**` operator instead. + +Examples of **incorrect** code for this rule: + +```js +/*eslint prefer-exponentiation-operator: "error"*/ + +const foo = Math.pow(2, 8); + +const bar = Math.pow(a, b); + +let baz = Math.pow(a + b, c + d); + +let quux = Math.pow(-1, n); +``` + +Examples of **correct** code for this rule: + +```js +/*eslint prefer-exponentiation-operator: "error"*/ + +const foo = 2 ** 8; + +const bar = a ** b; + +let baz = (a + b) ** (c + d); + +let quux = (-1) ** n; +``` + +## When Not To Use It + +This rule should not be used unless ES2016 is supported in your codebase. + +## Further Reading + +* [MDN Arithmetic Operators - Exponentiation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Exponentiation) +* [Issue 5848: Exponentiation operator ** has different results for numbers and variables from 50 upwards](https://bugs.chromium.org/p/v8/issues/detail?id=5848) + +## Version + +This rule was introduced in ESLint 6.7.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/prefer-exponentiation-operator.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/prefer-exponentiation-operator.md) diff --git a/docs/8.0.0/rules/prefer-named-capture-group.md b/docs/8.0.0/rules/prefer-named-capture-group.md new file mode 100644 index 0000000000..2c7520a5f4 --- /dev/null +++ b/docs/8.0.0/rules/prefer-named-capture-group.md @@ -0,0 +1,60 @@ +--- +title: prefer-named-capture-group - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/prefer-named-capture-group.md +rule_type: suggestion +--- + + +# Suggest using named capture group in regular expression (prefer-named-capture-group) + +With the landing of ECMAScript 2018, named capture groups can be used in regular expressions, which can improve their readability. + +```js +const regex = /(?[0-9]{4})/; +``` + +## Rule Details + +This rule is aimed at using named capture groups instead of numbered capture groups in regular expressions. + +Examples of **incorrect** code for this rule: + +```js +/*eslint prefer-named-capture-group: "error"*/ + +const foo = /(ba[rz])/; +const bar = new RegExp('(ba[rz])'); +const baz = RegExp('(ba[rz])'); + +foo.exec('bar')[1]; // Retrieve the group result. +``` + +Examples of **correct** code for this rule: + +```js +/*eslint prefer-named-capture-group: "error"*/ + +const foo = /(?ba[rz])/; +const bar = new RegExp('(?ba[rz])'); +const baz = RegExp('(?ba[rz])'); + +foo.exec('bar').groups.id; // Retrieve the group result. +``` + +## When Not To Use It + +If you are targeting ECMAScript 2017 and/or older environments, you can disable this rule, because this ECMAScript feature is only supported in ECMAScript 2018 and/or newer environments. + +## Related Rules + +* [no-invalid-regexp](./no-invalid-regexp) + +## Version + +This rule was introduced in ESLint 5.15.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/prefer-named-capture-group.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/prefer-named-capture-group.md) diff --git a/docs/8.0.0/rules/prefer-numeric-literals.md b/docs/8.0.0/rules/prefer-numeric-literals.md new file mode 100644 index 0000000000..a4e033b7e4 --- /dev/null +++ b/docs/8.0.0/rules/prefer-numeric-literals.md @@ -0,0 +1,76 @@ +--- +title: prefer-numeric-literals - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/prefer-numeric-literals.md +rule_type: suggestion +--- + + +# disallow `parseInt()` and `Number.parseInt()` in favor of binary, octal, and hexadecimal literals (prefer-numeric-literals) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +The `parseInt()` and `Number.parseInt()` functions can be used to turn binary, octal, and hexadecimal strings into integers. As binary, octal, and hexadecimal literals are supported in ES6, this rule encourages use of those numeric literals instead of `parseInt()` or `Number.parseInt()`. + +```js +0b111110111 === 503; +0o767 === 503; +``` + +## Rule Details + +This rule disallows calls to `parseInt()` or `Number.parseInt()` if called with two arguments: a string; and a radix option of 2 (binary), 8 (octal), or 16 (hexadecimal). + +Examples of **incorrect** code for this rule: + +```js +/*eslint prefer-numeric-literals: "error"*/ + +parseInt("111110111", 2) === 503; +parseInt(`111110111`, 2) === 503; +parseInt("767", 8) === 503; +parseInt("1F7", 16) === 503; +Number.parseInt("111110111", 2) === 503; +Number.parseInt("767", 8) === 503; +Number.parseInt("1F7", 16) === 503; +``` + +Examples of **correct** code for this rule: + +```js +/*eslint prefer-numeric-literals: "error"*/ +/*eslint-env es6*/ + +parseInt(1); +parseInt(1, 3); +Number.parseInt(1); +Number.parseInt(1, 3); + +0b111110111 === 503; +0o767 === 503; +0x1F7 === 503; + +a[parseInt](1,2); + +parseInt(foo); +parseInt(foo, 2); +Number.parseInt(foo); +Number.parseInt(foo, 2); +``` + +## When Not To Use It + +If you want to allow use of `parseInt()` or `Number.parseInt()` for binary, octal, or hexadecimal integers, or if you are not using ES6 (because binary and octal literals are not supported in ES5 and below), you may wish to disable this rule. + +## Compatibility + +* **JSCS**: [requireNumericLiterals](https://jscs-dev.github.io/rule/requireNumericLiterals) + +## Version + +This rule was introduced in ESLint 3.5.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/prefer-numeric-literals.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/prefer-numeric-literals.md) diff --git a/docs/8.0.0/rules/prefer-object-spread.md b/docs/8.0.0/rules/prefer-object-spread.md new file mode 100644 index 0000000000..a54ac84f0f --- /dev/null +++ b/docs/8.0.0/rules/prefer-object-spread.md @@ -0,0 +1,70 @@ +--- +title: prefer-object-spread - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/prefer-object-spread.md +rule_type: suggestion +--- + + +# Prefer use of an object spread over `Object.assign` (prefer-object-spread) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +When Object.assign is called using an object literal as the first argument, this rule requires using the object spread syntax instead. This rule also warns on cases where an `Object.assign` call is made using a single argument that is an object literal, in this case, the `Object.assign` call is not needed. + +Introduced in ES2018, object spread is a declarative alternative which may perform better than the more dynamic, imperative `Object.assign`. + +## Rule Details + +Examples of **incorrect** code for this rule: + +```js +/*eslint prefer-object-spread: "error"*/ + +Object.assign({}, foo) + +Object.assign({}, {foo: 'bar'}) + +Object.assign({ foo: 'bar'}, baz) + +Object.assign({ foo: 'bar' }, Object.assign({ bar: 'foo' })) + +Object.assign({}, { foo, bar, baz }) + +Object.assign({}, { ...baz }) + +// Object.assign with a single argument that is an object literal +Object.assign({}); + +Object.assign({ foo: bar }); +``` + +Examples of **correct** code for this rule: + +```js +/*eslint prefer-object-spread: "error"*/ + +Object.assign(...foo); + +// Any Object.assign call without an object literal as the first argument +Object.assign(foo, { bar: baz }); + +Object.assign(foo, Object.assign(bar)); + +Object.assign(foo, { bar, baz }) + +Object.assign(foo, { ...baz }); +``` + +## When Not To Use It + +This rule should not be used unless ES2018 is supported in your codebase. + +## Version + +This rule was introduced in ESLint 5.0.0-alpha.3. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/prefer-object-spread.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/prefer-object-spread.md) diff --git a/docs/8.0.0/rules/prefer-promise-reject-errors.md b/docs/8.0.0/rules/prefer-promise-reject-errors.md new file mode 100644 index 0000000000..979bdf2c90 --- /dev/null +++ b/docs/8.0.0/rules/prefer-promise-reject-errors.md @@ -0,0 +1,96 @@ +--- +title: prefer-promise-reject-errors - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/prefer-promise-reject-errors.md +rule_type: suggestion +--- + + +# require using Error objects as Promise rejection reasons (prefer-promise-reject-errors) + +It is considered good practice to only pass instances of the built-in `Error` object to the `reject()` function for user-defined errors in Promises. `Error` objects automatically store a stack trace, which can be used to debug an error by determining where it came from. If a Promise is rejected with a non-`Error` value, it can be difficult to determine where the rejection occurred. + + +## Rule Details + +This rule aims to ensure that Promises are only rejected with `Error` objects. + +## Options + +This rule takes one optional object argument: + +* `allowEmptyReject: true` (`false` by default) allows calls to `Promise.reject()` with no arguments. + +Examples of **incorrect** code for this rule: + +```js +/*eslint prefer-promise-reject-errors: "error"*/ + +Promise.reject("something bad happened"); + +Promise.reject(5); + +Promise.reject(); + +new Promise(function(resolve, reject) { + reject("something bad happened"); +}); + +new Promise(function(resolve, reject) { + reject(); +}); + +``` + +Examples of **correct** code for this rule: + +```js +/*eslint prefer-promise-reject-errors: "error"*/ + +Promise.reject(new Error("something bad happened")); + +Promise.reject(new TypeError("something bad happened")); + +new Promise(function(resolve, reject) { + reject(new Error("something bad happened")); +}); + +var foo = getUnknownValue(); +Promise.reject(foo); +``` + +Examples of **correct** code for this rule with the `allowEmptyReject: true` option: + +```js +/*eslint prefer-promise-reject-errors: ["error", {"allowEmptyReject": true}]*/ + +Promise.reject(); + +new Promise(function(resolve, reject) { + reject(); +}); +``` + +## Known Limitations + +Due to the limits of static analysis, this rule cannot guarantee that you will only reject Promises with `Error` objects. While the rule will report cases where it can guarantee that the rejection reason is clearly not an `Error`, it will not report cases where there is uncertainty about whether a given reason is an `Error`. For more information on this caveat, see the [similar limitations](no-throw-literal#known-limitations) in the `no-throw-literal` rule. + +To avoid conflicts between rules, this rule does not report non-error values used in `throw` statements in async functions, even though these lead to Promise rejections. To lint for these cases, use the [`no-throw-literal`](https://eslint.org/docs/rules/no-throw-literal) rule. + +## When Not To Use It + +If you're using custom non-error values as Promise rejection reasons, you can turn off this rule. + +## Further Reading + +* [`no-throw-literal`](https://eslint.org/docs/rules/no-throw-literal) +* [Warning: a promise was rejected with a non-error](http://bluebirdjs.com/docs/warning-explanations.html#warning-a-promise-was-rejected-with-a-non-error) + +## Version + +This rule was introduced in ESLint 3.14.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/prefer-promise-reject-errors.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/prefer-promise-reject-errors.md) diff --git a/docs/8.0.0/rules/prefer-reflect.md b/docs/8.0.0/rules/prefer-reflect.md new file mode 100644 index 0000000000..d9bdd149ed --- /dev/null +++ b/docs/8.0.0/rules/prefer-reflect.md @@ -0,0 +1,356 @@ +--- +title: prefer-reflect - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/prefer-reflect.md +rule_type: suggestion +--- + + +# Suggest using Reflect methods where applicable (prefer-reflect) + +This rule was **deprecated** in ESLint v3.9.0 and will not be replaced. The original intent of this rule now seems misguided as we have come to understand that `Reflect` methods are not actually intended to replace the `Object` counterparts the rule suggests, but rather exist as low-level primitives to be used with proxies in order to replicate the default behavior of various previously existing functionality. + +The ES6 Reflect API comes with a handful of methods which somewhat deprecate methods on old constructors: + +* [`Reflect.apply`](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-reflect.apply) effectively deprecates [`Function.prototype.apply`](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-function.prototype.apply) and [`Function.prototype.call`](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-function.prototype.call) +* [`Reflect.deleteProperty`](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-reflect.deleteproperty) effectively deprecates the [`delete` keyword](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-delete-operator-runtime-semantics-evaluation) +* [`Reflect.getOwnPropertyDescriptor`](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-reflect.getownpropertydescriptor) effectively deprecates [`Object.getOwnPropertyDescriptor`](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-object.getownpropertydescriptor) +* [`Reflect.getPrototypeOf`](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-reflect.getprototypeof) effectively deprecates [`Object.getPrototypeOf`](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-object.getprototypeof) +* [`Reflect.setPrototypeOf`](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-reflect.setprototypeof) effectively deprecates [`Object.setPrototypeOf`](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-object.setprototypeof) +* [`Reflect.preventExtensions`](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-reflect.preventextensions) effectively deprecates [`Object.preventExtensions`](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-object.preventextensions) + +The prefer-reflect rule will flag usage of any older method, suggesting to instead use the newer Reflect version. + +## Rule Details + +## Options + +### Exceptions + +``` +"prefer-reflect": [, { "exceptions": [<...exceptions>] }] +``` + +The `exceptions` option allows you to pass an array of methods names you'd like to continue to use in the old style. + +For example if you wish to use all Reflect methods, except for `Function.prototype.apply` then your config would look like `prefer-reflect: [2, { "exceptions": ["apply"] }]`. + +If you want to use Reflect methods, but keep using the `delete` keyword, then your config would look like `prefer-reflect: [2, { "exceptions": ["delete"] }]`. + +These can be combined as much as you like. To make all methods exceptions (thereby rendering this rule useless), use `prefer-reflect: [2, { "exceptions": ["apply", "call", "defineProperty", "getOwnPropertyDescriptor", "getPrototypeOf", "setPrototypeOf", "isExtensible", "getOwnPropertyNames", "preventExtensions", "delete"] }]` + +### Reflect.apply + +Deprecates `Function.prototype.apply()` and `Function.prototype.call()` + +Examples of **incorrect** code for this rule when used without exceptions: + +```js +/*eslint prefer-reflect: "error"*/ + +myFunction.apply(undefined, args); +myFunction.apply(null, args); +obj.myMethod.apply(obj, args); +obj.myMethod.apply(other, args); + +myFunction.call(undefined, arg); +myFunction.call(null, arg); +obj.myMethod.call(obj, arg); +obj.myMethod.call(other, arg); +``` + +Examples of **correct** code for this rule when used without exceptions: + +```js +/*eslint prefer-reflect: "error"*/ + +Reflect.apply(myFunction, undefined, args); +Reflect.apply(myFunction, null, args); +Reflect.apply(obj.myMethod, obj, args); +Reflect.apply(obj.myMethod, other, args); +Reflect.apply(myFunction, undefined, [arg]); +Reflect.apply(myFunction, null, [arg]); +Reflect.apply(obj.myMethod, obj, [arg]); +Reflect.apply(obj.myMethod, other, [arg]); +``` + +Examples of **correct** code for this rule with the `{ "exceptions": ["apply"] }` option: + +```js +/*eslint prefer-reflect: ["error", { "exceptions": ["apply"] }]*/ + +// in addition to Reflect.apply(...): +myFunction.apply(undefined, args); +myFunction.apply(null, args); +obj.myMethod.apply(obj, args); +obj.myMethod.apply(other, args); +``` + +Examples of **correct** code for this rule with the `{ "exceptions": ["call"] }` option: + +```js +/*eslint prefer-reflect: ["error", { "exceptions": ["call"] }]*/ + +// in addition to Reflect.apply(...): +myFunction.call(undefined, arg); +myFunction.call(null, arg); +obj.myMethod.call(obj, arg); +obj.myMethod.call(other, arg); +``` + +### Reflect.defineProperty + +Deprecates `Object.defineProperty()` + +Examples of **incorrect** code for this rule when used without exceptions: + +```js +/*eslint prefer-reflect: "error"*/ + +Object.defineProperty({}, 'foo', {value: 1}) +``` + +Examples of **correct** code for this rule when used without exceptions: + +```js +/*eslint prefer-reflect: "error"*/ + +Reflect.defineProperty({}, 'foo', {value: 1}) +``` + +Examples of **correct** code for this rule with the `{ "exceptions": ["defineProperty"] }` option: + +```js +/*eslint prefer-reflect: ["error", { "exceptions": ["defineProperty"] }]*/ + +Object.defineProperty({}, 'foo', {value: 1}) +Reflect.defineProperty({}, 'foo', {value: 1}) +``` + +### Reflect.getOwnPropertyDescriptor + +Deprecates `Object.getOwnPropertyDescriptor()` + +Examples of **incorrect** code for this rule when used without exceptions: + +```js +/*eslint prefer-reflect: "error"*/ + +Object.getOwnPropertyDescriptor({}, 'foo') +``` + +Examples of **correct** code for this rule when used without exceptions: + +```js +/*eslint prefer-reflect: "error"*/ + +Reflect.getOwnPropertyDescriptor({}, 'foo') +``` + +Examples of **correct** code for this rule with the `{ "exceptions": ["getOwnPropertyDescriptor"] }` option: + +```js +/*eslint prefer-reflect: ["error", { "exceptions": ["getOwnPropertyDescriptor"] }]*/ + +Object.getOwnPropertyDescriptor({}, 'foo') +Reflect.getOwnPropertyDescriptor({}, 'foo') +``` + +### Reflect.getPrototypeOf + +Deprecates `Object.getPrototypeOf()` + +Examples of **incorrect** code for this rule when used without exceptions: + +```js +/*eslint prefer-reflect: "error"*/ + +Object.getPrototypeOf({}, 'foo') +``` + +Examples of **correct** code for this rule when used without exceptions: + +```js +/*eslint prefer-reflect: "error"*/ + +Reflect.getPrototypeOf({}, 'foo') +``` + +Examples of **correct** code for this rule with the `{ "exceptions": ["getPrototypeOf"] }` option: + +```js +/*eslint prefer-reflect: ["error", { "exceptions": ["getPrototypeOf"] }]*/ + +Object.getPrototypeOf({}, 'foo') +Reflect.getPrototypeOf({}, 'foo') +``` + +### Reflect.setPrototypeOf + +Deprecates `Object.setPrototypeOf()` + +Examples of **incorrect** code for this rule when used without exceptions: + +```js +/*eslint prefer-reflect: "error"*/ + +Object.setPrototypeOf({}, Object.prototype) +``` + +Examples of **correct** code for this rule when used without exceptions: + +```js +/*eslint prefer-reflect: "error"*/ + +Reflect.setPrototypeOf({}, Object.prototype) +``` + +Examples of **correct** code for this rule with the `{ "exceptions": ["setPrototypeOf"] }` option: + +```js +/*eslint prefer-reflect: ["error", { "exceptions": ["setPrototypeOf"] }]*/ + +Object.setPrototypeOf({}, Object.prototype) +Reflect.setPrototypeOf({}, Object.prototype) +``` + +### Reflect.isExtensible + +Deprecates `Object.isExtensible` + +Examples of **incorrect** code for this rule when used without exceptions: + +```js +/*eslint prefer-reflect: "error"*/ + +Object.isExtensible({}) +``` + +Examples of **correct** code for this rule when used without exceptions: + +```js +/*eslint prefer-reflect: "error"*/ + +Reflect.isExtensible({}) +``` + +Examples of **correct** code for this rule with the `{ "exceptions": ["isExtensible"] }` option: + +```js +/*eslint prefer-reflect: ["error", { "exceptions": ["isExtensible"] }]*/ + +Object.isExtensible({}) +Reflect.isExtensible({}) +``` + +### Reflect.getOwnPropertyNames + +Deprecates `Object.getOwnPropertyNames()` + +Examples of **incorrect** code for this rule when used without exceptions: + +```js +/*eslint prefer-reflect: "error"*/ + +Object.getOwnPropertyNames({}) +``` + +Examples of **correct** code for this rule when used without exceptions: + +```js +/*eslint prefer-reflect: "error"*/ + +Reflect.getOwnPropertyNames({}) +``` + +Examples of **correct** code for this rule with the `{ "exceptions": ["getOwnPropertyNames"] }` option: + +```js +/*eslint prefer-reflect: ["error", { "exceptions": ["getOwnPropertyNames"] }]*/ + +Object.getOwnPropertyNames({}) +Reflect.getOwnPropertyNames({}) +``` + +### Reflect.preventExtensions + +Deprecates `Object.preventExtensions()` + +Examples of **incorrect** code for this rule when used without exceptions: + +```js +/*eslint prefer-reflect: "error"*/ + +Object.preventExtensions({}) +``` + +Examples of **correct** code for this rule when used without exceptions: + +```js +/*eslint prefer-reflect: "error"*/ + +Reflect.preventExtensions({}) +``` + +Examples of **correct** code for this rule with the `{ "exceptions": ["preventExtensions"] }` option: + +```js +/*eslint prefer-reflect: ["error", { "exceptions": ["preventExtensions"] }]*/ + +Object.preventExtensions({}) +Reflect.preventExtensions({}) +``` + +### Reflect.deleteProperty + +Deprecates the `delete` keyword + +Examples of **incorrect** code for this rule when used without exceptions: + +```js +/*eslint prefer-reflect: "error"*/ + +delete foo.bar; // deleting object property +``` + +Examples of **correct** code for this rule when used without exceptions: + +```js +/*eslint prefer-reflect: "error"*/ + +delete bar; // deleting variable +Reflect.deleteProperty(foo, 'bar'); +``` + +Note: For a rule preventing deletion of variables, see [no-delete-var instead](no-delete-var) + +Examples of **correct** code for this rule with the `{ "exceptions": ["delete"] }` option: + +```js +/*eslint prefer-reflect: ["error", { "exceptions": ["delete"] }]*/ + +delete bar +delete foo.bar +Reflect.deleteProperty(foo, 'bar'); +``` + +## When Not To Use It + +This rule should not be used in ES3/5 environments. + +In ES2015 (ES6) or later, if you don't want to be notified about places where Reflect could be used, you can safely disable this rule. + +## Related Rules + +* [no-useless-call](no-useless-call) +* [prefer-spread](prefer-spread) +* [no-delete-var](no-delete-var) + +## Version + +This rule was introduced in ESLint 1.0.0-rc-2. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/prefer-reflect.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/prefer-reflect.md) diff --git a/docs/8.0.0/rules/prefer-regex-literals.md b/docs/8.0.0/rules/prefer-regex-literals.md new file mode 100644 index 0000000000..5be7e61b2a --- /dev/null +++ b/docs/8.0.0/rules/prefer-regex-literals.md @@ -0,0 +1,143 @@ +--- +title: prefer-regex-literals - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/prefer-regex-literals.md +rule_type: suggestion +--- + + +# Disallow use of the `RegExp` constructor in favor of regular expression literals (prefer-regex-literals) + +There are two ways to create a regular expression: + +* Regular expression literals, e.g., `/abc/u`. +* The `RegExp` constructor function, e.g., `new RegExp("abc", "u")` or `RegExp("abc", "u")`. + +The constructor function is particularly useful when you want to dynamically generate the pattern, +because it takes string arguments. + +When using the constructor function with string literals, don't forget that the string escaping rules still apply. +If you want to put a backslash in the pattern, you need to escape it in the string literal. +Thus, the following are equivalent: + +```js +new RegExp("^\\d\\.$"); + +/^\d\.$/; + +// matches "0.", "1.", "2." ... "9." +``` + +In the above example, the regular expression literal is easier to read and reason about. +Also, it's a common mistake to omit the extra `\` in the string literal, which would produce a completely different regular expression: + +```js +new RegExp("^\d\.$"); + +// equivalent to /^d.$/, matches "d1", "d2", "da", "db" ... +``` + +When a regular expression is known in advance, it is considered a best practice to avoid the string literal notation on top +of the regular expression notation, and use regular expression literals instead of the constructor function. + +## Rule Details + +This rule disallows the use of the `RegExp` constructor function with string literals as its arguments. + +This rule also disallows the use of the `RegExp` constructor function with template literals without expressions +and `String.raw` tagged template literals without expressions. + +The rule does not disallow all use of the `RegExp` constructor. It should be still used for +dynamically generated regular expressions. + +Examples of **incorrect** code for this rule: + +```js +/*eslint prefer-regex-literals: "error"*/ + +new RegExp("abc"); + +new RegExp("abc", "u"); + +RegExp("abc"); + +RegExp("abc", "u"); + +new RegExp("\\d\\d\\.\\d\\d\\.\\d\\d\\d\\d"); + +RegExp(`^\\d\\.$`); + +new RegExp(String.raw`^\d\.$`); +``` + +Examples of **correct** code for this rule: + +```js +/*eslint prefer-regex-literals: "error"*/ + +/abc/; + +/abc/u; + +/\d\d\.\d\d\.\d\d\d\d/; + +/^\d\.$/; + +// RegExp constructor is allowed for dynamically generated regular expressions + +new RegExp(pattern); + +RegExp("abc", flags); + +new RegExp(prefix + "abc"); + +RegExp(`${prefix}abc`); + +new RegExp(String.raw`^\d\. ${suffix}`); +``` + +## Options + +This rule has an object option: + +* `disallowRedundantWrapping` set to `true` additionally checks for unnecessarily wrapped regex literals (Default `false`). + +### `disallowRedundantWrapping` + +By default, this rule doesn’t check when a regex literal is unnecessarily wrapped in a `RegExp` constructor call. When the option `disallowRedundantWrapping` is set to `true`, the rule will also disallow such unnecessary patterns. + +Examples of `incorrect` code for `{ "disallowRedundantWrapping": true }` + +```js +/*eslint prefer-regex-literals: ["error", {"disallowRedundantWrapping": true}]*/ + +new RegExp(/abc/); + +new RegExp(/abc/, 'u'); +``` + +Examples of `correct` code for `{ "disallowRedundantWrapping": true }` + +```js +/*eslint prefer-regex-literals: ["error", {"disallowRedundantWrapping": true}]*/ + +/abc/; + +/abc/u; + +new RegExp(/abc/, flags); +``` + +## Further Reading + +* [MDN: Regular Expressions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions) +* [MDN: RegExp Constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp) + +## Version + +This rule was introduced in ESLint 6.4.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/prefer-regex-literals.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/prefer-regex-literals.md) diff --git a/docs/8.0.0/rules/prefer-rest-params.md b/docs/8.0.0/rules/prefer-rest-params.md new file mode 100644 index 0000000000..aa1367283e --- /dev/null +++ b/docs/8.0.0/rules/prefer-rest-params.md @@ -0,0 +1,82 @@ +--- +title: prefer-rest-params - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/prefer-rest-params.md +rule_type: suggestion +--- + + +# Suggest using the rest parameters instead of `arguments` (prefer-rest-params) + +There are rest parameters in ES2015. +We can use that feature for variadic functions instead of the `arguments` variable. + +`arguments` does not have methods of `Array.prototype`, so it's a bit of an inconvenience. + +## Rule Details + +This rule is aimed to flag usage of `arguments` variables. + +## Examples + +Examples of **incorrect** code for this rule: + +```js +/*eslint prefer-rest-params: "error"*/ + +function foo() { + console.log(arguments); +} + +function foo(action) { + var args = Array.prototype.slice.call(arguments, 1); + action.apply(null, args); +} + +function foo(action) { + var args = [].slice.call(arguments, 1); + action.apply(null, args); +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint prefer-rest-params: "error"*/ + +function foo(...args) { + console.log(args); +} + +function foo(action, ...args) { + action.apply(null, args); // or `action(...args)`, related to the `prefer-spread` rule. +} + +// Note: the implicit arguments can be overwritten. +function foo(arguments) { + console.log(arguments); // This is the first argument. +} +function foo() { + var arguments = 0; + console.log(arguments); // This is a local variable. +} +``` + +## When Not To Use It + +This rule should not be used in ES3/5 environments. + +In ES2015 (ES6) or later, if you don't want to be notified about `arguments` variables, then it's safe to disable this rule. + +## Related Rules + +* [prefer-spread](prefer-spread) + +## Version + +This rule was introduced in ESLint 2.0.0-alpha-1. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/prefer-rest-params.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/prefer-rest-params.md) diff --git a/docs/8.0.0/rules/prefer-spread.md b/docs/8.0.0/rules/prefer-spread.md new file mode 100644 index 0000000000..c1749230de --- /dev/null +++ b/docs/8.0.0/rules/prefer-spread.md @@ -0,0 +1,95 @@ +--- +title: prefer-spread - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/prefer-spread.md +rule_type: suggestion +--- + + +# Suggest using spread syntax instead of `.apply()`. (prefer-spread) + +Before ES2015, one must use `Function.prototype.apply()` to call variadic functions. + +```js +var args = [1, 2, 3, 4]; +Math.max.apply(Math, args); +``` + +In ES2015, one can use spread syntax to call variadic functions. + +```js +/*eslint-env es6*/ + +var args = [1, 2, 3, 4]; +Math.max(...args); +``` + +## Rule Details + +This rule is aimed to flag usage of `Function.prototype.apply()` in situations where spread syntax could be used instead. + +## Examples + +Examples of **incorrect** code for this rule: + +```js +/*eslint prefer-spread: "error"*/ + +foo.apply(undefined, args); +foo.apply(null, args); +obj.foo.apply(obj, args); +``` + +Examples of **correct** code for this rule: + +```js +/*eslint prefer-spread: "error"*/ + +// Using spread syntax +foo(...args); +obj.foo(...args); + +// The `this` binding is different. +foo.apply(obj, args); +obj.foo.apply(null, args); +obj.foo.apply(otherObj, args); + +// The argument list is not variadic. +// Those are warned by the `no-useless-call` rule. +foo.apply(undefined, [1, 2, 3]); +foo.apply(null, [1, 2, 3]); +obj.foo.apply(obj, [1, 2, 3]); +``` + +Known limitations: + +This rule analyzes code statically to check whether or not the `this` argument is changed. So, if the `this` argument is computed in a dynamic expression, this rule cannot detect a violation. + +```js +/*eslint prefer-spread: "error"*/ + +// This warns. +a[i++].foo.apply(a[i++], args); + +// This does not warn. +a[++i].foo.apply(a[i], args); +``` + +## When Not To Use It + +This rule should not be used in ES3/5 environments. + +In ES2015 (ES6) or later, if you don't want to be notified about `Function.prototype.apply()` callings, you can safely disable this rule. + +## Related Rules + +* [no-useless-call](no-useless-call) + +## Version + +This rule was introduced in ESLint 1.0.0-rc-1. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/prefer-spread.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/prefer-spread.md) diff --git a/docs/8.0.0/rules/prefer-template.md b/docs/8.0.0/rules/prefer-template.md new file mode 100644 index 0000000000..96d3cab59a --- /dev/null +++ b/docs/8.0.0/rules/prefer-template.md @@ -0,0 +1,72 @@ +--- +title: prefer-template - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/prefer-template.md +rule_type: suggestion +--- + + +# Suggest using template literals instead of string concatenation. (prefer-template) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +In ES2015 (ES6), we can use template literals instead of string concatenation. + +```js +var str = "Hello, " + name + "!"; +``` + +```js +/*eslint-env es6*/ + +var str = `Hello, ${name}!`; +``` + +## Rule Details + +This rule is aimed to flag usage of `+` operators with strings. + +## Examples + +Examples of **incorrect** code for this rule: + +```js +/*eslint prefer-template: "error"*/ + +var str = "Hello, " + name + "!"; +var str = "Time: " + (12 * 60 * 60 * 1000); +``` + +Examples of **correct** code for this rule: + +```js +/*eslint prefer-template: "error"*/ +/*eslint-env es6*/ + +var str = "Hello World!"; +var str = `Hello, ${name}!`; +var str = `Time: ${12 * 60 * 60 * 1000}`; + +// This is reported by `no-useless-concat`. +var str = "Hello, " + "World!"; +``` + +## When Not To Use It + +This rule should not be used in ES3/5 environments. + +In ES2015 (ES6) or later, if you don't want to be notified about string concatenation, you can safely disable this rule. + +## Related Rules + +* [no-useless-concat](no-useless-concat) +* [quotes](quotes) + +## Version + +This rule was introduced in ESLint 1.2.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/prefer-template.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/prefer-template.md) diff --git a/docs/8.0.0/rules/quote-props.md b/docs/8.0.0/rules/quote-props.md new file mode 100644 index 0000000000..5f65cd9472 --- /dev/null +++ b/docs/8.0.0/rules/quote-props.md @@ -0,0 +1,287 @@ +--- +title: quote-props - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/quote-props.md +rule_type: suggestion +--- + + +# require quotes around object literal property names (quote-props) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +Object literal property names can be defined in two ways: using literals or using strings. For example, these two objects are equivalent: + +```js +var object1 = { + property: true +}; + +var object2 = { + "property": true +}; +``` + +In many cases, it doesn't matter if you choose to use an identifier instead of a string or vice-versa. Even so, you might decide to enforce a consistent style in your code. + +There are, however, some occasions when you must use quotes: + +1. If you are using an ECMAScript 3 JavaScript engine (such as IE8) and you want to use a keyword (such as `if`) as a property name. This restriction was removed in ECMAScript 5. +2. You want to use a non-identifier character in your property name, such as having a property with a space like `"one two"`. + +Another example where quotes do matter is when using numeric literals as property keys: + +```js +var object = { + 1e2: 1, + 100: 2 +}; +``` + +This may look alright at first sight, but this code in fact throws a syntax error in ECMAScript 5 strict mode. This happens because `1e2` and `100` are coerced into strings before getting used as the property name. Both `String(1e2)` and `String(100)` happen to be equal to `"100"`, which causes the "Duplicate data property in object literal not allowed in strict mode" error. Issues like that can be tricky to debug, so some prefer to require quotes around all property names. + +## Rule Details + +This rule requires quotes around object literal property names. + +## Options + +This rule has two options, a string option and an object option. + +String option: + +* `"always"` (default) requires quotes around all object literal property names +* `"as-needed"` disallows quotes around object literal property names that are not strictly required +* `"consistent"` enforces a consistent quote style; in a given object, either all of the properties should be quoted, or none of the properties should be quoted +* `"consistent-as-needed"` requires quotes around all object literal property names if any name strictly requires quotes, otherwise disallows quotes around object property names + +Object option: + +* `"keywords": true` requires quotes around language keywords used as object property names (only applies when using `as-needed` or `consistent-as-needed`) +* `"unnecessary": true` (default) disallows quotes around object literal property names that are not strictly required (only applies when using `as-needed`) +* `"unnecessary": false` allows quotes around object literal property names that are not strictly required (only applies when using `as-needed`) +* `"numbers": true` requires quotes around numbers used as object property names (only applies when using `as-needed`) + +### always + +Examples of **incorrect** code for this rule with the default `"always"` option: + +```js +/*eslint quote-props: ["error", "always"]*/ + +var object = { + foo: "bar", + baz: 42 +}; +``` + +Examples of **correct** code for this rule with the default `"always"` option: + +```js +/*eslint quote-props: ["error", "always"]*/ +/*eslint-env es6*/ + +var object1 = { + "foo": "bar", + "baz": 42, + "qux-lorem": true +}; + +var object2 = { + 'foo': 'bar', + 'baz': 42, + 'qux-lorem': true +}; + +var object3 = { + foo() { + return; + } +}; +``` + +### as-needed + +Examples of **incorrect** code for this rule with the `"as-needed"` option: + +```js +/*eslint quote-props: ["error", "as-needed"]*/ + +var object = { + "a": 0, + "0": 0, + "true": 0, + "null": 0 +}; +``` + +Examples of **correct** code for this rule with the `"as-needed"` option: + +```js +/*eslint quote-props: ["error", "as-needed"]*/ +/*eslint-env es6*/ + +var object1 = { + "a-b": 0, + "0x0": 0, + "1e2": 0 +}; + +var object2 = { + foo: 'bar', + baz: 42, + true: 0, + 0: 0, + 'qux-lorem': true +}; + +var object3 = { + foo() { + return; + } +}; +``` + +### consistent + +Examples of **incorrect** code for this rule with the `"consistent"` option: + +```js +/*eslint quote-props: ["error", "consistent"]*/ + +var object1 = { + foo: "bar", + "baz": 42, + "qux-lorem": true +}; + +var object2 = { + 'foo': 'bar', + baz: 42 +}; +``` + +Examples of **correct** code for this rule with the `"consistent"` option: + +```js +/*eslint quote-props: ["error", "consistent"]*/ + +var object1 = { + "foo": "bar", + "baz": 42, + "qux-lorem": true +}; + +var object2 = { + 'foo': 'bar', + 'baz': 42 +}; + +var object3 = { + foo: 'bar', + baz: 42 +}; +``` + +### consistent-as-needed + +Examples of **incorrect** code for this rule with the `"consistent-as-needed"` option: + +```js +/*eslint quote-props: ["error", "consistent-as-needed"]*/ + +var object1 = { + foo: "bar", + "baz": 42, + "qux-lorem": true +}; + +var object2 = { + 'foo': 'bar', + 'baz': 42 +}; +``` + +Examples of **correct** code for this rule with the `"consistent-as-needed"` option: + +```js +/*eslint quote-props: ["error", "consistent-as-needed"]*/ + +var object1 = { + "foo": "bar", + "baz": 42, + "qux-lorem": true +}; + +var object2 = { + foo: 'bar', + baz: 42 +}; +``` + +### keywords + +Examples of additional **incorrect** code for this rule with the `"as-needed", { "keywords": true }` options: + +```js +/*eslint quote-props: ["error", "as-needed", { "keywords": true }]*/ + +var x = { + while: 1, + volatile: "foo" +}; +``` + +Examples of additional **incorrect** code for this rule with the `"consistent-as-needed", { "keywords": true }` options: + +```js +/*eslint quote-props: ["error", "consistent-as-needed", { "keywords": true }]*/ + +var x = { + "prop": 1, + "bar": "foo" +}; +``` + +### unnecessary + +Examples of additional **correct** code for this rule with the `"as-needed", { "unnecessary": false }` options: + +```js +/*eslint quote-props: ["error", "as-needed", { "keywords": true, "unnecessary": false }]*/ + +var x = { + "while": 1, + "foo": "bar" // Would normally have caused a warning +}; +``` + +### numbers + +Examples of additional **incorrect** code for this rule with the `"as-needed", { "numbers": true }` options: + +```js +/*eslint quote-props: ["error", "as-needed", { "numbers": true }]*/ + +var x = { + 100: 1 +} +``` + +## When Not To Use It + +If you don't care if property names are consistently wrapped in quotes or not, and you don't target legacy ES3 environments, turn this rule off. + +## Further Reading + +* [Reserved words as property names](https://kangax.github.io/compat-table/es5/#Reserved_words_as_property_names) +* [Unquoted property names / object keys in JavaScript](https://mathiasbynens.be/notes/javascript-properties) + +## Version + +This rule was introduced in ESLint 0.0.6. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/quote-props.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/quote-props.md) diff --git a/docs/8.0.0/rules/quotes.md b/docs/8.0.0/rules/quotes.md new file mode 100644 index 0000000000..41062030da --- /dev/null +++ b/docs/8.0.0/rules/quotes.md @@ -0,0 +1,173 @@ +--- +title: quotes - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/quotes.md +rule_type: layout +--- + + +# enforce the consistent use of either backticks, double, or single quotes (quotes) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +JavaScript allows you to define strings in one of three ways: double quotes, single quotes, and backticks (as of ECMAScript 6). For example: + +```js +/*eslint-env es6*/ + +var double = "double"; +var single = 'single'; +var backtick = `backtick`; // ES6 only +``` + +Each of these lines creates a string and, in some cases, can be used interchangeably. The choice of how to define strings in a codebase is a stylistic one outside of template literals (which allow embedded of expressions to be interpreted). + +Many codebases require strings to be defined in a consistent manner. + +## Rule Details + +This rule enforces the consistent use of either backticks, double, or single quotes. + +## Options + +This rule has two options, a string option and an object option. + +String option: + +* `"double"` (default) requires the use of double quotes wherever possible +* `"single"` requires the use of single quotes wherever possible +* `"backtick"` requires the use of backticks wherever possible + +Object option: + +* `"avoidEscape": true` allows strings to use single-quotes or double-quotes so long as the string contains a quote that would have to be escaped otherwise +* `"allowTemplateLiterals": true` allows strings to use backticks + +**Deprecated**: The object property `avoid-escape` is deprecated; please use the object property `avoidEscape` instead. + +### double + +Examples of **incorrect** code for this rule with the default `"double"` option: + +```js +/*eslint quotes: ["error", "double"]*/ + +var single = 'single'; +var unescaped = 'a string containing "double" quotes'; +var backtick = `back\ntick`; // you can use \n in single or double quoted strings +``` + +Examples of **correct** code for this rule with the default `"double"` option: + +```js +/*eslint quotes: ["error", "double"]*/ +/*eslint-env es6*/ + +var double = "double"; +var backtick = `back +tick`; // backticks are allowed due to newline +var backtick = tag`backtick`; // backticks are allowed due to tag +``` + +### single + +Examples of **incorrect** code for this rule with the `"single"` option: + +```js +/*eslint quotes: ["error", "single"]*/ + +var double = "double"; +var unescaped = "a string containing 'single' quotes"; +``` + +Examples of **correct** code for this rule with the `"single"` option: + +```js +/*eslint quotes: ["error", "single"]*/ +/*eslint-env es6*/ + +var single = 'single'; +var backtick = `back${x}tick`; // backticks are allowed due to substitution +``` + +### backticks + +Examples of **incorrect** code for this rule with the `"backtick"` option: + +```js +/*eslint quotes: ["error", "backtick"]*/ + +var single = 'single'; +var double = "double"; +var unescaped = 'a string containing `backticks`'; +``` + +Examples of **correct** code for this rule with the `"backtick"` option: + +```js +/*eslint quotes: ["error", "backtick"]*/ +/*eslint-env es6*/ + +var backtick = `backtick`; +``` + +### avoidEscape + +Examples of additional **correct** code for this rule with the `"double", { "avoidEscape": true }` options: + +```js +/*eslint quotes: ["error", "double", { "avoidEscape": true }]*/ + +var single = 'a string containing "double" quotes'; +``` + +Examples of additional **correct** code for this rule with the `"single", { "avoidEscape": true }` options: + +```js +/*eslint quotes: ["error", "single", { "avoidEscape": true }]*/ + +var double = "a string containing 'single' quotes"; +``` + +Examples of additional **correct** code for this rule with the `"backtick", { "avoidEscape": true }` options: + +```js +/*eslint quotes: ["error", "backtick", { "avoidEscape": true }]*/ + +var double = "a string containing `backtick` quotes" +``` + +### allowTemplateLiterals + +Examples of additional **correct** code for this rule with the `"double", { "allowTemplateLiterals": true }` options: + +```js +/*eslint quotes: ["error", "double", { "allowTemplateLiterals": true }]*/ + +var double = "double"; +var double = `double`; +``` + +Examples of additional **correct** code for this rule with the `"single", { "allowTemplateLiterals": true }` options: + +```js +/*eslint quotes: ["error", "single", { "allowTemplateLiterals": true }]*/ + +var single = 'single'; +var single = `single`; +``` + +`{ "allowTemplateLiterals": false }` will not disallow the usage of all template literals. If you want to forbid any instance of template literals, use [no-restricted-syntax](https://eslint.org/docs/rules/no-restricted-syntax) and target the `TemplateLiteral` selector. + +## When Not To Use It + +If you do not need consistency in your string styles, you can safely disable this rule. + +## Version + +This rule was introduced in ESLint 0.0.7. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/quotes.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/quotes.md) diff --git a/docs/8.0.0/rules/radix.md b/docs/8.0.0/rules/radix.md new file mode 100644 index 0000000000..96b84747a8 --- /dev/null +++ b/docs/8.0.0/rules/radix.md @@ -0,0 +1,114 @@ +--- +title: radix - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/radix.md +rule_type: suggestion +--- + + +# Require Radix Parameter (radix) + +(hasSuggestions) Some problems reported by this rule are manually fixable by editor [suggestions](../developer-guide/working-with-rules#providing-suggestions). + +When using the `parseInt()` function it is common to omit the second argument, the radix, and let the function try to determine from the first argument what type of number it is. By default, `parseInt()` will autodetect decimal and hexadecimal (via `0x` prefix). Prior to ECMAScript 5, `parseInt()` also autodetected octal literals, which caused problems because many developers assumed a leading `0` would be ignored. + +This confusion led to the suggestion that you always use the radix parameter to `parseInt()` to eliminate unintended consequences. So instead of doing this: + +```js +var num = parseInt("071"); // 57 +``` + +Do this: + +```js +var num = parseInt("071", 10); // 71 +``` + +ECMAScript 5 changed the behavior of `parseInt()` so that it no longer autodetects octal literals and instead treats them as decimal literals. However, the differences between hexadecimal and decimal interpretation of the first parameter causes many developers to continue using the radix parameter to ensure the string is interpreted in the intended way. + +On the other hand, if the code is targeting only ES5-compliant environments passing the radix `10` may be redundant. In such a case you might want to disallow using such a radix. + +## Rule Details + +This rule is aimed at preventing the unintended conversion of a string to a number of a different base than intended or at preventing the redundant `10` radix if targeting modern environments only. + +## Options + +There are two options for this rule: + +* `"always"` enforces providing a radix (default) +* `"as-needed"` disallows providing the `10` radix + + +### always + +Examples of **incorrect** code for the default `"always"` option: + +```js +/*eslint radix: "error"*/ + +var num = parseInt("071"); + +var num = parseInt(someValue); + +var num = parseInt("071", "abc"); + +var num = parseInt("071", 37); + +var num = parseInt(); +``` + +Examples of **correct** code for the default `"always"` option: + +```js +/*eslint radix: "error"*/ + +var num = parseInt("071", 10); + +var num = parseInt("071", 8); + +var num = parseFloat(someValue); +``` + +### as-needed + +Examples of **incorrect** code for the `"as-needed"` option: + +```js +/*eslint radix: ["error", "as-needed"]*/ + +var num = parseInt("071", 10); + +var num = parseInt("071", "abc"); + +var num = parseInt(); +``` + +Examples of **correct** code for the `"as-needed"` option: + +```js +/*eslint radix: ["error", "as-needed"]*/ + +var num = parseInt("071"); + +var num = parseInt("071", 8); + +var num = parseFloat(someValue); +``` + +## When Not To Use It + +If you don't want to enforce either presence or omission of the `10` radix value you can turn this rule off. + +## Further Reading + +* [parseInt and radix](https://davidwalsh.name/parseint-radix) + +## Version + +This rule was introduced in ESLint 0.0.7. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/radix.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/radix.md) diff --git a/docs/8.0.0/rules/require-atomic-updates.md b/docs/8.0.0/rules/require-atomic-updates.md new file mode 100644 index 0000000000..b6a134dae0 --- /dev/null +++ b/docs/8.0.0/rules/require-atomic-updates.md @@ -0,0 +1,114 @@ +--- +title: require-atomic-updates - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/require-atomic-updates.md +rule_type: problem +--- + + +# Disallow assignments that can lead to race conditions due to usage of `await` or `yield` (require-atomic-updates) + +When writing asynchronous code, it is possible to create subtle race condition bugs. Consider the following example: + +```js +let totalLength = 0; + +async function addLengthOfSinglePage(pageNum) { + totalLength += await getPageLength(pageNum); +} + +Promise.all([addLengthOfSinglePage(1), addLengthOfSinglePage(2)]).then(() => { + console.log('The combined length of both pages is', totalLength); +}); +``` + +This code looks like it will sum the results of calling `getPageLength(1)` and `getPageLength(2)`, but in reality the final value of `totalLength` will only be the length of one of the two pages. The bug is in the statement `totalLength += await getPageLength(pageNum);`. This statement first reads an initial value of `totalLength`, then calls `getPageLength(pageNum)` and waits for that Promise to fulfill. Finally, it sets the value of `totalLength` to the sum of `await getPageLength(pageNum)` and the *initial* value of `totalLength`. If the `totalLength` variable is updated in a separate function call during the time that the `getPageLength(pageNum)` Promise is pending, that update will be lost because the new value is overwritten without being read. + +One way to fix this issue would be to ensure that `totalLength` is read at the same time as it's updated, like this: + +```js +async function addLengthOfSinglePage(pageNum) { + const lengthOfThisPage = await getPageLength(pageNum); + + totalLength += lengthOfThisPage; +} +``` + +Another solution would be to avoid using a mutable variable reference at all: + +```js +Promise.all([getPageLength(1), getPageLength(2)]).then(pageLengths => { + const totalLength = pageLengths.reduce((accumulator, length) => accumulator + length, 0); + + console.log('The combined length of both pages is', totalLength); +}); +``` + +## Rule Details + +This rule aims to report assignments to variables or properties where all of the following are true: + +* A variable or property is reassigned to a new value which is based on its old value. +* A `yield` or `await` expression interrupts the assignment after the old value is read, and before the new value is set. +* The rule cannot easily verify that the assignment is safe (e.g. if an assigned variable is local and would not be readable from anywhere else while the function is paused). + +Examples of **incorrect** code for this rule: + +```js +/* eslint require-atomic-updates: error */ + +let result; +async function foo() { + result += await somethingElse; + + result = result + await somethingElse; + + result = result + doSomething(await somethingElse); +} + +function* bar() { + result += yield; + + result = result + (yield somethingElse); + + result = result + doSomething(yield somethingElse); +} +``` + +Examples of **correct** code for this rule: + +```js +/* eslint require-atomic-updates: error */ + +let result; +async function foo() { + result = await somethingElse + result; + + let tmp = await somethingElse; + result += tmp; + + let localVariable = 0; + localVariable += await somethingElse; +} + +function* bar() { + result = (yield) + result; + + result = (yield somethingElse) + result; + + result = doSomething(yield somethingElse, result); +} +``` + +## When Not To Use It + +If you don't use async or generator functions, you don't need to enable this rule. + +## Version + +This rule was introduced in ESLint 5.3.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/require-atomic-updates.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/require-atomic-updates.md) diff --git a/docs/8.0.0/rules/require-await.md b/docs/8.0.0/rules/require-await.md new file mode 100644 index 0000000000..4ea6975b93 --- /dev/null +++ b/docs/8.0.0/rules/require-await.md @@ -0,0 +1,104 @@ +--- +title: require-await - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/require-await.md +rule_type: suggestion +--- + + +# Disallow async functions which have no `await` expression (require-await) + +Asynchronous functions in JavaScript behave differently than other functions in two important ways: + +1. The return value is always a `Promise`. +2. You can use the `await` operator inside of them. + +The primary reason to use asynchronous functions is typically to use the `await` operator, such as this: + +```js +async function fetchData(processDataItem) { + const response = await fetch(DATA_URL); + const data = await response.json(); + + return data.map(processDataItem); +} +``` + +Asynchronous functions that don't use `await` might not need to be asynchronous functions and could be the unintentional result of refactoring. + +Note: this rule ignores async generator functions. This is because generators yield rather than return a value and async generators might yield all the values of another async generator without ever actually needing to use await. + +## Rule Details + +This rule warns async functions which have no `await` expression. + +Examples of **incorrect** code for this rule: + +```js +/*eslint require-await: "error"*/ + +async function foo() { + doSomething(); +} + +bar(async () => { + doSomething(); +}); +``` + +Examples of **correct** code for this rule: + +```js +/*eslint require-await: "error"*/ + +async function foo() { + await doSomething(); +} + +bar(async () => { + await doSomething(); +}); + +function foo() { + doSomething(); +} + +bar(() => { + doSomething(); +}); + +// Allow empty functions. +async function noop() {} +``` + +## When Not To Use It + +Asynchronous functions are designed to work with promises such that throwing an error will cause a promise's rejection handler (such as `catch()`) to be called. For example: + +```js +async function fail() { + throw new Error("Failure!"); +} + +fail().catch(error => { + console.log(error.message); +}); +``` + +In this case, the `fail()` function throws an error that is intended to be caught by the `catch()` handler assigned later. Converting the `fail()` function into a synchronous function would require the call to `fail()` to be refactored to use a `try-catch` statement instead of a promise. + +If you are throwing an error inside of an asynchronous function for this purpose, then you may want to disable this rule. + + +## Related Rules + +* [require-yield](require-yield) + +## Version + +This rule was introduced in ESLint 3.11.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/require-await.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/require-await.md) diff --git a/docs/8.0.0/rules/require-jsdoc.md b/docs/8.0.0/rules/require-jsdoc.md new file mode 100644 index 0000000000..f30e1edb9b --- /dev/null +++ b/docs/8.0.0/rules/require-jsdoc.md @@ -0,0 +1,206 @@ +--- +title: require-jsdoc - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/require-jsdoc.md +rule_type: suggestion +--- + + +# require JSDoc comments (require-jsdoc) + +This rule was [**deprecated**](https://eslint.org/blog/2018/11/jsdoc-end-of-life) in ESLint v5.10.0. + +[JSDoc](http://usejsdoc.org) is a JavaScript API documentation generator. It uses specially-formatted comments inside of code to generate API documentation automatically. For example, this is what a JSDoc comment looks like for a function: + +```js +/** + * Adds two numbers together. + * @param {int} num1 The first number. + * @param {int} num2 The second number. + * @returns {int} The sum of the two numbers. + */ +function sum(num1, num2) { + return num1 + num2; +} +``` + +Some style guides require JSDoc comments for all functions as a way of explaining function behavior. + +## Rule Details + +This rule requires JSDoc comments for specified nodes. Supported nodes: + +* `"FunctionDeclaration"` +* `"ClassDeclaration"` +* `"MethodDefinition"` +* `"ArrowFunctionExpression"` +* `"FunctionExpression"` + +## Options + +This rule has a single object option: + +* `"require"` requires JSDoc comments for the specified nodes + +Default option settings are: + +```json +{ + "require-jsdoc": ["error", { + "require": { + "FunctionDeclaration": true, + "MethodDefinition": false, + "ClassDeclaration": false, + "ArrowFunctionExpression": false, + "FunctionExpression": false + } + }] +} +``` + +### require + +Examples of **incorrect** code for this rule with the `{ "require": { "FunctionDeclaration": true, "MethodDefinition": true, "ClassDeclaration": true, "ArrowFunctionExpression": true, "FunctionExpression": true } }` option: + +```js +/*eslint "require-jsdoc": ["error", { + "require": { + "FunctionDeclaration": true, + "MethodDefinition": true, + "ClassDeclaration": true, + "ArrowFunctionExpression": true, + "FunctionExpression": true + } +}]*/ + +function foo() { + return 10; +} + +var foo = () => { + return 10; +}; + +class Foo { + bar() { + return 10; + } +} + +var foo = function() { + return 10; +}; + +var foo = { + bar: function() { + return 10; + }, + + baz() { + return 10; + } +}; +``` + +Examples of **correct** code for this rule with the `{ "require": { "FunctionDeclaration": true, "MethodDefinition": true, "ClassDeclaration": true, "ArrowFunctionExpression": true, "FunctionExpression": true } }` option: + +```js +/*eslint "require-jsdoc": ["error", { + "require": { + "FunctionDeclaration": true, + "MethodDefinition": true, + "ClassDeclaration": true, + "ArrowFunctionExpression": true, + "FunctionExpression": true + } +}]*/ + +/** + * It returns 10 + */ +function foo() { + return 10; +} + +/** + * It returns test + 10 + * @params {int} test - some number + * @returns {int} sum of test and 10 + */ +var foo = (test) => { + return test + 10; +} + +/** + * It returns 10 + */ +var foo = () => { + return 10; +} + +/** + * It returns 10 + */ +var foo = function() { + return 10; +} + +var array = [1,2,3]; +array.filter(function(item) { + return item > 2; +}); + +/** + * A class that can return the number 10 + */ +class Foo { + /** + * It returns 10 + */ + bar() { + return 10; + } +} + +/** + * It returns 10 + */ +var foo = function() { + return 10; +}; + +var foo = { + /** + * It returns 10 + */ + bar: function() { + return 10; + }, + + /** + * It returns 10 + */ + baz() { + return 10; + } +}; + +setTimeout(() => {}, 10); // since it's an anonymous arrow function +``` + +## When Not To Use It + +If you do not require JSDoc for your functions, then you can leave this rule off. + +## Related Rules + +* [valid-jsdoc](valid-jsdoc) + +## Version + +This rule was introduced in ESLint 1.4.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/require-jsdoc.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/require-jsdoc.md) diff --git a/docs/8.0.0/rules/require-unicode-regexp.md b/docs/8.0.0/rules/require-unicode-regexp.md new file mode 100644 index 0000000000..d90acd6715 --- /dev/null +++ b/docs/8.0.0/rules/require-unicode-regexp.md @@ -0,0 +1,72 @@ +--- +title: require-unicode-regexp - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/require-unicode-regexp.md +rule_type: suggestion +--- + + +# Enforce the use of `u` flag on RegExp (require-unicode-regexp) + +RegExp `u` flag has two effects: + +1. **Make the regular expression handling UTF-16 surrogate pairs correctly.** + + Especially, character range syntax gets the correct behavior. + + ```js + /^[👍]$/.test("👍") //→ false + /^[👍]$/u.test("👍") //→ true + ``` + +2. **Make the regular expression throwing syntax errors early as disabling [Annex B extensions](https://www.ecma-international.org/ecma-262/6.0/#sec-regular-expressions-patterns).** + + Because of historical reason, JavaScript regular expressions are tolerant of syntax errors. For example, `/\w{1, 2/` is a syntax error, but JavaScript doesn't throw the error. It matches strings such as `"a{1, 2"` instead. Such a recovering logic is defined in Annex B. + + The `u` flag disables the recovering logic Annex B defined. As a result, you can find errors early. This is similar to [the strict mode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode). + +Therefore, the `u` flag lets us work better with regular expressions. + +## Rule Details + +This rule aims to enforce the use of `u` flag on regular expressions. + +Examples of **incorrect** code for this rule: + +```js +/*eslint require-unicode-regexp: error */ + +const a = /aaa/ +const b = /bbb/gi +const c = new RegExp("ccc") +const d = new RegExp("ddd", "gi") +``` + +Examples of **correct** code for this rule: + +```js +/*eslint require-unicode-regexp: error */ + +const a = /aaa/u +const b = /bbb/giu +const c = new RegExp("ccc", "u") +const d = new RegExp("ddd", "giu") + +// This rule ignores RegExp calls if the flags could not be evaluated to a static value. +function f(flags) { + return new RegExp("eee", flags) +} +``` + +## When Not To Use It + +If you don't want to notify regular expressions with no `u` flag, then it's safe to disable this rule. + +## Version + +This rule was introduced in ESLint 5.3.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/require-unicode-regexp.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/require-unicode-regexp.md) diff --git a/docs/8.0.0/rules/require-yield.md b/docs/8.0.0/rules/require-yield.md new file mode 100644 index 0000000000..e525a71bab --- /dev/null +++ b/docs/8.0.0/rules/require-yield.md @@ -0,0 +1,64 @@ +--- +title: require-yield - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/require-yield.md +rule_type: suggestion +--- + + +# Disallow generator functions that do not have `yield` (require-yield) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +## Rule Details + +This rule generates warnings for generator functions that do not have the `yield` keyword. + +## Examples + +Examples of **incorrect** code for this rule: + +```js +/*eslint require-yield: "error"*/ +/*eslint-env es6*/ + +function* foo() { + return 10; +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint require-yield: "error"*/ +/*eslint-env es6*/ + +function* foo() { + yield 5; + return 10; +} + +function foo() { + return 10; +} + +// This rule does not warn on empty generator functions. +function* foo() { } +``` + +## When Not To Use It + +If you don't want to notify generator functions that have no `yield` expression, then it's safe to disable this rule. + +## Related Rules + +* [require-await](require-await) + +## Version + +This rule was introduced in ESLint 1.0.0-rc-1. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/require-yield.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/require-yield.md) diff --git a/docs/8.0.0/rules/rest-spread-spacing.md b/docs/8.0.0/rules/rest-spread-spacing.md new file mode 100644 index 0000000000..1ce98aae13 --- /dev/null +++ b/docs/8.0.0/rules/rest-spread-spacing.md @@ -0,0 +1,159 @@ +--- +title: rest-spread-spacing - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/rest-spread-spacing.md +rule_type: layout +--- + + +# Enforce spacing between rest and spread operators and their expressions (rest-spread-spacing) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +ES2015 introduced the rest and spread operators, which expand an iterable structure into its individual parts. Some examples of their usage are as follows: + +```js +let numArr = [1, 2, 3]; +function add(a, b, c) { + return a + b + c; +} +add(...numArr); // -> 6 + +let arr1 = [1, 2, 3]; +let arr2 = [4, 5, 6]; +arr1.push(...arr2); // -> [1, 2, 3, 4, 5, 6] + +let [a, b, ...arr] = [1, 2, 3, 4, 5]; +a; // -> 1 +b // -> 2 +arr; // -> [3, 4, 5] + +function numArgs(...args) { + return args.length; +} +numArgs(a, b, c); // -> 3 +``` + +In addition to the above, there is currently a proposal to add object rest and spread properties to the spec. They can be used as follows: + +```js + +let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 }; +x; // -> 1 +y; // -> 2 +z; // -> { a: 3, b: 4 } + +let n = { x, y, ...z }; +n; // -> { x: 1, y: 2, a: 3, b: 4 } +``` + +As with other operators, whitespace is allowed between the rest or spread operator and the expression it is operating on, which can lead to inconsistent spacing within a codebase. + +## Rule Details + +This rule aims to enforce consistent spacing between rest and spread operators and their expressions. The rule also supports object rest and spread properties in ES2018: + +```json +{ + "parserOptions": { + "ecmaVersion": 2018 + } +} +``` + +Please read the user guide's section on [configuring parser options](/docs/user-guide/configuring#specifying-parser-options) to learn more. + +## Options + +This rule takes one option: a string with the value of `"never"` or `"always"`. The default value is `"never"`. + +### "never" + +When using the default `"never"` option, whitespace is not allowed between spread operators and their expressions. + +```json +rest-spread-spacing: ["error"] +``` + +or + +```json +rest-spread-spacing: ["error", "never"] +``` + +Examples of **incorrect** code for this rule with `"never"`: + +```js +/*eslint rest-spread-spacing: ["error", "never"]*/ + +fn(... args) +[... arr, 4, 5, 6] +let [a, b, ... arr] = [1, 2, 3, 4, 5]; +function fn(... args) { console.log(args); } +let { x, y, ... z } = { x: 1, y: 2, a: 3, b: 4 }; +let n = { x, y, ... z }; +``` + +Examples of **correct** code for this rule with `"never"`: + +```js +/*eslint rest-spread-spacing: ["error", "never"]*/ + +fn(...args) +[...arr, 4, 5, 6] +let [a, b, ...arr] = [1, 2, 3, 4, 5]; +function fn(...args) { console.log(args); } +let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 }; +let n = { x, y, ...z }; +``` + +### "always" + +When using the `"always"` option, whitespace is required between spread operators and their expressions. + +```json +rest-spread-spacing: ["error", "always"] +``` + +Examples of **incorrect** code for this rule with `"always"`: + +```js +/*eslint rest-spread-spacing:["error", "always"]*/ + +fn(...args) +[...arr, 4, 5, 6] +let [a, b, ...arr] = [1, 2, 3, 4, 5]; +function fn(...args) { console.log(args); } +let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 }; +let n = { x, y, ...z }; +``` + +Examples of **correct** code for this rule with `"always"`: + +```js +/*eslint rest-spread-spacing: ["error", "always"]*/ + +fn(... args) +[... arr, 4, 5, 6] +let [a, b, ... arr] = [1, 2, 3, 4, 5]; +function fn(... args) { console.log(args); } +let { x, y, ... z } = { x: 1, y: 2, a: 3, b: 4 }; +let n = { x, y, ... z }; +``` + +## When Not To Use It + +You can safely disable this rule if you do not care about enforcing consistent spacing between spread operators and their expressions. + +## Further Reading + +* [Object Rest/Spread Properties for ECMAScript](https://github.com/tc39/proposal-object-rest-spread) + +## Version + +This rule was introduced in ESLint 2.12.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/rest-spread-spacing.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/rest-spread-spacing.md) diff --git a/docs/8.0.0/rules/semi-spacing.md b/docs/8.0.0/rules/semi-spacing.md new file mode 100644 index 0000000000..166ef4bd78 --- /dev/null +++ b/docs/8.0.0/rules/semi-spacing.md @@ -0,0 +1,128 @@ +--- +title: semi-spacing - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/semi-spacing.md +rule_type: layout +--- + + +# Enforce spacing before and after semicolons (semi-spacing) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +JavaScript allows you to place unnecessary spaces before or after a semicolon. + +Disallowing or enforcing space around a semicolon can improve the readability of your program. + +```js +var a = "b" ; + +var c = "d";var e = "f"; +``` + +## Rule Details + +This rule aims to enforce spacing around a semicolon. This rule prevents the use of spaces before a semicolon in expressions. + +This rule doesn't check spacing in the following cases: + +* The spacing after the semicolon if it is the first token in the line. + +* The spacing before the semicolon if it is after an opening parenthesis (`(` or `{`), or the spacing after the semicolon if it is before a closing parenthesis (`)` or `}`). That spacing is checked by `space-in-parens` or `block-spacing`. + +* The spacing around the semicolon in a for loop with an empty condition (`for(;;)`). + +## Options + +The rule takes one option, an object, which has two keys `before` and `after` having boolean values `true` or `false`. +If `before` is `true`, space is enforced before semicolons and if it's `false`, space is disallowed before semicolons. +If `after` is `true`, space is enforced after semicolons and if it's `false`, space is disallowed after semicolons. +The `after` option will be only applied if a semicolon is not at the end of line. + +The default is `{"before": false, "after": true}`. + +```json + "semi-spacing": ["error", {"before": false, "after": true}] +``` + +### `{"before": false, "after": true}` + +This is the default option. It enforces spacing after semicolons and disallows spacing before semicolons. + +Examples of **incorrect** code for this rule: + +```js +/*eslint semi-spacing: "error"*/ + +var foo ; +var foo;var bar; +throw new Error("error") ; +while (a) { break ; } +for (i = 0 ; i < 10 ; i++) {} +for (i = 0;i < 10;i++) {} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint semi-spacing: "error"*/ + +var foo; +var foo; var bar; +throw new Error("error"); +while (a) { break; } +for (i = 0; i < 10; i++) {} +for (;;) {} +if (true) {;} +;foo(); +``` + +### `{"before": true, "after": false}` + +This option enforces spacing before semicolons and disallows spacing after semicolons. + +Examples of **incorrect** code for this rule with the `{"before": true, "after": false}` option: + +```js +/*eslint semi-spacing: ["error", { "before": true, "after": false }]*/ + +var foo; +var foo ; var bar; +throw new Error("error"); +while (a) { break; } +for (i = 0;i < 10;i++) {} +for (i = 0; i < 10; i++) {} +``` + +Examples of **correct** code for this rule with the `{"before": true, "after": false}` option: + +```js +/*eslint semi-spacing: ["error", { "before": true, "after": false }]*/ + +var foo ; +var foo ;var bar ; +throw new Error("error") ; +while (a) {break ;} +for (i = 0 ;i < 10 ;i++) {} +``` + +## When Not To Use It + +You can turn this rule off if you are not concerned with the consistency of spacing before or after semicolons. + +## Related Rules + +* [semi](semi) +* [no-extra-semi](no-extra-semi) +* [comma-spacing](comma-spacing) +* [block-spacing](block-spacing) +* [space-in-parens](space-in-parens) + +## Version + +This rule was introduced in ESLint 0.16.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/semi-spacing.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/semi-spacing.md) diff --git a/docs/8.0.0/rules/semi-style.md b/docs/8.0.0/rules/semi-style.md new file mode 100644 index 0000000000..6d6fbbfee7 --- /dev/null +++ b/docs/8.0.0/rules/semi-style.md @@ -0,0 +1,115 @@ +--- +title: semi-style - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/semi-style.md +rule_type: layout +--- + + +# Enforce location of semicolons (semi-style) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +Generally, semicolons are at the end of lines. However, in semicolon-less style, semicolons are at the beginning of lines. This rule enforces that semicolons are at the configured location. + +## Rule Details + +This rule reports line terminators around semicolons. + +This rule has an option. + +```json +{ + "semi-style": ["error", "last"], +} +``` + +- `"last"` (Default) enforces that semicolons are at the end of statements. +- `"first"` enforces that semicolons are at the beginning of statements. Semicolons of `for` loop heads (`for(a;b;c){}`) should be at the end of lines even if you use this option. + +Examples of **incorrect** code for this rule with `"last"` option: + +```js +/*eslint semi-style: ["error", "last"]*/ + +foo() +;[1, 2, 3].forEach(bar) + +for ( + var i = 0 + ; i < 10 + ; ++i +) { + foo() +} +``` + +Examples of **correct** code for this rule with `"last"` option: + +```js +/*eslint semi-style: ["error", "last"]*/ + +foo(); +[1, 2, 3].forEach(bar) + +for ( + var i = 0; + i < 10; + ++i +) { + foo() +} +``` + +Examples of **incorrect** code for this rule with `"first"` option: + +```js +/*eslint semi-style: ["error", "first"]*/ + +foo(); +[1, 2, 3].forEach(bar) + +for ( + var i = 0 + ; i < 10 + ; ++i +) { + foo() +} +``` + +Examples of **correct** code for this rule with `"first"` option: + +```js +/*eslint semi-style: ["error", "first"]*/ + +foo() +;[1, 2, 3].forEach(bar) + +for ( + var i = 0; + i < 10; + ++i +) { + foo() +} +``` + +## When Not To Use It + +If you don't want to notify the location of semicolons, then it's safe to disable this rule. + +## Related rules + +- [no-extra-semi](./no-extra-semi) +- [semi](./semi) +- [semi-spacing](./semi-spacing) + +## Version + +This rule was introduced in ESLint 4.0.0-beta.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/semi-style.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/semi-style.md) diff --git a/docs/8.0.0/rules/semi.md b/docs/8.0.0/rules/semi.md new file mode 100644 index 0000000000..ce2f161ea5 --- /dev/null +++ b/docs/8.0.0/rules/semi.md @@ -0,0 +1,215 @@ +--- +title: semi - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/semi.md +rule_type: layout +--- + + +# require or disallow semicolons instead of ASI (semi) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +JavaScript doesn't require semicolons at the end of each statement. In many cases, the JavaScript engine can determine that a semicolon should be in a certain spot and will automatically add it. This feature is known as **automatic semicolon insertion (ASI)** and is considered one of the more controversial features of JavaScript. For example, the following lines are both valid: + +```js +var name = "ESLint" +var website = "eslint.org"; +``` + +On the first line, the JavaScript engine will automatically insert a semicolon, so this is not considered a syntax error. The JavaScript engine still knows how to interpret the line and knows that the line end indicates the end of the statement. + +In the debate over ASI, there are generally two schools of thought. The first is that we should treat ASI as if it didn't exist and always include semicolons manually. The rationale is that it's easier to always include semicolons than to try to remember when they are or are not required, and thus decreases the possibility of introducing an error. + +However, the ASI mechanism can sometimes be tricky to people who are using semicolons. For example, consider this code: + +```js +return +{ + name: "ESLint" +}; +``` + +This may look like a `return` statement that returns an object literal, however, the JavaScript engine will interpret this code as: + +```js +return; +{ + name: "ESLint"; +} +``` + +Effectively, a semicolon is inserted after the `return` statement, causing the code below it (a labeled literal inside a block) to be unreachable. This rule and the [no-unreachable](no-unreachable) rule will protect your code from such cases. + +On the other side of the argument are those who say that since semicolons are inserted automatically, they are optional and do not need to be inserted manually. However, the ASI mechanism can also be tricky to people who don't use semicolons. For example, consider this code: + +```js +var globalCounter = { } + +(function () { + var n = 0 + globalCounter.increment = function () { + return ++n + } +})() +``` + +In this example, a semicolon will not be inserted after the first line, causing a run-time error (because an empty object is called as if it's a function). The [no-unexpected-multiline](no-unexpected-multiline) rule can protect your code from such cases. + +Although ASI allows for more freedom over your coding style, it can also make your code behave in an unexpected way, whether you use semicolons or not. Therefore, it is best to know when ASI takes place and when it does not, and have ESLint protect your code from these potentially unexpected cases. In short, as once described by Isaac Schlueter, a `\n` character always ends a statement (just like a semicolon) unless one of the following is true: + +1. The statement has an unclosed paren, array literal, or object literal or ends in some other way that is not a valid way to end a statement. (For instance, ending with `.` or `,`.) +1. The line is `--` or `++` (in which case it will decrement/increment the next token.) +1. It is a `for()`, `while()`, `do`, `if()`, or `else`, and there is no `{` +1. The next line starts with `[`, `(`, `+`, `*`, `/`, `-`, `,`, `.`, or some other binary operator that can only be found between two tokens in a single expression. + +## Rule Details + +This rule enforces consistent use of semicolons. + +## Options + +This rule has two options, a string option and an object option. + +String option: + +* `"always"` (default) requires semicolons at the end of statements +* `"never"` disallows semicolons as the end of statements (except to disambiguate statements beginning with `[`, `(`, `/`, `+`, or `-`) + +Object option (when `"always"`): + +* `"omitLastInOneLineBlock": true` ignores the last semicolon in a block in which its braces (and therefore the content of the block) are in the same line + +Object option (when `"never"`): + +* `"beforeStatementContinuationChars": "any"` (default) ignores semicolons (or lacking semicolon) at the end of statements if the next line starts with `[`, `(`, `/`, `+`, or `-`. +* `"beforeStatementContinuationChars": "always"` requires semicolons at the end of statements if the next line starts with `[`, `(`, `/`, `+`, or `-`. +* `"beforeStatementContinuationChars": "never"` disallows semicolons as the end of statements if it doesn't make ASI hazard even if the next line starts with `[`, `(`, `/`, `+`, or `-`. + +### always + +Examples of **incorrect** code for this rule with the default `"always"` option: + +```js +/*eslint semi: ["error", "always"]*/ + +var name = "ESLint" + +object.method = function() { + // ... +} +``` + +Examples of **correct** code for this rule with the default `"always"` option: + +```js +/*eslint semi: "error"*/ + +var name = "ESLint"; + +object.method = function() { + // ... +}; +``` + +### never + +Examples of **incorrect** code for this rule with the `"never"` option: + +```js +/*eslint semi: ["error", "never"]*/ + +var name = "ESLint"; + +object.method = function() { + // ... +}; +``` + +Examples of **correct** code for this rule with the `"never"` option: + +```js +/*eslint semi: ["error", "never"]*/ + +var name = "ESLint" + +object.method = function() { + // ... +} + +var name = "ESLint" + +;(function() { + // ... +})() + +import a from "a" +(function() { + // ... +})() + +import b from "b" +;(function() { + // ... +})() +``` + +#### omitLastInOneLineBlock + +Examples of additional **correct** code for this rule with the `"always", { "omitLastInOneLineBlock": true }` options: + +```js +/*eslint semi: ["error", "always", { "omitLastInOneLineBlock": true}] */ + +if (foo) { bar() } + +if (foo) { bar(); baz() } +``` + +#### beforeStatementContinuationChars + +Examples of additional **incorrect** code for this rule with the `"never", { "beforeStatementContinuationChars": "always" }` options: + +```js +/*eslint semi: ["error", "never", { "beforeStatementContinuationChars": "always"}] */ +import a from "a" + +(function() { + // ... +})() +``` + +Examples of additional **incorrect** code for this rule with the `"never", { "beforeStatementContinuationChars": "never" }` options: + +```js +/*eslint semi: ["error", "never", { "beforeStatementContinuationChars": "never"}] */ +import a from "a" + +;(function() { + // ... +})() +``` + +## When Not To Use It + +If you do not want to enforce semicolon usage (or omission) in any particular way, then you can turn this rule off. + +## Further Reading + +* [An Open Letter to JavaScript Leaders Regarding Semicolons](http://blog.izs.me/post/2353458699/an-open-letter-to-javascript-leaders-regarding) +* [JavaScript Semicolon Insertion](http://inimino.org/~inimino/blog/javascript_semicolons) + +## Related Rules + +* [no-extra-semi](no-extra-semi) +* [no-unexpected-multiline](no-unexpected-multiline) +* [semi-spacing](semi-spacing) + +## Version + +This rule was introduced in ESLint 0.0.6. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/semi.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/semi.md) diff --git a/docs/8.0.0/rules/sort-imports.md b/docs/8.0.0/rules/sort-imports.md new file mode 100644 index 0000000000..2fcb0072ca --- /dev/null +++ b/docs/8.0.0/rules/sort-imports.md @@ -0,0 +1,304 @@ +--- +title: sort-imports - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/sort-imports.md +rule_type: suggestion +--- + + +# Import Sorting (sort-imports) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +The import statement is used to import members (functions, objects or primitives) that have been exported from an external module. Using a specific member syntax: + +```js +// single - Import single member. +import myMember from "my-module.js"; + +// multiple - Import multiple members. +import {foo, bar} from "my-module.js"; + +// all - Import all members, where myModule contains all the exported bindings. +import * as myModule from "my-module.js"; +``` + +The import statement can also import a module without exported bindings. Used when the module does not export anything, but runs it own code or changes the global context object. + +```js +// none - Import module without exported bindings. +import "my-module.js" +``` + +When declaring multiple imports, a sorted list of import declarations make it easier for developers to read the code and find necessary imports later. This rule is purely a matter of style. + + +## Rule Details + +This rule checks all import declarations and verifies that all imports are first sorted by the used member syntax and then alphabetically by the first member or alias name. + +The `--fix` option on the command line automatically fixes some problems reported by this rule: multiple members on a single line are automatically sorted (e.g. `import { b, a } from 'foo.js'` is corrected to `import { a, b } from 'foo.js'`), but multiple lines are not reordered. + +## Options + +This rule accepts an object with its properties as + +* `ignoreCase` (default: `false`) +* `ignoreDeclarationSort` (default: `false`) +* `ignoreMemberSort` (default: `false`) +* `memberSyntaxSortOrder` (default: `["none", "all", "multiple", "single"]`); all 4 items must be present in the array, but you can change the order: + * `none` = import module without exported bindings. + * `all` = import all members provided by exported bindings. + * `multiple` = import multiple members. + * `single` = import single member. +* `allowSeparatedGroups` (default: `false`) + +Default option settings are: + +```json +{ + "sort-imports": ["error", { + "ignoreCase": false, + "ignoreDeclarationSort": false, + "ignoreMemberSort": false, + "memberSyntaxSortOrder": ["none", "all", "multiple", "single"], + "allowSeparatedGroups": false + }] +} +``` + +## Examples + +### Default settings + +Examples of **correct** code for this rule when using default options: + +```js +/*eslint sort-imports: "error"*/ +import 'module-without-export.js'; +import * as bar from 'bar.js'; +import * as foo from 'foo.js'; +import {alpha, beta} from 'alpha.js'; +import {delta, gamma} from 'delta.js'; +import a from 'baz.js'; +import b from 'qux.js'; + +/*eslint sort-imports: "error"*/ +import a from 'foo.js'; +import b from 'bar.js'; +import c from 'baz.js'; + +/*eslint sort-imports: "error"*/ +import 'foo.js' +import * as bar from 'bar.js'; +import {a, b} from 'baz.js'; +import c from 'qux.js'; + +/*eslint sort-imports: "error"*/ +import {a, b, c} from 'foo.js' +``` + +Examples of **incorrect** code for this rule when using default options: + +```js +/*eslint sort-imports: "error"*/ +import b from 'foo.js'; +import a from 'bar.js'; + +/*eslint sort-imports: "error"*/ +import a from 'foo.js'; +import A from 'bar.js'; + +/*eslint sort-imports: "error"*/ +import {b, c} from 'foo.js'; +import {a, b} from 'bar.js'; + +/*eslint sort-imports: "error"*/ +import a from 'foo.js'; +import {b, c} from 'bar.js'; + +/*eslint sort-imports: "error"*/ +import a from 'foo.js'; +import * as b from 'bar.js'; + +/*eslint sort-imports: "error"*/ +import {b, a, c} from 'foo.js' +``` + +### `ignoreCase` + +When `true` the rule ignores the case-sensitivity of the imports local name. + +Examples of **incorrect** code for this rule with the `{ "ignoreCase": true }` option: + +```js +/*eslint sort-imports: ["error", { "ignoreCase": true }]*/ + +import B from 'foo.js'; +import a from 'bar.js'; +``` + +Examples of **correct** code for this rule with the `{ "ignoreCase": true }` option: + +```js +/*eslint sort-imports: ["error", { "ignoreCase": true }]*/ + +import a from 'foo.js'; +import B from 'bar.js'; +import c from 'baz.js'; +``` + +Default is `false`. + +### `ignoreDeclarationSort` + +Ignores the sorting of import declaration statements. + +Examples of **incorrect** code for this rule with the default `{ "ignoreDeclarationSort": false }` option: + +```js +/*eslint sort-imports: ["error", { "ignoreDeclarationSort": false }]*/ +import b from 'foo.js' +import a from 'bar.js' +``` + +Examples of **correct** code for this rule with the `{ "ignoreDeclarationSort": true }` option: + +```js +/*eslint sort-imports: ["error", { "ignoreDeclarationSort": true }]*/ +import a from 'foo.js' +import b from 'bar.js' +``` + +```js +/*eslint sort-imports: ["error", { "ignoreDeclarationSort": true }]*/ +import b from 'foo.js' +import a from 'bar.js' +``` + +Default is `false`. + +### `ignoreMemberSort` + +Ignores the member sorting within a `multiple` member import declaration. + +Examples of **incorrect** code for this rule with the default `{ "ignoreMemberSort": false }` option: + +```js +/*eslint sort-imports: ["error", { "ignoreMemberSort": false }]*/ +import {b, a, c} from 'foo.js' +``` + +Examples of **correct** code for this rule with the `{ "ignoreMemberSort": true }` option: + +```js +/*eslint sort-imports: ["error", { "ignoreMemberSort": true }]*/ +import {b, a, c} from 'foo.js' +``` + +Default is `false`. + +### `memberSyntaxSortOrder` + +There are four different styles and the default member syntax sort order is: + +* `none` - import module without exported bindings. +* `all` - import all members provided by exported bindings. +* `multiple` - import multiple members. +* `single` - import single member. + +All four options must be specified in the array, but you can customize their order. + +Examples of **incorrect** code for this rule with the default `{ "memberSyntaxSortOrder": ["none", "all", "multiple", "single"] }` option: + +```js +/*eslint sort-imports: "error"*/ +import a from 'foo.js'; +import * as b from 'bar.js'; +``` + +Examples of **correct** code for this rule with the `{ "memberSyntaxSortOrder": ['single', 'all', 'multiple', 'none'] }` option: + +```js +/*eslint sort-imports: ["error", { "memberSyntaxSortOrder": ['single', 'all', 'multiple', 'none'] }]*/ + +import a from 'foo.js'; +import * as b from 'bar.js'; +``` + +Examples of **correct** code for this rule with the `{ "memberSyntaxSortOrder": ['all', 'single', 'multiple', 'none'] }` option: + +```js +/*eslint sort-imports: ["error", { "memberSyntaxSortOrder": ['all', 'single', 'multiple', 'none'] }]*/ + +import * as foo from 'foo.js'; +import z from 'zoo.js'; +import {a, b} from 'foo.js'; +``` + +Default is `["none", "all", "multiple", "single"]`. + +### `allowSeparatedGroups` + +When `true` the rule checks the sorting of import declaration statements only for those that appear on consecutive lines. + +In other words, a blank line or a comment line or line with any other statement after an import declaration statement will reset the sorting of import declaration statements. + +Examples of **incorrect** code for this rule with the `{ "allowSeparatedGroups": true }` option: + +```js +/*eslint sort-imports: ["error", { "allowSeparatedGroups": true }]*/ + +import b from 'foo.js'; +import c from 'bar.js'; +import a from 'baz.js'; +``` + +Examples of **correct** code for this rule with the `{ "allowSeparatedGroups": true }` option: + +```js +/*eslint sort-imports: ["error", { "allowSeparatedGroups": true }]*/ + +import b from 'foo.js'; +import c from 'bar.js'; + +import a from 'baz.js'; +``` + +```js +/*eslint sort-imports: ["error", { "allowSeparatedGroups": true }]*/ + +import b from 'foo.js'; +import c from 'bar.js'; +// comment +import a from 'baz.js'; +``` + +```js +/*eslint sort-imports: ["error", { "allowSeparatedGroups": true }]*/ + +import b from 'foo.js'; +import c from 'bar.js'; +quux(); +import a from 'baz.js'; +``` + +Default is `false`. + +## When Not To Use It + +This rule is a formatting preference and not following it won't negatively affect the quality of your code. If alphabetizing imports isn't a part of your coding standards, then you can leave this rule disabled. + +## Related Rules + +* [sort-keys](sort-keys) +* [sort-vars](sort-vars) + +## Version + +This rule was introduced in ESLint 2.0.0-beta.1. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/sort-imports.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/sort-imports.md) diff --git a/docs/8.0.0/rules/sort-keys.md b/docs/8.0.0/rules/sort-keys.md new file mode 100644 index 0000000000..cf37b4a32f --- /dev/null +++ b/docs/8.0.0/rules/sort-keys.md @@ -0,0 +1,245 @@ +--- +title: sort-keys - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/sort-keys.md +rule_type: suggestion +--- + + +# require object keys to be sorted (sort-keys) + +When declaring multiple properties, some developers prefer to sort property names alphabetically to more easily find and/or diff necessary properties at a later time. Others feel that it adds complexity and becomes burden to maintain. + +## Rule Details + +This rule checks all property definitions of object expressions and verifies that all variables are sorted alphabetically. + +Examples of **incorrect** code for this rule: + +```js +/*eslint sort-keys: "error"*/ +/*eslint-env es6*/ + +let obj = {a: 1, c: 3, b: 2}; +let obj = {a: 1, "c": 3, b: 2}; + +// Case-sensitive by default. +let obj = {a: 1, b: 2, C: 3}; + +// Non-natural order by default. +let obj = {1: a, 2: c, 10: b}; + +// This rule checks computed properties which have a simple name as well. +// Simple names are names which are expressed by an Identifier node or a Literal node. +const S = Symbol("s") +let obj = {a: 1, ["c"]: 3, b: 2}; +let obj = {a: 1, [S]: 3, b: 2}; +``` + +Examples of **correct** code for this rule: + +```js +/*eslint sort-keys: "error"*/ +/*eslint-env es6*/ + +let obj = {a: 1, b: 2, c: 3}; +let obj = {a: 1, "b": 2, c: 3}; + +// Case-sensitive by default. +let obj = {C: 3, a: 1, b: 2}; + +// Non-natural order by default. +let obj = {1: a, 10: b, 2: c}; + +// This rule checks computed properties which have a simple name as well. +let obj = {a: 1, ["b"]: 2, c: 3}; +let obj = {a: 1, [b]: 2, c: 3}; + +// This rule ignores computed properties which have a non-simple name. +let obj = {a: 1, [c + d]: 3, b: 2}; +let obj = {a: 1, ["c" + "d"]: 3, b: 2}; +let obj = {a: 1, [`${c}`]: 3, b: 2}; +let obj = {a: 1, [tag`c`]: 3, b: 2}; + +// This rule does not report unsorted properties that are separated by a spread property. +let obj = {b: 1, ...c, a: 2}; +``` + +## Options + +```json +{ + "sort-keys": ["error", "asc", {"caseSensitive": true, "natural": false, "minKeys": 2}] +} +``` + +The 1st option is `"asc"` or `"desc"`. + +* `"asc"` (default) - enforce properties to be in ascending order. +* `"desc"` - enforce properties to be in descending order. + +The 2nd option is an object which has 3 properties. + +* `caseSensitive` - if `true`, enforce properties to be in case-sensitive order. Default is `true`. +* `minKeys` - Specifies the minimum number of keys that an object should have in order for the object's unsorted keys to produce an error. Default is `2`, which means by default all objects with unsorted keys will result in lint errors. +* `natural` - if `true`, enforce properties to be in natural order. Default is `false`. Natural Order compares strings containing combination of letters and numbers in the way a human being would sort. It basically sorts numerically, instead of sorting alphabetically. So the number 10 comes after the number 3 in Natural Sorting. + +Example for a list: + +With `natural` as true, the ordering would be +1 +3 +6 +8 +10 + +With `natural` as false, the ordering would be +1 +10 +3 +6 +8 + +### desc + +Examples of **incorrect** code for the `"desc"` option: + +```js +/*eslint sort-keys: ["error", "desc"]*/ +/*eslint-env es6*/ + +let obj = {b: 2, c: 3, a: 1}; +let obj = {"b": 2, c: 3, a: 1}; + +// Case-sensitive by default. +let obj = {C: 1, b: 3, a: 2}; + +// Non-natural order by default. +let obj = {10: b, 2: c, 1: a}; +``` + +Examples of **correct** code for the `"desc"` option: + +```js +/*eslint sort-keys: ["error", "desc"]*/ +/*eslint-env es6*/ + +let obj = {c: 3, b: 2, a: 1}; +let obj = {c: 3, "b": 2, a: 1}; + +// Case-sensitive by default. +let obj = {b: 3, a: 2, C: 1}; + +// Non-natural order by default. +let obj = {2: c, 10: b, 1: a}; +``` + +### insensitive + +Examples of **incorrect** code for the `{caseSensitive: false}` option: + +```js +/*eslint sort-keys: ["error", "asc", {caseSensitive: false}]*/ +/*eslint-env es6*/ + +let obj = {a: 1, c: 3, C: 4, b: 2}; +let obj = {a: 1, C: 3, c: 4, b: 2}; +``` + +Examples of **correct** code for the `{caseSensitive: false}` option: + +```js +/*eslint sort-keys: ["error", "asc", {caseSensitive: false}]*/ +/*eslint-env es6*/ + +let obj = {a: 1, b: 2, c: 3, C: 4}; +let obj = {a: 1, b: 2, C: 3, c: 4}; +``` + +### natural + +Examples of **incorrect** code for the `{natural: true}` option: + +```js +/*eslint sort-keys: ["error", "asc", {natural: true}]*/ +/*eslint-env es6*/ + +let obj = {1: a, 10: c, 2: b}; +``` + +Examples of **correct** code for the `{natural: true}` option: + +```js +/*eslint sort-keys: ["error", "asc", {natural: true}]*/ +/*eslint-env es6*/ + +let obj = {1: a, 2: b, 10: c}; +``` + +### minKeys + +Examples of **incorrect** code for the `{minKeys: 4}` option: + +```js +/*eslint sort-keys: ["error", "asc", {minKeys: 4}]*/ +/*eslint-env es6*/ + +// 4 keys +let obj = { + b: 2, + a: 1, // not sorted correctly (should be 1st key) + c: 3, + d: 4, +}; + +// 5 keys +let obj = { + 2: 'a', + 1: 'b', // not sorted correctly (should be 1st key) + 3: 'c', + 4: 'd', + 5: 'e', +}; +``` + +Examples of **correct** code for the `{minKeys: 4}` option: + +```js +/*eslint sort-keys: ["error", "asc", {minKeys: 4}]*// +/*eslint-env es6*/ + +// 3 keys +let obj = { + b: 2, + a: 1, + c: 3, +}; + +// 2 keys +let obj = { + 2: 'b', + 1: 'a', +}; +``` + +## When Not To Use It + +If you don't want to notify about properties' order, then it's safe to disable this rule. + +## Related Rules + +* [sort-imports](sort-imports) +* [sort-vars](sort-vars) + +## Compatibility + +* **JSCS:** [validateOrderInObjectKeys](https://jscs-dev.github.io/rule/validateOrderInObjectKeys) + +## Version + +This rule was introduced in ESLint 3.3.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/sort-keys.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/sort-keys.md) diff --git a/docs/8.0.0/rules/sort-vars.md b/docs/8.0.0/rules/sort-vars.md new file mode 100644 index 0000000000..de5e687dd9 --- /dev/null +++ b/docs/8.0.0/rules/sort-vars.md @@ -0,0 +1,97 @@ +--- +title: sort-vars - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/sort-vars.md +rule_type: suggestion +--- + + +# Variable Sorting (sort-vars) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +When declaring multiple variables within the same block, some developers prefer to sort variable names alphabetically to be able to find necessary variable easier at the later time. Others feel that it adds complexity and becomes burden to maintain. + +## Rule Details + +This rule checks all variable declaration blocks and verifies that all variables are sorted alphabetically. +The default configuration of the rule is case-sensitive. + +Examples of **incorrect** code for this rule: + +```js +/*eslint sort-vars: "error"*/ + +var b, a; + +var a, B, c; + +var a, A; +``` + +Examples of **correct** code for this rule: + +```js +/*eslint sort-vars: "error"*/ + +var a, b, c, d; + +var _a = 10; +var _b = 20; + +var A, a; + +var B, a, c; +``` + +Alphabetical list is maintained starting from the first variable and excluding any that are considered problems. So the following code will produce two problems: + +```js +/*eslint sort-vars: "error"*/ + +var c, d, a, b; +``` + +But this one, will only produce one: + +```js +/*eslint sort-vars: "error"*/ + +var c, d, a, e; +``` + +## Options + +This rule has an object option: + +* `"ignoreCase": true` (default `false`) ignores the case-sensitivity of the variables order + +### ignoreCase + +Examples of **correct** code for this rule with the `{ "ignoreCase": true }` option: + +```js +/*eslint sort-vars: ["error", { "ignoreCase": true }]*/ + +var a, A; + +var a, B, c; +``` + +## When Not To Use It + +This rule is a formatting preference and not following it won't negatively affect the quality of your code. If you alphabetizing variables isn't a part of your coding standards, then you can leave this rule off. + +## Related Rules + +* [sort-keys](sort-keys) +* [sort-imports](sort-imports) + +## Version + +This rule was introduced in ESLint 0.2.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/sort-vars.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/sort-vars.md) diff --git a/docs/8.0.0/rules/space-after-function-name.md b/docs/8.0.0/rules/space-after-function-name.md new file mode 100644 index 0000000000..8fe8406390 --- /dev/null +++ b/docs/8.0.0/rules/space-after-function-name.md @@ -0,0 +1,68 @@ +--- +title: space-after-function-name - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/space-after-function-name.md + +--- + + +# space-after-function-name: enforce consistent spacing after name in function definitions + +(removed) This rule was **removed** in ESLint v1.0 and **replaced** by the [space-before-function-paren](space-before-function-paren) rule. + +Whitespace between a function name and its parameter list is optional. + +```js +function withoutSpace(x) { + // ... +} + +function withSpace (x) { + // ... +} +``` + +Some style guides may require a consistent spacing for function names. + +## Rule Details + +This rule aims to enforce a consistent spacing after function names. It takes one argument. If it is `"always"` then all function names must be followed by at least one space. If `"never"` then there should be no spaces between the name and the parameter list. The default is `"never"`. + + +Examples of **incorrect** code for this rule: + +```js +function foo (x) { + // ... +} + +var x = function named (x) {}; + +// When ["error", "always"] +function bar(x) { + // ... +} +``` + +Examples of **correct** code for this rule: + +```js +function foo(x) { + // ... +} + +var x = function named(x) {}; + +// When ["error", "always"] +function bar (x) { + // ... +} +``` + +## Version + +This rule was introduced in ESLint 0.11.0 and removed in 1.0.0-rc-1. + +## Resources + +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/space-after-function-name.md) diff --git a/docs/8.0.0/rules/space-after-keywords.md b/docs/8.0.0/rules/space-after-keywords.md new file mode 100644 index 0000000000..3f75f9f711 --- /dev/null +++ b/docs/8.0.0/rules/space-after-keywords.md @@ -0,0 +1,78 @@ +--- +title: space-after-keywords - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/space-after-keywords.md + +--- + + +# space-after-keywords: enforce consistent spacing after keywords + +(removed) This rule was **removed** in ESLint v2.0 and replaced by the [keyword-spacing](keyword-spacing) rule. + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#--fix) automatically fixed problems reported by this rule. + +Some style guides will require or disallow spaces following the certain keywords. + +```js +if (condition) { + doSomething(); +} else { + doSomethingElse(); +} + +if(condition) { + doSomething(); +}else{ + doSomethingElse(); +} +``` + +## Rule Details + +This rule will enforce consistency of spacing after the keywords `if`, `else`, `for`, `while`, `do`, `switch`, `try`, `catch`, `finally`, and `with`. + +This rule takes one argument. If it is `"always"` then the keywords must be followed by at least one space. If `"never"` +then there should be no spaces following. The default is `"always"`. + +Examples of **incorrect** code for this rule: + +```js +/*eslint space-after-keywords: "error"*/ + +if(a) {} + +if (a) {} else{} + +do{} while (a); +``` + +```js +/*eslint space-after-keywords: ["error", "never"]*/ + +if (a) {} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint space-after-keywords: "error"*/ + +if (a) {} + +if (a) {} else {} +``` + +```js +/*eslint space-after-keywords: ["error", "never"]*/ + +if(a) {} +``` + +## Version + +This rule was introduced in ESLint 0.6.0 and removed in 2.0.0-beta.3. + +## Resources + +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/space-after-keywords.md) diff --git a/docs/8.0.0/rules/space-before-blocks.md b/docs/8.0.0/rules/space-before-blocks.md new file mode 100644 index 0000000000..50fe2bba74 --- /dev/null +++ b/docs/8.0.0/rules/space-before-blocks.md @@ -0,0 +1,232 @@ +--- +title: space-before-blocks - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/space-before-blocks.md +rule_type: layout +--- + + +# Require Or Disallow Space Before Blocks (space-before-blocks) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +Consistency is an important part of any style guide. +While it is a personal preference where to put the opening brace of blocks, +it should be consistent across a whole project. +Having an inconsistent style distracts the reader from seeing the important parts of the code. + +## Rule Details + +This rule will enforce consistency of spacing before blocks. It is only applied on blocks that don’t begin on a new line. + +* This rule ignores spacing which is between `=>` and a block. The spacing is handled by the `arrow-spacing` rule. +* This rule ignores spacing which is between a keyword and a block. The spacing is handled by the `keyword-spacing` rule. + +## Options + +This rule takes one argument. If it is `"always"` then blocks must always have at least one preceding space. If `"never"` +then all blocks should never have any preceding space. If different spacing is desired for function +blocks, keyword blocks and classes, an optional configuration object can be passed as the rule argument to +configure the cases separately. If any value in the configuration object is `"off"`, then neither style will be enforced for blocks of that kind. + +( e.g. `{ "functions": "never", "keywords": "always", "classes": "always" }` ) + +The default is `"always"`. + +### "always" + +Examples of **incorrect** code for this rule with the "always" option: + +```js +/*eslint space-before-blocks: "error"*/ + +if (a){ + b(); +} + +function a(){} + +for (;;){ + b(); +} + +try {} catch(a){} + +class Foo{ + constructor(){} +} +``` + +Examples of **correct** code for this rule with the `"always"` option: + +```js +/*eslint space-before-blocks: "error"*/ + +if (a) { + b(); +} + +if (a) { + b(); +} else{ /*no error. this is checked by `keyword-spacing` rule.*/ + c(); +} + + +function a() {} + +for (;;) { + b(); +} + +try {} catch(a) {} +``` + +### "never" + +Examples of **incorrect** code for this rule with the `"never"` option: + +```js +/*eslint space-before-blocks: ["error", "never"]*/ + +if (a) { + b(); +} + +function a() {} + +for (;;) { + b(); +} + +try {} catch(a) {} +``` + +Examples of **correct** code for this rule with the `"never"` option: + +```js +/*eslint space-before-blocks: ["error", "never"]*/ + +if (a){ + b(); +} + +function a(){} + +for (;;){ + b(); +} + +try{} catch(a){} + +class Foo{ + constructor(){} +} +``` + +Examples of **incorrect** code for this rule when configured `{ "functions": "never", "keywords": "always", "classes": "never" }`: + +```js +/*eslint space-before-blocks: ["error", { "functions": "never", "keywords": "always", "classes": "never" }]*/ +/*eslint-env es6*/ + +function a() {} + +try {} catch(a){} + +class Foo{ + constructor() {} +} +``` + +Examples of **correct** code for this rule when configured `{ "functions": "never", "keywords": "always", "classes": "never" }`: + +```js +/*eslint space-before-blocks: ["error", { "functions": "never", "keywords": "always", "classes": "never" }]*/ +/*eslint-env es6*/ + +for (;;) { + // ... +} + +describe(function(){ + // ... +}); + +class Foo{ + constructor(){} +} +``` + +Examples of **incorrect** code for this rule when configured `{ "functions": "always", "keywords": "never", "classes": "never" }`: + +```js +/*eslint space-before-blocks: ["error", { "functions": "always", "keywords": "never", "classes": "never" }]*/ +/*eslint-env es6*/ + +function a(){} + +try {} catch(a) {} + +class Foo { + constructor(){} +} +``` + +Examples of **correct** code for this rule when configured `{ "functions": "always", "keywords": "never", "classes": "never" }`: + +```js +/*eslint space-before-blocks: ["error", { "functions": "always", "keywords": "never", "classes": "never" }]*/ +/*eslint-env es6*/ + +if (a){ + b(); +} + +var a = function() {} + +class Foo{ + constructor() {} +} +``` + +Examples of **incorrect** code for this rule when configured `{ "functions": "never", "keywords": "never", "classes": "always" }`: + +```js +/*eslint space-before-blocks: ["error", { "functions": "never", "keywords": "never", "classes": "always" }]*/ +/*eslint-env es6*/ + +class Foo{ + constructor(){} +} +``` + +Examples of **correct** code for this rule when configured `{ "functions": "never", "keywords": "never", "classes": "always" }`: + +```js +/*eslint space-before-blocks: ["error", { "functions": "never", "keywords": "never", "classes": "always" }]*/ +/*eslint-env es6*/ + +class Foo { + constructor(){} +} +``` + +## When Not To Use It + +You can turn this rule off if you are not concerned with the consistency of spacing before blocks. + +## Related Rules + +* [keyword-spacing](keyword-spacing) +* [arrow-spacing](arrow-spacing) +* [brace-style](brace-style) + +## Version + +This rule was introduced in ESLint 0.9.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/space-before-blocks.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/space-before-blocks.md) diff --git a/docs/8.0.0/rules/space-before-function-paren.md b/docs/8.0.0/rules/space-before-function-paren.md new file mode 100644 index 0000000000..6ad93654a0 --- /dev/null +++ b/docs/8.0.0/rules/space-before-function-paren.md @@ -0,0 +1,387 @@ +--- +title: space-before-function-paren - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/space-before-function-paren.md +rule_type: layout +--- + + +# Require or disallow a space before function parenthesis (space-before-function-paren) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +When formatting a function, whitespace is allowed between the function name or `function` keyword and the opening paren. Named functions also require a space between the `function` keyword and the function name, but anonymous functions require no whitespace. For example: + +```js +function withoutSpace(x) { + // ... +} + +function withSpace (x) { + // ... +} + +var anonymousWithoutSpace = function() {}; + +var anonymousWithSpace = function () {}; +``` + +Style guides may require a space after the `function` keyword for anonymous functions, while others specify no whitespace. Similarly, the space after a function name may or may not be required. + +## Rule Details + +This rule aims to enforce consistent spacing before function parentheses and as such, will warn whenever whitespace doesn't match the preferences specified. + +## Options + +This rule has a string option or an object option: + +```js +{ + "space-before-function-paren": ["error", "always"], + // or + "space-before-function-paren": ["error", { + "anonymous": "always", + "named": "always", + "asyncArrow": "always" + }], +} +``` + +* `always` (default) requires a space followed by the `(` of arguments. +* `never` disallows any space followed by the `(` of arguments. + +The string option does not check async arrow function expressions for backward compatibility. + +You can also use a separate option for each type of function. +Each of the following options can be set to `"always"`, `"never"`, or `"ignore"`. The default is `"always"`. + +* `anonymous` is for anonymous function expressions (e.g. `function () {}`). +* `named` is for named function expressions (e.g. `function foo () {}`). +* `asyncArrow` is for async arrow function expressions (e.g. `async () => {}`). + +### "always" + +Examples of **incorrect** code for this rule with the default `"always"` option: + +```js +/*eslint space-before-function-paren: "error"*/ +/*eslint-env es6*/ + +function foo() { + // ... +} + +var bar = function() { + // ... +}; + +var bar = function foo() { + // ... +}; + +class Foo { + constructor() { + // ... + } +} + +var foo = { + bar() { + // ... + } +}; + +var foo = async() => 1 +``` + +Examples of **correct** code for this rule with the default `"always"` option: + +```js +/*eslint space-before-function-paren: "error"*/ +/*eslint-env es6*/ + +function foo () { + // ... +} + +var bar = function () { + // ... +}; + +var bar = function foo () { + // ... +}; + +class Foo { + constructor () { + // ... + } +} + +var foo = { + bar () { + // ... + } +}; + +var foo = async () => 1 +``` + +### "never" + +Examples of **incorrect** code for this rule with the `"never"` option: + +```js +/*eslint space-before-function-paren: ["error", "never"]*/ +/*eslint-env es6*/ + +function foo () { + // ... +} + +var bar = function () { + // ... +}; + +var bar = function foo () { + // ... +}; + +class Foo { + constructor () { + // ... + } +} + +var foo = { + bar () { + // ... + } +}; + +var foo = async () => 1 +``` + +Examples of **correct** code for this rule with the `"never"` option: + +```js +/*eslint space-before-function-paren: ["error", "never"]*/ +/*eslint-env es6*/ + +function foo() { + // ... +} + +var bar = function() { + // ... +}; + +var bar = function foo() { + // ... +}; + +class Foo { + constructor() { + // ... + } +} + +var foo = { + bar() { + // ... + } +}; + +var foo = async() => 1 +``` + +### `{"anonymous": "always", "named": "never", "asyncArrow": "always"}` + +Examples of **incorrect** code for this rule with the `{"anonymous": "always", "named": "never", "asyncArrow": "always"}` option: + +```js +/*eslint space-before-function-paren: ["error", {"anonymous": "always", "named": "never", "asyncArrow": "always"}]*/ +/*eslint-env es6*/ + +function foo () { + // ... +} + +var bar = function() { + // ... +}; + +class Foo { + constructor () { + // ... + } +} + +var foo = { + bar () { + // ... + } +}; + +var foo = async(a) => await a +``` + +Examples of **correct** code for this rule with the `{"anonymous": "always", "named": "never", "asyncArrow": "always"}` option: + +```js +/*eslint space-before-function-paren: ["error", {"anonymous": "always", "named": "never", "asyncArrow": "always"}]*/ +/*eslint-env es6*/ + +function foo() { + // ... +} + +var bar = function () { + // ... +}; + +class Foo { + constructor() { + // ... + } +} + +var foo = { + bar() { + // ... + } +}; + +var foo = async (a) => await a +``` + +### `{"anonymous": "never", "named": "always"}` + +Examples of **incorrect** code for this rule with the `{"anonymous": "never", "named": "always"}` option: + +```js +/*eslint space-before-function-paren: ["error", { "anonymous": "never", "named": "always" }]*/ +/*eslint-env es6*/ + +function foo() { + // ... +} + +var bar = function () { + // ... +}; + +class Foo { + constructor() { + // ... + } +} + +var foo = { + bar() { + // ... + } +}; +``` + +Examples of **correct** code for this rule with the `{"anonymous": "never", "named": "always"}` option: + +```js +/*eslint space-before-function-paren: ["error", { "anonymous": "never", "named": "always" }]*/ +/*eslint-env es6*/ + +function foo () { + // ... +} + +var bar = function() { + // ... +}; + +class Foo { + constructor () { + // ... + } +} + +var foo = { + bar () { + // ... + } +}; +``` + +### `{"anonymous": "ignore", "named": "always"}` + +Examples of **incorrect** code for this rule with the `{"anonymous": "ignore", "named": "always"}` option: + +```js +/*eslint space-before-function-paren: ["error", { "anonymous": "ignore", "named": "always" }]*/ +/*eslint-env es6*/ + +function foo() { + // ... +} + +class Foo { + constructor() { + // ... + } +} + +var foo = { + bar() { + // ... + } +}; +``` + +Examples of **correct** code for this rule with the `{"anonymous": "ignore", "named": "always"}` option: + +```js +/*eslint space-before-function-paren: ["error", { "anonymous": "ignore", "named": "always" }]*/ +/*eslint-env es6*/ + +var bar = function() { + // ... +}; + +var bar = function () { + // ... +}; + +function foo () { + // ... +} + +class Foo { + constructor () { + // ... + } +} + +var foo = { + bar () { + // ... + } +}; +``` + +## When Not To Use It + +You can turn this rule off if you are not concerned with the consistency of spacing before function parenthesis. + +## Related Rules + +* [space-after-keywords](space-after-keywords) +* [space-return-throw-case](space-return-throw-case) + +## Version + +This rule was introduced in ESLint 0.18.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/space-before-function-paren.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/space-before-function-paren.md) diff --git a/docs/8.0.0/rules/space-before-function-parentheses.md b/docs/8.0.0/rules/space-before-function-parentheses.md new file mode 100644 index 0000000000..dd58287039 --- /dev/null +++ b/docs/8.0.0/rules/space-before-function-parentheses.md @@ -0,0 +1,276 @@ +--- +title: space-before-function-parentheses - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/space-before-function-parentheses.md + +--- + + +# space-before-function-parentheses: enforce consistent spacing before opening parenthesis in function definitions + +(removed) This rule was **removed** in ESLint v1.0 and **replaced** by the [space-before-function-paren](space-before-function-paren) rule. The name of the rule changed from "parentheses" to "paren" for consistency with the names of other rules. + +When formatting a function, whitespace is allowed between the function name or `function` keyword and the opening paren. Named functions also require a space between the `function` keyword and the function name, but anonymous functions require no whitespace. For example: + +```js +function withoutSpace(x) { + // ... +} + +function withSpace (x) { + // ... +} + +var anonymousWithoutSpace = function() {}; + +var anonymousWithSpace = function () {}; +``` + +Style guides may require a space after the `function` keyword for anonymous functions, while others specify no whitespace. Similarly, the space after a function name may or may not be required. + +## Rule Details + +This rule aims to enforce consistent spacing before function parentheses and as such, will warn whenever whitespace doesn't match the preferences specified. + +This rule takes one argument. If it is `"always"`, which is the default option, all named functions and anonymous functions must have space before function parentheses. If `"never"` then all named functions and anonymous functions must not have space before function parentheses. If you want different spacing for named and anonymous functions you can pass a configuration object as the rule argument to configure those separately (e. g. `{"anonymous": "always", "named": "never"}`). + +Examples of **incorrect** code for this rule with the default `"always"` option: + +```js +/*eslint-env es6*/ + +function foo() { + // ... +} + +var bar = function() { + // ... +}; + +var bar = function foo() { + // ... +}; + +class Foo { + constructor() { + // ... + } +} + +var foo = { + bar() { + // ... + } +}; +``` + +Examples of **correct** code for this rule with the default `"always"` option: + +```js +/*eslint-env es6*/ + +function foo () { + // ... +} + +var bar = function () { + // ... +}; + +var bar = function foo () { + // ... +}; + +class Foo { + constructor () { + // ... + } +} + +var foo = { + bar () { + // ... + } +}; +``` + +Examples of **incorrect** code for this rule with the `"never"` option: + +```js +/*eslint-env es6*/ + +function foo () { + // ... +} + +var bar = function () { + // ... +}; + +var bar = function foo () { + // ... +}; + +class Foo { + constructor () { + // ... + } +} + +var foo = { + bar () { + // ... + } +}; +``` + +Examples of **correct** code for this rule with the `"never"` option: + +```js +/*eslint-env es6*/ + +function foo() { + // ... +} + +var bar = function() { + // ... +}; + +var bar = function foo() { + // ... +}; + +class Foo { + constructor() { + // ... + } +} + +var foo = { + bar() { + // ... + } +}; +``` + +Examples of **incorrect** code for this rule with the `{"anonymous": "always", "named": "never"}` option: + +```js +/*eslint-env es6*/ + +function foo () { + // ... +} + +var bar = function() { + // ... +}; + +class Foo { + constructor () { + // ... + } +} + +var foo = { + bar () { + // ... + } +}; +``` + +Examples of **correct** code for this rule with the `{"anonymous": "always", "named": "never"}` option: + +```js +/*eslint-env es6*/ + +function foo() { + // ... +} + +var bar = function () { + // ... +}; + +class Foo { + constructor() { + // ... + } +} + +var foo = { + bar() { + // ... + } +}; +``` + +Examples of **incorrect** code for this rule with the `{"anonymous": "never", "named": "always"}` option: + +```js +/*eslint-env es6*/ + +function foo() { + // ... +} + +var bar = function () { + // ... +}; + +class Foo { + constructor() { + // ... + } +} + +var foo = { + bar() { + // ... + } +}; +``` + +Examples of **correct** code for this rule with the `{"anonymous": "never", "named": "always"}` option: + +```js +/*eslint-env es6*/ + +function foo () { + // ... +} + +var bar = function() { + // ... +}; + +class Foo { + constructor () { + // ... + } +} + +var foo = { + bar () { + // ... + } +}; +``` + +## When Not To Use It + +You can turn this rule off if you are not concerned with the consistency of spacing before function parenthesis. + +## Related Rules + +* [space-after-keywords](space-after-keywords) +* [space-return-throw-case](space-return-throw-case) + +## Version + +This rule was introduced in ESLint 0.15.0 and removed in 1.0.0-rc-1. + +## Resources + +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/space-before-function-parentheses.md) diff --git a/docs/8.0.0/rules/space-before-keywords.md b/docs/8.0.0/rules/space-before-keywords.md new file mode 100644 index 0000000000..1c3a5ea4af --- /dev/null +++ b/docs/8.0.0/rules/space-before-keywords.md @@ -0,0 +1,130 @@ +--- +title: space-before-keywords - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/space-before-keywords.md + +--- + + +# space-before-keywords: enforce consistent spacing before keywords + +(removed) This rule was **removed** in ESLint v2.0 and **replaced** by the [keyword-spacing](keyword-spacing) rule. + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#--fix) automatically fixed problems reported by this rule. + +Keywords are syntax elements of JavaScript, such as `function` and `if`. These identifiers have special meaning to the language and so often appear in a different color in code editors. As an important part of the language, style guides often refer to the spacing that should be used around keywords. For example, you might have a style guide that says keywords should be always be preceded by spaces, which would mean `if-else` statements must look like this: + +```js +if (foo) { + // ... +} else { + // ... +} +``` + +Of course, you could also have a style guide that disallows spaces before keywords. + +## Rule Details + +This rule will enforce consistency of spacing before the keywords `if`, `else`, `for`, +`while`, `do`, `switch`, `throw`, `try`, `catch`, `finally`, `with`, `break`, `continue`, +`return`, `function`, `yield`, `class` and variable declarations (`let`, `const`, `var`) +and label statements. + +This rule takes one argument: `"always"` or `"never"`. If `"always"` then the keywords +must be preceded by at least one space. If `"never"` then no spaces will be allowed before +the keywords `else`, `while` (do...while), `finally` and `catch`. The default value is `"always"`. + +This rule will allow keywords to be preceded by an opening curly brace (`{`). If you wish to alter +this behavior, consider using the [block-spacing](block-spacing) rule. + +Examples of **incorrect** code for this rule with the default `"always"` option: + +```js +/*eslint space-before-keywords: ["error", "always"]*/ +/*eslint-env es6*/ + +if (foo) { + // ... +}else {} + +const foo = 'bar';let baz = 'qux'; + +var foo =function bar () {} + +function bar() { + if (foo) {return; } +} +``` + +Examples of **correct** code for this rule with the default `"always"` option: + +```js +/*eslint space-before-keywords: ["error", "always"]*/ +/*eslint-env es6*/ + +if (foo) { + // ... +} else {} + +(function() {})() + + + +for (let foo of ['bar', 'baz', 'qux']) {} +``` + +Examples of **incorrect** code for this rule with the `"never"` option: + +```js +/*eslint space-before-keywords: ["error", "never"]*/ + +if (foo) { + // ... +} else {} + +do { + +} +while (foo) + +try {} finally {} + +try {} catch(e) {} +``` + +Examples of **correct** code for this rule with the `"never"` option: + +```js +/*eslint space-before-keywords: ["error", "never"]*/ + +if (foo) { + // ... +}else {} + +do {}while (foo) + +try {}finally {} + +try{}catch(e) {} +``` + +## When Not To Use It + +If you do not wish to enforce consistency on keyword spacing. + +## Related Rules + +* [space-after-keywords](space-after-keywords) +* [block-spacing](block-spacing) +* [space-return-throw-case](space-return-throw-case) +* [space-unary-ops](space-unary-ops) +* [space-infix-ops](space-infix-ops) + +## Version + +This rule was introduced in ESLint 1.4.0 and removed in 2.0.0-beta.3. + +## Resources + +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/space-before-keywords.md) diff --git a/docs/8.0.0/rules/space-in-brackets.md b/docs/8.0.0/rules/space-in-brackets.md new file mode 100644 index 0000000000..f719cee997 --- /dev/null +++ b/docs/8.0.0/rules/space-in-brackets.md @@ -0,0 +1,324 @@ +--- +title: space-in-brackets - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/space-in-brackets.md + +--- + + +# space-in-brackets: enforce consistent spacing inside braces of object literals and brackets of array literals + +(removed) This rule was **removed** in ESLint v1.0 and **replaced** by the [object-curly-spacing](object-curly-spacing) and [array-bracket-spacing](array-bracket-spacing) rules. + +While formatting preferences are very personal, a number of style guides require or disallow spaces between brackets: + +```js +var obj = { foo: 'bar' }; +var arr = [ 'foo', 'bar' ]; +foo[ 'bar' ]; + +var obj = {foo: 'bar'}; +var arr = ['foo', 'bar']; +foo['bar']; +``` + +## Rule Details + +This rule aims to maintain consistency around the spacing inside of square brackets, either by disallowing spaces inside of brackets between the brackets and other tokens or enforcing spaces. Brackets that are separated from the adjacent value by a new line are excepted from this rule, as this is a common pattern. Object literals that are used as the first or last element in an array are also ignored. + +## Options + +There are two options for this rule: + +* `"always"` enforces a space inside of object and array literals +* `"never"` enforces zero spaces inside of object and array literals (default) + +Depending on your coding conventions, you can choose either option by specifying it in your configuration: + +```json +"space-in-brackets": ["error", "always"] +``` + +### "never" + +Examples of **incorrect** code for this rule with the default `"never"` option: + +```js +/*eslint-env es6*/ + +foo[ 'bar' ]; +foo['bar' ]; + +var arr = [ 'foo', 'bar' ]; +var arr = ['foo', 'bar' ]; +var arr = [ ['foo'], 'bar']; +var arr = [[ 'foo' ], 'bar']; +var arr = ['foo', + 'bar' +]; + +var obj = { 'foo': 'bar' }; +var obj = {'foo': 'bar' }; +var obj = { baz: {'foo': 'qux'}, bar}; +var obj = {baz: { 'foo': 'qux' }, bar}; +``` + +Examples of **correct** code for this rule with the default `"never"` option: + +```js +// When options are ["error", "never"] + +foo['bar']; +foo[ + 'bar' +]; +foo[ + 'bar']; + +var arr = []; +var arr = ['foo', 'bar', 'baz']; +var arr = [['foo'], 'bar', 'baz']; +var arr = [ + 'foo', + 'bar', + 'baz' +]; + +var arr = [ + 'foo', + 'bar']; + +var obj = {'foo': 'bar'}; + +var obj = {'foo': {'bar': 'baz'}, 'qux': 'quxx'}; + +var obj = { + 'foo': 'bar' +}; +var obj = {'foo': 'bar' +}; +var obj = { + 'foo':'bar'}; + +var obj = {}; +``` + +### "always" + +Examples of **incorrect** code for this rule with the `"always"` option: + +```js +/*eslint-env es6*/ + +foo['bar']; +foo['bar' ]; +foo[ 'bar']; + +var arr = ['foo', 'bar']; +var arr = ['foo', 'bar' ]; +var arr = [ ['foo'], 'bar' ]; +var arr = ['foo', + 'bar' +]; + +var arr = [ + 'foo', + 'bar']; + +var obj = {'foo': 'bar'}; +var obj = {'foo': 'bar' }; +var obj = { baz: {'foo': 'qux'}, bar}; +var obj = {baz: { 'foo': 'qux' }, bar}; +var obj = {'foo': 'bar' +}; + +var obj = { + 'foo':'bar'}; +``` + +Examples of **correct** code for this rule with the `"always"` option: + +```js +foo[ 'bar' ]; +foo[ + 'bar' +]; + +var arr = []; +var arr = [ 'foo', 'bar', 'baz' ]; +var arr = [ [ 'foo' ], 'bar', 'baz' ]; + +var arr = [ + 'foo', + 'bar', + 'baz' +]; + +var obj = {}; +var obj = { 'foo': 'bar' }; +var obj = { 'foo': { 'bar': 'baz' }, 'qux': 'quxx' }; +var obj = { + 'foo': 'bar' +}; +``` + +Note that `"always"` has a special case where `{}` and `[]` are not considered problems. + +### Exceptions + +An object literal may be used as a third array item to specify spacing exceptions. These exceptions work in the context of the first option. That is, if `"always"` is set to enforce spacing and an exception is set to `false`, it will disallow spacing for cases matching the exception. Likewise, if `"never"` is set to disallow spacing and an exception is set to `true`, it will enforce spacing for cases matching the exception. + +You can add exceptions like so: + +In case of `"always"` option, set an exception to `false` to enable it: + +```json +"space-in-brackets": ["error", "always", { + "singleValue": false, + "objectsInArrays": false, + "arraysInArrays": false, + "arraysInObjects": false, + "objectsInObjects": false, + "propertyName": false +}] +``` + +In case of `"never"` option, set an exception to `true` to enable it: + +```json +"space-in-brackets": ["error", "never", { + "singleValue": true, + "objectsInArrays": true, + "arraysInArrays": true, + "arraysInObjects": true, + "objectsInObjects": true, + "propertyName": true +}] +``` + +The following exceptions are available: + +* `singleValue` sets the spacing of a single value inside of square brackets of an array. +* `objectsInArrays` sets the spacings between the curly braces and square brackets of object literals that are the first or last element in an array. +* `arraysInArrays` sets the spacing between the square brackets of array literals that are the first or last element in an array. +* `arraysInObjects` sets the spacing between the square bracket and the curly brace of an array literal that is the last element in an object. +* `objectsInObjects` sets the spacing between the curly brace of an object literal that is the last element in an object and the curly brace of the containing object. +* `propertyName` sets the spacing in square brackets of computed member expressions. + +In each of the following examples, the `"always"` option is assumed. + +Examples of **incorrect** code for this rule when `"singleValue"` is set to `false`: + +```js +var foo = [ 'foo' ]; +var foo = [ 'foo']; +var foo = ['foo' ]; +var foo = [ 1 ]; +var foo = [ 1]; +var foo = [1 ]; +var foo = [ [ 1, 2 ] ]; +var foo = [ { 'foo': 'bar' } ]; +``` + +Examples of **correct** code for this rule when `"singleValue"` is set to `false`: + +```js +var foo = ['foo']; +var foo = [1]; +var foo = [[ 1, 1 ]]; +var foo = [{ 'foo': 'bar' }]; +``` + +Examples of **incorrect** code when `"objectsInArrays"` is set to `false`: + +```js +var arr = [ { 'foo': 'bar' } ]; +var arr = [ { + 'foo': 'bar' +} ] +``` + +Examples of **correct** code when `"objectsInArrays"` is set to `false`: + + +```js +var arr = [{ 'foo': 'bar' }]; +var arr = [{ + 'foo': 'bar' +}]; +``` + +Examples of **incorrect** code when `"arraysInArrays"` is set to `false`: + +```js +var arr = [ [ 1, 2 ], 2, 3, 4 ]; +var arr = [ [ 1, 2 ], 2, [ 3, 4 ] ]; +``` + +Examples of **correct** code when `"arraysInArrays"` is set to `false`: + +```js +var arr = [[ 1, 2 ], 2, 3, 4 ]; +var arr = [[ 1, 2 ], 2, [ 3, 4 ]]; +``` + +Examples of **incorrect** code when `"arraysInObjects"` is set to `false`: + +```js +var obj = { "foo": [ 1, 2 ] }; +var obj = { "foo": [ "baz", "bar" ] }; +``` + +Examples of **correct** code when `"arraysInObjects"` is set to `false`: + +```js +var obj = { "foo": [ 1, 2 ]}; +var obj = { "foo": [ "baz", "bar" ]}; +``` + +Examples of **incorrect** code when `"objectsInObjects"` is set to `false`: + +```js +var obj = { "foo": { "baz": 1, "bar": 2 } }; +var obj = { "foo": [ "baz", "bar" ], "qux": { "baz": 1, "bar": 2 } }; +``` + +Examples of **correct** code when `"objectsInObjects"` is set to `false`: + +```js +var obj = { "foo": { "baz": 1, "bar": 2 }}; +var obj = { "foo": [ "baz", "bar" ], "qux": { "baz": 1, "bar": 2 }}; +``` + +Examples of **incorrect** code when `"propertyName"` is set to `false`: + +```js +var foo = obj[ 1 ]; +var foo = obj[ bar ]; +``` + +Examples of **correct** code when `"propertyName"` is set to `false`: + +```js +var foo = obj[bar]; +var foo = obj[0, 1]; +``` + +## When Not To Use It + +You can turn this rule off if you are not concerned with the consistency of spacing between brackets. + +## Related Rules + +* [array-bracket-spacing](array-bracket-spacing) +* [object-curly-spacing](object-curly-spacing) +* [space-in-parens](space-in-parens) +* [computed-property-spacing](computed-property-spacing) + +## Version + +This rule was introduced in ESLint 0.4.1 and removed in 1.0.0-rc-1. + +## Resources + +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/space-in-brackets.md) diff --git a/docs/8.0.0/rules/space-in-parens.md b/docs/8.0.0/rules/space-in-parens.md new file mode 100644 index 0000000000..213f84b352 --- /dev/null +++ b/docs/8.0.0/rules/space-in-parens.md @@ -0,0 +1,311 @@ +--- +title: space-in-parens - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/space-in-parens.md +rule_type: layout +--- + + +# Disallow or enforce spaces inside of parentheses (space-in-parens) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +Some style guides require or disallow spaces inside of parentheses: + +```js +foo( 'bar' ); +var x = ( 1 + 2 ) * 3; + +foo('bar'); +var x = (1 + 2) * 3; +``` + +## Rule Details + +This rule will enforce consistent spacing directly inside of parentheses, by disallowing or requiring one or more spaces to the right of `(` and to the left of `)`. + +As long as you do not explicitly disallow empty parentheses using the `"empty"` exception , `()` will be allowed. + +## Options + +There are two options for this rule: + +* `"never"` (default) enforces zero spaces inside of parentheses +* `"always"` enforces a space inside of parentheses + +Depending on your coding conventions, you can choose either option by specifying it in your configuration: + +```json +"space-in-parens": ["error", "always"] +``` + +### "never" + +Examples of **incorrect** code for this rule with the default `"never"` option: + +```js +/*eslint space-in-parens: ["error", "never"]*/ + +foo( ); + +foo( 'bar'); +foo('bar' ); +foo( 'bar' ); + +foo( /* bar */ ); + +var foo = ( 1 + 2 ) * 3; +( function () { return 'bar'; }() ); +``` + +Examples of **correct** code for this rule with the default `"never"` option: + +```js +/*eslint space-in-parens: ["error", "never"]*/ + +foo(); + +foo('bar'); + +foo(/* bar */); + +var foo = (1 + 2) * 3; +(function () { return 'bar'; }()); +``` + +### "always" + +Examples of **incorrect** code for this rule with the `"always"` option: + +```js +/*eslint space-in-parens: ["error", "always"]*/ + +foo( 'bar'); +foo('bar' ); +foo('bar'); + +foo(/* bar */); + +var foo = (1 + 2) * 3; +(function () { return 'bar'; }()); +``` + +Examples of **correct** code for this rule with the `"always"` option: + +```js +/*eslint space-in-parens: ["error", "always"]*/ + +foo(); +foo( ); + +foo( 'bar' ); + +foo( /* bar */ ); + +var foo = ( 1 + 2 ) * 3; +( function () { return 'bar'; }() ); +``` + +### Exceptions + +An object literal may be used as a third array item to specify exceptions, with the key `"exceptions"` and an array as the value. These exceptions work in the context of the first option. That is, if `"always"` is set to enforce spacing, then any "exception" will *disallow* spacing. Conversely, if `"never"` is set to disallow spacing, then any "exception" will *enforce* spacing. + +Note that this rule only enforces spacing within parentheses; it does not check spacing within curly or square brackets, but will enforce or disallow spacing of those brackets if and only if they are adjacent to an opening or closing parenthesis. + +The following exceptions are available: `["{}", "[]", "()", "empty"]`. + +### Empty Exception + +Empty parens exception and behavior: + +* `always` allows for both `()` and `( )` +* `never` (default) requires `()` +* `always` excepting `empty` requires `()` +* `never` excepting `empty` requires `( )` (empty parens without a space is here forbidden) + +### Examples + +Examples of **incorrect** code for this rule with the `"never", { "exceptions": ["{}"] }` option: + +```js +/*eslint space-in-parens: ["error", "never", { "exceptions": ["{}"] }]*/ + +foo({bar: 'baz'}); +foo(1, {bar: 'baz'}); +``` + +Examples of **correct** code for this rule with the `"never", { "exceptions": ["{}"] }` option: + +```js +/*eslint space-in-parens: ["error", "never", { "exceptions": ["{}"] }]*/ + +foo( {bar: 'baz'} ); +foo(1, {bar: 'baz'} ); +``` + +Examples of **incorrect** code for this rule with the `"always", { "exceptions": ["{}"] }` option: + +```js +/*eslint space-in-parens: ["error", "always", { "exceptions": ["{}"] }]*/ + +foo( {bar: 'baz'} ); +foo( 1, {bar: 'baz'} ); +``` + +Examples of **correct** code for this rule with the `"always", { "exceptions": ["{}"] }` option: + +```js +/*eslint space-in-parens: ["error", "always", { "exceptions": ["{}"] }]*/ + +foo({bar: 'baz'}); +foo( 1, {bar: 'baz'}); +``` + +Examples of **incorrect** code for this rule with the `"never", { "exceptions": ["[]"] }` option: + +```js +/*eslint space-in-parens: ["error", "never", { "exceptions": ["[]"] }]*/ + +foo([bar, baz]); +foo([bar, baz], 1); +``` + +Examples of **correct** code for this rule with the `"never", { "exceptions": ["[]"] }` option: + +```js +/*eslint space-in-parens: ["error", "never", { "exceptions": ["[]"] }]*/ + +foo( [bar, baz] ); +foo( [bar, baz], 1); +``` + +Examples of **incorrect** code for this rule with the `"always", { "exceptions": ["[]"] }` option: + +```js +/*eslint space-in-parens: ["error", "always", { "exceptions": ["[]"] }]*/ + +foo( [bar, baz] ); +foo( [bar, baz], 1 ); +``` + +Examples of **correct** code for this rule with the `"always", { "exceptions": ["[]"] }` option: + +```js +/*eslint space-in-parens: ["error", "always", { "exceptions": ["[]"] }]*/ + +foo([bar, baz]); +foo([bar, baz], 1 ); +``` + +Examples of **incorrect** code for this rule with the `"never", { "exceptions": ["()"] }]` option: + +```js +/*eslint space-in-parens: ["error", "never", { "exceptions": ["()"] }]*/ + +foo((1 + 2)); +foo((1 + 2), 1); +foo(bar()); +``` + +Examples of **correct** code for this rule with the `"never", { "exceptions": ["()"] }]` option: + +```js +/*eslint space-in-parens: ["error", "never", { "exceptions": ["()"] }]*/ + +foo( (1 + 2) ); +foo( (1 + 2), 1); +foo(bar() ); +``` + +Examples of **incorrect** code for this rule with the `"always", { "exceptions": ["()"] }]` option: + +```js +/*eslint space-in-parens: ["error", "always", { "exceptions": ["()"] }]*/ + +foo( ( 1 + 2 ) ); +foo( ( 1 + 2 ), 1 ); +``` + +Examples of **correct** code for this rule with the `"always", { "exceptions": ["()"] }]` option: + +```js +/*eslint space-in-parens: ["error", "always", { "exceptions": ["()"] }]*/ + +foo(( 1 + 2 )); +foo(( 1 + 2 ), 1 ); +``` + +The `"empty"` exception concerns empty parentheses, and works the same way as the other exceptions, inverting the first option. + +Example of **incorrect** code for this rule with the `"never", { "exceptions": ["empty"] }]` option: + +```js +/*eslint space-in-parens: ["error", "never", { "exceptions": ["empty"] }]*/ + +foo(); +``` + +Example of **correct** code for this rule with the `"never", { "exceptions": ["empty"] }]` option: + +```js +/*eslint space-in-parens: ["error", "never", { "exceptions": ["empty"] }]*/ + +foo( ); +``` + +Example of **incorrect** code for this rule with the `"always", { "exceptions": ["empty"] }]` option: + +```js +/*eslint space-in-parens: ["error", "always", { "exceptions": ["empty"] }]*/ + +foo( ); +``` + +Example of **correct** code for this rule with the `"always", { "exceptions": ["empty"] }]` option: + +```js +/*eslint space-in-parens: ["error", "always", { "exceptions": ["empty"] }]*/ + +foo(); +``` + +You can include multiple entries in the `"exceptions"` array. + +Examples of **incorrect** code for this rule with the `"always", { "exceptions": ["{}", "[]"] }]` option: + +```js +/*eslint space-in-parens: ["error", "always", { "exceptions": ["{}", "[]"] }]*/ + +bar( {bar:'baz'} ); +baz( 1, [1,2] ); +foo( {bar: 'baz'}, [1, 2] ); +``` + +Examples of **correct** code for this rule with the `"always", { "exceptions": ["{}", "[]"] }]` option: + +```js +/*eslint space-in-parens: ["error", "always", { "exceptions": ["{}", "[]"] }]*/ + +bar({bar:'baz'}); +baz( 1, [1,2]); +foo({bar: 'baz'}, [1, 2]); +``` + +## When Not To Use It + +You can turn this rule off if you are not concerned with the consistency of spacing between parentheses. + +## Related Rules + +* [array-bracket-spacing](array-bracket-spacing) +* [object-curly-spacing](object-curly-spacing) +* [computed-property-spacing](computed-property-spacing) + +## Version + +This rule was introduced in ESLint 0.8.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/space-in-parens.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/space-in-parens.md) diff --git a/docs/8.0.0/rules/space-infix-ops.md b/docs/8.0.0/rules/space-infix-ops.md new file mode 100644 index 0000000000..8ced7e875d --- /dev/null +++ b/docs/8.0.0/rules/space-infix-ops.md @@ -0,0 +1,98 @@ +--- +title: space-infix-ops - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/space-infix-ops.md +rule_type: layout +--- + + +# require spacing around infix operators (space-infix-ops) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +While formatting preferences are very personal, a number of style guides require spaces around operators, such as: + +```js +var sum = 1 + 2; +``` + +The proponents of these extra spaces believe it make the code easier to read and can more easily highlight potential errors, such as: + +```js +var sum = i+++2; +``` + +While this is valid JavaScript syntax, it is hard to determine what the author intended. + +## Rule Details + +This rule is aimed at ensuring there are spaces around infix operators. + +## Options + +This rule accepts a single options argument with the following defaults: + +```json +"space-infix-ops": ["error", { "int32Hint": false }] +``` + +### `int32Hint` + +Set the `int32Hint` option to `true` (default is `false`) to allow write `a|0` without space. + +```js +var foo = bar|0; // `foo` is forced to be signed 32 bit integer +``` + +Examples of **incorrect** code for this rule: + +```js +/*eslint space-infix-ops: "error"*/ +/*eslint-env es6*/ + +a+b + +a+ b + +a +b + +a?b:c + +const a={b:1}; + +var {a=0}=bar; + +function foo(a=0) { } +``` + +Examples of **correct** code for this rule: + +```js +/*eslint space-infix-ops: "error"*/ +/*eslint-env es6*/ + +a + b + +a + b + +a ? b : c + +const a = {b:1}; + +var {a = 0} = bar; + +function foo(a = 0) { } +``` + +## When Not To Use It + +You can turn this rule off if you are not concerned with the consistency of spacing around infix operators. + +## Version + +This rule was introduced in ESLint 0.2.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/space-infix-ops.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/space-infix-ops.md) diff --git a/docs/8.0.0/rules/space-return-throw-case.md b/docs/8.0.0/rules/space-return-throw-case.md new file mode 100644 index 0000000000..470aacda5e --- /dev/null +++ b/docs/8.0.0/rules/space-return-throw-case.md @@ -0,0 +1,49 @@ +--- +title: space-return-throw-case - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/space-return-throw-case.md + +--- + + +# space-return-throw-case: require spaces after `return`, `throw`, and `case` keywords + +(removed) This rule was **removed** in ESLint v2.0 and **replaced** by the [keyword-spacing](keyword-spacing) rule. + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#--fix) automatically fixed problems reported by this rule. + +Require spaces following `return`, `throw`, and `case`. + +## Rule Details + +Examples of **incorrect** code for this rule: + +```js +/*eslint space-return-throw-case: "error"*/ + +throw{a:0} + +function f(){ return-a; } + +switch(a){ case'a': break; } +``` + +Examples of **correct** code for this rule: + +```js +/*eslint space-return-throw-case: "error"*/ + +throw {a: 0}; + +function f(){ return -a; } + +switch(a){ case 'a': break; } +``` + +## Version + +This rule was introduced in ESLint 0.1.4 and removed in 2.0.0-beta.3. + +## Resources + +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/space-return-throw-case.md) diff --git a/docs/8.0.0/rules/space-unary-ops.md b/docs/8.0.0/rules/space-unary-ops.md new file mode 100644 index 0000000000..0c3087daaa --- /dev/null +++ b/docs/8.0.0/rules/space-unary-ops.md @@ -0,0 +1,167 @@ +--- +title: space-unary-ops - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/space-unary-ops.md +rule_type: layout +--- + + +# Require or disallow spaces before/after unary operators (space-unary-ops) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +Some style guides require or disallow spaces before or after unary operators. This is mainly a stylistic issue, however, some JavaScript expressions can be written without spacing which makes it harder to read and maintain. + +## Rule Details + +This rule enforces consistency regarding the spaces after `words` unary operators and after/before `nonwords` unary operators. + +For `words` operators, this rule only applies when a space is not syntactically required. For instance, `delete obj.foo` requires the space and will not be considered by this rule. The equivalent `delete(obj.foo)` has an optional space (`delete (obj.foo)`), therefore this rule will apply to it. + +Examples of unary `words` operators: + +```js +// new +var joe = new Person(); + +// delete +var obj = { + foo: 'bar' +}; +delete obj.foo; + +// typeof +typeof {} // object + +// void +void 0 // undefined +``` + +Examples of unary `nonwords` operators: + +```js +if ([1,2,3].indexOf(1) !== -1) {}; +foo = --foo; +bar = bar++; +baz = !foo; +qux = !!baz; +``` + +## Options + +This rule has three options: + +* `words` - applies to unary word operators such as: `new`, `delete`, `typeof`, `void`, `yield` +* `nonwords` - applies to unary operators such as: `-`, `+`, `--`, `++`, `!`, `!!` +* `overrides` - specifies overwriting usage of spacing for each + operator, word or non word. This is empty by default, but can be used + to enforce or disallow spacing around operators. For example: + +```js + "space-unary-ops": [ + 2, { + "words": true, + "nonwords": false, + "overrides": { + "new": false, + "++": true + } + }] +``` + +In this case, spacing will be disallowed after a `new` operator and required before/after a `++` operator. + +Examples of **incorrect** code for this rule with the default `{"words": true, "nonwords": false}` option: + +```js +/*eslint space-unary-ops: "error"*/ + +typeof!foo; + +void{foo:0}; + +new[foo][0]; + +delete(foo.bar); + +++ foo; + +foo --; + +- foo; + ++ "3"; +``` + +```js +/*eslint space-unary-ops: "error"*/ +/*eslint-env es6*/ + +function *foo() { + yield(0) +} +``` + +```js +/*eslint space-unary-ops: "error"*/ + +async function foo() { + await(bar); +} +``` + +Examples of **correct** code for this rule with the `{"words": true, "nonwords": false}` option: + +```js +/*eslint space-unary-ops: "error"*/ + +// Word unary operator "typeof" is followed by a whitespace. +typeof !foo; + +// Word unary operator "void" is followed by a whitespace. +void {foo:0}; + +// Word unary operator "new" is followed by a whitespace. +new [foo][0]; + +// Word unary operator "delete" is followed by a whitespace. +delete (foo.bar); + +// Unary operator "++" is not followed by whitespace. +++foo; + +// Unary operator "--" is not preceded by whitespace. +foo--; + +// Unary operator "-" is not followed by whitespace. +-foo; + +// Unary operator "+" is not followed by whitespace. ++"3"; +``` + +```js +/*eslint space-unary-ops: "error"*/ +/*eslint-env es6*/ + +function *foo() { + yield (0) +} +``` + +```js +/*eslint space-unary-ops: "error"*/ + +async function foo() { + await (bar); +} +``` + +## Version + +This rule was introduced in ESLint 0.10.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/space-unary-ops.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/space-unary-ops.md) diff --git a/docs/8.0.0/rules/space-unary-word-ops.md b/docs/8.0.0/rules/space-unary-word-ops.md new file mode 100644 index 0000000000..ab79d6e1b2 --- /dev/null +++ b/docs/8.0.0/rules/space-unary-word-ops.md @@ -0,0 +1,55 @@ +--- +title: space-unary-word-ops - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/space-unary-word-ops.md + +--- + + +# space-unary-word-ops: require spaces after unary word operators + +(removed) This rule was **removed** in ESLint v0.10.0 and **replaced** by the [space-unary-ops](space-unary-ops) rule. + +Require spaces following unary word operators. + +## Rule Details + +Examples of **incorrect** code for this rule: + +```js +typeof!a +``` + +```js +void{a:0} +``` + +```js +new[a][0] +``` + +```js +delete(a.b) +``` + +Examples of **correct** code for this rule: + +```js +delete a.b +``` + +```js +new C +``` + +```js +void 0 +``` + +## Version + +This rule was introduced in ESLint 0.1.4 and removed in 0.10.0. + +## Resources + +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/space-unary-word-ops.md) diff --git a/docs/8.0.0/rules/spaced-comment.md b/docs/8.0.0/rules/spaced-comment.md new file mode 100644 index 0000000000..5622281300 --- /dev/null +++ b/docs/8.0.0/rules/spaced-comment.md @@ -0,0 +1,306 @@ +--- +title: spaced-comment - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/spaced-comment.md +rule_type: suggestion +--- + + +# Requires or disallows a whitespace (space or tab) beginning a comment (spaced-comment) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +Some style guides require or disallow a whitespace immediately after the initial `//` or `/*` of a comment. +Whitespace after the `//` or `/*` makes it easier to read text in comments. +On the other hand, commenting out code is easier without having to put a whitespace right after the `//` or `/*`. + +## Rule Details + +This rule will enforce consistency of spacing after the start of a comment `//` or `/*`. It also provides several +exceptions for various documentation styles. + +## Options + +The rule takes two options. + +* The first is a string which be either `"always"` or `"never"`. The default is `"always"`. + + * If `"always"` then the `//` or `/*` must be followed by at least one whitespace. + + * If `"never"` then there should be no whitespace following. + +* This rule can also take a 2nd option, an object with any of the following keys: `"exceptions"` and `"markers"`. + + * The `"exceptions"` value is an array of string patterns which are considered exceptions to the rule. The rule will not warn when the pattern starts from the beginning of the comment and repeats until the end of the line or `*/` if the comment is a single line comment. + Please note that exceptions are ignored if the first argument is `"never"`. + + ``` + "spaced-comment": ["error", "always", { "exceptions": ["-", "+"] }] + ``` + + * The `"markers"` value is an array of string patterns which are considered markers for docblock-style comments, + such as an additional `/`, used to denote documentation read by doxygen, vsdoc, etc. which must have additional characters. + The `"markers"` array will apply regardless of the value of the first argument, e.g. `"always"` or `"never"`. + + ``` + "spaced-comment": ["error", "always", { "markers": ["/"] }] + ``` + +The difference between a marker and an exception is that a marker only appears at the beginning of the comment whereas +exceptions can occur anywhere in the comment string. + +You can also define separate exceptions and markers for block and line comments. The `"block"` object can have an additional key `"balanced"`, a boolean that specifies if inline block comments should have balanced spacing. The default value is `false`. + +* If `"balanced": true` and `"always"` then the `/*` must be followed by at least one whitespace, and the `*/` must be preceded by at least one whitespace. + +* If `"balanced": true` and `"never"` then there should be no whitespace following `/*` or preceding `*/`. + +* If `"balanced": false` then balanced whitespace is not enforced. + +```json +"spaced-comment": ["error", "always", { + "line": { + "markers": ["/"], + "exceptions": ["-", "+"] + }, + "block": { + "markers": ["!"], + "exceptions": ["*"], + "balanced": true + } +}] +``` + +### always + +Examples of **incorrect** code for this rule with the `"always"` option: + +```js +/*eslint spaced-comment: ["error", "always"]*/ + +//This is a comment with no whitespace at the beginning + +/*This is a comment with no whitespace at the beginning */ +``` + +```js +/* eslint spaced-comment: ["error", "always", { "block": { "balanced": true } }] */ +/* This is a comment with whitespace at the beginning but not the end*/ +``` + +Examples of **correct** code for this rule with the `"always"` option: + +```js +/* eslint spaced-comment: ["error", "always"] */ + +// This is a comment with a whitespace at the beginning + +/* This is a comment with a whitespace at the beginning */ + +/* + * This is a comment with a whitespace at the beginning + */ + +/* +This comment has a newline +*/ +``` + +```js +/* eslint spaced-comment: ["error", "always"] */ + +/** +* I am jsdoc +*/ +``` + +### never + +Examples of **incorrect** code for this rule with the `"never"` option: + +```js +/*eslint spaced-comment: ["error", "never"]*/ + +// This is a comment with a whitespace at the beginning + +/* This is a comment with a whitespace at the beginning */ + +/* \nThis is a comment with a whitespace at the beginning */ +``` + +```js +/*eslint spaced-comment: ["error", "never", { "block": { "balanced": true } }]*/ +/*This is a comment with whitespace at the end */ +``` + +Examples of **correct** code for this rule with the `"never"` option: + +```js +/*eslint spaced-comment: ["error", "never"]*/ + +/*This is a comment with no whitespace at the beginning */ +``` + +```js +/*eslint spaced-comment: ["error", "never"]*/ + +/** +* I am jsdoc +*/ +``` + +### exceptions + +Examples of **incorrect** code for this rule with the `"always"` option combined with `"exceptions"`: + +```js +/* eslint spaced-comment: ["error", "always", { "block": { "exceptions": ["-"] } }] */ + +//-------------- +// Comment block +//-------------- +``` + +```js +/* eslint spaced-comment: ["error", "always", { "exceptions": ["-", "+"] }] */ + +//------++++++++ +// Comment block +//------++++++++ +``` + +```js +/* eslint spaced-comment: ["error", "always", { "exceptions": ["-", "+"] }] */ + +/*------++++++++*/ +/* Comment block */ +/*------++++++++*/ +``` + +```js +/* eslint spaced-comment: ["error", "always", { "line": { "exceptions": ["-+"] } }] */ + +/*-+-+-+-+-+-+-+*/ +// Comment block +/*-+-+-+-+-+-+-+*/ +``` + +```js +/* eslint spaced-comment: ["error", "always", { "block": { "exceptions": ["*"] } }] */ + +/******** COMMENT *******/ +``` + +Examples of **correct** code for this rule with the `"always"` option combined with `"exceptions"`: + +```js +/* eslint spaced-comment: ["error", "always", { "exceptions": ["-"] }] */ + +//-------------- +// Comment block +//-------------- +``` + +```js +/* eslint spaced-comment: ["error", "always", { "line": { "exceptions": ["-"] } }] */ + +//-------------- +// Comment block +//-------------- +``` + +```js +/* eslint spaced-comment: ["error", "always", { "exceptions": ["*"] }] */ + +/**************** + * Comment block + ****************/ +``` + +```js +/* eslint spaced-comment: ["error", "always", { "exceptions": ["-+"] }] */ + +//-+-+-+-+-+-+-+ +// Comment block +//-+-+-+-+-+-+-+ + +/*-+-+-+-+-+-+-+*/ +// Comment block +/*-+-+-+-+-+-+-+*/ +``` + +```js +/* eslint spaced-comment: ["error", "always", { "block": { "exceptions": ["-+"] } }] */ + +/*-+-+-+-+-+-+-+*/ +// Comment block +/*-+-+-+-+-+-+-+*/ +``` + +```js +/* eslint spaced-comment: ["error", "always", { "block": { "exceptions": ["*"] } }] */ + +/***************/ + +/******** +COMMENT +*******/ +``` + +### markers + +Examples of **incorrect** code for this rule with the `"always"` option combined with `"markers"`: + +```js +/* eslint spaced-comment: ["error", "always", { "markers": ["/"] }] */ + +///This is a comment with a marker but without whitespace +``` + +```js +/*eslint spaced-comment: ["error", "always", { "block": { "markers": ["!"], "balanced": true } }]*/ +/*! This is a comment with a marker but without whitespace at the end*/ +``` + +```js +/*eslint spaced-comment: ["error", "never", { "block": { "markers": ["!"], "balanced": true } }]*/ +/*!This is a comment with a marker but with whitespace at the end */ +``` + +Examples of **correct** code for this rule with the `"always"` option combined with `"markers"`: + +```js +/* eslint spaced-comment: ["error", "always", { "markers": ["/"] }] */ + +/// This is a comment with a marker +``` + +```js +/*eslint spaced-comment: ["error", "never", { "markers": ["!<"] }]*/ + +//! + +# spaced-line-comment: enforce consistent spacing after `//` in line comments + +(removed) This rule was **removed** in ESLint v1.0 and **replaced** by the [spaced-comment](spaced-comment) rule. + +Some style guides require or disallow a whitespace immediately after the initial `//` of a line comment. +Whitespace after the `//` makes it easier to read text in comments. +On the other hand, commenting out code is easier without having to put a whitespace right after the `//`. + + +## Rule Details + +This rule will enforce consistency of spacing after the start of a line comment `//`. + +This rule takes two arguments. If the first is `"always"` then the `//` must be followed by at least once whitespace. +If `"never"` then there should be no whitespace following. +The default is `"always"`. + +The second argument is an object with one key, `"exceptions"`. +The value is an array of string patterns which are considered exceptions to the rule. +It is important to note that the exceptions are ignored if the first argument is `"never"`. +Exceptions cannot be mixed. + +Examples of **incorrect** code for this rule: + +```js +// When ["never"] +// This is a comment with a whitespace at the beginning +``` + +```js +//When ["always"] +//This is a comment with no whitespace at the beginning +var foo = 5; +``` + +```js +// When ["always",{"exceptions":["-","+"]}] +//------++++++++ +// Comment block +//------++++++++ +``` + +Examples of **correct** code for this rule: + +```js +// When ["always"] +// This is a comment with a whitespace at the beginning +var foo = 5; +``` + +```js +//When ["never"] +//This is a comment with no whitespace at the beginning +var foo = 5; +``` + +```js +// When ["always",{"exceptions":["-"]}] +//-------------- +// Comment block +//-------------- +``` + +```js +// When ["always",{"exceptions":["-+"]}] +//-+-+-+-+-+-+-+ +// Comment block +//-+-+-+-+-+-+-+ +``` + +## Related Rules + +* [spaced-comment](spaced-comment) + +## Version + +This rule was introduced in ESLint 0.9.0 and removed in 1.0.0-rc-1. + +## Resources + +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/spaced-line-comment.md) diff --git a/docs/8.0.0/rules/strict.md b/docs/8.0.0/rules/strict.md new file mode 100644 index 0000000000..c2cc7534ac --- /dev/null +++ b/docs/8.0.0/rules/strict.md @@ -0,0 +1,291 @@ +--- +title: strict - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/strict.md +rule_type: suggestion +--- + + +# require or disallow strict mode directives (strict) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +A strict mode directive is a `"use strict"` literal at the beginning of a script or function body. It enables strict mode semantics. + +When a directive occurs in global scope, strict mode applies to the entire script: + +```js +"use strict"; + +// strict mode + +function foo() { + // strict mode +} +``` + +When a directive occurs at the beginning of a function body, strict mode applies only to that function, including all contained functions: + +```js +function foo() { + "use strict"; + // strict mode +} + +function foo2() { + // not strict mode +}; + +(function() { + "use strict"; + function bar() { + // strict mode + } +}()); +``` + +In the **CommonJS** module system, a hidden function wraps each module and limits the scope of a "global" strict mode directive. + +In **ECMAScript** modules, which always have strict mode semantics, the directives are unnecessary. + +## Rule Details + +This rule requires or disallows strict mode directives. + +This rule disallows strict mode directives, no matter which option is specified, if ESLint configuration specifies either of the following as [parser options](/docs/user-guide/configuring/language-options#specifying-parser-options): + +* `"sourceType": "module"` that is, files are **ECMAScript** modules +* `"impliedStrict": true` property in the `ecmaFeatures` object + +This rule disallows strict mode directives, no matter which option is specified, in functions with non-simple parameter lists (for example, parameter lists with default parameter values) because that is a syntax error in **ECMAScript 2016** and later. See the examples of the [function](#function) option. + +The `--fix` option on the command line does not insert new `"use strict"` statements, but only removes unneeded statements. + +## Options + +This rule has a string option: + +* `"safe"` (default) corresponds either of the following options: + * `"global"` if ESLint considers a file to be a **CommonJS** module + * `"function"` otherwise +* `"global"` requires one strict mode directive in the global scope (and disallows any other strict mode directives) +* `"function"` requires one strict mode directive in each top-level function declaration or expression (and disallows any other strict mode directives) +* `"never"` disallows strict mode directives + +### safe + +The `"safe"` option corresponds to the `"global"` option if ESLint considers a file to be a **Node.js** or **CommonJS** module because the configuration specifies either of the following: + +* `node` or `commonjs` [environments](/docs/user-guide/configuring/language-options#specifying-environments) +* `"globalReturn": true` property in the `ecmaFeatures` object of [parser options](/docs/user-guide/configuring/language-options#specifying-parser-options) + +Otherwise the `"safe"` option corresponds to the `"function"` option. Note that if `"globalReturn": false` is explicitly specified in the configuration, the `"safe"` option will correspond to the `"function"` option regardless of the specified environment. + +### global + +Examples of **incorrect** code for this rule with the `"global"` option: + +```js +/*eslint strict: ["error", "global"]*/ + +function foo() { +} +``` + +```js +/*eslint strict: ["error", "global"]*/ + +function foo() { + "use strict"; +} +``` + +```js +/*eslint strict: ["error", "global"]*/ + +"use strict"; + +function foo() { + "use strict"; +} +``` + +Examples of **correct** code for this rule with the `"global"` option: + +```js +/*eslint strict: ["error", "global"]*/ + +"use strict"; + +function foo() { +} +``` + +### function + +This option ensures that all function bodies are strict mode code, while global code is not. Particularly if a build step concatenates multiple scripts, a strict mode directive in global code of one script could unintentionally enable strict mode in another script that was not intended to be strict code. + +Examples of **incorrect** code for this rule with the `"function"` option: + +```js +/*eslint strict: ["error", "function"]*/ + +"use strict"; + +function foo() { +} +``` + +```js +/*eslint strict: ["error", "function"]*/ + +function foo() { +} + +(function() { + function bar() { + "use strict"; + } +}()); +``` + +```js +/*eslint strict: ["error", "function"]*/ +/*eslint-env es6*/ + +// Illegal "use strict" directive in function with non-simple parameter list. +// This is a syntax error since ES2016. +function foo(a = 1) { + "use strict"; +} + +// We cannot write "use strict" directive in this function. +// So we have to wrap this function with a function with "use strict" directive. +function foo(a = 1) { +} +``` + +Examples of **correct** code for this rule with the `"function"` option: + +```js +/*eslint strict: ["error", "function"]*/ + +function foo() { + "use strict"; +} + +(function() { + "use strict"; + + function bar() { + } + + function baz(a = 1) { + } +}()); + +var foo = (function() { + "use strict"; + + return function foo(a = 1) { + }; +}()); +``` + +### never + +Examples of **incorrect** code for this rule with the `"never"` option: + +```js +/*eslint strict: ["error", "never"]*/ + +"use strict"; + +function foo() { +} +``` + +```js +/*eslint strict: ["error", "never"]*/ + +function foo() { + "use strict"; +} +``` + +Examples of **correct** code for this rule with the `"never"` option: + +```js +/*eslint strict: ["error", "never"]*/ + +function foo() { +} +``` + +### earlier default (removed) + +(removed) The default option (that is, no string option specified) for this rule was **removed** in ESLint v1.0. The `"function"` option is most similar to the removed option. + +This option ensures that all functions are executed in strict mode. A strict mode directive must be present in global code or in every top-level function declaration or expression. It does not concern itself with unnecessary strict mode directives in nested functions that are already strict, nor with multiple strict mode directives at the same level. + +Examples of **incorrect** code for this rule with the earlier default option which has been removed: + +```js +// "strict": "error" + +function foo() { +} +``` + +```js +// "strict": "error" + +(function() { + function bar() { + "use strict"; + } +}()); +``` + +Examples of **correct** code for this rule with the earlier default option which has been removed: + +```js +// "strict": "error" + +"use strict"; + +function foo() { +} +``` + +```js +// "strict": "error" + +function foo() { + "use strict"; +} +``` + +```js +// "strict": "error" + +(function() { + "use strict"; + function bar() { + "use strict"; + } +}()); +``` + +## When Not To Use It + +In a codebase that has both strict and non-strict code, either turn this rule off, or [selectively disable it](/docs/user-guide/configuring/rules#disabling-rules) where necessary. For example, functions referencing `arguments.callee` are invalid in strict mode. A [full list of strict mode differences](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode/Transitioning_to_strict_mode#Differences_from_non-strict_to_strict) is available on MDN. + +## Version + +This rule was introduced in ESLint 0.1.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/strict.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/strict.md) diff --git a/docs/8.0.0/rules/switch-colon-spacing.md b/docs/8.0.0/rules/switch-colon-spacing.md new file mode 100644 index 0000000000..eae06b0439 --- /dev/null +++ b/docs/8.0.0/rules/switch-colon-spacing.md @@ -0,0 +1,99 @@ +--- +title: switch-colon-spacing - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/switch-colon-spacing.md +rule_type: layout +--- + + +# Enforce spacing around colons of switch statements (switch-colon-spacing) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +Spacing around colons improves readability of `case`/`default` clauses. + +## Rule Details + +This rule controls spacing around colons of `case` and `default` clauses in `switch` statements. +This rule does the check only if the consecutive tokens exist on the same line. + +This rule has 2 options that are boolean value. + +```json +{ + "switch-colon-spacing": ["error", {"after": true, "before": false}] +} +``` + +- `"after": true` (Default) requires one or more spaces after colons. +- `"after": false` disallows spaces after colons. +- `"before": true` requires one or more spaces before colons. +- `"before": false` (Default) disallows before colons. + + +Examples of **incorrect** code for this rule: + +```js +/*eslint switch-colon-spacing: "error"*/ + +switch (a) { + case 0 :break; + default :foo(); +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint switch-colon-spacing: "error"*/ + +switch (a) { + case 0: foo(); break; + case 1: + bar(); + break; + default: + baz(); + break; +} +``` + +Examples of **incorrect** code for this rule with `{"after": false, "before": true}` option: + +```js +/*eslint switch-colon-spacing: ["error", {"after": false, "before": true}]*/ + +switch (a) { + case 0: break; + default: foo(); +} +``` + +Examples of **correct** code for this rule with `{"after": false, "before": true}` option: + +```js +/*eslint switch-colon-spacing: ["error", {"after": false, "before": true}]*/ + +switch (a) { + case 0 :foo(); break; + case 1 : + bar(); + break; + default : + baz(); + break; +} +``` + +## When Not To Use It + +If you don't want to notify spacing around colons of switch statements, then it's safe to disable this rule. + +## Version + +This rule was introduced in ESLint 4.0.0-beta.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/switch-colon-spacing.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/switch-colon-spacing.md) diff --git a/docs/8.0.0/rules/symbol-description.md b/docs/8.0.0/rules/symbol-description.md new file mode 100644 index 0000000000..685253485f --- /dev/null +++ b/docs/8.0.0/rules/symbol-description.md @@ -0,0 +1,78 @@ +--- +title: symbol-description - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/symbol-description.md +rule_type: suggestion +--- + + +# require symbol description (symbol-description) + +The `Symbol` function may have an optional description: + +```js +var foo = Symbol("some description"); + +var someString = "some description"; +var bar = Symbol(someString); +``` + + +Using `description` promotes easier debugging: when a symbol is logged the description is used: + +```js +var foo = Symbol("some description"); + +> console.log(foo); +// Symbol(some description) +``` + +It may facilitate identifying symbols when one is observed during debugging. + + +## Rule Details + +This rules requires a description when creating symbols. + + +## Examples + +Examples of **incorrect** code for this rule: + +```js +/*eslint symbol-description: "error"*/ +/*eslint-env es6*/ + +var foo = Symbol(); +``` + +Examples of **correct** code for this rule: + +```js +/*eslint symbol-description: "error"*/ +/*eslint-env es6*/ + +var foo = Symbol("some description"); + +var someString = "some description"; +var bar = Symbol(someString); +``` + + +## When Not To Use It + +This rule should not be used in ES3/5 environments. +In addition, this rule can be safely turned off if you don't want to enforce presence of `description` when creating Symbols. + +## Further Reading + +* [Symbol Objects specification: Symbol description](https://www.ecma-international.org/ecma-262/6.0/#sec-symbol-description) + +## Version + +This rule was introduced in ESLint 3.4.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/symbol-description.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/symbol-description.md) diff --git a/docs/8.0.0/rules/template-curly-spacing.md b/docs/8.0.0/rules/template-curly-spacing.md new file mode 100644 index 0000000000..96d7a94a00 --- /dev/null +++ b/docs/8.0.0/rules/template-curly-spacing.md @@ -0,0 +1,101 @@ +--- +title: template-curly-spacing - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/template-curly-spacing.md +rule_type: layout +--- + + +# Enforce Usage of Spacing in Template Strings (template-curly-spacing) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +We can embed expressions in template strings with using a pair of `${` and `}`. + +This rule can force usage of spacing _within_ the curly brace pair according to style guides. + +```js +let hello = `hello, ${people.name}!`; +``` + +## Rule Details + +This rule aims to maintain consistency around the spacing inside of template literals. + +## Options + +```json +{ + "template-curly-spacing": ["error", "never"] +} +``` + +This rule has one option which has either `"never"` or `"always"` as value. + +* `"never"` (by default) - Disallows spaces inside of the curly brace pair. +* `"always"` - Requires one or more spaces inside of the curly brace pair. + +## Examples + +### never + +Examples of **incorrect** code for this rule with the default `"never"` option: + +```js +/*eslint template-curly-spacing: "error"*/ + +`hello, ${ people.name}!`; +`hello, ${people.name }!`; + +`hello, ${ people.name }!`; +``` + +Examples of **correct** code for this rule with the default `"never"` option: + +```js +/*eslint template-curly-spacing: "error"*/ + +`hello, ${people.name}!`; + +`hello, ${ + people.name +}!`; +``` + +### always + +Examples of **incorrect** code for this rule with the `"always"` option: + +```js +/*eslint template-curly-spacing: ["error", "always"]*/ + +`hello, ${ people.name}!`; +`hello, ${people.name }!`; + +`hello, ${people.name}!`; +``` + +Examples of **correct** code for this rule with the `"always"` option: + +```js +/*eslint template-curly-spacing: ["error", "always"]*/ + +`hello, ${ people.name }!`; + +`hello, ${ + people.name +}!`; +``` + +## When Not To Use It + +If you don't want to be notified about usage of spacing inside of template strings, then it's safe to disable this rule. + +## Version + +This rule was introduced in ESLint 2.0.0-rc.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/template-curly-spacing.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/template-curly-spacing.md) diff --git a/docs/8.0.0/rules/template-tag-spacing.md b/docs/8.0.0/rules/template-tag-spacing.md new file mode 100644 index 0000000000..d490d6acdb --- /dev/null +++ b/docs/8.0.0/rules/template-tag-spacing.md @@ -0,0 +1,95 @@ +--- +title: template-tag-spacing - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/template-tag-spacing.md +rule_type: layout +--- + + +# Require or disallow spacing between template tags and their literals (template-tag-spacing) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +With ES6, it's possible to create functions called [tagged template literals](#further-reading) where the function parameters consist of a template literal's strings and expressions. + +When using tagged template literals, it's possible to insert whitespace between the tag function and the template literal. Since this whitespace is optional, the following lines are equivalent: + +```js +let hello = func`Hello world`; +let hello = func `Hello world`; +``` + +## Rule Details + +This rule aims to maintain consistency around the spacing between template tag functions and their template literals. + +## Options + +```json +{ + "template-tag-spacing": ["error", "never"] +} +``` + +This rule has one option whose value can be set to `"never"` or `"always"` + +* `"never"` (default) - Disallows spaces between a tag function and its template literal. +* `"always"` - Requires one or more spaces between a tag function and its template literal. + +## Examples + +### never + +Examples of **incorrect** code for this rule with the default `"never"` option: + +```js +/*eslint template-tag-spacing: "error"*/ + +func `Hello world`; +``` + +Examples of **correct** code for this rule with the default `"never"` option: + +```js +/*eslint template-tag-spacing: "error"*/ + +func`Hello world`; +``` + +### always + +Examples of **incorrect** code for this rule with the `"always"` option: + +```js +/*eslint template-tag-spacing: ["error", "always"]*/ + +func`Hello world`; +``` + +Examples of **correct** code for this rule with the `"always"` option: + +```js +/*eslint template-tag-spacing: ["error", "always"]*/ + +func `Hello world`; +``` + +## When Not To Use It + +If you don't want to be notified about usage of spacing between tag functions and their template literals, then it's safe to disable this rule. + +## Further Reading + +If you want to learn more about tagged template literals, check out the links below: + +* [Template literals (MDN)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#Tagged_template_literals) +* [Examples of using tagged template literals (Exploring ES6)](http://exploringjs.com/es6/ch_template-literals.html#_examples-of-using-tagged-template-literals) + +## Version + +This rule was introduced in ESLint 3.15.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/template-tag-spacing.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/template-tag-spacing.md) diff --git a/docs/8.0.0/rules/unicode-bom.md b/docs/8.0.0/rules/unicode-bom.md new file mode 100644 index 0000000000..e215118aca --- /dev/null +++ b/docs/8.0.0/rules/unicode-bom.md @@ -0,0 +1,82 @@ +--- +title: unicode-bom - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/unicode-bom.md +rule_type: layout +--- + + +# Require or disallow the Unicode Byte Order Mark (BOM) (unicode-bom) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +The Unicode Byte Order Mark (BOM) is used to specify whether code units are big +endian or little endian. That is, whether the most significant or least +significant bytes come first. UTF-8 does not require a BOM because byte ordering +does not matter when characters are a single byte. Since UTF-8 is the dominant +encoding of the web, we make `"never"` the default option. + +## Rule Details + +If the `"always"` option is used, this rule requires that files always begin +with the Unicode BOM character U+FEFF. If `"never"` is used, files must never +begin with U+FEFF. + +## Options + +This rule has a string option: + +* `"always"` files must begin with the Unicode BOM +* `"never"` (default) files must not begin with the Unicode BOM + +### always + +Example of **correct** code for this rule with the `"always"` option: + +```js +/*eslint unicode-bom: ["error", "always"]*/ + +U+FEFF +var abc; +``` + +Example of **incorrect** code for this rule with the `"always"` option: + +```js +/*eslint unicode-bom: ["error", "always"]*/ + +var abc; +``` + +### never + +Example of **correct** code for this rule with the default `"never"` option: + +```js +/*eslint unicode-bom: ["error", "never"]*/ + +var abc; +``` + +Example of **incorrect** code for this rule with the `"never"` option: + +```js +/*eslint unicode-bom: ["error", "never"]*/ + +U+FEFF +var abc; +``` + +## When Not To Use It + +If you use some UTF-16 or UTF-32 files and you want to allow a file to +optionally begin with a Unicode BOM, you should turn this rule off. + +## Version + +This rule was introduced in ESLint 2.11.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/unicode-bom.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/unicode-bom.md) diff --git a/docs/8.0.0/rules/use-isnan.md b/docs/8.0.0/rules/use-isnan.md new file mode 100644 index 0000000000..8bc18de9df --- /dev/null +++ b/docs/8.0.0/rules/use-isnan.md @@ -0,0 +1,268 @@ +--- +title: use-isnan - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/use-isnan.md +rule_type: problem +--- + + +# require calls to `isNaN()` when checking for `NaN` (use-isnan) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +In JavaScript, `NaN` is a special value of the `Number` type. It's used to represent any of the "not-a-number" values represented by the double-precision 64-bit format as specified by the IEEE Standard for Binary Floating-Point Arithmetic. + +Because `NaN` is unique in JavaScript by not being equal to anything, including itself, the results of comparisons to `NaN` are confusing: + +* `NaN === NaN` or `NaN == NaN` evaluate to false +* `NaN !== NaN` or `NaN != NaN` evaluate to true + +Therefore, use `Number.isNaN()` or global `isNaN()` functions to test whether a value is `NaN`. + +## Rule Details + +This rule disallows comparisons to 'NaN'. + +Examples of **incorrect** code for this rule: + +```js +/*eslint use-isnan: "error"*/ + +if (foo == NaN) { + // ... +} + +if (foo != NaN) { + // ... +} + +if (foo == Number.NaN) { + // ... +} + +if (foo != Number.NaN) { + // ... +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint use-isnan: "error"*/ + +if (isNaN(foo)) { + // ... +} + +if (!isNaN(foo)) { + // ... +} +``` + +## Options + +This rule has an object option, with two options: + +* `"enforceForSwitchCase": true` (default) additionally disallows `case NaN` and `switch(NaN)` in `switch` statements. +* `"enforceForIndexOf": true` additionally disallows the use of `indexOf` and `lastIndexOf` methods with `NaN`. Default is `false`, meaning that this rule by default does not warn about `indexOf(NaN)` or `lastIndexOf(NaN)` method calls. + +### enforceForSwitchCase + +The `switch` statement internally uses the `===` comparison to match the expression's value to a case clause. +Therefore, it can never match `case NaN`. Also, `switch(NaN)` can never match a case clause. + +Examples of **incorrect** code for this rule with `"enforceForSwitchCase"` option set to `true` (default): + +```js +/*eslint use-isnan: ["error", {"enforceForSwitchCase": true}]*/ + +switch (foo) { + case NaN: + bar(); + break; + case 1: + baz(); + break; + // ... +} + +switch (NaN) { + case a: + bar(); + break; + case b: + baz(); + break; + // ... +} + +switch (foo) { + case Number.NaN: + bar(); + break; + case 1: + baz(); + break; + // ... +} + +switch (Number.NaN) { + case a: + bar(); + break; + case b: + baz(); + break; + // ... +} +``` + +Examples of **correct** code for this rule with `"enforceForSwitchCase"` option set to `true` (default): + +```js +/*eslint use-isnan: ["error", {"enforceForSwitchCase": true}]*/ + +if (Number.isNaN(foo)) { + bar(); +} else { + switch (foo) { + case 1: + baz(); + break; + // ... + } +} + +if (Number.isNaN(a)) { + bar(); +} else if (Number.isNaN(b)) { + baz(); +} // ... +``` + +Examples of **correct** code for this rule with `"enforceForSwitchCase"` option set to `false`: + +```js +/*eslint use-isnan: ["error", {"enforceForSwitchCase": false}]*/ + +switch (foo) { + case NaN: + bar(); + break; + case 1: + baz(); + break; + // ... +} + +switch (NaN) { + case a: + bar(); + break; + case b: + baz(); + break; + // ... +} + +switch (foo) { + case Number.NaN: + bar(); + break; + case 1: + baz(); + break; + // ... +} + +switch (Number.NaN) { + case a: + bar(); + break; + case b: + baz(); + break; + // ... +} +``` + +### enforceForIndexOf + +The following methods internally use the `===` comparison to match the given value with an array element: + +* [`Array.prototype.indexOf`](https://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.indexof) +* [`Array.prototype.lastIndexOf`](https://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.lastindexof) + +Therefore, for any array `foo`, `foo.indexOf(NaN)` and `foo.lastIndexOf(NaN)` will always return `-1`. + +Set `"enforceForIndexOf"` to `true` if you want this rule to report `indexOf(NaN)` and `lastIndexOf(NaN)` method calls. + +Examples of **incorrect** code for this rule with `"enforceForIndexOf"` option set to `true`: + +```js +/*eslint use-isnan: ["error", {"enforceForIndexOf": true}]*/ + +var hasNaN = myArray.indexOf(NaN) >= 0; + +var firstIndex = myArray.indexOf(NaN); + +var lastIndex = myArray.lastIndexOf(NaN); +``` + +Examples of **correct** code for this rule with `"enforceForIndexOf"` option set to `true`: + +```js +/*eslint use-isnan: ["error", {"enforceForIndexOf": true}]*/ + +function myIsNaN(val) { + return typeof val === "number" && isNaN(val); +} + +function indexOfNaN(arr) { + for (var i = 0; i < arr.length; i++) { + if (myIsNaN(arr[i])) { + return i; + } + } + return -1; +} + +function lastIndexOfNaN(arr) { + for (var i = arr.length - 1; i >= 0; i--) { + if (myIsNaN(arr[i])) { + return i; + } + } + return -1; +} + +var hasNaN = myArray.some(myIsNaN); + +var hasNaN = indexOfNaN(myArray) >= 0; + +var firstIndex = indexOfNaN(myArray); + +var lastIndex = lastIndexOfNaN(myArray); + +// ES2015 +var hasNaN = myArray.some(Number.isNaN); + +// ES2015 +var firstIndex = myArray.findIndex(Number.isNaN); + +// ES2016 +var hasNaN = myArray.includes(NaN); +``` + +#### Known Limitations + +This option checks methods with the given names, *even if* the object which has the method is *not* an array. + +## Version + +This rule was introduced in ESLint 0.0.6. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/use-isnan.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/use-isnan.md) diff --git a/docs/8.0.0/rules/valid-jsdoc.md b/docs/8.0.0/rules/valid-jsdoc.md new file mode 100644 index 0000000000..337e2cc20c --- /dev/null +++ b/docs/8.0.0/rules/valid-jsdoc.md @@ -0,0 +1,412 @@ +--- +title: valid-jsdoc - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/valid-jsdoc.md +rule_type: suggestion +--- + + +# enforce valid JSDoc comments (valid-jsdoc) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +This rule was [**deprecated**](https://eslint.org/blog/2018/11/jsdoc-end-of-life) in ESLint v5.10.0. + +[JSDoc](http://usejsdoc.org) generates application programming interface (API) documentation from specially-formatted comments in JavaScript code. For example, this is a JSDoc comment for a function: + +```js +/** + * Add two numbers. + * @param {number} num1 The first number. + * @param {number} num2 The second number. + * @returns {number} The sum of the two numbers. + */ +function add(num1, num2) { + return num1 + num2; +} +``` + +If comments are invalid because of typing mistakes, then documentation will be incomplete. + +If comments are inconsistent because they are not updated when function definitions are modified, then readers might become confused. + +## Rule Details + +This rule enforces valid and consistent JSDoc comments. It reports any of the following problems: + +* missing parameter tag: `@arg`, `@argument`, or `@param` +* inconsistent order of parameter names in a comment compared to the function or method +* missing return tag: `@return` or `@returns` +* missing parameter or return type +* missing parameter or return description +* syntax error + +This rule does not report missing JSDoc comments for classes, functions, or methods. + +**Note:** This rule does not support all of the Google Closure documentation tool's use cases. As such, some code such as `(/**number*/ n => n * 2);` will be flagged as missing appropriate function JSDoc comments even though `/**number*/` is intended to be a type hint and not a documentation block for the function. We don't recommend using this rule if you use type hints in this way. + +Examples of **incorrect** code for this rule: + +```js +/*eslint valid-jsdoc: "error"*/ + +// expected @param tag for parameter num1 but found num instead +// missing @param tag for parameter num2 +// missing return type +/** + * Add two numbers. + * @param {number} num The first number. + * @returns The sum of the two numbers. + */ +function add(num1, num2) { + return num1 + num2; +} + +// missing brace +// missing @returns tag +/** + * @param {string name Whom to greet. + */ +function greet(name) { + console.log("Hello " + name); +} + +// missing parameter type for num1 +// missing parameter description for num2 +/** + * Represents a sum. + * @constructor + * @param num1 The first number. + * @param {number} num2 + */ +function sum(num1, num2) { + this.num1 = num1; + this.num2 = num2; +} +``` + +Examples of **correct** code for this rule: + +```js +/*eslint valid-jsdoc: "error"*/ +/*eslint-env es6*/ + +/** + * Add two numbers. + * @param {number} num1 The first number. + * @param {number} num2 The second number. + * @returns {number} The sum of the two numbers. + */ +function add(num1, num2) { + return num1 + num2; +} + +// default options allow missing function description +// return type `void` means the function has no `return` statement +/** + * @param {string} name Whom to greet. + * @returns {void} + */ +function greet(name) { + console.log("Hello " + name); +} + +// @constructor tag allows missing @returns tag +/** + * Represents a sum. + * @constructor + * @param {number} num1 The first number. + * @param {number} num2 The second number. + */ +function sum(num1, num2) { + this.num1 = num1; + this.num2 = num2; +} + +// class constructor allows missing @returns tag +/** + * Represents a sum. + */ +class Sum { + /** + * @param {number} num1 The first number. + * @param {number} num2 The second number. + */ + constructor(num1, num2) { + this.num1 = num1; + this.num2 = num2; + } +} + +// @abstract tag allows @returns tag without `return` statement +class Widget { + /** + * When the state changes, does it affect the rendered appearance? + * @abstract + * @param {Object} state The new state of the widget. + * @returns {boolean} Is current appearance inconsistent with new state? + */ + mustRender (state) { + throw new Error("Widget subclass did not implement mustRender"); + } +} + +// @override tag allows missing @param and @returns tags +class WonderfulWidget extends Widget { + /** + * @override + */ + mustRender (state) { + return state !== this.state; // shallow comparison + } +} +``` + +## Options + +This rule has an object option: + +* `"prefer"` enforces consistent documentation tags specified by an object whose properties mean instead of key use value (for example, `"return": "returns"` means instead of `@return` use `@returns`) +* `"preferType"` enforces consistent type strings specified by an object whose properties mean instead of key use value (for example, `"object": "Object"` means instead of `object` use `Object`) +* `"requireReturn"` requires a return tag: + * `true` (default) **even if** the function or method does not have a `return` statement (this option value does not apply to constructors) + * `false` **if and only if** the function or method has a `return` statement or returns a value e.g. `async` function (this option value does apply to constructors) +* `"requireReturnType": false` allows missing type in return tags +* `"matchDescription"` specifies (as a string) a regular expression to match the description in each JSDoc comment (for example, `".+"` requires a description; this option does not apply to descriptions in parameter or return tags) +* `"requireParamDescription": false` allows missing description in parameter tags +* `"requireReturnDescription": false` allows missing description in return tags +* `"requireParamType": false` allows missing type in parameter tags + +### prefer + +Examples of additional **incorrect** code for this rule with sample `"prefer": { "arg": "param", "argument": "param", "class": "constructor", "return": "returns", "virtual": "abstract" }` options: + +```js +/*eslint valid-jsdoc: ["error", { "prefer": { "arg": "param", "argument": "param", "class": "constructor", "return": "returns", "virtual": "abstract" } }]*/ +/*eslint-env es6*/ + +/** + * Add two numbers. + * @arg {int} num1 The first number. + * @arg {int} num2 The second number. + * @return {int} The sum of the two numbers. + */ +function add(num1, num2) { + return num1 + num2; +} + +/** + * Represents a sum. + * @class + * @argument {number} num1 The first number. + * @argument {number} num2 The second number. + */ +function sum(num1, num2) { + this.num1 = num1; + this.num2 = num2; +} + +class Widget { + /** + * When the state changes, does it affect the rendered appearance? + * @virtual + * @argument {Object} state The new state of the widget. + * @return {boolean} Is current appearance inconsistent with new state? + */ + mustRender (state) { + throw new Error("Widget subclass did not implement mustRender"); + } +} +``` + +### preferType + +Examples of additional **incorrect** code for this rule with sample `"preferType": { "Boolean": "boolean", "Number": "number", "object": "Object", "String": "string" }` options: + +```js +/*eslint valid-jsdoc: ["error", { "preferType": { "Boolean": "boolean", "Number": "number", "object": "Object", "String": "string" } }]*/ +/*eslint-env es6*/ + +/** + * Add two numbers. + * @param {Number} num1 The first number. + * @param {Number} num2 The second number. + * @returns {Number} The sum of the two numbers. + */ +function add(num1, num2) { + return num1 + num2; +} + +/** + * Output a greeting as a side effect. + * @param {String} name Whom to greet. + * @returns {void} + */ +function greet(name) { + console.log("Hello " + name); +} + +class Widget { + /** + * When the state changes, does it affect the rendered appearance? + * @abstract + * @param {object} state The new state of the widget. + * @returns {Boolean} Is current appearance inconsistent with new state? + */ + mustRender (state) { + throw new Error("Widget subclass did not implement mustRender"); + } +} +``` + +### requireReturn + +Examples of additional **incorrect** code for this rule with the `"requireReturn": false` option: + +```js +/*eslint valid-jsdoc: ["error", { "requireReturn": false }]*/ + +// unexpected @returns tag because function has no `return` statement +/** + * @param {string} name Whom to greet. + * @returns {string} The greeting. + */ +function greet(name) { + console.log("Hello " + name); +} + +// add @abstract tag to allow @returns tag without `return` statement +class Widget { + /** + * When the state changes, does it affect the rendered appearance? + * @param {Object} state The new state of the widget. + * @returns {boolean} Is current appearance inconsistent with new state? + */ + mustRender (state) { + throw new Error("Widget subclass did not implement mustRender"); + } +} +``` + +Example of additional **correct** code for this rule with the `"requireReturn": false` option: + +```js +/*eslint valid-jsdoc: ["error", { "requireReturn": false }]*/ + +/** + * @param {string} name Whom to greet. + */ +function greet(name) { + console.log("Hello " + name); +} +``` + +### requireReturnType + +Example of additional **correct** code for this rule with the `"requireReturnType": false` option: + +```js +/*eslint valid-jsdoc: ["error", { "requireReturnType": false }]*/ + +/** + * Add two numbers. + * @param {number} num1 The first number. + * @param {number} num2 The second number. + * @returns The sum of the two numbers. + */ +function add(num1, num2) { + return num1 + num2; +} +``` + +### requireParamType + +Example of additional **correct** code for this rule with the `"requireParamType": false` option: + +```js +/*eslint valid-jsdoc: ["error", { "requireParamType": false }]*/ + +/** + * Add two numbers. + * @param num1 The first number. + * @param num2 The second number. + * @returns {number} The sum of the two numbers. + */ +function add(num1, num2) { + return num1 + num2; +} +``` + +### matchDescription + +Example of additional **incorrect** code for this rule with a sample `"matchDescription": ".+"` option: + +```js +/*eslint valid-jsdoc: ["error", { "matchDescription": ".+" }]*/ + +// missing function description +/** + * @param {string} name Whom to greet. + * @returns {void} + */ +function greet(name) { + console.log("Hello " + name); +} +``` + +### requireParamDescription + +Example of additional **correct** code for this rule with the `"requireParamDescription": false` option: + +```js +/*eslint valid-jsdoc: ["error", { "requireParamDescription": false }]*/ + +/** + * Add two numbers. + * @param {int} num1 + * @param {int} num2 + * @returns {int} The sum of the two numbers. + */ +function add(num1, num2) { + return num1 + num2; +} +``` + +### requireReturnDescription + +Example of additional **correct** code for this rule with the `"requireReturnDescription": false` option: + +```js +/*eslint valid-jsdoc: ["error", { "requireReturnDescription": false }]*/ + +/** + * Add two numbers. + * @param {number} num1 The first number. + * @param {number} num2 The second number. + * @returns {number} + */ +function add(num1, num2) { + return num1 + num2; +} +``` + +## When Not To Use It + +If you aren't using JSDoc, then you can safely turn this rule off. + +## Further Reading + +* [JSDoc](http://usejsdoc.org) + +## Related Rules + +* [require-jsdoc](require-jsdoc) + +## Version + +This rule was introduced in ESLint 0.4.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/valid-jsdoc.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/valid-jsdoc.md) diff --git a/docs/8.0.0/rules/valid-typeof.md b/docs/8.0.0/rules/valid-typeof.md new file mode 100644 index 0000000000..823b4ec52a --- /dev/null +++ b/docs/8.0.0/rules/valid-typeof.md @@ -0,0 +1,86 @@ +--- +title: valid-typeof - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/valid-typeof.md +rule_type: problem +--- + + +# enforce comparing `typeof` expressions against valid strings (valid-typeof) + +(recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. + +For a vast majority of use cases, the result of the `typeof` operator is one of the following string literals: `"undefined"`, `"object"`, `"boolean"`, `"number"`, `"string"`, `"function"`, `"symbol"`, and `"bigint"`. It is usually a typing mistake to compare the result of a `typeof` operator to other string literals. + +## Rule Details + +This rule enforces comparing `typeof` expressions to valid string literals. + +## Options + +This rule has an object option: + +* `"requireStringLiterals": true` requires `typeof` expressions to only be compared to string literals or other `typeof` expressions, and disallows comparisons to any other value. + +Examples of **incorrect** code for this rule: + +```js +/*eslint valid-typeof: "error"*/ + +typeof foo === "strnig" +typeof foo == "undefimed" +typeof bar != "nunber" +typeof bar !== "fucntion" +``` + +Examples of **correct** code for this rule: + +```js +/*eslint valid-typeof: "error"*/ + +typeof foo === "string" +typeof bar == "undefined" +typeof foo === baz +typeof bar === typeof qux +``` + +Examples of **incorrect** code with the `{ "requireStringLiterals": true }` option: + +```js +/*eslint valid-typeof: ["error", { "requireStringLiterals": true }]*/ + +typeof foo === undefined +typeof bar == Object +typeof baz === "strnig" +typeof qux === "some invalid type" +typeof baz === anotherVariable +typeof foo == 5 +``` + +Examples of **correct** code with the `{ "requireStringLiterals": true }` option: + +```js +/*eslint valid-typeof: ["error", { "requireStringLiterals": true }]*/ + +typeof foo === "undefined" +typeof bar == "object" +typeof baz === "string" +typeof bar === typeof qux +``` + +## When Not To Use It + +You may want to turn this rule off if you will be using the `typeof` operator on host objects. + +## Further Reading + +* [MDN: `typeof` documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof) + +## Version + +This rule was introduced in ESLint 0.5.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/valid-typeof.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/valid-typeof.md) diff --git a/docs/8.0.0/rules/vars-on-top.md b/docs/8.0.0/rules/vars-on-top.md new file mode 100644 index 0000000000..9b6a5032b1 --- /dev/null +++ b/docs/8.0.0/rules/vars-on-top.md @@ -0,0 +1,105 @@ +--- +title: vars-on-top - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/vars-on-top.md +rule_type: suggestion +--- + + +# Require Variable Declarations to be at the top of their scope (vars-on-top) + +The `vars-on-top` rule generates warnings when variable declarations are not used serially at the top of a function scope or the top of a program. +By default variable declarations are always moved (“hoisted”) invisibly to the top of their containing scope by the JavaScript interpreter. +This rule forces the programmer to represent that behavior by manually moving the variable declaration to the top of its containing scope. + +## Rule Details + +This rule aims to keep all variable declarations in the leading series of statements. +Allowing multiple declarations helps promote maintainability and is thus allowed. + +Examples of **incorrect** code for this rule: + +```js +/*eslint vars-on-top: "error"*/ + +// Variable declarations in a block: +function doSomething() { + var first; + if (true) { + first = true; + } + var second; +} + +// Variable declaration in for initializer: +function doSomething() { + for (var i=0; i<10; i++) {} +} +``` + +```js +/*eslint vars-on-top: "error"*/ + +// Variables after other statements: +f(); +var a; +``` + +Examples of **correct** code for this rule: + +```js +/*eslint vars-on-top: "error"*/ + +function doSomething() { + var first; + var second; //multiple declarations are allowed at the top + if (true) { + first = true; + } +} + +function doSomething() { + var i; + for (i=0; i<10; i++) {} +} +``` + +```js +/*eslint vars-on-top: "error"*/ + +var a; +f(); +``` + +```js +/*eslint vars-on-top: "error"*/ + +// Directives may precede variable declarations. +"use strict"; +var a; +f(); + +// Comments can describe variables. +function doSomething() { + // this is the first var. + var first; + // this is the second var. + var second +} +``` + +## Further Reading + +* [JavaScript Scoping and Hoisting](http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html) +* [var Hoisting](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var#var_hoisting) +* [A criticism of the Single Var Pattern in JavaScript, and a simple alternative](http://danielhough.co.uk/blog/single-var-pattern-rant/) +* [Multiple var statements in JavaScript, not superfluous](http://benalman.com/news/2012/05/multiple-var-statements-javascript/) + +## Version + +This rule was introduced in ESLint 0.8.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/vars-on-top.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/vars-on-top.md) diff --git a/docs/8.0.0/rules/wrap-iife.md b/docs/8.0.0/rules/wrap-iife.md new file mode 100644 index 0000000000..0be5b727dd --- /dev/null +++ b/docs/8.0.0/rules/wrap-iife.md @@ -0,0 +1,127 @@ +--- +title: wrap-iife - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/wrap-iife.md +rule_type: layout +--- + + +# Require IIFEs to be Wrapped (wrap-iife) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +You can immediately invoke function expressions, but not function declarations. A common technique to create an immediately-invoked function expression (IIFE) is to wrap a function declaration in parentheses. The opening parentheses causes the contained function to be parsed as an expression, rather than a declaration. + +```js +// function expression could be unwrapped +var x = function () { return { y: 1 };}(); + +// function declaration must be wrapped +function () { /* side effects */ }(); // SyntaxError +``` + +## Rule Details + +This rule requires all immediately-invoked function expressions to be wrapped in parentheses. + +## Options + +This rule has two options, a string option and an object option. + +String option: + +* `"outside"` enforces always wrapping the *call* expression. The default is `"outside"`. +* `"inside"` enforces always wrapping the *function* expression. +* `"any"` enforces always wrapping, but allows either style. + +Object option: + +* `"functionPrototypeMethods": true` additionally enforces wrapping function expressions invoked using `.call` and `.apply`. The default is `false`. + +### outside + +Examples of **incorrect** code for the default `"outside"` option: + +```js +/*eslint wrap-iife: ["error", "outside"]*/ + +var x = function () { return { y: 1 };}(); // unwrapped +var x = (function () { return { y: 1 };})(); // wrapped function expression +``` + +Examples of **correct** code for the default `"outside"` option: + +```js +/*eslint wrap-iife: ["error", "outside"]*/ + +var x = (function () { return { y: 1 };}()); // wrapped call expression +``` + +### inside + +Examples of **incorrect** code for the `"inside"` option: + +```js +/*eslint wrap-iife: ["error", "inside"]*/ + +var x = function () { return { y: 1 };}(); // unwrapped +var x = (function () { return { y: 1 };}()); // wrapped call expression +``` + +Examples of **correct** code for the `"inside"` option: + +```js +/*eslint wrap-iife: ["error", "inside"]*/ + +var x = (function () { return { y: 1 };})(); // wrapped function expression +``` + +### any + +Examples of **incorrect** code for the `"any"` option: + +```js +/*eslint wrap-iife: ["error", "any"]*/ + +var x = function () { return { y: 1 };}(); // unwrapped +``` + +Examples of **correct** code for the `"any"` option: + +```js +/*eslint wrap-iife: ["error", "any"]*/ + +var x = (function () { return { y: 1 };}()); // wrapped call expression +var x = (function () { return { y: 1 };})(); // wrapped function expression +``` + +### functionPrototypeMethods + +Examples of **incorrect** code for this rule with the `"inside", { "functionPrototypeMethods": true }` options: + +```js +/* eslint wrap-iife: [2, "inside", { functionPrototypeMethods: true }] */ + +var x = function(){ foo(); }() +var x = (function(){ foo(); }()) +var x = function(){ foo(); }.call(bar) +var x = (function(){ foo(); }.call(bar)) +``` + +Examples of **correct** code for this rule with the `"inside", { "functionPrototypeMethods": true }` options: + +```js +/* eslint wrap-iife: [2, "inside", { functionPrototypeMethods: true }] */ + +var x = (function(){ foo(); })() +var x = (function(){ foo(); }).call(bar) +``` + +## Version + +This rule was introduced in ESLint 0.0.9. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/wrap-iife.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/wrap-iife.md) diff --git a/docs/8.0.0/rules/wrap-regex.md b/docs/8.0.0/rules/wrap-regex.md new file mode 100644 index 0000000000..c4361e75e4 --- /dev/null +++ b/docs/8.0.0/rules/wrap-regex.md @@ -0,0 +1,52 @@ +--- +title: wrap-regex - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/wrap-regex.md +rule_type: layout +--- + + +# Require Regex Literals to be Wrapped (wrap-regex) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +When a regular expression is used in certain situations, it can end up looking like a division operator. For example: + +```js +function a() { + return /foo/.test("bar"); +} +``` + +## Rule Details + +This is used to disambiguate the slash operator and facilitates more readable code. + +Example of **incorrect** code for this rule: + +```js +/*eslint wrap-regex: "error"*/ + +function a() { + return /foo/.test("bar"); +} +``` + +Example of **correct** code for this rule: + +```js +/*eslint wrap-regex: "error"*/ + +function a() { + return (/foo/).test("bar"); +} +``` + +## Version + +This rule was introduced in ESLint 0.1.0. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/wrap-regex.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/wrap-regex.md) diff --git a/docs/8.0.0/rules/yield-star-spacing.md b/docs/8.0.0/rules/yield-star-spacing.md new file mode 100644 index 0000000000..1a6bddb8f1 --- /dev/null +++ b/docs/8.0.0/rules/yield-star-spacing.md @@ -0,0 +1,113 @@ +--- +title: yield-star-spacing - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/yield-star-spacing.md +rule_type: layout +--- + + +# Enforce spacing around the `*` in `yield*` expressions (yield-star-spacing) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +## Rule Details + +This rule enforces spacing around the `*` in `yield*` expressions. + +## Options + +The rule takes one option, an object, which has two keys `before` and `after` having boolean values `true` or `false`. + +* `before` enforces spacing between the `yield` and the `*`. + If `true`, a space is required, otherwise spaces are disallowed. + +* `after` enforces spacing between the `*` and the argument. + If it is `true`, a space is required, otherwise spaces are disallowed. + +The default is `{"before": false, "after": true}`. + +```json +"yield-star-spacing": ["error", {"before": true, "after": false}] +``` + +The option also has a string shorthand: + +* `{"before": false, "after": true}` → `"after"` +* `{"before": true, "after": false}` → `"before"` +* `{"before": true, "after": true}` → `"both"` +* `{"before": false, "after": false}` → `"neither"` + +```json +"yield-star-spacing": ["error", "after"] +``` + +## Examples + +### after + +Examples of **correct** code for this rule with the default `"after"` option: + +```js +/*eslint yield-star-spacing: ["error", "after"]*/ +/*eslint-env es6*/ + +function* generator() { + yield* other(); +} +``` + +### before + +Examples of **correct** code for this rule with the `"before"` option: + +```js +/*eslint yield-star-spacing: ["error", "before"]*/ +/*eslint-env es6*/ + +function *generator() { + yield *other(); +} +``` + +### both + +Examples of **correct** code for this rule with the `"both"` option: + +```js +/*eslint yield-star-spacing: ["error", "both"]*/ +/*eslint-env es6*/ + +function * generator() { + yield * other(); +} +``` + +### neither + +Examples of **correct** code for this rule with the `"neither"` option: + +```js +/*eslint yield-star-spacing: ["error", "neither"]*/ +/*eslint-env es6*/ + +function*generator() { + yield*other(); +} +``` + +## When Not To Use It + +If your project will not be using generators or you are not concerned with spacing consistency, you do not need this rule. + +## Further Reading + +* [Understanding ES6: Generators](https://leanpub.com/understandinges6/read/#leanpub-auto-generators) + +## Version + +This rule was introduced in ESLint 2.0.0-alpha-1. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/yield-star-spacing.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/yield-star-spacing.md) diff --git a/docs/8.0.0/rules/yoda.md b/docs/8.0.0/rules/yoda.md new file mode 100644 index 0000000000..f41fe043a9 --- /dev/null +++ b/docs/8.0.0/rules/yoda.md @@ -0,0 +1,206 @@ +--- +title: yoda - Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/yoda.md +rule_type: suggestion +--- + + +# Require or disallow Yoda Conditions (yoda) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +Yoda conditions are so named because the literal value of the condition comes first while the variable comes second. For example, the following is a Yoda condition: + +```js +if ("red" === color) { + // ... +} +``` + +This is called a Yoda condition because it reads as, "if red equals the color", similar to the way the Star Wars character Yoda speaks. Compare to the other way of arranging the operands: + +```js +if (color === "red") { + // ... +} +``` + +This typically reads, "if the color equals red", which is arguably a more natural way to describe the comparison. + +Proponents of Yoda conditions highlight that it is impossible to mistakenly use `=` instead of `==` because you cannot assign to a literal value. Doing so will cause a syntax error and you will be informed of the mistake early on. This practice was therefore very common in early programming where tools were not yet available. + +Opponents of Yoda conditions point out that tooling has made us better programmers because tools will catch the mistaken use of `=` instead of `==` (ESLint will catch this for you). Therefore, they argue, the utility of the pattern doesn't outweigh the readability hit the code takes while using Yoda conditions. + +## Rule Details + +This rule aims to enforce consistent style of conditions which compare a variable to a literal value. + +## Options + +This rule can take a string option: + +* If it is the default `"never"`, then comparisons must never be Yoda conditions. +* If it is `"always"`, then the literal value must always come first. + +The default `"never"` option can have exception options in an object literal: + +* If the `"exceptRange"` property is `true`, the rule *allows* yoda conditions in range comparisons which are wrapped directly in parentheses, including the parentheses of an `if` or `while` condition. The default value is `false`. A *range* comparison tests whether a variable is inside or outside the range between two literal values. +* If the `"onlyEquality"` property is `true`, the rule reports yoda conditions *only* for the equality operators `==` and `===`. The default value is `false`. + +The `onlyEquality` option allows a superset of the exceptions which `exceptRange` allows, thus both options are not useful together. + +### never + +Examples of **incorrect** code for the default `"never"` option: + +```js +/*eslint yoda: "error"*/ + +if ("red" === color) { + // ... +} + +if (`red` === color) { + // ... +} + +if (`red` === `${color}`) { + // ... +} + +if (true == flag) { + // ... +} + +if (5 > count) { + // ... +} + +if (-1 < str.indexOf(substr)) { + // ... +} + +if (0 <= x && x < 1) { + // ... +} +``` + +Examples of **correct** code for the default `"never"` option: + +```js +/*eslint yoda: "error"*/ + +if (5 & value) { + // ... +} + +if (value === "red") { + // ... +} + +if (value === `red`) { + // ... +} + +if (`${value}` === `red`) { + +} +``` + +### exceptRange + +Examples of **correct** code for the `"never", { "exceptRange": true }` options: + +```js +/*eslint yoda: ["error", "never", { "exceptRange": true }]*/ + +function isReddish(color) { + return (color.hue < 60 || 300 < color.hue); +} + +if (x < -1 || 1 < x) { + // ... +} + +if (count < 10 && (0 <= rand && rand < 1)) { + // ... +} + +if (`blue` < x && x < `green`) { + // ... +} + +function howLong(arr) { + return (0 <= arr.length && arr.length < 10) ? "short" : "long"; +} +``` + +### onlyEquality + +Examples of **correct** code for the `"never", { "onlyEquality": true }` options: + +```js +/*eslint yoda: ["error", "never", { "onlyEquality": true }]*/ + +if (x < -1 || 9 < x) { +} + +if (x !== 'foo' && 'bar' != x) { +} + +if (x !== `foo` && `bar` != x) { +} +``` + +### always + +Examples of **incorrect** code for the `"always"` option: + +```js +/*eslint yoda: ["error", "always"]*/ + +if (color == "blue") { + // ... +} + +if (color == `blue`) { + // ... +} +``` + +Examples of **correct** code for the `"always"` option: + +```js +/*eslint yoda: ["error", "always"]*/ + +if ("blue" == value) { + // ... +} + +if (`blue` == value) { + // ... +} + +if (`blue` == `${value}`) { + // ... +} + +if (-1 < str.indexOf(substr)) { + // ... +} +``` + +## Further Reading + +* [Yoda Conditions](https://en.wikipedia.org/wiki/Yoda_conditions) +* [Yoda Notation and Safe Switching](http://thomas.tuerke.net/on/design/?with=1249091668#msg1146181680) + +## Version + +This rule was introduced in ESLint 0.7.1. + +## Resources + +* [Rule source](https://github.com/eslint/eslint/tree/master/lib/rules/yoda.js) +* [Documentation source](https://github.com/eslint/eslint/tree/master/docs/rules/yoda.md) diff --git a/docs/8.0.0/user-guide/README.md b/docs/8.0.0/user-guide/README.md new file mode 100644 index 0000000000..1fcb0dfc12 --- /dev/null +++ b/docs/8.0.0/user-guide/README.md @@ -0,0 +1,39 @@ +# User Guide + +This guide is intended for those who wish to use ESLint as an end-user. If you're looking for how to extend ESLint or work with the ESLint source code, please see the [Developer Guide](../developer-guide). + +## [Getting Started](getting-started.md) + +Want to skip ahead and just start using ESLint? This section gives a high-level overview of installation, setup, and configuration options. + +## [Rules](../rules) + +ESLint has a lot of rules that you can configure to fine-tune it to your project. This section is an exhaustive list of every rule and link to each rule's documentation. + +## [Configuring](configuring/) + +Once you've got ESLint running, you'll probably want to adjust the configuration to better suit your project. This section explains all the different ways you can configure ESLint. + +## [Command Line Interface](command-line-interface.md) + +There are a lot of command line flags for ESLint and this section explains what they do. + +## [Integrations](integrations.md) + +Wondering if ESLint will work with your favorite editor or build system? This section has a list of all known integrations (submitted by their authors). + +## [Rule Deprecation](rule-deprecation.md) + +The ESLint team is committed to making upgrading as easy and painless as possible. This section outlines the guidelines the team has set in place for the deprecation of rules in future releases. + +## Migrating + +If you were using a prior version of ESLint, you can get help with the transition by reading: + +- [migrating-to-1.0.0](migrating-to-1.0.0.md) +- [migrating-to-2.0.0](migrating-to-2.0.0.md) +- [migrating-to-3.0.0](migrating-to-3.0.0.md) +- [migrating-to-4.0.0](migrating-to-4.0.0.md) +- [migrating-to-5.0.0](migrating-to-5.0.0.md) +- [migrating-to-6.0.0](migrating-to-6.0.0.md) +- [migrating-to-7.0.0](migrating-to-7.0.0.md) diff --git a/docs/8.0.0/user-guide/command-line-interface.md b/docs/8.0.0/user-guide/command-line-interface.md new file mode 100644 index 0000000000..093216eb1b --- /dev/null +++ b/docs/8.0.0/user-guide/command-line-interface.md @@ -0,0 +1,517 @@ +--- +title: Command Line Interface +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/user-guide/command-line-interface.md + +--- + + +# Command Line Interface + +To run ESLint on Node.js, you must have npm installed. If npm is not installed, follow the instructions here: https://www.npmjs.com/ + +Once npm is installed, run the following + + npm i -g eslint + +This installs the ESLint CLI from the npm repository. To run ESLint, use the following format: + + eslint [options] [file|dir|glob]* + +Such as: + + eslint file1.js file2.js + +or: + + eslint lib/** + +Please note that when passing a glob as a parameter, it will be expanded by your shell. The results of the expansion can vary depending on your shell, and its configuration. If you want to use node `glob` syntax, you have to quote your parameter (using double quotes if you need it to run in Windows), as follows: + + eslint "lib/**" + +## Options + +The command line utility has several options. You can view the options by running `eslint -h`. + +```text +eslint [options] file.js [file.js] [dir] + +Basic configuration: + --no-eslintrc Disable use of configuration from .eslintrc.* + -c, --config path::String Use this configuration, overriding .eslintrc.* config options if present + --env [String] Specify environments + --ext [String] Specify JavaScript file extensions - default: .js + --global [String] Define global variables + --parser String Specify the parser to be used + --parser-options Object Specify parser options + --resolve-plugins-relative-to path::String A folder where plugins should be resolved from, CWD by default + +Specifying rules and plugins: + --rulesdir [path::String] Use additional rules from this directory + --plugin [String] Specify plugins + --rule Object Specify rules + +Fixing problems: + --fix Automatically fix problems + --fix-dry-run Automatically fix problems without saving the changes to the file system + --fix-type Array Specify the types of fixes to apply (directive, problem, suggestion, layout) + +Ignoring files: + --ignore-path path::String Specify path of ignore file + --no-ignore Disable use of ignore files and patterns + --ignore-pattern [String] Pattern of files to ignore (in addition to those in .eslintignore) + +Using stdin: + --stdin Lint code provided on - default: false + --stdin-filename String Specify filename to process STDIN as + +Handling warnings: + --quiet Report errors only - default: false + --max-warnings Int Number of warnings to trigger nonzero exit code - default: -1 + +Output: + -o, --output-file path::String Specify file to write report to + -f, --format String Use a specific output format - default: stylish + --color, --no-color Force enabling/disabling of color + +Inline configuration comments: + --no-inline-config Prevent comments from changing config or rules + --report-unused-disable-directives Adds reported errors for unused eslint-disable directives + +Caching: + --cache Only check changed files - default: false + --cache-file path::String Path to the cache file. Deprecated: use --cache-location - default: .eslintcache + --cache-location path::String Path to the cache file or directory + --cache-strategy String Strategy to use for detecting changed files - either: metadata or content - default: metadata + +Miscellaneous: + --init Run config initialization wizard - default: false + --env-info Output execution environment information - default: false + --no-error-on-unmatched-pattern Prevent errors when pattern is unmatched - default: false + --exit-on-fatal-error Exit with exit code 2 in case of fatal error - default: false + --debug Output debugging information + -h, --help Show help + -v, --version Output the version number + --print-config path::String Print the configuration for the given file +``` + +Options that accept array values can be specified by repeating the option or with a comma-delimited list (other than `--ignore-pattern` which does not allow the second style). + +Example: + + eslint --ext .jsx --ext .js lib/ + + eslint --ext .jsx,.js lib/ + +### Basic configuration + +#### `--no-eslintrc` + +Disables use of configuration from `.eslintrc.*` and `package.json` files. + +Example: + + eslint --no-eslintrc file.js + +#### `-c`, `--config` + +This option allows you to specify an additional configuration file for ESLint (see [Configuring ESLint](configuring) for more). + +Example: + + eslint -c ~/my-eslint.json file.js + +This example uses the configuration file at `~/my-eslint.json`. + +If `.eslintrc.*` and/or `package.json` files are also used for configuration (i.e., `--no-eslintrc` was not specified), the configurations will be merged. Options from this configuration file have precedence over the options from `.eslintrc.*` and `package.json` files. + +#### `--env` + +This option enables specific environments. Details about the global variables defined by each environment are available on the [Specifying Environments](configuring/language-options#specifying-environments) documentation. This option only enables environments; it does not disable environments set in other configuration files. To specify multiple environments, separate them using commas, or use the option multiple times. + +Examples: + + eslint --env browser,node file.js + eslint --env browser --env node file.js + +#### `--ext` + +This option allows you to specify which file extensions ESLint will use when searching for target files in the directories you specify. +By default, ESLint lints `*.js` files and the files that match the `overrides` entries of your configuration. + +Examples: + + # Use only .ts extension + eslint . --ext .ts + + # Use both .js and .ts + eslint . --ext .js --ext .ts + + # Also use both .js and .ts + eslint . --ext .js,.ts + +**Note:** `--ext` is only used when the arguments are directories. If you use glob patterns or file names, then `--ext` is ignored. + +For example, `eslint lib/* --ext .js` will match all files within the `lib/` directory, regardless of extension. + +#### `--global` + +This option defines global variables so that they will not be flagged as undefined by the `no-undef` rule. Any specified global variables are assumed to be read-only by default, but appending `:true` to a variable's name ensures that `no-undef` will also allow writes. To specify multiple global variables, separate them using commas, or use the option multiple times. + +Examples: + + eslint --global require,exports:true file.js + eslint --global require --global exports:true + +#### `--parser` + +This option allows you to specify a parser to be used by ESLint. By default, `espree` will be used. + +#### `--parser-options` + +This option allows you to specify parser options to be used by ESLint. Note that the available parser options are determined by the parser being used. + +Examples: + + echo '3 ** 4' | eslint --stdin --parser-options=ecmaVersion:6 # will fail with a parsing error + echo '3 ** 4' | eslint --stdin --parser-options=ecmaVersion:7 # succeeds, yay! + +#### `--resolve-plugins-relative-to` + +Changes the folder where plugins are resolved from. By default, plugins are resolved from the current working directory. This option should be used when plugins were installed by someone other than the end user. It should be set to the project directory of the project that has a dependency on the necessary plugins. For example: + +* When using a config file that is located outside of the current project (with the `--config` flag), if the config uses plugins which are installed locally to itself, `--resolve-plugins-relative-to` should be set to the directory containing the config file. +* If an integration has dependencies on ESLint and a set of plugins, and the tool invokes ESLint on behalf of the user with a preset configuration, the tool should set `--resolve-plugins-relative-to` to the top-level directory of the tool. + +### Specifying rules and plugins + +#### `--rulesdir` + +This option allows you to specify another directory from which to load rules files. This allows you to dynamically load new rules at run time. This is useful when you have custom rules that aren't suitable for being bundled with ESLint. + +Example: + + eslint --rulesdir my-rules/ file.js + +The rules in your custom rules directory must follow the same format as bundled rules to work properly. You can also specify multiple locations for custom rules by including multiple `--rulesdir` options: + + eslint --rulesdir my-rules/ --rulesdir my-other-rules/ file.js + +Note that, as with core rules and plugin rules, you still need to enable the rules in configuration or via the `--rule` CLI option in order to actually run those rules during linting. Specifying a rules directory with `--rulesdir` does not automatically enable the rules within that directory. + +#### `--plugin` + +This option specifies a plugin to load. You can omit the prefix `eslint-plugin-` from the plugin name. + +Before using the plugin, you have to install it using npm. + +Examples: + + eslint --plugin jquery file.js + eslint --plugin eslint-plugin-mocha file.js + +#### `--rule` + +This option specifies rules to be used. These rules will be merged with any rules specified with configuration files. (You can use `--no-eslintrc` to change that behavior.) To define multiple rules, separate them using commas, or use the option multiple times. The [levn](https://github.com/gkz/levn#levn--) format is used for specifying the rules. + +If the rule is defined within a plugin, you have to prefix the rule ID with the plugin name and a `/`. + +Examples: + + eslint --rule 'quotes: [2, double]' + eslint --rule 'guard-for-in: 2' --rule 'brace-style: [2, 1tbs]' + eslint --rule 'jquery/dollar-sign: 2' + +### Fixing problems + +#### `--fix` + +This option instructs ESLint to try to fix as many issues as possible. The fixes are made to the actual files themselves and only the remaining unfixed issues are output. Not all problems are fixable using this option, and the option does not work in these situations: + +1. This option throws an error when code is piped to ESLint. +1. This option has no effect on code that uses a processor, unless the processor opts into allowing autofixes. + +If you want to fix code from `stdin` or otherwise want to get the fixes without actually writing them to the file, use the [`--fix-dry-run`](#--fix-dry-run) option. + +#### `--fix-dry-run` + +This option has the same effect as `--fix` with one difference: the fixes are not saved to the file system. This makes it possible to fix code from `stdin` (when used with the `--stdin` flag). + +Because the default formatter does not output the fixed code, you'll have to use another one (e.g. `json`) to get the fixes. Here's an example of this pattern: + +``` +getSomeText | eslint --stdin --fix-dry-run --format=json +``` + +This flag can be useful for integrations (e.g. editor plugins) which need to autofix text from the command line without saving it to the filesystem. + +#### `--fix-type` + +This option allows you to specify the type of fixes to apply when using either `--fix` or `--fix-dry-run`. The four types of fixes are: + +1. `problem` - fix potential errors in the code +1. `suggestion` - apply fixes to the code that improve it +1. `layout` - apply fixes that do not change the program structure (AST) +1. `directive` - apply fixes to inline directives such as `// eslint-disable` + +You can specify one or more fix type on the command line. Here are some examples: + +``` +eslint --fix --fix-type suggestion . +eslint --fix --fix-type suggestion --fix-type problem . +eslint --fix --fix-type suggestion,layout . +``` + +This option is helpful if you are using another program to format your code but you would still like ESLint to apply other types of fixes. + +### Ignoring files + +#### `--ignore-path` + +This option allows you to specify the file to use as your `.eslintignore`. By default, ESLint looks in the current working directory for `.eslintignore`. You can override this behavior by providing a path to a different file. + +Example: + + eslint --ignore-path tmp/.eslintignore file.js + eslint --ignore-path .gitignore file.js + +#### `--no-ignore` + +Disables excluding of files from `.eslintignore`, `--ignore-path`, `--ignore-pattern`, and `ignorePatterns` property in config files. + +Example: + + eslint --no-ignore file.js + +#### `--ignore-pattern` + +This option allows you to specify patterns of files to ignore (in addition to those in `.eslintignore`). You can repeat the option to provide multiple patterns. The supported syntax is the same as for `.eslintignore` [files](configuring/ignoring-code#the-eslintignore-file), which use the same patterns as the `.gitignore` [specification](https://git-scm.com/docs/gitignore). You should quote your patterns in order to avoid shell interpretation of glob patterns. + +Example: + + eslint --ignore-pattern '/lib/' --ignore-pattern '/src/vendor/*' . + +### Using stdin + +#### `--stdin` + +This option tells ESLint to read and lint source code from STDIN instead of from files. You can use this to pipe code to ESLint. + +Example: + + cat myfile.js | eslint --stdin + +#### `--stdin-filename` + +This option allows you to specify a filename to process STDIN as. This is useful when processing files from STDIN and you have rules which depend on the filename. + +Example + + cat myfile.js | eslint --stdin --stdin-filename=myfile.js + +### Handling warnings + +#### `--quiet` + +This option allows you to disable reporting on warnings. If you enable this option, only errors are reported by ESLint. + +Example: + + eslint --quiet file.js + +#### `--max-warnings` + +This option allows you to specify a warning threshold, which can be used to force ESLint to exit with an error status if there are too many warning-level rule violations in your project. + +Normally, if ESLint runs and finds no errors (only warnings), it will exit with a success exit status. However, if `--max-warnings` is specified and the total warning count is greater than the specified threshold, ESLint will exit with an error status. Specifying a threshold of `-1` or omitting this option will prevent this behavior. + +Example: + + eslint --max-warnings 10 file.js + +### Output + +#### `-o`, `--output-file` + +Enable report to be written to a file. + +Example: + + eslint -o ./test/test.html + +When specified, the given format is output into the provided file name. + +#### `-f`, `--format` + +This option specifies the output format for the console. Possible formats are: + +* [checkstyle](formatters/#checkstyle) +* [compact](formatters/#compact) +* [html](formatters/#html) +* [jslint-xml](formatters/#jslint-xml) +* [json](formatters/#json) +* [junit](formatters/#junit) +* [stylish](formatters/#stylish) (the default) +* [tap](formatters/#tap) +* [unix](formatters/#unix) +* [visualstudio](formatters/#visualstudio) + +Example: + + eslint -f compact file.js + +You can also use a custom formatter from the command line by specifying a path to the custom formatter file. + +Example: + + eslint -f ./customformat.js file.js + +An npm-installed formatter is resolved with or without `eslint-formatter-` prefix. + +Example: + + npm install eslint-formatter-pretty + + eslint -f pretty file.js + + // equivalent: + eslint -f eslint-formatter-pretty file.js + +When specified, the given format is output to the console. If you'd like to save that output into a file, you can do so on the command line like so: + + eslint -f compact file.js > results.txt + +This saves the output into the `results.txt` file. + +#### `--color`, `--no-color` + +This option forces the enabling/disabling of colorized output. You can use this to override the default behavior, which is to enable colorized output unless no TTY is detected, such as when piping `eslint` through `cat` or `less`. + +Examples: + + eslint --color file.js | cat + eslint --no-color file.js + +### Inline configuration comments + +#### `--no-inline-config` + +This option prevents inline comments like `/*eslint-disable*/` or +`/*global foo*/` from having any effect. This allows you to set an ESLint +config without files modifying it. All inline config comments are ignored, e.g.: + +* `/*eslint-disable*/` +* `/*eslint-enable*/` +* `/*global*/` +* `/*eslint*/` +* `/*eslint-env*/` +* `// eslint-disable-line` +* `// eslint-disable-next-line` + +Example: + + eslint --no-inline-config file.js + +#### `--report-unused-disable-directives` + +This option causes ESLint to report directive comments like `// eslint-disable-line` when no errors would have been reported on that line anyway. This can be useful to prevent future errors from unexpectedly being suppressed, by cleaning up old `eslint-disable` comments which are no longer applicable. + +**Warning**: When using this option, it is possible that new errors will start being reported whenever ESLint or custom rules are upgraded. For example, suppose a rule has a bug that causes it to report a false positive, and an `eslint-disable` comment is added to suppress the incorrect report. If the bug is then fixed in a patch release of ESLint, the `eslint-disable` comment will become unused since ESLint is no longer generating an incorrect report. This will result in a new reported error for the unused directive if the `report-unused-disable-directives` option is used. + +Example: + + eslint --report-unused-disable-directives file.js + +### Caching + +#### `--cache` + +Store the info about processed files in order to only operate on the changed ones. The cache is stored in `.eslintcache` by default. Enabling this option can dramatically improve ESLint's running time by ensuring that only changed files are linted. + +**Note:** If you run ESLint with `--cache` and then run ESLint without `--cache`, the `.eslintcache` file will be deleted. This is necessary because the results of the lint might change and make `.eslintcache` invalid. If you want to control when the cache file is deleted, then use `--cache-location` to specify an alternate location for the cache file. + +**Note:** Autofixed files are not placed in the cache. Subsequent linting that does not trigger an autofix will place it in the cache. + +#### `--cache-file` + +Path to the cache file. If none specified `.eslintcache` will be used. The file will be created in the directory where the `eslint` command is executed. **Deprecated**: Use `--cache-location` instead. + +#### `--cache-location` + +Path to the cache location. Can be a file or a directory. If no location is specified, `.eslintcache` will be used. In that case, the file will be created in the directory where the `eslint` command is executed. + +If a directory is specified, a cache file will be created inside the specified folder. The name of the file will be based on the hash of the current working directory (CWD). e.g.: `.cache_hashOfCWD` + +**Important note:** If the directory for the cache does not exist make sure you add a trailing `/` on \*nix systems or `\` in windows. Otherwise the path will be assumed to be a file. + +Example: + + eslint "src/**/*.js" --cache --cache-location "/Users/user/.eslintcache/" + +#### `--cache-strategy` + +Strategy for the cache to use for detecting changed files. Can be either `metadata` or `content`. If no strategy is specified, `metadata` will be used. + +The `content` strategy can be useful in cases where the modification time of your files change even if their contents have not. For example, this can happen during git operations like git clone because git does not track file modification time. + +Example: + + eslint "src/**/*.js" --cache --cache-strategy content + +### Miscellaneous + +#### `--init` + +This option will start config initialization wizard. It's designed to help new users quickly create .eslintrc file by answering a few questions, choosing a popular style guide, or inspecting your source files and attempting to automatically generate a suitable configuration. + +The resulting configuration file will be created in the current directory. + +#### `--env-info` + +This option outputs information about the execution environment, including the version of Node, npm, and local and global installations of ESLint. The ESLint team may ask for this information to help solve bugs. + +#### `--no-error-on-unmatched-pattern` + +This option prevents errors when a quoted glob pattern or `--ext` is unmatched. This will not prevent errors when your shell can't match a glob. + +#### `--exit-on-fatal-error` + +This option causes ESLint to exit with exit code 2 if one or more fatal parsing errors occur. Without this option, fatal parsing errors are reported as rule violations. + +#### `--debug` + +This option outputs debugging information to the console. This information is useful when you're seeing a problem and having a hard time pinpointing it. The ESLint team may ask for this debugging information to help solve bugs. + +#### `-h`, `--help` + +This option outputs the help menu, displaying all of the available options. All other options are ignored when this is present. + +#### `-v`, `--version` + +This option outputs the current ESLint version onto the console. All other options are ignored when this is present. + +#### `--print-config` + +This option outputs the configuration to be used for the file passed. When present, no linting is performed and only config-related options are valid. + +Example: + + eslint --print-config file.js + +## Ignoring files from linting + +ESLint supports `.eslintignore` files to exclude files from the linting process when ESLint operates on a directory. Files given as individual CLI arguments will be exempt from exclusion. The `.eslintignore` file is a plain text file containing one pattern per line. It can be located in any of the target directory's ancestors; it will affect files in its containing directory as well as all sub-directories. Here's a simple example of a `.eslintignore` file: + + temp.js + **/vendor/*.js + +A more detailed breakdown of supported patterns and directories ESLint ignores by default can be found in [Ignoring Code](configuring/ignoring-code). + +## Exit codes + +When linting files, ESLint will exit with one of the following exit codes: + +* `0`: Linting was successful and there are no linting errors. If the `--max-warnings` flag is set to `n`, the number of linting warnings is at most `n`. +* `1`: Linting was successful and there is at least one linting error, or there are more linting warnings than allowed by the `--max-warnings` option. +* `2`: Linting was unsuccessful due to a configuration problem or an internal error. diff --git a/docs/8.0.0/user-guide/configuring/README.md b/docs/8.0.0/user-guide/configuring/README.md new file mode 100644 index 0000000000..2d22421e0c --- /dev/null +++ b/docs/8.0.0/user-guide/configuring/README.md @@ -0,0 +1,52 @@ +# Configuring ESLint + +ESLint is designed to be flexible and configurable for your use case. You can turn off every rule and run only with basic syntax validation or mix and match the bundled rules and your custom rules to fit the needs of your project. There are two primary ways to configure ESLint: + +1. **Configuration Comments** - use JavaScript comments to embed configuration information directly into a file. +1. **Configuration Files** - use a JavaScript, JSON, or YAML file to specify configuration information for an entire directory and all of its subdirectories. This can be in the form of an [`.eslintrc.*`](./configuration-files.md#configuration-file-formats) file or an `eslintConfig` field in a [`package.json`](https://docs.npmjs.com/files/package.json) file, both of which ESLint will look for and read automatically, or you can specify a configuration file on the [command line](https://eslint.org/docs/user-guide/command-line-interface). + +Here are some of the options that you can configure in ESLint: + +* [**Environments**](./language-options.md#specifying-environments) - which environments your script is designed to run in. Each environment brings with it a certain set of predefined global variables. +* [**Globals**](./language-options.md#specifying-globals) - the additional global variables your script accesses during execution. +* [**Rules**](rules.md) - which rules are enabled and at what error level. +* [**Plugins**](plugins.md) - which third-party plugins define additional rules, environments, configs, etc. for ESLint to use. + +All of these options give you fine-grained control over how ESLint treats your code. + +## Table of Contents + +[**Configuration Files**](configuration-files.md) + +* [Configuration File Formats](./configuration-files.md#configuration-file-formats) +* [Using Configuration Files](./configuration-files.md#using-configuration-files) +* [Adding Shared Settings](./configuration-files.md#adding-shared-settings) +* [Cascading and Hierarchy](./configuration-files.md#cascading-and-hierarchy) +* [Extending Configuration Files](./configuration-files.md#extending-configuration-files) +* [Configuration Based on Glob Patterns](./configuration-files.md#configuration-based-on-glob-patterns) +* [Personal Configuration Files](./configuration-files.md#personal-configuration-files-deprecated) + +[**Language Options**](language-options.md) + +* [Specifying Environments](./language-options.md#specifying-environments) +* [Specifying Globals](./language-options.md#specifying-globals) +* [Specifying Parser Options](./language-options.md#specifying-parser-options) + +[**Rules**](rules.md) + +* [Configuring Rules](./rules.md#configuring-rules) +* [Disabling Rules](./rules.md#disabling-rules) + +[**Plugins**](plugins.md) + +* [Specifying Parser](./plugins.md#specifying-parser) +* [Specifying Processor](./plugins.md#specifying-processor) +* [Configuring Plugins](./plugins.md#configuring-plugins) + +[**Ignoring Code**](ignoring-code.md) + +* [`ignorePatterns` in Config Files](./ignoring-code.md#ignorepatterns-in-config-files) +* [The `.eslintignore` File](./ignoring-code.md#the-eslintignore-file) +* [Using an Alternate File](./ignoring-code.md#using-an-alternate-file) +* [Using eslintIgnore in package.json](./ignoring-code.md#using-eslintignore-in-packagejson) +* [Ignored File Warnings](./ignoring-code.md#ignored-file-warnings) diff --git a/docs/8.0.0/user-guide/configuring/configuration-files.md b/docs/8.0.0/user-guide/configuring/configuration-files.md new file mode 100644 index 0000000000..546f7b966e --- /dev/null +++ b/docs/8.0.0/user-guide/configuring/configuration-files.md @@ -0,0 +1,416 @@ +--- +title: Configuration Files +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/user-guide/configuring/configuration-files.md + +--- + + +# Configuration Files + +* [Configuration File Formats](#configuration-file-formats) +* [Using Configuration Files](#using-configuration-files) +* [Adding Shared Settings](#adding-shared-settings) +* [Cascading and Hierarchy](#cascading-and-hierarchy) +* [Extending Configuration Files](#extending-configuration-files) +* [Configuration Based on Glob Patterns](#configuration-based-on-glob-patterns) +* [Personal Configuration Files](#personal-configuration-files) + +## Configuration File Formats + +ESLint supports configuration files in several formats: + +* **JavaScript** - use `.eslintrc.js` and export an object containing your configuration. +* **JavaScript (ESM)** - use `.eslintrc.cjs` when running ESLint in JavaScript packages that specify `"type":"module"` in their `package.json`. Note that ESLint does not support ESM configuration at this time. +* **YAML** - use `.eslintrc.yaml` or `.eslintrc.yml` to define the configuration structure. +* **JSON** - use `.eslintrc.json` to define the configuration structure. ESLint's JSON files also allow JavaScript-style comments. +* **package.json** - create an `eslintConfig` property in your `package.json` file and define your configuration there. + +If there are multiple configuration files in the same directory, ESLint will only use one. The priority order is as follows: + +1. `.eslintrc.js` +1. `.eslintrc.cjs` +1. `.eslintrc.yaml` +1. `.eslintrc.yml` +1. `.eslintrc.json` +1. `package.json` + +## Using Configuration Files + +There are two ways to use configuration files. + +The first way to use configuration files is via `.eslintrc.*` and `package.json` files. ESLint will automatically look for them in the directory of the file to be linted, and in successive parent directories all the way up to the root directory of the filesystem (unless `root: true` is specified). Configuration files can be useful when you want different configurations for different parts of a project or when you want others to be able to use ESLint directly without needing to remember to pass in the configuration file. + +The second way to use configuration files is to save the file wherever you would like and pass its location to the CLI using the `--config` option, such as: + + eslint -c myconfig.json myfiletotest.js + +If you are using one configuration file and want ESLint to ignore any `.eslintrc.*` files, make sure to use [`--no-eslintrc`](https://eslint.org/docs/user-guide/command-line-interface#--no-eslintrc) along with the [`-c`](https://eslint.org/docs/user-guide/command-line-interface#-c---config) flag. + +### Comments in configuration files + +Both the JSON and YAML configuration file formats support comments (package.json files should not include them). You can use JavaScript-style comments for JSON files and YAML-style comments for YAML files. ESLint safely ignores comments in configuration files. This allows your configuration files to be more human-friendly. + +For JavaScript-style comments: + +```js +{ + "env": { + "browser": true + }, + "rules": { + // Override our default settings just for this directory + "eqeqeq": "warn", + "strict": "off" + } +} +``` + +For YAML-style comments: + +```yaml +env: + browser: true +rules: + # Override default settings + eqeqeq: warn + strict: off +``` + +## Adding Shared Settings + +ESLint supports adding shared settings into configuration files. Plugins use `settings` to specify information that should be shared across all of its rules. You can add `settings` object to ESLint configuration file and it will be supplied to every rule being executed. This may be useful if you are adding custom rules and want them to have access to the same information and be easily configurable. + +In JSON: + +```json +{ + "settings": { + "sharedData": "Hello" + } +} +``` + +And in YAML: + +```yaml +--- + settings: + sharedData: "Hello" +``` + +## Cascading and Hierarchy + +When using `.eslintrc.*` and `package.json` files for configuration, you can take advantage of configuration cascading. Suppose you have the following structure: + +```text +your-project +├── .eslintrc.json +├── lib +│ └── source.js +└─┬ tests + ├── .eslintrc.json + └── test.js +``` + +The configuration cascade works based on the location of the file being linted. If there is a `.eslintrc` file in the same directory as the file being linted, then that configuration takes precedence. ESLint then searches up the directory structure, merging any `.eslintrc` files it finds along the way until reaching either a `.eslintrc` file with `root: true` or the root directory. + +In the same way, if there is a `package.json` file in the root directory with an `eslintConfig` field, the configuration it describes will apply to all subdirectories beneath it, but the configuration described by the `.eslintrc` file in the `tests/` directory will override it where there are conflicting specifications. + +```text +your-project +├── package.json +├── lib +│ └── source.js +└─┬ tests + ├── .eslintrc.json + └── test.js +``` + +If there is an `.eslintrc` and a `package.json` file found in the same directory, `.eslintrc` will take priority and `package.json` file will not be used. + +By default, ESLint will look for configuration files in all parent folders up to the root directory. This can be useful if you want all of your projects to follow a certain convention, but can sometimes lead to unexpected results. To limit ESLint to a specific project, place `"root": true` inside the `.eslintrc.*` file or `eslintConfig` field of the `package.json` file or in the `.eslintrc.*` file at your project's root level. ESLint will stop looking in parent folders once it finds a configuration with `"root": true`. + +```js +{ + "root": true +} +``` + +And in YAML: + +```yaml +--- + root: true +``` + +For example, consider `projectA` which has `"root": true` set in the `.eslintrc` file in the `lib/` directory. In this case, while linting `main.js`, the configurations within `lib/` will be used, but the `.eslintrc` file in `projectA/` will not. + +```text +home +└── user + └── projectA + ├── .eslintrc.json <- Not used + └── lib + ├── .eslintrc.json <- { "root": true } + └── main.js +``` + +The complete configuration hierarchy, from highest to lowest precedence, is as follows: + +1. Inline configuration + 1. `/*eslint-disable*/` and `/*eslint-enable*/` + 1. `/*global*/` + 1. `/*eslint*/` + 1. `/*eslint-env*/` +1. Command line options (or CLIEngine equivalents): + 1. `--global` + 1. `--rule` + 1. `--env` + 1. `-c`, `--config` +1. Project-level configuration: + 1. `.eslintrc.*` or `package.json` file in the same directory as the linted file + 1. Continue searching for `.eslintrc.*` and `package.json` files in ancestor directories up to and including the root directory or until a config with `"root": true` is found. + +## Extending Configuration Files + +A configuration file, once extended, can inherit all the traits of another configuration file (including rules, plugins, and language options) and modify all the options. As a result, there are three configurations, as defined below: + +* Base config: the configuration that is extended. +* Derived config: the configuration that extends the base configuration. +* Resulting actual config: the result of merging the derived configuration into the base configuration. + +The `extends` property value is either: + +* a string that specifies a configuration (either a path to a config file, the name of a shareable config, `eslint:recommended`, or `eslint:all`) +* an array of strings where each additional configuration extends the preceding configurations + +ESLint extends configurations recursively, so a base configuration can also have an `extends` property. Relative paths and shareable config names in an `extends` property are resolved from the location of the config file where they appear. + +The `eslint-config-` prefix can be omitted from the configuration name. For example, `airbnb` resolves as `eslint-config-airbnb`. + +The `rules` property can do any of the following to extend (or override) the set of rules: + +* enable additional rules +* change an inherited rule's severity without changing its options: + * Base config: `"eqeqeq": ["error", "allow-null"]` + * Derived config: `"eqeqeq": "warn"` + * Resulting actual config: `"eqeqeq": ["warn", "allow-null"]` +* override options for rules from base configurations: + * Base config: `"quotes": ["error", "single", "avoid-escape"]` + * Derived config: `"quotes": ["error", "single"]` + * Resulting actual config: `"quotes": ["error", "single"]` + +### Using a shareable configuration package + +A [sharable configuration](https://eslint.org/docs/developer-guide/shareable-configs) is an npm package that exports a configuration object. Make sure that you have installed the package in your project root directory, so that ESLint can require it. + +The `extends` property value can omit the `eslint-config-` prefix of the package name. + +The `eslint --init` command can create a configuration so you can extend a popular style guide (for example, `eslint-config-standard`). + +Example of a configuration file in YAML format: + +```yaml +extends: standard +rules: + comma-dangle: + - error + - always + no-empty: warn +``` + +### Using `eslint:recommended` + +Using `"eslint:recommended"` in the `extends` property enables a subset of core rules that report common problems (these rules are identified with a checkmark (recommended) on the [rules page](https://eslint.org/docs/rules/)). + +Here's an example of extending `eslint:recommended` and overriding some of the set configuration options: + +Example of a configuration file in JavaScript format: + +```js +module.exports = { + "extends": "eslint:recommended", + "rules": { + // enable additional rules + "indent": ["error", 4], + "linebreak-style": ["error", "unix"], + "quotes": ["error", "double"], + "semi": ["error", "always"], + + // override configuration set by extending "eslint:recommended" + "no-empty": "warn", + "no-cond-assign": ["error", "always"], + + // disable rules from base configurations + "for-direction": "off", + } +} +``` + +### Using a configuration from a plugin + +A [plugin](https://eslint.org/docs/developer-guide/working-with-plugins) is an npm package that can add various extensions to ESLint. A plugin can perform numerous functions, including but not limited to adding new rules and exporting [shareable configurations](https://eslint.org/docs/developer-guide/working-with-plugins#configs-in-plugins). Make sure the package has been installed in a directory where ESLint can require it. + +The `plugins` [property value](./plugins#configuring-plugins) can omit the `eslint-plugin-` prefix of the package name. + +The `extends` property value can consist of: + +* `plugin:` +* the package name (from which you can omit the prefix, for example, `react` is short for `eslint-plugin-react`) +* `/` +* the configuration name (for example, `recommended`) + +Example of a configuration file in JSON format: + +```json +{ + "plugins": [ + "react" + ], + "extends": [ + "eslint:recommended", + "plugin:react/recommended" + ], + "rules": { + "react/no-set-state": "off" + } +} +``` + +### Using a configuration file + +The `extends` property value can be an absolute or relative path to a base [configuration file](#using-configuration-files). ESLint resolves a relative path to a base configuration file relative to the configuration file that uses it. + +Example of a configuration file in JSON format: + +```json +{ + "extends": [ + "./node_modules/coding-standard/eslintDefaults.js", + "./node_modules/coding-standard/.eslintrc-es6", + "./node_modules/coding-standard/.eslintrc-jsx" + ], + "rules": { + "eqeqeq": "warn" + } +} +``` + +### Using `"eslint:all"` + +The `extends` property value can be `"eslint:all"` to enable all core rules in the currently installed version of ESLint. The set of core rules can change at any minor or major version of ESLint. + +**Important:** This configuration is **not recommended for production use** because it changes with every minor and major version of ESLint. Use it at your own risk. + +You might enable all core rules as a shortcut to explore rules and options while you decide on the configuration for a project, especially if you rarely override options or disable rules. The default options for rules are not endorsements by ESLint (for example, the default option for the [`quotes`](https://eslint.org/docs/rules/quotes) rule does not mean double quotes are better than single quotes). + +If your configuration extends `eslint:all`, after you upgrade to a newer major or minor version of ESLint, review the reported problems before you use the `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#--fix), so you know if a new fixable rule will make changes to the code. + +Example of a configuration file in JavaScript format: + +```js +module.exports = { + "extends": "eslint:all", + "rules": { + // override default options + "comma-dangle": ["error", "always"], + "indent": ["error", 2], + "no-cond-assign": ["error", "always"], + + // disable now, but enable in the future + "one-var": "off", // ["error", "never"] + + // disable + "init-declarations": "off", + "no-console": "off", + "no-inline-comments": "off", + } +} +``` + +## Configuration Based on Glob Patterns + +v4.1.0+. Sometimes a more fine-controlled configuration is necessary, for example, if the configuration for files within the same directory has to be different. Therefore you can provide configurations under the `overrides` key that will only apply to files that match specific glob patterns, using the same format you would pass on the command line (e.g., `app/**/*.test.js`). + +### How do overrides work? + +It is possible to override settings based on file glob patterns in your configuration by using the `overrides` key. An example of using the `overrides` key is as follows: + +In your `.eslintrc.json`: + +```json +{ + "rules": { + "quotes": ["error", "double"] + }, + + "overrides": [ + { + "files": ["bin/*.js", "lib/*.js"], + "excludedFiles": "*.test.js", + "rules": { + "quotes": ["error", "single"] + } + } + ] +} +``` + +Here is how overrides work in a configuration file: + +* The patterns are applied against the file path relative to the directory of the config file. For example, if your config file has the path `/Users/john/workspace/any-project/.eslintrc.js` and the file you want to lint has the path `/Users/john/workspace/any-project/lib/util.js`, then the pattern provided in `.eslintrc.js` will be executed against the relative path `lib/util.js`. +* Glob pattern overrides have higher precedence than the regular configuration in the same config file. Multiple overrides within the same config are applied in order. That is, the last override block in a config file always has the highest precedence. +* A glob specific configuration works almost the same as any other ESLint config. Override blocks can contain any configuration options that are valid in a regular config, with the exception of `root` and `ignorePatterns`. + * A glob specific configuration can have an `extends` setting, but the `root` property in the extended configs is ignored. The `ignorePatterns` property in the extended configs is used only for the files the glob specific configuration matched. + * Nested `overrides` setting will be applied only if the glob patterns of both of the parent config and the child config matched. This is the same when the extended configs have an `overrides` setting. +* Multiple glob patterns can be provided within a single override block. A file must match at least one of the supplied patterns for the configuration to apply. +* Override blocks can also specify patterns to exclude from matches. If a file matches any of the excluded patterns, the configuration won't apply. + +### Relative glob patterns + +``` +project-root +├── app +│ ├── lib +│ │ ├── foo.js +│ │ ├── fooSpec.js +│ ├── components +│ │ ├── bar.js +│ │ ├── barSpec.js +│ ├── .eslintrc.json +├── server +│ ├── server.js +│ ├── serverSpec.js +├── .eslintrc.json +``` + +The config in `app/.eslintrc.json` defines the glob pattern `**/*Spec.js`. This pattern is relative to the base directory of `app/.eslintrc.json`. So, this pattern would match `app/lib/fooSpec.js` and `app/components/barSpec.js` but **NOT** `server/serverSpec.js`. If you defined the same pattern in the `.eslintrc.json` file within in the `project-root` folder, it would match all three of the `*Spec` files. + +If a config is provided via the `--config` CLI option, the glob patterns in the config are relative to the current working directory rather than the base directory of the given config. For example, if `--config configs/.eslintrc.json` is present, the glob patterns in the config are relative to `.` rather than `./configs`. + +### Specifying target files to lint + +If you specified directories with CLI (e.g., `eslint lib`), ESLint searches target files in the directory to lint. The target files are `*.js` or the files that match any of `overrides` entries (but exclude entries that are any of `files` end with `*`). + +If you specified the [`--ext`](https://eslint.org/docs/user-guide/command-line-interface#ext) command line option along with directories, the target files are only the files that have specified file extensions regardless of `overrides` entries. + +## Personal Configuration Files (deprecated) + +⚠️ **This feature has been deprecated**. This feature will be removed in the 8.0.0 release. If you want to continue to use personal configuration files, please use the [`--config` CLI option](https://eslint.org/docs/user-guide/command-line-interface#-c---config). For more information regarding this decision, please see [RFC 28](https://github.com/eslint/rfcs/pull/28) and [RFC 32](https://github.com/eslint/rfcs/pull/32). + +`~/` refers to [the home directory of the current user on your preferred operating system](https://nodejs.org/api/os.html#os_os_homedir). The personal configuration file being referred to here is `~/.eslintrc.*` file, which is currently handled differently than other configuration files. + +### How does ESLint find personal configuration files? + +If `eslint` could not find any configuration file in the project, `eslint` loads `~/.eslintrc.*` file. + +If `eslint` could find configuration files in the project, `eslint` ignores `~/.eslintrc.*` file even if it's in an ancestor directory of the project directory. + +### How do personal configuration files behave? + +`~/.eslintrc.*` files behave similarly to regular configuration files, with some exceptions: + +`~/.eslintrc.*` files load shareable configs and custom parsers from `~/node_modules/` – similarly to `require()` – in the user's home directory. Please note that it doesn't load global-installed packages. + +`~/.eslintrc.*` files load plugins from `$CWD/node_modules` by default in order to identify plugins uniquely. If you want to use plugins with `~/.eslintrc.*` files, plugins must be installed locally per project. Alternatively, you can use the [`--resolve-plugins-relative-to` CLI option](https://eslint.org/docs/user-guide/command-line-interface#--resolve-plugins-relative-to) to change the location from which ESLint loads plugins. diff --git a/docs/8.0.0/user-guide/configuring/ignoring-code.md b/docs/8.0.0/user-guide/configuring/ignoring-code.md new file mode 100644 index 0000000000..6d08c2eaa2 --- /dev/null +++ b/docs/8.0.0/user-guide/configuring/ignoring-code.md @@ -0,0 +1,163 @@ +--- +title: Ignoring Code +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/user-guide/configuring/ignoring-code.md + +--- + + +# Ignoring Code + + +* [`ignorePatterns` in Config Files](#ignorepatterns-in-config-files) +* [The `.eslintignore` File](#the-eslintignore-file) +* [Using an Alternate File](#using-an-alternate-file) +* [Using eslintIgnore in package.json](#using-eslintignore-in-packagejson) +* [Ignored File Warnings](#ignored-file-warnings) + +## `ignorePatterns` in Config Files + +You can tell ESLint to ignore specific files and directories using `ignorePatterns` in your config files. `ignorePatterns` patterns follow the same rules as `.eslintignore`. Please see the [the `.eslintignore` file documentation](./ignoring-code#the-eslintignore-file) to learn more. + +```json +{ + "ignorePatterns": ["temp.js", "**/vendor/*.js"], + "rules": { + //... + } +} +``` + +* Glob patterns in `ignorePatterns` are relative to the directory that the config file is placed in. +* You cannot write `ignorePatterns` property under `overrides` property. +* Patterns defined in `.eslintignore` take precedence over the `ignorePatterns` property of config files. + +If a glob pattern starts with `/`, the pattern is relative to the base directory of the config file. For example, `/foo.js` in `lib/.eslintrc.json` matches to `lib/foo.js` but not `lib/subdir/foo.js`. + +If a config is provided via the `--config` CLI option, the ignore patterns that start with `/` in the config are relative to the current working directory rather than the base directory of the given config. For example, if `--config configs/.eslintrc.json` is present, the ignore patterns in the config are relative to `.` rather than `./configs`. + +## The `.eslintignore` File + +You can tell ESLint to ignore specific files and directories by creating an `.eslintignore` file in your project's root directory. The `.eslintignore` file is a plain text file where each line is a glob pattern indicating which paths should be omitted from linting. For example, the following will omit all JavaScript files: + +```text +**/*.js +``` + +When ESLint is run, it looks in the current working directory to find an `.eslintignore` file before determining which files to lint. If this file is found, then those preferences are applied when traversing directories. Only one `.eslintignore` file can be used at a time, so `.eslintignore` files other than the one in the current working directory will not be used. + +Globs are matched using [node-ignore](https://github.com/kaelzhang/node-ignore), so a number of features are available: + +* Lines beginning with `#` are treated as comments and do not affect the ignore patterns. +* Paths are relative to the current working directory. This is also true of paths passed in via the `--ignore-pattern` [command](https://eslint.org/docs/user-guide/command-line-interface#--ignore-pattern). +* Lines preceded by `!` are negated patterns that re-include a pattern that was ignored by an earlier pattern. +* Ignore patterns behave according to the `.gitignore` [specification](https://git-scm.com/docs/gitignore). + +Of particular note is that like `.gitignore` files, all paths used as patterns for both `.eslintignore` and `--ignore-pattern` must use forward slashes as their path separators. + +```text +# Valid +/root/src/*.js + +# Invalid +\root\src\*.js +``` + +Please see [`.gitignore`](https://git-scm.com/docs/gitignore)'s specification for further examples of valid syntax. + +In addition to any patterns in the `.eslintignore` file, ESLint always follows a couple of implicit ignore rules even if the `--no-ignore` flag is passed. The implicit rules are as follows: + +* `node_modules/` is ignored. +* dot-files (except for `.eslintrc.*`), as well as dot-folders and their contents, are ignored. + +There are also some exceptions to these rules: + +* If the path to lint is a glob pattern or directory path and contains a dot-folder, all dot-files and dot-folders will be linted. This includes dot-files and dot-folders that are buried deeper in the directory structure. + + For example, `eslint .config/` will lint all dot-folders and dot-files in the `.config` directory, including immediate children as well as children that are deeper in the directory structure. + +* If the path to lint is a specific file path and the `--no-ignore` flag has been passed, ESLint will lint the file regardless of the implicit ignore rules. + + For example, `eslint .config/my-config-file.js --no-ignore` will cause `my-config-file.js` to be linted. It should be noted that the same command without the `--no-ignore` line will not lint the `my-config-file.js` file. + +* Allowlist and denylist rules specified via `--ignore-pattern` or `.eslintignore` are prioritized above implicit ignore rules. + + For example, in this scenario, `.build/test.js` is the desired file to allowlist. Because all dot-folders and their children are ignored by default, `.build` must first be allowlisted so that eslint becomes aware of its children. Then, `.build/test.js` must be explicitly allowlisted, while the rest of the content is denylisted. This is done with the following `.eslintignore` file: + + ```text + # Allowlist 'test.js' in the '.build' folder + # But do not allow anything else in the '.build' folder to be linted + !.build + .build/* + !.build/test.js + ``` + + The following `--ignore-pattern` is also equivalent: + + eslint --ignore-pattern '!.build' --ignore-pattern '.build/*' --ignore-pattern '!.build/test.js' parent-folder/ + +## Using an Alternate File + +If you'd prefer to use a different file than the `.eslintignore` in the current working directory, you can specify it on the command line using the `--ignore-path` option. For example, you can use `.jshintignore` file because it has the same format: + + eslint --ignore-path .jshintignore file.js + +You can also use your `.gitignore` file: + + eslint --ignore-path .gitignore file.js + +Any file that follows the standard ignore file format can be used. Keep in mind that specifying `--ignore-path` means that any existing `.eslintignore` file will not be used. Note that globbing rules in `.eslintignore` follow those of `.gitignore`. + +## Using eslintIgnore in package.json + +If an `.eslintignore` file is not found and an alternate file is not specified, ESLint will look in package.json for an `eslintIgnore` key to check for files to ignore. + + { + "name": "mypackage", + "version": "0.0.1", + "eslintConfig": { + "env": { + "browser": true, + "node": true + } + }, + "eslintIgnore": ["hello.js", "world.js"] + } + +## Ignored File Warnings + +When you pass directories to ESLint, files and directories are silently ignored. If you pass a specific file to ESLint, then you will see a warning indicating that the file was skipped. For example, suppose you have an `.eslintignore` file that looks like this: + +```text +foo.js +``` + +And then you run: + + eslint foo.js + +You'll see this warning: + +```text +foo.js + 0:0 warning File ignored because of a matching ignore pattern. Use "--no-ignore" to override. + +✖ 1 problem (0 errors, 1 warning) +``` + +This message occurs because ESLint is unsure if you wanted to actually lint the file or not. As the message indicates, you can use `--no-ignore` to omit using the ignore rules. + +Consider another scenario where you may want to run ESLint on a specific dot-file or dot-folder, but have forgotten to specifically allow those files in your `.eslintignore` file. You would run something like this: + + eslint .config/foo.js + +You would see this warning: + +```text +.config/foo.js + 0:0 warning File ignored by default. Use a negated ignore pattern (like "--ignore-pattern '!'") to override + +✖ 1 problem (0 errors, 1 warning) +``` + +This message occurs because, normally, this file would be ignored by ESLint's implicit ignore rules (as mentioned above). A negated ignore rule in your `.eslintignore` file would override the implicit rule and reinclude this file for linting. Additionally, in this specific case, `--no-ignore` could be used to lint the file as well. diff --git a/docs/8.0.0/user-guide/configuring/index.md b/docs/8.0.0/user-guide/configuring/index.md new file mode 100644 index 0000000000..1a87e37abe --- /dev/null +++ b/docs/8.0.0/user-guide/configuring/index.md @@ -0,0 +1,60 @@ +--- +title: Configuring ESLint +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/user-guide/configuring/README.md + +--- + + +# Configuring ESLint + +ESLint is designed to be flexible and configurable for your use case. You can turn off every rule and run only with basic syntax validation or mix and match the bundled rules and your custom rules to fit the needs of your project. There are two primary ways to configure ESLint: + +1. **Configuration Comments** - use JavaScript comments to embed configuration information directly into a file. +1. **Configuration Files** - use a JavaScript, JSON, or YAML file to specify configuration information for an entire directory and all of its subdirectories. This can be in the form of an [`.eslintrc.*`](./configuration-files#configuration-file-formats) file or an `eslintConfig` field in a [`package.json`](https://docs.npmjs.com/files/package.json) file, both of which ESLint will look for and read automatically, or you can specify a configuration file on the [command line](https://eslint.org/docs/user-guide/command-line-interface). + +Here are some of the options that you can configure in ESLint: + +* [**Environments**](./language-options#specifying-environments) - which environments your script is designed to run in. Each environment brings with it a certain set of predefined global variables. +* [**Globals**](./language-options#specifying-globals) - the additional global variables your script accesses during execution. +* [**Rules**](rules) - which rules are enabled and at what error level. +* [**Plugins**](plugins) - which third-party plugins define additional rules, environments, configs, etc. for ESLint to use. + +All of these options give you fine-grained control over how ESLint treats your code. + +## Table of Contents + +[**Configuration Files**](configuration-files) + +* [Configuration File Formats](./configuration-files#configuration-file-formats) +* [Using Configuration Files](./configuration-files#using-configuration-files) +* [Adding Shared Settings](./configuration-files#adding-shared-settings) +* [Cascading and Hierarchy](./configuration-files#cascading-and-hierarchy) +* [Extending Configuration Files](./configuration-files#extending-configuration-files) +* [Configuration Based on Glob Patterns](./configuration-files#configuration-based-on-glob-patterns) +* [Personal Configuration Files](./configuration-files#personal-configuration-files-deprecated) + +[**Language Options**](language-options) + +* [Specifying Environments](./language-options#specifying-environments) +* [Specifying Globals](./language-options#specifying-globals) +* [Specifying Parser Options](./language-options#specifying-parser-options) + +[**Rules**](rules) + +* [Configuring Rules](./rules#configuring-rules) +* [Disabling Rules](./rules#disabling-rules) + +[**Plugins**](plugins) + +* [Specifying Parser](./plugins#specifying-parser) +* [Specifying Processor](./plugins#specifying-processor) +* [Configuring Plugins](./plugins#configuring-plugins) + +[**Ignoring Code**](ignoring-code) + +* [`ignorePatterns` in Config Files](./ignoring-code#ignorepatterns-in-config-files) +* [The `.eslintignore` File](./ignoring-code#the-eslintignore-file) +* [Using an Alternate File](./ignoring-code#using-an-alternate-file) +* [Using eslintIgnore in package.json](./ignoring-code#using-eslintignore-in-packagejson) +* [Ignored File Warnings](./ignoring-code#ignored-file-warnings) diff --git a/docs/8.0.0/user-guide/configuring/language-options.md b/docs/8.0.0/user-guide/configuring/language-options.md new file mode 100644 index 0000000000..f27b85ac34 --- /dev/null +++ b/docs/8.0.0/user-guide/configuring/language-options.md @@ -0,0 +1,230 @@ +--- +title: Language Options +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/user-guide/configuring/language-options.md + +--- + + +# Language Options + + +* [Specifying Environments](#specifying-environments) +* [Specifying Globals](#specifying-globals) +* [Specifying Parser Options](#specifying-parser-options) + +## Specifying Environments + +An environment provides predefined global variables. The available environments are: + +* `browser` - browser global variables. +* `node` - Node.js global variables and Node.js scoping. +* `commonjs` - CommonJS global variables and CommonJS scoping (use this for browser-only code that uses Browserify/WebPack). +* `shared-node-browser` - Globals common to both Node.js and Browser. +* `es6` - enable all ECMAScript 6 features except for modules (this automatically sets the `ecmaVersion` parser option to 6). +* `es2017` - adds all ECMAScript 2017 globals and automatically sets the `ecmaVersion` parser option to 8. +* `es2020` - adds all ECMAScript 2020 globals and automatically sets the `ecmaVersion` parser option to 11. +* `es2021` - adds all ECMAScript 2021 globals and automatically sets the `ecmaVersion` parser option to 12. +* `worker` - web workers global variables. +* `amd` - defines `require()` and `define()` as global variables as per the [amd](https://github.com/amdjs/amdjs-api/wiki/AMD) spec. +* `mocha` - adds all of the Mocha testing global variables. +* `jasmine` - adds all of the Jasmine testing global variables for version 1.3 and 2.0. +* `jest` - Jest global variables. +* `phantomjs` - PhantomJS global variables. +* `protractor` - Protractor global variables. +* `qunit` - QUnit global variables. +* `jquery` - jQuery global variables. +* `prototypejs` - Prototype.js global variables. +* `shelljs` - ShellJS global variables. +* `meteor` - Meteor global variables. +* `mongo` - MongoDB global variables. +* `applescript` - AppleScript global variables. +* `nashorn` - Java 8 Nashorn global variables. +* `serviceworker` - Service Worker global variables. +* `atomtest` - Atom test helper globals. +* `embertest` - Ember test helper globals. +* `webextensions` - WebExtensions globals. +* `greasemonkey` - GreaseMonkey globals. + +These environments are not mutually exclusive, so you can define more than one at a time. + +Environments can be specified inside of a file, in configuration files or using the `--env` [command line](https://eslint.org/docs/user-guide/command-line-interface) flag. + +### Using configuration comments + +To specify environments using a line or block comment inside of your JavaScript file, use the following format: + +```js +/* eslint-env node, mocha */ +``` + +```js +// eslint-env node, mocha +``` + +This enables Node.js and Mocha environments. + +### Using configuration files + +To specify environments in a configuration file, use the `env` key and specify which environments you want to enable by setting each to `true`. For example, the following enables the browser and Node.js environments: + +```json +{ + "env": { + "browser": true, + "node": true + } +} +``` + +Or in a `package.json` file + +```json +{ + "name": "mypackage", + "version": "0.0.1", + "eslintConfig": { + "env": { + "browser": true, + "node": true + } + } +} +``` + +And in YAML: + +```yaml +--- + env: + browser: true + node: true +``` + +### Using a plugin + +If you want to use an environment from a plugin, be sure to specify the plugin name in the `plugins` array and then use the unprefixed plugin name, followed by a slash, followed by the environment name. For example: + +```json +{ + "plugins": ["example"], + "env": { + "example/custom": true + } +} +``` + +Or in a `package.json` file + +```json +{ + "name": "mypackage", + "version": "0.0.1", + "eslintConfig": { + "plugins": ["example"], + "env": { + "example/custom": true + } + } +} +``` + +## Specifying Globals + +Some of ESLint's core rules rely on knowledge of the global variables available to your code at runtime. Since these can vary greatly between different environments as well as be modified at runtime, ESLint makes no assumptions about what global variables exist in your execution environment. If you would like to use rules that require knowledge of what global variables are available, you can define global variables in your configuration file or by using configuration comments in your source code. + +### Using configuration comments + +To specify globals using a line or block comment inside of your JavaScript file, use the following format: + +```js +/* global var1, var2 */ +``` + +```js +// global var1, var2 +``` + +This defines two global variables, `var1` and `var2`. If you want to optionally specify that these global variables can be written to (rather than only being read), then you can set each with a `"writable"` flag: + +```js +/* global var1:writable, var2:writable */ +``` + +### Using configuration files + +To configure global variables inside of a configuration file, set the `globals` configuration property to an object containing keys named for each of the global variables you want to use. For each global variable key, set the corresponding value equal to `"writable"` to allow the variable to be overwritten or `"readonly"` to disallow overwriting. For example: + +```json +{ + "globals": { + "var1": "writable", + "var2": "readonly" + } +} +``` + +And in YAML: + +```yaml +--- + globals: + var1: writable + var2: readonly +``` + +These examples allow `var1` to be overwritten in your code, but disallow it for `var2`. + +Globals can be disabled with the string `"off"`. For example, in an environment where most ES2015 globals are available but `Promise` is unavailable, you might use this config: + +```json +{ + "env": { + "es6": true + }, + "globals": { + "Promise": "off" + } +} +``` + +For historical reasons, the boolean value `false` and the string value `"readable"` are equivalent to `"readonly"`. Similarly, the boolean value `true` and the string value `"writeable"` are equivalent to `"writable"`. However, the use of older values is deprecated. + + +## Specifying Parser Options + +ESLint allows you to specify the JavaScript language options you want to support. By default, ESLint expects ECMAScript 5 syntax. You can override that setting to enable support for other ECMAScript versions as well as JSX by using parser options. + +Please note that supporting JSX syntax is not the same as supporting React. React applies specific semantics to JSX syntax that ESLint doesn't recognize. We recommend using [eslint-plugin-react](https://github.com/yannickcr/eslint-plugin-react) if you are using React and want React semantics. +By the same token, supporting ES6 syntax is not the same as supporting new ES6 globals (e.g., new types such as +`Set`). +For ES6 syntax, use `{ "parserOptions": { "ecmaVersion": 6 } }`; for new ES6 global variables, use `{ "env": +{ "es6": true } }`. `{ "env": { "es6": true } }` enables ES6 syntax automatically, but `{ "parserOptions": { "ecmaVersion": 6 } }` does not enable ES6 globals automatically. + +Parser options are set in your `.eslintrc.*` file by using the `parserOptions` property. The available options are: + +* `ecmaVersion` - set to 3, 5 (default), 6, 7, 8, 9, 10, 11, or 12 to specify the version of ECMAScript syntax you want to use. You can also set to 2015 (same as 6), 2016 (same as 7), 2017 (same as 8), 2018 (same as 9), 2019 (same as 10), 2020 (same as 11), or 2021 (same as 12) to use the year-based naming. You can also set "latest" to use the most recently supported version. +* `sourceType` - set to `"script"` (default) or `"module"` if your code is in ECMAScript modules. +* `ecmaFeatures` - an object indicating which additional language features you'd like to use: + * `globalReturn` - allow `return` statements in the global scope + * `impliedStrict` - enable global [strict mode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode) (if `ecmaVersion` is 5 or greater) + * `jsx` - enable [JSX](https://facebook.github.io/jsx/) + +Here's an example `.eslintrc.json` file: + +```json +{ + "parserOptions": { + "ecmaVersion": "latest", + "sourceType": "module", + "ecmaFeatures": { + "jsx": true + } + }, + "rules": { + "semi": "error" + } +} +``` + +Setting parser options helps ESLint determine what is a parsing error. All language options are `false` by default. diff --git a/docs/8.0.0/user-guide/configuring/plugins.md b/docs/8.0.0/user-guide/configuring/plugins.md new file mode 100644 index 0000000000..8d4da69ff9 --- /dev/null +++ b/docs/8.0.0/user-guide/configuring/plugins.md @@ -0,0 +1,185 @@ +--- +title: Plugins +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/user-guide/configuring/plugins.md + +--- + + +# Plugins + + +* [Specifying Parser](#specifying-parser) +* [Specifying Processor](#specifying-processor) +* [Configuring Plugins](#configuring-plugins) + +## Specifying Parser + +By default, ESLint uses [Espree](https://github.com/eslint/espree) as its parser. You can optionally specify that a different parser should be used in your configuration file so long as the parser meets the following requirements: + +1. It must be a Node module loadable from the config file where the parser is used. Usually, this means you should install the parser package separately using npm. +1. It must conform to the [parser interface](https://eslint.org/docs/developer-guide/working-with-custom-parsers). + +Note that even with these compatibilities, there are no guarantees that an external parser will work correctly with ESLint and ESLint will not fix bugs related to incompatibilities with other parsers. + +To indicate the npm module to use as your parser, specify it using the `parser` option in your `.eslintrc` file. For example, the following specifies to use Esprima instead of Espree: + +```json +{ + "parser": "esprima", + "rules": { + "semi": "error" + } +} +``` + +The following parsers are compatible with ESLint: + +* [Esprima](https://www.npmjs.com/package/esprima) +* [@babel/eslint-parser](https://www.npmjs.com/package/@babel/eslint-parser) - A wrapper around the [Babel](https://babeljs.io) parser that makes it compatible with ESLint. +* [@typescript-eslint/parser](https://www.npmjs.com/package/@typescript-eslint/parser) - A parser that converts TypeScript into an ESTree-compatible form so it can be used in ESLint. + +Note when using a custom parser, the `parserOptions` configuration property is still required for ESLint to work properly with features not in ECMAScript 5 by default. Parsers are all passed `parserOptions` and may or may not use them to determine which features to enable. + +## Specifying Processor + +Plugins may provide processors. Processors can extract JavaScript code from other kinds of files, then let ESLint lint the JavaScript code or processors can convert JavaScript code in preprocessing for some purpose. + +To specify processors in a configuration file, use the `processor` key with the concatenated string of a plugin name and a processor name by a slash. For example, the following enables the processor `a-processor` that the plugin `a-plugin` provided: + +```json +{ + "plugins": ["a-plugin"], + "processor": "a-plugin/a-processor" +} +``` + +To specify processors for specific kinds of files, use the combination of the `overrides` key and the `processor` key. For example, the following uses the processor `a-plugin/markdown` for `*.md` files. + +```json +{ + "plugins": ["a-plugin"], + "overrides": [ + { + "files": ["*.md"], + "processor": "a-plugin/markdown" + } + ] +} +``` + +Processors may make named code blocks such as `0.js` and `1.js`. ESLint handles such a named code block as a child file of the original file. You can specify additional configurations for named code blocks in the `overrides` section of the config. For example, the following disables the `strict` rule for the named code blocks which end with `.js` in markdown files. + +```json +{ + "plugins": ["a-plugin"], + "overrides": [ + { + "files": ["*.md"], + "processor": "a-plugin/markdown" + }, + { + "files": ["**/*.md/*.js"], + "rules": { + "strict": "off" + } + } + ] +} +``` + +ESLint checks the file path of named code blocks then ignores those if any `overrides` entry didn't match the file path. Be sure to add an `overrides` entry if you want to lint named code blocks other than `*.js`. + +## Configuring Plugins + +ESLint supports the use of third-party plugins. Before using the plugin, you have to install it using npm. + +To configure plugins inside of a configuration file, use the `plugins` key, which contains a list of plugin names. The `eslint-plugin-` prefix can be omitted from the plugin name. + +```json +{ + "plugins": [ + "plugin1", + "eslint-plugin-plugin2" + ] +} +``` + +And in YAML: + +```yaml +--- + plugins: + - plugin1 + - eslint-plugin-plugin2 +``` + +**Notes:** + +1. Plugins are resolved relative to the config file. In other words, ESLint will load the plugin as a user would obtain by running `require('eslint-plugin-pluginname')` in the config file. +2. Plugins in the base configuration (loaded by `extends` setting) are relative to the derived config file. For example, if `./.eslintrc` has `extends: ["foo"]` and the `eslint-config-foo` has `plugins: ["bar"]`, ESLint finds the `eslint-plugin-bar` from `./node_modules/` (rather than `./node_modules/eslint-config-foo/node_modules/`) or ancestor directories. Thus every plugin in the config file and base configurations is resolved uniquely. + +### Naming convention + +#### Include a plugin + +The `eslint-plugin-` prefix can be omitted for non-scoped packages + +```js +{ + // ... + "plugins": [ + "jquery", // means eslint-plugin-jquery + ] + // ... +} +``` + +The same rule does apply to scoped packages: + +```js +{ + // ... + "plugins": [ + "@jquery/jquery", // means @jquery/eslint-plugin-jquery + "@foobar" // means @foobar/eslint-plugin + ] + // ... +} +``` + +#### Use a plugin + +When using rules, environments or configs defined by plugins, they must be referenced following the convention: + +* `eslint-plugin-foo` → `foo/a-rule` +* `@foo/eslint-plugin` → `@foo/a-config` +* `@foo/eslint-plugin-bar` → `@foo/bar/a-environment` + +For example: + +```js +{ + // ... + "plugins": [ + "jquery", // eslint-plugin-jquery + "@foo/foo", // @foo/eslint-plugin-foo + "@bar" // @bar/eslint-plugin + ], + "extends": [ + "plugin:@foo/foo/recommended", + "plugin:@bar/recommended" + ], + "rules": { + "jquery/a-rule": "error", + "@foo/foo/some-rule": "error", + "@bar/another-rule": "error" + }, + "env": { + "jquery/jquery": true, + "@foo/foo/env-foo": true, + "@bar/env-bar": true, + } + // ... +} +``` diff --git a/docs/8.0.0/user-guide/configuring/rules.md b/docs/8.0.0/user-guide/configuring/rules.md new file mode 100644 index 0000000000..fb68a056bb --- /dev/null +++ b/docs/8.0.0/user-guide/configuring/rules.md @@ -0,0 +1,284 @@ +--- +title: Rules +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/user-guide/configuring/rules.md + +--- + + +# Rules + + +* [Configuring Rules](#configuring-rules) +* [Disabling Rules](#disabling-rules) + +## Configuring Rules + +ESLint comes with a large number of built-in rules and you can add more rules through plugins. You can modify which rules your project uses either using configuration comments or configuration files. To change a rule setting, you must set the rule ID equal to one of these values: + +* `"off"` or `0` - turn the rule off +* `"warn"` or `1` - turn the rule on as a warning (doesn't affect exit code) +* `"error"` or `2` - turn the rule on as an error (exit code is 1 when triggered) + +### Using configuration comments + +To configure rules inside of a file using configuration comments, use a line or block comment in the following format: + +```js +/* eslint eqeqeq: "off", curly: "error" */ +``` + +```js +// eslint eqeqeq: "off", curly: "error" +``` + +In this example, [`eqeqeq`](https://eslint.org/docs/rules/eqeqeq) is turned off and [`curly`](.https://eslint.org/docs/rules/curly) is turned on as an error. You can also use the numeric equivalent for the rule severity: + +```js +/* eslint eqeqeq: 0, curly: 2 */ +``` + +This example is the same as the last example, only it uses the numeric codes instead of the string values. The `eqeqeq` rule is off and the `curly` rule is set to be an error. + +If a rule has additional options, you can specify them using array literal syntax, such as: + +```js +/* eslint quotes: ["error", "double"], curly: 2 */ +``` + +This comment specifies the "double" option for the [`quotes`](https://eslint.org/docs/rules/quotes) rule. The first item in the array is always the rule severity (number or string). + +Configuration comments can include descriptions to explain why the comment is necessary. The description must occur after the configuration and is separated from the configuration by two or more consecutive `-` characters. For example: + +```js +/* eslint eqeqeq: "off", curly: "error" -- Here's a description about why this configuration is necessary. */ +``` + +```js +/* eslint eqeqeq: "off", curly: "error" + -------- + Here's a description about why this configuration is necessary. */ +``` + +```js +/* eslint eqeqeq: "off", curly: "error" + * -------- + * This will not work due to the line above starting with a '*' character. + */ +``` + +### Using configuration files + +To configure rules inside of a configuration file, use the `rules` key along with an error level and any options you want to use. For example: + +```json +{ + "rules": { + "eqeqeq": "off", + "curly": "error", + "quotes": ["error", "double"] + } +} +``` + +And in YAML: + +```yaml +--- +rules: + eqeqeq: off + curly: error + quotes: + - error + - double +``` + +To configure a rule which is defined within a plugin you have to prefix the rule ID with the plugin name and a `/`. For example: + +```json +{ + "plugins": [ + "plugin1" + ], + "rules": { + "eqeqeq": "off", + "curly": "error", + "quotes": ["error", "double"], + "plugin1/rule1": "error" + } +} +``` + +And in YAML: + +```yaml +--- +plugins: + - plugin1 +rules: + eqeqeq: 0 + curly: error + quotes: + - error + - "double" + plugin1/rule1: error +``` + +In these configuration files, the rule `plugin1/rule1` comes from the plugin named `plugin1`. You can also use this format with configuration comments, such as: + +```js +/* eslint "plugin1/rule1": "error" */ +``` + +**Note:** When specifying rules from plugins, make sure to omit `eslint-plugin-`. ESLint uses only the unprefixed name internally to locate rules. + +## Disabling Rules + +### Using configuration comments + +To temporarily disable rule warnings in your file, use line or block comments in the following format: + +```js +/* eslint-disable */ + +alert('foo'); + +/* eslint-enable */ +``` + +```js +// eslint-disable + +alert('foo'); + +// eslint-enable +``` + +You can also disable or enable warnings for specific rules: + +```js +/* eslint-disable no-alert, no-console */ + +alert('foo'); +console.log('bar'); + +/* eslint-enable no-alert, no-console */ +``` + +To disable rule warnings in an entire file, put a `/* eslint-disable */` or `// eslint-disable` at the top of the file: + +```js +/* eslint-disable */ + +alert('foo'); +``` + +You can also disable or enable specific rules for an entire file: + +```js +/* eslint-disable no-alert */ + +alert('foo'); +``` + +To disable all rules on a specific line, use a line or block comment in one of the following formats: + +```js +alert('foo'); // eslint-disable-line + +// eslint-disable-next-line +alert('foo'); + +/* eslint-disable-next-line */ +alert('foo'); + +alert('foo'); /* eslint-disable-line */ +``` + +To disable a specific rule on a specific line: + +```js +alert('foo'); // eslint-disable-line no-alert + +// eslint-disable-next-line no-alert +alert('foo'); + +alert('foo'); /* eslint-disable-line no-alert */ + +/* eslint-disable-next-line no-alert */ +alert('foo'); +``` + +To disable multiple rules on a specific line: + +```js +alert('foo'); // eslint-disable-line no-alert, quotes, semi + +// eslint-disable-next-line no-alert, quotes, semi +alert('foo'); + +alert('foo'); /* eslint-disable-line no-alert, quotes, semi */ + +/* eslint-disable-next-line no-alert, quotes, semi */ +alert('foo'); +``` + +All of the above methods also work for plugin rules. For example, to disable `eslint-plugin-example`'s `rule-name` rule, combine the plugin's name (`example`) and the rule's name (`rule-name`) into `example/rule-name`: + +```js +foo(); // eslint-disable-line example/rule-name +foo(); /* eslint-disable-line example/rule-name */ +``` + +Configuration comments can include descriptions to explain why the comment is necessary. The description must come after the configuration and needs to be separated from the configuration by two or more consecutive `-` characters. For example: + +```js +// eslint-disable-next-line no-console -- Here's a description about why this configuration is necessary. +console.log('hello'); +``` + +**Note:** Comments that disable warnings for a portion of a file tell ESLint not to report rule violations for the disabled code. ESLint still parses the entire file, however, so disabled code still needs to be syntactically valid JavaScript. + +### Using configuration files + +To disable rules inside of a configuration file for a group of files, use the `overrides` key along with a `files` key. For example: + +```json +{ + "rules": {...}, + "overrides": [ + { + "files": ["*-test.js","*.spec.js"], + "rules": { + "no-unused-expressions": "off" + } + } + ] +} +``` + +### Disabling Inline Comments + +To disable all inline config comments, use the `noInlineConfig` setting. For example: + +```json +{ + "rules": {...}, + "noInlineConfig": true +} +``` + +This setting is similar to [--no-inline-config](https://eslint.org/docs/user-guide/command-line-interface#--no-inline-config) CLI option. + +#### Report unused `eslint-disable` comments + +To report unused `eslint-disable` comments, use the `reportUnusedDisableDirectives` setting. For example: + +```json +{ + "rules": {...}, + "reportUnusedDisableDirectives": true +} +``` + +This setting is similar to [--report-unused-disable-directives](https://eslint.org/docs/user-guide/command-line-interface#--report-unused-disable-directives) CLI option, but doesn't fail linting (reports as `"warn"` severity). diff --git a/docs/8.0.0/user-guide/formatters/html-formatter-example.html b/docs/8.0.0/user-guide/formatters/html-formatter-example.html new file mode 100644 index 0000000000..bc5d68c5a5 --- /dev/null +++ b/docs/8.0.0/user-guide/formatters/html-formatter-example.html @@ -0,0 +1,201 @@ + + + + + ESLint Report + + + +
    +

    ESLint Report

    +
    + 9 problems (5 errors, 4 warnings) - Generated on Sat Aug 14 2021 19:58:45 GMT-0400 (Eastern Daylight Time) +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + [+] /var/lib/jenkins/workspace/Releases/eslint Release/eslint/fullOfProblems.js + 9 problems (5 errors, 4 warnings) +
    + + + diff --git a/docs/8.0.0/user-guide/formatters/index.md b/docs/8.0.0/user-guide/formatters/index.md new file mode 100644 index 0000000000..28109146fc --- /dev/null +++ b/docs/8.0.0/user-guide/formatters/index.md @@ -0,0 +1,227 @@ +--- +title: Documentation +layout: doc +--- +# ESLint Formatters + +ESLint comes with several built-in formatters to control the appearance of the linting results, and supports third-party formatters as well. + +You can specify a formatter using the `--format` or `-f` flag on the command line. For example, `--format json` uses the `json` formatter. + +The built-in formatter options are: + +* [checkstyle](#checkstyle) +* [compact](#compact) +* [html](#html) +* [jslint-xml](#jslint-xml) +* [json-with-metadata](#json-with-metadata) +* [json](#json) +* [junit](#junit) +* [stylish](#stylish) +* [tap](#tap) +* [unix](#unix) +* [visualstudio](#visualstudio) + +## Example Source + +Examples of each formatter were created from linting `fullOfProblems.js` using the `.eslintrc` configuration shown below. + +### `fullOfProblems.js` + +```js +function addOne(i) { + if (i != NaN) { + return i ++ + } else { + return + } +}; +``` + +### `.eslintrc`: + +```json +{ + "extends": "eslint:recommended", + "rules": { + "consistent-return": 2, + "indent" : [1, 4], + "no-else-return" : 1, + "semi" : [1, "always"], + "space-unary-ops" : 2 + } +} +``` + +## Output Examples + +### checkstyle +``` + +``` + +### compact +``` +/var/lib/jenkins/workspace/Releases/eslint Release/eslint/fullOfProblems.js: line 1, col 10, Error - 'addOne' is defined but never used. (no-unused-vars) +/var/lib/jenkins/workspace/Releases/eslint Release/eslint/fullOfProblems.js: line 2, col 9, Error - Use the isNaN function to compare with NaN. (use-isnan) +/var/lib/jenkins/workspace/Releases/eslint Release/eslint/fullOfProblems.js: line 3, col 16, Error - Unexpected space before unary operator '++'. (space-unary-ops) +/var/lib/jenkins/workspace/Releases/eslint Release/eslint/fullOfProblems.js: line 3, col 20, Warning - Missing semicolon. (semi) +/var/lib/jenkins/workspace/Releases/eslint Release/eslint/fullOfProblems.js: line 4, col 12, Warning - Unnecessary 'else' after 'return'. (no-else-return) +/var/lib/jenkins/workspace/Releases/eslint Release/eslint/fullOfProblems.js: line 5, col 1, Warning - Expected indentation of 8 spaces but found 6. (indent) +/var/lib/jenkins/workspace/Releases/eslint Release/eslint/fullOfProblems.js: line 5, col 7, Error - Function 'addOne' expected a return value. (consistent-return) +/var/lib/jenkins/workspace/Releases/eslint Release/eslint/fullOfProblems.js: line 5, col 13, Warning - Missing semicolon. (semi) +/var/lib/jenkins/workspace/Releases/eslint Release/eslint/fullOfProblems.js: line 7, col 2, Error - Unnecessary semicolon. (no-extra-semi) + +9 problems +``` + +### html + + +### jslint-xml +``` + +``` + +### json-with-metadata +``` +{"results":[{"filePath":"/var/lib/jenkins/workspace/Releases/eslint Release/eslint/fullOfProblems.js","messages":[{"ruleId":"no-unused-vars","severity":2,"message":"'addOne' is defined but never used.","line":1,"column":10,"nodeType":"Identifier","messageId":"unusedVar","endLine":1,"endColumn":16},{"ruleId":"use-isnan","severity":2,"message":"Use the isNaN function to compare with NaN.","line":2,"column":9,"nodeType":"BinaryExpression","messageId":"comparisonWithNaN","endLine":2,"endColumn":17},{"ruleId":"space-unary-ops","severity":2,"message":"Unexpected space before unary operator '++'.","line":3,"column":16,"nodeType":"UpdateExpression","messageId":"unexpectedBefore","endLine":3,"endColumn":20,"fix":{"range":[57,58],"text":""}},{"ruleId":"semi","severity":1,"message":"Missing semicolon.","line":3,"column":20,"nodeType":"ReturnStatement","messageId":"missingSemi","endLine":4,"endColumn":1,"fix":{"range":[60,60],"text":";"}},{"ruleId":"no-else-return","severity":1,"message":"Unnecessary 'else' after 'return'.","line":4,"column":12,"nodeType":"BlockStatement","messageId":"unexpected","endLine":6,"endColumn":6,"fix":{"range":[0,94],"text":"function addOne(i) {\n if (i != NaN) {\n return i ++\n } \n return\n \n}"}},{"ruleId":"indent","severity":1,"message":"Expected indentation of 8 spaces but found 6.","line":5,"column":1,"nodeType":"Keyword","messageId":"wrongIndentation","endLine":5,"endColumn":7,"fix":{"range":[74,80],"text":" "}},{"ruleId":"consistent-return","severity":2,"message":"Function 'addOne' expected a return value.","line":5,"column":7,"nodeType":"ReturnStatement","messageId":"missingReturnValue","endLine":5,"endColumn":13},{"ruleId":"semi","severity":1,"message":"Missing semicolon.","line":5,"column":13,"nodeType":"ReturnStatement","messageId":"missingSemi","endLine":6,"endColumn":1,"fix":{"range":[86,86],"text":";"}},{"ruleId":"no-extra-semi","severity":2,"message":"Unnecessary semicolon.","line":7,"column":2,"nodeType":"EmptyStatement","messageId":"unexpected","endLine":7,"endColumn":3,"fix":{"range":[93,95],"text":"}"}}],"errorCount":5,"fatalErrorCount":0,"warningCount":4,"fixableErrorCount":2,"fixableWarningCount":4,"source":"function addOne(i) {\n if (i != NaN) {\n return i ++\n } else {\n return\n }\n};"}],"metadata":{"rulesMeta":{"no-else-return":{"type":"suggestion","docs":{"description":"disallow `else` blocks after `return` statements in `if` statements","category":"Best Practices","recommended":false,"url":"https://eslint.org/docs/rules/no-else-return"},"schema":[{"type":"object","properties":{"allowElseIf":{"type":"boolean","default":true}},"additionalProperties":false}],"fixable":"code","messages":{"unexpected":"Unnecessary 'else' after 'return'."}},"indent":{"type":"layout","docs":{"description":"enforce consistent indentation","category":"Stylistic Issues","recommended":false,"url":"https://eslint.org/docs/rules/indent"},"fixable":"whitespace","schema":[{"oneOf":[{"enum":["tab"]},{"type":"integer","minimum":0}]},{"type":"object","properties":{"SwitchCase":{"type":"integer","minimum":0,"default":0},"VariableDeclarator":{"oneOf":[{"oneOf":[{"type":"integer","minimum":0},{"enum":["first","off"]}]},{"type":"object","properties":{"var":{"oneOf":[{"type":"integer","minimum":0},{"enum":["first","off"]}]},"let":{"oneOf":[{"type":"integer","minimum":0},{"enum":["first","off"]}]},"const":{"oneOf":[{"type":"integer","minimum":0},{"enum":["first","off"]}]}},"additionalProperties":false}]},"outerIIFEBody":{"oneOf":[{"type":"integer","minimum":0},{"enum":["off"]}]},"MemberExpression":{"oneOf":[{"type":"integer","minimum":0},{"enum":["off"]}]},"FunctionDeclaration":{"type":"object","properties":{"parameters":{"oneOf":[{"type":"integer","minimum":0},{"enum":["first","off"]}]},"body":{"type":"integer","minimum":0}},"additionalProperties":false},"FunctionExpression":{"type":"object","properties":{"parameters":{"oneOf":[{"type":"integer","minimum":0},{"enum":["first","off"]}]},"body":{"type":"integer","minimum":0}},"additionalProperties":false},"CallExpression":{"type":"object","properties":{"arguments":{"oneOf":[{"type":"integer","minimum":0},{"enum":["first","off"]}]}},"additionalProperties":false},"ArrayExpression":{"oneOf":[{"type":"integer","minimum":0},{"enum":["first","off"]}]},"ObjectExpression":{"oneOf":[{"type":"integer","minimum":0},{"enum":["first","off"]}]},"ImportDeclaration":{"oneOf":[{"type":"integer","minimum":0},{"enum":["first","off"]}]},"flatTernaryExpressions":{"type":"boolean","default":false},"offsetTernaryExpressions":{"type":"boolean","default":false},"ignoredNodes":{"type":"array","items":{"type":"string","not":{"pattern":":exit$"}}},"ignoreComments":{"type":"boolean","default":false}},"additionalProperties":false}],"messages":{"wrongIndentation":"Expected indentation of {{expected}} but found {{actual}}."}},"space-unary-ops":{"type":"layout","docs":{"description":"enforce consistent spacing before or after unary operators","category":"Stylistic Issues","recommended":false,"url":"https://eslint.org/docs/rules/space-unary-ops"},"fixable":"whitespace","schema":[{"type":"object","properties":{"words":{"type":"boolean","default":true},"nonwords":{"type":"boolean","default":false},"overrides":{"type":"object","additionalProperties":{"type":"boolean"}}},"additionalProperties":false}],"messages":{"unexpectedBefore":"Unexpected space before unary operator '{{operator}}'.","unexpectedAfter":"Unexpected space after unary operator '{{operator}}'.","unexpectedAfterWord":"Unexpected space after unary word operator '{{word}}'.","wordOperator":"Unary word operator '{{word}}' must be followed by whitespace.","operator":"Unary operator '{{operator}}' must be followed by whitespace.","beforeUnaryExpressions":"Space is required before unary expressions '{{token}}'."}},"semi":{"type":"layout","docs":{"description":"require or disallow semicolons instead of ASI","category":"Stylistic Issues","recommended":false,"url":"https://eslint.org/docs/rules/semi"},"fixable":"code","schema":{"anyOf":[{"type":"array","items":[{"enum":["never"]},{"type":"object","properties":{"beforeStatementContinuationChars":{"enum":["always","any","never"]}},"additionalProperties":false}],"minItems":0,"maxItems":2},{"type":"array","items":[{"enum":["always"]},{"type":"object","properties":{"omitLastInOneLineBlock":{"type":"boolean"}},"additionalProperties":false}],"minItems":0,"maxItems":2}]},"messages":{"missingSemi":"Missing semicolon.","extraSemi":"Extra semicolon."}},"consistent-return":{"type":"suggestion","docs":{"description":"require `return` statements to either always or never specify values","category":"Best Practices","recommended":false,"url":"https://eslint.org/docs/rules/consistent-return"},"schema":[{"type":"object","properties":{"treatUndefinedAsUnspecified":{"type":"boolean","default":false}},"additionalProperties":false}],"messages":{"missingReturn":"Expected to return a value at the end of {{name}}.","missingReturnValue":"{{name}} expected a return value.","unexpectedReturnValue":"{{name}} expected no return value."}}}}} +``` + +### json +``` +[{"filePath":"/var/lib/jenkins/workspace/Releases/eslint Release/eslint/fullOfProblems.js","messages":[{"ruleId":"no-unused-vars","severity":2,"message":"'addOne' is defined but never used.","line":1,"column":10,"nodeType":"Identifier","messageId":"unusedVar","endLine":1,"endColumn":16},{"ruleId":"use-isnan","severity":2,"message":"Use the isNaN function to compare with NaN.","line":2,"column":9,"nodeType":"BinaryExpression","messageId":"comparisonWithNaN","endLine":2,"endColumn":17},{"ruleId":"space-unary-ops","severity":2,"message":"Unexpected space before unary operator '++'.","line":3,"column":16,"nodeType":"UpdateExpression","messageId":"unexpectedBefore","endLine":3,"endColumn":20,"fix":{"range":[57,58],"text":""}},{"ruleId":"semi","severity":1,"message":"Missing semicolon.","line":3,"column":20,"nodeType":"ReturnStatement","messageId":"missingSemi","endLine":4,"endColumn":1,"fix":{"range":[60,60],"text":";"}},{"ruleId":"no-else-return","severity":1,"message":"Unnecessary 'else' after 'return'.","line":4,"column":12,"nodeType":"BlockStatement","messageId":"unexpected","endLine":6,"endColumn":6,"fix":{"range":[0,94],"text":"function addOne(i) {\n if (i != NaN) {\n return i ++\n } \n return\n \n}"}},{"ruleId":"indent","severity":1,"message":"Expected indentation of 8 spaces but found 6.","line":5,"column":1,"nodeType":"Keyword","messageId":"wrongIndentation","endLine":5,"endColumn":7,"fix":{"range":[74,80],"text":" "}},{"ruleId":"consistent-return","severity":2,"message":"Function 'addOne' expected a return value.","line":5,"column":7,"nodeType":"ReturnStatement","messageId":"missingReturnValue","endLine":5,"endColumn":13},{"ruleId":"semi","severity":1,"message":"Missing semicolon.","line":5,"column":13,"nodeType":"ReturnStatement","messageId":"missingSemi","endLine":6,"endColumn":1,"fix":{"range":[86,86],"text":";"}},{"ruleId":"no-extra-semi","severity":2,"message":"Unnecessary semicolon.","line":7,"column":2,"nodeType":"EmptyStatement","messageId":"unexpected","endLine":7,"endColumn":3,"fix":{"range":[93,95],"text":"}"}}],"errorCount":5,"fatalErrorCount":0,"warningCount":4,"fixableErrorCount":2,"fixableWarningCount":4,"source":"function addOne(i) {\n if (i != NaN) {\n return i ++\n } else {\n return\n }\n};"}] +``` + +### junit +``` + + + + + + + + + + + + + + + +``` + +### stylish +``` + +/var/lib/jenkins/workspace/Releases/eslint Release/eslint/fullOfProblems.js + 1:10 error 'addOne' is defined but never used no-unused-vars + 2:9 error Use the isNaN function to compare with NaN use-isnan + 3:16 error Unexpected space before unary operator '++' space-unary-ops + 3:20 warning Missing semicolon semi + 4:12 warning Unnecessary 'else' after 'return' no-else-return + 5:1 warning Expected indentation of 8 spaces but found 6 indent + 5:7 error Function 'addOne' expected a return value consistent-return + 5:13 warning Missing semicolon semi + 7:2 error Unnecessary semicolon no-extra-semi + +✖ 9 problems (5 errors, 4 warnings) + 2 errors and 4 warnings potentially fixable with the `--fix` option. + +``` + +### tap +``` +TAP version 13 +1..1 +not ok 1 - /var/lib/jenkins/workspace/Releases/eslint Release/eslint/fullOfProblems.js + --- + message: '''addOne'' is defined but never used.' + severity: error + data: + line: 1 + column: 10 + ruleId: no-unused-vars + messages: + - message: Use the isNaN function to compare with NaN. + severity: error + data: + line: 2 + column: 9 + ruleId: use-isnan + - message: Unexpected space before unary operator '++'. + severity: error + data: + line: 3 + column: 16 + ruleId: space-unary-ops + - message: Missing semicolon. + severity: warning + data: + line: 3 + column: 20 + ruleId: semi + - message: Unnecessary 'else' after 'return'. + severity: warning + data: + line: 4 + column: 12 + ruleId: no-else-return + - message: Expected indentation of 8 spaces but found 6. + severity: warning + data: + line: 5 + column: 1 + ruleId: indent + - message: Function 'addOne' expected a return value. + severity: error + data: + line: 5 + column: 7 + ruleId: consistent-return + - message: Missing semicolon. + severity: warning + data: + line: 5 + column: 13 + ruleId: semi + - message: Unnecessary semicolon. + severity: error + data: + line: 7 + column: 2 + ruleId: no-extra-semi + ... + +``` + +### unix +``` +/var/lib/jenkins/workspace/Releases/eslint Release/eslint/fullOfProblems.js:1:10: 'addOne' is defined but never used. [Error/no-unused-vars] +/var/lib/jenkins/workspace/Releases/eslint Release/eslint/fullOfProblems.js:2:9: Use the isNaN function to compare with NaN. [Error/use-isnan] +/var/lib/jenkins/workspace/Releases/eslint Release/eslint/fullOfProblems.js:3:16: Unexpected space before unary operator '++'. [Error/space-unary-ops] +/var/lib/jenkins/workspace/Releases/eslint Release/eslint/fullOfProblems.js:3:20: Missing semicolon. [Warning/semi] +/var/lib/jenkins/workspace/Releases/eslint Release/eslint/fullOfProblems.js:4:12: Unnecessary 'else' after 'return'. [Warning/no-else-return] +/var/lib/jenkins/workspace/Releases/eslint Release/eslint/fullOfProblems.js:5:1: Expected indentation of 8 spaces but found 6. [Warning/indent] +/var/lib/jenkins/workspace/Releases/eslint Release/eslint/fullOfProblems.js:5:7: Function 'addOne' expected a return value. [Error/consistent-return] +/var/lib/jenkins/workspace/Releases/eslint Release/eslint/fullOfProblems.js:5:13: Missing semicolon. [Warning/semi] +/var/lib/jenkins/workspace/Releases/eslint Release/eslint/fullOfProblems.js:7:2: Unnecessary semicolon. [Error/no-extra-semi] + +9 problems +``` + +### visualstudio +``` +/var/lib/jenkins/workspace/Releases/eslint Release/eslint/fullOfProblems.js(1,10): error no-unused-vars : 'addOne' is defined but never used. +/var/lib/jenkins/workspace/Releases/eslint Release/eslint/fullOfProblems.js(2,9): error use-isnan : Use the isNaN function to compare with NaN. +/var/lib/jenkins/workspace/Releases/eslint Release/eslint/fullOfProblems.js(3,16): error space-unary-ops : Unexpected space before unary operator '++'. +/var/lib/jenkins/workspace/Releases/eslint Release/eslint/fullOfProblems.js(3,20): warning semi : Missing semicolon. +/var/lib/jenkins/workspace/Releases/eslint Release/eslint/fullOfProblems.js(4,12): warning no-else-return : Unnecessary 'else' after 'return'. +/var/lib/jenkins/workspace/Releases/eslint Release/eslint/fullOfProblems.js(5,1): warning indent : Expected indentation of 8 spaces but found 6. +/var/lib/jenkins/workspace/Releases/eslint Release/eslint/fullOfProblems.js(5,7): error consistent-return : Function 'addOne' expected a return value. +/var/lib/jenkins/workspace/Releases/eslint Release/eslint/fullOfProblems.js(5,13): warning semi : Missing semicolon. +/var/lib/jenkins/workspace/Releases/eslint Release/eslint/fullOfProblems.js(7,2): error no-extra-semi : Unnecessary semicolon. + +9 problems +``` diff --git a/docs/8.0.0/user-guide/getting-started.md b/docs/8.0.0/user-guide/getting-started.md new file mode 100644 index 0000000000..e753233066 --- /dev/null +++ b/docs/8.0.0/user-guide/getting-started.md @@ -0,0 +1,96 @@ +--- +title: Getting Started with ESLint +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/user-guide/getting-started.md + +--- + + +# Getting Started with ESLint + +ESLint is a tool for identifying and reporting on patterns found in ECMAScript/JavaScript code, with the goal of making code more consistent and avoiding bugs. In many ways, it is similar to JSLint and JSHint with a few exceptions: + +* ESLint uses [Espree](https://github.com/eslint/espree) for JavaScript parsing. +* ESLint uses an AST to evaluate patterns in code. +* ESLint is completely pluggable, every single rule is a plugin and you can add more at runtime. + +## Installation and Usage + +Prerequisites: [Node.js](https://nodejs.org/en/) (`^12.22.0`, `^14.17.0`, or `>=16.0.0`) built with SSL support. (If you are using an official Node.js distribution, SSL is always built in.) + +You can install ESLint using npm or yarn: + +``` +npm install eslint --save-dev + +# or + +yarn add eslint --dev +``` + +You should then set up a configuration file, and the easiest way to do that is to use the `--init` flag: + +``` +$ npx eslint --init + +# or + +$ yarn run eslint --init +``` + +**Note:** `--init` assumes you have a `package.json` file already. If you don't, make sure to run `npm init` or `yarn init` beforehand. + +After that, you can run ESLint on any file or directory like this: + +``` +$ npx eslint yourfile.js + +# or + +$ yarn run eslint yourfile.js +``` + +It is also possible to install ESLint globally rather than locally (using `npm install eslint --global`). However, this is not recommended, and any plugins or shareable configs that you use must be installed locally in either case. + +## Configuration + +**Note:** If you are coming from a version before 1.0.0 please see the [migration guide](migrating-to-1.0.0). + +After running `eslint --init`, you'll have a `.eslintrc.{js,yml,json}` file in your directory. In it, you'll see some rules configured like this: + +```json +{ + "rules": { + "semi": ["error", "always"], + "quotes": ["error", "double"] + } +} +``` + +The names `"semi"` and `"quotes"` are the names of [rules](/docs/rules) in ESLint. The first value is the error level of the rule and can be one of these values: + +* `"off"` or `0` - turn the rule off +* `"warn"` or `1` - turn the rule on as a warning (doesn't affect exit code) +* `"error"` or `2` - turn the rule on as an error (exit code will be 1) + +The three error levels allow you fine-grained control over how ESLint applies rules (for more configuration options and details, see the [configuration docs](configuring/)). + +Your `.eslintrc.{js,yml,json}` configuration file will also include the line: + +```json +{ + "extends": "eslint:recommended" +} +``` + +Because of this line, all of the rules marked "(recommended)" on the [rules page](/docs/rules) will be turned on. Alternatively, you can use configurations that others have created by searching for "eslint-config" on [npmjs.com](https://www.npmjs.com/search?q=eslint-config). ESLint will not lint your code unless you extend from a shared configuration or explicitly turn rules on in your configuration. + +--- + +## Next Steps + +* Learn about [advanced configuration](configuring/) of ESLint. +* Get familiar with the [command line options](command-line-interface). +* Explore [ESLint integrations](integrations) into other tools like editors, build systems, and more. +* Can't find just the right rule? Make your own [custom rule](/docs/developer-guide/working-with-rules). +* Make ESLint even better by [contributing](/docs/developer-guide/contributing/). diff --git a/docs/8.0.0/user-guide/index.md b/docs/8.0.0/user-guide/index.md new file mode 100644 index 0000000000..8f79609549 --- /dev/null +++ b/docs/8.0.0/user-guide/index.md @@ -0,0 +1,47 @@ +--- +title: User Guide +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/user-guide/README.md + +--- + + +# User Guide + +This guide is intended for those who wish to use ESLint as an end-user. If you're looking for how to extend ESLint or work with the ESLint source code, please see the [Developer Guide](../developer-guide). + +## [Getting Started](getting-started) + +Want to skip ahead and just start using ESLint? This section gives a high-level overview of installation, setup, and configuration options. + +## [Rules](../rules) + +ESLint has a lot of rules that you can configure to fine-tune it to your project. This section is an exhaustive list of every rule and link to each rule's documentation. + +## [Configuring](configuring/) + +Once you've got ESLint running, you'll probably want to adjust the configuration to better suit your project. This section explains all the different ways you can configure ESLint. + +## [Command Line Interface](command-line-interface) + +There are a lot of command line flags for ESLint and this section explains what they do. + +## [Integrations](integrations) + +Wondering if ESLint will work with your favorite editor or build system? This section has a list of all known integrations (submitted by their authors). + +## [Rule Deprecation](rule-deprecation) + +The ESLint team is committed to making upgrading as easy and painless as possible. This section outlines the guidelines the team has set in place for the deprecation of rules in future releases. + +## Migrating + +If you were using a prior version of ESLint, you can get help with the transition by reading: + +- [migrating-to-1.0.0](migrating-to-1.0.0) +- [migrating-to-2.0.0](migrating-to-2.0.0) +- [migrating-to-3.0.0](migrating-to-3.0.0) +- [migrating-to-4.0.0](migrating-to-4.0.0) +- [migrating-to-5.0.0](migrating-to-5.0.0) +- [migrating-to-6.0.0](migrating-to-6.0.0) +- [migrating-to-7.0.0](migrating-to-7.0.0) diff --git a/docs/8.0.0/user-guide/integrations.md b/docs/8.0.0/user-guide/integrations.md new file mode 100644 index 0000000000..7a957bc8ac --- /dev/null +++ b/docs/8.0.0/user-guide/integrations.md @@ -0,0 +1,72 @@ +--- +title: Integrations +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/user-guide/integrations.md + +--- + + +# Integrations + +## Editors + +* Sublime Text 3: + * [SublimeLinter-eslint](https://github.com/roadhump/SublimeLinter-eslint) + * [Build Next](https://github.com/albertosantini/sublimetext-buildnext) +* Vim: + * [ALE](https://github.com/w0rp/ale) + * [Syntastic](https://github.com/vim-syntastic/syntastic/tree/master/syntax_checkers/javascript) +* Emacs: [Flycheck](http://www.flycheck.org/) supports ESLint with the [javascript-eslint](http://www.flycheck.org/en/latest/languages.html#javascript) checker. +* Eclipse Orion: ESLint is the [default linter](https://dev.eclipse.org/mhonarc/lists/orion-dev/msg02718.html) +* Eclipse IDE: [Tern ESLint linter](https://github.com/angelozerr/tern.java/wiki/Tern-Linter-ESLint) +* TextMate 2: + * [eslint.tmbundle](https://github.com/ryanfitzer/eslint.tmbundle) + * [javascript-eslint.tmbundle](https://github.com/natesilva/javascript-eslint.tmbundle) +* Atom: [linter-eslint](https://atom.io/packages/linter-eslint) +* IntelliJ IDEA, RubyMine, WebStorm, PhpStorm, PyCharm, AppCode, Android Studio, 0xDBE: [ESLint Plugin](https://plugins.jetbrains.com/plugin/7494-eslint) +* Visual Studio Code: [ESLint Extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) +* Brackets: Included and [Brackets ESLint](https://github.com/brackets-userland/brackets-eslint) + +## Build tools + +* Grunt: [grunt-eslint](https://www.npmjs.com/package/grunt-eslint) +* Gulp: [gulp-eslint](https://www.npmjs.com/package/gulp-eslint) +* Mimosa: [mimosa-eslint](https://www.npmjs.com/package/mimosa-eslint) +* Broccoli: [broccoli-eslint](https://www.npmjs.com/package/broccoli-eslint) +* Browserify: [eslintify](https://www.npmjs.com/package/eslintify) +* Webpack: [eslint-webpack-plugin](https://www.npmjs.com/package/eslint-webpack-plugin) +* Rollup: [rollup-plugin-eslint](https://www.npmjs.com/package/rollup-plugin-eslint) +* Ember-cli: [ember-cli-eslint](https://www.npmjs.com/package/ember-cli-eslint) +* Sails.js: [sails-hook-lint](https://www.npmjs.com/package/sails-hook-lint), [sails-eslint](https://www.npmjs.com/package/sails-eslint) +* Start: [@start/plugin-lib-eslint](https://www.npmjs.com/package/@start/plugin-lib-eslint) +* Brunch: [eslint-brunch](https://www.npmjs.com/package/eslint-brunch) + +## Command Line Tools + +* [ESLint Watch](https://www.npmjs.com/package/eslint-watch) +* [Code Climate CLI](https://github.com/codeclimate/codeclimate) +* [ESLint Nibble](https://github.com/IanVS/eslint-nibble) + +## Source Control + +* [Git Precommit Hook](https://coderwall.com/p/zq8jlq/eslint-pre-commit-hook) +* [Git pre-commit hook that only lints staged changes](https://gist.github.com/dahjelle/8ddedf0aebd488208a9a7c829f19b9e8) +* [overcommit Git hook manager](https://github.com/brigade/overcommit) +* [Mega-Linter](https://nvuillam.github.io/mega-linter): Linters aggregator for CI, [embedding eslint](https://nvuillam.github.io/mega-linter/descriptors/javascript_eslint/) + +## Testing + +* Mocha.js: [mocha-eslint](https://www.npmjs.com/package/mocha-eslint) + +## External ESLint rules + +* [AngularJS](https://github.com/Gillespie59/eslint-plugin-angular) +* [BackboneJS](https://github.com/ilyavolodin/eslint-plugin-backbone) +* [Jasmine](https://github.com/tlvince/eslint-plugin-jasmine) +* [React](https://github.com/yannickcr/eslint-plugin-react) + +… and many more published on npm with the [eslintplugin](https://www.npmjs.com/browse/keyword/eslintplugin) keyword. + +## Other Integration Lists + +You can find a curated list of other popular integrations for ESLint in the [awesome-eslint](https://github.com/dustinspecker/awesome-eslint) GitHub repository. diff --git a/docs/8.0.0/user-guide/migrating-from-jscs.md b/docs/8.0.0/user-guide/migrating-from-jscs.md new file mode 100644 index 0000000000..c2b2fb7d4f --- /dev/null +++ b/docs/8.0.0/user-guide/migrating-from-jscs.md @@ -0,0 +1,179 @@ +--- +title: Migrating from JSCS +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/user-guide/migrating-from-jscs.md + +--- + + +# Migrating from JSCS + +In April 2016, we [announced](https://eslint.org/blog/2016/04/welcoming-jscs-to-eslint) that the JSCS project was shutting down and the JSCS team would be joining the ESLint team. This guide is intended to help those who are using JSCS to migrate their settings and projects to use ESLint. We've tried to automate as much of the conversion as possible, but there are some manual changes that are needed. + +## Terminology + +Before beginning the process of migrating to ESLint, it's helpful to understand some of the terminology that ESLint uses and how it relates to terminology that JSCS uses. + +* **Configuration File** - In JSCS, the configuration file is `.jscsrc`, `.jscsrc.json`, `.jscsrc.yaml`, or `.jscsrs.js`. In ESLint, the configuration file can be `.eslintrc.json`, `.eslintrc.yml`, `.eslintrc.yaml`, or `.eslintrc.js` (there is also a deprecated `.eslintrc` file format). +* **Presets** - In JSCS, there were numerous predefined configurations shipped directly within JSCS. ESLint ships with just one predefined configuration (`eslint:recommended`) that has no style rules enabled. However, ESLint does support [shareable configs](https://eslint.org/docs/developer-guide/shareable-configs). Shareable configs are configurations that are published on their own to npm and there are shareable configs available for almost all of the JSCS presets (see the "Converting Presets" section below). Additionally, the "preset" option in a configuration file is the equivalent of the ESLint "extends" option. + +## Convert Configuration Files Using Polyjuice + +[Polyjuice](https://github.com/brenolf/polyjuice) is a utility for converting JSCS (and JSHint) configuration files into ESLint configuration files automatically. It understands the equivalent rules from each utility and will automatically output an ESLint configuration file that is a good approximation of your existing JSCS file. + +To install Polyjuice: + +``` +$ npm install -g polyjuice +``` + +Polyjuice works with JSON configuration files, so if you're using a JavaScript or YAML JSCS configuration file, you should first convert it into a JSON configuration file. + +To convert your configuration file, pass in the location of your `.jscs.json` file using the `--jscs` flag: + +``` +$ polyjuice --jscs .jscsrc.json > .eslintrc.json +``` + +This creates a `.eslintrc.json` with the equivalent rules from `.jscsrc.json`. + +If you have multiple `.jscsrc.json` files, you can pass them all and Polyjuice will combine them into one `.eslintrc.json` file: + +``` +$ polyjuice --jscs .jscsrc.json ./foo/.jscsrc.json > .eslintrc.json +``` + +**Note:** Polyjuice does a good job of creating a reasonable ESLint configuration from your JSCS configuration, but it may not be 100%. You may still see different warnings than you saw with JSCS, and so you may need to further modify your configuration after using Polyjuice. This is especially true if you're using inline comments to enable/disable certain rules in JSCS (you'll need to manually convert those to use ESLint-style comments instead, see "Disabling Rules Inline" later in this page). + +### Creating a New Configuration From Scratch + +If you don't want to convert your JSCS configuration directly into an ESLint configuration, then you can use ESLint's built-in wizard to get you started. Just run: + +``` +$ eslint --init +``` + +You'll be guided through a series of questions that will help you setup a basic configuration file to get you started. + +## Converting Presets + +There are shareable configs available for most JSCS presets. The equivalent shareable configs for each JSCS preset are listed in the following table: + +| **JSCS Preset** | **ESLint Shareable Config** | +|-----------------|-----------------------------| +| `airbnb` | [`eslint-config-airbnb-base`](https://github.com/airbnb/javascript/tree/master/packages/eslint-config-airbnb-base) | +| `crockford` | (not available) | +| `google` | [`eslint-config-google`](https://github.com/google/eslint-config-google) | +| `grunt` | [`eslint-config-grunt`](https://github.com/markelog/eslint-config-grunt) | +| `idiomatic` | [`eslint-config-idiomatic`](https://github.com/jamespamplin/eslint-config-idiomatic) | +| `jquery` | [`eslint-config-jquery`](https://github.com/jquery/eslint-config-jquery) | +| `mdcs` | [`eslint-config-mdcs`](https://github.com/zz85/mrdoobapproves) | +| `node-style-guide` | [`eslint-config-node-style-guide`](https://github.com/pdehaan/eslint-config-node-style-guide) | +| `wikimedia` | [`eslint-config-wikimedia`](https://github.com/wikimedia/eslint-config-wikimedia) | +| `wordpress` | [`eslint-config-wordpress`](https://github.com/WordPress-Coding-Standards/eslint-config-wordpress) | + +As an example, suppose that you are using the `airbnb` preset, so your `.jscsrc` file looks like this: + +```json +{ + "preset": "airbnb" +} +``` + +In order to get the same functionality in ESLint, you would first need to install the `eslint-config-airbnb` shareable config package: + +``` +$ npm install eslint-config-airbnb-base --save-dev +``` + +And then you would modify your configuration file like this: + +```json +{ + "extends": "airbnb-base" +} +``` + +ESLint sees `"airbnb-base"` and will look for `eslint-config-airbnb-base` (to save you some typing). + +## Disabling Rules Inline + +Both JSCS and ESLint use comments inside of files to disable rules around certain parts of your code. The following table lists out the JSCS inline configuration comments and their ESLint equivalents. + +| **Description** | **JSCS Comment** | **ESLint Comment** | +|-----------------|------------------|--------------------| +| Disable all rules | `// jscs:disable` or `/* jscs:disable */` | `/* eslint-disable */` | +| Enable all rules | `// jscs:enable` or `/* jscs:enable */` | `/* eslint-enable */` | +| Disable one rule | `// jscs:disable ruleName` or `/* jscs:disable ruleName */` | `/* eslint-disable rule-name */` | +| Enable one rule | `// jscs:enable ruleName` or `/* jscs:enable ruleName */` | `/* eslint-enable rule-name */` | +| Disable multiple rules | `// jscs:disable ruleName1, ruleName2` or `/* jscs:disable ruleName1, ruleName2 */` | `/* eslint-disable rule-name1, rule-name2 */` | +| Enable multiple rules | `// jscs:enable ruleName1, ruleName2` or `/* jscs:enable ruleName1, ruleName2 */` | `/* eslint-enable rule-name1, rule-name2 */` | +| Disable one rule on single line | `// jscs:ignore ruleName` | `// eslint-disable-line rule-name` | + +## Command Line Options + +Both JSCS and ESLint have command line arguments corresponding to many of their configuration options. The following are the ESLint equivalents of JSCS command line options. + +### `--fix` + +JSCS uses the `--fix` option to apply automatic fixes to code: + +``` +$ jscs --fix file.js +``` + +ESLint has the same option: + +``` +$ eslint --fix file.js +``` + +### `--auto-configure` + +The JSCS `--auto-configure` option created a configuration based on what it found in a given file: + +``` +$ jscs --auto-configure file.js +``` + +In ESLint, there's a similar option when you use `--init`. Just select "Inspect your JavaScript file(s)": + +``` +$ eslint --init +? How would you like to configure ESLint? (Use arrow keys) +> Answer questions about your style + Use a popular style guide + Inspect your JavaScript file(s) +``` + +## `--config`, `-c` + +JSCS allows you to specify a configuration file to use on the command line using either `--config` or `-c`, such as: + +``` +$ jscs --config myconfig.json file.js +$ jscs -c myconfig.json file.js +``` + +Both flags are also supported by ESLint: + +``` +$ eslint --config myconfig.json file.js +$ eslint -c myconfig.json file.js +``` + + + +## Piping Code Into ESLint + +In JSCS, you can pipe code in like this: + +``` +$ cat file.js | jscs +``` + +In ESLint, you can also pipe in code, but you need to use the `--stdin` flag: + +``` +$ cat file.js | eslint --stdin +``` diff --git a/docs/8.0.0/user-guide/migrating-to-1.0.0.md b/docs/8.0.0/user-guide/migrating-to-1.0.0.md new file mode 100644 index 0000000000..cad52fc388 --- /dev/null +++ b/docs/8.0.0/user-guide/migrating-to-1.0.0.md @@ -0,0 +1,217 @@ +--- +title: Migrating to v1.0.0 +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/user-guide/migrating-to-1.0.0.md + +--- + + +# Migrating to v1.0.0 + +ESLint v1.0.0 is the first major version release. As a result, there are some significant changes between how ESLint worked during its life in 0.x and how it will work going forward. These changes are the direct result of feedback from the ESLint community of users and were not made without due consideration for the upgrade path. We believe that these changes make ESLint even better, and while some work is necessary to upgrade, we hope the pain of this upgrade is small enough that you will see the benefit of upgrading. + +## All Rules Off by Default + +The most important difference in v1.0.0 is that all rules are off by default. We made this change after numerous requests to allow turning off the default rules from within configuration files. While that wasn't technically feasible, it was feasible to have all rules off by default and then re-enable rules in configuration files using `extends`. As such, we've made the `--reset` behavior the default and removed this command line option. + +When using `--init`, your configuration file will automatically include the following line: + +```json +{ + "extends": "eslint:recommended" +} +``` + +This setting mimics some of the default behavior from 0.x, but not all. If you don't want to use any of the recommended rules, you can delete this line. + +**To address:** If you are currently using `--reset`, then you should stop passing `--reset` on the command line; no other changes are necessary. If you are not using `--reset`, then you should review your configuration to determine which rules should be on by default. You can partially restore some of the default behavior by adding the following to your configuration file: + +The `"eslint:recommended"` configuration contains many of the same default rule settings from 0.x, but not all. These rules are no longer on by default, so you should review your settings to ensure they are still as you expect: + +* [no-alert](https://eslint.org/docs/rules/no-alert) +* [no-array-constructor](https://eslint.org/docs/rules/no-array-constructor) +* [no-caller](https://eslint.org/docs/rules/no-caller) +* [no-catch-shadow](https://eslint.org/docs/rules/no-catch-shadow) +* [no-empty-label](https://eslint.org/docs/rules/no-empty-label) +* [no-eval](https://eslint.org/docs/rules/no-eval) +* [no-extend-native](https://eslint.org/docs/rules/no-extend-native) +* [no-extra-bind](https://eslint.org/docs/rules/no-extra-bind) +* [no-extra-strict](https://eslint.org/docs/rules/no-extra-strict) +* [no-implied-eval](https://eslint.org/docs/rules/no-implied-eval) +* [no-iterator](https://eslint.org/docs/rules/no-iterator) +* [no-label-var](https://eslint.org/docs/rules/no-label-var) +* [no-labels](https://eslint.org/docs/rules/no-labels) +* [no-lone-blocks](https://eslint.org/docs/rules/no-lone-blocks) +* [no-loop-func](https://eslint.org/docs/rules/no-loop-func) +* [no-multi-spaces](https://eslint.org/docs/rules/no-multi-spaces) +* [no-multi-str](https://eslint.org/docs/rules/no-multi-str) +* [no-native-reassign](https://eslint.org/docs/rules/no-native-reassign) +* [no-new](https://eslint.org/docs/rules/no-new) +* [no-new-func](https://eslint.org/docs/rules/no-new-func) +* [no-new-object](https://eslint.org/docs/rules/no-new-object) +* [no-new-wrappers](https://eslint.org/docs/rules/no-new-wrappers) +* [no-octal-escape](https://eslint.org/docs/rules/no-octal-escape) +* [no-process-exit](https://eslint.org/docs/rules/no-process-exit) +* [no-proto](https://eslint.org/docs/rules/no-proto) +* [no-return-assign](https://eslint.org/docs/rules/no-return-assign) +* [no-script-url](https://eslint.org/docs/rules/no-script-url) +* [no-sequences](https://eslint.org/docs/rules/no-sequences) +* [no-shadow](https://eslint.org/docs/rules/no-shadow) +* [no-shadow-restricted-names](https://eslint.org/docs/rules/no-shadow-restricted-names) +* [no-spaced-func](https://eslint.org/docs/rules/no-spaced-func) +* [no-trailing-spaces](https://eslint.org/docs/rules/no-trailing-spaces) +* [no-undef-init](https://eslint.org/docs/rules/no-undef-init) +* [no-underscore-dangle](https://eslint.org/docs/rules/no-underscore-dangle) +* [no-unused-expressions](https://eslint.org/docs/rules/no-unused-expressions) +* [no-use-before-define](https://eslint.org/docs/rules/no-use-before-define) +* [no-with](https://eslint.org/docs/rules/no-with) +* [no-wrap-func](https://eslint.org/docs/rules/no-wrap-func) +* [camelcase](https://eslint.org/docs/rules/camelcase) +* [comma-spacing](https://eslint.org/docs/rules/comma-spacing) +* [consistent-return](https://eslint.org/docs/rules/consistent-return) +* [curly](https://eslint.org/docs/rules/curly) +* [dot-notation](https://eslint.org/docs/rules/dot-notation) +* [eol-last](https://eslint.org/docs/rules/eol-last) +* [eqeqeq](https://eslint.org/docs/rules/eqeqeq) +* [key-spacing](https://eslint.org/docs/rules/key-spacing) +* [new-cap](https://eslint.org/docs/rules/new-cap) +* [new-parens](https://eslint.org/docs/rules/new-parens) +* [quotes](https://eslint.org/docs/rules/quotes) +* [semi](https://eslint.org/docs/rules/semi) +* [semi-spacing](https://eslint.org/docs/rules/semi-spacing) +* [space-infix-ops](https://eslint.org/docs/rules/space-infix-ops) +* [space-return-throw-case](https://eslint.org/docs/rules/space-return-throw-case) +* [space-unary-ops](https://eslint.org/docs/rules/space-unary-ops) +* [strict](https://eslint.org/docs/rules/strict) +* [yoda](https://eslint.org/docs/rules/yoda) + +See also: the [full diff](https://github.com/eslint/eslint/commit/e3e9dbd9876daf4bdeb4e15f8a76a9d5e6e03e39#diff-b01a5cfd9361ca9280a460fd6bb8edbbL1) where the defaults were changed. + +Here's a configuration file with the closest equivalent of the old defaults: + +```json +{ + "extends": "eslint:recommended", + "rules": { + "no-alert": 2, + "no-array-constructor": 2, + "no-caller": 2, + "no-catch-shadow": 2, + "no-empty-label": 2, + "no-eval": 2, + "no-extend-native": 2, + "no-extra-bind": 2, + "no-implied-eval": 2, + "no-iterator": 2, + "no-label-var": 2, + "no-labels": 2, + "no-lone-blocks": 2, + "no-loop-func": 2, + "no-multi-spaces": 2, + "no-multi-str": 2, + "no-native-reassign": 2, + "no-new": 2, + "no-new-func": 2, + "no-new-object": 2, + "no-new-wrappers": 2, + "no-octal-escape": 2, + "no-process-exit": 2, + "no-proto": 2, + "no-return-assign": 2, + "no-script-url": 2, + "no-sequences": 2, + "no-shadow": 2, + "no-shadow-restricted-names": 2, + "no-spaced-func": 2, + "no-trailing-spaces": 2, + "no-undef-init": 2, + "no-underscore-dangle": 2, + "no-unused-expressions": 2, + "no-use-before-define": 2, + "no-with": 2, + "camelcase": 2, + "comma-spacing": 2, + "consistent-return": 2, + "curly": [2, "all"], + "dot-notation": [2, { "allowKeywords": true }], + "eol-last": 2, + "no-extra-parens": [2, "functions"], + "eqeqeq": 2, + "key-spacing": [2, { "beforeColon": false, "afterColon": true }], + "new-cap": 2, + "new-parens": 2, + "quotes": [2, "double"], + "semi": 2, + "semi-spacing": [2, {"before": false, "after": true}], + "space-infix-ops": 2, + "space-return-throw-case": 2, + "space-unary-ops": [2, { "words": true, "nonwords": false }], + "strict": [2, "function"], + "yoda": [2, "never"] + } +} +``` + +## Removed Rules + +Over the past several releases, we have been deprecating rules and introducing new rules to take their place. The following is a list of the removed rules and their replacements: + +* [generator-star](https://eslint.org/docs/rules/generator-star) is replaced by [generator-star-spacing](https://eslint.org/docs/rules/generator-star-spacing) +* [global-strict](https://eslint.org/docs/rules/global-strict) is replaced by [strict](https://eslint.org/docs/rules/strict) +* [no-comma-dangle](https://eslint.org/docs/rules/no-comma-dangle) is replaced by [comma-dangle](https://eslint.org/docs/rules/comma-dangle) +* [no-empty-class](https://eslint.org/docs/rules/no-empty-class) is replaced by [no-empty-character-class](https://eslint.org/docs/rules/no-empty-character-class) +* [no-extra-strict](https://eslint.org/docs/rules/no-extra-strict) is replaced by [strict](https://eslint.org/docs/rules/strict) +* [no-reserved-keys](https://eslint.org/docs/rules/no-reserved-keys) is replaced by [quote-props](https://eslint.org/docs/rules/quote-props) +* [no-space-before-semi](https://eslint.org/docs/rules/no-space-before-semi) is replaced by [semi-spacing](https://eslint.org/docs/rules/semi-spacing) +* [no-wrap-func](https://eslint.org/docs/rules/no-wrap-func) is replaced by [no-extra-parens](https://eslint.org/docs/rules/no-extra-parens) +* [space-after-function-name](https://eslint.org/docs/rules/space-after-function-name) is replaced by [space-before-function-paren](https://eslint.org/docs/rules/space-before-function-paren) +* [space-before-function-parentheses](https://eslint.org/docs/rules/space-before-function-parentheses) is replaced by [space-before-function-paren](https://eslint.org/docs/rules/space-before-function-paren) +* [space-in-brackets](https://eslint.org/docs/rules/space-in-brackets) is replaced by[object-curly-spacing](https://eslint.org/docs/rules/object-curly-spacing) and [array-bracket-spacing](https://eslint.org/docs/rules/array-bracket-spacing) +* [space-unary-word-ops](https://eslint.org/docs/rules/space-unary-word-ops) is replaced by [space-unary-ops](https://eslint.org/docs/rules/space-unary-ops) +* [spaced-line-comment](https://eslint.org/docs/rules/spaced-line-comment) is replaced by [spaced-comment](https://eslint.org/docs/rules/spaced-comment) + +**To address:** You'll need to update your rule configurations to use the new rules. ESLint v1.0.0 will also warn you when you're using a rule that has been removed and will suggest the replacement rules. Hopefully, this will result in few surprises during the upgrade process. + +## Column Numbers are 1-based + +From the beginning, ESLint has reported errors using 0-based columns because that's what Esprima, and later Espree, reported. However, most tools and editors use 1-based columns, which made for some tricky integrations with ESLint. In v1.0.0, we've switched over to reporting errors using 1-based columns to fall into line with the tools developers use everyday. + +**To address:** If you've created an editor integration, or a tool that had to correct the column number, you'll need to update to just pass through the column number from ESLint. Otherwise, no change is necessary. + +## No Longer Exporting cli + +In 0.x, the `cli` object was exported for use by external tools. It was later deprecated in favor of `CLIEngine`. In v1.0.0, we are no longer exporting `cli` as it should not be used by external tools. This will break existing tools that make use of it. + +**To address:** If you are using the exported `cli` object, switch to using `CLIEngine` instead. + +## Deprecating eslint-tester + +The `eslint-tester` module, which has long been the primary tester for ESLint rules, has now been moved into the `eslint` module. This was the result of a difficult relationship between these two modules that created circular dependencies and was causing a lot of problems in rule tests. Moving the tester into the `eslint` module fixed a lot of those issues. + +The replacement for `eslint-tester` is called `RuleTester`. It's a simplified version of `ESLintTester` that's designed to work with any testing framework. This object is exposed by the package. + +**To address:** Convert all of your rule tests to use `RuleTester`. If you have this as a test using `ESLintTester`: + +```js +var eslint = require("../../../lib/eslint"), + ESLintTester = require("eslint-tester"); + +var eslintTester = new ESLintTester(eslint); +eslintTester.addRuleTest("lib/rules/your-rule", { + valid: [], + invalid: [] +}); +``` + +Then you can change to: + +```js +var rule = require("../../../lib/rules/your-rule"), + RuleTester = require("eslint").RuleTester; + +var ruleTester = new RuleTester(); +ruleTester.run("your-rule", rule, { + valid: [], + invalid: [] +}); +``` diff --git a/docs/8.0.0/user-guide/migrating-to-2.0.0.md b/docs/8.0.0/user-guide/migrating-to-2.0.0.md new file mode 100644 index 0000000000..8665a5d3f5 --- /dev/null +++ b/docs/8.0.0/user-guide/migrating-to-2.0.0.md @@ -0,0 +1,364 @@ +--- +title: Migrating to v2.0.0 +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/user-guide/migrating-to-2.0.0.md + +--- + + +# Migrating to v2.0.0 + +ESLint v2.0.0 is the second major version release. As a result, there are some significant changes between how ESLint worked during its life in 0.x and 1.x and how it will work going forward. These changes are the direct result of feedback from the ESLint community of users and were not made without due consideration for the upgrade path. We believe that these changes make ESLint even better, and while some work is necessary to upgrade, we hope the pain of this upgrade is small enough that you will see the benefit of upgrading. + +**Important:** If you are upgrading from 0.x, please refer to [Migrating to 1.0.0](./migrating-to-1.0.0) as your starting point. + +## Rule Schema Changes + +Due to a quirk in the way rule schemas worked, it was possible that you'd need to account for the rule severity (0, 1, or 2) in a rule schema if the options were sufficiently complex. That would result in a schema such as: + +```js +module.exports = { + "type": "array", + "items": [ + { + "enum": [0, 1, 2] + }, + { + "enum": ["always", "never"] + } + ], + "minItems": 1, + "maxItems": 2 +}; +``` + +This was confusing to rule developers as it seemed that rules shouldn't be in charge of validating their own severity. In 2.0.0, rules no longer need to check their own severity. + +**To address:** If you are exporting a rule schema that checks severity, you need to make several changes: + +1. Remove the severity from the schema +1. Adjust `minItems` from 1 to 0 +1. Adjust `maxItems` by subtracting 1 + +Here's what the schema from above looks like when properly converted: + +```js +module.exports = { + "type": "array", + "items": [ + { + "enum": ["always", "never"] + } + ], + "minItems": 0, + "maxItems": 1 +}; +``` + +## Removed Rules + +The following rules have been deprecated with new rules created to take their place. The following is a list of the removed rules and their replacements: + +* [no-arrow-condition](https://eslint.org/docs/rules/no-arrow-condition) is replaced by a combination of [no-confusing-arrow](https://eslint.org/docs/rules/no-confusing-arrow) and [no-constant-condition](https://eslint.org/docs/rules/no-constant-condition). Turn on both of these rules to get the same functionality as `no-arrow-condition`. +* [no-empty-label](https://eslint.org/docs/rules/no-empty-label) is replaced by [no-labels](https://eslint.org/docs/rules/no-labels) with `{"allowLoop": true, "allowSwitch": true}` option. +* [space-after-keywords](https://eslint.org/docs/rules/space-after-keywords) is replaced by [keyword-spacing](https://eslint.org/docs/rules/keyword-spacing). +* [space-before-keywords](https://eslint.org/docs/rules/space-before-keywords) is replaced by [keyword-spacing](https://eslint.org/docs/rules/keyword-spacing). +* [space-return-throw-case](https://eslint.org/docs/rules/space-return-throw-case) is replaced by [keyword-spacing](https://eslint.org/docs/rules/keyword-spacing). + +**To address:** You'll need to update your rule configurations to use the new rules. ESLint v2.0.0 will also warn you when you're using a rule that has been removed and will suggest the replacement rules. Hopefully, this will result in few surprises during the upgrade process. + +## Configuration Cascading Changes + +Prior to 2.0.0, if a directory contained both an `.eslintrc` file and a `package.json` file with ESLint configuration information, the settings from the two files would be merged together. In 2.0.0, only the settings from the `.eslintrc.*` file are used and the ones in `package.json` are ignored when both are present. Otherwise, `package.json` can still be used with ESLint configuration, but only if no other `.eslintrc.*` files are present. + +**To address:** If you have both an `.eslintrc.*` and `package.json` with ESLint configuration information in the same directory, combine your configurations into just one of those files. + +## Built-In Global Variables + +Prior to 2.0.0, new global variables that were standardized as part of ES6 such as `Promise`, `Map`, `Set`, and `Symbol` were included in the built-in global environment. This could lead to potential issues when, for example, `no-undef` permitted use of the `Promise` constructor even in ES5 code where promises are unavailable. In 2.0.0, the built-in environment only includes the standard ES5 global variables, and the new ES6 global variables have been moved to the `es6` environment. + +**To address:** If you are writing ES6 code, enable the `es6` environment if you have not already done so: + +```js +// In your .eslintrc +{ + env: { + es6: true + } +} + +// Or in a configuration comment +/*eslint-env es6*/ +``` + +## Language Options + +Prior to 2.0.0, the way to enable language options was by using `ecmaFeatures` in your configuration. In 2.0.0: + +* The `ecmaFeatures` property is now under a top-level `parserOptions` property. +* All ECMAScript 6 `ecmaFeatures` flags have been removed in favor of a `ecmaVersion` property under `parserOptions` that can be set to 3, 5 (default), or 6. +* The `ecmaFeatures.modules` flag has been replaced by a `sourceType` property under `parserOptions` which can be set to `"script"` (default) or `"module"` for ES6 modules. + +**To address:** If you are using any ECMAScript 6 feature flags in `ecmaFeatures`, you'll need to use `ecmaVersion: 6` instead. The ECMAScript 6 feature flags are: + +* `arrowFunctions` - enable [arrow functions](https://leanpub.com/understandinges6/read#leanpub-auto-arrow-functions) +* `binaryLiterals` - enable [binary literals](https://leanpub.com/understandinges6/read#leanpub-auto-octal-and-binary-literals) +* `blockBindings` - enable `let` and `const` (aka [block bindings](https://leanpub.com/understandinges6/read#leanpub-auto-block-bindings)) +* `classes` - enable classes +* `defaultParams` - enable [default function parameters](https://leanpub.com/understandinges6/read/#leanpub-auto-default-parameters) +* `destructuring` - enable [destructuring](https://leanpub.com/understandinges6/read#leanpub-auto-destructuring-assignment) +* `forOf` - enable [`for-of` loops](https://leanpub.com/understandinges6/read#leanpub-auto-iterables-and-for-of) +* `generators` - enable [generators](https://leanpub.com/understandinges6/read#leanpub-auto-generators) +* `modules` - enable modules and global strict mode +* `objectLiteralComputedProperties` - enable [computed object literal property names](https://leanpub.com/understandinges6/read#leanpub-auto-computed-property-names) +* `objectLiteralDuplicateProperties` - enable [duplicate object literal properties](https://leanpub.com/understandinges6/read#leanpub-auto-duplicate-object-literal-properties) in strict mode +* `objectLiteralShorthandMethods` - enable [object literal shorthand methods](https://leanpub.com/understandinges6/read#leanpub-auto-method-initializer-shorthand) +* `objectLiteralShorthandProperties` - enable [object literal shorthand properties](https://leanpub.com/understandinges6/read#leanpub-auto-property-initializer-shorthand) +* `octalLiterals` - enable [octal literals](https://leanpub.com/understandinges6/read#leanpub-auto-octal-and-binary-literals) +* `regexUFlag` - enable the [regular expression `u` flag](https://leanpub.com/understandinges6/read#leanpub-auto-the-regular-expression-u-flag) +* `regexYFlag` - enable the [regular expression `y` flag](https://leanpub.com/understandinges6/read#leanpub-auto-the-regular-expression-y-flag) +* `restParams` - enable the [rest parameters](https://leanpub.com/understandinges6/read#leanpub-auto-rest-parameters) +* `spread` - enable the [spread operator](https://leanpub.com/understandinges6/read#leanpub-auto-the-spread-operator) for arrays +* `superInFunctions` - enable `super` references inside of functions +* `templateStrings` - enable [template strings](https://leanpub.com/understandinges6/read/#leanpub-auto-template-strings) +* `unicodeCodePointEscapes` - enable [code point escapes](https://leanpub.com/understandinges6/read/#leanpub-auto-escaping-non-bmp-characters) + +If you're using any of these flags, such as: + +```js +{ + ecmaFeatures: { + arrowFunctions: true + } +} +``` + +Then you should enable ES6 using `ecmaVersion`: + +```js +{ + parserOptions: { + ecmaVersion: 6 + } +} +``` + +If you're using any non-ES6 flags in `ecmaFeatures`, you need to move those inside of `parserOptions`. For instance: + +```js +{ + ecmaFeatures: { + jsx: true + } +} +``` + +Then you should move `ecmaFeatures` under `parserOptions`: + +```js +{ + parserOptions: { + ecmaFeatures: { + jsx: true + } + } +} +``` + +If you were using `ecmaFeatures.modules` to enable ES6 module support like this: + +```js +{ + ecmaFeatures: { + modules: true + } +} +``` + +```js +{ + parserOptions: { + sourceType: "module" + } +} +``` + +Additionally, if you are using `context.ecmaFeatures` inside of your rules, then you'll need to update your code in the following ways: + +1. If you're using an ES6 feature flag such as `context.ecmaFeatures.blockBindings`, rewrite to check for `context.parserOptions.ecmaVersion > 5`. +1. If you're using `context.ecmaFeatures.modules`, rewrite to check that the `sourceType` property of the Program node is `"module"`. +1. If you're using a non-ES6 feature flag such as `context.ecmaFeatures.jsx`, rewrite to check for `context.parserOptions.ecmaFeatures.jsx`. + +If you have a plugin with rules and you are using RuleTester, then you also need to update the options you pass for rules that use `ecmaFeatures`. For example: + +```js +var ruleTester = new RuleTester(); +ruleTester.run("no-var", rule, { + valid: [ + { + code: "let x;", + parserOptions: { ecmaVersion: 6 } + } + ] +}); +``` + +If you're not using `ecmaFeatures` in your configuration or your custom/plugin rules and tests, then no change is needed. + +## New Rules in `"eslint:recommended"` + +```json +{ + "extends": "eslint:recommended" +} +``` + +In 2.0.0, the following 11 rules were added to `"eslint:recommended"`. + +* [constructor-super](https://eslint.org/docs/rules/constructor-super) +* [no-case-declarations](https://eslint.org/docs/rules/no-case-declarations) +* [no-class-assign](https://eslint.org/docs/rules/no-class-assign) +* [no-const-assign](https://eslint.org/docs/rules/no-const-assign) +* [no-dupe-class-members](https://eslint.org/docs/rules/no-dupe-class-members) +* [no-empty-pattern](https://eslint.org/docs/rules/no-empty-pattern) +* [no-new-symbol](https://eslint.org/docs/rules/no-new-symbol) +* [no-self-assign](https://eslint.org/docs/rules/no-self-assign) +* [no-this-before-super](https://eslint.org/docs/rules/no-this-before-super) +* [no-unexpected-multiline](https://eslint.org/docs/rules/no-unexpected-multiline) +* [no-unused-labels](https://eslint.org/docs/rules/no-unused-labels) + +**To address:** If you don't want to be notified by those rules, you can simply disable those rules. + +```json +{ + "extends": "eslint:recommended", + "rules": { + "no-case-declarations": 0, + "no-class-assign": 0, + "no-const-assign": 0, + "no-dupe-class-members": 0, + "no-empty-pattern": 0, + "no-new-symbol": 0, + "no-self-assign": 0, + "no-this-before-super": 0, + "no-unexpected-multiline": 0, + "no-unused-labels": 0, + "constructor-super": 0 + } +} +``` + +## Scope Analysis Changes + +We found some bugs in our scope analysis that needed to be addressed. Specifically, we were not properly accounting for global variables in all the ways they are defined. + +Originally, `Variable` objects and `Reference` objects refer each other: + +* `Variable#references` property is an array of `Reference` objects which are referencing the variable. +* `Reference#resolved` property is a `Variable` object which are referenced. + +But until 1.x, the following variables and references had the wrong value (empty) in those properties: + +* `var` declarations in the global. +* `function` declarations in the global. +* Variables defined in config files. +* Variables defined in `/* global */` comments. + +Now, those variables and references have correct values in these properties. + +`Scope#through` property has references where `Reference#resolved` is `null`. So as a result of this change, the value of `Scope#through` property was changed also. + +**To address:** If you are using `Scope#through` to find references of a built-in global variable, you need to make several changes. + +For example, this is how you might locate the `window` global variable in 1.x: + +```js +var globalScope = context.getScope(); +globalScope.through.forEach(function(reference) { + if (reference.identifier.name === "window") { + checkForWindow(reference); + } +}); +``` + +This was a roundabout way to find the variable because it was added after the fact by ESLint. The `window` variable was in `Scope#through` because the definition couldn't be found. + +In 2.0.0, `window` is no longer located in `Scope#through` because we have added back the correct declaration. That means you can reference the `window` object (or any other global object) directly. So the previous example would change to this: + +```js +var globalScope = context.getScope(); +var variable = globalScope.set.get("window"); +if (variable) { + variable.references.forEach(checkForWindow); +} +``` + +Further Reading: https://estools.github.io/escope/ + +## Default Changes When Using `eslint:recommended` + +This will affect you if you are extending from `eslint:recommended`, and are enabling [`no-multiple-empty-lines`] or [`func-style`] with only a severity, such as: + +```json +{ + "extends": "eslint:recommended", + "rules": { + "no-multiple-empty-lines": 2, + "func-style": 2 + } +} +``` + +The rule `no-multiple-empty-lines` has no default exceptions, but in ESLint `1.x`, a default from `eslint:recommended` was applied such that a maximum of two empty lines would be permitted. + +The rule `func-style` has a default configuration of `"expression"`, but in ESLint `1.x`, `eslint:recommended` defaulted it to `"declaration"`. + +ESLint 2.0.0 removes these conflicting defaults, and so you may begin seeing linting errors related to these rules. + +**To address:** If you would like to maintain the previous behavior, update your configuration for `no-multiple-empty-lines` by adding `{"max": 2}`, and change `func-style` to `"declaration"`. For example: + +```json +{ + "extends": "eslint:recommended", + "rules": { + "no-multiple-empty-lines": [2, {"max": 2}], + "func-style": [2, "declaration"] + } +} +``` + +[`no-multiple-empty-lines`]: ../rules/no-multiple-empty-lines +[`func-style`]: ../rules/func-style + +## SourceCode constructor (Node API) changes + +`SourceCode` constructor got to handle Unicode BOM. +If the first argument `text` has BOM, `SourceCode` constructor sets `true` to `this.hasBOM` and strips BOM from the text. + +```js +var SourceCode = require("eslint").SourceCode; + +var code = new SourceCode("\uFEFFvar foo = bar;", ast); + +assert(code.hasBOM === true); +assert(code.text === "var foo = bar;"); +``` + +So the second argument `ast` also should be parsed from stripped text. + +**To address:** If you are using `SourceCode` constructor in your code, please parse the source code after it stripped BOM: + +```js +var ast = yourParser.parse(text.replace(/^\uFEFF/, ""), options); +var sourceCode = new SourceCode(text, ast); +``` + +## Rule Changes + +* [`strict`](../rules/strict) - defaults to `"safe"` (previous default was `"function"`) + +## Plugins No Longer Have Default Configurations + +Prior to v2.0.0, plugins could specify a `rulesConfig` for the plugin. The `rulesConfig` would automatically be applied whenever someone uses the plugin, which is the opposite of what ESLint does in every other situation (where nothing is on by default). To bring plugins behavior in line, we have removed support for `rulesConfig` in plugins. + +**To address:** If you are using a plugin in your configuration file, you will need to manually enable the plugin rules in the configuration file. diff --git a/docs/8.0.0/user-guide/migrating-to-3.0.0.md b/docs/8.0.0/user-guide/migrating-to-3.0.0.md new file mode 100644 index 0000000000..39b6ab0485 --- /dev/null +++ b/docs/8.0.0/user-guide/migrating-to-3.0.0.md @@ -0,0 +1,89 @@ +--- +title: Migrating to v3.0.0 +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/user-guide/migrating-to-3.0.0.md + +--- + + +# Migrating to v3.0.0 + +ESLint v3.0.0 is the third major version release. We have made several breaking changes in this release, however, we believe the changes to be small enough that they should not require significant changes for ESLint users. This guide is intended to walk you through the changes. + +## Dropping Support for Node.js < 4 + +With ESLint v3.0.0, we are dropping support for Node.js versions prior to 4. Node.js 0.10 and 0.12 are in [maintenance mode](https://github.com/nodejs/Release) and Node.js 4 is the current LTS version. If you are using an older version of Node.js, we recommend upgrading to at least Node.js 4 as soon as possible. If you are unable to upgrade to Node.js 4 or higher, then we recommend continuing to use ESLint v2.x until you are ready to upgrade Node.js. + +**Important:** We will not be updating the ESLint v2.x versions going forward. All bug fixes and enhancements will land in ESLint v3.x. + +## Requiring Configuration to Run + +ESLint v3.0.0 now requires that you use a configuration to run. A configuration can be any of the following: + +1. A `.eslintrc.js`, `.eslintrc.json`, `.eslintrc.yml`, `.eslintrc.yaml`, or `.eslintrc` file either in your project or home directory. +2. Configuration options passed on the command line using `--rule` (or to CLIEngine using `rules`). +3. A configuration file passed on the command line using `-c` (or to CLIEngine using `configFile`). +4. A base configuration is provided to CLIEngine using the `baseConfig` option. + +If ESLint can't find a configuration, then it will throw an error and ask you to provide one. + +This change was made to help new ESLint users who are frequently confused that ESLint does nothing by default besides reporting parser errors. We anticipate this change will have minimal impact on most established users because you're more likely to have configuration files already. + +**To Address:** You should be sure to use a configuration whenever you run ESLint. However, you can still run ESLint without a configuration by passing the `--no-eslintrc` option on the command line or setting the `useEslintrc` option to `false` for `CLIEngine`. + +To create a new configuration, use `eslint --init`. + +## Changes to `"eslint:recommended"` + +```json +{ + "extends": "eslint:recommended" +} +``` + +In 3.0.0, the following rules were added to `"eslint:recommended"`: + +* [`no-unsafe-finally`](https://eslint.org/docs/rules/no-unsafe-finally) helps catch `finally` clauses that may not behave as you think. +* [`no-native-reassign`](https://eslint.org/docs/rules/no-native-reassign) was previously part of `no-undef`, but was split out because it didn't make sense as part of another rule. The `no-native-reassign` rule warns whenever you try to overwrite a read-only global variable. +* [`require-yield`](https://eslint.org/docs/rules/require-yield) helps to identify generator functions that do not have the `yield` keyword. + +The following rules were removed from `"eslint:recommended"`: + +* [`comma-dangle`](https://eslint.org/docs/rules/comma-dangle) used to be recommended because Internet Explorer 8 and earlier threw a syntax error when it found a dangling comma on object literal properties. However, [Internet Explorer 8 was end-of-lifed](https://www.microsoft.com/en-us/WindowsForBusiness/End-of-IE-support) in January 2016 and all other active browsers allow dangling commas. As such, we consider dangling commas to now be a stylistic issue instead of a possible error. + +The following rules were modified: + +* [`complexity`](https://eslint.org/docs/rules/complexity) used to have a hardcoded default of 11 in `eslint:recommended` that would be used if you turned the rule on without specifying a maximum. The default is now 20. The rule actually always had a default of 20, but `eslint:recommended` was overriding it by mistake. + +**To address:** If you want to mimic how `eslint:recommended` worked in v2.x, you can use the following: + +```json +{ + "extends": "eslint:recommended", + "rules": { + "no-unsafe-finally": "off", + "no-native-reassign": "off", + "complexity": ["off", 11], + "comma-dangle": "error", + "require-yield": "error" + } +} +``` + +## Changes to `CLIEngine#executeOnText()` + +The `CLIEngine#executeOnText()` method has changed to work more like `CLIEngine#executeOnFiles()`. In v2.x, `CLIEngine#executeOnText()` warned about ignored files by default and didn't have a way to opt-out of those warnings whereas `CLIEngine#executeOnFiles()` did not warn about ignored files by default and allowed you to opt-in to warning about them. The `CLIEngine#executeOnText()` method now also does not warn about ignored files by default and allows you to opt-in with a new, third argument (a boolean, `true` to warn about ignored files and `false` to not warn). + +**To address:** If you are currently using `CLIEngine#executeOnText()` in your project like this: + +```js +var result = engine.executeOnText(text, filename); +``` + +You can get the equivalent behavior using this: + +```js +var result = engine.executeOnText(text, filename, true); +``` + +If you do not want ignored file warnings output to the console, you can omit the third argument or pass `false`. diff --git a/docs/8.0.0/user-guide/migrating-to-4.0.0.md b/docs/8.0.0/user-guide/migrating-to-4.0.0.md new file mode 100644 index 0000000000..07b1a81305 --- /dev/null +++ b/docs/8.0.0/user-guide/migrating-to-4.0.0.md @@ -0,0 +1,234 @@ +--- +title: Migrating to v4.0.0 +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/user-guide/migrating-to-4.0.0.md + +--- + + +# Migrating to v4.0.0 + +ESLint v4.0.0 is the fourth major version release. We have made several breaking changes in this release; however, we expect that most of the changes will only affect a very small percentage of users. This guide is intended to walk you through the changes. + +The lists below are ordered roughly by the number of users each change is expected to affect, where the first items are expected to affect the most users. + +### Breaking changes for users + +1. [New rules have been added to `eslint:recommended`](#eslint-recommended-changes) +1. [The `indent` rule is more strict](#indent-rewrite) +1. [Unrecognized properties in config files now cause a fatal error](#config-validation) +1. [.eslintignore patterns are now resolved from the location of the file](#eslintignore-patterns) +1. [The `padded-blocks` rule is more strict by default](#padded-blocks-defaults) +1. [The `space-before-function-paren` rule is more strict by default](#space-before-function-paren-defaults) +1. [The `no-multi-spaces` rule is more strict by default](#no-multi-spaces-eol-comments) +1. [References to scoped plugins in config files are now required to include the scope](#scoped-plugin-resolution) + +### Breaking changes for plugin/custom rule developers + +1. [`RuleTester` now validates properties of test cases](#rule-tester-validation) +1. [AST nodes no longer have comment properties](#comment-attachment) +1. [`LineComment` and `BlockComment` events will no longer be emitted during AST traversal](#event-comments) +1. [Shebangs are now returned from comment APIs](#shebangs) + +### Breaking changes for integration developers + +1. [The `global` property in the `linter.verify()` API is no longer supported](#global-property) +1. [More report messages now have full location ranges](#report-locations) +1. [Some exposed APIs are now ES2015 classes](#exposed-es2015-classes) + +--- + +##
    `eslint:recommended` changes + +Two new rules have been added to the [`eslint:recommended`](https://eslint.org/docs/user-guide/configuring#using-eslintrecommended) config: + +* [`no-compare-neg-zero`](/docs/rules/no-compare-neg-zero) disallows comparisons to `-0` +* [`no-useless-escape`](/docs/rules/no-useless-escape) disallows uselessly-escaped characters in strings and regular expressions + +**To address:** To mimic the `eslint:recommended` behavior from 3.x, you can disable these rules in a config file: + +```json +{ + "extends": "eslint:recommended", + + "rules": { + "no-compare-neg-zero": "off", + "no-useless-escape": "off" + } +} +``` + +## The `indent` rule is more strict + +Previously, the [`indent`](/docs/rules/indent) rule was fairly lenient about checking indentation; there were many code patterns where indentation was not validated by the rule. This caused confusion for users, because they were accidentally writing code with incorrect indentation, and they expected ESLint to catch the issues. + +In 4.0.0, the `indent` rule has been rewritten. The new version of the rule will report some indentation errors that the old version of the rule did not catch. Additionally, the indentation of `MemberExpression` nodes, function parameters, and function arguments will now be checked by default (it was previously ignored by default for backwards compatibility). + +To make the upgrade process easier, we've introduced the [`indent-legacy`](/docs/rules/indent-legacy) rule as a snapshot of the `indent` rule from 3.x. If you run into issues from the `indent` rule when you upgrade, you should be able to use the `indent-legacy` rule to replicate the 3.x behavior. However, the `indent-legacy` rule is deprecated and will not receive bugfixes or improvements in the future, so you should eventually switch back to the `indent` rule. + +**To address:** We recommend upgrading without changing your `indent` configuration, and fixing any new indentation errors that appear in your codebase. However, if you want to mimic how the `indent` rule worked in 3.x, you can update your configuration: + +```js +{ + rules: { + indent: "off", + "indent-legacy": "error" // replace this with your previous `indent` configuration + } +} +``` + +## Unrecognized properties in config files now cause a fatal error + +When creating a config, users sometimes make typos or misunderstand how the config is supposed to be structured. Previously, ESLint did not validate the properties of a config file, so a typo in a config could be very tedious to debug. Starting in 4.0.0, ESLint will raise an error if a property in a config file is unrecognized or has the wrong type. + +**To address:** If you see a config validation error after upgrading, verify that your config doesn't contain any typos. If you are using an unrecognized property, you should be able to remove it from your config to restore the previous behavior. + +## .eslintignore patterns are now resolved from the location of the file + +Due to a bug, glob patterns in an `.eslintignore` file were previously resolved from the current working directory of the process, rather than the location of the `.eslintignore` file. Starting in 4.0, patterns in an `.eslintignore` file will be resolved from the `.eslintignore` file's location. + +**To address:** If you use an `.eslintignore` file and you frequently run ESLint from somewhere other than the project root, it's possible that the patterns will be matched differently. You should update the patterns in the `.eslintignore` file to ensure they are relative to the file, not to the working directory. + +## The `padded-blocks` rule is more strict by default + +By default, the [`padded-blocks`](/docs/rules/padded-blocks) rule will now enforce padding in class bodies and switch statements. Previously, the rule would ignore these cases unless the user opted into enforcing them. + +**To address:** If this change results in more linting errors in your codebase, you should fix them or reconfigure the rule. + +## The `space-before-function-paren` rule is more strict by default + +By default, the [`space-before-function-paren`](/docs/rules/space-before-function-paren) rule will now enforce spacing for async arrow functions. Previously, the rule would ignore these cases unless the user opted into enforcing them. + +**To address:** To mimic the default config from 3.x, you can use: + +```json +{ + "rules": { + "space-before-function-paren": ["error", { + "anonymous": "always", + "named": "always", + "asyncArrow": "ignore" + }] + } +} +``` + +## The `no-multi-spaces` rule is more strict by default + +By default, the [`no-multi-spaces`](/docs/rules/no-multi-spaces) rule will now disallow multiple spaces before comments at the end of a line. Previously, the rule did not check this case. + +**To address:** To mimic the default config from 3.x, you can use: + +```json +{ + "rules": { + "no-multi-spaces": ["error", {"ignoreEOLComments": true}] + } +} +``` + +## References to scoped plugins in config files are now required to include the scope + +In 3.x, there was a bug where references to scoped NPM packages as plugins in config files could omit the scope. For example, in 3.x the following config was legal: + +```json +{ + "plugins": [ + "@my-organization/foo" + ], + "rules": { + "foo/some-rule": "error" + } +} +``` + +In other words, it was possible to reference a rule from a scoped plugin (such as `foo/some-rule`) without explicitly stating the `@my-organization` scope. This was a bug because it could lead to ambiguous rule references if there was also an unscoped plugin called `eslint-plugin-foo` loaded at the same time. + +To avoid this ambiguity, in 4.0 references to scoped plugins must include the scope. The config from above should be fixed to: + +```json +{ + "plugins": [ + "@my-organization/foo" + ], + "rules": { + "@my-organization/foo/some-rule": "error" + } +} +``` + +**To address:** If you reference a scoped NPM package as a plugin in a config file, be sure to include the scope wherever you reference it. + +--- + +## `RuleTester` now validates properties of test cases + +Starting in 4.0, the `RuleTester` utility will validate properties of test case objects, and an error will be thrown if an unknown property is encountered. This change was added because we found that it was relatively common for developers to make typos in rule tests, often invalidating the assertions that the test cases were trying to make. + +**To address:** If your tests for custom rules have extra properties, you should remove those properties. + +## AST Nodes no longer have comment properties + +Prior to 4.0, ESLint required parsers to implement comment attachment, a process where AST nodes would gain additional properties corresponding to their leading and trailing comments in the source file. This made it difficult for users to develop custom parsers, because they would have to replicate the confusing comment attachment semantics required by ESLint. + +In 4.0, we have moved away from the concept of comment attachment and have moved all comment handling logic into ESLint itself. This should make it easier to develop custom parsers, but it also means that AST nodes will no longer have `leadingComments` and `trailingComments` properties. Conceptually, rule authors can now think of comments in the context of tokens rather than AST nodes. + +**To address:** If you have a custom rule that depends on the `leadingComments` or `trailingComments` properties of an AST node, you can now use `sourceCode.getCommentsBefore()` and `sourceCode.getCommentsAfter()` instead, respectively. + +Additionally, the `sourceCode` object now also has `sourceCode.getCommentsInside()` (which returns all the comments inside a node), `sourceCode.getAllComments()` (which returns all the comments in the file), and allows comments to be accessed through various other token iterator methods (such as `getTokenBefore()` and `getTokenAfter()`) with the `{ includeComments: true }` option. + +For rule authors concerned about supporting ESLint v3.0 in addition to v4.0, the now deprecated `sourceCode.getComments()` is still available and will work for both versions. + +Finally, please note that the following `SourceCode` methods have been deprecated and will be removed in a future version of ESLint: + +* `getComments()` - replaced by `getCommentsBefore()`, `getCommentsAfter()`, and `getCommentsInside()` +* `getTokenOrCommentBefore()` - replaced by `getTokenBefore()` with the `{ includeComments: true }` option +* `getTokenOrCommentAfter()` - replaced by `getTokenAfter()` with the `{ includeComments: true }` option + +## `LineComment` and `BlockComment` events will no longer be emitted during AST traversal + +Starting in 4.0, `LineComment` and `BlockComments` events will not be emitted during AST traversal. There are two reasons for this: + +* This behavior was relying on comment attachment happening at the parser level, which does not happen anymore, to ensure that all comments would be accounted for +* Thinking of comments in the context of tokens is more predictable and easier to reason about than thinking about comment tokens in the context of AST nodes + +**To address:** Instead of relying on `LineComment` and `BlockComment`, rules can now use `sourceCode.getAllComments()` to get all comments in a file. To check all comments of a specific type, rules can use the following pattern: + +``` +sourceCode.getAllComments().filter(comment => comment.type === "Line"); +sourceCode.getAllComments().filter(comment => comment.type === "Block"); +``` + +## Shebangs are now returned from comment APIs + +Prior to 4.0, shebang comments in a source file would not appear in the output of `sourceCode.getAllComments()` or `sourceCode.getComments()`, but they would appear in the output of `sourceCode.getTokenOrCommentBefore` as line comments. This inconsistency led to some confusion for rule developers. + +In 4.0, shebang comments are treated as comment tokens of type `Shebang` and will be returned by any `SourceCode` method that returns comments. The goal of this change is to make working with shebang comments more consistent with how other tokens are handled. + +**To address:** If you have a custom rule that performs operations on comments, some additional logic might be required to ensure that shebang comments are correctly handled or filtered out: + +``` +sourceCode.getAllComments().filter(comment => comment.type !== "Shebang"); +``` + +--- + +## The `global` property in the `linter.verify()` API is no longer supported + +Previously, the `linter.verify()` API accepted a `global` config option, which was a synonym for the documented `globals` property. The `global` option was never documented or officially supported, and did not work in config files. It has been removed in 4.0. + +**To address:** If you were using the `global` property, please use the `globals` property instead, which does the same thing. + +## More report messages now have full location ranges + +Starting in 3.1.0, rules have been able to specify the *end* location of a reported problem, in addition to the start location, by explicitly specifying an end location in the `report` call. This is useful for tools like editor integrations, which can use the range to precisely display where a reported problem occurs. Starting in 4.0, if a *node* is reported rather than a location, the end location of the range will automatically be inferred from the end location of the node. As a result, many more reported problems will have end locations. + +This is not expected to cause breakage. However, it will likely result in larger report locations than before. For example, if a rule reports the root node of the AST, the reported problem's range will be the entire program. In some integrations, this could result in a poor user experience (e.g. if the entire program is highlighted to indicate an error). + +**To address:** If you have an integration that deals with the ranges of reported problems, make sure you handle large report ranges in a user-friendly way. + +## Some exposed APIs are now ES2015 classes + +The `CLIEngine`, `SourceCode`, and `RuleTester` modules from ESLint's Node.js API are now ES2015 classes. This will not break any documented behavior, but it does have some observable effects (for example, the methods on `CLIEngine.prototype` are now non-enumerable). + +**To address:** If you rely on enumerating the methods of ESLint's Node.js APIs, use a function that can also access non-enumerable properties such as `Object.getOwnPropertyNames`. diff --git a/docs/8.0.0/user-guide/migrating-to-5.0.0.md b/docs/8.0.0/user-guide/migrating-to-5.0.0.md new file mode 100644 index 0000000000..3dd0090513 --- /dev/null +++ b/docs/8.0.0/user-guide/migrating-to-5.0.0.md @@ -0,0 +1,278 @@ +--- +title: Migrating to v5.0.0 +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/user-guide/migrating-to-5.0.0.md + +--- + + +# Migrating to v5.0.0 + +ESLint v5.0.0 is the fifth major version release. We have made a few breaking changes in this release, but we expect that most users will be able to upgrade without any modifications to their build. This guide is intended to walk you through the breaking changes. + +The lists below are ordered roughly by the number of users each change is expected to affect, where the first items are expected to affect the most users. + +### Breaking changes for users + +1. [Node.js 4 is no longer supported](#drop-node-4) +1. [New rules have been added to `eslint:recommended`](#eslint-recommended-changes) +1. [The `experimentalObjectRestSpread` option has been deprecated](#experimental-object-rest-spread) +1. [Linting nonexistent files from the command line is now a fatal error](#nonexistent-files) +1. [The default options for some rules have changed](#rule-default-changes) +1. [Deprecated globals have been removed from the `node`, `browser`, and `jest` environments](#deprecated-globals) +1. [Empty files are now linted](#empty-files) +1. [Plugins in scoped packages are now resolvable in configs](#scoped-plugins) +1. [Multi-line `eslint-disable-line` directives are now reported as problems](#multiline-directives) + +### Breaking changes for plugin/custom rule developers + +1. [The `parent` property of AST nodes is now set before rules start running](#parent-before-rules) +1. [When using the default parser, spread operators now have type `SpreadElement`](#spread-operators) +1. [When using the default parser, rest operators now have type `RestElement`](#rest-operators) +1. [When using the default parser, text nodes in JSX elements now have type `JSXText`](#jsx-text-nodes) +1. [The `context.getScope()` method now returns more proper scopes](#context-get-scope) +1. [The `_linter` property on rule context objects has been removed](#no-context-linter) +1. [`RuleTester` now uses strict equality checks in its assertions](#rule-tester-equality) +1. [Rules are now required to provide messages along with reports](#required-report-messages) + +### Breaking changes for integration developers + +1. [The `source` property is no longer available on individual linting messages](#source-property) +1. [Fatal errors now result in an exit code of 2](#exit-code-two) +1. [The `eslint.linter` property is now non-enumerable](#non-enumerable-linter) + +--- + +## Node.js 4 is no longer supported + +As of April 30th, 2018, Node.js 4 will be at EOL and will no longer be receiving security updates. As a result, we have decided to drop support for it in ESLint v5. We now support the following versions of Node.js: + +* Node.js 6 (6.14.0 and above) +* Node.js 8 (8.10.0 and above) +* Anything above Node.js 9.10.0 + +**To address:** Make sure you upgrade to at least Node.js 6 when using ESLint v5. If you are unable to upgrade, we recommend continuing to use ESLint v4.x until you are able to upgrade Node.js. + +## `eslint:recommended` changes + +Two new rules have been added to the [`eslint:recommended`](https://eslint.org/docs/user-guide/configuring#using-eslintrecommended) config: + +* [`for-direction`](/docs/rules/for-direction) enforces that a `for` loop update clause moves the counter in the right direction. +* [`getter-return`](/docs/rules/getter-return) enforces that a `return` statement is present in property getters. + +**To address:** To mimic the `eslint:recommended` behavior from 4.x, you can disable these rules in a config file: + +```json +{ + "extends": "eslint:recommended", + + "rules": { + "for-direction": "off", + "getter-return": "off" + } +} +``` + +## The `experimentalObjectRestSpread` option has been deprecated + +Previously, when using the default parser it was possible to use the `experimentalObjectRestSpread` option to enable support for [rest/spread properties](https://developers.google.com/web/updates/2017/06/object-rest-spread), as follows: + +```json +{ + "parserOptions": { + "ecmaFeatures": { + "experimentalObjectRestSpread": true + } + } +} +``` + +Object rest/spread is now an official part of the JavaScript language, so our support for it is no longer experimental. In both ESLint v4 and ESLint v5, object rest/spread can now be enabled with the `"ecmaVersion": 2018` option: + +```json +{ + "parserOptions": { + "ecmaVersion": 2018 + } +} +``` + +Note that this also enables parsing for other features from ES2018, such as [async iteration](https://github.com/tc39/proposal-async-iteration). When using ESLint v5 with the default parser, it is no longer possible to toggle syntax support for object rest/spread independently of other features. + +For compatibility, ESLint v5 will treat `ecmaFeatures: { experimentalObjectRestSpread: true }` as an alias for `ecmaVersion: 2018` when the former is found in a config file. As a result, if you use object rest/spread, your code should still parse successfully with ESLint v5. However, note that this alias will be removed in ESLint v6. + +**To address:** If you use the `experimentalObjectRestSpread` option, you should be able to upgrade to ESLint v5 without any changes, but you will encounter a deprecation warning. To avoid the warning, use `ecmaVersion: 2018` in your config file rather than `ecmaFeatures: { experimentalObjectRestSpread: true }`. If you would like to disallow the use of other ES2018 features, consider using rules such as [`no-restricted-syntax`](/docs/rules/no-restricted-syntax). + +## Linting nonexistent files from the command line is now a fatal error + +Previous versions of ESLint silently ignored any nonexistent files and globs provided on the command line: + +```bash +$ eslint nonexistent-file.js 'nonexistent-folder/**/*.js' # exits without any errors in ESLint v4 +``` + +Many users found this behavior confusing, because if they made a typo in a filename, ESLint would appear to lint that file successfully while actually not linting anything. + +ESLint v5 will report a fatal error when either of the following conditions is met: + +* A file provided on the command line does not exist +* A glob or folder provided on the command line does not match any lintable files + +Note that this also affects the [`CLIEngine.executeOnFiles()`](https://eslint.org/docs/developer-guide/nodejs-api#cliengineexecuteonfiles) API. + +**To address:** If you encounter an error about missing files after upgrading to ESLint v5, you may want to double-check that there are no typos in the paths you provide to ESLint. To make the error go away, you can simply remove the given files or globs from the list of arguments provided to ESLint on the command line. + +If you use a boilerplate generator that relies on this behavior (e.g. to generate a script that runs `eslint tests/` in a new project before any test files are actually present), you can work around this issue by adding a dummy file that matches the given pattern (e.g. an empty `tests/index.js` file). + +## The default options for some rules have changed + +* The default options for the [`object-curly-newline`](/docs/rules/object-curly-newline) rule have changed from `{ multiline: true }` to `{ consistent: true }`. +* The default options object for the [`no-self-assign`](/docs/rules/no-self-assign) rule has changed from `{ props: false }` to `{ props: true }`. + +**To address:** To restore the rule behavior from ESLint v4, you can update your config file to include the previous options: + +```json +{ + "rules": { + "object-curly-newline": ["error", { "multiline": true }], + "no-self-assign": ["error", { "props": false }] + } +} +``` + +## Deprecated globals have been removed from the `node`, `browser`, and `jest` environments + +Some global variables have been deprecated or removed for code running in Node.js, browsers, and Jest. (For example, browsers used to expose an `SVGAltGlyphElement` global variable to JavaScript code, but this global has been removed from web standards and is no longer present in browsers.) As a result, we have removed these globals from the corresponding `eslint` environments, so use of these globals will trigger an error when using rules such as [`no-undef`](/docs/rules/no-undef). + +**To address:** If you use deprecated globals in the `node`, `browser`, or `jest` environments, you can add a `globals` section to your configuration to re-enable any globals you need. For example: + +```json +{ + "env": { + "browser": true + }, + "globals": { + "SVGAltGlyphElement": false + } +} +``` + +## Empty files are now linted + +ESLint v4 had a special behavior when linting files that only contain whitespace: it would skip running the parser and rules, and it would always return zero errors. This led to some confusion for users and rule authors, particularly when writing tests for rules. (When writing a stylistic rule, rule authors would occasionally write a test where the source code only contained whitespace, to ensure that the rule behaved correctly when no applicable code was found. However, a test like this would actually not run the rule at all, so an aspect of the rule would end up untested.) + +ESLint v5 treats whitespace-only files the same way as all other files: it parses them and runs enabled rules on them as appropriate. This could lead to additional linting problems if you use a custom rule that reports errors on empty files. + +**To address:** If you have an empty file in your project and you don't want it to be linted, consider adding it to an [`.eslintignore` file](/docs/user-guide/configuring#ignoring-files-and-directories). + +If you have a custom rule, you should make sure it handles empty files appropriately. (In most cases, no changes should be necessary.) + +## Plugins in scoped packages are now resolvable in configs + +When ESLint v5 encounters a plugin name in a config starting with `@`, the plugin will be resolved as a [scoped npm package](https://docs.npmjs.com/misc/scope). For example, if a config contains `"plugins": ["@foo"]`, ESLint v5 will attempt to load a package called `@foo/eslint-plugin`. (On the other hand, ESLint v4 would attempt to load a package called `eslint-plugin-@foo`.) This is a breaking change because users might have been relying on ESLint finding a package at `node_modules/eslint-plugin-@foo`. However, we think it is unlikely that many users were relying on this behavior, because packages published to npm cannot contain an `@` character in the middle. + +**To address:** If you rely on ESLint loading a package like `eslint-config-@foo`, consider renaming the package to something else. + +## Multi-line `eslint-disable-line` directives are now reported as problems + +`eslint-disable-line` and `eslint-disable-next-line` directive comments are only allowed to span a single line. For example, the following directive comment is invalid: + +```js +alert('foo'); /* eslint-disable-line + no-alert */ alert('bar'); + +// (which line is the rule disabled on?) +``` + +Previously, ESLint would ignore these malformed directive comments. ESLint v5 will report an error when it sees a problem like this, so that the issue can be more easily corrected. + +**To address:** If you see new reported errors as a result of this change, ensure that your `eslint-disable-line` directives only span a single line. Note that "block comments" (delimited by `/* */`) are still allowed to be used for directives, provided that the block comments do not contain linebreaks. + +--- + +## The `parent` property of AST nodes is now set before rules start running + +Previously, ESLint would set the `parent` property on each AST node immediately before running rule listeners for that node. This caused some confusion for rule authors, because the `parent` property would not initially be present on any nodes, and it was sometimes necessary to complicate the structure of a rule to ensure that the `parent` property of a given node would be available when needed. + +In ESLint v5, the `parent` property is set on all AST nodes before any rules have access to the AST. This makes it easier to write some rules, because the `parent` property is always available rather than being mutated behind the scenes. However, as a side-effect of having `parent` properties, the AST object has a circular structure the first time a rule sees it (previously, it only had a circular structure after the first rule listeners were called). As a result, a custom rule that enumerates all properties of a node in order to traverse the AST might now loop forever or run out of memory if it does not check for cycles properly. + +**To address:** If you have written a custom rule that enumerates all properties of an AST node, consider excluding the `parent` property or implementing cycle detection to ensure that you obtain the correct result. + +## When using the default parser, spread operators now have type `SpreadElement` + +Previously, when parsing JS code like `const foo = {...data}` with the `experimentalObjectRestSpread` option enabled, the default parser would generate an `ExperimentalSpreadProperty` node type for the `...data` spread element. + +In ESLint v5, the default parser will now always give the `...data` AST node the `SpreadElement` type, even if the (now deprecated) [`experimentalObjectRestSpread`](#experimental-object-rest-spread) option is enabled. This makes the AST compliant with the current ESTree spec. + +**To address:** If you have written a custom rule that relies on spread operators having the `ExperimentalSpreadProperty` type, you should update it to also work with spread operators that have the `SpreadElement` type. + +## When using the default parser, rest operators now have type `RestElement` + +Previously, when parsing JS code like `const {foo, ...rest} = data` with the `experimentalObjectRestSpread` option enabled, the default parser would generate an `ExperimentalRestProperty` node type for the `...data` rest element. + +In ESLint v5, the default parser will now always give the `...data` AST node the `RestElement` type, even if the (now deprecated) [`experimentalObjectRestSpread`](#experimental-object-rest-spread) option is enabled. This makes the AST compliant with the current ESTree spec. + +**To address:** If you have written a custom rule that relies on rest operators having the `ExperimentalRestProperty` type, you should update it to also work with rest operators that have the `RestElement` type. + +## When using the default parser, text nodes in JSX elements now have type `JSXText` + +When parsing JSX code like `foo`, the default parser will now give the `foo` AST node the `JSXText` type, rather than the `Literal` type. This makes the AST compliant with a recent update to the JSX spec. + +**To address:** If you have written a custom rule that relies on text nodes in JSX elements having the `Literal` type, you should update it to also work with nodes that have the `JSXText` type. + +## The `context.getScope()` method now returns more proper scopes + +Previously, the `context.getScope()` method changed its behavior based on the `parserOptions.ecmaVersion` property. However, this could cause confusing behavior when using a parser that doesn't respond to the `ecmaVersion` option, such as `babel-eslint`. + +Additionally, `context.getScope()` incorrectly returned the parent scope of the proper scope on `CatchClause` (in ES5), `ForStatement` (in ≧ES2015), `ForInStatement` (in ≧ES2015), `ForOfStatement`, and `WithStatement` nodes. + +In ESLint v5, the `context.getScope()` method has the same behavior regardless of `parserOptions.ecmaVersion` and returns the proper scope. See [the documentation](../developer-guide/working-with-rules#contextgetscope) for more details on which scopes are returned. + +**To address:** If you have written a custom rule that uses the `context.getScope()` method in node handlers, you may need to update it to account for the modified scope information. + +## The `_linter` property on rule context objects has been removed + +Previously, rule context objects had an undocumented `_linter` property, which was used internally within ESLint to process reports from rules. Some rules used this property to achieve functionality that was not intended to be possible for rules. For example, several plugins used the `_linter` property in a rule to monitor reports from other rules, for the purpose of checking for unused `/* eslint-disable */` directive comments. Although this functionality was useful for users, it could also cause stability problems for projects using ESLint. For example, an upgrade to a rule in one plugin could unexpectedly cause a rule in another plugin to start reporting errors. + +The `_linter` property has been removed in ESLint v5.0, so it is no longer possible to implement rules with this functionality. However, the [`--report-unused-disable-directives`](/docs/user-guide/command-line-interface#--report-unused-disable-directives) CLI flag can be used to flag unused directive comments. + +## `RuleTester` now uses strict equality checks in its assertions + +Previously, `RuleTester` used loose equality when making some of its assertions. For example, if a rule produced the string `"7"` as a result of autofixing, `RuleTester` would allow the number `7` in an `output` assertion, rather than the string `"7"`. In ESLint v5, comparisons from `RuleTester` use strict equality, so an assertion like this will no longer pass. + +**To address:** If you use `RuleTester` to write tests for your custom rules, make sure the expected values in your assertions are strictly equal to the actual values. + +## Rules are now required to provide messages along with reports + +Previously, it was possible for rules to report AST nodes without providing a report message. This was not intended behavior, and as a result the default formatter would crash if a rule omitted a message. However, it was possible to avoid a crash when using a non-default formatter, such as `json`. + +In ESLint v5, reporting a problem without providing a message always results in an error. + +**To address:** If you have written a custom rule that reports a problem without providing a message, update it to provide a message along with the report. + +--- + +## The `source` property is no longer available on individual linting messages + +As announced in [October 2016](/blog/2016/10/eslint-v3.8.0-released#additional-property-on-linting-results), the `source` property has been removed from individual lint message objects. + +**To address:** If you have a formatter or integration which relies on using the `source` property on individual linting messages, you should update it to use the `source` property on file results objects instead. + +## Fatal errors now result in an exit code of 2 + +When using ESLint v4, both of the following scenarios resulted in an exit code of 1 when running ESLint on the command line: + +* Linting completed successfully, but there are some linting errors +* Linting was unsuccessful due to a fatal error (e.g. an invalid config file) + +As a result, it was difficult for an integration to distinguish between the two cases to determine whether it should try to extract linting results from the output. + +In ESLint v5, an unsuccessful linting run due to a fatal error will result in an exit code of 2, rather than 1. + +**To address:** If you have an integration that detects all problems with linting runs by checking whether the exit code is equal to 1, update it to check whether the exit code is nonzero instead. + +## The `eslint.linter` property is now non-enumerable + +When using ESLint's Node.js API, the [`linter`](/docs/developer-guide/nodejs-api#linter-1) property is now non-enumerable. Note that the `linter` property was deprecated in ESLint v4 in favor of the [`Linter`](/docs/developer-guide/nodejs-api#linter) property. + +**To address:** If you rely on enumerating all the properties of the `eslint` object, use something like `Object.getOwnPropertyNames` to ensure that non-enumerable keys are captured. diff --git a/docs/8.0.0/user-guide/migrating-to-6.0.0.md b/docs/8.0.0/user-guide/migrating-to-6.0.0.md new file mode 100644 index 0000000000..a2c588f30a --- /dev/null +++ b/docs/8.0.0/user-guide/migrating-to-6.0.0.md @@ -0,0 +1,338 @@ +--- +title: Migrating to v6.0.0 +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/user-guide/migrating-to-6.0.0.md + +--- + + +# Migrating to v6.0.0 + +ESLint v6.0.0 is a major release of ESLint. We have made a few breaking changes in this release. This guide is intended to walk you through the breaking changes. + +The lists below are ordered roughly by the number of users each change is expected to affect, where the first items are expected to affect the most users. + +### Breaking changes for users + +1. [Node.js 6 is no longer supported](#drop-node-6) +1. [`eslint:recommended` has been updated](#eslint-recommended-changes) +1. [Plugins and shareable configs are no longer affected by ESLint's location](#package-loading-simplification) +1. [The default parser now validates options more strictly](#espree-validation) +1. [Rule configuration are validated more strictly](#rule-config-validating) +1. [The `no-redeclare` rule is now more strict by default](#no-redeclare-updates) +1. [The `comma-dangle` rule is now more strict by default](#comma-dangle-updates) +1. [The `no-confusing-arrow` rule is now more lenient by default](#no-confusing-arrow-updates) +1. [Overrides in a config file can now match dotfiles](#overrides-dotfiles) +1. [Overrides in an extended config file can now be overridden by a parent config file](#overrides-precedence) +1. [Configuration values for globals are now validated](#globals-validation) +1. [The deprecated `experimentalObjectRestSpread` option has been removed](#experimental-object-rest-spread) +1. [User-provided regular expressions in rule options are parsed with the unicode flag](#unicode-regexes) + +### Breaking changes for plugin/custom rule developers + +1. [Plugin authors may need to update installation instructions](#plugin-documentation) +1. [`RuleTester` now validates against invalid `default` keywords in rule schemas](#rule-tester-defaults) +1. [`RuleTester` now requires an absolute path on `parser` option](#rule-tester-parser) +1. [The `eslintExplicitGlobalComment` scope analysis property has been removed](#eslintExplicitGlobalComment) + +### Breaking changes for integration developers + +1. [Plugins and shareable configs are no longer affected by ESLint's location](#package-loading-simplification) +1. [`Linter` no longer tries to load missing parsers from the filesystem](#linter-parsers) + +--- + +## Node.js 6 is no longer supported + +As of April 2019, Node.js 6 will be at EOL and will no longer be receiving security updates. As a result, we have decided to drop support for it in ESLint v6. We now support the following versions of Node.js: + +* Node.js 8 (8.10.0 and above) +* Node.js 10 (10.13.0 and above) +* Anything above Node.js 11.10.1 + +**To address:** Make sure you upgrade to at least Node.js 8 when using ESLint v6. If you are unable to upgrade, we recommend continuing to use ESLint v5.x until you are able to upgrade Node.js. + +**Related issue(s):** [eslint/eslint#11546](https://github.com/eslint/eslint/issues/11456) + +## `eslint:recommended` has been updated + +The following rules have been added to the [`eslint:recommended`](https://eslint.org/docs/user-guide/configuring#using-eslintrecommended) config: + +* [`no-async-promise-executor`](https://eslint.org/docs/rules/no-async-promise-executor) disallows using an `async` function as the argument to the `Promise` constructor, which is usually a bug. +* [`no-misleading-character-class`](https://eslint.org/docs/rules/no-misleading-character-class) reports character classes in regular expressions that might not behave as expected. +* [`no-prototype-builtins`](https://eslint.org/docs/rules/no-prototype-builtins) reports method calls like `foo.hasOwnProperty("bar")` (which are a frequent source of bugs), and suggests that they be replaced with `Object.prototype.hasOwnProperty.call(foo, "bar")` instead. +* [`no-shadow-restricted-names`](https://eslint.org/docs/rules/no-shadow-restricted-names) disallows shadowing variables like `undefined` (e.g. with code like `let undefined = 5;`), since is likely to confuse readers. +* [`no-useless-catch`](https://eslint.org/docs/rules/no-useless-catch) reports `catch` clauses that are redundant and can be removed from the code without changing its behavior. +* [`no-with`](https://eslint.org/docs/rules/no-with) disallows use of the [`with` statement](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with), which can make code difficult to understand and cause compatibility problems. +* [`require-atomic-updates`](https://eslint.org/docs/rules/require-atomic-updates) reports race condition bugs that can occur when reassigning variables in async functions. + +Additionally, the following rule has been *removed* from `eslint:recommended`: + +* [`no-console`](https://eslint.org/docs/rules/no-console) disallows calling functions like `console.log`. While this rule is useful in many cases (e.g. to avoid inadvertently leaving debugging statements in production code), it is not as broadly applicable as the other rules in `eslint:recommended`, and it was a source of false positives in cases where `console.log` is acceptable (e.g. in CLI applications). + +Finally, in ESLint v5 `eslint:recommended` would explicitly disable all core rules that were not considered "recommended". This could cause confusing behavior if `eslint:recommended` was loaded after another config, since `eslint:recommended` would have the effect of turning off some rules. In ESLint v6, `eslint:recommended` has no effect on non-recommended rules. + +**To address:** To mimic the `eslint:recommended` behavior from 5.x, you can explicitly disable/enable rules in a config file as follows: + +```json +{ + "extends": "eslint:recommended", + + "rules": { + "no-async-promise-executor": "off", + "no-misleading-character-class": "off", + "no-prototype-builtins": "off", + "no-shadow-restricted-names": "off", + "no-useless-catch": "off", + "no-with": "off", + "require-atomic-updates": "off", + + "no-console": "error" + } +} +``` + +In rare cases (if you were relying on the previous behavior where `eslint:recommended` disables core rules), you might need to disable additional rules to restore the previous behavior. + +**Related issue(s):** [eslint/eslint#10768](https://github.com/eslint/eslint/issues/10768), [eslint/eslint#10873](https://github.com/eslint/eslint/issues/10873) + +## Plugins and shareable configs are no longer affected by ESLint's location + +Previously, ESLint loaded plugins relative to the location of the ESLint package itself. As a result, we suggested that users with global ESLint installations should also install plugins globally, and users with local ESLint installations should install plugins locally. However, due to a design bug, this strategy caused ESLint to randomly fail to load plugins and shareable configs under certain circumstances, particularly when using package management tools like [`lerna`](https://github.com/lerna/lerna) and [Yarn Plug n' Play](https://yarnpkg.com/lang/en/docs/pnp/). + +As a rule of thumb: With ESLint v6, plugins should always be installed locally, even if ESLint was installed globally. More precisely, ESLint v6 resolves plugins relative to the end user's project by default, and always resolves shareable configs and parsers relative to the location of the config file that imports them. + +**To address:** If you use a global installation of ESLint (e.g. installed with `npm install eslint --global`) along with plugins, you should install those plugins locally in the projects where you run ESLint. If your config file extends shareable configs and/or parsers, you should ensure that those packages are installed as dependencies of the project containing the config file. + +If you use a config file located outside of a local project (with the `--config` flag), consider installing the plugins as dependencies of that config file, and setting the [`--resolve-plugins-relative-to`](./command-line-interface#--resolve-plugins-relative-to) flag to the location of the config file. + +**Related issue(s):** [eslint/eslint#10125](https://github.com/eslint/eslint/issues/10125), [eslint/rfcs#7](https://github.com/eslint/rfcs/pull/7) + +## The default parser now validates options more strictly + +`espree`, the default parser used by ESLint, will now raise an error in the following cases: + +* The `ecmaVersion` parser option is set to something other than a number, such as the string `"2015"`. (Previously, a non-number option would simply be ignored.) +* The `sourceType: "module"` parser option is set while `ecmaVersion` is set to `5` or left unspecified. (Previously, setting `sourceType: "module"` would implicitly cause `ecmaVersion` to be set to a minimum of 2015, which could be surprising.) +* The `sourceType` is set to anything other than `"script"` or `"module"`. + +**To address:** If your config sets `ecmaVersion` to something other than a number, you can restore the previous behavior by removing `ecmaVersion`. (However, you may want to double-check that your config is actually working as expected.) If your config sets `parserOptions: { sourceType: "module" }` without also setting `parserOptions.ecmaVersion`, you should add `parserOptions: { ecmaVersion: 2015 }` to restore the previous behavior. + +**Related issue(s):** [eslint/eslint#9687](https://github.com/eslint/eslint/issues/9687), [eslint/espree#384](https://github.com/eslint/espree/issues/384) + +## Rule configuration are validated more strictly + +To catch config errors earlier, ESLint v6 will report a linting error if you are trying to configure a non-existent rule. + +config | ESLint v5 | ESLint v6 +------------- | ------------- | ------------- +`/*eslint-enable foo*/` | no error | linting error +`/*eslint-disable(-line) foo*/` | no error | linting error +`/*eslint foo: 0*/` | no error | linting error +`{rules: {foo: 0}}` | no error | no error +`{rules: {foo: 1}` | linting warning | linting error + +**To address:** You can remove the non-existent rule in your (inline) config. + +**Related issue(s):** [eslint/eslint#9505](https://github.com/eslint/eslint/issues/9505) + +## The `no-redeclare` rule is now more strict by default + +The default options for the [`no-redeclare`](https://eslint.org/docs/rules/no-redeclare) rule have changed from `{ builtinGlobals: false }` to `{ builtinGlobals: true }`. Additionally, the `no-redeclare` rule will now report an error for globals enabled by comments like `/* global foo */` if those globals were already enabled through configuration anyway. + +**To address:** + +To restore the previous options for the rule, you can configure it as follows: + +```json +{ + "rules": { + "no-redeclare": ["error", { "builtinGlobals": false }] + } +} +``` + +Additionally, if you see new errors for `global` comments in your code, you should remove those comments. + +**Related issue(s):** [eslint/eslint#11370](https://github.com/eslint/eslint/issues/11370), [eslint/eslint#11405](https://github.com/eslint/eslint/issues/11405) + +## The `comma-dangle` rule is now more strict by default + +Previously, the [`comma-dangle`](https://eslint.org/docs/rules/comma-dangle) rule would ignore trailing function arguments and parameters, unless explicitly configured to check for function commas. In ESLint v6, function commas are treated the same way as other types of trailing commas. + +**To address:** You can restore the previous default behavior of the rule with: + +```json +{ + "rules": { + "comma-dangle": ["error", { + "arrays": "never", + "objects": "never", + "imports": "never", + "exports": "never", + "functions": "ignore" + }] + } +} +``` + +To restore the previous behavior of a string option like `"always-multiline"`, replace `"never"` with `"always-multiline"` in the example above. + +**Related issue(s):** [eslint/eslint#11502](https://github.com/eslint/eslint/issues/11502) + +## The `no-confusing-arrow` rule is now more lenient by default + +The default options for the [`no-confusing-arrow`](https://eslint.org/docs/rules/no-confusing-arrow) rule have changed from `{ allowParens: false }` to `{ allowParens: true }`. + +**To address:** You can restore the previous default behavior of the rule with: + +```json +{ + "rules": { + "no-confusing-arrow": ["error", { "allowParens": false }] + } +} +``` + +**Related issue(s):** [eslint/eslint#11503](https://github.com/eslint/eslint/issues/11503) + +## Overrides in a config file can now match dotfiles + +Due to a bug, the glob patterns in a `files` list in an `overrides` section of a config file would never match dotfiles, making it impossible to have overrides apply to files starting with a dot. This bug has been fixed in ESLint v6. + +**To address:** If you don't want dotfiles to be matched by an override, consider adding something like `excludedFiles: [".*"]` to that `overrides` section. See the [documentation](https://eslint.org/docs/user-guide/configuring#configuration-based-on-glob-patterns) for more details. + +**Related issue(s):** [eslint/eslint#11201](https://github.com/eslint/eslint/issues/11201) + +## Overrides in an extended config file can now be overridden by a parent config file + +Due to a bug, it was previously the case that an `overrides` block in a shareable config had precedence over the top level of a parent config. For example, with the following config setup, the `semi` rule would end up enabled even though it was explicitly disabled in the end user's config: + +```js +// .eslintrc.js +module.exports = { + extends: ["foo"], + rules: { + semi: "off" + } +}; +``` + +```js +// eslint-config-foo/index.js +module.exports = { + overrides: { + files: ["*.js"], + rules: { + semi: "error" + } + } +}; +``` + +In ESLint v6.0.0, a parent config always has precedence over extended configs, even with `overrides` blocks. + +**To address:** We expect the impact of this issue to be very low because most shareable configs don't use `overrides` blocks. However, if you use a shareable config with `overrides` blocks, you might encounter a change in behavior due to something that is explicitly specified in your config but was inactive until now. If you would rather inherit the behavior from the shareable config, simply remove the corresponding entry from your own config. (In the example above, the previous behavior could be restored by removing `semi: "off"` from `.eslintrc.js`.) + +**Related issue(s):** [eslint/eslint#11510](https://github.com/eslint/eslint/issues/11510) + +## Configuration values for globals are now validated + +Previously, when configuring a set of global variables with an object, it was possible to use anything as the values of the object. An unknown value would be treated the same as `"writable"`. + +```js +// .eslintrc.js +module.exports = { + globals: { + foo: "readonly", + bar: "writable", + baz: "hello!" // ??? + } +}; +``` + +With this change, any unknown values in a `globals` object result in a config validation error. + +**To address:** If you see config validation errors related to globals after updating, ensure that all values configured for globals are either `readonly`, `writable`, or `off`. (ESLint also accepts some alternate spellings and variants for compatibility.) + +## The deprecated `experimentalObjectRestSpread` option has been removed + +Previously, when using the default parser, a config could use the `experimentalObjectRestSpread` option to enable parsing support for object rest/spread properties: + +```json +{ + "parserOptions": { + "ecmaFeatures": { + "experimentalObjectRestSpread": true + } + } +} +``` + +Since ESLint v5, `ecmaFeatures: { experimentalObjectRestSpread: true }` has been equivalent to `ecmaVersion: 2018`, and has also emitted a deprecation warning. In ESLint v6, the `experimentalObjectRestSpread` feature has been removed entirely and has no effect. If your config was relying on `experimentalObjectRestSpread` to enable ES2018 parsing, you might start seeing parsing errors for recent syntax. + +**To address:** If you use the `experimentalObjectRestSpread` option, you should change your config to contain this instead: + +```json +{ + "parserOptions": { + "ecmaVersion": 2018 + } +} +``` + +If you're not sure which config file needs to be updated, it may be useful to run ESLint v5 and look at what config file is mentioned in the deprecation warning. + +**Related issue(s):** [eslint/eslint#9990](https://github.com/eslint/eslint/issues/9990) + +## User-provided regular expressions in rule options are parsed with the unicode flag + +Rules like [`max-len`](/docs/rules/max-len) accept a string option which is interpreted as a regular expression. In ESLint v6.0.0, these regular expressions are interpreted with the [unicode flag](https://mathiasbynens.be/notes/es6-unicode-regex), which should exhibit more reasonable behavior when matching characters like astral symbols. Unicode regexes also validate escape sequences more strictly than non-unicode regexes. + +**To address:** If you get rule option validation errors after upgrading, ensure that any regular expressions in your rule options have no invalid escape sequences. + +**Related issue(s):** [eslint/eslint#11423](https://github.com/eslint/eslint/issues/11423) + +--- + +## Plugin authors may need to update installation instructions + +If you maintain a plugin and provide installation instructions, you should ensure that the installation instructions are up to date with the [user-facing changes to how plugins are loaded](#package-loading-simplification). In particular, if your plugin was generated with the [`generator-eslint`](https://github.com/eslint/generator-eslint) package, it likely contains outdated instructions for how to use the plugin with global ESLint installations. + +**Related issue(s):** [eslint/rfcs#7](https://github.com/eslint/rfcs/pull/7) + +## `RuleTester` now validates against invalid `default` keywords in rule schemas + +In some cases, rule schemas can use the `default` keyword to automatically specify default values for rule options. However, the `default` keyword is only effective in certain schema locations, and is ignored elsewhere, which creates a risk of bugs if a rule incorrectly expects a default value to be provided as a rule option. In ESLint v6.0.0, `RuleTester` will raise an error if a rule has an invalid `default` keyword in its schema. + +**To address:** If `RuleTester` starts reporting an error about an invalid default, you can remove the `default` property at the indicated location in your rule schema, and the rule will behave the same way. (If this happens, you might also want to verify that the rule behaves correctly when no option value is provided in that location.) + +**Related issue(s):** [eslint/eslint#11473](https://github.com/eslint/eslint/issues/11473) + +## `RuleTester` now requires an absolute path on `parser` option + +To use custom parsers in tests, we could use `parser` property with a package name or file path. However, if a package name was given, it's unclear where the tester should load the parser package from because the tester doesn't know which files are running the tester. In ESLint v6.0.0, `RuleTester` disallows `parser` property with a package name. + +**To address:** If you use `parser` property with package names in test cases, update it with `require.resolve()` function to resolve the package name to the absolute path to the package. + +**Related issue(s):** [eslint/eslint#11728](https://github.com/eslint/eslint/issues/11728), [eslint/eslint#10125](https://github.com/eslint/eslint/issues/10125), [eslint/rfcs#7](https://github.com/eslint/rfcs/pull/7) + +## The `eslintExplicitGlobalComment` scope analysis property has been removed + +Previously, ESLint would add an `eslintExplicitGlobalComment` property to `Variable` objects in scope analysis to indicate that a variable was introduced as a result of a `/* global */` comment. This property was undocumented, and the ESLint team was unable to find any usage of the property outside of ESLint core. The property has been removed in ESLint v6, and replaced with the `eslintExplicitGlobalComments` property, which can contain a list of all `/* global */` comments if a variable was declared with more than one of them. + +**To address:** If you maintain a rule that uses the `eslintExplicitGlobalComment` property, update it to use the `eslintExplicitGlobalComments` property as a list instead. + +**Related issue(s):** [eslint/rfcs#17](https://github.com/eslint/rfcs/pull/17) + +--- + +## `Linter` no longer tries to load missing parsers from the filesystem + +Previously, when linting code with a parser that had not been previously defined, the `Linter` API would attempt to load the parser from the filesystem. However, this behavior was confusing because `Linter` never access the filesystem in any other cases, and it was difficult to ensure that the correct parser would be found when loading the parser from the filesystem. + +In ESLint v6, `Linter` will no longer perform any filesystem operations, including loading parsers. + +**To address:** If you're using `Linter` with a custom parser, use [`Linter#defineParser`](https://eslint.org/docs/developer-guide/nodejs-api#linterdefineparser) to explicitly define the parser before linting any code. + +**Related issue(s):** [eslint/rfcs#7](https://github.com/eslint/rfcs/pull/7) diff --git a/docs/8.0.0/user-guide/migrating-to-7.0.0.md b/docs/8.0.0/user-guide/migrating-to-7.0.0.md new file mode 100644 index 0000000000..2f2f292e93 --- /dev/null +++ b/docs/8.0.0/user-guide/migrating-to-7.0.0.md @@ -0,0 +1,240 @@ +--- +title: Migrating to v7.0.0 +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/user-guide/migrating-to-7.0.0.md + +--- + + +# Migrating to v7.0.0 + +ESLint v7.0.0 is a major release of ESLint. We have made a few breaking changes in this release. This guide is intended to walk you through the breaking changes. + +The lists below are ordered roughly by the number of users each change is expected to affect, where the first items are expected to affect the most users. + +## Table of Content + +### Breaking changes for users + +- [Node.js 8 is no longer supported](#drop-node-8) +- [Lint files matched by `overrides[].files` by default](#additional-lint-targets) +- [The base path of `overrides` and `ignorePatterns` is changed if the config file is given by the `--config`/`--ignore-path` options](#base-path-change) +- [The place where ESLint loads plugins from is changed](#plugin-loading-change) +- [Runtime deprecation warnings for `~/.eslintrc.*` config files](#runtime-deprecation-on-personal-config-files) +- [Default ignore patterns have changed](#default-ignore-patterns) +- [Description in directive comments](#description-in-directive-comments) +- [Node.js/CommonJS rules are deprecated](#deprecate-node-rules) +- [Several rules have been updated to cover more cases](#rules-strict) +- [`eslint:recommended` has been updated](#eslint-recommended) + +### Breaking changes for plugin developers + +- [Node.js 8 is no longer supported](#drop-node-8) +- [Lint files matched by `overrides[].files` by default](#additional-lint-targets) +- [Plugin resolution has been updated](#plugin-loading-change) +- [Additional validation added to the `RuleTester` class](#rule-tester-strict) + +### Breaking changes for integration developers + +- [Node.js 8 is no longer supported](#drop-node-8) +- [Plugin resolution has been updated](#plugin-loading-change) +- [The `CLIEngine` class has been deprecated](#deprecate-cliengine) + +--- + +## Node.js 8 is no longer supported + +Node.js 8 reached EOL in December 2019, and we are officially dropping support for it in this release. ESLint now supports the following versions of Node.js: + +- Node.js 10 (`10.12.0` and above) +- Node.js 12 and above + +**To address:** Make sure you upgrade to at least Node.js `10.12.0` when using ESLint v7.0.0. One important thing to double check is the Node.js version supported by your editor when using ESLint via editor integrations. If you are unable to upgrade, we recommend continuing to use ESLint 6 until you are able to upgrade Node.js. + +**Related issue(s):** [RFC44](https://github.com/eslint/rfcs/blob/master/designs/2019-drop-node8/README.md), [#12700](https://github.com/eslint/eslint/pull/12700) + +## Lint files matched by `overrides[].files` by default + +Previously to v7.0.0, ESLint would only lint files with a `.js` extension by default if you give directories like `eslint src`. + +ESLint v7.0.0 will now additionally lint files with other extensions (`.ts`, `.vue`, etc.) if the extension is explicitly matched by an `overrides[].files` entry. This will allow for users to lint files that don't end with `*.js` to be linted without having to use the `--ext` command line flag, as well as allow shared configuration authors to enable linting of these files without additional overhead for the end user. Please note that patterns that end with `*` are exempt from this behavior and will behave as they did previously. For example, if the following config file is present, + +```yml +# .eslintrc.yml +extends: my-config-js +overrides: + - files: "*.ts" + extends: my-config-ts +``` + +then running `eslint src` would check both `*.js` and `*.ts` files in the `src` directory. + +**To address:** Using the `--ext` CLI option will override this new behavior. Run ESLint with `--ext .js` if you are using `overrides` but only want to lint files that have a `.js` extension. + +If you maintain plugins that check files with extensions other than `.js`, this feature will allow you to check these files by default by configuring an `overrides` setting in your `recommended` preset. + +**Related issue(s):** [RFC20](https://github.com/eslint/rfcs/blob/master/designs/2019-additional-lint-targets/README.md), [#12677](https://github.com/eslint/eslint/pull/12677) + +## The base path of `overrides` and `ignorePatterns` has changed when using the `--config`/`--ignore-path` options + +Up until now, ESLint has resolved the following paths relative to the directory path of the _entry_ configuration file: + +- Configuration files (`.eslintrc.*`) + - relative paths in the `overrides[].files` setting + - relative paths in the `overrides[].excludedFiles` setting + - paths which start with `/` in the `ignorePatterns` setting +- Ignore files (`.eslintignore`) + - paths which start with `/` + +Starting in ESLint v7.0.0, configuration files and ignore files passed to ESLint using the `--config path/to/a-config` and `--ignore-path path/to/a-ignore` CLI flags, respectively, will resolve from the current working directory rather than the file location. This allows for users to utilize shared plugins without having to install them directly in their project. + +**To address:** Update the affected paths if you are using a configuration or ignore file via the `--config` or `--ignore-path` CLI options. + +**Related issue(s):** [RFC37](https://github.com/eslint/rfcs/blob/master/designs/2019-changing-base-path-in-config-files-that-cli-options-specify/README.md), [#12887](https://github.com/eslint/eslint/pull/12887) + +## Plugin resolution has been updated + +In previous versions, ESLint resolved all plugins from the current working directory by default. + +Starting in ESLint v7.0.0, `plugins` are resolved relative to the directory path of the _entry_ configuration file. + +This will not change anything in most cases. If a configuration file in a subdirectory has `plugins` defined, the plugins will be loaded from the subdirectory (or ancestor directories that include the current working directory if not found). + +This means that if you are using a config file from a shared location via `--config` option, the plugins that the config file declare will be loaded from the shared config file location. + +**To address:** Ensure that plugins are installed in a place that can be resolved relative to your configuration file or use `--resolve-plugins-relative-to .` to override this change. + +**Related issue(s):** [RFC47](https://github.com/eslint/rfcs/blob/master/designs/2019-plugin-loading-improvement/README.md), [#12922](https://github.com/eslint/eslint/pull/12922) + +## Runtime deprecation warnings for `~/.eslintrc.*` config files + +Personal config files have been deprecated since [v6.7.0](https://eslint.org/blog/2019/11/eslint-v6.7.0-released). ESLint v7.0.0 will start printing runtime deprecation warnings. It will print a warning for the following situations: + +1. When a project does not have a configuration file present and ESLint loads configuration from `~/.eslintrc.*`. +1. When a project has a configuration file and ESLint ignored a `~/.eslintrc.*` configuration file. This occurs when the `$HOME` directory is an ancestor directory of the project and the project's configuration files doesn't contain `root:true`. + +**To address:** Remove `~/.eslintrc.*` configuration files and add a `.eslintrc.*` configuration file to your project. Alternatively, use the `--config` option to use shared config files. + +**Related issue(s):** [RFC32](https://github.com/eslint/rfcs/tree/master/designs/2019-deprecating-personal-config/README.md), [#12678](https://github.com/eslint/eslint/pull/12678) + +## Default ignore patterns have changed + +Up until now, ESLint has ignored the following files by default: + +- Dotfiles (`.*`) +- `node_modules` in the current working directory (`/node_modules/*`) +- `bower_components` in the current working directory (`/bower_components/*`) + +ESLint v7.0.0 ignores `node_modules/*` of subdirectories as well, but no longer ignores `bower_components/*` and `.eslintrc.js`. Therefore, the new default ignore patterns are: + +- Dotfiles except `.eslintrc.*` (`.*` but not `.eslintrc.*`) +- `node_modules` (`/**/node_modules/*`) + +**To address:** Modify your `.eslintignore` or the `ignorePatterns` property of your config file if you don't want to lint `bower_components/*` and `.eslintrc.js`. + +**Related issue(s):** [RFC51](https://github.com/eslint/rfcs/blob/master/designs/2019-update-default-ignore-patterns/README.md), [#12888](https://github.com/eslint/eslint/pull/12888) + +## Descriptions in directive comments + +In older version of ESLint, there was no convenient way to indicate why a directive comment – such as `/*eslint-disable*/` – was necessary. + +To allow for the colocation of comments that provide context with the directive, ESLint v7.0.0 adds the ability to append arbitrary text in directive comments by ignoring text following `--` surrounded by whitespace. For example: + +```js +// eslint-disable-next-line a-rule, another-rule -- those are buggy!! +``` + +**To address:** If you have `--` surrounded by whitespace in directive comments, consider moving it into your configuration file. + +**Related issue(s):** [RFC33](https://github.com/eslint/rfcs/blob/master/designs/2019-description-in-directive-comments/README.md), [#12699](https://github.com/eslint/eslint/pull/12699) + +## Node.js/CommonJS rules have been deprecated + +The ten Node.js/CommonJS rules in core have been deprecated and moved to the [eslint-plugin-node](https://github.com/mysticatea/eslint-plugin-node) plugin. + +**To address:** As per [our deprecation policy](https://eslint.org/docs/user-guide/rule-deprecation), the deprecated rules will remain in core for the foreseeable future and are still available for use. However, we will no longer be updating or fixing any bugs in those rules. To use a supported version of the rules, we recommend using the corresponding rules in the plugin instead. + +| Deprecated Rules | Replacement | +| :--------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------ | +| [callback-return](https://eslint.org/docs/rules/callback-return) | [node/callback-return](https://github.com/mysticatea/eslint-plugin-node/blob/v11.1.0/docs/rules/callback-return.md) | +| [global-require](https://eslint.org/docs/rules/global-require) | [node/global-require](https://github.com/mysticatea/eslint-plugin-node/blob/v11.1.0/docs/rules/global-require.md) | +| [handle-callback-err](https://eslint.org/docs/rules/handle-callback-err) | [node/handle-callback-err](https://github.com/mysticatea/eslint-plugin-node/blob/v11.1.0/docs/rules/handle-callback-err.md) | +| [no-mixed-requires](https://eslint.org/docs/rules/no-mixed-requires) | [node/no-mixed-requires](https://github.com/mysticatea/eslint-plugin-node/blob/v11.1.0/docs/rules/no-mixed-requires.md) | +| [no-new-require](https://eslint.org/docs/rules/no-new-require) | [node/no-new-require](https://github.com/mysticatea/eslint-plugin-node/blob/v11.1.0/docs/rules/no-new-require.md) | +| [no-path-concat](https://eslint.org/docs/rules/no-path-concat) | [node/no-path-concat](https://github.com/mysticatea/eslint-plugin-node/blob/v11.1.0/docs/rules/no-path-concat.md) | +| [no-process-env](https://eslint.org/docs/rules/no-process-env) | [node/no-process-env](https://github.com/mysticatea/eslint-plugin-node/blob/v11.1.0/docs/rules/no-process-env.md) | +| [no-process-exit](https://eslint.org/docs/rules/no-process-exit) | [node/no-process-exit](https://github.com/mysticatea/eslint-plugin-node/blob/v11.1.0/docs/rules/no-process-exit.md) | +| [no-restricted-modules](https://eslint.org/docs/rules/no-restricted-modules) | [node/no-restricted-require](https://github.com/mysticatea/eslint-plugin-node/blob/v11.1.0/docs/rules/no-restricted-require.md) | +| [no-sync](https://eslint.org/docs/rules/no-sync) | [node/no-sync](https://github.com/mysticatea/eslint-plugin-node/blob/v11.1.0/docs/rules/no-sync.md) | + +**Related issue(s):** [#12898](https://github.com/eslint/eslint/pull/12898) + +## Several rules have been updated to cover more cases + +Several rules have been enhanced and now report additional errors: + +- [accessor-pairs](https://eslint.org/docs/rules/accessor-pairs) rule now recognizes class members by default. +- [array-callback-return](https://eslint.org/docs/rules/array-callback-return) rule now recognizes `flatMap` method. +- [computed-property-spacing](https://eslint.org/docs/rules/computed-property-spacing) rule now recognizes class members by default. +- [func-names](https://eslint.org/docs/rules/func-names) rule now recognizes function declarations in default exports. +- [no-extra-parens](https://eslint.org/docs/rules/no-extra-parens) rule now recognizes parentheses in assignment targets. +- [no-dupe-class-members](https://eslint.org/docs/rules/no-dupe-class-members) rule now recognizes computed keys for static class members. +- [no-magic-numbers](https://eslint.org/docs/rules/no-magic-numbers) rule now recognizes bigint literals. +- [radix](https://eslint.org/docs/rules/radix) rule now recognizes invalid numbers for the second parameter of `parseInt()`. +- [use-isnan](https://eslint.org/docs/rules/use-isnan) rule now recognizes class members by default. +- [yoda](https://eslint.org/docs/rules/yoda) rule now recognizes bigint literals. + +**To address:** Fix errors or disable these rules. + +**Related issue(s):** [#12490](https://github.com/eslint/eslint/pull/12490), [#12608](https://github.com/eslint/eslint/pull/12608), [#12670](https://github.com/eslint/eslint/pull/12670), [#12701](https://github.com/eslint/eslint/pull/12701), [#12765](https://github.com/eslint/eslint/pull/12765), [#12837](https://github.com/eslint/eslint/pull/12837), [#12913](https://github.com/eslint/eslint/pull/12913), [#12915](https://github.com/eslint/eslint/pull/12915), [#12919](https://github.com/eslint/eslint/pull/12919) + +## `eslint:recommended` has been updated + +Three new rules have been enabled in the `eslint:recommended` preset. + +- [no-dupe-else-if](https://eslint.org/docs/rules/no-dupe-else-if) +- [no-import-assign](https://eslint.org/docs/rules/no-import-assign) +- [no-setter-return](https://eslint.org/docs/rules/no-setter-return) + +**To address:** Fix errors or disable these rules. + +**Related issue(s):** [#12920](https://github.com/eslint/eslint/pull/12920) + +## Additional validation added to the `RuleTester` class + +The `RuleTester` now validates the following: + +- It fails test cases if the rule under test uses the non-standard `node.start` or `node.end` properties. Rules should use `node.range` instead. +- It fails test cases if the rule under test provides an autofix but a test case doesn't have an `output` property. Add an `output` property to test cases to test the rule's autofix functionality. +- It fails test cases if any unknown properties are found in the objects in the `errors` property. + +**To address:** Modify your rule or test case if existing test cases fail. + +**Related issue(s):** [RFC25](https://github.com/eslint/rfcs/blob/master/designs/2019-rule-tester-improvements/README.md), [#12096](https://github.com/eslint/eslint/pull/12096), [#12955](https://github.com/eslint/eslint/pull/12955) + +## The `CLIEngine` class has been deprecated + +The [`CLIEngine` class](https://eslint.org/docs/developer-guide/nodejs-api#cliengine) has been deprecated and replaced by the new [`ESLint` class](https://eslint.org/docs/developer-guide/nodejs-api#eslint-class). + +The `CLIEngine` class provides a synchronous API that is blocking the implementation of features such as parallel linting, supporting ES modules in shareable configs/parsers/plugins/formatters, and adding the ability to visually display the progress of linting runs. The new `ESLint` class provides an asynchronous API that ESLint core will now using going forward. `CLIEngine` will remain in core for the foreseeable future but may be removed in a future major version. + +**To address:** Update your code to use the new `ESLint` class if you are currently using `CLIEngine`. The following table maps the existing `CLIEngine` methods to their `ESLint` counterparts: + +| `CLIEngine` | `ESLint` | +| :------------------------------------------- | :--------------------------------- | +| `executeOnFiles(patterns)` | `lintFiles(patterns)` | +| `executeOnText(text, filePath, warnIgnored)` | `lintText(text, options)` | +| `getFormatter(name)` | `loadFormatter(name)` | +| `getConfigForFile(filePath)` | `calculateConfigForFile(filePath)` | +| `isPathIgnored(filePath)` | `isPathIgnored(filePath)` | +| `static outputFixes(results)` | `static outputFixes(results)` | +| `static getErrorResults(results)` | `static getErrorResults(results)` | +| `static getFormatter(name)` | (removed ※1) | +| `addPlugin(pluginId, definition)` | the `plugins` constructor option | +| `getRules()` | (not implemented yet) | +| `resolveFileGlobPatterns()` | (removed ※2) | + +- ※1 The `engine.getFormatter()` method currently returns the object of loaded packages as-is, which made it difficult to add new features to formatters for backward compatibility reasons. The new `eslint.loadFormatter()` method returns an adapter object that wraps the object of loaded packages, to ease the process of adding new features. Additionally, the adapter object has access to the `ESLint` instance to calculate default data (using loaded plugin rules to make `rulesMeta`, for example). As a result, the `ESLint` class only implements an instance version of the `loadFormatter()` method. +- ※2 Since ESLint 6, ESLint uses different logic from the `resolveFileGlobPatterns()` method to iterate files, making this method obsolete. + +**Related issue(s):** [RFC40](https://github.com/eslint/rfcs/blob/master/designs/2019-move-to-async-api/README.md), [#12939](https://github.com/eslint/eslint/pull/12939) diff --git a/docs/8.0.0/user-guide/migrating-to-8.0.0.md b/docs/8.0.0/user-guide/migrating-to-8.0.0.md new file mode 100644 index 0000000000..e43e89462f --- /dev/null +++ b/docs/8.0.0/user-guide/migrating-to-8.0.0.md @@ -0,0 +1,305 @@ +--- +title: Migrating to v8.0.0 +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/user-guide/migrating-to-8.0.0.md + +--- + + +# Migrating to v8.0.0 + +ESLint v8.0.0 is a major release of ESLint. We have made a few breaking changes in this release. This guide is intended to walk you through the breaking changes. + +The lists below are ordered roughly by the number of users each change is expected to affect, where the first items are expected to affect the most users. + +## Table of Contents + +### Breaking changes for users + +- [Node.js 10, 13, and 15 are no longer supported](#drop-old-node) +- [Removed `codeframe` and `table` formatters](#removed-formatters) +- [`comma-dangle` rule schema is stricter](#comma-dangle) +- [Unused disable directives are now fixable](#directives) +- [`eslint:recommended` has been updated](#eslint-recommended) + +### Breaking changes for plugin developers + +- [Node.js 10, 13, and 15 are no longer supported](#drop-old-node) +- [Rules require `meta.hasSuggestions` to provide suggestions](#suggestions) +- [Rules require `meta.fixable` to provide fixes](#fixes) +- [`SourceCode#getComments()` fails in `RuleTester`](#get-comments) +- [Changes to shorthand property AST format](#ast-format) + +### Breaking changes for integration developers + +- [Node.js 10, 13, and 15 are no longer supported](#drop-old-node) +- [The `CLIEngine` class has been removed](#remove-cliengine) +- [The `linter` object has been removed](#remove-linter) +- [The `/lib` entrypoint has been removed](#remove-lib) + +--- + +## Node.js 10, 13, and 15 are no longer supported + +Node.js 10, 13, 15 all reached end of life either in 2020 or early 2021. ESLint is officially dropping support for these versions of Node.js starting with ESLint v8.0.0. ESLint now supports the following versions of Node.js: + +- Node.js 12.22 and above +- Node.js 14 and above +- Node.js 16 and above + +**To address:** Make sure you upgrade to at least Node.js `12.22.0` when using ESLint v8.0.0. One important thing to double check is the Node.js version supported by your editor when using ESLint via editor integrations. If you are unable to upgrade, we recommend continuing to use ESLint 7 until you are able to upgrade Node.js. + +**Related issue(s):** [#14023](https://github.com/eslint/eslint/issues/14023) + +## Removed `codeframe` and `table` formatters + +ESLint v8.0.0 has removed the `codeframe` and `table` formatters from the core. These formatters required dependencies that weren't used anywhere else in ESLint, and removing them allows us to reduce the size of ESLint, allowing for faster installation. + +**To address:** If you are using the `codeframe` or `table` formatters, you'll need to install the standalone [`eslint-formatter-codeframe`](https://github.com/fregante/eslint-formatter-codeframe) or [`eslint-formatter-table`](https://github.com/fregante/eslint-formatter-table) packages, respectively, to be able to use them in ESLint v8.0.0. + +**Related issue(s):** [#14277](https://github.com/eslint/eslint/issues/14277), [#14316](https://github.com/eslint/eslint/pull/14316) + + +## `comma-dangle` rule schema is stricter + +In ESLint v7.0.0, the `comma-dangle` rule could be configured like this without error: + +```json +{ + "rules": { + "comma-dangle": ["error", "never", { "arrays": "always" }] + } +} +``` + +With this configuration, the rule would ignore the third element in the array because only the second element is read. In ESLint v8.0.0, this configuration will cause ESLint to throw an error. + +**To address:** Change your rule configuration so that there are only two elements in the array, and the second element is either a string or an object, such as: + +```jsonc +{ + "comma-dangle": ["error", "never"], + // or + "comma-dangle": ["error", { + "arrays": "never", + "objects": "never", + "imports": "never", + "exports": "never", + "functions": "never" + }] +} +``` + +**Related issue(s):** [#13739](https://github.com/eslint/eslint/issues/13739) + +## Unused disable directives are now fixable + +In ESLint v7.0.0, using both `--report-unused-disable-directives` and `--fix` on the command line would fix only rules but leave unused disable directives in place. In ESLint v8.0.0, this combination of command-line options will result in the unused disable directives being removed. + +**To address:** If you are using `--report-unused-disable-directives` and `--fix` together on the command line, and you don't want unused disable directives to be removed, add `--fix-type problem,suggestion,layout` as a command line option. + +**Related issue(s):** [#11815](https://github.com/eslint/eslint/issues/11815) + +## `eslint:recommended` has been updated + +Three new rules have been enabled in the `eslint:recommended` preset. + +- [`no-loss-of-precision`](https://eslint.org/docs/rules/no-loss-of-precision) +- [`no-nonoctal-decimal-escape`](https://eslint.org/docs/rules/no-nonoctal-decimal-escape) +- [`no-unsafe-optional-chaining`](https://eslint.org/docs/rules/no-unsafe-optional-chaining) +- [`no-useless-backreference`](https://eslint.org/docs/rules/no-useless-backreference) + +**To address:** Fix errors or disable these rules. + +**Related issue(s):** [#14673](https://github.com/eslint/eslint/issues/14673) + + +## Rules require `meta.hasSuggestions` to provide suggestions + +In ESLint v7.0.0, rules that [provided suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions) did not need to let ESLint know. In v8.0.0, rules providing suggestions need to set their `meta.hasSuggestions` to `true`. This informs ESLint that the rule intends to provide suggestions. Without this property, any attempt to provide a suggestion will result in an error. + +**To address:** If your rule provides suggestions, add `meta.hasSuggestions` to the object, such as: + +```js +module.exports = { + meta: { + hasSuggestions: true + }, + create(context) { + // your rule + } +}; +``` + +The [eslint-plugin/require-meta-has-suggestions](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/require-meta-has-suggestions.md) rule can automatically fix and enforce that your rules are properly specifying `meta.hasSuggestions`. + +**Related issue(s):** [#14312](https://github.com/eslint/eslint/issues/14312) + +## Rules require `meta.fixable` to provide fixes + +In ESLint v7.0.0, rules that were written as a function (rather than object) were able to provide fixes. In ESLint v8.0.0, only rules written as an object are allowed to provide fixes and must have a `meta.fixable` property set to either `"code"` or `"whitespace"`. + +**To address:** If your rule makes fixes and is written as a function, such as: + +```js +module.exports = function(context) { + // your rule +}; +``` + +Then rewrite your rule in this format: + +```js +module.exports = function(context) { + meta: { + fixable: "code" // or "whitespace" + }, + create(context) { + // your rule + } +}; +``` + +The [eslint-plugin/require-meta-fixable](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/require-meta-fixable.md) rule can automatically fix and enforce that your rules are properly specifying `meta.fixable`. + +The [eslint-plugin/prefer-object-rule](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/prefer-object-rule.md) rule can automatically fix and enforce that your rules are written with the object format instead of the deprecated function format. + +See the [rule documentation](https://eslint.org/docs/developer-guide/working-with-rules) for more information on writing rules. + +**Related issue(s):** [#13349](https://github.com/eslint/eslint/issues/13349) + +## `SourceCode#getComments()` fails in `RuleTester` + +Back in ESLint v4.0.0, we deprecated `SourceCode#getComments()`, but we neglected to remove it. Rather than removing it completely in v8.0.0, we are taking the intermediate step of updating `RuleTester` to fail when `SourceCode#getComments()` is used inside of a rule. As such, all existing rules will continue to work, but when the developer runs tests for the rule there will be a failure. + +The `SourceCode#getComments()` method will be removed in v9.0.0. + +**To address:** If your rule uses `SourceCode#getComments()`, please use [`SourceCode#getCommentsBefore()`, `SourceCode#getCommentsAfter()`, or `SourceCode#getCommentsInside()`](https://eslint.org/docs/developer-guide/working-with-rules#sourcecodegetcommentsbefore-sourcecodegetcommentsafter-and-sourcecodegetcommentsinside). + +**Related issue(s):** [#14744](https://github.com/eslint/eslint/issues/14744) + +## Changes to shorthand property AST format + +ESLint v8.0.0 includes an upgrade to Espree v8.0.0 to support new syntax. This Espree upgrade, in turn, contains an upgrade to Acorn v8.0.0, which changed how shorthand properties were represented in the AST. Here's an example: + +```js +const version = 8; +const x = { + version +}; +``` + +This code creates a property node that looks like this: + +```json +{ + "type": "Property", + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "name": "version" + }, + "kind": "init", + "value": { + "type": "Identifier", + "name": "version" + } +} +``` + +Note that both the `key` and the `value` properties contain the same information. Prior to Acorn v8.0.0 (and therefore prior to ESLint v8.0.0), these two nodes were represented by the same object, so you could use `===` to determine if they represented the same node, such as: + +```js +// true in ESLint v7.x, false in ESLint v8.0.0 +if (propertyNode.key === propertyNode.value) { + // do something +} +``` + +In ESLint v8.0.0 (via Acorn v8.0.0), the key and value are now separate objects and therefore no longer equivalent. + +**To address:** If your rule makes a comparison between the key and value of a shorthand object literal property to determine if they are the same node, you'll need to change your code in one of two ways: + +1. Use `propertyNode.shorthand` to determine if the property is a shorthand property node. +1. Use the `range` property of each node to determine if the key and value occupy the same location. + +**Related issue(s):** [#14591](https://github.com/eslint/eslint/pull/14591#issuecomment-887733070) + + +## The `CLIEngine` class has been removed + +The `CLIEngine` class has been removed and replaced by the [`ESLint` class](https://eslint.org/docs/developer-guide/nodejs-api#eslint-class). + +**To address:** Update your code to use the new `ESLint` class if you are currently using `CLIEngine`. The following table maps the existing `CLIEngine` methods to their `ESLint` counterparts: + +| `CLIEngine` | `ESLint` | +| :------------------------------------------- | :--------------------------------- | +| `executeOnFiles(patterns)` | `lintFiles(patterns)` | +| `executeOnText(text, filePath, warnIgnored)` | `lintText(text, options)` | +| `getFormatter(name)` | `loadFormatter(name)` | +| `getConfigForFile(filePath)` | `calculateConfigForFile(filePath)` | +| `isPathIgnored(filePath)` | `isPathIgnored(filePath)` | +| `static outputFixes(results)` | `static outputFixes(results)` | +| `static getErrorResults(results)` | `static getErrorResults(results)` | +| `static getFormatter(name)` | (removed ※1) | +| `addPlugin(pluginId, definition)` | the `plugins` constructor option | +| `getRules()` | (removed ※2) | +| `resolveFileGlobPatterns()` | (removed ※3) | + +- ※1 The `engine.getFormatter()` method currently returns the object of loaded packages as-is, which made it difficult to add new features to formatters for backward compatibility reasons. The new `eslint.loadFormatter()` method returns an adapter object that wraps the object of loaded packages, to ease the process of adding new features. Additionally, the adapter object has access to the `ESLint` instance to calculate default data (using loaded plugin rules to make `rulesMeta`, for example). As a result, the `ESLint` class only implements an instance version of the `loadFormatter()` method. +- ※2 The `CLIEngine#getRules()` method had side effects and so was removed. If you were using `CLIEngine#getRules()` to retrieve meta information about rules based on linting results, use `ESLint#getRulesMetaForResults()` instead. If you were using `CLIEngine#getRules()` to retrieve all built-in rules, import `builtinRules` from `eslint/use-at-your-own-risk` for an unsupported API that allows access to internal rules. +- ※3 Since ESLint v6.0.0, ESLint uses different logic from the `resolveFileGlobPatterns()` method to iterate files, making this method obsolete. + +**Related issue(s):** [RFC80](https://github.com/eslint/rfcs/tree/main/designs/2021-package-exports), [#14716](https://github.com/eslint/eslint/pull/14716), [#13654](https://github.com/eslint/eslint/issues/13654) + +## The `linter` object has been removed + +The deprecated `linter` object has been removed from the ESLint package in v8.0.0. + +**To address:** If you are using the `linter` object, such as: + +```js +const { linter } = require("eslint"); +``` + +Change your code to this: + +```js +const { Linter } = require("eslint"); +const linter = new Linter(); +``` + +**Related issue(s):** [RFC80](https://github.com/eslint/rfcs/tree/main/designs/2021-package-exports), [#14716](https://github.com/eslint/eslint/pull/14716), [#13654](https://github.com/eslint/eslint/issues/13654) + +## The `/lib` entrypoint has been removed + +Beginning in v8.0.0, ESLint is strictly defining its public API. Previously, you could reach into individual files such as `require("eslint/lib/rules/semi")` and this is no longer allowed. There are a limited number of existing APIs that are now available through the `/use-at-your-own-risk` entrypoint for backwards compatibility, but these APIs are not formally supported and may break or disappear at any point in time. + +**To address:** If you are accessing rules directly through the `/lib` entrypoint, such as: + +```js +const rule = require("eslint/lib/rules/semi"); +``` + +Change your code to this: + +```js +const { builtinRules } = require("eslint/use-at-your-own-risk"); +const rule = builtinRules.get("semi"); +``` + +If you are accessing `FileEnumerator` directly through the `/lib` entrypoint, such as: + +```js +const { FileEnumerator } = require("eslint/lib/cli-engine/file-enumerator"); +``` + +Change your code to this: + +```js +const { FileEnumerator } = require("eslint/use-at-your-own-risk"); +``` + +**Related issue(s):** [RFC80](https://github.com/eslint/rfcs/tree/main/designs/2021-package-exports), [#14716](https://github.com/eslint/eslint/pull/14716), [#13654](https://github.com/eslint/eslint/issues/13654) diff --git a/docs/8.0.0/user-guide/rule-deprecation.md b/docs/8.0.0/user-guide/rule-deprecation.md new file mode 100644 index 0000000000..25785e67a0 --- /dev/null +++ b/docs/8.0.0/user-guide/rule-deprecation.md @@ -0,0 +1,21 @@ +--- +title: Rule Deprecation +layout: doc +edit_link: https://github.com/eslint/eslint/edit/master/docs/user-guide/rule-deprecation.md + +--- + + +# Rule Deprecation + +Balancing the trade-offs of improving a tool and the frustration these changes can cause is a difficult task. One key area in which this affects our users is in the removal of rules. + +The ESLint team is committed to making upgrading as easy and painless as possible. To that end, the team has agreed upon the following set of guidelines for deprecating rules in the future. The goal of these guidelines is to allow for improvements and changes to be made without breaking existing configurations. + +* Rules will never be removed from ESLint. +* Rules will be deprecated as needed, and marked as such in all documentation. +* After a rule has been deprecated, the team will no longer do any work on it. This includes bug fixes, enhancements, and updates to the rule's documentation. Issues and pull requests related to deprecated rule will not be accepted and will be closed. + +Since deprecated rules will never be removed, you can continue to use them indefinitely if they are working for you. However, keep in mind that deprecated rules will effectively be unmaintained. + +We hope that by following these guidelines we will be able to continue improving and working to make ESLint the best tool it can be while causing as little disruption to our users as possible during the process. diff --git a/docs/developer-guide/code-conventions.md b/docs/developer-guide/code-conventions.md index 7c0271514f..2166df61c2 100644 --- a/docs/developer-guide/code-conventions.md +++ b/docs/developer-guide/code-conventions.md @@ -8,926 +8,10 @@ edit_link: https://github.com/eslint/eslint/edit/master/docs/developer-guide/cod # Code Conventions -Programming language style guides are important for the long-term maintainability of software. This guide is based on the [Code Conventions for the Java Programming Language](https://java.sun.com/docs/codeconv/) and [Douglas Crockford's Code Conventions for the JavaScript Programming Language](http://javascript.crockford.com/code.html). Modifications have been made due to my personal experience and preferences. +Code conventions for ESLint are determined by +[eslint-config-eslint](https://www.npmjs.com/package/eslint-config-eslint). -## File Format - -Each file has this same basic format: - -```js -/** - * @fileoverview Description of the file - * @author Your Name - */ - -"use strict"; - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - -// require() statements - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -// private methods/data - -//------------------------------------------------------------------------------ -// Public Interface -//------------------------------------------------------------------------------ - -// exported objects/methods -module.exports = { - -}; -``` - -The `@author` field gives you credit for having created the file. - -## Indentation - -Each indentation level is made up of four spaces. Do not use tabs. - - // Good - if (true) { - doSomething(); - } - -## Primitive Literals - -Strings should always use double quotes (never single quotes) and should always appear on a single line. Never use a slash to create a new line in a string. - - // Good - var name = "Nicholas"; - - // Bad: Single quotes - var name = 'Nicholas'; - - // Bad: Wrapping to second line - var longString = "Here's the story, of a man \ - named Brady."; - -Numbers should be written as decimal integers, e-notation integers, hexadecimal integers or floating-point decimals with at least one digit before and one digit after the decimal point. Never use octal literals. - - // Good - var count = 10; - - // Good - var price = 10.0; - var price = 10.00; - - // Good - var num = 0xA2; - - // Good - var num = 1e23; - - // Bad: Hanging decimal point - var price = 10.; - - // Bad: Leading decimal point - var price = .1; - - // Bad: Octal (base 8) is deprecated - var num = 010; - -The special value `null` should be used only in the following situations: - -1. To initialize a variable that may later be assign an object value. -1. To compare against an initialized variable that may or may not have an object value. -1. To pass into a function where an object is expected. -1. To return from a function where an object is expected. - -Examples: - - // Good - var person = null; - - // Good - function getPerson() { - if (condition) { - return new Person("Nicholas"); - } else { - return null; - } - } - - // Good - var person = getPerson(); - if (person !== null){ - doSomething(); - } - - // Bad: Testing against uninitialized variable - var person; - if (person != null){ - doSomething(); - } - - // Bad: Testing to see if an argument was passed - function doSomething(arg1, arg2, arg3, arg4){ - if (arg4 != null){ - doSomethingElse(); - } - } - -Never use the special value `undefined`. To see if a variable has been defined, use the `typeof` operator: - - // Good - if (typeof variable == "undefined") { - // do something - } - - // Bad: Using undefined literal - if (variable == undefined) { - // do something - } - -## Operator Spacing - -Operators with two operands must be preceded and followed by a single space to make the expression clear. Operators include assignments and logical operators. - - // Good - var found = (values[i] === item); - - // Good - if (found && (count > 10)) { - doSomething(); - } - - // Good - for (i = 0; i < count; i++) { - process(i); - } - - // Bad: Missing spaces - var found = (values[i]===item); - - // Bad: Missing spaces - if (found&&(count>10)) { - doSomething(); - } - - // Bad: Missing spaces - for (i=0; i 10)) { - doSomething(); - } - - // Good - for (i = 0; i < count; i++) { - process(i); - } - - // Bad: Extra space after opening paren - var found = ( values[i] === item); - - // Bad: Extra space before closing paren - if (found && (count > 10) ) { - doSomething(); - } - - // Bad: Extra space around argument - for (i = 0; i < count; i++) { - process( i ); - } - -## Object Literals - -Object literals should have the following format: - -* The opening brace should be on the same line as the containing statement. -* Each property-value pair should be indented one level with the first property appearing on the next line after the opening brace. -* Each property-value pair should have an unquoted property name, followed by a colon (no space preceding it), followed by the value. -* If the value is a function, it should wrap under the property name and should have a blank line both before and after the function. -* Additional empty lines may be inserted to group related properties or otherwise improve readability. -* The closing brace should be on a separate line. - -Examples: - - // Good - var object = { - - key1: value1, - key2: value2, - - func: function() { - // do something - }, - - key3: value3 - }; - - // Bad: Improper indentation - var object = { - key1: value1, - key2: value2 - }; - - // Bad: Missing blank lines around function - var object = { - - key1: value1, - key2: value2, - func: function() { - // do something - }, - key3: value3 - }; - -When an object literal is passed to a function, the opening brace should be on the same line as if the value is a variable. All other formatting rules from above still apply. - - // Good - doSomething({ - key1: value1, - key2: value2 - }); - - // Bad: All on one line - doSomething({ key1: value1, key2: value2 }); - -## Comments - -Make frequent use of comments to aid others in understanding your code. Use comments when: - -* Code is difficult to understand. -* The code might be mistaken for an error. -* Browser-specific code is necessary but not obvious. -* Documentation generation is necessary for an object, method, or property (use appropriate documentation comments). - -### Single-Line Comments - -Single-line comments should be used to document one line of code or a group of related lines of code. A single-line comment may be used in three ways: - -1. On a separate line, describing the code beneath it. -1. At the end of a line, describing the code before it. -1. On multiple lines, to comment out sections of code. - -When on a separate line, a single-line comment should be at the same indentation level as the code it describes and be preceded by a single line. Never use multiple single-line comments on consecutive lines, use a multi-line comment instead. - - // Good - if (condition){ - - // if you made it here, then all security checks passed - allowed(); - } - - // Bad: No empty line preceding comment - if (condition){ - // if you made it here, then all security checks passed - allowed(); - } - - // Bad: Wrong indentation - if (condition){ - - // if you made it here, then all security checks passed - allowed(); - } - - // Bad: This should be a multi-line comment - // This next piece of code is quite difficult, so let me explain. - // What you want to do is determine if the condition is true - // and only then allow the user in. The condition is calculated - // from several different functions and may change during the - // lifetime of the session. - if (condition){ - // if you made it here, then all security checks passed - allowed(); - } - -For single-line comments at the end of a line, ensure there is at least one indentation level between the end of the code and the beginning of the comment: - - // Good - var result = something + somethingElse; // somethingElse will never be null - - // Bad: Not enough space between code and comment - var result = something + somethingElse;// somethingElse will never be null - -The only acceptable time to have multiple single-line comments on successive lines is to comment out large sections of code. Multi-line comments should not be used for this purpose. - - // Good - // if (condition){ - // doSomething(); - // thenDoSomethingElse(); - // } - -### Multi-Line Comments - -Multi-line comments should be used to document code that requires more explanation. Each multi-line comment should have at least three lines: - -1. The first line contains only the `/*` comment opening. No further text is allowed on this line. -1. The next line(s) have a `*` aligned with the `*` in the first line. Text is allowed on these lines. -1. The last line has the `*/` comment opening aligned with the preceding lines. No other text is allowed on this line. - -The first line of multi-comments should be indented to the same level as the code it describes. Each subsequent line should have the same indentation plus one space (for proper alignment of the `*` characters). Each multi-line comment should be preceded by one empty line. - - // Good - if (condition){ - - /* - * if you made it here, - * then all security checks passed - */ - allowed(); - } - - // Bad: No empty line preceding comment - if (condition){ - /* - * if you made it here, - * then all security checks passed - */ - allowed(); - } - - // Bad: Missing a space after asterisk - if (condition){ - - /* - *if you made it here, - *then all security checks passed - */ - allowed(); - } - - // Bad: Wrong indentation - if (condition){ - - /* - * if you made it here, - * then all security checks passed - */ - allowed(); - } - - // Bad: Don't use multi-line comments for trailing comments - var result = something + somethingElse; /*somethingElse will never be null*/ - -### Comment Annotations - -Comments may be used to annotate pieces of code with additional information. These annotations take the form of a single word followed by a colon. The acceptable annotations are: - -* `TODO` - indicates that the code is not yet complete. Information about the next steps should be included. -* `HACK` - indicates that the code is using a shortcut. Information about why the hack is being used should be included. This may also indicate that it would be nice to come up with a better way to solve the problem. -* `XXX` - indicates that the code is problematic and should be fixed as soon as possible. -* `FIXME` - indicates that the code is problematic and should be fixed soon. Less important than `XXX`. -* `REVIEW` - indicates that the code needs to be reviewed for potential changes. - -These annotations may be used with either single-line or multi-line comments and should follow the same formatting rules as the general comment type. Examples: - - // Good - // TODO: I'd like to find a way to make this faster - doSomething(); - - // Good - /* - * HACK: Have to do this for IE. I plan on revisiting in - * the future when I have more time. This probably should - * get replaced before v1.2. - */ - if (document.all) { - doSomething(); - } - - // Good - // REVIEW: Is there a better way to do this? - if (document.all) { - doSomething(); - } - - // Bad: Annotation spacing is incorrect - // TODO : I'd like to find a way to make this faster - doSomething(); - - // Bad: Comment should be at the same indentation as code - // REVIEW: Is there a better way to do this? - if (document.all) { - doSomething(); - } - - -## Variable Declarations - -All variables should be declared before they are used. Variable declarations should take place at the beginning of a function using a single `var` statement with one variable per line. All lines after the first should be indented one level so the variable names line up. Variables should be initialized when declared if applicable and the equals operator should be at a consistent indentation level. Initialized variables should come first followed by uninitialized variables. - - // Good - var count = 10, - name = "Nicholas", - found = false, - empty; - - // Bad: Improper initialization alignment - var count = 10, - name = "Nicholas", - found= false, - empty; - - // Bad: Incorrect indentation - var count = 10, - name = "Nicholas", - found = false, - empty; - - // Bad: Multiple declarations on one line - var count = 10, name = "Nicholas", - found = false, empty; - - // Bad: Uninitialized variables first - var empty, - count = 10, - name = "Nicholas", - found = false; - - // Bad: Multiple var statements - var count = 10, - name = "Nicholas"; - - var found = false, - empty; - -Always declare variables. Implied globals should not be used. - -## Function Declarations - -Functions should be declared before they are used. When a function is not a method (not attached to an object) it should be defined using function declaration format (not function expression format nor using the `Function` constructor). There should be no space between the function name and the opening parentheses. There should be one space between the closing parentheses and the right brace. The right brace should be on the same line as the `function` keyword. There should be no space after the opening parentheses or before the closing parentheses. Named arguments should have a space after the comma but not before it. The function body should be indented one level. - - // Good - function doSomething(arg1, arg2) { - return arg1 + arg2; - } - - // Bad: Improper spacing of first line - function doSomething (arg1, arg2){ - return arg1 + arg2; - } - - // Bad: Function expression - var doSomething = function(arg1, arg2) { - return arg1 + arg2; - }; - - // Bad: Left brace on wrong line - function doSomething(arg1, arg2) - { - return arg1 + arg2; - } - - // Bad: Using Function constructor - var doSomething = new Function("arg1", "arg2", "return arg1 + arg2"); - -Functions declared inside of other functions should be declared immediately after the `var` statement. - - // Good - function outer() { - - var count = 10, - name = "Nicholas", - found = false, - empty; - - function inner() { - // code - } - - // code that uses inner() - } - - // Bad: Inner function declared before variables - function outer() { - - function inner() { - // code - } - - var count = 10, - name = "Nicholas", - found = false, - empty; - - // code that uses inner() - } - -Anonymous functions may be used for assignment of object methods or as arguments to other functions. There should be no space between the `function` keyword and the opening parentheses. - - // Good - object.method = function() { - // code - }; - - // Bad: Incorrect spacing - object.method = function () { - // code - }; - -Immediately-invoked functions should surround the entire function call with parentheses. - - // Good - var value = (function() { - - // function body - - return { - message: "Hi" - } - }()); - - // Bad: No parentheses around function call - var value = function() { - - // function body - - return { - message: "Hi" - } - }(); - - // Bad: Improper parentheses placement - var value = (function() { - - // function body - - return { - message: "Hi" - } - })(); - -## Naming - -Care should be taken to name variables and functions properly. Names should be limited to alphanumeric characters and, in some cases, the underscore character. Do not use the dollar sign (`$`) or back slash (`\`) characters in any names. - -Variable names should be formatted in camel case with the first letter being lowercase and the first letter of each subsequent word being uppercase. The first word of a variable name should be a noun (not a verb) to avoid confusion with functions. Do not use underscore for variable names. - - // Good - var accountNumber = "8401-1"; - - // Bad: Begins with uppercase letter - var AccountNumber = "8401-1"; - - // Bad: Begins with verb - var getAccountNumber = "8401-1"; - - // Bad: Uses underscore - var account_number = "8401-1"; - -Function names should also be formatted using camel case. The first word of a function name should be a verb (not a noun) to avoid confusion with variables. Do not use underscore for function names. - - // Good - function doSomething() { - // code - } - - // Bad: Begins with uppercase letter - function DoSomething() { - // code - } - - // Bad: Begins with noun - function car() { - // code - } - - // Bad: Uses underscores - function do_something() { - // code - } - -Constructor functions, those functions used with the `new` operator to create new objects, should be formatted in camel case but must begin with an uppercase letter. Constructor function names should begin with a non-verb because `new` is the action of creating an object instance. - - // Good - function MyObject() { - // code - } - - // Bad: Begins with lowercase letter - function myObject() { - // code - } - - // Bad: Uses underscores - function My_Object() { - // code - } - - // Bad: Begins with verb - function getMyObject() { - // code - } - -Variables that act as constants (values that won't be changed) should be formatted using all uppercase letters with words separated by a single underscore. - - // Good - var TOTAL_COUNT = 10; - - // Bad: Camel case - var totalCount = 10; - - // Bad: Mixed case - var total_COUNT = 10; - -Object properties follow the same naming conventions as variables. Object methods follow the same naming conventions as functions. If a property or method is meant to be private, then it should be prefixed with an underscore character. - - // Good - var object = { - _count: 10, - - _getCount: function () { - return this._count; - } - }; - -## Strict Mode - -Strict mode should be used in all modules, specified below the file overview comment and above everything else: - - // Bad: Strict mode in functions - function doSomething() { - "use strict"; - - // code - } - - // Bad: Strict mode in global scope and redundant strict mode directive in function - "use strict"; // This one is good - - function doSomething() { - "use strict"; // This one is bad - - // code - } - - // Good: Global strict mode - "use strict"; - - function doSomething() { - // no "use strict" here - - // code - } - -## Assignments - -When assigning a value to a variable, use parentheses around a right-side expression that contains a comparison. - - // Good - var flag = (i < count); - - // Bad: Missing parentheses - var flag = i < count; - -## Equality Operators - -Use `===` and `!==` instead of `==` and `!=`. This avoids type coercion errors. - - // Good - var same = (a === b); - - // Bad: Using == - var same = (a == b); - -## Ternary Operator - -The ternary operator should be used only for assigning values conditionally and never as a shortcut for an `if` statement. - - // Good - var value = condition ? value1 : value2; - - // Bad: no assignment, should be an if statement - condition ? doSomething() : doSomethingElse(); - -## Statements - -### Simple Statements - -Each line should contain at most one statement. All simple statements should end with a semicolon (`;`). - - // Good - count++; - a = b; - - // Bad: Multiple statements on one line - count++; a = b; - -### return Statement - -A return statement with a value should not use parentheses unless they make the return value more obvious in some way. Example: - - return; - - return collection.size(); - - return (size > 0 ? size : defaultSize); - -### Compound Statements - -Compound statements are lists of statements enclosed inside of braces. - -* The enclosed statements should be indented one more level than the compound statement. -* The opening brace should be at the end of the line that begins the compound statement; the closing brace should begin a line and be indented to the beginning of the compound statement. -* Braces are used around all statements, even single statements, when they are part of a control structure, such as a `if` or `for` statement. This makes it easier to add statements without accidentally introducing bugs due to forgetting to add braces. -* The statement beginning keyword, such as `if`, should be followed by one space and the opening brace should be preceded by a space. - -### if Statement - -The `if` class of statements should have the following form: - - if (condition) { - statements - } - - if (condition) { - statements - } else { - statements - } - - if (condition) { - statements - } else if (condition) { - statements - } else { - statements - } - -It is never permissible to omit the braces in any part of an `if` statement. - - // Good - if (condition) { - doSomething(); - } - - // Bad: Improper spacing - if(condition){ - doSomething(); - } - - // Bad: Missing braces - if (condition) - doSomething(); - - // Bad: All on one line - if (condition) { doSomething(); } - - // Bad: All on one line without braces - if (condition) doSomething(); - -### for Statement - -The `for` class of statements should have the following form: - - for (initialization; condition; update) { - statements - } - - for (variable in object) { - statements - } - -Variables should not be declared in the initialization section of a `for` statement. - - // Good - var i, - len; - - for (i=0, len=10; i < len; i++) { - // code - } - - // Bad: Variables declared during initialization - for (var i=0, len=10; i < len; i++) { - // code - } - - // Bad: Variables declared during initialization - for (var prop in object) { - // code - } - -When using a `for-in` statement, double-check whether or not you need to use `hasOwnProperty()` to filter out object members. - -### while Statement - -The `while` class of statements should have the following form: - - while (condition) { - statements - } - -### do Statement - -The `do` class of statements should have the following form: - - do { - statements - } while (condition); - -Note the use of a semicolon as the final part of this statement. There should be a space before and after the `while` keyword. - -### switch Statement - -The `switch` class of statements should have the following form: - - switch (expression) { - case expression: - statements - - default: - statements - } - -Each `case` is indented one level under the `switch`. Each `case` after the first, including `default`, should be preceded by a single empty line. - -Each group of statements (except the default) should end with `break`, `return`, `throw`, or a comment indicating fall through. - - // Good - switch (value) { - case 1: - /* falls through */ - - case 2: - doSomething(); - break; - - case 3: - return true; - - default: - throw new Error("This shouldn't happen.); - } - -If a `switch` doesn't have a `default` case, then it should be indicated with a comment. - - // Good - switch (value) { - case 1: - /*falls through*/ - - case 2: - doSomething(); - break; - - case 3: - return true; - - // no default - } - -### try Statement - -The `try` class of statements should have the following form: - - try { - statements - } catch (variable) { - statements - } - - try { - statements - } catch (variable) { - statements - } finally { - statements - } - -## Whitespace - -Blank lines improve readability by setting off sections of code that are logically related. - -Two blank lines should always be used in the following circumstances: - -* Between sections of a source file -* Between class and interface definitions - -One blank line should always be used in the following circumstances: - -* Between methods -* Between the local variables in a method and its first statement -* Before a multi-line or single-line comment -* Between logical sections inside a method to improve readability - -Blank spaces should be used in the following circumstances: - -* A keyword followed by a parenthesis should be separated by a space. -* A blank space should appear after commas in argument lists. -* All binary operators except dot (`.`) should be separated from their operands by spaces. Blank spaces should never separate unary operators such as unary minus, increment (`++`), and decrement (`--`) from their operands. -* The expressions in a `for` statement should be separated by blank spaces. Blank spaces should only be used after semicolons, not before. - -## Things to Avoid - -* Never use the primitive wrapper types, such as `String`, to create new objects. -* Never use `eval()`. -* Never use the `with` statement. This statement isn't available in strict mode and likely won't be available in future ECMAScript editions. +The rationales for the specific rules in use can be found by looking to the +project documentation for any given rule. If the rule is one of our own, see +our own [rule documentation](https://eslint.org/docs/rules/) and otherwise, see +the documentation of the plugin in which the rule can be found. diff --git a/docs/developer-guide/nodejs-api.md b/docs/developer-guide/nodejs-api.md index c1b6cf19c3..9f368e5467 100644 --- a/docs/developer-guide/nodejs-api.md +++ b/docs/developer-guide/nodejs-api.md @@ -363,7 +363,9 @@ The `LintResult` value is the information of the linting result of each file. Th * `fixableWarningCount` (`number`)
    The number of warnings that can be fixed automatically by the `fix` constructor option. * `errorCount` (`number`)
    - The number of errors. This includes fixable errors. + The number of errors. This includes fixable errors and fatal errors. +* `fatalErrorCount` (`number`)
    + The number of fatal errors. * `warningCount` (`number`)
    The number of warnings. This includes fixable warnings. * `output` (`string | undefined`)
    @@ -470,7 +472,7 @@ const codeLines = SourceCode.splitLines(code); The `Linter` object does the actual evaluation of the JavaScript code. It doesn't do any filesystem operations, it simply parses and reports on the code. In particular, the `Linter` object does not process configuration objects or files. The `Linter` is a constructor, and you can create a new instance by passing in the options you want to use. The available options are: -* `cwd` - Path to a directory that should be considered as the current working directory. It is accessible to rules by calling `context.getCwd()` (see [The Context Object](./working-with-rules#The-Context-Object)). If `cwd` is `undefined`, it will be normalized to `process.cwd()` if the global `process` object is defined (for example, in the Node.js runtime) , or `undefined` otherwise. +* `cwd` - Path to a directory that should be considered as the current working directory. It is accessible to rules by calling `context.getCwd()` (see [The Context Object](./working-with-rules#the-context-object)). If `cwd` is `undefined`, it will be normalized to `process.cwd()` if the global `process` object is defined (for example, in the Node.js runtime) , or `undefined` otherwise. For example: diff --git a/docs/developer-guide/working-with-rules.md b/docs/developer-guide/working-with-rules.md index 57741d16c7..43c529f1c8 100644 --- a/docs/developer-guide/working-with-rules.md +++ b/docs/developer-guide/working-with-rules.md @@ -69,7 +69,7 @@ The source file for a rule exports an object with the following properties. * `description` (string) provides the short description of the rule in the [rules index](../rules/) * `category` (string) specifies the heading under which the rule is listed in the [rules index](../rules/) * `recommended` (boolean) is whether the `"extends": "eslint:recommended"` property in a [configuration file](../user-guide/configuring/configuration-files#extending-configuration-files) enables the rule - * `url` (string) specifies the URL at which the full documentation can be accessed + * `url` (string) specifies the URL at which the full documentation can be accessed (enabling code editors to provide a helpful link on highlighted rule violations) * `suggestion` (boolean) specifies whether rules can return suggestions (defaults to false if omitted) In a custom rule or plugin, you can omit `docs` or include any properties that you need in it. diff --git a/docs/rules/README.md b/docs/rules/README.md index eba1b7be8d..02dde724b6 100644 --- a/docs/rules/README.md +++ b/docs/rules/README.md @@ -1,10 +1,10 @@ # Rules -Rules in ESLint are grouped by category to help you understand their purpose. +Rules in ESLint are grouped by category to help you understand their purpose. Each rule has emojis denoting: -No rules are enabled by default. The `"extends": "eslint:recommended"` property in a [configuration file](../user-guide/configuring#extending-configuration-files) enables rules that report common problems, which have a check mark (recommended) below. - -The `--fix` option on the [command line](../user-guide/command-line-interface#fix) automatically fixes problems (currently mostly whitespace) reported by rules which have a wrench (fixable) below. +* (recommended) if the `"extends": "eslint:recommended"` property in a [configuration file](../user-guide/configuring#extending-configuration-files) enables the rule +* (fixable) if some problems reported by the rule are automatically fixable by the `--fix` [command line](../user-guide/command-line-interface#--fix) option +* (hasSuggestions) if some problems reported by the rule are manually fixable by editor [suggestions](../developer-guide/working-with-rules#providing-suggestions) ## Possible Errors diff --git a/docs/rules/index.liquid b/docs/rules/index.liquid index 356ed3f5fa..9e4c1cf1cd 100644 --- a/docs/rules/index.liquid +++ b/docs/rules/index.liquid @@ -4,9 +4,10 @@ layout: doc ---

    Rules

    -

    Rules in ESLint are grouped by type to help you understand their purpose.

    -

    No rules are enabled by default. The "extends": "eslint:recommended" property in a configuration file enables rules that report common problems, which have a check mark (recommended) below.

    -

    The --fix option on the command line automatically fixes problems (currently mostly whitespace) reported by rules which have a wrench (fixable) below.

    +

    Rules in ESLint are grouped by type to help you understand their purpose. Each rule has emojis denoting:

    +

    (recommended) if the "extends": "eslint:recommended" property in a configuration file enables the rule

    +

    (fixable) if some problems reported by the rule are automatically fixable by the --fix command line option

    +

    (hasSuggestions) if some problems reported by the rule are manually fixable by editor suggestions

    {% for type in rules.types %}

    {{ type.displayName }}

    {{ type.description }} @@ -14,6 +15,7 @@ layout: doc + @@ -22,6 +24,7 @@ layout: doc {% if rule.recommended %}(recommended){% endif %} {% if rule.fixable %}(fixable){% endif %} + {% if rule.hasSuggestions %}(hasSuggestions){% endif %} {{ rule.name }} {{ rule.description }} diff --git a/docs/rules/no-eq-null.md b/docs/rules/no-eq-null.md index 94b2d50347..4d0c86de9a 100644 --- a/docs/rules/no-eq-null.md +++ b/docs/rules/no-eq-null.md @@ -48,6 +48,14 @@ while (qux !== null) { } ``` +## Compatibility + +* **JSHint**: This rule corresponds to `eqnull` rule of JSHint. + +## When Not To Use It + +If you want to enforce type-checking operations in general, use the more powerful [eqeqeq](./eqeqeq) instead. + ## Version This rule was introduced in ESLint 0.0.9. diff --git a/docs/rules/no-nonoctal-decimal-escape.md b/docs/rules/no-nonoctal-decimal-escape.md index 25e36cc0f3..cb826d36e3 100644 --- a/docs/rules/no-nonoctal-decimal-escape.md +++ b/docs/rules/no-nonoctal-decimal-escape.md @@ -8,6 +8,8 @@ rule_type: suggestion # Disallow `\8` and `\9` escape sequences in string literals (no-nonoctal-decimal-escape) +(hasSuggestions) Some problems reported by this rule are manually fixable by editor [suggestions](../developer-guide/working-with-rules#providing-suggestions). + Although not being specified in the language until ECMAScript 2021, `\8` and `\9` escape sequences in string literals were allowed in most JavaScript engines, and treated as "useless" escapes: ```js diff --git a/docs/rules/no-unsafe-negation.md b/docs/rules/no-unsafe-negation.md index 673645538d..a268cd82c8 100644 --- a/docs/rules/no-unsafe-negation.md +++ b/docs/rules/no-unsafe-negation.md @@ -10,6 +10,8 @@ rule_type: problem (recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. +(hasSuggestions) Some problems reported by this rule are manually fixable by editor [suggestions](../developer-guide/working-with-rules#providing-suggestions). + Just as developers might type `-a + b` when they mean `-(a + b)` for the negative of a sum, they might type `!key in object` by mistake when they almost certainly mean `!(key in object)` to test that a key is not in an object. `!obj instanceof Ctor` is similar. ## Rule Details diff --git a/docs/rules/no-useless-escape.md b/docs/rules/no-useless-escape.md index d985a018c2..1bbe0e4655 100644 --- a/docs/rules/no-useless-escape.md +++ b/docs/rules/no-useless-escape.md @@ -10,6 +10,8 @@ rule_type: suggestion (recommended) The `"extends": "eslint:recommended"` property in a configuration file enables this rule. +(hasSuggestions) Some problems reported by this rule are manually fixable by editor [suggestions](../developer-guide/working-with-rules#providing-suggestions). + Escaping non-special characters in strings, template literals, and regular expressions doesn't have any effect, as demonstrated in the following example: ```js diff --git a/docs/rules/radix.md b/docs/rules/radix.md index f13cd9431e..96b84747a8 100644 --- a/docs/rules/radix.md +++ b/docs/rules/radix.md @@ -8,6 +8,8 @@ rule_type: suggestion # Require Radix Parameter (radix) +(hasSuggestions) Some problems reported by this rule are manually fixable by editor [suggestions](../developer-guide/working-with-rules#providing-suggestions). + When using the `parseInt()` function it is common to omit the second argument, the radix, and let the function try to determine from the first argument what type of number it is. By default, `parseInt()` will autodetect decimal and hexadecimal (via `0x` prefix). Prior to ECMAScript 5, `parseInt()` also autodetected octal literals, which caused problems because many developers assumed a leading `0` would be ignored. This confusion led to the suggestion that you always use the radix parameter to `parseInt()` to eliminate unintended consequences. So instead of doing this: diff --git a/docs/rules/space-after-keywords.md b/docs/rules/space-after-keywords.md index d5dcb0226c..3f75f9f711 100644 --- a/docs/rules/space-after-keywords.md +++ b/docs/rules/space-after-keywords.md @@ -10,7 +10,7 @@ edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/space-after-k (removed) This rule was **removed** in ESLint v2.0 and replaced by the [keyword-spacing](keyword-spacing) rule. -(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fix) automatically fixed problems reported by this rule. +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#--fix) automatically fixed problems reported by this rule. Some style guides will require or disallow spaces following the certain keywords. diff --git a/docs/rules/space-before-keywords.md b/docs/rules/space-before-keywords.md index 0aaebf62b7..1c3a5ea4af 100644 --- a/docs/rules/space-before-keywords.md +++ b/docs/rules/space-before-keywords.md @@ -10,7 +10,7 @@ edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/space-before- (removed) This rule was **removed** in ESLint v2.0 and **replaced** by the [keyword-spacing](keyword-spacing) rule. -(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fix) automatically fixed problems reported by this rule. +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#--fix) automatically fixed problems reported by this rule. Keywords are syntax elements of JavaScript, such as `function` and `if`. These identifiers have special meaning to the language and so often appear in a different color in code editors. As an important part of the language, style guides often refer to the spacing that should be used around keywords. For example, you might have a style guide that says keywords should be always be preceded by spaces, which would mean `if-else` statements must look like this: diff --git a/docs/rules/space-return-throw-case.md b/docs/rules/space-return-throw-case.md index 71235a82b8..470aacda5e 100644 --- a/docs/rules/space-return-throw-case.md +++ b/docs/rules/space-return-throw-case.md @@ -10,7 +10,7 @@ edit_link: https://github.com/eslint/eslint/edit/master/docs/rules/space-return- (removed) This rule was **removed** in ESLint v2.0 and **replaced** by the [keyword-spacing](keyword-spacing) rule. -(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fix) automatically fixed problems reported by this rule. +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#--fix) automatically fixed problems reported by this rule. Require spaces following `return`, `throw`, and `case`. diff --git a/docs/user-guide/README.md b/docs/user-guide/README.md index 1fcb0dfc12..489f0fe672 100644 --- a/docs/user-guide/README.md +++ b/docs/user-guide/README.md @@ -37,3 +37,4 @@ If you were using a prior version of ESLint, you can get help with the transitio - [migrating-to-5.0.0](migrating-to-5.0.0.md) - [migrating-to-6.0.0](migrating-to-6.0.0.md) - [migrating-to-7.0.0](migrating-to-7.0.0.md) +- [migrating-to-8.0.0](/docs/8.0.0/user-guide/migrating-to-8.0.0.md) diff --git a/docs/user-guide/command-line-interface.md b/docs/user-guide/command-line-interface.md index 93fa05b71a..6b0e79f9c7 100644 --- a/docs/user-guide/command-line-interface.md +++ b/docs/user-guide/command-line-interface.md @@ -89,6 +89,7 @@ Miscellaneous: --init Run config initialization wizard - default: false --env-info Output execution environment information - default: false --no-error-on-unmatched-pattern Prevent errors when pattern is unmatched - default: false + --exit-on-fatal-error Exit with exit code 2 in case of fatal error - default: false --debug Output debugging information -h, --help Show help -v, --version Output the version number @@ -475,6 +476,10 @@ This option outputs information about the execution environment, including the v This option prevents errors when a quoted glob pattern or `--ext` is unmatched. This will not prevent errors when your shell can't match a glob. +#### `--exit-on-fatal-error` + +This option causes ESLint to exit with exit code 2 if one or more fatal parsing errors occur. Without this option, fatal parsing errors are reported as rule violations. + #### `--debug` This option outputs debugging information to the console. This information is useful when you're seeing a problem and having a hard time pinpointing it. The ESLint team may ask for this debugging information to help solve bugs. diff --git a/docs/user-guide/configuring/configuration-files.md b/docs/user-guide/configuring/configuration-files.md index 08c40c4b54..546f7b966e 100644 --- a/docs/user-guide/configuring/configuration-files.md +++ b/docs/user-guide/configuring/configuration-files.md @@ -305,7 +305,7 @@ The `extends` property value can be `"eslint:all"` to enable all core rules in t You might enable all core rules as a shortcut to explore rules and options while you decide on the configuration for a project, especially if you rarely override options or disable rules. The default options for rules are not endorsements by ESLint (for example, the default option for the [`quotes`](https://eslint.org/docs/rules/quotes) rule does not mean double quotes are better than single quotes). -If your configuration extends `eslint:all`, after you upgrade to a newer major or minor version of ESLint, review the reported problems before you use the `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fix), so you know if a new fixable rule will make changes to the code. +If your configuration extends `eslint:all`, after you upgrade to a newer major or minor version of ESLint, review the reported problems before you use the `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#--fix), so you know if a new fixable rule will make changes to the code. Example of a configuration file in JavaScript format: diff --git a/docs/user-guide/formatters/html-formatter-example.html b/docs/user-guide/formatters/html-formatter-example.html index e54464c389..2cc5d1e540 100644 --- a/docs/user-guide/formatters/html-formatter-example.html +++ b/docs/user-guide/formatters/html-formatter-example.html @@ -91,7 +91,7 @@

    ESLint Report

    - 9 problems (5 errors, 4 warnings) - Generated on Fri Jul 02 2021 18:04:52 GMT-0400 (Eastern Daylight Time) + 9 problems (5 errors, 4 warnings) - Generated on Fri Jul 30 2021 18:45:42 GMT-0400 (Eastern Daylight Time)
    diff --git a/docs/user-guide/formatters/index.md b/docs/user-guide/formatters/index.md index 0aa9c7fdb2..ad95eb3f85 100644 --- a/docs/user-guide/formatters/index.md +++ b/docs/user-guide/formatters/index.md @@ -174,12 +174,12 @@ error: Unnecessary semicolon (no-extra-semi) at fullOfProblems.js:7:2: ### json-with-metadata ``` -{"results":[{"filePath":"/var/lib/jenkins/workspace/Releases/eslint Release/eslint/fullOfProblems.js","messages":[{"ruleId":"no-unused-vars","severity":2,"message":"'addOne' is defined but never used.","line":1,"column":10,"nodeType":"Identifier","messageId":"unusedVar","endLine":1,"endColumn":16},{"ruleId":"use-isnan","severity":2,"message":"Use the isNaN function to compare with NaN.","line":2,"column":9,"nodeType":"BinaryExpression","messageId":"comparisonWithNaN","endLine":2,"endColumn":17},{"ruleId":"space-unary-ops","severity":2,"message":"Unexpected space before unary operator '++'.","line":3,"column":16,"nodeType":"UpdateExpression","messageId":"unexpectedBefore","endLine":3,"endColumn":20,"fix":{"range":[57,58],"text":""}},{"ruleId":"semi","severity":1,"message":"Missing semicolon.","line":3,"column":20,"nodeType":"ReturnStatement","messageId":"missingSemi","endLine":4,"endColumn":1,"fix":{"range":[60,60],"text":";"}},{"ruleId":"no-else-return","severity":1,"message":"Unnecessary 'else' after 'return'.","line":4,"column":12,"nodeType":"BlockStatement","messageId":"unexpected","endLine":6,"endColumn":6,"fix":{"range":[0,94],"text":"function addOne(i) {\n if (i != NaN) {\n return i ++\n } \n return\n \n}"}},{"ruleId":"indent","severity":1,"message":"Expected indentation of 8 spaces but found 6.","line":5,"column":1,"nodeType":"Keyword","messageId":"wrongIndentation","endLine":5,"endColumn":7,"fix":{"range":[74,80],"text":" "}},{"ruleId":"consistent-return","severity":2,"message":"Function 'addOne' expected a return value.","line":5,"column":7,"nodeType":"ReturnStatement","messageId":"missingReturnValue","endLine":5,"endColumn":13},{"ruleId":"semi","severity":1,"message":"Missing semicolon.","line":5,"column":13,"nodeType":"ReturnStatement","messageId":"missingSemi","endLine":6,"endColumn":1,"fix":{"range":[86,86],"text":";"}},{"ruleId":"no-extra-semi","severity":2,"message":"Unnecessary semicolon.","line":7,"column":2,"nodeType":"EmptyStatement","messageId":"unexpected","endLine":7,"endColumn":3,"fix":{"range":[93,95],"text":"}"}}],"errorCount":5,"warningCount":4,"fixableErrorCount":2,"fixableWarningCount":4,"source":"function addOne(i) {\n if (i != NaN) {\n return i ++\n } else {\n return\n }\n};"}],"metadata":{"rulesMeta":{"no-else-return":{"type":"suggestion","docs":{"description":"disallow `else` blocks after `return` statements in `if` statements","category":"Best Practices","recommended":false,"url":"https://eslint.org/docs/rules/no-else-return"},"schema":[{"type":"object","properties":{"allowElseIf":{"type":"boolean","default":true}},"additionalProperties":false}],"fixable":"code","messages":{"unexpected":"Unnecessary 'else' after 'return'."}},"indent":{"type":"layout","docs":{"description":"enforce consistent indentation","category":"Stylistic Issues","recommended":false,"url":"https://eslint.org/docs/rules/indent"},"fixable":"whitespace","schema":[{"oneOf":[{"enum":["tab"]},{"type":"integer","minimum":0}]},{"type":"object","properties":{"SwitchCase":{"type":"integer","minimum":0,"default":0},"VariableDeclarator":{"oneOf":[{"oneOf":[{"type":"integer","minimum":0},{"enum":["first","off"]}]},{"type":"object","properties":{"var":{"oneOf":[{"type":"integer","minimum":0},{"enum":["first","off"]}]},"let":{"oneOf":[{"type":"integer","minimum":0},{"enum":["first","off"]}]},"const":{"oneOf":[{"type":"integer","minimum":0},{"enum":["first","off"]}]}},"additionalProperties":false}]},"outerIIFEBody":{"oneOf":[{"type":"integer","minimum":0},{"enum":["off"]}]},"MemberExpression":{"oneOf":[{"type":"integer","minimum":0},{"enum":["off"]}]},"FunctionDeclaration":{"type":"object","properties":{"parameters":{"oneOf":[{"type":"integer","minimum":0},{"enum":["first","off"]}]},"body":{"type":"integer","minimum":0}},"additionalProperties":false},"FunctionExpression":{"type":"object","properties":{"parameters":{"oneOf":[{"type":"integer","minimum":0},{"enum":["first","off"]}]},"body":{"type":"integer","minimum":0}},"additionalProperties":false},"CallExpression":{"type":"object","properties":{"arguments":{"oneOf":[{"type":"integer","minimum":0},{"enum":["first","off"]}]}},"additionalProperties":false},"ArrayExpression":{"oneOf":[{"type":"integer","minimum":0},{"enum":["first","off"]}]},"ObjectExpression":{"oneOf":[{"type":"integer","minimum":0},{"enum":["first","off"]}]},"ImportDeclaration":{"oneOf":[{"type":"integer","minimum":0},{"enum":["first","off"]}]},"flatTernaryExpressions":{"type":"boolean","default":false},"offsetTernaryExpressions":{"type":"boolean","default":false},"ignoredNodes":{"type":"array","items":{"type":"string","not":{"pattern":":exit$"}}},"ignoreComments":{"type":"boolean","default":false}},"additionalProperties":false}],"messages":{"wrongIndentation":"Expected indentation of {{expected}} but found {{actual}}."}},"space-unary-ops":{"type":"layout","docs":{"description":"enforce consistent spacing before or after unary operators","category":"Stylistic Issues","recommended":false,"url":"https://eslint.org/docs/rules/space-unary-ops"},"fixable":"whitespace","schema":[{"type":"object","properties":{"words":{"type":"boolean","default":true},"nonwords":{"type":"boolean","default":false},"overrides":{"type":"object","additionalProperties":{"type":"boolean"}}},"additionalProperties":false}],"messages":{"unexpectedBefore":"Unexpected space before unary operator '{{operator}}'.","unexpectedAfter":"Unexpected space after unary operator '{{operator}}'.","unexpectedAfterWord":"Unexpected space after unary word operator '{{word}}'.","wordOperator":"Unary word operator '{{word}}' must be followed by whitespace.","operator":"Unary operator '{{operator}}' must be followed by whitespace.","beforeUnaryExpressions":"Space is required before unary expressions '{{token}}'."}},"semi":{"type":"layout","docs":{"description":"require or disallow semicolons instead of ASI","category":"Stylistic Issues","recommended":false,"url":"https://eslint.org/docs/rules/semi"},"fixable":"code","schema":{"anyOf":[{"type":"array","items":[{"enum":["never"]},{"type":"object","properties":{"beforeStatementContinuationChars":{"enum":["always","any","never"]}},"additionalProperties":false}],"minItems":0,"maxItems":2},{"type":"array","items":[{"enum":["always"]},{"type":"object","properties":{"omitLastInOneLineBlock":{"type":"boolean"}},"additionalProperties":false}],"minItems":0,"maxItems":2}]},"messages":{"missingSemi":"Missing semicolon.","extraSemi":"Extra semicolon."}},"consistent-return":{"type":"suggestion","docs":{"description":"require `return` statements to either always or never specify values","category":"Best Practices","recommended":false,"url":"https://eslint.org/docs/rules/consistent-return"},"schema":[{"type":"object","properties":{"treatUndefinedAsUnspecified":{"type":"boolean","default":false}},"additionalProperties":false}],"messages":{"missingReturn":"Expected to return a value at the end of {{name}}.","missingReturnValue":"{{name}} expected a return value.","unexpectedReturnValue":"{{name}} expected no return value."}}}}} +{"results":[{"filePath":"/var/lib/jenkins/workspace/Releases/eslint Release/eslint/fullOfProblems.js","messages":[{"ruleId":"no-unused-vars","severity":2,"message":"'addOne' is defined but never used.","line":1,"column":10,"nodeType":"Identifier","messageId":"unusedVar","endLine":1,"endColumn":16},{"ruleId":"use-isnan","severity":2,"message":"Use the isNaN function to compare with NaN.","line":2,"column":9,"nodeType":"BinaryExpression","messageId":"comparisonWithNaN","endLine":2,"endColumn":17},{"ruleId":"space-unary-ops","severity":2,"message":"Unexpected space before unary operator '++'.","line":3,"column":16,"nodeType":"UpdateExpression","messageId":"unexpectedBefore","endLine":3,"endColumn":20,"fix":{"range":[57,58],"text":""}},{"ruleId":"semi","severity":1,"message":"Missing semicolon.","line":3,"column":20,"nodeType":"ReturnStatement","messageId":"missingSemi","endLine":4,"endColumn":1,"fix":{"range":[60,60],"text":";"}},{"ruleId":"no-else-return","severity":1,"message":"Unnecessary 'else' after 'return'.","line":4,"column":12,"nodeType":"BlockStatement","messageId":"unexpected","endLine":6,"endColumn":6,"fix":{"range":[0,94],"text":"function addOne(i) {\n if (i != NaN) {\n return i ++\n } \n return\n \n}"}},{"ruleId":"indent","severity":1,"message":"Expected indentation of 8 spaces but found 6.","line":5,"column":1,"nodeType":"Keyword","messageId":"wrongIndentation","endLine":5,"endColumn":7,"fix":{"range":[74,80],"text":" "}},{"ruleId":"consistent-return","severity":2,"message":"Function 'addOne' expected a return value.","line":5,"column":7,"nodeType":"ReturnStatement","messageId":"missingReturnValue","endLine":5,"endColumn":13},{"ruleId":"semi","severity":1,"message":"Missing semicolon.","line":5,"column":13,"nodeType":"ReturnStatement","messageId":"missingSemi","endLine":6,"endColumn":1,"fix":{"range":[86,86],"text":";"}},{"ruleId":"no-extra-semi","severity":2,"message":"Unnecessary semicolon.","line":7,"column":2,"nodeType":"EmptyStatement","messageId":"unexpected","endLine":7,"endColumn":3,"fix":{"range":[93,95],"text":"}"}}],"errorCount":5,"fatalErrorCount":0,"warningCount":4,"fixableErrorCount":2,"fixableWarningCount":4,"source":"function addOne(i) {\n if (i != NaN) {\n return i ++\n } else {\n return\n }\n};"}],"metadata":{"rulesMeta":{"no-else-return":{"type":"suggestion","docs":{"description":"disallow `else` blocks after `return` statements in `if` statements","category":"Best Practices","recommended":false,"url":"https://eslint.org/docs/rules/no-else-return"},"schema":[{"type":"object","properties":{"allowElseIf":{"type":"boolean","default":true}},"additionalProperties":false}],"fixable":"code","messages":{"unexpected":"Unnecessary 'else' after 'return'."}},"indent":{"type":"layout","docs":{"description":"enforce consistent indentation","category":"Stylistic Issues","recommended":false,"url":"https://eslint.org/docs/rules/indent"},"fixable":"whitespace","schema":[{"oneOf":[{"enum":["tab"]},{"type":"integer","minimum":0}]},{"type":"object","properties":{"SwitchCase":{"type":"integer","minimum":0,"default":0},"VariableDeclarator":{"oneOf":[{"oneOf":[{"type":"integer","minimum":0},{"enum":["first","off"]}]},{"type":"object","properties":{"var":{"oneOf":[{"type":"integer","minimum":0},{"enum":["first","off"]}]},"let":{"oneOf":[{"type":"integer","minimum":0},{"enum":["first","off"]}]},"const":{"oneOf":[{"type":"integer","minimum":0},{"enum":["first","off"]}]}},"additionalProperties":false}]},"outerIIFEBody":{"oneOf":[{"type":"integer","minimum":0},{"enum":["off"]}]},"MemberExpression":{"oneOf":[{"type":"integer","minimum":0},{"enum":["off"]}]},"FunctionDeclaration":{"type":"object","properties":{"parameters":{"oneOf":[{"type":"integer","minimum":0},{"enum":["first","off"]}]},"body":{"type":"integer","minimum":0}},"additionalProperties":false},"FunctionExpression":{"type":"object","properties":{"parameters":{"oneOf":[{"type":"integer","minimum":0},{"enum":["first","off"]}]},"body":{"type":"integer","minimum":0}},"additionalProperties":false},"CallExpression":{"type":"object","properties":{"arguments":{"oneOf":[{"type":"integer","minimum":0},{"enum":["first","off"]}]}},"additionalProperties":false},"ArrayExpression":{"oneOf":[{"type":"integer","minimum":0},{"enum":["first","off"]}]},"ObjectExpression":{"oneOf":[{"type":"integer","minimum":0},{"enum":["first","off"]}]},"ImportDeclaration":{"oneOf":[{"type":"integer","minimum":0},{"enum":["first","off"]}]},"flatTernaryExpressions":{"type":"boolean","default":false},"offsetTernaryExpressions":{"type":"boolean","default":false},"ignoredNodes":{"type":"array","items":{"type":"string","not":{"pattern":":exit$"}}},"ignoreComments":{"type":"boolean","default":false}},"additionalProperties":false}],"messages":{"wrongIndentation":"Expected indentation of {{expected}} but found {{actual}}."}},"space-unary-ops":{"type":"layout","docs":{"description":"enforce consistent spacing before or after unary operators","category":"Stylistic Issues","recommended":false,"url":"https://eslint.org/docs/rules/space-unary-ops"},"fixable":"whitespace","schema":[{"type":"object","properties":{"words":{"type":"boolean","default":true},"nonwords":{"type":"boolean","default":false},"overrides":{"type":"object","additionalProperties":{"type":"boolean"}}},"additionalProperties":false}],"messages":{"unexpectedBefore":"Unexpected space before unary operator '{{operator}}'.","unexpectedAfter":"Unexpected space after unary operator '{{operator}}'.","unexpectedAfterWord":"Unexpected space after unary word operator '{{word}}'.","wordOperator":"Unary word operator '{{word}}' must be followed by whitespace.","operator":"Unary operator '{{operator}}' must be followed by whitespace.","beforeUnaryExpressions":"Space is required before unary expressions '{{token}}'."}},"semi":{"type":"layout","docs":{"description":"require or disallow semicolons instead of ASI","category":"Stylistic Issues","recommended":false,"url":"https://eslint.org/docs/rules/semi"},"fixable":"code","schema":{"anyOf":[{"type":"array","items":[{"enum":["never"]},{"type":"object","properties":{"beforeStatementContinuationChars":{"enum":["always","any","never"]}},"additionalProperties":false}],"minItems":0,"maxItems":2},{"type":"array","items":[{"enum":["always"]},{"type":"object","properties":{"omitLastInOneLineBlock":{"type":"boolean"}},"additionalProperties":false}],"minItems":0,"maxItems":2}]},"messages":{"missingSemi":"Missing semicolon.","extraSemi":"Extra semicolon."}},"consistent-return":{"type":"suggestion","docs":{"description":"require `return` statements to either always or never specify values","category":"Best Practices","recommended":false,"url":"https://eslint.org/docs/rules/consistent-return"},"schema":[{"type":"object","properties":{"treatUndefinedAsUnspecified":{"type":"boolean","default":false}},"additionalProperties":false}],"messages":{"missingReturn":"Expected to return a value at the end of {{name}}.","missingReturnValue":"{{name}} expected a return value.","unexpectedReturnValue":"{{name}} expected no return value."}}}}} ``` ### json ``` -[{"filePath":"/var/lib/jenkins/workspace/Releases/eslint Release/eslint/fullOfProblems.js","messages":[{"ruleId":"no-unused-vars","severity":2,"message":"'addOne' is defined but never used.","line":1,"column":10,"nodeType":"Identifier","messageId":"unusedVar","endLine":1,"endColumn":16},{"ruleId":"use-isnan","severity":2,"message":"Use the isNaN function to compare with NaN.","line":2,"column":9,"nodeType":"BinaryExpression","messageId":"comparisonWithNaN","endLine":2,"endColumn":17},{"ruleId":"space-unary-ops","severity":2,"message":"Unexpected space before unary operator '++'.","line":3,"column":16,"nodeType":"UpdateExpression","messageId":"unexpectedBefore","endLine":3,"endColumn":20,"fix":{"range":[57,58],"text":""}},{"ruleId":"semi","severity":1,"message":"Missing semicolon.","line":3,"column":20,"nodeType":"ReturnStatement","messageId":"missingSemi","endLine":4,"endColumn":1,"fix":{"range":[60,60],"text":";"}},{"ruleId":"no-else-return","severity":1,"message":"Unnecessary 'else' after 'return'.","line":4,"column":12,"nodeType":"BlockStatement","messageId":"unexpected","endLine":6,"endColumn":6,"fix":{"range":[0,94],"text":"function addOne(i) {\n if (i != NaN) {\n return i ++\n } \n return\n \n}"}},{"ruleId":"indent","severity":1,"message":"Expected indentation of 8 spaces but found 6.","line":5,"column":1,"nodeType":"Keyword","messageId":"wrongIndentation","endLine":5,"endColumn":7,"fix":{"range":[74,80],"text":" "}},{"ruleId":"consistent-return","severity":2,"message":"Function 'addOne' expected a return value.","line":5,"column":7,"nodeType":"ReturnStatement","messageId":"missingReturnValue","endLine":5,"endColumn":13},{"ruleId":"semi","severity":1,"message":"Missing semicolon.","line":5,"column":13,"nodeType":"ReturnStatement","messageId":"missingSemi","endLine":6,"endColumn":1,"fix":{"range":[86,86],"text":";"}},{"ruleId":"no-extra-semi","severity":2,"message":"Unnecessary semicolon.","line":7,"column":2,"nodeType":"EmptyStatement","messageId":"unexpected","endLine":7,"endColumn":3,"fix":{"range":[93,95],"text":"}"}}],"errorCount":5,"warningCount":4,"fixableErrorCount":2,"fixableWarningCount":4,"source":"function addOne(i) {\n if (i != NaN) {\n return i ++\n } else {\n return\n }\n};"}] +[{"filePath":"/var/lib/jenkins/workspace/Releases/eslint Release/eslint/fullOfProblems.js","messages":[{"ruleId":"no-unused-vars","severity":2,"message":"'addOne' is defined but never used.","line":1,"column":10,"nodeType":"Identifier","messageId":"unusedVar","endLine":1,"endColumn":16},{"ruleId":"use-isnan","severity":2,"message":"Use the isNaN function to compare with NaN.","line":2,"column":9,"nodeType":"BinaryExpression","messageId":"comparisonWithNaN","endLine":2,"endColumn":17},{"ruleId":"space-unary-ops","severity":2,"message":"Unexpected space before unary operator '++'.","line":3,"column":16,"nodeType":"UpdateExpression","messageId":"unexpectedBefore","endLine":3,"endColumn":20,"fix":{"range":[57,58],"text":""}},{"ruleId":"semi","severity":1,"message":"Missing semicolon.","line":3,"column":20,"nodeType":"ReturnStatement","messageId":"missingSemi","endLine":4,"endColumn":1,"fix":{"range":[60,60],"text":";"}},{"ruleId":"no-else-return","severity":1,"message":"Unnecessary 'else' after 'return'.","line":4,"column":12,"nodeType":"BlockStatement","messageId":"unexpected","endLine":6,"endColumn":6,"fix":{"range":[0,94],"text":"function addOne(i) {\n if (i != NaN) {\n return i ++\n } \n return\n \n}"}},{"ruleId":"indent","severity":1,"message":"Expected indentation of 8 spaces but found 6.","line":5,"column":1,"nodeType":"Keyword","messageId":"wrongIndentation","endLine":5,"endColumn":7,"fix":{"range":[74,80],"text":" "}},{"ruleId":"consistent-return","severity":2,"message":"Function 'addOne' expected a return value.","line":5,"column":7,"nodeType":"ReturnStatement","messageId":"missingReturnValue","endLine":5,"endColumn":13},{"ruleId":"semi","severity":1,"message":"Missing semicolon.","line":5,"column":13,"nodeType":"ReturnStatement","messageId":"missingSemi","endLine":6,"endColumn":1,"fix":{"range":[86,86],"text":";"}},{"ruleId":"no-extra-semi","severity":2,"message":"Unnecessary semicolon.","line":7,"column":2,"nodeType":"EmptyStatement","messageId":"unexpected","endLine":7,"endColumn":3,"fix":{"range":[93,95],"text":"}"}}],"errorCount":5,"fatalErrorCount":0,"warningCount":4,"fixableErrorCount":2,"fixableWarningCount":4,"source":"function addOne(i) {\n if (i != NaN) {\n return i ++\n } else {\n return\n }\n};"}] ``` ### junit diff --git a/docs/user-guide/index.md b/docs/user-guide/index.md index 8f79609549..5503fe1d55 100644 --- a/docs/user-guide/index.md +++ b/docs/user-guide/index.md @@ -45,3 +45,4 @@ If you were using a prior version of ESLint, you can get help with the transitio - [migrating-to-5.0.0](migrating-to-5.0.0) - [migrating-to-6.0.0](migrating-to-6.0.0) - [migrating-to-7.0.0](migrating-to-7.0.0) +- [migrating-to-8.0.0](/docs/8.0.0/user-guide/migrating-to-8.0.0) diff --git a/src/styles/lib/overrides.less b/src/styles/lib/overrides.less index 763e80d4d2..e395eb9b17 100644 --- a/src/styles/lib/overrides.less +++ b/src/styles/lib/overrides.less @@ -89,7 +89,7 @@ p { } &.recommended:before { - content: "\e013"; /* ok */ + content: "✓"; /* ok */ } &.removed:before { @@ -97,7 +97,11 @@ p { } &.fixable:before { - content: "\e136"; /* wrench */ + content: "🔧"; /* wrench */ + } + + &.hasSuggestions:before { + content: "💡"; /* lightbulb */ } &.incorrect:before {