Skip to content
Permalink
Browse files

Update: add autofix support for spaced-comment (fixes #4969, fixes #5030

)
  • Loading branch information...
zandaqo committed Jan 22, 2016
1 parent 9a7574f commit c1fad4fd8fa6cab774204cb367e0740b43a22d3c
Showing with 68 additions and 8 deletions.
  1. +3 −1 docs/rules/spaced-comment.md
  2. +40 −6 lib/rules/spaced-comment.js
  3. +25 −1 tests/lib/rules/spaced-comment.js
@@ -4,6 +4,8 @@ Some style guides require or disallow a whitespace immediately after the initial
Whitespace after the `//` or `/*` makes it easier to read text in comments.
On the other hand, commenting out code is easier without having to put a whitespace right after the `//` or `/*`.

**Fixable:** This rule is automatically fixable using the `--fix` flag on the command line.

## Rule Details

This rule will enforce consistency of spacing after the start of a comment `//` or `/*`. It also provides several
@@ -97,7 +99,7 @@ The following patterns are considered problems:
```js
/* eslint spaced-comment: [2, "always", { "markers": ["/"] }] */
///This is a comment with a marker but without whitespace /*error Expected space or tab after '//' in comment.*/
///This is a comment with a marker but without whitespace /*error Expected space or tab after '///' in comment.*/
```

