Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Update: add fixer for dot-notation (fixes #7014) (#7054)
  • Loading branch information
not-an-aardvark authored and ilyavolodin committed Sep 7, 2016
1 parent 2657846 commit 645dda5
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 10 deletions.
2 changes: 2 additions & 0 deletions docs/rules/dot-notation.md
@@ -1,5 +1,7 @@
# Require Dot Notation (dot-notation)

(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fix) automatically fixes problems reported by this rule.

In JavaScript, one can access properties using the dot notation (`foo.bar`) or square-bracket notation (`foo["bar"]`). However, the dot notation is often preferred because it is easier to read, less verbose, and works better with aggressive JavaScript minimizers.

```js
Expand Down
37 changes: 36 additions & 1 deletion lib/rules/dot-notation.js
Expand Up @@ -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;

Expand All @@ -59,6 +62,23 @@ module.exports = {
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}`
);
}
});
}
Expand All @@ -73,6 +93,21 @@ module.exports = {
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}"]`
);
}
});
}
Expand Down
88 changes: 79 additions & 9 deletions tests/lib/rules/dot-notation.js
Expand Up @@ -47,13 +47,43 @@ ruleTester.run("dot-notation", rule, {
"a[b()];"
],
invalid: [
{ code: "a.true;", options: [{allowKeywords: false}], errors: [{ message: ".true is a syntax error." }] },
{ code: "a['true'];", errors: [{ message: "[\"true\"] is better written in dot notation." }] },
{ code: "a[null];", errors: [{ message: "[null] is better written in dot notation." }] },
{ code: "a['b'];", errors: [{ message: "[\"b\"] is better written in dot notation." }] },
{ code: "a.b['c'];", errors: [{ message: "[\"c\"] is better written in dot notation." }] },
{ code: "a['_dangle'];", options: [{allowPattern: "^[a-z]+(_[a-z]+)+$"}], errors: [{ message: "[\"_dangle\"] is better written in dot notation." }] },
{ code: "a['SHOUT_CASE'];", options: [{allowPattern: "^[a-z]+(_[a-z]+)+$"}], errors: [{ message: "[\"SHOUT_CASE\"] is better written in dot notation." }] },
{
code: "a.true;",
options: [{allowKeywords: false}],
errors: [{ message: ".true is a syntax error." }],
output: "a[\"true\"];"
},
{
code: "a['true'];",
errors: [{ message: "[\"true\"] is better written in dot notation." }],
output: "a.true;"
},
{
code: "a[null];",
errors: [{ message: "[null] is better written in dot notation." }],
output: "a.null;"
},
{
code: "a['b'];",
errors: [{ message: "[\"b\"] is better written in dot notation." }],
output: "a.b;"
},
{
code: "a.b['c'];",
errors: [{ message: "[\"c\"] is better written in dot notation." }],
output: "a.b.c;"
},
{
code: "a['_dangle'];",
options: [{allowPattern: "^[a-z]+(_[a-z]+)+$"}], errors: [{ message: "[\"_dangle\"] is better written in dot notation." }],
output: "a._dangle;"
},
{
code: "a['SHOUT_CASE'];",
options: [{allowPattern: "^[a-z]+(_[a-z]+)+$"}],
errors: [{ message: "[\"SHOUT_CASE\"] is better written in dot notation." }],
output: "a.SHOUT_CASE;"
},
{
code:
"a\n" +
Expand All @@ -62,7 +92,10 @@ ruleTester.run("dot-notation", rule, {
message: "[\"SHOUT_CASE\"] is better written in dot notation.",
line: 2,
column: 4
}]
}],
output:
"a\n" +
" .SHOUT_CASE;"
},
{
code:
Expand All @@ -82,7 +115,44 @@ ruleTester.run("dot-notation", rule, {
line: 5,
column: 6
}
]
],
output:
"getResource()\n" +
" .then(function(){})\n" +
" .catch(function(){})\n" +
" .then(function(){})\n" +
" .catch(function(){});"
},
{
code:
"foo\n" +
" .while;",
options: [{ allowKeywords: false }],
errors: [{ message: ".while is a syntax error." }],
output:
"foo\n" +
" [\"while\"];"
},
{
code: "foo[ /* comment */ 'bar' ]",
errors: [{ message: "[\"bar\"] is better written in dot notation." }],
output: "foo[ /* comment */ 'bar' ]" // Not fixed due to comment
},
{
code: "foo[ 'bar' /* comment */ ]",
errors: [{ message: "[\"bar\"] is better written in dot notation." }],
output: "foo[ 'bar' /* comment */ ]" // Not fixed due to comment
},
{
code: "foo[ 'bar' ];",
errors: [{ message: "[\"bar\"] is better written in dot notation." }],
output: "foo.bar;"
},
{
code: "foo. /* comment */ while",
options: [{ allowKeywords: false }],
errors: [{ message: ".while is a syntax error." }],
output: "foo. /* comment */ while" // Not fixed due to comment
}
]
});

0 comments on commit 645dda5

Please sign in to comment.