Skip to content

Commit

Permalink
Update: Improve report location for array-callback-return (refs #12334)…
Browse files Browse the repository at this point in the history
… (#13109)
  • Loading branch information
mdjermanovic committed Apr 24, 2020
1 parent d85e291 commit 0b1d65a
Show file tree
Hide file tree
Showing 2 changed files with 249 additions and 21 deletions.
21 changes: 3 additions & 18 deletions lib/rules/array-callback-return.js
Expand Up @@ -29,22 +29,6 @@ function isReachable(segment) {
return segment.reachable;
}

/**
* Gets a readable location.
*
* - FunctionExpression -> the function name or `function` keyword.
* - ArrowFunctionExpression -> `=>` token.
* @param {ASTNode} node A function node to get.
* @param {SourceCode} sourceCode A source code to get tokens.
* @returns {ASTNode|Token} The node or the token of a location.
*/
function getLocation(node, sourceCode) {

This comment has been minimized.

Copy link
@SAMP2101

SAMP2101 Apr 27, 2020

need to open my gmail

if (node.type === "ArrowFunctionExpression") {
return sourceCode.getTokenBefore(node.body);
}
return node.id || node;
}

/**
* Checks a given node is a MemberExpression node which has the specified name's
* property.
Expand Down Expand Up @@ -179,6 +163,7 @@ module.exports = {
create(context) {

const options = context.options[0] || { allowImplicit: false, checkForEach: false };
const sourceCode = context.getSourceCode();

let funcInfo = {
arrayMethodName: null,
Expand Down Expand Up @@ -217,12 +202,12 @@ module.exports = {
}

if (messageId) {
let name = astUtils.getFunctionNameWithKind(funcInfo.node);
let name = astUtils.getFunctionNameWithKind(node);

name = messageId === "expectedNoReturnValue" ? lodash.upperFirst(name) : name;
context.report({
node,
loc: getLocation(node, context.getSourceCode()).loc.start,
loc: astUtils.getFunctionHeadLoc(node, sourceCode),
messageId,
data: { name }
});
Expand Down
249 changes: 246 additions & 3 deletions tests/lib/rules/array-callback-return.js
Expand Up @@ -147,7 +147,7 @@ ruleTester.run("array-callback-return", rule, {
{ code: "foo[`every`](function foo() {})", parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "expectedInside", data: { name: "function 'foo'" } }] },
{ code: "foo.every(() => {})", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected to return a value in arrow function.", column: 14 }] },
{ code: "foo.every(function() { if (a) return true; })", errors: [{ message: "Expected to return a value at the end of function.", column: 11 }] },
{ code: "foo.every(function cb() { if (a) return true; })", errors: [{ message: "Expected to return a value at the end of function 'cb'.", column: 20 }] },
{ code: "foo.every(function cb() { if (a) return true; })", errors: [{ message: "Expected to return a value at the end of function 'cb'.", column: 11 }] },
{ code: "foo.every(function() { switch (a) { case 0: break; default: return true; } })", errors: [{ messageId: "expectedAtEnd", data: { name: "function" } }] },
{ code: "foo.every(function foo() { switch (a) { case 0: break; default: return true; } })", errors: [{ messageId: "expectedAtEnd", data: { name: "function 'foo'" } }] },
{ code: "foo.every(function() { try { bar(); } catch (err) { return true; } })", errors: [{ messageId: "expectedAtEnd", data: { name: "function" } }] },
Expand All @@ -163,7 +163,7 @@ ruleTester.run("array-callback-return", rule, {
{ code: "foo.every(a ? function() {} : function() {})", errors: ["Expected to return a value in function.", "Expected to return a value in function."] },
{ code: "foo.every(a ? function foo() {} : function bar() {})", errors: ["Expected to return a value in function 'foo'.", "Expected to return a value in function 'bar'."] },
{ code: "foo.every(function(){ return function() {}; }())", errors: [{ message: "Expected to return a value in function.", column: 30 }] },
{ code: "foo.every(function(){ return function foo() {}; }())", errors: [{ message: "Expected to return a value in function 'foo'.", column: 39 }] },
{ code: "foo.every(function(){ return function foo() {}; }())", errors: [{ message: "Expected to return a value in function 'foo'.", column: 30 }] },
{ code: "foo.every(() => {})", options: [{ allowImplicit: false }], parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected to return a value in arrow function." }] },
{ code: "foo.every(() => {})", options: [{ allowImplicit: true }], parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected to return a value in arrow function." }] },

Expand Down Expand Up @@ -198,7 +198,250 @@ ruleTester.run("array-callback-return", rule, {
{ code: "foo.every(function() {})", options: checkForEachOptions, errors: [{ messageId: "expectedInside", data: { name: "function" } }] },
{ code: "foo.filter(function foo() {})", options: checkForEachOptions, errors: [{ messageId: "expectedInside", data: { name: "function 'foo'" } }] },
{ code: "foo.filter(function foo() { return; })", options: checkForEachOptions, errors: [{ messageId: "expectedReturnValue", data: { name: "Function 'foo'" } }] },
{ code: "foo.every(cb || function() {})", options: checkForEachOptions, errors: ["Expected to return a value in function."] }
{ code: "foo.every(cb || function() {})", options: checkForEachOptions, errors: ["Expected to return a value in function."] },

// full location tests
{
code: "foo.filter(bar => { baz(); } )",
parserOptions: { ecmaVersion: 6 },
errors: [{
messageId: "expectedInside",
data: { name: "arrow function" },
type: "ArrowFunctionExpression",
line: 1,
column: 16,
endLine: 1,
endColumn: 18
}]
},
{
code: "foo.filter(\n() => {} )",
parserOptions: { ecmaVersion: 6 },
errors: [{
messageId: "expectedInside",
data: { name: "arrow function" },
type: "ArrowFunctionExpression",
line: 2,
column: 4,
endLine: 2,
endColumn: 6
}]
},
{
code: "foo.filter(bar || ((baz) => {}) )",
parserOptions: { ecmaVersion: 6 },
errors: [{
messageId: "expectedInside",
data: { name: "arrow function" },
type: "ArrowFunctionExpression",
line: 1,
column: 26,
endLine: 1,
endColumn: 28
}]
},
{
code: "foo.filter(bar => { return; })",
parserOptions: { ecmaVersion: 6 },
errors: [{
messageId: "expectedReturnValue",
data: { name: "Arrow function" },
type: "ReturnStatement",
line: 1,
column: 21,
endLine: 1,
endColumn: 28
}]
},
{
code: "Array.from(foo, bar => { bar })",
parserOptions: { ecmaVersion: 6 },
errors: [{
messageId: "expectedInside",
data: { name: "arrow function" },
type: "ArrowFunctionExpression",
line: 1,
column: 21,
endLine: 1,
endColumn: 23
}]
},
{
code: "foo.forEach(bar => bar)",
options: checkForEachOptions,
parserOptions: { ecmaVersion: 6 },
errors: [{
messageId: "expectedNoReturnValue",
data: { name: "Arrow function" },
type: "ArrowFunctionExpression",
line: 1,
column: 17,
endLine: 1,
endColumn: 19
}]
},
{
code: "foo.forEach((function () { return (bar) => bar; })())",
options: checkForEachOptions,
parserOptions: { ecmaVersion: 6 },
errors: [{
messageId: "expectedNoReturnValue",
data: { name: "Arrow function" },
type: "ArrowFunctionExpression",
line: 1,
column: 41,
endLine: 1,
endColumn: 43
}]
},
{
code: "foo.forEach((() => {\n return bar => bar; })())",
options: checkForEachOptions,
parserOptions: { ecmaVersion: 6 },
errors: [{
messageId: "expectedNoReturnValue",
data: { name: "Arrow function" },
type: "ArrowFunctionExpression",
line: 2,
column: 13,
endLine: 2,
endColumn: 15
}]
},
{
code: "foo.forEach((bar) => { if (bar) { return; } else { return bar ; } })",
options: checkForEachOptions,
parserOptions: { ecmaVersion: 6 },
errors: [{
messageId: "expectedNoReturnValue",
data: { name: "Arrow function" },
type: "ReturnStatement",
line: 1,
column: 52,
endLine: 1,
endColumn: 64
}]
},
{
code: "foo.filter(function(){})",
errors: [{
messageId: "expectedInside",
data: { name: "function" },
type: "FunctionExpression",
line: 1,
column: 12,
endLine: 1,
endColumn: 20
}]
},
{
code: "foo.filter(function (){})",
errors: [{
messageId: "expectedInside",
data: { name: "function" },
type: "FunctionExpression",
line: 1,
column: 12,
endLine: 1,
endColumn: 21
}]
},
{
code: "foo.filter(function\n(){})",
errors: [{
messageId: "expectedInside",
data: { name: "function" },
type: "FunctionExpression",
line: 1,
column: 12,
endLine: 2,
endColumn: 1
}]
},
{
code: "foo.filter(function bar(){})",
errors: [{
messageId: "expectedInside",
data: { name: "function 'bar'" },
type: "FunctionExpression",
line: 1,
column: 12,
endLine: 1,
endColumn: 24
}]
},
{
code: "foo.filter(function bar (){})",
errors: [{
messageId: "expectedInside",
data: { name: "function 'bar'" },
type: "FunctionExpression",
line: 1,
column: 12,
endLine: 1,
endColumn: 26
}]
},
{
code: "foo.filter(function\n bar() {})",
errors: [{
messageId: "expectedInside",
data: { name: "function 'bar'" },
type: "FunctionExpression",
line: 1,
column: 12,
endLine: 2,
endColumn: 5
}]
},
{
code: "Array.from(foo, function bar(){})",
errors: [{
messageId: "expectedInside",
data: { name: "function 'bar'" },
type: "FunctionExpression",
line: 1,
column: 17,
endLine: 1,
endColumn: 29
}]
},
{
code: "Array.from(foo, bar ? function (){} : baz)",
errors: [{
messageId: "expectedInside",
data: { name: "function" },
type: "FunctionExpression",
line: 1,
column: 23,
endLine: 1,
endColumn: 32
}]
},
{
code: "foo.filter(function bar() { return \n })",
errors: [{
messageId: "expectedReturnValue",
data: { name: "Function 'bar'" },
type: "ReturnStatement",
line: 1,
column: 29,
endLine: 1,
endColumn: 35
}]
},
{
code: "foo.forEach(function () { \nif (baz) return bar\nelse return\n })",
options: checkForEachOptions,
errors: [{
messageId: "expectedNoReturnValue",
data: { name: "Function" },
type: "ReturnStatement",
line: 2,
column: 10,
endLine: 2,
endColumn: 20
}]
}
]
});

0 comments on commit 0b1d65a

Please sign in to comment.