```js
@@ -116,7 +116,7 @@ function createAlwaysStylePattern(markers, exceptions) {
* @returns {RegExp} A RegExp object for `never` mode.
*/
function createNeverStylePattern(markers) {
var pattern = "^(" + markers.map(escape).join("|") + ")?[ \t]";
var pattern = "^(" + markers.map(escape).join("|") + ")?[ \t]+";
return new RegExp(pattern);
}

@@ -138,12 +138,44 @@ module.exports = function(context) {
// Create RegExp object for valid patterns.
rule[type] = {
regex: requireSpace ? createAlwaysStylePattern(markers, exceptions) : createNeverStylePattern(markers),
hasExceptions: exceptions.length > 0
hasExceptions: exceptions.length > 0,
markers: new RegExp("^(" + markers.map(escape).join("|") + ")")
};

return rule;
}, {});

/**
* Reports a spacing error with an appropriate message.
* @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.
* @returns {void}
*/
function report(node, message, match) {
var type = node.type.toLowerCase(),
commentIdentifier = type === "block" ? "/*" : "//";

context.report({
node: node,
fix: function(fixer) {
var start = node.range[0],
end = start + 2;

if (requireSpace) {
if (match) {
end += match[0].length;
}
return fixer.insertTextAfterRange([start, end], " ");
} else {
end += match[0].length;
return fixer.replaceTextRange([start, end], commentIdentifier + (match[1] ? match[1] : ""));
}
},
message: message
});
}

/**
* Reports a given comment if it's invalid.
* @param {ASTNode} node - a comment node to check.
@@ -162,19 +194,21 @@ module.exports = function(context) {
// Checks.
if (requireSpace) {
if (!rule.regex.test(node.value)) {
var hasMarker = rule.markers.exec(node.value);
var marker = hasMarker ? commentIdentifier + hasMarker[0] : commentIdentifier;
if (rule.hasExceptions) {
context.report(node, "Expected exception block, space or tab after '" + commentIdentifier + "' in comment.");
report(node, "Expected exception block, space or tab after '" + marker + "' in comment.", hasMarker);
} else {
context.report(node, "Expected space or tab after '" + commentIdentifier + "' in comment.");
report(node, "Expected space or tab after '" + marker + "' in comment.", hasMarker);
}
}
} else {
var matched = rule.regex.exec(node.value);
if (matched) {
if (!matched[1]) {
context.report(node, "Unexpected space or tab after '" + commentIdentifier + "' in comment.");
report(node, "Unexpected space or tab after '" + commentIdentifier + "' in comment.", matched);
} else {
context.report(node, "Unexpected space or tab after marker (" + matched[1] + ") in comment.");
report(node, "Unexpected space or tab after marker (" + matched[1] + ") in comment.", matched);
}
}
}
@@ -246,6 +246,7 @@ ruleTester.run("spaced-comment", rule, {
invalid: [
{
code: "//An invalid comment NOT starting with space\nvar a = 1;",
output: "// An invalid comment NOT starting with space\nvar a = 1;",
errors: [{
messsage: "Expected space or tab after '//' in comment.",
type: "Line"
@@ -254,6 +255,7 @@ ruleTester.run("spaced-comment", rule, {
},
{
code: "// An invalid comment starting with space\nvar a = 2;",
output: "//An invalid comment starting with space\nvar a = 2;",
errors: [{
message: "Unexpected space or tab after '//' in comment.",
type: "Line"
@@ -262,16 +264,20 @@ ruleTester.run("spaced-comment", rule, {
},
{
code: "// An invalid comment starting with tab\nvar a = 2;",
output: "//An invalid comment starting with tab\nvar a = 2;",
errors: [{
message: "Unexpected space or tab after '//' in comment.",
type: "Line"
}],
options: ["never"]
},
{
// note that the first line in the comment is not a valid exception block pattern
// because of the minus sign at the end of the line: `//*********************-`
code: "//*********************-\n// Comment Block 3\n//***********************",
output: "//* ********************-\n// Comment Block 3\n//***********************",
errors: [{
message: "Expected exception block, space or tab after '//' in comment.",
message: "Expected exception block, space or tab after '//*' in comment.",
type: "Line"
}],
options: ["always", {
@@ -280,6 +286,7 @@ ruleTester.run("spaced-comment", rule, {
},
{
code: "//-=-=-=-=-=-=\n// A comment\n//-=-=-=-=-=-=",
output: "// -=-=-=-=-=-=\n// A comment\n// -=-=-=-=-=-=",
errors: [
{
message: "Expected exception block, space or tab after '//' in comment.",
@@ -296,30 +303,35 @@ ruleTester.run("spaced-comment", rule, {
},
{
code: "//!<docblock style comment",
output: "//!< docblock style comment",
errors: 1,
options: ["always", {
markers: ["/", "!<"]
}]
},
{
code: "//!< docblock style comment",
output: "//!<docblock style comment",
errors: 1,
options: ["never", {
markers: ["/", "!<"]
}]
},
{
code: invalidShebangProgram,
output: "#!/path/to/node\n#!/second/shebang\nvar a = 3;",
errors: 1,
options: ["always"]
},
{
code: invalidShebangProgram,
output: "#!/path/to/node\n#!/second/shebang\nvar a = 3;",
errors: 1,
options: ["never"]
},
{
code: "var a = 1; /* A valid comment starting with space */",
output: "var a = 1; /*A valid comment starting with space */",
options: ["never"],
errors: [{
message: "Unexpected space or tab after '/*' in comment.",
@@ -328,6 +340,7 @@ ruleTester.run("spaced-comment", rule, {
},
{
code: "var a = 1; /*######*/",
output: "var a = 1; /* ######*/",
options: ["always", {
exceptions: ["-", "=", "*", "!@#"]
}],
@@ -338,6 +351,7 @@ ruleTester.run("spaced-comment", rule, {
},
{
code: "var a = 1; /*A valid comment NOT starting with space */",
output: "var a = 1; /* A valid comment NOT starting with space */",
options: ["always"],
errors: [{
message: "Expected space or tab after '/*' in comment.",
@@ -346,6 +360,7 @@ ruleTester.run("spaced-comment", rule, {
},
{
code: "function foo(/* height */a) { \n }",
output: "function foo(/*height */a) { \n }",
options: ["never"],
errors: [{
message: "Unexpected space or tab after '/*' in comment.",
@@ -354,6 +369,7 @@ ruleTester.run("spaced-comment", rule, {
},
{
code: "function foo(/*height */a) { \n }",
output: "function foo(/* height */a) { \n }",
options: ["always"],
errors: [{
message: "Expected space or tab after '/*' in comment.",
@@ -362,6 +378,7 @@ ruleTester.run("spaced-comment", rule, {
},
{
code: "function foo(a/*height */) { \n }",
output: "function foo(a/* height */) { \n }",
options: ["always"],
errors: [{
message: "Expected space or tab after '/*' in comment.",
@@ -370,6 +387,7 @@ ruleTester.run("spaced-comment", rule, {
},
{
code: "/* \n *Test\n */",
output: "/*\n *Test\n */",
options: ["never"],
errors: [{
message: "Unexpected space or tab after '/*' in comment.",
@@ -378,6 +396,7 @@ ruleTester.run("spaced-comment", rule, {
},
{
code: "//-----------------------\n// A comment\n//-----------------------",
output: "// -----------------------\n// A comment\n// -----------------------",
options: ["always", {
block: { exceptions: ["-", "=", "*", "#", "!@#"] }
}],
@@ -388,6 +407,7 @@ ruleTester.run("spaced-comment", rule, {
},
{
code: "var a = 1; /*######*/",
output: "var a = 1; /* ######*/",
options: ["always", {
line: { exceptions: ["-", "=", "*", "#", "!@#"] }
}],
@@ -398,6 +418,7 @@ ruleTester.run("spaced-comment", rule, {
},
{
code: "//!< docblock style comment",
output: "// !< docblock style comment",
options: ["always", {
block: { markers: ["/", "!<"] }
}],
@@ -408,6 +429,7 @@ ruleTester.run("spaced-comment", rule, {
},
{
code: "/*!\n *comment\n */",
output: "/* !\n *comment\n */",
options: ["always", { line: { markers: ["!"] } }],
errors: [{
message: "Expected space or tab after '/*' in comment.",
@@ -416,6 +438,7 @@ ruleTester.run("spaced-comment", rule, {
},
{
code: "///--------\r\n/// test\r\n///--------\r\n/*/ blah *//*-----*/",
output: "///--------\r\n/// test\r\n///--------\r\n/* / blah *//*-----*/",
options: ["always", { markers: ["/"], exceptions: ["-"], block: { markers: [] } }],
errors: [{
message: "Expected exception block, space or tab after '/*' in comment.",
@@ -424,6 +447,7 @@ ruleTester.run("spaced-comment", rule, {
},
{
code: "///--------\r\n/// test\r\n///--------\r\n/*/ blah */ /*-----*/",
output: "///--------\r\n/// test\r\n///--------\r\n/* / blah */ /* -----*/",
options: ["always", { line: { markers: ["/"], exceptions: ["-"] } }],
errors: [{
message: "Expected space or tab after '/*' in comment.",

0 comments on commit c1fad4f

Please sign in to comment.
You can’t perform that action at this time.