Skip to content

Commit

Permalink
Update: new-parens false negative (fixes #6997) (#6999)
Browse files Browse the repository at this point in the history
  • Loading branch information
mysticatea authored and nzakas committed Sep 1, 2016
1 parent 326f457 commit 8e77f16
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 10 deletions.
2 changes: 2 additions & 0 deletions docs/rules/new-parens.md
Expand Up @@ -16,6 +16,7 @@ Examples of **incorrect** code for this rule:
/*eslint new-parens: "error"*/

var person = new Person;
var person = new (Person);
```

Examples of **correct** code for this rule:
Expand All @@ -24,4 +25,5 @@ Examples of **correct** code for this rule:
/*eslint new-parens: "error"*/

var person = new Person();
var person = new (Person)();
```
57 changes: 49 additions & 8 deletions lib/rules/new-parens.js
Expand Up @@ -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
//------------------------------------------------------------------------------
Expand All @@ -24,18 +62,21 @@ module.exports = {
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."
});
}
}
};

}
};
14 changes: 12 additions & 2 deletions tests/lib/rules/new-parens.js
Expand Up @@ -21,9 +21,19 @@ const ruleTester = new RuleTester();
ruleTester.run("new-parens", rule, {
valid: [
"var a = new Date();",
"var a = new Date(function() {});"
"var a = new Date(function() {});",
"var a = new (Date)();",
"var a = new ((Date))();",
"var a = (new Date());",
],
invalid: [
{ code: "var a = new Date;", errors: [{ message: "Missing '()' invoking a constructor.", type: "NewExpression"}] }
{ code: "var a = new Date;", errors: [{ message: "Missing '()' invoking a constructor.", type: "NewExpression"}] },
{ code: "var a = new Date", errors: [{ message: "Missing '()' invoking a constructor.", type: "NewExpression"}] },
{ code: "var a = new (Date);", errors: [{ message: "Missing '()' invoking a constructor.", type: "NewExpression"}] },
{ code: "var a = new (Date)", errors: [{ message: "Missing '()' invoking a constructor.", type: "NewExpression"}] },
{ code: "var a = (new Date)", errors: [{ message: "Missing '()' invoking a constructor.", type: "NewExpression"}] },

// This `()` is `CallExpression`'s. This is a call of the result of `new Date`.
{ code: "var a = (new Date)()", errors: [{ message: "Missing '()' invoking a constructor.", type: "NewExpression"}] },
]
});

0 comments on commit 8e77f16

Please sign in to comment.