Jump to: navigation, search

Difference between revisions of "Orion/ESLint"

(Rule priority)
Line 602: Line 602:
== Tests ==
== Tests ==
We don't have legal approval to commit the ESLint tests, because I didn't include them in the CQ. Moreover, they are written using '''vows''', whereas Orion is converging on '''Mocha'''.
* Every rule needs extensive unit tests
* Unit tests should still work when run from Node
* Unit tests should use Mocha
* Unit tests should work when run from Node or the browser (TODO)
== User interface ==
== User interface ==

Revision as of 15:28, 11 December 2013

Orion 5.0 will replace our current JSLint validator with ESLint. This page captures ongoing issues.

Rule parity

Here's a table showing the equivalent validation rules in JSLint and ESLint. Rules that JSLint does not support are marked as Unsupported.

ESLint rule JSLint option JSLint message Details
block-scoped-var Always on '{variable}' is already defined.
  • Occurs when a function-scoped variable is treated as if it was block scoped.
  • ESLint calls this error '{variable} used outside of binding context.'
brace-style Unsupported
camelcase Unsupported
complexity Unsupported
consistent-this Unsupported
curly Always on
  • Statement body should be inside '{ }' braces. (Orion)
  • Expected '{'. (Regular JSLint)
dot-notation sub {a} is better written in dot notation.
eqeqeq eqeqeq or eqeq
  • Expected '===' and saw '=='.
  • Expected '!==' and saw '!='.
  • Newer versions of JSLint call this option eqeqeq.
  • Orion's version calls it eqeq, and inverts the flag's value.
guard-for-in forin The body of a for in should be wrapped in an if statement to filter unwanted properties from the prototype.
max-depth Unsupported Enforces max depth of nested blocks within a function.
max-len maxlen Line too long. Enforces a maximum line length.
max-params Unsupported
max-statements Unsupported
new-cap newcap A constructor name should start with an uppercase letter.
new-parens Always on Missing '()' invoking a constructor. Flags new Whatever
no-alert devel '{alert, confirm, prompt}' is not defined.
no-bitwise bitwise Unexpected use of '{operator}'. JSLint disallows bitwise ops by default.
no-caller Unsupported Flags references to arguments.callee and arguments.caller.
no-catch-shadow Always on '{a}' is already defined.
  • Flags a catch clause's variable that shadows a variable declared in an outer scope. (In IE8 this [weblog.bocoup.com/the-catch-with-try-catch/ causes the outer variable to be overwritten]).
no-comma-dangle Always on Unexpected comma. Flags trailing commas in object literals.
no-cond-assign Unsupported Flags assignment in an if/while/do..while/for condition.
no-console devel
no-control-regex Unsupported Flags control characters (U+0000–U+001F and U+007F) within the source argument to the RegExp constructor.
no-debugger debug All 'debugger' statements should be removed.
no-delete-var Always on Expected '.' and instead saw ';'. Flags an attempt to delete a local variable.
no-div-regex Always on A regular expression literal can be confused with '/='. Flags a regex literal starting with /=
no-dupe-keys Always on Duplicate key '{a}'. Flags object literals that contain the same key more than once.
no-else-return Unsupported Flags an else appearing after an if that contains a return.
no-empty-class Always on Empty class. Flags an empty character class [] within a regular expression.
no-empty-label Always on Label '{a}' on statement. Flags a labeled statement that is not a switch, for, or while.
no-empty Unsupported Flags an empty block like if (something) { }.
no-eq-null Always on Use '===' to compare with 'null'. JSLint produces a similar warning when comparing against undefined.
no-eval evil eval is evil.
no-ex-assign Always on Do not assign to the exception parameter.
no-extra-semi Always on Unnecessary semicolon.
no-fallthrough Unsupported Flags a fallthrough case within a switch statement, unless it is explicitly commented.
no-floating-decimal Always on A {leading, trailing} decimal point can be confused with a dot: '{n}'. Flags numeric literals that have a leading or trailing decimal point.
no-func-assign Unsupported Flags assignment to a variable that's already bound to a FunctionExpression.
no-global-strict Unsupported Flags "use strict" applied to the entire Program.
no-implied-eval Always on Implied eval is evil. Pass a function instead of a string. Flags calls to the string-argument form of setTimeout and setInterval, which implicitly perform eval.
no-iterator Always on Reserved name '__iterator__'. Flags use of __iterator__ as an identifier name or property key.
no-label-var Always on '{label}' is already defined. Flags labels that collide with an identifier.
no-loop-func Always on Don't make functions within a loop.
no-mixed-requires Flags Node.js require()s that mix different types of requires (core, module, file, computed).
no-multi-str Flags use of ES5 multiline string literals.
no-native-reassign Always on
  • Read only.
  • Bad assignment. (if assigning to undefined)
Flags an attempt to reassign a native object like Math, Array, undefined, etc.
no-negated-in-lhs Unsupported
  • Flags a unary ! operator applied to the LHS of an in statement, which negates the LHS, not the in.
  • Eg. (!"key" in {key: 1}) (which always evaluates to false), will be flagged.
no-new-array Always on Use the array literal notation []. Flags new Array().
no-new-func Always on The Function constructor is eval.
no-new-object Always on Use the object literal notation {}. Flags new Object().
no-new-wrappers Do not use {String, Number, Boolean, Math, JSON} as a constructor. Flags new applied to any of those.
no-new Always on Do not use 'new' for side effects. Flags uses of new operator in an expression that is not assigned to anything.
no-obj-calls Partial support Math is not a function..
  • Flags attempts to call object properties of the global object (Math, JSON) as a function, like Math().
  • JSLint warns only on Math().
