Browse Source

tools: update ESLint to 3.5.0

PR-URL: https://github.com/nodejs/node/pull/8478
Reviewed-By: James M Snell <jasnell@gmail.com>
v7.x
Rich Trott 8 years ago
parent
commit
2da2625ad1
  1. 3412
      tools/eslint/CHANGELOG.md
  2. 3
      tools/eslint/README.md
  3. 4
      tools/eslint/conf/eslint.json
  4. 35
      tools/eslint/lib/ast-utils.js
  5. 10
      tools/eslint/lib/config/plugins.js
  6. 11
      tools/eslint/lib/eslint.js
  7. 20
      tools/eslint/lib/rules/array-bracket-spacing.js
  8. 4
      tools/eslint/lib/rules/arrow-parens.js
  9. 16
      tools/eslint/lib/rules/arrow-spacing.js
  10. 10
      tools/eslint/lib/rules/block-spacing.js
  11. 8
      tools/eslint/lib/rules/class-methods-use-this.js
  12. 7
      tools/eslint/lib/rules/comma-spacing.js
  13. 77
      tools/eslint/lib/rules/comma-style.js
  14. 20
      tools/eslint/lib/rules/computed-property-spacing.js
  15. 11
      tools/eslint/lib/rules/consistent-return.js
  16. 4
      tools/eslint/lib/rules/curly.js
  17. 57
      tools/eslint/lib/rules/dot-notation.js
  18. 7
      tools/eslint/lib/rules/generator-star-spacing.js
  19. 90
      tools/eslint/lib/rules/indent.js
  20. 16
      tools/eslint/lib/rules/init-declarations.js
  21. 5
      tools/eslint/lib/rules/jsx-quotes.js
  22. 5
      tools/eslint/lib/rules/key-spacing.js
  23. 2
      tools/eslint/lib/rules/keyword-spacing.js
  24. 101
      tools/eslint/lib/rules/line-comment-position.js
  25. 165
      tools/eslint/lib/rules/lines-around-directive.js
  26. 92
      tools/eslint/lib/rules/max-len.js
  27. 41
      tools/eslint/lib/rules/max-statements-per-line.js
  28. 2
      tools/eslint/lib/rules/new-cap.js
  29. 62
      tools/eslint/lib/rules/new-parens.js
  30. 71
      tools/eslint/lib/rules/newline-before-return.js
  31. 13
      tools/eslint/lib/rules/newline-per-chained-call.js
  32. 97
      tools/eslint/lib/rules/no-console.js
  33. 6
      tools/eslint/lib/rules/no-control-regex.js
  34. 2
      tools/eslint/lib/rules/no-dupe-class-members.js
  35. 7
      tools/eslint/lib/rules/no-duplicate-imports.js
  36. 5
      tools/eslint/lib/rules/no-empty-function.js
  37. 16
      tools/eslint/lib/rules/no-extend-native.js
  38. 16
      tools/eslint/lib/rules/no-floating-decimal.js
  39. 111
      tools/eslint/lib/rules/no-implicit-coercion.js
  40. 17
      tools/eslint/lib/rules/no-invalid-regexp.js
  41. 13
      tools/eslint/lib/rules/no-magic-numbers.js
  42. 13
      tools/eslint/lib/rules/no-mixed-operators.js
  43. 18
      tools/eslint/lib/rules/no-multiple-empty-lines.js
  44. 8
      tools/eslint/lib/rules/no-plusplus.js
  45. 13
      tools/eslint/lib/rules/no-regex-spaces.js
  46. 88
      tools/eslint/lib/rules/no-restricted-properties.js
  47. 8
      tools/eslint/lib/rules/no-shadow-restricted-names.js
  48. 8
      tools/eslint/lib/rules/no-sync.js
  49. 4
      tools/eslint/lib/rules/no-trailing-spaces.js
  50. 24
      tools/eslint/lib/rules/no-underscore-dangle.js
  51. 5
      tools/eslint/lib/rules/no-unsafe-finally.js
  52. 2
      tools/eslint/lib/rules/no-unused-vars.js
  53. 5
      tools/eslint/lib/rules/no-useless-escape.js
  54. 8
      tools/eslint/lib/rules/no-warning-comments.js
  55. 20
      tools/eslint/lib/rules/object-curly-spacing.js
  56. 13
      tools/eslint/lib/rules/object-shorthand.js
  57. 48
      tools/eslint/lib/rules/one-var.js
  58. 60
      tools/eslint/lib/rules/operator-linebreak.js
  59. 44
      tools/eslint/lib/rules/prefer-arrow-callback.js
  60. 62
      tools/eslint/lib/rules/prefer-numeric-literals.js
  61. 2
      tools/eslint/lib/rules/quote-props.js
  62. 12
      tools/eslint/lib/rules/quotes.js
  63. 30
      tools/eslint/lib/rules/space-unary-ops.js
  64. 24
      tools/eslint/lib/rules/spaced-comment.js
  65. 10
      tools/eslint/lib/rules/template-curly-spacing.js
  66. 16
      tools/eslint/lib/rules/valid-jsdoc.js
  67. 10
      tools/eslint/lib/rules/wrap-regex.js
  68. 6
      tools/eslint/lib/rules/yield-star-spacing.js
  69. 18
      tools/eslint/lib/rules/yoda.js
  70. 30
      tools/eslint/lib/util/glob-util.js
  71. 3
      tools/eslint/messages/whitespace-found.txt
  72. 97
      tools/eslint/node_modules/bluebird/js/browser/bluebird.core.js
  73. 6
      tools/eslint/node_modules/bluebird/js/browser/bluebird.core.min.js
  74. 136
      tools/eslint/node_modules/bluebird/js/browser/bluebird.js
  75. 8
      tools/eslint/node_modules/bluebird/js/browser/bluebird.min.js
  76. 22
      tools/eslint/node_modules/bluebird/package.json
  77. 19
      tools/eslint/node_modules/concat-stream/index.js
  78. 30
      tools/eslint/node_modules/concat-stream/package.json
  79. 2
      tools/eslint/node_modules/concat-stream/readme.md
  80. 2
      tools/eslint/node_modules/deep-is/package.json
  81. 2
      tools/eslint/node_modules/es6-weak-map/package.json
  82. 8
      tools/eslint/node_modules/inherits/inherits.js
  83. 28
      tools/eslint/node_modules/inherits/package.json
  84. 2
      tools/eslint/node_modules/is-path-cwd/package.json
  85. 2
      tools/eslint/node_modules/is-path-in-cwd/package.json
  86. 2
      tools/eslint/node_modules/is-property/package.json
  87. 2
      tools/eslint/node_modules/number-is-nan/package.json
  88. 28
      tools/eslint/node_modules/once/README.md
  89. 21
      tools/eslint/node_modules/once/once.js
  90. 24
      tools/eslint/node_modules/once/package.json
  91. 2
      tools/eslint/node_modules/path-is-absolute/package.json
  92. 2
      tools/eslint/node_modules/prelude-ls/package.json
  93. 2
      tools/eslint/node_modules/typedarray/package.json
  94. 2
      tools/eslint/node_modules/util-deprecate/package.json
  95. 18
      tools/eslint/package.json

3412
tools/eslint/CHANGELOG.md

File diff suppressed because it is too large

3
tools/eslint/README.md

