Skip to content

Commit cdcf23a

Browse files
Trottevanlucas
authored andcommitted
tools: update ESLint to 3.3.0 and enable rules
Update ESLint 3.3.0 and update .eslintrc: * replace deprecated no-negated-in-lhs rule with no-unsafe-negation * http://eslint.org/docs/rules/no-negated-in-lhs * http://eslint.org/docs/rules/no-unsafe-negation * enable no-template-curly-in-string * http://eslint.org/docs/rules/no-template-curly-in-string * enable no-global-assign * http://eslint.org/docs/rules/no-global-assign * enable func-call-spacing * http://eslint.org/docs/rules/func-call-spacing PR-URL: #8097 Reviewed-By: targos - Michaël Zasso <[email protected]> Reviewed-By: jasnell - James M Snell <[email protected]> Reviewed-By: Roman Reiss <[email protected]>
1 parent be41f58 commit cdcf23a

File tree

391 files changed

+4755
-5775
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

391 files changed

+4755
-5775
lines changed

.eslintrc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,19 @@ rules:
1919
no-func-assign: 2
2020
no-invalid-regexp: 2
2121
no-irregular-whitespace: 2
22-
no-negated-in-lhs: 2
2322
no-obj-calls: 2
2423
no-proto: 2
24+
no-template-curly-in-string: 2
2525
no-unexpected-multiline: 2
2626
no-unreachable: 2
27+
no-unsafe-negation: 2
2728
use-isnan: 2
2829
valid-typeof: 2
2930

3031
# Best Practices
3132
# http://eslint.org/docs/rules/#best-practices
3233
no-fallthrough: 2
34+
no-global-assign: 2
3335
no-multi-spaces: 2
3436
no-octal: 2
3537
no-redeclare: 2
@@ -58,6 +60,7 @@ rules:
5860
brace-style: [2, 1tbs, {allowSingleLine: true}]
5961
comma-spacing: 2
6062
eol-last: 2
63+
func-call-spacing: 2
6164
indent: [2, 2, {SwitchCase: 1, MemberExpression: 1}]
6265
key-spacing: [2, {mode: minimum}]
6366
keyword-spacing: 2

tools/eslint/conf/category-list.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88
{ "name": "Stylistic Issues", "description": "These rules relate to style guidelines, and are therefore quite subjective:" },
99
{ "name": "ECMAScript 6", "description": "These rules relate to ES6, also known as ES2015:" }
1010
],
11+
"deprecated": {
12+
"name": "Deprecated",
13+
"description": "These rules have been deprecated and replaced by newer rules:",
14+
"rules": []
15+
},
1116
"removed": {
1217
"name": "Removed",
1318
"description": "These rules from older versions of ESLint have been replaced by newer rules:",
@@ -32,4 +37,4 @@
3237
{ "removed": "spaced-line-comment", "replacedBy": ["spaced-comment"] }
3338
]
3439
}
35-
}
40+
}

tools/eslint/conf/environments.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// Requirements
99
//------------------------------------------------------------------------------
1010

11-
let globals = require("globals");
11+
const globals = require("globals");
1212

1313
//------------------------------------------------------------------------------
1414
// Public Interface

tools/eslint/conf/eslint-all.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,16 @@
99
// Requirements
1010
//------------------------------------------------------------------------------
1111

12-
let fs = require("fs"),
13-
path = require("path");
12+
const load = require("../lib/load-rules"),
13+
rules = require("../lib/rules");
1414

1515
//------------------------------------------------------------------------------
1616
// Helpers
1717
//------------------------------------------------------------------------------
1818