no-octal-escape Always on Bad escapement. Flags octal escapes in strings, for example var x = "Copyright \251";
no-octal Always on Don't use extra leading zeros '{n}'. Flags number literals that begin with leading 0s, which indicate a (probably accidental) octal literal.
no-plusplus plusplus
  • Unexpected use of '++'
  • Unexpected use of '--'
no-proto Always on
  • Reserved name '__proto__'. (if used as an identifier)
  • Stupid key '{a}'. (if used as a key)
Treated as a fatal parse error in JSLint.
no-redeclare Always on '{a}' is already defined. Usually results from having two for loops in the same function that share a loop variable declaration like var i=....
no-return-assign Unsupported
  • Prevents assignment in a return statement.
  • Unsupported by JSLint, although JSLint does require parens around a return-assignment, eg: return (x = 2);
no-script-url Always on Script URL.
  • Flags string literals beginning with javascript:. (Script URLs are a form of eval.)
  • Fatal parse error in JSLint.
no-self-compare Unsupported Flags comparisons where the left- and right-hand sides are the same.
no-shadow Unsupported Flags variables that have the same name as a variable declared in an outer scope.
no-sync stupid Unexpected sync method: '{a}'.
  • Flags Node.js's synchronous I/O methods.
  • The stupid option is supported only in newer versions of JSLint (not Orion's).
no-ternary Unsupported Flags any use of the ternary operator cond ? thenExpr : elseExpr
no-undef-init Always on It is not necessary to initialize '{variable}' to 'undefined'.
no-undef undef '{variable}' is not defined.
  • Flags references to a global variable that is not listed in a /*global*/ or /*globals*/ block.
  • Predefined environments (eg. node, browser) can be set in the /*jslint */ block.
no-underscore-dangle nomen Dangling '_'
no-unreachable Always on Unreachable '{statement}' after '{control flow statement}'. Flags statements that occur after a return, throw, etc.
no-unused-expressions Always on Expected an assignment or function call and instead saw an expression. Flags expressions that appear in a statement context and don't cause side effects.
no-unused-vars Always on Function declares unused variable '{a}'. (Orion) Newer JSlint versions have an unparam option which works similarly.
no-use-before-define Always on '{a}' was used before it was defined.
no-with Always on Expected an identifier and instead saw 'with'. Treated as fatal parse error in JSLint.
no-wrap-func Always on Do not wrap function literals in parens unless they are to be immediately invoked. Flags a parenthesized function literal that is not immediately invoked, eg. (function fun(){})
one-var onevar Too many var statements. Allows only 1 var statement per function.
quote-props Unsupported Requires object literal keys to be quoted with " or '.
quotes Unsupported Flags any use of single or double quote marks, depending on setting.
radix Always on Missing radix parameter. Affects parseInt().
regex-spaces Always on Spaces are hard to count. Use {n}.
semi Always on Missing semicolon.
strict strict Flags any code that lacks the "use strict" pragma.
unnecessary-strict Unsupported Flags "use strict" on a function when the entire Program is already in strict mode.
use-isnan Always on Use the isNaN function to compare with NaN.
wrap-iife immed
  • Wrap the entire immediate function invocation in parens.
  • Move the invocation into the parens that contain the function.
Flags missing parens on immediately-invoked functions, eg. function(){ console.log('hi'); }();
wrap-regex Always on Wrap the /regexp/ literal in parens to disambiguate the slash operator.

New rules

Ideas for new linting rules that we should write.

Name Severity Description
object-prototype-external Warning Flags calls to methods of Object.prototype that rely on the prototype chain. For example this code should be flagged:
  1. foo.hasOwnProperty("bar")

Example (1) is unsafe, as foo may have a property named hasOwnProperty, or have been constructed via Object.create(null).

As for this:

  1. Object.hasOwnProperty.call(foo, "bar")

Example (2) technically relies on the prototype chain as well: the hasOwnProperty method is defined on Object.prototype, not Object. Object inherits the methods of Object.prototype through its prototype chain. However (2) is unlikely to fail, as sane JavaScript programs will not modify the global objects' prototypes. If we choose to flag (2), it should only be for style.

Rule priority

Here are the rules we want to support, grouped by priority. Implemented rules are struck out.


  • block-scoped-var
  • eqeqeq
  • no-undef
  • no-redeclare
  • no-unused-vars
  • no-use-before-define


  • guard-for-in
  • no-dupe-keys
  • no-octal
  • no-with
  • radix
  • semi
  • wrap-iife

Nice to have

  • dot-notation
  • new-cap
  • new-parens
  • no-caller
  • no-comma-dangle
  • no-implied-eval
  • no-new-array
  • no-new-object
  • no-undef-init
  • no-unused-expressions
  • no-wrap-func
  • use-isnan


  • Every rule needs extensive unit tests
  • Unit tests should use Mocha
  • Unit tests should work when run from Node or the browser (TODO)

User interface

  • Should we have a UI for configuring what rules are active?
  • Should we try to support .eslintrc? This would be an ideal project-scope setting.
  • Should we try to honor equivalent JSLint/JSHint flags when possible? For example /*jslint eqeqeq:false */ could disable the eqeqeq rule on a per-file basis.
    • This would give compatibility with Orion codebase which uses these flags.
    • OTOH, eslint now has its own syntax for this: /*eslint ..*/, which we should perhaps use instead.


We need to support i18n. Pre-req is bug 422278 (orion.edit.validator support for i18n).