@ -111,6 +111,7 @@ These folks keep the project moving and are resources for help.
* Gyandeep Singh ([@gyandeeps](https://github.com/gyandeeps))
* Toru Nagashima ([@mysticatea](https://github.com/mysticatea))
* Alberto Rodríguez ([@alberto](https://github.com/alberto))
* Kai Cataldo ([@kaicataldo](https://github.com/kaicataldo))
### Development Team
@ -118,7 +119,6 @@ These folks keep the project moving and are resources for help.
* Jamund Ferguson ([@xjamundx](https://github.com/xjamundx))
* Ian VanSchooten ([@ianvs](https://github.com/ianvs))
* Burak Yiğit Kaya ([@byk](https://github.com/byk))
* Kai Cataldo ([@kaicataldo](https://github.com/kaicataldo))
* Michael Ficarra ([@michaelficarra](https://github.com/michaelficarra))
* Mark Pedrotti ([@pedrottimark](https://github.com/pedrottimark))
* Oleg Gaidarenko ([@markelog](https://github.com/markelog))
@ -128,6 +128,7 @@ These folks keep the project moving and are resources for help.
* Alexej Yaroshevich ([@zxqfox](https://github.com/zxqfox))
* Kevin Partington ([@platinumazure](https://github.com/platinumazure))
* Vitor Balocco ([@vitorbal](https://github.com/vitorbal))
* James Henry ([@JamesHenry](https://github.com/JamesHenry))
## Releases

4
tools/eslint/conf/eslint.json

@ -88,6 +88,7 @@
"no-restricted-globals": "off",
"no-restricted-imports": "off",
"no-restricted-modules": "off",
"no-restricted-properties": "off",
"no-restricted-syntax": "off",
"no-return-assign": "off",
"no-script-url": "off",
@ -171,7 +172,9 @@
"key-spacing": "off",
"keyword-spacing": "off",
"linebreak-style": "off",
"line-comment-position": "off",
"lines-around-comment": "off",
"lines-around-directive": "off",
"max-depth": "off",
"max-len": "off",
"max-lines": "off",
@ -196,6 +199,7 @@
"padded-blocks": "off",
"prefer-arrow-callback": "off",
"prefer-const": "off",
"prefer-numeric-literals": "off",
"prefer-reflect": "off",
"prefer-rest-params": "off",
"prefer-spread": "off",

35
tools/eslint/lib/ast-utils.js

@ -680,5 +680,40 @@ module.exports = {
}
return null;
},
/**
* Get directives from directive prologue of a Program or Function node.
* @param {ASTNode} node - The node to check.
* @returns {ASTNode[]} The directives found in the directive prologue.
*/
getDirectivePrologue(node) {
const directives = [];
// Directive prologues only occur at the top of files or functions.
if (
node.type === "Program" ||
node.type === "FunctionDeclaration" ||
node.type === "FunctionExpression" ||
// Do not check arrow functions with implicit return.
// `() => "use strict";` returns the string `"use strict"`.
(node.type === "ArrowFunctionExpression" && node.body.type === "BlockStatement")
) {
const statements = node.type === "Program" ? node.body : node.body.body;
for (const statement of statements) {
if (
statement.type === "ExpressionStatement" &&
statement.expression.type === "Literal"
) {
directives.push(statement);
} else {
break;
}
}
}
return directives;
}
};

10
tools/eslint/lib/config/plugins.js

@ -114,6 +114,16 @@ module.exports = {
longName = pluginNamespace + PLUGIN_NAME_PREFIX + pluginNameWithoutPrefix;
let plugin = null;
if (pluginName.match(/\s+/)) {
const whitespaceError = new Error("Whitespace found in plugin name '" + pluginName + "'");
whitespaceError.messageTemplate = "whitespace-found";
whitespaceError.messageData = {
pluginName: longName
};
throw whitespaceError;
}
if (!plugins[shortName]) {
try {
plugin = require(longName);

11
tools/eslint/lib/eslint.js

@ -598,10 +598,11 @@ module.exports = (function() {
* as possible
* @param {string} text The text to parse.
* @param {Object} config The ESLint configuration object.
* @param {string} filePath The path to the file being parsed.
* @returns {ASTNode} The AST if successful or null if not.
* @private
*/
function parse(text, config) {
function parse(text, config, filePath) {
let parser,
parserOptions = {
@ -610,7 +611,8 @@ module.exports = (function() {
raw: true,
tokens: true,
comment: true,
attachComment: true
attachComment: true,
filePath
};
try {
@ -783,7 +785,8 @@ module.exports = (function() {
shebang = captured;
return "//" + captured;
}),
config
config,
currentFilename
);
if (ast) {
@ -974,7 +977,7 @@ module.exports = (function() {
}
if (opts) {
message = message.replace(/\{\{\s*(.+?)\s*\}\}/g, function(fullMatch, term) {
message = message.replace(/\{\{\s*([^{}]+?)\s*\}\}/g, function(fullMatch, term) {
if (term in opts) {
return opts[term];
}

20
tools/eslint/lib/rules/array-bracket-spacing.js

@ -75,7 +75,10 @@ module.exports = {
context.report({
node,
loc: token.loc.start,
message: "There should be no space after '" + token.value + "'.",
message: "There should be no space after '{{tokenValue}}'.",
data: {
tokenValue: token.value
},
fix(fixer) {
const nextToken = sourceCode.getTokenAfter(token);
@ -94,7 +97,10 @@ module.exports = {
context.report({
node,
loc: token.loc.start,
message: "There should be no space before '" + token.value + "'.",
message: "There should be no space before '{{tokenValue}}'.",
data: {
tokenValue: token.value
},
fix(fixer) {
const previousToken = sourceCode.getTokenBefore(token);
@ -113,7 +119,10 @@ module.exports = {
context.report({
node,
loc: token.loc.start,
message: "A space is required after '" + token.value + "'.",
message: "A space is required after '{{tokenValue}}'.",
data: {
tokenValue: token.value
},
fix(fixer) {
return fixer.insertTextAfter(token, " ");
}
@ -130,7 +139,10 @@ module.exports = {
context.report({
node,
loc: token.loc.start,
message: "A space is required before '" + token.value + "'.",
message: "A space is required before '{{tokenValue}}'.",
data: {
tokenValue: token.value
},
fix(fixer) {
return fixer.insertTextBefore(token, " ");
}

4
tools/eslint/lib/rules/arrow-parens.js

@ -87,7 +87,7 @@ module.exports = {
node,
message: requireForBlockBodyNoParensMessage,
fix(fixer) {
return fixer.replaceText(token, "(" + token.value + ")");
return fixer.replaceText(token, `(${token.value})`);
}
});
}
@ -123,7 +123,7 @@ module.exports = {
node,
message,
fix(fixer) {
return fixer.replaceText(token, "(" + token.value + ")");
return fixer.replaceText(token, `(${token.value})`);
}
});
}

16
tools/eslint/lib/rules/arrow-spacing.js

@ -51,16 +51,18 @@ module.exports = {
* @returns {Object} Tokens of arrow and before/after arrow.
*/
function getTokens(node) {
let t = sourceCode.getFirstToken(node);
let before;
let arrow = sourceCode.getTokenBefore(node.body);
while (t.type !== "Punctuator" || t.value !== "=>") {
before = t;
t = sourceCode.getTokenAfter(t);
// skip '(' tokens.
while (arrow.value !== "=>") {
arrow = sourceCode.getTokenBefore(arrow);
}
const after = sourceCode.getTokenAfter(t);
return { before, arrow: t, after };
return {
before: sourceCode.getTokenBefore(arrow),
arrow,
after: sourceCode.getTokenAfter(arrow)
};
}
/**

10
tools/eslint/lib/rules/block-spacing.js

@ -97,7 +97,10 @@ module.exports = {
context.report({
node,
loc: openBrace.loc.start,
message: message + " after '{'.",
message: "{{message}} after '{'.",
data: {
message
},
fix(fixer) {
if (always) {
return fixer.insertTextBefore(firstToken, " ");
@ -111,7 +114,10 @@ module.exports = {
context.report({
node,
loc: closeBrace.loc.start,
message: message + " before '}'.",
message: "{{message}} before '}'.",
data: {
message
},
fix(fixer) {
if (always) {
return fixer.insertTextAfter(lastToken, " ");

8
tools/eslint/lib/rules/class-methods-use-this.js

@ -53,7 +53,13 @@ module.exports = {
const methodUsesThis = stack.pop();
if (isInstanceMethod(node.parent) && !methodUsesThis) {
context.report(node, "Expected 'this' to be used by class method '" + node.parent.key.name + "'.");
context.report({
node,
message: "Expected 'this' to be used by class method '{{classMethod}}'.",
data: {
classMethod: node.parent.key.name
}
});
}
}

7
tools/eslint/lib/rules/comma-spacing.js

@ -97,8 +97,11 @@ module.exports = {
}
},
message: options[dir] ?
"A space is required " + dir + " ','." :
"There should be no space " + dir + " ','."
"A space is required {{dir}} ','." :
"There should be no space {{dir}} ','.",
data: {
dir
}
});
}

77
tools/eslint/lib/rules/comma-style.js

@ -18,7 +18,7 @@ module.exports = {
category: "Stylistic Issues",
recommended: false
},
fixable: "code",
schema: [
{
enum: ["first", "last"]
@ -61,6 +61,49 @@ module.exports = {
return !!token && (token.type === "Punctuator") && (token.value === ",");
}
/**
* Modified text based on the style
* @param {string} styleType Style type
* @param {string} text Source code text
* @returns {string} modified text
* @private
*/
function getReplacedText(styleType, text) {
switch (styleType) {
case "between":
return `,${text.replace("\n", "")}`;
case "first":
return `${text},`;
case "last":
return `,${text}`;
default:
return "";
}
}
/**
* Determines the fixer function for a given style.
* @param {string} styleType comma style
* @param {ASTNode} previousItemToken The token to check.
* @param {ASTNode} commaToken The token to check.
* @param {ASTNode} currentItemToken The token to check.
* @returns {Function} Fixer function
* @private
*/
function getFixerFunction(styleType, previousItemToken, commaToken, currentItemToken) {
const text =
sourceCode.text.slice(previousItemToken.range[1], commaToken.range[0]) +
sourceCode.text.slice(commaToken.range[1], currentItemToken.range[0]);
const range = [previousItemToken.range[1], currentItemToken.range[0]];
return function(fixer) {
return fixer.replaceTextRange(range, getReplacedText(styleType, text));
};
}
/**
* Validates the spacing around single items in lists.
* @param {Token} previousItemToken The last token from the previous item.
@ -82,21 +125,35 @@ module.exports = {
!astUtils.isTokenOnSameLine(previousItemToken, commaToken)) {
// lone comma
context.report(reportItem, {
line: commaToken.loc.end.line,
column: commaToken.loc.start.column
}, "Bad line breaking before and after ','.");
context.report({
node: reportItem,
loc: {
line: commaToken.loc.end.line,
column: commaToken.loc.start.column
},
message: "Bad line breaking before and after ','.",
fix: getFixerFunction("between", previousItemToken, commaToken, currentItemToken)
});
} else if (style === "first" && !astUtils.isTokenOnSameLine(commaToken, currentItemToken)) {
context.report(reportItem, "',' should be placed first.");
context.report({
node: reportItem,
message: "',' should be placed first.",
fix: getFixerFunction(style, previousItemToken, commaToken, currentItemToken)
});
} else if (style === "last" && astUtils.isTokenOnSameLine(commaToken, currentItemToken)) {
context.report(reportItem, {
line: commaToken.loc.end.line,
column: commaToken.loc.end.column
}, "',' should be placed last.");
context.report({
node: reportItem,
loc: {
line: commaToken.loc.end.line,
column: commaToken.loc.end.column
},
message: "',' should be placed last.",
fix: getFixerFunction(style, previousItemToken, commaToken, currentItemToken)
});
}
}

20
tools/eslint/lib/rules/computed-property-spacing.js

@ -46,7 +46,10 @@ module.exports = {
context.report({
node,
loc: token.loc.start,
message: "There should be no space after '" + token.value + "'.",
message: "There should be no space after '{{tokenValue}}'.",
data: {
tokenValue: token.value
},
fix(fixer) {
return fixer.removeRange([token.range[1], tokenAfter.range[0]]);
}
@ -64,7 +67,10 @@ module.exports = {
context.report({
node,
loc: token.loc.start,
message: "There should be no space before '" + token.value + "'.",
message: "There should be no space before '{{tokenValue}}'.",
data: {
tokenValue: token.value
},
fix(fixer) {
return fixer.removeRange([tokenBefore.range[1], token.range[0]]);
}
@ -81,7 +87,10 @@ module.exports = {
context.report({
node,
loc: token.loc.start,
message: "A space is required after '" + token.value + "'.",
message: "A space is required after '{{tokenValue}}'.",
data: {
tokenValue: token.value
},
fix(fixer) {
return fixer.insertTextAfter(token, " ");
}
@ -98,7 +107,10 @@ module.exports = {
context.report({
node,
loc: token.loc.start,
message: "A space is required before '" + token.value + "'.",
message: "A space is required before '{{tokenValue}}'.",
data: {
tokenValue: token.value
},
fix(fixer) {
return fixer.insertTextBefore(token, " ");
}

11
tools/eslint/lib/rules/consistent-return.js

@ -145,9 +145,16 @@ module.exports = {
if (!funcInfo.hasReturn) {
funcInfo.hasReturn = true;
funcInfo.hasReturnValue = hasReturnValue;
funcInfo.message = "Expected " + (hasReturnValue ? "a" : "no") + " return value.";
funcInfo.message = "Expected {{which}} return value.";
funcInfo.data = {
which: hasReturnValue ? "a" : "no"
};
} else if (funcInfo.hasReturnValue !== hasReturnValue) {
context.report({node, message: funcInfo.message});
context.report({
node,
message: funcInfo.message,
data: funcInfo.data
});
}
},

4
tools/eslint/lib/rules/curly.js

@ -149,7 +149,7 @@ module.exports = {
message: "Expected { after '{{name}}'{{suffix}}.",
data: {
name,
suffix: (suffix ? " " + suffix : "")
suffix: (suffix ? ` ${suffix}` : "")
}
});
}
@ -169,7 +169,7 @@ module.exports = {
message: "Unnecessary { after '{{name}}'{{suffix}}.",
data: {
name,
suffix: (suffix ? " " + suffix : "")
suffix: (suffix ? ` ${suffix}` : "")
}
});
}

57
tools/eslint/lib/rules/dot-notation.js

@ -32,12 +32,15 @@ module.exports = {
},
additionalProperties: false
}
]
],
fixable: "code"
},
create(context) {
const options = context.options[0] || {};
const allowKeywords = options.allowKeywords === void 0 || !!options.allowKeywords;
const sourceCode = context.getSourceCode();
let allowPattern;
@ -51,18 +54,62 @@ module.exports = {
node.computed &&
node.property.type === "Literal" &&
validIdentifier.test(node.property.value) &&
(allowKeywords || keywords.indexOf("" + node.property.value) === -1)
(allowKeywords || keywords.indexOf(String(node.property.value)) === -1)
) {
if (!(allowPattern && allowPattern.test(node.property.value))) {
context.report(node.property, "[" + JSON.stringify(node.property.value) + "] is better written in dot notation.");
context.report({
node: node.property,
message: "[{{propertyValue}}] is better written in dot notation.",
data: {
propertyValue: JSON.stringify(node.property.value)
},
fix(fixer) {
const leftBracket = sourceCode.getTokenBefore(node.property);
const rightBracket = sourceCode.getTokenAfter(node.property);
const textBeforeProperty = sourceCode.text.slice(leftBracket.range[1], node.property.range[0]);
const textAfterProperty = sourceCode.text.slice(node.property.range[1], rightBracket.range[0]);
if (textBeforeProperty.trim() || textAfterProperty.trim()) {
// Don't perform any fixes if there are comments inside the brackets.
return null;
}
return fixer.replaceTextRange(
[leftBracket.range[0], rightBracket.range[1]],
`.${node.property.value}`
);
}
});
}
}
if (
!allowKeywords &&
!node.computed &&
keywords.indexOf("" + node.property.name) !== -1
keywords.indexOf(String(node.property.name)) !== -1
) {
context.report(node.property, "." + node.property.name + " is a syntax error.");
context.report({
node: node.property,
message: ".{{propertyName}} is a syntax error.",
data: {
propertyName: node.property.name
},
fix(fixer) {
const dot = sourceCode.getTokenBefore(node.property);
const textAfterDot = sourceCode.text.slice(dot.range[1], node.property.range[0]);
if (textAfterDot.trim()) {
// Don't perform any fixes if there are comments between the dot and the property name.
return null;
}
return fixer.replaceTextRange(
[dot.range[0], node.property.range[1]],
`[${textAfterDot}"${node.property.name}"]`
);
}
});
}
}
};

7
tools/eslint/lib/rules/generator-star-spacing.js

@ -87,11 +87,16 @@ module.exports = {
const spaceRequired = mode[side];
const node = after ? leftToken : rightToken;
const type = spaceRequired ? "Missing" : "Unexpected";
const message = type + " space " + side + " *.";
const message = "{{type}} space {{side}} *.";
const data = {
type,
side
};
context.report({
node,
message,
data,
fix(fixer) {
if (spaceRequired) {
if (after) {

90
tools/eslint/lib/rules/indent.js

@ -73,6 +73,46 @@ module.exports = {
MemberExpression: {
type: "integer",
minimum: 0
},
FunctionDeclaration: {
type: "object",
properties: {
parameters: {
oneOf: [
{
type: "integer",
minimum: 0
},
{
enum: ["first"]
}
]
},
body: {
type: "integer",
minimum: 0
}
}
},
FunctionExpression: {
type: "object",
properties: {
parameters: {
oneOf: [
{
type: "integer",
minimum: 0
},
{
enum: ["first"]
}
]
},
body: {
type: "integer",
minimum: 0
}
}
}
},
additionalProperties: false
@ -84,6 +124,8 @@ module.exports = {
const MESSAGE = "Expected indentation of {{needed}} {{type}} {{characters}} but found {{gotten}}.";
const DEFAULT_VARIABLE_INDENT = 1;
const DEFAULT_PARAMETER_INDENT = null; // For backwards compatibility, don't check parameter indentation unless specified in the config
const DEFAULT_FUNCTION_BODY_INDENT = 1;
let indentType = "space";
let indentSize = 4;
@ -94,7 +136,15 @@ module.exports = {
let: DEFAULT_VARIABLE_INDENT,
const: DEFAULT_VARIABLE_INDENT
},
outerIIFEBody: null
outerIIFEBody: null,
FunctionDeclaration: {
parameters: DEFAULT_PARAMETER_INDENT,
body: DEFAULT_FUNCTION_BODY_INDENT
},
FunctionExpression: {
parameters: DEFAULT_PARAMETER_INDENT,
body: DEFAULT_FUNCTION_BODY_INDENT
}
};
const sourceCode = context.getSourceCode();
@ -131,6 +181,14 @@ module.exports = {
if (typeof opts.MemberExpression === "number") {
options.MemberExpression = opts.MemberExpression;
}
if (typeof opts.FunctionDeclaration === "object") {
Object.assign(options.FunctionDeclaration, opts.FunctionDeclaration);
}
if (typeof opts.FunctionExpression === "object") {
Object.assign(options.FunctionExpression, opts.FunctionExpression);
}
}
}
@ -168,7 +226,7 @@ module.exports = {
let rangeToFix = [];
if (needed > gotten) {
const spaces = "" + new Array(needed - gotten + 1).join(indentChar); // replace with repeat in future
const spaces = indentChar.repeat(needed - gotten);
if (isLastNodeCheck === true) {
rangeToFix = [
@ -492,11 +550,15 @@ module.exports = {
}
// function body indent should be indent + indent size, unless this
// is the outer IIFE and that option is enabled.
// is a FunctionDeclaration, FunctionExpression, or outer IIFE and the corresponding options are enabled.
let functionOffset = indentSize;
if (options.outerIIFEBody !== null && isOuterIIFE(calleeNode)) {
functionOffset = options.outerIIFEBody * indentSize;
} else if (calleeNode.type === "FunctionExpression") {
functionOffset = options.FunctionExpression.body * indentSize;
} else if (calleeNode.type === "FunctionDeclaration") {
functionOffset = options.FunctionDeclaration.body * indentSize;
}
indent += functionOffset;
@ -884,6 +946,28 @@ module.exports = {
const caseIndent = expectedCaseIndent(node);
checkNodesIndent(node.consequent, caseIndent + indentSize);
},
FunctionDeclaration(node) {
if (isSingleLineNode(node)) {
return;
}
if (options.FunctionDeclaration.parameters === "first" && node.params.length) {
checkNodesIndent(node.params.slice(1), node.params[0].loc.start.column);
} else if (options.FunctionDeclaration.parameters !== null) {
checkNodesIndent(node.params, indentSize * options.FunctionDeclaration.parameters);
}
},
FunctionExpression(node) {
if (isSingleLineNode(node)) {
return;
}
if (options.FunctionExpression.parameters === "first" && node.params.length) {
checkNodesIndent(node.params.slice(1), node.params[0].loc.start.column);
} else if (options.FunctionExpression.parameters !== null) {
checkNodesIndent(node.params, indentSize * options.FunctionExpression.parameters);
}
}
};

16
tools/eslint/lib/rules/init-declarations.js

@ -114,9 +114,21 @@ module.exports = {
}
if (mode === MODE_ALWAYS && !initialized) {
context.report(declaration, "Variable '" + id.name + "' should be initialized on declaration.");
context.report({
node: declaration,
message: "Variable '{{idName}}' should be initialized on declaration.",
data: {
idName: id.name
}
});
} else if (mode === MODE_NEVER && kind !== "const" && initialized && !isIgnoredForLoop) {
context.report(declaration, "Variable '" + id.name + "' should not be initialized on declaration.");
context.report({
node: declaration,
message: "Variable '{{idName}}' should not be initialized on declaration.",
data: {
idName: id.name
}
});
}
}
}

5
tools/eslint/lib/rules/jsx-quotes.js

@ -74,7 +74,10 @@ module.exports = {
if (attributeValue && astUtils.isStringLiteral(attributeValue) && !usesExpectedQuotes(attributeValue)) {
context.report({
node: attributeValue,
message: "Unexpected usage of " + setting.description + ".",
message: "Unexpected usage of {{description}}.",
data: {
description: setting.description
},
fix(fixer) {
return fixer.replaceText(attributeValue, setting.convert(attributeValue.raw));
}

5
tools/eslint/lib/rules/key-spacing.js

@ -136,7 +136,7 @@ function initOptions(toOptions, fromOptions) {
if (toOptions.multiLine.align) {
toOptions.align = {
on: toOptions.multiLine.align.on,
mode: toOptions.multiLine.mode,
mode: toOptions.multiLine.align.mode || toOptions.multiLine.mode,
beforeColon: toOptions.multiLine.align.beforeColon,
afterColon: toOptions.multiLine.align.afterColon
};
@ -289,6 +289,9 @@ module.exports = {
multiLine: {
type: "object",
properties: {
mode: {
enum: ["strict", "minimum"]
},
beforeColon: {
type: "boolean"
},

2
tools/eslint/lib/rules/keyword-spacing.js

@ -30,7 +30,7 @@ const KEYS = keywords.concat(["as", "await", "from", "get", "let", "of", "set",
KEYS.sort();
for (let i = 1; i < KEYS.length; ++i) {
if (KEYS[i] === KEYS[i - 1]) {
throw new Error("Duplication was found in the keyword list: " + KEYS[i]);
throw new Error(`Duplication was found in the keyword list: ${KEYS[i]}`);
}
}
}());

101
tools/eslint/lib/rules/line-comment-position.js

@ -0,0 +1,101 @@
/**
* @fileoverview Rule to enforce the position of line comments
* @author Alberto Rodríguez
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = {
meta: {
docs: {
description: "enforce position of line comments",
category: "Stylistic Issues",
recommended: false
},
schema: [
{
oneOf: [
{
enum: ["above", "beside"]
},
{
type: "object",
properties: {
position: {
enum: ["above", "beside"]
},
ignorePattern: {
type: "string"
},
applyDefaultPatterns: {
type: "boolean"
}
},
additionalProperties: false
}
]
}
]
},
create(context) {
const DEFAULT_IGNORE_PATTERN = "^\\s*(?:eslint|jshint\\s+|jslint\\s+|istanbul\\s+|globals?\\s+|exported\\s+|jscs|falls?\\s?through)";
const options = context.options[0];
let above,
ignorePattern,
applyDefaultPatterns = true;
if (!options || typeof option === "string") {
above = !options || options === "above";
} else {
above = options.position === "above";
ignorePattern = options.ignorePattern;
applyDefaultPatterns = options.applyDefaultPatterns !== false;
}
const defaultIgnoreRegExp = new RegExp(DEFAULT_IGNORE_PATTERN);
const customIgnoreRegExp = new RegExp(ignorePattern);
const sourceCode = context.getSourceCode();
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
return {
LineComment(node) {
if (applyDefaultPatterns && defaultIgnoreRegExp.test(node.value)) {
return;
}
if (ignorePattern && customIgnoreRegExp.test(node.value)) {
return;
}
const previous = sourceCode.getTokenOrCommentBefore(node);
const isOnSameLine = previous && previous.loc.end.line === node.loc.start.line;
if (above) {
if (isOnSameLine) {
context.report({
node,
message: "Expected comment to be above code."
});
}
} else {
if (!isOnSameLine) {
context.report({
node,
message: "Expected comment to be beside code."
});
}
}
}
};
}
};

165
tools/eslint/lib/rules/lines-around-directive.js

@ -0,0 +1,165 @@
/**
* @fileoverview Require or disallow newlines around directives.
* @author Kai Cataldo
*/
"use strict";
const astUtils = require("../ast-utils");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = {
meta: {
docs: {
description: "require or disallow newlines around directives",
category: "Stylistic Issues",
recommended: false
},
schema: [{
oneOf: [
{
enum: ["always", "never"]
},
{
type: "object",
properties: {
before: {
enum: ["always", "never"]
},
after: {
enum: ["always", "never"]
},
},
additionalProperties: false,
minProperties: 2
}
]
}]
},
create(context) {
const sourceCode = context.getSourceCode();
const config = context.options[0] || "always";
const expectLineBefore = typeof config === "string" ? config : config.before;
const expectLineAfter = typeof config === "string" ? config : config.after;
//--------------------------------------------------------------------------
// Helpers
//--------------------------------------------------------------------------
/**
* Check if node is preceded by a blank newline.
* @param {ASTNode} node Node to check.
* @returns {boolean} Whether or not the passed in node is preceded by a blank newline.
*/
function hasNewlineBefore(node) {
const tokenBefore = sourceCode.getTokenOrCommentBefore(node);
const tokenLineBefore = tokenBefore ? tokenBefore.loc.end.line : 0;
return node.loc.start.line - tokenLineBefore >= 2;
}
/**
* Check if node is followed by a blank newline.
* @param {ASTNode} node Node to check.
* @returns {boolean} Whether or not the passed in node is followed by a blank newline.
*/
function hasNewlineAfter(node) {
const tokenAfter = sourceCode.getTokenOrCommentAfter(node);
return tokenAfter.loc.start.line - node.loc.end.line >= 2;
}
/**
* Report errors for newlines around directives.
* @param {ASTNode} node Node to check.
* @param {string} location Whether the error was found before or after the directive.
* @param {boolean} expected Whether or not a newline was expected or unexpected.
* @returns {void}
*/
function reportError(node, location, expected) {
context.report({
node,
message: "{{expected}} newline {{location}} \"{{value}}\" directive.",
data: {
expected: expected ? "Expected" : "Unexpected",
value: node.expression.value,
location
}
});
}
/**
* Check lines around directives in node
* @param {ASTNode} node - node to check
* @returns {void}
*/
function checkDirectives(node) {
const directives = astUtils.getDirectivePrologue(node);
if (!directives.length) {
return;
}
const firstDirective = directives[0];
const hasTokenOrCommentBefore = !!sourceCode.getTokenOrCommentBefore(firstDirective);
// Only check before the first directive if it is preceded by a comment or if it is at the top of
// the file and expectLineBefore is set to "never". This is to not force a newline at the top of
// the file if there are no comments as well as for compatibility with padded-blocks.
if (
firstDirective.leadingComments && firstDirective.leadingComments.length ||
// Shebangs are not added to leading comments but are accounted for by the following.
node.type === "Program" && hasTokenOrCommentBefore
) {
if (expectLineBefore === "always" && !hasNewlineBefore(firstDirective)) {
reportError(firstDirective, "before", true);
}
if (expectLineBefore === "never" && hasNewlineBefore(firstDirective)) {
reportError(firstDirective, "before", false);
}
} else if (
node.type === "Program" &&
expectLineBefore === "never" &&
!hasTokenOrCommentBefore &&
hasNewlineBefore(firstDirective)
) {
reportError(firstDirective, "before", false);
}
const lastDirective = directives[directives.length - 1];
const statements = node.type === "Program" ? node.body : node.body.body;
// Do not check after the last directive if the body only
// contains a directive prologue and isn't followed by a comment to ensure
// this rule behaves well with padded-blocks.
if (lastDirective === statements[statements.length - 1] && !lastDirective.trailingComments) {
return;
}
if (expectLineAfter === "always" && !hasNewlineAfter(lastDirective)) {
reportError(lastDirective, "after", true);
}
if (expectLineAfter === "never" && hasNewlineAfter(lastDirective)) {
reportError(lastDirective, "after", false);
}
}
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
return {
Program: checkDirectives,
FunctionDeclaration: checkDirectives,
FunctionExpression: checkDirectives,
ArrowFunctionExpression: checkDirectives
};
}
};

92
tools/eslint/lib/rules/max-len.js

@ -30,9 +30,15 @@ const OPTIONS_SCHEMA = {
ignoreComments: {
type: "boolean"
},
ignoreStrings: {
type: "boolean"
},
ignoreUrls: {
type: "boolean"
},
ignoreTemplateLiterals: {
type: "boolean"
},
ignoreTrailingComments: {
type: "boolean"
}
@ -121,6 +127,8 @@ module.exports = {
const maxLength = options.code || 80,
tabWidth = options.tabWidth || 4,
ignoreComments = options.ignoreComments || false,
ignoreStrings = options.ignoreStrings || false,
ignoreTemplateLiterals = options.ignoreTemplateLiterals || false,
ignoreTrailingComments = options.ignoreTrailingComments || options.ignoreComments || false,
ignoreUrls = options.ignoreUrls || false,
maxCommentLength = options.comments;
@ -179,6 +187,59 @@ module.exports = {
return line.slice(0, comment.loc.start.column).replace(/\s+$/, "");
}
/**
* Ensure that an array exists at [key] on `object`, and add `value` to it.
*
* @param {Object} object the object to mutate
* @param {string} key the object's key
* @param {*} value the value to add
* @returns {void}
* @private
*/
function ensureArrayAndPush(object, key, value) {
if (!Array.isArray(object[key])) {
object[key] = [];
}
object[key].push(value);
}
/**
* Retrieves an array containing all strings (" or ') in the source code.
*
* @returns {ASTNode[]} An array of string nodes.
*/
function getAllStrings() {
return sourceCode.ast.tokens.filter(function(token) {
return token.type === "String";
});
}
/**
* Retrieves an array containing all template literals in the source code.
*
* @returns {ASTNode[]} An array of template literal nodes.
*/
function getAllTemplateLiterals() {
return sourceCode.ast.tokens.filter(function(token) {
return token.type === "Template";
});
}
/**
* A reducer to group an AST node by line number, both start and end.
*
* @param {Object} acc the accumulator
* @param {ASTNode} node the AST node in question
* @returns {Object} the modified accumulator
* @private
*/
function groupByLineNumber(acc, node) {
ensureArrayAndPush(acc, node.loc.start.line, node);
ensureArrayAndPush(acc, node.loc.end.line, node);
return acc;
}
/**
* Check the program for max length
* @param {ASTNode} node Node to examine
@ -196,6 +257,12 @@ module.exports = {
// we iterate over comments in parallel with the lines
let commentsIndex = 0;
const strings = getAllStrings(sourceCode);
const stringsByLine = strings.reduce(groupByLineNumber, {});
const templateLiterals = getAllTemplateLiterals(sourceCode);
const templateLiteralsByLine = templateLiterals.reduce(groupByLineNumber, {});
lines.forEach(function(line, i) {
// i is zero-indexed, line numbers are one-indexed
@ -229,7 +296,10 @@ module.exports = {
}
}
if (ignorePattern && ignorePattern.test(line) ||
ignoreUrls && URL_REGEXP.test(line)) {
ignoreUrls && URL_REGEXP.test(line) ||
ignoreStrings && stringsByLine[lineNumber] ||
ignoreTemplateLiterals && templateLiteralsByLine[lineNumber]
) {
// ignore this line
return;
@ -242,9 +312,25 @@ module.exports = {
}
if (lineIsComment && lineLength > maxCommentLength) {
context.report(node, { line: lineNumber, column: 0 }, "Line " + (i + 1) + " exceeds the maximum comment line length of " + maxCommentLength + ".");
context.report({
node,
loc: { line: lineNumber, column: 0 },
message: "Line {{lineNumber}} exceeds the maximum comment line length of {{maxCommentLength}}.",
data: {
lineNumber: i + 1,
maxCommentLength
}
});
} else if (lineLength > maxLength) {
context.report(node, { line: lineNumber, column: 0 }, "Line " + (i + 1) + " exceeds the maximum line length of " + maxLength + ".");
context.report({
node,
loc: { line: lineNumber, column: 0 },
message: "Line {{lineNumber}} exceeds the maximum line length of {{maxLength}}.",
data: {
lineNumber: i + 1,
maxLength
}
});
}
});
}

41
tools/eslint/lib/rules/max-statements-per-line.js

@ -35,9 +35,11 @@ module.exports = {
const sourceCode = context.getSourceCode(),
options = context.options[0] || {},
maxStatementsPerLine = typeof options.max !== "undefined" ? options.max : 1,
message = "This line has too many statements. Maximum allowed is " + maxStatementsPerLine + ".";
message = "This line has {{numberOfStatementsOnThisLine}} {{statements}}. Maximum allowed is {{maxStatementsPerLine}}.";
let lastStatementLine = 0,
numberOfStatementsOnThisLine = 0;
numberOfStatementsOnThisLine = 0,
firstExtraStatement;
//--------------------------------------------------------------------------
// Helpers
@ -45,6 +47,26 @@ module.exports = {
const SINGLE_CHILD_ALLOWED = /^(?:(?:DoWhile|For|ForIn|ForOf|If|Labeled|While)Statement|Export(?:Default|Named)Declaration)$/;
/**
* Reports with the first extra statement, and clears it.
*
* @returns {void}
*/
function reportFirstExtraStatementAndClear() {
if (firstExtraStatement) {
context.report({
node: firstExtraStatement,
message,
data: {
numberOfStatementsOnThisLine,
maxStatementsPerLine,
statements: numberOfStatementsOnThisLine === 1 ? "statement" : "statements",
}
});
}
firstExtraStatement = null;
}
/**
* Gets the actual last token of a given node.
*
@ -83,13 +105,14 @@ module.exports = {
if (line === lastStatementLine) {
numberOfStatementsOnThisLine += 1;
} else {
reportFirstExtraStatementAndClear();
numberOfStatementsOnThisLine = 1;
lastStatementLine = line;
}
// Reports if the node violated this rule.
if (numberOfStatementsOnThisLine === maxStatementsPerLine + 1) {
context.report({node, message});
firstExtraStatement = firstExtraStatement || node;
}
}
@ -104,6 +127,7 @@ module.exports = {
// Update state.
if (line !== lastStatementLine) {
reportFirstExtraStatementAndClear();
numberOfStatementsOnThisLine = 1;
lastStatementLine = line;
}
@ -161,12 +185,21 @@ module.exports = {
"ExportNamedDeclaration:exit": leaveStatement,
"ExportDefaultDeclaration:exit": leaveStatement,
"ExportAllDeclaration:exit": leaveStatement,
"Program:exit": reportFirstExtraStatementAndClear,
// For backward compatibility.
// Empty blocks should be warned if `{max: 0}` was given.
BlockStatement: function reportIfZero(node) {
if (maxStatementsPerLine === 0 && node.body.length === 0) {
context.report({node, message});
context.report({
node,
message,
data: {
numberOfStatementsOnThisLine: 0,
maxStatementsPerLine,
statements: "statements",
}
});
}
}
};

2
tools/eslint/lib/rules/new-cap.js

@ -37,7 +37,7 @@ function checkArray(obj, key, fallback) {
/* istanbul ignore if */
if (Object.prototype.hasOwnProperty.call(obj, key) && !Array.isArray(obj[key])) {
throw new TypeError(key + ", if provided, must be an Array");
throw new TypeError(`${key}, if provided, must be an Array`);
}
return obj[key] || fallback;
}

62
tools/eslint/lib/rules/new-parens.js

@ -5,6 +5,44 @@
"use strict";
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
/**
* Checks whether the given token is an opening parenthesis or not.
*
* @param {Token} token - The token to check.
* @returns {boolean} `true` if the token is an opening parenthesis.
*/
function isOpeningParen(token) {
return token.type === "Punctuator" && token.value === "(";
}
/**
* Checks whether the given token is an closing parenthesis or not.
*
* @param {Token} token - The token to check.
* @returns {boolean} `true` if the token is an closing parenthesis.
*/
function isClosingParen(token) {
return token.type === "Punctuator" && token.value === ")";
}
/**
* Checks whether the given node is inside of another given node.
*
* @param {ASTNode|Token} inner - The inner node to check.
* @param {ASTNode|Token} outer - The outer node to check.
* @returns {boolean} `true` if the `inner` is in `outer`.
*/
function isInRange(inner, outer) {
const ir = inner.range;
const or = outer.range;
return or[0] <= ir[0] && ir[1] <= or[1];
}
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
@ -17,25 +55,31 @@ module.exports = {
recommended: false
},
schema: []
schema: [],
fixable: "code"
},
create(context) {
const sourceCode = context.getSourceCode();
return {
NewExpression(node) {
const tokens = sourceCode.getTokens(node);
const prenticesTokens = tokens.filter(function(token) {
return token.value === "(" || token.value === ")";
});
let token = sourceCode.getTokenAfter(node.callee);
// Skip ')'
while (token && isClosingParen(token)) {
token = sourceCode.getTokenAfter(token);
}
if (prenticesTokens.length < 2) {
context.report(node, "Missing '()' invoking a constructor.");
if (!(token && isOpeningParen(token) && isInRange(token, node))) {
context.report({
node,
message: "Missing '()' invoking a constructor.",
fix: fixer => fixer.insertTextAfter(node, "()")
});
}
}
};
}
};

71
tools/eslint/lib/rules/newline-before-return.js

@ -15,7 +15,7 @@ module.exports = {
category: "Stylistic Issues",
recommended: false
},
fixable: "whitespace",
schema: []
},
@ -103,14 +103,13 @@ module.exports = {
}
/**
* Checks whether node is preceded by a newline
* @param {ASTNode} node - node to check
* @returns {boolean} Whether or not the node is preceded by a newline
* Returns the line number of the token before the node that is passed in as an argument
* @param {ASTNode} node - The node to use as the start of the calculation
* @returns {number} Line number of the token before `node`
* @private
*/
function hasNewlineBefore(node) {
const tokenBefore = sourceCode.getTokenBefore(node),
lineNumNode = node.loc.start.line;
function getLineNumberOfTokenBefore(node) {
const tokenBefore = sourceCode.getTokenBefore(node);
let lineNumTokenBefore;
/**
@ -127,11 +126,58 @@ module.exports = {
lineNumTokenBefore = 0; // global return at beginning of script
}
return lineNumTokenBefore;
}
/**
* Checks whether node is preceded by a newline
* @param {ASTNode} node - node to check
* @returns {boolean} Whether or not the node is preceded by a newline
* @private
*/
function hasNewlineBefore(node) {
const lineNumNode = node.loc.start.line;
const lineNumTokenBefore = getLineNumberOfTokenBefore(node);
const commentLines = calcCommentLines(node, lineNumTokenBefore);
return (lineNumNode - lineNumTokenBefore - commentLines) > 1;
}
/**
* Checks whether it is safe to apply a fix to a given return statement.
*
* The fix is not considered safe if the given return statement has leading comments,
* as we cannot safely determine if the newline should be added before or after the comments.
* For more information, see: https://github.com/eslint/eslint/issues/5958#issuecomment-222767211
*
* @param {ASTNode} node - The return statement node to check.
* @returns {boolean} `true` if it can fix the node.
* @private
*/
function canFix(node) {
const leadingComments = sourceCode.getComments(node).leading;
const lastLeadingComment = leadingComments[leadingComments.length - 1];
const tokenBefore = sourceCode.getTokenBefore(node);
if (leadingComments.length === 0) {
return true;
}
// if the last leading comment ends in the same line as the previous token and
// does not share a line with the `return` node, we can consider it safe to fix.
// Example:
// function a() {
// var b; //comment
// return;
// }
if (lastLeadingComment.loc.end.line === tokenBefore.loc.end.line &&
lastLeadingComment.loc.end.line !== node.loc.start.line) {
return true;
}
return false;
}
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
@ -141,7 +187,16 @@ module.exports = {
if (!isFirstNode(node) && !hasNewlineBefore(node)) {
context.report({
node,
message: "Expected newline before return statement."
message: "Expected newline before return statement.",
fix(fixer) {
if (canFix(node)) {
const tokenBefore = sourceCode.getTokenBefore(node);
const newlines = node.loc.start.line === tokenBefore.loc.end.line ? "\n\n" : "\n";
return fixer.insertTextBefore(node, newlines);
}
return null;
}
});
}
}

13
tools/eslint/lib/rules/newline-per-chained-call.js

@ -69,11 +69,14 @@ module.exports = {
}
if (depth > ignoreChainWithDepth && callee.property.loc.start.line === callee.object.loc.end.line) {
context.report(
callee.property,
callee.property.loc.start,
"Expected line break before `" + getPropertyText(callee) + "`."
);
context.report({
node: callee.property,
loc: callee.property.loc.start,
message: "Expected line break before `{{callee}}`.",
data: {
callee: getPropertyText(callee)
}
});
}
}
};

97
tools/eslint/lib/rules/no-console.js

@ -5,6 +5,12 @@
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
const astUtils = require("../ast-utils");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
@ -36,30 +42,89 @@ module.exports = {
},
create(context) {
const options = context.options[0] || {};
const allowed = options.allow || [];
return {
/**
* Checks whether the given reference is 'console' or not.
*
* @param {escope.Reference} reference - The reference to check.
* @returns {boolean} `true` if the reference is 'console'.
*/
function isConsole(reference) {
const id = reference.identifier;
MemberExpression(node) {
return id && id.name === "console";
}
if (node.object.name === "console") {
let blockConsole = true;
/**
* Checks whether the property name of the given MemberExpression node
* is allowed by options or not.
*
* @param {ASTNode} node - The MemberExpression node to check.
* @returns {boolean} `true` if the property name of the node is allowed.
*/
function isAllowed(node) {
const propertyName = astUtils.getStaticPropertyName(node);
if (context.options.length > 0) {
const allowedProperties = context.options[0].allow;
const passedProperty = node.property.name;
const propertyIsAllowed = (allowedProperties.indexOf(passedProperty) > -1);
return propertyName && allowed.indexOf(propertyName) !== -1;
}
if (propertyIsAllowed) {
blockConsole = false;
}
}
/**
* Checks whether the given reference is a member access which is not
* allowed by options or not.
*
* @param {escope.Reference} reference - The reference to check.
* @returns {boolean} `true` if the reference is a member access which
* is not allowed by options.
*/
function isMemberAccessExceptAllowed(reference) {
const node = reference.identifier;
const parent = node.parent;
if (blockConsole) {
context.report(node, "Unexpected console statement.");
}
return (
parent.type === "MemberExpression" &&
parent.object === node &&
!isAllowed(parent)
);
}
/**
* Reports the given reference as a violation.
*
* @param {escope.Reference} reference - The reference to report.
* @returns {void}
*/
function report(reference) {
const node = reference.identifier.parent;
context.report({
node,
loc: node.loc,
message: "Unexpected console statement."
});
}
return {
"Program:exit"() {
const scope = context.getScope();
const consoleVar = astUtils.getVariableByName(scope, "console");
const shadowed = consoleVar && consoleVar.defs.length > 0;
/* 'scope.through' includes all references to undefined
* variables. If the variable 'console' is not defined, it uses
* 'scope.through'.
*/
const references = consoleVar
? consoleVar.references
: scope.through.filter(isConsole);
if (!shadowed) {
references
.filter(isMemberAccessExceptAllowed)
.forEach(report);
}
}
};
}
};

6
tools/eslint/lib/rules/no-control-regex.js

@ -88,13 +88,15 @@ module.exports = {
.map(function(x) {
const match = x.match(stringControlCharWithoutSlash) || [x];
return "\\" + match[0];
return `\\${match[0]}`;
});
}
}
return controlChars.map(function(x) {
return "\\x" + ("0" + x.charCodeAt(0).toString(16)).slice(-2);
const hexCode = `0${x.charCodeAt(0).toString(16)}`.slice(-2);
return `\\x${hexCode}`;
}).concat(stringControlChars);
}

2
tools/eslint/lib/rules/no-dupe-class-members.js

@ -34,7 +34,7 @@ module.exports = {
*/
function getState(name, isStatic) {
const stateMap = stack[stack.length - 1];
const key = "$" + name; // to avoid "__proto__".
const key = `$${name}`; // to avoid "__proto__".
if (!stateMap[key]) {
stateMap[key] = {

7
tools/eslint/lib/rules/no-duplicate-imports.js

@ -37,8 +37,11 @@ function checkAndReport(context, node, value, array, message) {
if (array.indexOf(value) !== -1) {
context.report({
node,
message: "'{{module}}' " + message,
data: {module: value}
message: "'{{module}}' {{message}}",
data: {
module: value,
message
}
});
}
}

5
tools/eslint/lib/rules/no-empty-function.js

@ -146,7 +146,10 @@ module.exports = {
context.report({
node,
loc: node.body.loc.start,
message: "Unexpected empty " + SHOW_KIND[kind] + "."
message: "Unexpected empty {{kind}}.",
data: {
kind: SHOW_KIND[kind]
}
});
}
}

16
tools/eslint/lib/rules/no-extend-native.js

@ -74,7 +74,13 @@ module.exports = {
modifiedBuiltins.forEach(function(builtin) {
if (lhs.object.object.name === builtin) {
context.report(node, builtin + " prototype is read only, properties should not be added.");
context.report({
node,
message: "{{builtin}} prototype is read only, properties should not be added.",
data: {
builtin
}
});
}
});
},
@ -98,7 +104,13 @@ module.exports = {
(modifiedBuiltins.indexOf(object.name) > -1) &&
subject.property.name === "prototype") {
context.report(node, object.name + " prototype is read only, properties should not be added.");
context.report({
node,
message: "{{objectName}} prototype is read only, properties should not be added.",
data: {
objectName: object.name
}
});
}
}

16
tools/eslint/lib/rules/no-floating-decimal.js

@ -17,7 +17,9 @@ module.exports = {
recommended: false
},
schema: []
schema: [],
fixable: "code"
},
create(context) {
@ -27,10 +29,18 @@ module.exports = {
if (typeof node.value === "number") {
if (node.raw.indexOf(".") === 0) {
context.report(node, "A leading decimal point can be confused with a dot.");
context.report({
node,
message: "A leading decimal point can be confused with a dot.",
fix: fixer => fixer.insertTextBefore(node, "0")
});
}
if (node.raw.indexOf(".") === node.raw.length - 1) {
context.report(node, "A trailing decimal point can be confused with a dot.");
context.report({
node,
message: "A trailing decimal point can be confused with a dot.",
fix: fixer => fixer.insertTextAfter(node, "0")
});
}
}
}

111
tools/eslint/lib/rules/no-implicit-coercion.js

@ -5,6 +5,8 @@
"use strict";
const astUtils = require("../ast-utils");
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
@ -105,6 +107,26 @@ function getNonNumericOperand(node) {
return null;
}
/**
* Checks whether a node is a string literal or not.
* @param {ASTNode} node The node to check.
* @returns {boolean} Whether or not the passed in node is a
* string literal or not.
*/
function isStringLiteral(node) {
return astUtils.isStringLiteral(node) && node.type !== "TemplateLiteral";
}
/**
* Checks whether a node is an empty string literal or not.
* @param {ASTNode} node The node to check.
* @returns {boolean} Whether or not the passed in node is an
* empty string literal or not.
*/
function isEmptyString(node) {
return isStringLiteral(node) && node.value === "";
}
/**
* Checks whether or not a node is a concatenating with an empty string.
* @param {ASTNode} node - A BinaryExpression node to check.
@ -112,8 +134,8 @@ function getNonNumericOperand(node) {
*/
function isConcatWithEmptyString(node) {
return node.operator === "+" && (
(node.left.type === "Literal" && node.left.value === "") ||
(node.right.type === "Literal" && node.right.value === "")
(isEmptyString(node.left) && !isStringLiteral(node.right)) ||
(isEmptyString(node.right) && !isStringLiteral(node.left))
);
}
@ -123,20 +145,16 @@ function isConcatWithEmptyString(node) {
* @returns {boolean} Whether or not the node is appended with an empty string.
*/
function isAppendEmptyString(node) {
return node.operator === "+=" && node.right.type === "Literal" && node.right.value === "";
return node.operator === "+=" && isEmptyString(node.right);
}
/**
* Gets a node that is the left or right operand of a node, is not the specified literal.
* @param {ASTNode} node - A BinaryExpression node to get.
* @param {any} value - A literal value to check.
* @returns {ASTNode} A node that is the left or right operand of the node, is not the specified literal.
* Returns the operand that is not an empty string from a flagged BinaryExpression.
* @param {ASTNode} node - The flagged BinaryExpression node to check.
* @returns {ASTNode} The operand that is not an empty string from a flagged BinaryExpression.
*/
function getOtherOperand(node, value) {
if (node.left.type === "Literal" && node.left.value === value) {
return node.right;
}
return node.left;
function getNonEmptyOperand(node) {
return isEmptyString(node.left) ? node.right : node.left;
}
//------------------------------------------------------------------------------
@ -151,6 +169,7 @@ module.exports = {
recommended: false
},
fixable: "code",
schema: [{
type: "object",
properties: {
@ -179,6 +198,25 @@ module.exports = {
const options = parseOptions(context.options[0]);
const sourceCode = context.getSourceCode();
/**
* Reports an error and autofixes the node
* @param {ASTNode} node - An ast node to report the error on.
* @param {string} recommendation - The recommended code for the issue
* @returns {void}
*/
function report(node, recommendation) {
context.report({
node,
message: "use `{{recommendation}}` instead.",
data: {
recommendation
},
fix(fixer) {
return fixer.replaceText(node, recommendation);
}
});
}
return {
UnaryExpression(node) {
let operatorAllowed;
@ -186,31 +224,25 @@ module.exports = {
// !!foo
operatorAllowed = options.allow.indexOf("!!") >= 0;
if (!operatorAllowed && options.boolean && isDoubleLogicalNegating(node)) {
context.report(
node,
"use `Boolean({{code}})` instead.", {
code: sourceCode.getText(node.argument.argument)
});
const recommendation = `Boolean(${sourceCode.getText(node.argument.argument)})`;
report(node, recommendation);
}
// ~foo.indexOf(bar)
operatorAllowed = options.allow.indexOf("~") >= 0;
if (!operatorAllowed && options.boolean && isBinaryNegatingOfIndexOf(node)) {
context.report(
node,
"use `{{code}} !== -1` instead.", {
code: sourceCode.getText(node.argument)
});
const recommendation = `${sourceCode.getText(node.argument)} !== -1`;
report(node, recommendation);
}
// +foo
operatorAllowed = options.allow.indexOf("+") >= 0;
if (!operatorAllowed && options.number && node.operator === "+" && !isNumeric(node.argument)) {
context.report(
node,
"use `Number({{code}})` instead.", {
code: sourceCode.getText(node.argument)
});
const recommendation = `Number(${sourceCode.getText(node.argument)})`;
report(node, recommendation);
}
},
@ -223,21 +255,17 @@ module.exports = {
const nonNumericOperand = !operatorAllowed && options.number && isMultiplyByOne(node) && getNonNumericOperand(node);
if (nonNumericOperand) {
context.report(
node,
"use `Number({{code}})` instead.", {
code: sourceCode.getText(nonNumericOperand)
});
const recommendation = `Number(${sourceCode.getText(nonNumericOperand)})`;
report(node, recommendation);
}
// "" + foo
operatorAllowed = options.allow.indexOf("+") >= 0;
if (!operatorAllowed && options.string && isConcatWithEmptyString(node)) {
context.report(
node,
"use `String({{code}})` instead.", {
code: sourceCode.getText(getOtherOperand(node, ""))
});
const recommendation = `String(${sourceCode.getText(getNonEmptyOperand(node))})`;
report(node, recommendation);
}
},
@ -247,11 +275,10 @@ module.exports = {
const operatorAllowed = options.allow.indexOf("+") >= 0;
if (!operatorAllowed && options.string && isAppendEmptyString(node)) {
context.report(
node,
"use `{{code}} = String({{code}})` instead.", {
code: sourceCode.getText(getOtherOperand(node, ""))
});
const code = sourceCode.getText(getNonEmptyOperand(node));
const recommendation = `${code} = String(${code})`;
report(node, recommendation);
}
}
};

17
tools/eslint/lib/rules/no-invalid-regexp.js

@ -66,21 +66,30 @@ module.exports = {
let flags = isString(node.arguments[1]) ? node.arguments[1].value : "";
if (allowedFlags) {
flags = flags.replace(new RegExp("[" + allowedFlags + "]", "gi"), "");
flags = flags.replace(new RegExp(`[${allowedFlags}]`, "gi"), "");
}
try {
void new RegExp(node.arguments[0].value);
} catch (e) {
context.report(node, e.message + ".");
context.report({
node,
message: `${e.message}.`
});
}
if (flags) {
try {
espree.parse("/./" + flags, context.parserOptions);
espree.parse(`/./${flags}`, context.parserOptions);
} catch (ex) {
context.report(node, "Invalid flags supplied to RegExp constructor '" + flags + "'.");
context.report({
node,
message: "Invalid flags supplied to RegExp constructor '{{flags}}'.",
data: {
flags
}
});
}
}

13
tools/eslint/lib/rules/no-magic-numbers.js

@ -114,7 +114,7 @@ module.exports = {
node = parent;
parent = node.parent;
value = -value;
raw = "-" + raw;
raw = `-${raw}`;
}
if (shouldIgnoreNumber(value) ||
@ -131,11 +131,16 @@ module.exports = {
message: "Number constants declarations must use 'const'."
});
}
} else if (okTypes.indexOf(parent.type) === -1 ||
(parent.type === "AssignmentExpression" && parent.operator !== "=")) {
} else if (
okTypes.indexOf(parent.type) === -1 ||
(parent.type === "AssignmentExpression" && parent.left.type === "Identifier")
) {
context.report({
node,
message: "No magic number: " + raw + "."
message: "No magic number: {{raw}}.",
data: {
raw
}
});
}
}

13
tools/eslint/lib/rules/no-mixed-operators.js

@ -173,18 +173,23 @@ module.exports = {
const left = (parent.left === node) ? node : parent;
const right = (parent.left !== node) ? node : parent;
const message =
"Unexpected mix of '" + left.operator + "' and '" +
right.operator + "'.";
"Unexpected mix of '{{leftOperator}}' and '{{rightOperator}}'.";
const data = {
leftOperator: left.operator,
rightOperator: right.operator
};
context.report({
node: left,
loc: getOperatorToken(left).loc.start,
message
message,
data
});
context.report({
node: right,
loc: getOperatorToken(right).loc.start,
message
message,
data
});
}

18
tools/eslint/lib/rules/no-multiple-empty-lines.js

@ -146,7 +146,10 @@ module.exports = {
context.report({
node,
loc: node.loc.start,
message: "Too many blank lines at the beginning of file. Max of " + maxBOF + " allowed.",
message: "Too many blank lines at the beginning of file. Max of {{maxBOF}} allowed.",
data: {
maxBOF
},
fix
});
}
@ -162,7 +165,7 @@ module.exports = {
} else {
const location = {
line: lastLocation + 1,
column: 1
column: 0
};
if (lastLocation < firstOfEndingBlankLines) {
@ -176,7 +179,11 @@ module.exports = {
context.report({
node,
loc: location,
message: "More than " + max + " blank " + (max === 1 ? "line" : "lines") + " not allowed.",
message: "More than {{max}} blank {{lines}} not allowed.",
data: {
max,
lines: (max === 1 ? "line" : "lines")
},
fix
});
}
@ -190,7 +197,10 @@ module.exports = {
context.report({
node,
loc: location,
message: "Too many blank lines at the end of file. Max of " + maxEOF + " allowed.",
message: "Too many blank lines at the end of file. Max of {{maxEOF}} allowed.",
data: {
maxEOF
},
fix
});
}

8
tools/eslint/lib/rules/no-plusplus.js

@ -46,7 +46,13 @@ module.exports = {
if (allowInForAfterthought && node.parent.type === "ForStatement") {
return;
}
context.report(node, "Unary operator '" + node.operator + "' used.");
context.report({
node,
message: "Unary operator '{{operator}}' used.",
data: {
operator: node.operator
}
});
}
};

13
tools/eslint/lib/rules/no-regex-spaces.js

@ -35,7 +35,18 @@ module.exports = {
regexResults = multipleSpacesRegex.exec(value);
if (regexResults !== null) {
context.report(node, "Spaces are hard to count. Use {" + regexResults[0].length + "}.");
context.report({
node,
message: "Spaces are hard to count. Use {{{count}}}.",
data: {
count: regexResults[0].length
}
});
/*
* TODO: (platinumazure) Fix message to use rule message
* substitution when api.report is fixed in lib/eslint.js.
*/
}
}

88
tools/eslint/lib/rules/no-restricted-properties.js

@ -0,0 +1,88 @@
/**
* @fileoverview Rule to disallow certain object properties
* @author Will Klein & Eli White
*/
"use strict";
const astUtils = require("../ast-utils");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = {
meta: {
docs: {
description: "disallow certain properties on certain objects",
category: "Node.js and CommonJS",
recommended: false
},
schema: {
type: "array",
items: {
type: "object",
properties: {
object: {
type: "string"
},
property: {
type: "string"
},
message: {
type: "string"
}
},
additionalProperties: false,
required: [
"object",
"property"
]
},
uniqueItems: true
}
},
create(context) {
const restrictedCalls = context.options;
if (restrictedCalls.length === 0) {
return {};
}
const restrictedProperties = restrictedCalls.reduce(function(restrictions, option) {
const objectName = option.object;
const propertyName = option.property;
if (!restrictions.has(objectName)) {
restrictions.set(objectName, new Map());
}
restrictions.get(objectName).set(propertyName, {
message: option.message
});
return restrictions;
}, new Map());
return {
MemberExpression(node) {
const objectName = node.object && node.object.name;
const propertyName = astUtils.getStaticPropertyName(node);
const matchedObject = restrictedProperties.get(objectName);
const matchedObjectProperty = matchedObject && matchedObject.get(propertyName);
if (matchedObjectProperty) {
const message = matchedObjectProperty.message ? " " + matchedObjectProperty.message : "";
context.report(node, "'{{objectName}}.{{propertyName}}' is restricted from being used.{{message}}", {
objectName,
propertyName,
message
});
}
}
};
}
};

8
tools/eslint/lib/rules/no-shadow-restricted-names.js

@ -31,7 +31,13 @@ module.exports = {
*/
function checkForViolation(id) {
if (RESTRICTED.indexOf(id.name) > -1) {
context.report(id, "Shadowing of global property '" + id.name + "'.");
context.report({
node: id,
message: "Shadowing of global property '{{idName}}'.",
data: {
idName: id.name
}
});
}
}

8
tools/eslint/lib/rules/no-sync.js

@ -31,7 +31,13 @@ module.exports = {
syncRegex = /.*Sync$/;
if (syncRegex.exec(propertyName) !== null) {
context.report(node, "Unexpected sync method: '" + propertyName + "'.");
context.report({
node,
message: "Unexpected sync method: '{{propertyName}}'.",
data: {
propertyName
}
});
}
}
};

4
tools/eslint/lib/rules/no-trailing-spaces.js

@ -35,8 +35,8 @@ module.exports = {
const sourceCode = context.getSourceCode();
const BLANK_CLASS = "[ \t\u00a0\u2000-\u200b\u2028\u2029\u3000]",
SKIP_BLANK = "^" + BLANK_CLASS + "*$",
NONBLANK = BLANK_CLASS + "+$";
SKIP_BLANK = `^${BLANK_CLASS}*$`,
NONBLANK = `${BLANK_CLASS}+$`;
const options = context.options[0] || {},
skipBlankLines = options.skipBlankLines || false;

24
tools/eslint/lib/rules/no-underscore-dangle.js

@ -107,7 +107,13 @@ module.exports = {
const identifier = node.id.name;
if (typeof identifier !== "undefined" && hasTrailingUnderscore(identifier) && !isAllowed(identifier)) {
context.report(node, "Unexpected dangling '_' in '" + identifier + "'.");
context.report({
node,
message: "Unexpected dangling '_' in '{{identifier}}'.",
data: {
identifier
}
});
}
}
}
@ -123,7 +129,13 @@ module.exports = {
if (typeof identifier !== "undefined" && hasTrailingUnderscore(identifier) &&
!isSpecialCaseIdentifierInVariableExpression(identifier) && !isAllowed(identifier)) {
context.report(node, "Unexpected dangling '_' in '" + identifier + "'.");
context.report({
node,
message: "Unexpected dangling '_' in '{{identifier}}'.",
data: {
identifier
}
});
}
}
@ -142,7 +154,13 @@ module.exports = {
!(isMemberOfThis && allowAfterThis) &&
!(isMemberOfSuper && allowAfterSuper) &&
!isSpecialCaseIdentifierForMemberExpression(identifier) && !isAllowed(identifier)) {
context.report(node, "Unexpected dangling '_' in '" + identifier + "'.");
context.report({
node,
message: "Unexpected dangling '_' in '{{identifier}}'.",
data: {
identifier
}
});
}
}

5
tools/eslint/lib/rules/no-unsafe-finally.js

@ -83,7 +83,10 @@ module.exports = {
function check(node) {
if (isInFinallyBlock(node, node.label)) {
context.report({
message: "Unsafe usage of " + node.type + ".",
message: "Unsafe usage of {{nodeType}}.",
data: {
nodeType: node.type
},
node,
line: node.loc.line,
column: node.loc.column

2
tools/eslint/lib/rules/no-unused-vars.js

@ -514,7 +514,7 @@ module.exports = {
* @private
*/
function getColumnInComment(variable, comment) {
const namePattern = new RegExp("[\\s,]" + lodash.escapeRegExp(variable.name) + "(?:$|[\\s,:])", "g");
const namePattern = new RegExp(`[\\s,]${lodash.escapeRegExp(variable.name)}(?:$|[\\s,:])`, "g");
// To ignore the first text "global".
namePattern.lastIndex = comment.value.indexOf("global") + 6;

5
tools/eslint/lib/rules/no-useless-escape.js

@ -90,7 +90,10 @@ module.exports = {
line: node.loc.start.line,
column: node.loc.start.column + elm.index
},
message: "Unnecessary escape character: " + elm[0] + "."
message: "Unnecessary escape character: {{character}}.",
data: {
character: elm[0]
}
});
}
}

8
tools/eslint/lib/rules/no-warning-comments.js

@ -117,7 +117,13 @@ module.exports = {
const matches = commentContainsWarningTerm(node.value);
matches.forEach(function(matchedTerm) {
context.report(node, "Unexpected '" + matchedTerm + "' comment.");
context.report({
node,
message: "Unexpected '{{matchedTerm}}' comment.",
data: {
matchedTerm
}
});
});
}

20
tools/eslint/lib/rules/object-curly-spacing.js

@ -74,7 +74,10 @@ module.exports = {
context.report({
node,
loc: token.loc.start,
message: "There should be no space after '" + token.value + "'.",
message: "There should be no space after '{{token}}'.",
data: {
token: token.value
},
fix(fixer) {
const nextToken = context.getSourceCode().getTokenAfter(token);
@ -93,7 +96,10 @@ module.exports = {
context.report({
node,
loc: token.loc.start,
message: "There should be no space before '" + token.value + "'.",
message: "There should be no space before '{{token}}'.",
data: {
token: token.value
},
fix(fixer) {
const previousToken = context.getSourceCode().getTokenBefore(token);
@ -112,7 +118,10 @@ module.exports = {
context.report({
node,
loc: token.loc.start,
message: "A space is required after '" + token.value + "'.",
message: "A space is required after '{{token}}'.",
data: {
token: token.value
},
fix(fixer) {
return fixer.insertTextAfter(token, " ");
}
@ -129,7 +138,10 @@ module.exports = {
context.report({
node,
loc: token.loc.start,
message: "A space is required before '" + token.value + "'.",
message: "A space is required before '{{token}}'.",
data: {
token: token.value
},
fix(fixer) {
return fixer.insertTextBefore(token, " ");
}

13
tools/eslint/lib/rules/object-shorthand.js

@ -237,17 +237,20 @@ module.exports = {
context.report({
node,
message: "Expected longform " + type + " syntax.",
message: "Expected longform {{type}} syntax.",
data: {
type
},
fix(fixer) {
if (node.method) {
if (node.value.generator) {
return fixer.replaceTextRange([node.range[0], node.key.range[1]], node.key.name + ": function*");
return fixer.replaceTextRange([node.range[0], node.key.range[1]], `${node.key.name}: function*`);
}
return fixer.insertTextAfter(node.key, ": function");
}
return fixer.insertTextAfter(node.key, ": " + node.key.name);
return fixer.insertTextAfter(node.key, `: ${node.key.name}`);
}
});
}
@ -289,7 +292,7 @@ module.exports = {
if (node.value.generator) {
return fixer.replaceTextRange(
[node.key.range[0], node.value.range[0] + "function*".length],
"*[" + node.key.name + "]"
`*[${node.key.name}]`
);
}
@ -307,7 +310,7 @@ module.exports = {
if (node.value.generator) {
return fixer.replaceTextRange(
[node.key.range[0], node.value.range[0] + "function*".length],
"*" + node.key.name
`*${node.key.name}`
);
}

48
tools/eslint/lib/rules/one-var.js

@ -279,16 +279,34 @@ module.exports = {
// always
if (!hasOnlyOneStatement(type, declarations)) {
if (options[type].initialized === MODE_ALWAYS && options[type].uninitialized === MODE_ALWAYS) {
context.report(node, "Combine this with the previous '" + type + "' statement.");
context.report({
node,
message: "Combine this with the previous '{{type}}' statement.",
data: {
type
}
});
} else {
if (options[type].initialized === MODE_ALWAYS) {
context.report(node, "Combine this with the previous '" + type + "' statement with initialized variables.");
context.report({
node,
message: "Combine this with the previous '{{type}}' statement with initialized variables.",
data: {
type
}
});
}
if (options[type].uninitialized === MODE_ALWAYS) {
if (node.parent.left === node && (node.parent.type === "ForInStatement" || node.parent.type === "ForOfStatement")) {
return;
}
context.report(node, "Combine this with the previous '" + type + "' statement with uninitialized variables.");
context.report({
node,
message: "Combine this with the previous '{{type}}' statement with uninitialized variables.",
data: {
type
}
});
}
}
}
@ -302,15 +320,33 @@ module.exports = {
if (options[type].initialized === MODE_NEVER && options[type].uninitialized === MODE_NEVER) {
// both initialized and uninitialized
context.report(node, "Split '" + type + "' declarations into multiple statements.");
context.report({
node,
message: "Split '{{type}}' declarations into multiple statements.",
data: {
type
}
});
} else if (options[type].initialized === MODE_NEVER && declarationCounts.initialized > 0) {
// initialized
context.report(node, "Split initialized '" + type + "' declarations into multiple statements.");
context.report({
node,
message: "Split initialized '{{type}}' declarations into multiple statements.",
data: {
type
}
});
} else if (options[type].uninitialized === MODE_NEVER && declarationCounts.uninitialized > 0) {
// uninitialized
context.report(node, "Split uninitialized '" + type + "' declarations into multiple statements.");
context.report({
node,
message: "Split uninitialized '{{type}}' declarations into multiple statements.",
data: {
type
}
});
}
}
}

60
tools/eslint/lib/rules/operator-linebreak.js

@ -98,31 +98,59 @@ module.exports = {
!astUtils.isTokenOnSameLine(operatorToken, rightToken)) {
// lone operator
context.report(node, {
line: operatorToken.loc.end.line,
column: operatorToken.loc.end.column
}, "Bad line breaking before and after '" + operator + "'.");
context.report({
node,
loc: {
line: operatorToken.loc.end.line,
column: operatorToken.loc.end.column
},
message: "Bad line breaking before and after '{{operator}}'.",
data: {
operator
}
});
} else if (style === "before" && astUtils.isTokenOnSameLine(leftToken, operatorToken)) {
context.report(node, {
line: operatorToken.loc.end.line,
column: operatorToken.loc.end.column
}, "'" + operator + "' should be placed at the beginning of the line.");
context.report({
node,
loc: {
line: operatorToken.loc.end.line,
column: operatorToken.loc.end.column
},
message: "'{{operator}}' should be placed at the beginning of the line.",
data: {
operator
}
});
} else if (style === "after" && astUtils.isTokenOnSameLine(operatorToken, rightToken)) {
context.report(node, {
line: operatorToken.loc.end.line,
column: operatorToken.loc.end.column
}, "'" + operator + "' should be placed at the end of the line.");
context.report({
node,
loc: {
line: operatorToken.loc.end.line,
column: operatorToken.loc.end.column
},
message: "'{{operator}}' should be placed at the end of the line.",
data: {
operator
}
});
} else if (style === "none") {
context.report(node, {
line: operatorToken.loc.end.line,
column: operatorToken.loc.end.column
}, "There should be no line break before or after '" + operator + "'.");
context.report({
node,
loc: {
line: operatorToken.loc.end.line,
column: operatorToken.loc.end.column
},
message: "There should be no line break before or after '{{operator}}'.",
data: {
operator
}
});
}
}

44
tools/eslint/lib/rules/prefer-arrow-callback.js

@ -115,6 +115,17 @@ function getCallbackInfo(node) {
throw new Error("unreachable");
}
/**
* Checks whether a simple list of parameters contains any duplicates. This does not handle complex
parameter lists (e.g. with destructuring), since complex parameter lists are a SyntaxError with duplicate
parameter names anyway. Instead, it always returns `false` for complex parameter lists.
* @param {ASTNode[]} paramsList The list of parameters for a function
* @returns {boolean} `true` if the list of parameters contains any duplicates
*/
function hasDuplicateParams(paramsList) {
return paramsList.every(param => param.type === "Identifier") && paramsList.length !== new Set(paramsList.map(param => param.name)).size;
}
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
@ -140,7 +151,9 @@ module.exports = {
},
additionalProperties: false
}
]
],
fixable: "code"
},
create(context) {
@ -148,6 +161,7 @@ module.exports = {
const allowUnboundThis = options.allowUnboundThis !== false; // default to true
const allowNamedFunctions = options.allowNamedFunctions;
const sourceCode = context.getSourceCode();
/*
* {Array<{this: boolean, super: boolean, meta: boolean}>}
@ -246,7 +260,33 @@ module.exports = {
!scopeInfo.super &&
!scopeInfo.meta
) {
context.report(node, "Unexpected function expression.");
context.report({
node,
message: "Unexpected function expression.",
fix(fixer) {
if ((!callbackInfo.isLexicalThis && scopeInfo.this) || hasDuplicateParams(node.params)) {
// If the callback function does not have .bind(this) and contains a reference to `this`, there
// is no way to determine what `this` should be, so don't perform any fixes.
// If the callback function has duplicates in its list of parameters (possible in sloppy mode),
// don't replace it with an arrow function, because this is a SyntaxError with arrow functions.
return null;
}
const paramsLeftParen = node.params.length ? sourceCode.getTokenBefore(node.params[0]) : sourceCode.getTokenBefore(node.body, 1);
const paramsRightParen = sourceCode.getTokenBefore(node.body);
const paramsFullText = sourceCode.text.slice(paramsLeftParen.range[0], paramsRightParen.range[1]);
if (callbackInfo.isLexicalThis) {
// If the callback function has `.bind(this)`, replace it with an arrow function and remove the binding.
return fixer.replaceText(node.parent.parent, paramsFullText + " => " + sourceCode.getText(node.body));
}
// Otherwise, only replace the `function` keyword and parameters with the arrow function parameters.
return fixer.replaceTextRange([node.start, node.body.start], paramsFullText + " => ");
}
});
}
}
};

62
tools/eslint/lib/rules/prefer-numeric-literals.js

@ -0,0 +1,62 @@
/**
* @fileoverview Rule to disallow `parseInt()` in favor of binary, octal, and hexadecimal literals
* @author Annie Zhang, Henry Zhu
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = {
meta: {
docs: {
description: "disallow `parseInt()` in favor of binary, octal, and hexadecimal literals",
category: "ECMAScript 6",
recommended: false
},
schema: []
},
create(context) {
const radixMap = {
2: "binary",
8: "octal",
16: "hexadecimal"
};
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
return {
CallExpression(node) {
// doesn't check parseInt() if it doesn't have a radix argument
if (node.arguments.length !== 2) {
return;
}
// only error if the radix is 2, 8, or 16
const radixName = radixMap[node.arguments[1].value];
if (node.callee.type === "Identifier" &&
node.callee.name === "parseInt" &&
radixName &&
node.arguments[0].type === "Literal"
) {
context.report({
node,
message: "Use {{radixName}} literals instead of parseInt().",
data: {
radixName
}
});
}
}
};
}
};

2
tools/eslint/lib/rules/quote-props.js

@ -97,7 +97,7 @@ module.exports = {
function areQuotesRedundant(rawKey, tokens, skipNumberLiterals) {
return tokens.length === 1 && tokens[0].start === 0 && tokens[0].end === rawKey.length &&
(["Identifier", "Keyword", "Null", "Boolean"].indexOf(tokens[0].type) >= 0 ||
(tokens[0].type === "Numeric" && !skipNumberLiterals && "" + +tokens[0].value === tokens[0].value));
(tokens[0].type === "Numeric" && !skipNumberLiterals && String(+tokens[0].value) === tokens[0].value));
}
/**

12
tools/eslint/lib/rules/quotes.js

@ -56,7 +56,7 @@ QUOTE_SETTINGS.backtick.convert = function(str) {
return escaped; // unescape
}
if (match === newQuote || newQuote === "`" && match === "${") {
return "\\" + match; // escape
return `\\${match}`; // escape
}
if (newline && oldQuote === "`") {
return "\\n"; // escape newlines
@ -225,7 +225,10 @@ module.exports = {
if (!isValid) {
context.report({
node,
message: "Strings must use " + settings.description + ".",
message: "Strings must use {{description}}.",
data: {
description: settings.description
},
fix(fixer) {
return fixer.replaceText(node, settings.convert(node.raw));
}
@ -246,7 +249,10 @@ module.exports = {
if (shouldWarn) {
context.report({
node,
message: "Strings must use " + settings.description + ".",
message: "Strings must use {{description}}.",
data: {
description: settings.description,
},
fix(fixer) {
return fixer.replaceText(node, settings.convert(sourceCode.getText(node)));
}

30
tools/eslint/lib/rules/space-unary-ops.js

@ -100,7 +100,10 @@ module.exports = {
if (secondToken.range[0] === firstToken.range[1]) {
context.report({
node,
message: "Unary word operator '" + word + "' must be followed by whitespace.",
message: "Unary word operator '{{word}}' must be followed by whitespace.",
data: {
word
},
fix(fixer) {
return fixer.insertTextAfter(firstToken, " ");
}
@ -121,7 +124,10 @@ module.exports = {
if (secondToken.range[0] > firstToken.range[1]) {
context.report({
node,
message: "Unexpected space after unary word operator '" + word + "'.",
message: "Unexpected space after unary word operator '{{word}}'.",
data: {
word
},
fix(fixer) {
return fixer.removeRange([firstToken.range[1], secondToken.range[0]]);
}
@ -185,7 +191,10 @@ module.exports = {
if (firstToken.range[1] === secondToken.range[0]) {
context.report({
node,
message: "Unary operator '" + firstToken.value + "' must be followed by whitespace.",
message: "Unary operator '{{operator}}' must be followed by whitespace.",
data: {
operator: firstToken.value
},
fix(fixer) {
return fixer.insertTextAfter(firstToken, " ");
}
@ -195,7 +204,10 @@ module.exports = {
if (firstToken.range[1] === secondToken.range[0]) {
context.report({
node,
message: "Space is required before unary expressions '" + secondToken.value + "'.",
message: "Space is required before unary expressions '{{token}}'.",
data: {
token: secondToken.value
},
fix(fixer) {
return fixer.insertTextBefore(secondToken, " ");
}
@ -216,7 +228,10 @@ module.exports = {
if (secondToken.range[0] > firstToken.range[1]) {
context.report({
node,
message: "Unexpected space after unary operator '" + firstToken.value + "'.",
message: "Unexpected space after unary operator '{{operator}}'.",
data: {
operator: firstToken.value
},
fix(fixer) {
return fixer.removeRange([firstToken.range[1], secondToken.range[0]]);
}
@ -226,7 +241,10 @@ module.exports = {
if (secondToken.range[0] > firstToken.range[1]) {
context.report({
node,
message: "Unexpected space before unary operator '" + secondToken.value + "'.",
message: "Unexpected space before unary operator '{{operator}}'.",
data: {
operator: secondToken.value
},
fix(fixer) {
return fixer.removeRange([firstToken.range[1], secondToken.range[0]]);
}

24
tools/eslint/lib/rules/spaced-comment.js

@ -19,7 +19,7 @@ function escape(s) {
const isOneChar = s.length === 1;
s = lodash.escapeRegExp(s);
return isOneChar ? s : "(?:" + s + ")";
return isOneChar ? s : `(?:${s})`;
}
/**
@ -29,7 +29,7 @@ function escape(s) {
* @returns {string} An escaped string.
*/
function escapeAndRepeat(s) {
return escape(s) + "+";
return `${escape(s)}+`;
}
/**
@ -144,7 +144,7 @@ function createAlwaysStylePattern(markers, exceptions) {
* @returns {RegExp} A RegExp object for `never` mode.
*/
function createNeverStylePattern(markers) {
const pattern = "^(" + markers.map(escape).join("|") + ")?[ \t]+";
const pattern = `^(${markers.map(escape).join("|")})?[ \t]+`;
return new RegExp(pattern);
}
@ -248,9 +248,9 @@ module.exports = {
// Create RegExp object for valid patterns.
rule[type] = {
beginRegex: requireSpace ? createAlwaysStylePattern(markers, exceptions) : createNeverStylePattern(markers),
endRegex: balanced && requireSpace ? new RegExp(createExceptionsPattern(exceptions) + "$") : new RegExp(endNeverPattern),
endRegex: balanced && requireSpace ? new RegExp(`${createExceptionsPattern(exceptions)}$`) : new RegExp(endNeverPattern),
hasExceptions: exceptions.length > 0,
markers: new RegExp("^(" + markers.map(escape).join("|") + ")")
markers: new RegExp(`^(${markers.map(escape).join("|")})`)
};
return rule;
@ -261,9 +261,10 @@ module.exports = {
* @param {ASTNode} node - A comment node to check.
* @param {string} message - An error message to report.
* @param {Array} match - An array of match results for markers.
* @param {string} refChar - Character used for reference in the error message.
* @returns {void}
*/
function reportBegin(node, message, match) {
function reportBegin(node, message, match, refChar) {
const type = node.type.toLowerCase(),
commentIdentifier = type === "block" ? "/*" : "//";
@ -283,7 +284,8 @@ module.exports = {
return fixer.replaceTextRange([start, end], commentIdentifier + (match[1] ? match[1] : ""));
}
},
message
message,
data: { refChar }
});
}
@ -336,9 +338,9 @@ module.exports = {
const marker = hasMarker ? commentIdentifier + hasMarker[0] : commentIdentifier;
if (rule.hasExceptions) {
reportBegin(node, "Expected exception block, space or tab after '" + marker + "' in comment.", hasMarker);
reportBegin(node, "Expected exception block, space or tab after '{{refChar}}' in comment.", hasMarker, marker);
} else {
reportBegin(node, "Expected space or tab after '" + marker + "' in comment.", hasMarker);
reportBegin(node, "Expected space or tab after '{{refChar}}' in comment.", hasMarker, marker);
}
}
@ -348,9 +350,9 @@ module.exports = {
} else {
if (beginMatch) {
if (!beginMatch[1]) {
reportBegin(node, "Unexpected space or tab after '" + commentIdentifier + "' in comment.", beginMatch);
reportBegin(node, "Unexpected space or tab after '{{refChar}}' in comment.", beginMatch, commentIdentifier);
} else {
reportBegin(node, "Unexpected space or tab after marker (" + beginMatch[1] + ") in comment.", beginMatch);
reportBegin(node, "Unexpected space or tab after marker ({{refChar}}) in comment.", beginMatch, beginMatch[1]);
}
}

10
tools/eslint/lib/rules/template-curly-spacing.js

@ -57,7 +57,10 @@ module.exports = {
) {
context.report({
loc: token.loc.start,
message: prefix + " space(s) before '}'.",
message: "{{prefix}} space(s) before '}'.",
data: {
prefix
},
fix(fixer) {
if (always) {
return fixer.insertTextBefore(token, " ");
@ -89,7 +92,10 @@ module.exports = {
line: token.loc.end.line,
column: token.loc.end.column - 2
},
message: prefix + " space(s) after '${'.",
message: "{{prefix}} space(s) after '${'.",
data: {
prefix
},
fix(fixer) {
if (always) {
return fixer.insertTextAfter(token, " ");

16
tools/eslint/lib/rules/valid-jsdoc.js

@ -279,7 +279,13 @@ module.exports = {
hasReturns = true;
if (!requireReturn && !functionData.returnPresent && (tag.type === null || !isValidReturnType(tag)) && !isAbstract) {
context.report(jsdocNode, "Unexpected @" + tag.title + " tag; function has no return statement.");
context.report({
node: jsdocNode,
message: "Unexpected @{{title}} tag; function has no return statement.",
data: {
title: tag.title
}
});
} else {
if (requireReturnType && !tag.type) {
context.report(jsdocNode, "Missing JSDoc return type.");
@ -330,7 +336,13 @@ module.exports = {
node.parent.kind !== "get" && node.parent.kind !== "constructor" &&
node.parent.kind !== "set" && !isTypeClass(node)) {
if (requireReturn || functionData.returnPresent) {
context.report(jsdocNode, "Missing JSDoc @" + (prefer.returns || "returns") + " for function.");
context.report({
node: jsdocNode,
message: "Missing JSDoc @{{returns}} for function.",
data: {
returns: prefer.returns || "returns"
}
});
}
}

10
tools/eslint/lib/rules/wrap-regex.js

@ -17,7 +17,9 @@ module.exports = {
recommended: false
},
schema: []
schema: [],
fixable: "code"
},
create(context) {
@ -36,7 +38,11 @@ module.exports = {
if (grandparent.type === "MemberExpression" && grandparent.object === node &&
(!source || source.value !== "(")) {
context.report(node, "Wrap the regexp literal in parens to disambiguate the slash.");
context.report({
node,
message: "Wrap the regexp literal in parens to disambiguate the slash.",
fix: fixer => fixer.replaceText(node, `(${sourceCode.getText(node)})`)
});
}
}
}

6
tools/eslint/lib/rules/yield-star-spacing.js

@ -68,11 +68,15 @@ module.exports = {
const spaceRequired = mode[side];
const node = after ? leftToken : rightToken;
const type = spaceRequired ? "Missing" : "Unexpected";
const message = type + " space " + side + " *.";
const message = "{{type}} space {{side}} *.";
context.report({
node,
message,
data: {
type,
side
},
fix(fixer) {
if (spaceRequired) {
if (after) {

18
tools/eslint/lib/rules/yoda.js

@ -69,7 +69,7 @@ function getNormalizedLiteral(node) {
return {
type: "Literal",
value: -node.argument.value,
raw: "-" + node.argument.value
raw: `-${node.argument.value}`
};
}
@ -234,7 +234,13 @@ module.exports = {
isComparisonOperator(node.operator) &&
!(exceptRange && isRangeTest(context.getAncestors().pop()))
) {
context.report(node, "Expected literal to be on the left side of " + node.operator + ".");
context.report({
node,
message: "Expected literal to be on the left side of {{operator}}.",
data: {
operator: node.operator
}
});
}
} : function(node) {
@ -247,7 +253,13 @@ module.exports = {
isComparisonOperator(node.operator) &&
!(exceptRange && isRangeTest(context.getAncestors().pop()))
) {
context.report(node, "Expected literal to be on the right side of " + node.operator + ".");
context.report({
node,
message: "Expected literal to be on the right side of {{operator}}.",
data: {
operator: node.operator
}
});
}
}

30
tools/eslint/lib/util/glob-util.js

@ -104,28 +104,22 @@ function resolveFileGlobPatterns(patterns, options) {
* @returns {string[]} Resolved absolute filenames.
*/
function listFilesToProcess(globPatterns, options) {
options = options || { ignore: true };
const files = [],
added = {};
const cwd = (options && options.cwd) || process.cwd();
options = options || { ignore: true, dotfiles: true };
const ignoredPaths = new IgnoredPaths(options);
const globOptions = {
nodir: true,
cwd
};
const shouldIgnore = ignoredPaths.getIgnoredFoldersGlobChecker();
/**
* Executes the linter on a file defined by the `filename`. Skips
* unsupported file extensions and any files that are already linted.
* @param {string} filename The file to be processed
* @param {boolean} shouldWarnIgnored Whether or not a report should be made if
* the file is ignored
* @param {IgnoredPaths} ignoredPaths An instance of IgnoredPaths
* @returns {void}
*/
function addFile(filename, shouldWarnIgnored) {
function addFile(filename, shouldWarnIgnored, ignoredPaths) {
let ignored = false;
let isSilentlyIgnored;
@ -160,10 +154,24 @@ function listFilesToProcess(globPatterns, options) {
const file = path.resolve(cwd, pattern);
if (shell.test("-f", file)) {
addFile(fs.realpathSync(file), !shell.test("-d", file));
const ignoredPaths = new IgnoredPaths(options);
addFile(fs.realpathSync(file), !shell.test("-d", file), ignoredPaths);
} else {
// regex to find .hidden or /.hidden patterns, but not ./relative or ../relative
const globIncludesDotfiles = /(?:(?:^\.)|(?:[\/\\]\.))[^\/\\\.].*/.test(pattern);
const ignoredPaths = new IgnoredPaths(Object.assign({}, options, {dotfiles: options.dotfiles || globIncludesDotfiles}));
const shouldIgnore = ignoredPaths.getIgnoredFoldersGlobChecker();
const globOptions = {
nodir: true,
dot: true,
cwd,
};
new GlobSync(pattern, globOptions, shouldIgnore).found.forEach(function(globMatch) {
addFile(path.resolve(cwd, globMatch), false);
addFile(path.resolve(cwd, globMatch), false, ignoredPaths);
});
}
});

3
tools/eslint/messages/whitespace-found.txt

@ -0,0 +1,3 @@
ESLint couldn't find the plugin "<%- pluginName %>". because there is whitespace in the name. Please check your configuration and remove all whitespace from the plugin name.
If you still can't figure out the problem, please stop by https://gitter.im/eslint/eslint to chat with the team.

97
tools/eslint/node_modules/bluebird/js/browser/bluebird.core.js

@ -23,7 +23,7 @@
*
*/
/**
* bluebird build version 3.4.3
* bluebird build version 3.4.6
* Features enabled: core
* Features disabled: race, call_get, generators, map, nodeify, promisify, props, reduce, settle, some, using, timers, filter, any, each
*/
@ -624,14 +624,16 @@ Promise.prototype._warn = function(message, shouldUseOwnTrace, promise) {
Promise.onPossiblyUnhandledRejection = function (fn) {
var domain = getDomain();
possiblyUnhandledRejection =
typeof fn === "function" ? (domain === null ? fn : domain.bind(fn))
typeof fn === "function" ? (domain === null ?
fn : util.domainBind(domain, fn))
: undefined;
};
Promise.onUnhandledRejectionHandled = function (fn) {
var domain = getDomain();
unhandledRejectionHandled =
typeof fn === "function" ? (domain === null ? fn : domain.bind(fn))
typeof fn === "function" ? (domain === null ?
fn : util.domainBind(domain, fn))
: undefined;
};
@ -671,7 +673,20 @@ var fireDomEvent = (function() {
var event = new CustomEvent("CustomEvent");
util.global.dispatchEvent(event);
return function(name, event) {
var domEvent = new CustomEvent(name.toLowerCase(), event);
var domEvent = new CustomEvent(name.toLowerCase(), {
detail: event,
cancelable: true
});
return !util.global.dispatchEvent(domEvent);
};
} else if (typeof Event === "function") {
var event = new Event("CustomEvent");
util.global.dispatchEvent(event);
return function(name, event) {
var domEvent = new Event(name.toLowerCase(), {
cancelable: true
});
domEvent.detail = event;
return !util.global.dispatchEvent(domEvent);
};
} else {
@ -1427,7 +1442,7 @@ return {
},{"./errors":9,"./util":21}],8:[function(_dereq_,module,exports){
"use strict";
module.exports = function(Promise, tryConvertToPromise) {
module.exports = function(Promise) {
function returner() {
return this.value;
}
@ -1437,7 +1452,6 @@ function thrower() {
Promise.prototype["return"] =
Promise.prototype.thenReturn = function (value) {
value = tryConvertToPromise(value);
if (value instanceof Promise) value.suppressUnhandledRejections();
return this._then(
returner, undefined, undefined, {value: value}, undefined);
@ -1462,13 +1476,11 @@ Promise.prototype.catchThrow = function (reason) {
Promise.prototype.catchReturn = function (value) {
if (arguments.length <= 1) {
value = tryConvertToPromise(value);
if (value instanceof Promise) value.suppressUnhandledRejections();
return this._then(
undefined, returner, undefined, {value: value}, undefined);
} else {
var _value = arguments[1];
_value = tryConvertToPromise(_value);
if (_value instanceof Promise) _value.suppressUnhandledRejections();
var handler = function() {return _value;};
return this.caught(value, handler);
@ -1792,7 +1804,8 @@ return PassThroughHandlerContext;
},{"./util":21}],12:[function(_dereq_,module,exports){
"use strict";
module.exports =
function(Promise, PromiseArray, tryConvertToPromise, INTERNAL) {
function(Promise, PromiseArray, tryConvertToPromise, INTERNAL, async,
getDomain) {
var util = _dereq_("./util");
var canEvaluate = util.canEvaluate;
var tryCatch = util.tryCatch;
@ -1834,25 +1847,35 @@ if (canEvaluate) {
var name = "Holder$" + total;
var code = "return function(tryCatch, errorObj, Promise) { \n\
var code = "return function(tryCatch, errorObj, Promise, async) { \n\
'use strict'; \n\
function [TheName](fn) { \n\
[TheProperties] \n\
this.fn = fn; \n\
this.asyncNeeded = true; \n\
this.now = 0; \n\
} \n\
\n\
[TheName].prototype._callFunction = function(promise) { \n\
promise._pushContext(); \n\
var ret = tryCatch(this.fn)([ThePassedArguments]); \n\
promise._popContext(); \n\
if (ret === errorObj) { \n\
promise._rejectCallback(ret.e, false); \n\
} else { \n\
promise._resolveCallback(ret); \n\
} \n\
}; \n\
\n\
[TheName].prototype.checkFulfillment = function(promise) { \n\
var now = ++this.now; \n\
if (now === [TheTotal]) { \n\
promise._pushContext(); \n\
var callback = this.fn; \n\
var ret = tryCatch(callback)([ThePassedArguments]); \n\
promise._popContext(); \n\
if (ret === errorObj) { \n\
promise._rejectCallback(ret.e, false); \n\
if (this.asyncNeeded) { \n\
async.invoke(this._callFunction, this, promise); \n\
} else { \n\
promise._resolveCallback(ret); \n\
this._callFunction(promise); \n\
} \n\
\n\
} \n\
}; \n\
\n\
@ -1861,7 +1884,7 @@ if (canEvaluate) {
}; \n\
\n\
return [TheName]; \n\
}(tryCatch, errorObj, Promise); \n\
}(tryCatch, errorObj, Promise, async); \n\
";
code = code.replace(/\[TheName\]/g, name)
@ -1870,8 +1893,8 @@ if (canEvaluate) {
.replace(/\[TheProperties\]/g, assignment)
.replace(/\[CancellationCode\]/g, cancellationCode);
return new Function("tryCatch", "errorObj", "Promise", code)
(tryCatch, errorObj, Promise);
return new Function("tryCatch", "errorObj", "Promise", "async", code)
(tryCatch, errorObj, Promise, async);
};
var holderClasses = [];
@ -1912,6 +1935,7 @@ Promise.join = function () {
maybePromise._then(callbacks[i], reject,
undefined, ret, holder);
promiseSetters[i](maybePromise, holder);
holder.asyncNeeded = false;
} else if (((bitField & 33554432) !== 0)) {
callbacks[i].call(ret,
maybePromise._value(), holder);
@ -1924,7 +1948,14 @@ Promise.join = function () {
callbacks[i].call(ret, maybePromise, holder);
}
}
if (!ret._isFateSealed()) {
if (holder.asyncNeeded) {
var domain = getDomain();
if (domain !== null) {
holder.fn = util.domainBind(domain, holder.fn);
}
}
ret._setAsyncGuaranteed();
ret._setOnCancel(holder);
}
@ -2312,7 +2343,8 @@ Promise.prototype._then = function (
async.invoke(settler, target, {
handler: domain === null ? handler
: (typeof handler === "function" && domain.bind(handler)),
: (typeof handler === "function" &&
util.domainBind(domain, handler)),
promise: promise,
receiver: receiver,
value: value
@ -2448,11 +2480,11 @@ Promise.prototype._addCallbacks = function (
this._receiver0 = receiver;
if (typeof fulfill === "function") {
this._fulfillmentHandler0 =
domain === null ? fulfill : domain.bind(fulfill);
domain === null ? fulfill : util.domainBind(domain, fulfill);
}
if (typeof reject === "function") {
this._rejectionHandler0 =
domain === null ? reject : domain.bind(reject);
domain === null ? reject : util.domainBind(domain, reject);
}
} else {
var base = index * 4 - 4;
@ -2460,11 +2492,11 @@ Promise.prototype._addCallbacks = function (
this[base + 3] = receiver;
if (typeof fulfill === "function") {
this[base + 0] =
domain === null ? fulfill : domain.bind(fulfill);
domain === null ? fulfill : util.domainBind(domain, fulfill);
}
if (typeof reject === "function") {
this[base + 1] =
domain === null ? reject : domain.bind(reject);
domain === null ? reject : util.domainBind(domain, reject);
}
}
this._setLength(index + 1);
@ -2778,12 +2810,12 @@ _dereq_("./method")(Promise, INTERNAL, tryConvertToPromise, apiRejection,
debug);
_dereq_("./bind")(Promise, INTERNAL, tryConvertToPromise, debug);
_dereq_("./cancel")(Promise, PromiseArray, apiRejection, debug);
_dereq_("./direct_resolve")(Promise, tryConvertToPromise);
_dereq_("./direct_resolve")(Promise);
_dereq_("./synchronous_inspection")(Promise);
_dereq_("./join")(
Promise, PromiseArray, tryConvertToPromise, INTERNAL, debug);
Promise, PromiseArray, tryConvertToPromise, INTERNAL, async, getDomain);
Promise.Promise = Promise;
Promise.version = "3.4.3";
Promise.version = "3.4.6";
util.toFastProperties(Promise);
util.toFastProperties(Promise.prototype);
@ -3110,7 +3142,7 @@ if (util.isNode && typeof MutationObserver === "undefined") {
} else if ((typeof MutationObserver !== "undefined") &&
!(typeof window !== "undefined" &&
window.navigator &&
window.navigator.standalone)) {
(window.navigator.standalone || window.cordova))) {
schedule = (function() {
var div = document.createElement("div");
var opts = {attributes: true};
@ -3671,6 +3703,10 @@ function getNativePromise() {
}
}
function domainBind(self, cb) {
return self.bind(cb);
}
var ret = {
isClass: isClass,
isIdentifier: isIdentifier,
@ -3703,7 +3739,8 @@ var ret = {
isNode: isNode,
env: env,
global: globalObject,
getNativePromise: getNativePromise
getNativePromise: getNativePromise,
domainBind: domainBind
};
ret.isRecentNode = ret.isNode && (function() {
var version = process.versions.node.split(".").map(Number);

6
tools/eslint/node_modules/bluebird/js/browser/bluebird.core.min.js

File diff suppressed because one or more lines are too long

136
tools/eslint/node_modules/bluebird/js/browser/bluebird.js

@ -23,7 +23,7 @@
*
*/
/**
* bluebird build version 3.4.3
* bluebird build version 3.4.6
* Features enabled: core, race, call_get, generators, map, nodeify, promisify, props, reduce, settle, some, using, timers, filter, any, each
*/
!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.Promise=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof _dereq_=="function"&&_dereq_;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof _dereq_=="function"&&_dereq_;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
@ -771,14 +771,16 @@ Promise.prototype._warn = function(message, shouldUseOwnTrace, promise) {
Promise.onPossiblyUnhandledRejection = function (fn) {
var domain = getDomain();
possiblyUnhandledRejection =
typeof fn === "function" ? (domain === null ? fn : domain.bind(fn))
typeof fn === "function" ? (domain === null ?
fn : util.domainBind(domain, fn))
: undefined;
};
Promise.onUnhandledRejectionHandled = function (fn) {
var domain = getDomain();
unhandledRejectionHandled =
typeof fn === "function" ? (domain === null ? fn : domain.bind(fn))
typeof fn === "function" ? (domain === null ?
fn : util.domainBind(domain, fn))
: undefined;
};
@ -818,7 +820,20 @@ var fireDomEvent = (function() {
var event = new CustomEvent("CustomEvent");
util.global.dispatchEvent(event);
return function(name, event) {
var domEvent = new CustomEvent(name.toLowerCase(), event);
var domEvent = new CustomEvent(name.toLowerCase(), {
detail: event,
cancelable: true
});
return !util.global.dispatchEvent(domEvent);
};
} else if (typeof Event === "function") {
var event = new Event("CustomEvent");
util.global.dispatchEvent(event);
return function(name, event) {
var domEvent = new Event(name.toLowerCase(), {
cancelable: true
});
domEvent.detail = event;
return !util.global.dispatchEvent(domEvent);
};
} else {
@ -1574,7 +1589,7 @@ return {
},{"./errors":12,"./util":36}],10:[function(_dereq_,module,exports){
"use strict";
module.exports = function(Promise, tryConvertToPromise) {
module.exports = function(Promise) {
function returner() {
return this.value;
}
@ -1584,7 +1599,6 @@ function thrower() {
Promise.prototype["return"] =
Promise.prototype.thenReturn = function (value) {
value = tryConvertToPromise(value);
if (value instanceof Promise) value.suppressUnhandledRejections();
return this._then(
returner, undefined, undefined, {value: value}, undefined);
@ -1609,13 +1623,11 @@ Promise.prototype.catchThrow = function (reason) {
Promise.prototype.catchReturn = function (value) {
if (arguments.length <= 1) {
value = tryConvertToPromise(value);
if (value instanceof Promise) value.suppressUnhandledRejections();
return this._then(
undefined, returner, undefined, {value: value}, undefined);
} else {
var _value = arguments[1];
_value = tryConvertToPromise(_value);
if (_value instanceof Promise) _value.suppressUnhandledRejections();
var handler = function() {return _value;};
return this.caught(value, handler);
@ -1638,8 +1650,8 @@ function PromiseMapSeries(promises, fn) {
}
Promise.prototype.each = function (fn) {
return this.mapSeries(fn)
._then(promiseAllThis, undefined, undefined, this, undefined);
return PromiseReduce(this, fn, INTERNAL, 0)
._then(promiseAllThis, undefined, undefined, this, undefined);
};
Promise.prototype.mapSeries = function (fn) {
@ -1647,13 +1659,14 @@ Promise.prototype.mapSeries = function (fn) {
};
Promise.each = function (promises, fn) {
return PromiseMapSeries(promises, fn)
._then(promiseAllThis, undefined, undefined, promises, undefined);
return PromiseReduce(promises, fn, INTERNAL, 0)
._then(promiseAllThis, undefined, undefined, promises, undefined);
};
Promise.mapSeries = PromiseMapSeries;
};
},{}],12:[function(_dereq_,module,exports){
"use strict";
var es5 = _dereq_("./es5");
@ -2209,7 +2222,8 @@ Promise.spawn = function (generatorFunction) {
},{"./errors":12,"./util":36}],17:[function(_dereq_,module,exports){
"use strict";
module.exports =
function(Promise, PromiseArray, tryConvertToPromise, INTERNAL) {
function(Promise, PromiseArray, tryConvertToPromise, INTERNAL, async,
getDomain) {
var util = _dereq_("./util");
var canEvaluate = util.canEvaluate;
var tryCatch = util.tryCatch;
@ -2251,25 +2265,35 @@ if (canEvaluate) {
var name = "Holder$" + total;
var code = "return function(tryCatch, errorObj, Promise) { \n\
var code = "return function(tryCatch, errorObj, Promise, async) { \n\
'use strict'; \n\
function [TheName](fn) { \n\
[TheProperties] \n\
this.fn = fn; \n\
this.asyncNeeded = true; \n\
this.now = 0; \n\
} \n\
\n\
[TheName].prototype._callFunction = function(promise) { \n\
promise._pushContext(); \n\
var ret = tryCatch(this.fn)([ThePassedArguments]); \n\
promise._popContext(); \n\
if (ret === errorObj) { \n\
promise._rejectCallback(ret.e, false); \n\
} else { \n\
promise._resolveCallback(ret); \n\
} \n\
}; \n\
\n\
[TheName].prototype.checkFulfillment = function(promise) { \n\
var now = ++this.now; \n\
if (now === [TheTotal]) { \n\
promise._pushContext(); \n\
var callback = this.fn; \n\
var ret = tryCatch(callback)([ThePassedArguments]); \n\
promise._popContext(); \n\
if (ret === errorObj) { \n\
promise._rejectCallback(ret.e, false); \n\
if (this.asyncNeeded) { \n\
async.invoke(this._callFunction, this, promise); \n\
} else { \n\
promise._resolveCallback(ret); \n\
this._callFunction(promise); \n\
} \n\
\n\
} \n\
}; \n\
\n\
@ -2278,7 +2302,7 @@ if (canEvaluate) {
}; \n\
\n\
return [TheName]; \n\
}(tryCatch, errorObj, Promise); \n\
}(tryCatch, errorObj, Promise, async); \n\
";
code = code.replace(/\[TheName\]/g, name)
@ -2287,8 +2311,8 @@ if (canEvaluate) {
.replace(/\[TheProperties\]/g, assignment)
.replace(/\[CancellationCode\]/g, cancellationCode);
return new Function("tryCatch", "errorObj", "Promise", code)
(tryCatch, errorObj, Promise);
return new Function("tryCatch", "errorObj", "Promise", "async", code)
(tryCatch, errorObj, Promise, async);
};
var holderClasses = [];
@ -2329,6 +2353,7 @@ Promise.join = function () {
maybePromise._then(callbacks[i], reject,
undefined, ret, holder);
promiseSetters[i](maybePromise, holder);
holder.asyncNeeded = false;
} else if (((bitField & 33554432) !== 0)) {
callbacks[i].call(ret,
maybePromise._value(), holder);
@ -2341,7 +2366,14 @@ Promise.join = function () {
callbacks[i].call(ret, maybePromise, holder);
}
}
if (!ret._isFateSealed()) {
if (holder.asyncNeeded) {
var domain = getDomain();
if (domain !== null) {
holder.fn = util.domainBind(domain, holder.fn);
}
}
ret._setAsyncGuaranteed();
ret._setOnCancel(holder);
}
@ -2369,23 +2401,27 @@ var getDomain = Promise._getDomain;
var util = _dereq_("./util");
var tryCatch = util.tryCatch;
var errorObj = util.errorObj;
var EMPTY_ARRAY = [];
var async = Promise._async;
function MappingPromiseArray(promises, fn, limit, _filter) {
this.constructor$(promises);
this._promise._captureStackTrace();
var domain = getDomain();
this._callback = domain === null ? fn : domain.bind(fn);
this._callback = domain === null ? fn : util.domainBind(domain, fn);
this._preservedValues = _filter === INTERNAL
? new Array(this.length())
: null;
this._limit = limit;
this._inFlight = 0;
this._queue = limit >= 1 ? [] : EMPTY_ARRAY;
this._init$(undefined, -2);
this._queue = [];
async.invoke(this._asyncInit, this, undefined);
}
util.inherits(MappingPromiseArray, PromiseArray);
MappingPromiseArray.prototype._asyncInit = function() {
this._init$(undefined, -2);
};
MappingPromiseArray.prototype._init = function () {};
MappingPromiseArray.prototype._promiseFulfilled = function (value, index) {
@ -2955,7 +2991,8 @@ Promise.prototype._then = function (
async.invoke(settler, target, {
handler: domain === null ? handler
: (typeof handler === "function" && domain.bind(handler)),
: (typeof handler === "function" &&
util.domainBind(domain, handler)),
promise: promise,
receiver: receiver,
value: value
@ -3091,11 +3128,11 @@ Promise.prototype._addCallbacks = function (
this._receiver0 = receiver;
if (typeof fulfill === "function") {
this._fulfillmentHandler0 =
domain === null ? fulfill : domain.bind(fulfill);
domain === null ? fulfill : util.domainBind(domain, fulfill);
}
if (typeof reject === "function") {
this._rejectionHandler0 =
domain === null ? reject : domain.bind(reject);
domain === null ? reject : util.domainBind(domain, reject);
}
} else {
var base = index * 4 - 4;
@ -3103,11 +3140,11 @@ Promise.prototype._addCallbacks = function (
this[base + 3] = receiver;
if (typeof fulfill === "function") {
this[base + 0] =
domain === null ? fulfill : domain.bind(fulfill);
domain === null ? fulfill : util.domainBind(domain, fulfill);
}
if (typeof reject === "function") {
this[base + 1] =
domain === null ? reject : domain.bind(reject);
domain === null ? reject : util.domainBind(domain, reject);
}
}
this._setLength(index + 1);
@ -3421,12 +3458,12 @@ _dereq_("./method")(Promise, INTERNAL, tryConvertToPromise, apiRejection,
debug);
_dereq_("./bind")(Promise, INTERNAL, tryConvertToPromise, debug);
_dereq_("./cancel")(Promise, PromiseArray, apiRejection, debug);
_dereq_("./direct_resolve")(Promise, tryConvertToPromise);
_dereq_("./direct_resolve")(Promise);
_dereq_("./synchronous_inspection")(Promise);
_dereq_("./join")(
Promise, PromiseArray, tryConvertToPromise, INTERNAL, debug);
Promise, PromiseArray, tryConvertToPromise, INTERNAL, async, getDomain);
Promise.Promise = Promise;
Promise.version = "3.4.3";
Promise.version = "3.4.6";
_dereq_('./map.js')(Promise, PromiseArray, apiRejection, tryConvertToPromise, INTERNAL, debug);
_dereq_('./call_get.js')(Promise);
_dereq_('./using.js')(Promise, apiRejection, tryConvertToPromise, createContext, INTERNAL, debug);
@ -4247,27 +4284,37 @@ var tryCatch = util.tryCatch;
function ReductionPromiseArray(promises, fn, initialValue, _each) {
this.constructor$(promises);
var domain = getDomain();
this._fn = domain === null ? fn : domain.bind(fn);
this._fn = domain === null ? fn : util.domainBind(domain, fn);
if (initialValue !== undefined) {
initialValue = Promise.resolve(initialValue);
initialValue._attachCancellationCallback(this);
}
this._initialValue = initialValue;
this._currentCancellable = null;
this._eachValues = _each === INTERNAL ? [] : undefined;
if(_each === INTERNAL) {
this._eachValues = Array(this._length);
} else if (_each === 0) {
this._eachValues = null;
} else {
this._eachValues = undefined;
}
this._promise._captureStackTrace();
this._init$(undefined, -5);
}
util.inherits(ReductionPromiseArray, PromiseArray);
ReductionPromiseArray.prototype._gotAccum = function(accum) {
if (this._eachValues !== undefined && accum !== INTERNAL) {
if (this._eachValues !== undefined &&
this._eachValues !== null &&
accum !== INTERNAL) {
this._eachValues.push(accum);
}
};
ReductionPromiseArray.prototype._eachComplete = function(value) {
this._eachValues.push(value);
if (this._eachValues !== null) {
this._eachValues.push(value);
}
return this._eachValues;
};
@ -4419,7 +4466,7 @@ if (util.isNode && typeof MutationObserver === "undefined") {
} else if ((typeof MutationObserver !== "undefined") &&
!(typeof window !== "undefined" &&
window.navigator &&
window.navigator.standalone)) {
(window.navigator.standalone || window.cordova))) {
schedule = (function() {
var div = document.createElement("div");
var opts = {attributes: true};
@ -5498,6 +5545,10 @@ function getNativePromise() {
}
}
function domainBind(self, cb) {
return self.bind(cb);
}
var ret = {
isClass: isClass,
isIdentifier: isIdentifier,
@ -5530,7 +5581,8 @@ var ret = {
isNode: isNode,
env: env,
global: globalObject,
getNativePromise: getNativePromise
getNativePromise: getNativePromise,
domainBind: domainBind
};
ret.isRecentNode = ret.isNode && (function() {
var version = process.versions.node.split(".").map(Number);

8
tools/eslint/node_modules/bluebird/js/browser/bluebird.min.js

File diff suppressed because one or more lines are too long

22
tools/eslint/node_modules/bluebird/package.json

@ -14,20 +14,20 @@
]
],
"_from": "bluebird@>=3.1.1 <4.0.0",
"_id": "bluebird@3.4.3",
"_id": "bluebird@3.4.6",
"_inCache": true,
"_installable": true,
"_location": "/bluebird",
"_nodeVersion": "6.4.0",
"_nodeVersion": "5.6.0",
"_npmOperationalInternal": {
"host": "packages-16-east.internal.npmjs.com",
"tmp": "tmp/bluebird-3.4.3.tgz_1472108494164_0.43675709678791463"
"host": "packages-12-west.internal.npmjs.com",
"tmp": "tmp/bluebird-3.4.6.tgz_1472763137386_0.698919479502365"
},
"_npmUser": {
"name": "esailija",
"email": "petka_antonov@hotmail.com"
},
"_npmVersion": "3.10.3",
"_npmVersion": "3.6.0",
"_phantomChildren": {},
"_requested": {
"raw": "bluebird@^3.1.1",
@ -41,8 +41,8 @@
"_requiredBy": [
"/table"
],
"_resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.3.tgz",
"_shasum": "1bdf56bb9336f4206f0f4efb7bedd5b5e9392058",
"_resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.6.tgz",
"_shasum": "01da8d821d87813d158967e743d5fe6c62cf8c0f",
"_shrinkwrap": null,
"_spec": "bluebird@^3.1.1",
"_where": "/Users/trott/io.js/tools/node_modules/table",
@ -85,15 +85,15 @@
},
"directories": {},
"dist": {
"shasum": "1bdf56bb9336f4206f0f4efb7bedd5b5e9392058",
"tarball": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.3.tgz"
"shasum": "01da8d821d87813d158967e743d5fe6c62cf8c0f",
"tarball": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.6.tgz"
},
"files": [
"js/browser",
"js/release",
"LICENSE"
],
"gitHead": "64326d7ec06dd2839d9704b13969320e3dfb63e0",
"gitHead": "b466418e1d8cafd93c807f84b4dceee715c70b35",
"homepage": "https://github.com/petkaantonov/bluebird",
"keywords": [
"promise",
@ -133,5 +133,5 @@
"prepublish": "npm run generate-browser-core && npm run generate-browser-full",
"test": "node tools/test.js"
},
"version": "3.4.3"
"version": "3.4.6"
}

19
tools/eslint/node_modules/concat-stream/index.js

@ -73,6 +73,10 @@ function isArrayish (arr) {
return /Array\]$/.test(Object.prototype.toString.call(arr))
}
function isBufferish (p) {
return typeof p === 'string' || isArrayish(p) || (p && typeof p.subarray === 'function')
}
function stringConcat (parts) {
var strings = []
var needsToString = false
@ -82,8 +86,10 @@ function stringConcat (parts) {
strings.push(p)
} else if (Buffer.isBuffer(p)) {
strings.push(p)
} else if (isBufferish(p)) {
strings.push(new Buffer(p))
} else {
strings.push(Buffer(p))
strings.push(new Buffer(String(p)))
}
}
if (Buffer.isBuffer(parts[0])) {
@ -101,10 +107,11 @@ function bufferConcat (parts) {
var p = parts[i]
if (Buffer.isBuffer(p)) {
bufs.push(p)
} else if (typeof p === 'string' || isArrayish(p)
|| (p && typeof p.subarray === 'function')) {
bufs.push(Buffer(p))
} else bufs.push(Buffer(String(p)))
} else if (isBufferish(p)) {
bufs.push(new Buffer(p))
} else {
bufs.push(new Buffer(String(p)))
}
}
return Buffer.concat(bufs)
}
@ -121,7 +128,7 @@ function u8Concat (parts) {
var len = 0
for (var i = 0; i < parts.length; i++) {
if (typeof parts[i] === 'string') {
parts[i] = Buffer(parts[i])
parts[i] = new Buffer(parts[i])
}
len += parts[i].length
}

30
tools/eslint/node_modules/concat-stream/package.json

@ -14,16 +14,20 @@
]
],
"_from": "concat-stream@>=1.4.6 <2.0.0",
"_id": "concat-stream@1.5.1",
"_id": "concat-stream@1.5.2",
"_inCache": true,
"_installable": true,
"_location": "/concat-stream",
"_nodeVersion": "4.0.0",
"_nodeVersion": "4.4.3",
"_npmOperationalInternal": {
"host": "packages-12-west.internal.npmjs.com",
"tmp": "tmp/concat-stream-1.5.2.tgz_1472715196934_0.010375389130786061"
},
"_npmUser": {
"name": "maxogden",
"email": "max@maxogden.com"
"name": "mafintosh",
"email": "mathiasbuus@gmail.com"
},
"_npmVersion": "2.14.2",
"_npmVersion": "2.15.9",
"_phantomChildren": {},
"_requested": {
"raw": "concat-stream@^1.4.6",
@ -37,8 +41,8 @@
"_requiredBy": [
"/eslint"
],
"_resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.1.tgz",
"_shasum": "f3b80acf9e1f48e3875c0688b41b6c31602eea1c",
"_resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.2.tgz",
"_shasum": "708978624d856af41a5a741defdd261da752c266",
"_shrinkwrap": null,
"_spec": "concat-stream@^1.4.6",
"_where": "/Users/trott/io.js/tools/node_modules/eslint",
@ -60,8 +64,8 @@
},
"directories": {},
"dist": {
"shasum": "f3b80acf9e1f48e3875c0688b41b6c31602eea1c",
"tarball": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.1.tgz"
"shasum": "708978624d856af41a5a741defdd261da752c266",
"tarball": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.2.tgz"
},
"engines": [
"node >= 0.8"
@ -69,11 +73,15 @@
"files": [
"index.js"
],
"gitHead": "522adc12d82f57c691a5f946fbc8ba08718dcdcb",
"gitHead": "731fedd137eae89d066c249fdca070f8f16afbb8",
"homepage": "https://github.com/maxogden/concat-stream#readme",
"license": "MIT",
"main": "index.js",
"maintainers": [
{
"name": "mafintosh",
"email": "mathiasbuus@gmail.com"
},
{
"name": "maxogden",
"email": "max@maxogden.com"
@ -111,5 +119,5 @@
"android-browser/4.2..latest"
]
},
"version": "1.5.1"
"version": "1.5.2"
}

2
tools/eslint/node_modules/concat-stream/readme.md

@ -89,6 +89,8 @@ By default `concat-stream` will give you back the same data type as the type of
If you don't specify an encoding, and the types can't be inferred (e.g. you write things that aren't in the list above), it will try to convert concat them into a `Buffer`.
If nothing is written to `writable` then `data` will be an empty array `[]`.
# error handling
`concat-stream` does not handle errors for you, so you must handle errors on whatever streams you pipe into `concat-stream`. This is a general rule when programming with node.js streams: always handle errors on each and every stream. Since `concat-stream` is not itself a stream it does not emit errors.

2
tools/eslint/node_modules/deep-is/package.json

@ -61,7 +61,7 @@
},
"dist": {
"shasum": "b369d6fb5dbc13eecf524f91b070feedc357cf34",
"tarball": "http://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz"
"tarball": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz"
},
"gitHead": "f126057628423458636dec9df3d621843b9ac55e",
"homepage": "https://github.com/thlorenz/deep-is",

2
tools/eslint/node_modules/es6-weak-map/package.json

@ -65,7 +65,7 @@
"directories": {},
"dist": {
"shasum": "0d2bbd8827eb5fb4ba8f97fbfea50d43db21ea81",
"tarball": "http://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.1.tgz"
"tarball": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.1.tgz"
},
"gitHead": "b8b62d44e3b9f8134095c8fb6a5697e371b36867",
"homepage": "https://github.com/medikoo/es6-weak-map#readme",

8
tools/eslint/node_modules/inherits/inherits.js

@ -1 +1,7 @@
module.exports = require('util').inherits
try {
var util = require('util');
if (typeof util.inherits !== 'function') throw '';
module.exports = util.inherits;
} catch (e) {
module.exports = require('./inherits_browser.js');
}

28
tools/eslint/node_modules/inherits/package.json

@ -14,15 +14,20 @@
]
],
"_from": "inherits@>=2.0.1 <2.1.0",
"_id": "inherits@2.0.1",
"_id": "inherits@2.0.3",
"_inCache": true,
"_installable": true,
"_location": "/inherits",
"_nodeVersion": "6.5.0",
"_npmOperationalInternal": {
"host": "packages-16-east.internal.npmjs.com",
"tmp": "tmp/inherits-2.0.3.tgz_1473295776489_0.08142363070510328"
},
"_npmUser": {
"name": "isaacs",
"email": "i@izs.me"
},
"_npmVersion": "1.3.8",
"_npmVersion": "3.10.7",
"_phantomChildren": {},
"_requested": {
"raw": "inherits@~2.0.1",
@ -38,8 +43,8 @@
"/glob",
"/readable-stream"
],
"_resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
"_shasum": "b17d08d326b4423e568eff719f91b0b1cbdf69f1",
"_resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"_shasum": "633c2c83e3da42a502f52466022480f4208261de",
"_shrinkwrap": null,
"_spec": "inherits@~2.0.1",
"_where": "/Users/trott/io.js/tools/node_modules/concat-stream",
@ -49,12 +54,19 @@
},
"dependencies": {},
"description": "Browser-friendly inheritance fully compatible with standard node.js inherits()",
"devDependencies": {},
"devDependencies": {
"tap": "^7.1.0"
},
"directories": {},
"dist": {
"shasum": "b17d08d326b4423e568eff719f91b0b1cbdf69f1",
"tarball": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
"shasum": "633c2c83e3da42a502f52466022480f4208261de",
"tarball": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz"
},
"files": [
"inherits.js",
"inherits_browser.js"
],
"gitHead": "e05d0fb27c61a3ec687214f0476386b765364d5f",
"homepage": "https://github.com/isaacs/inherits#readme",
"keywords": [
"inheritance",
@ -84,5 +96,5 @@
"scripts": {
"test": "node test"
},
"version": "2.0.1"
"version": "2.0.3"
}

2
tools/eslint/node_modules/is-path-cwd/package.json

@ -57,7 +57,7 @@
"directories": {},
"dist": {
"shasum": "d225ec23132e89edd38fda767472e62e65f1106d",
"tarball": "http://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz"
"tarball": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz"
},
"engines": {
"node": ">=0.10.0"

2
tools/eslint/node_modules/is-path-in-cwd/package.json

@ -59,7 +59,7 @@
"directories": {},
"dist": {
"shasum": "6477582b8214d602346094567003be8a9eac04dc",
"tarball": "http://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz"
"tarball": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz"
},
"engines": {
"node": ">=0.10.0"

2
tools/eslint/node_modules/is-property/package.json

@ -58,7 +58,7 @@
},
"dist": {
"shasum": "57fe1c4e48474edd65b09911f26b1cd4095dda84",
"tarball": "http://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz"
"tarball": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz"
},
"gitHead": "0a85ea5b6b1264ea1cdecc6e5cf186adbb3ffc50",
"homepage": "https://github.com/mikolalysenko/is-property",

2
tools/eslint/node_modules/number-is-nan/package.json

@ -59,7 +59,7 @@
"directories": {},
"dist": {
"shasum": "c020f529c5282adfdd233d91d4b181c3d686dc4b",
"tarball": "http://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.0.tgz"
"tarball": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.0.tgz"
},
"engines": {
"node": ">=0.10.0"

28
tools/eslint/node_modules/once/README.md

@ -49,3 +49,31 @@ function load (cb) {
})
}
```
## `once.strict(func)`
Throw an error if the function is called twice.
Some functions are expected to be called only once. Using `once` for them would
potentially hide logical errors.
In the example below, the `greet` function has to call the callback only once:
```javascript
function greet (name, cb) {
// return is missing from the if statement
// when no name is passed, the callback is called twice
if (!name) cb('Hello anonymous')
cb('Hello ' + name)
}
function log (msg) {
console.log(msg)
}
// this will print 'Hello anonymous' but the logical error will be missed
greet(null, once(msg))
// once.strict will print 'Hello anonymous' and throw an error when the callback will be called the second time
greet(null, once.strict(msg))
```

21
tools/eslint/node_modules/once/once.js

@ -1,5 +1,6 @@
var wrappy = require('wrappy')
module.exports = wrappy(once)
module.exports.strict = wrappy(onceStrict)
once.proto = once(function () {
Object.defineProperty(Function.prototype, 'once', {
@ -8,6 +9,13 @@ once.proto = once(function () {
},
configurable: true
})
Object.defineProperty(Function.prototype, 'onceStrict', {
value: function () {
return onceStrict(this)
},
configurable: true
})
})
function once (fn) {
@ -19,3 +27,16 @@ function once (fn) {
f.called = false
return f
}
function onceStrict (fn) {
var f = function () {
if (f.called)
throw new Error(f.onceError)
f.called = true
return f.value = fn.apply(this, arguments)
}
var name = fn.name || 'Function wrapped with `once`'
f.onceError = name + " shouldn't be called more than once"
f.called = false
return f
}

24
tools/eslint/node_modules/once/package.json

@ -14,16 +14,20 @@
]
],
"_from": "once@>=1.3.0 <2.0.0",
"_id": "once@1.3.3",
"_id": "once@1.4.0",
"_inCache": true,
"_installable": true,
"_location": "/once",
"_nodeVersion": "4.0.0",
"_nodeVersion": "6.5.0",
"_npmOperationalInternal": {
"host": "packages-12-west.internal.npmjs.com",
"tmp": "tmp/once-1.4.0.tgz_1473196269128_0.537820661207661"
},
"_npmUser": {
"name": "isaacs",
"email": "i@izs.me"
},
"_npmVersion": "3.3.2",
"_npmVersion": "3.10.7",
"_phantomChildren": {},
"_requested": {
"raw": "once@^1.3.0",
@ -39,8 +43,8 @@
"/inflight",
"/run-async"
],
"_resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz",
"_shasum": "b2e261557ce4c314ec8304f3fa82663e4297ca20",
"_resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"_shasum": "583b1aa775961d4b113ac17d9c50baef9dd76bd1",
"_shrinkwrap": null,
"_spec": "once@^1.3.0",
"_where": "/Users/trott/io.js/tools/node_modules/glob",
@ -57,19 +61,19 @@
},
"description": "Run a function exactly one time",
"devDependencies": {
"tap": "^1.2.0"
"tap": "^7.0.1"
},
"directories": {
"test": "test"
},
"dist": {
"shasum": "b2e261557ce4c314ec8304f3fa82663e4297ca20",
"tarball": "https://registry.npmjs.org/once/-/once-1.3.3.tgz"
"shasum": "583b1aa775961d4b113ac17d9c50baef9dd76bd1",
"tarball": "https://registry.npmjs.org/once/-/once-1.4.0.tgz"
},
"files": [
"once.js"
],
"gitHead": "2ad558657e17fafd24803217ba854762842e4178",
"gitHead": "0e614d9f5a7e6f0305c625f6b581f6d80b33b8a6",
"homepage": "https://github.com/isaacs/once#readme",
"keywords": [
"once",
@ -95,5 +99,5 @@
"scripts": {
"test": "tap test/*.js"
},
"version": "1.3.3"
"version": "1.4.0"
}

2
tools/eslint/node_modules/path-is-absolute/package.json

@ -56,7 +56,7 @@
"directories": {},
"dist": {
"shasum": "263dada66ab3f2fb10bf7f9d24dd8f3e570ef912",
"tarball": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.0.tgz"
"tarball": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.0.tgz"
},
"engines": {
"node": ">=0.10.0"

2
tools/eslint/node_modules/prelude-ls/package.json

@ -64,7 +64,7 @@
"directories": {},
"dist": {
"shasum": "21932a549f5e52ffd9a827f570e04be62a97da54",
"tarball": "http://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz"
"tarball": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz"
},
"engines": {
"node": ">= 0.8.0"

2
tools/eslint/node_modules/typedarray/package.json

@ -57,7 +57,7 @@
"directories": {},
"dist": {
"shasum": "867ac74e3864187b1d3d47d996a78ec5c8830777",
"tarball": "http://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz"
"tarball": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz"
},
"homepage": "https://github.com/substack/typedarray",
"keywords": [

2
tools/eslint/node_modules/util-deprecate/package.json

@ -57,7 +57,7 @@
"directories": {},
"dist": {
"shasum": "450d4dc9fa70de732762fbd2d4a28981419a0ccf",
"tarball": "http://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
"tarball": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
},
"gitHead": "475fb6857cd23fafff20c1be846c1350abf8e6d4",
"homepage": "https://github.com/TooTallNate/util-deprecate",

18
tools/eslint/package.json

@ -14,14 +14,14 @@
]
],
"_from": "eslint@latest",
"_id": "eslint@3.4.0",
"_id": "eslint@3.5.0",
"_inCache": true,
"_installable": true,
"_location": "/eslint",
"_nodeVersion": "4.4.7",
"_npmOperationalInternal": {
"host": "packages-12-west.internal.npmjs.com",
"tmp": "tmp/eslint-3.4.0.tgz_1472234173647_0.17217218782752752"
"host": "packages-16-east.internal.npmjs.com",
"tmp": "tmp/eslint-3.5.0.tgz_1473451101299_0.8081250376999378"
},
"_npmUser": {
"name": "eslint",
@ -41,8 +41,8 @@
"_requiredBy": [
"#USER"
],
"_resolved": "https://registry.npmjs.org/eslint/-/eslint-3.4.0.tgz",
"_shasum": "af5984007bd3f1fb1b3b6b01a0a22eda0ec7a9f4",
"_resolved": "https://registry.npmjs.org/eslint/-/eslint-3.5.0.tgz",
"_shasum": "22fc9f780ea5bca1306fab2b6d3336b0fa62c754",
"_shrinkwrap": null,
"_spec": "eslint",
"_where": "/Users/trott/io.js/tools",
@ -133,8 +133,8 @@
},
"directories": {},
"dist": {
"shasum": "af5984007bd3f1fb1b3b6b01a0a22eda0ec7a9f4",
"tarball": "https://registry.npmjs.org/eslint/-/eslint-3.4.0.tgz"
"shasum": "22fc9f780ea5bca1306fab2b6d3336b0fa62c754",
"tarball": "https://registry.npmjs.org/eslint/-/eslint-3.5.0.tgz"
},
"engines": {
"node": ">=4"
@ -147,7 +147,7 @@
"lib",
"messages"
],
"gitHead": "faab36e519ce8caf428da4567766e699464a2316",
"gitHead": "18be52eab695f0d78d19b349fefb09db19751d51",
"homepage": "http://eslint.org",
"keywords": [
"ast",
@ -194,5 +194,5 @@
"release": "node Makefile.js release",
"test": "node Makefile.js test"
},
"version": "3.4.0"
"version": "3.5.0"
}

Loading…
Cancel
Save