19-
let ruleFiles = fs.readdirSync(path.resolve(__dirname, "../lib/rules"));
20-
let enabledRules = ruleFiles.reduce(function(result, filename) {
21-
if (path.extname(filename) === ".js") {
22-
result[path.basename(filename, ".js")] = "error";
19+
const enabledRules = Object.keys(load()).reduce((result, ruleId) => {
20+
if (!rules.get(ruleId).meta.deprecated) {
21+
result[ruleId] = "error";
2322
}
2423
return result;
2524
}, {});

tools/eslint/conf/eslint.json

100644100755
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
"no-fallthrough": "error",
4242
"no-floating-decimal": "off",
4343
"no-func-assign": "error",
44+
"no-global-assign": "off",
4445
"no-implicit-coercion": "off",
4546
"no-implicit-globals": "off",
4647
"no-implied-eval": "off",
@@ -113,6 +114,7 @@
113114
"no-unneeded-ternary": "off",
114115
"no-unreachable": "error",
115116
"no-unsafe-finally": "error",
117+
"no-unsafe-negation": "off",
116118
"no-unused-expressions": "off",
117119
"no-unused-labels": "error",
118120
"no-unused-vars": "error",
@@ -152,6 +154,7 @@
152154
"dot-notation": "off",
153155
"eol-last": "off",
154156
"eqeqeq": "off",
157+
"func-call-spacing": "off",
155158
"func-names": "off",
156159
"func-style": "off",
157160
"generator-star-spacing": "off",
@@ -204,6 +207,7 @@
204207
"rest-spread-spacing": "off",
205208
"semi": "off",
206209
"semi-spacing": "off",
210+
"sort-keys": "off",
207211
"sort-imports": "off",
208212
"sort-vars": "off",
209213
"space-before-blocks": "off",
@@ -221,6 +225,7 @@
221225
"vars-on-top": "off",
222226
"wrap-iife": "off",
223227
"wrap-regex": "off",
228+
"no-template-curly-in-string": "off",
224229
"yield-star-spacing": "off",
225230
"yoda": "off"
226231
}

tools/eslint/lib/ast-utils.js

Lines changed: 130 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,19 @@
99
// Requirements
1010
//------------------------------------------------------------------------------
1111

12-
let esutils = require("esutils");
12+
const esutils = require("esutils");
1313

1414
//------------------------------------------------------------------------------
1515
// Helpers
1616
//------------------------------------------------------------------------------
1717

18-
let anyFunctionPattern = /^(?:Function(?:Declaration|Expression)|ArrowFunctionExpression)$/;
19-
let anyLoopPattern = /^(?:DoWhile|For|ForIn|ForOf|While)Statement$/;
20-
let arrayOrTypedArrayPattern = /Array$/;
21-
let arrayMethodPattern = /^(?:every|filter|find|findIndex|forEach|map|some)$/;
22-
let bindOrCallOrApplyPattern = /^(?:bind|call|apply)$/;
23-
let breakableTypePattern = /^(?:(?:Do)?While|For(?:In|Of)?|Switch)Statement$/;
24-
let thisTagPattern = /^[\s\*]*@this/m;
18+
const anyFunctionPattern = /^(?:Function(?:Declaration|Expression)|ArrowFunctionExpression)$/;
19+
const anyLoopPattern = /^(?:DoWhile|For|ForIn|ForOf|While)Statement$/;
20+
const arrayOrTypedArrayPattern = /Array$/;
21+
const arrayMethodPattern = /^(?:every|filter|find|findIndex|forEach|map|some)$/;
22+
const bindOrCallOrApplyPattern = /^(?:bind|call|apply)$/;
23+
const breakableTypePattern = /^(?:(?:Do)?While|For(?:In|Of)?|Switch)Statement$/;
24+
const thisTagPattern = /^[\s\*]*@this/m;
2525

2626
/**
2727
* Checks reference if is non initializer and writable.
@@ -32,15 +32,14 @@ let thisTagPattern = /^[\s\*]*@this/m;
3232
* @private
3333
*/
3434
function isModifyingReference(reference, index, references) {
35-
let identifier = reference.identifier,
36-
modifyingDifferentIdentifier;
35+
const identifier = reference.identifier;
3736

3837
/*
3938
* Destructuring assignments can have multiple default value, so
4039
* possibly there are multiple writeable references for the same
4140
* identifier.
4241
*/
43-
modifyingDifferentIdentifier = index === 0 ||
42+
const modifyingDifferentIdentifier = index === 0 ||
4443
references[index - 1].identifier !== identifier;
4544

4645
return (identifier &&
@@ -50,16 +49,23 @@ function isModifyingReference(reference, index, references) {
5049
);
5150
}
5251

52+
/**
53+
* Checks whether the given string starts with uppercase or not.
54+
*
55+
* @param {string} s - The string to check.
56+
* @returns {boolean} `true` if the string starts with uppercase.
57+
*/
58+
function startsWithUpperCase(s) {
59+
return s[0] !== s[0].toLocaleLowerCase();
60+
}
61+
5362
/**
5463
* Checks whether or not a node is a constructor.
5564
* @param {ASTNode} node - A function node to check.
5665
* @returns {boolean} Wehether or not a node is a constructor.
5766
*/
5867
function isES5Constructor(node) {
59-
return (
60-
node.id &&
61-
node.id.name[0] !== node.id.name[0].toLocaleLowerCase()
62-
);
68+
return (node.id && startsWithUpperCase(node.id.name));
6369
}
6470

6571
/**
@@ -160,7 +166,7 @@ function isMethodWhichHasThisArg(node) {
160166
* @returns {boolean} Whether or not the node has a `@this` tag in its comments.
161167
*/
162168
function hasJSDocThisTag(node, sourceCode) {
163-
let jsdocComment = sourceCode.getJSDocComment(node);
169+
const jsdocComment = sourceCode.getJSDocComment(node);
164170

165171
if (jsdocComment && thisTagPattern.test(jsdocComment.value)) {
166172
return true;
@@ -183,7 +189,7 @@ function hasJSDocThisTag(node, sourceCode) {
183189
* @private
184190
*/
185191
function isParenthesised(sourceCode, node) {
186-
let previousToken = sourceCode.getTokenBefore(node),
192+
const previousToken = sourceCode.getTokenBefore(node),
187193
nextToken = sourceCode.getTokenAfter(node);
188194

189195
return Boolean(previousToken && nextToken) &&
@@ -285,7 +291,7 @@ module.exports = {
285291
* @returns {boolean} `true` if the node is an ESLint directive comment
286292
*/
287293
isDirectiveComment: function(node) {
288-
let comment = node.value.trim();
294+
const comment = node.value.trim();
289295

290296
return (
291297
node.type === "Line" && comment.indexOf("eslint-") === 0 ||
@@ -321,7 +327,7 @@ module.exports = {
321327
let scope = initScope;
322328

323329
while (scope) {
324-
let variable = scope.set.get(name);
330+
const variable = scope.set.get(name);
325331

326332
if (variable) {
327333
return variable;
@@ -345,9 +351,9 @@ module.exports = {
345351
* If the location is below, this judges `this` is valid.
346352
*
347353
* - The location is not on an object literal.
348-
* - The location does not assign to a property.
354+
* - The location is not assigned to a variable which starts with an uppercase letter.
349355
* - The location is not on an ES2015 class.
350-
* - The location does not call its `bind`/`call`/`apply` method directly.
356+
* - Its `bind`/`call`/`apply` method is not called directly.
351357
* - The function is not a callback of array methods (such as `.forEach()`) if `thisArg` is given.
352358
*
353359
* @param {ASTNode} node - A function node to check.
@@ -358,9 +364,10 @@ module.exports = {
358364
if (isES5Constructor(node) || hasJSDocThisTag(node, sourceCode)) {
359365
return false;
360366
}
367+
const isAnonymous = node.id === null;
361368

362369
while (node) {
363-
let parent = node.parent;
370+
const parent = node.parent;
364371

365372
switch (parent.type) {
366373

@@ -392,25 +399,44 @@ module.exports = {
392399
// e.g.
393400
// var obj = { foo() { ... } };
394401
// var obj = { foo: function() { ... } };
395-
case "Property":
396-
return false;
397-
398-
// e.g.
399-
// obj.foo = foo() { ... };
400-
case "AssignmentExpression":
401-
return (
402-
parent.right !== node ||
403-
parent.left.type !== "MemberExpression"
404-
);
405-
406-
// e.g.
407402
// class A { constructor() { ... } }
408403
// class A { foo() { ... } }
409404
// class A { get foo() { ... } }
410405
// class A { set foo() { ... } }
411406
// class A { static foo() { ... } }
407+
case "Property":
412408
case "MethodDefinition":
413-
return false;
409+
return parent.value !== node;
410+
411+
// e.g.
412+
// obj.foo = function foo() { ... };
413+
// Foo = function() { ... };
414+
// [obj.foo = function foo() { ... }] = a;
415+
// [Foo = function() { ... }] = a;
416+
case "AssignmentExpression":
417+
case "AssignmentPattern":
418+
if (parent.right === node) {
419+
if (parent.left.type === "MemberExpression") {
420+
return false;
421+
}
422+
if (isAnonymous &&
423+
parent.left.type === "Identifier" &&
424+
startsWithUpperCase(parent.left.name)
425+
) {
426+
return false;
427+
}
428+
}
429+
return true;
430+
431+
// e.g.
432+
// var Foo = function() { ... };
433+
case "VariableDeclarator":
434+
return !(
435+
isAnonymous &&
436+
parent.init === node &&
437+
parent.id.type === "Identifier" &&
438+
startsWithUpperCase(parent.id.name)
439+
);
414440

415441
// e.g.
416442
// var foo = function foo() { ... }.bind(obj);
@@ -585,5 +611,74 @@ module.exports = {
585611
*/
586612
isFunction: function(node) {
587613
return Boolean(node && anyFunctionPattern.test(node.type));
614+
},
615+
616+
/**
617+
* Gets the property name of a given node.
618+
* The node can be a MemberExpression, a Property, or a MethodDefinition.
619+
*
620+
* If the name is dynamic, this returns `null`.
621+
*
622+
* For examples:
623+
*
624+
* a.b // => "b"
625+
* a["b"] // => "b"
626+
* a['b'] // => "b"
627+
* a[`b`] // => "b"
628+
* a[100] // => "100"
629+
* a[b] // => null
630+
* a["a" + "b"] // => null
631+
* a[tag`b`] // => null
632+
* a[`${b}`] // => null
633+
*
634+
* let a = {b: 1} // => "b"
635+
* let a = {["b"]: 1} // => "b"
636+
* let a = {['b']: 1} // => "b"
637+
* let a = {[`b`]: 1} // => "b"
638+
* let a = {[100]: 1} // => "100"
639+
* let a = {[b]: 1} // => null
640+
* let a = {["a" + "b"]: 1} // => null
641+
* let a = {[tag`b`]: 1} // => null
642+
* let a = {[`${b}`]: 1} // => null
643+
*
644+
* @param {ASTNode} node - The node to get.
645+
* @returns {string|null} The property name if static. Otherwise, null.
646+
*/
647+
getStaticPropertyName(node) {
648+
let prop;
649+
650+
switch (node && node.type) {
651+
case "Property":
652+
case "MethodDefinition":
653+
prop = node.key;
654+
break;
655+
656+
case "MemberExpression":
657+
prop = node.property;
658+
break;
659+
660+
// no default
661+
}
662+
663+
switch (prop && prop.type) {
664+
case "Literal":
665+
return String(prop.value);
666+
667+
case "TemplateLiteral":
668+
if (prop.expressions.length === 0 && prop.quasis.length === 1) {
669+
return prop.quasis[0].value.cooked;
670+
}
671+
break;
672+
673+
case "Identifier":
674+
if (!node.computed) {
675+
return prop.name;
676+
}
677+
break;
678+
679+
// no default
680+
}
681+
682+
return null;
588683
}
589684
};

0 commit comments

Comments
 (0)