Skip to content
This repository has been archived by the owner on Mar 23, 2024. It is now read-only.

Commit

Permalink
Merge 3b18e04 into 13d888b
Browse files Browse the repository at this point in the history
  • Loading branch information
BryanDonovan committed Oct 19, 2014
2 parents 13d888b + 3b18e04 commit b09377a
Show file tree
Hide file tree
Showing 8 changed files with 377 additions and 2 deletions.
67 changes: 67 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,40 @@ if (x) {
if (x) x++;
```

### requireSpaceBeforeKeywords

Requires space before keyword.

Type: `Array` or `Boolean`

Values: Array of quoted keywords or `true` to require all possible keywords to have a preceding space.

#### Example

```js
"requireSpaceBeforeKeywords": [
"else",
"while",
"catch"
]
```

##### Valid

```js
} else {
x++;
}
```

##### Invalid

```js
}else {
x++;
}
```

### requireSpaceAfterKeywords

Requires space after keyword.
Expand Down Expand Up @@ -403,6 +437,39 @@ if(x > y) {
```


### disallowSpaceBeforeKeywords

Disallows space before keyword.

Type: `Array` or `Boolean`

Values: Array of quoted keywords or `true` to disallow spaces before all possible keywords.

#### Example

```js
"disallowSpaceBeforeKeywords": [
"else",
"catch"
]
```

##### Valid

```js
}else {
y--;
}
```

##### Invalid

```js
} else {
y--;
}
```

### requireSpaceBeforeBlockStatements

Requires space before block statements (for loops, control structures).
Expand Down
71 changes: 71 additions & 0 deletions lib/rules/disallow-space-before-keywords.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
var assert = require('assert');
var util = require('util');
var texts = [
'Illegal space before "%s" keyword',
'Should be zero spaces instead of %d, before "%s" keyword'
];

var defaultKeywords = require('../utils').spacedKeywords;

module.exports = function() {};

module.exports.prototype = {

configure: function(keywords) {
assert(
Array.isArray(keywords) || keywords === true,
'disallowSpaceAfterKeywords option requires array or true value');

if (keywords === true) {
keywords = defaultKeywords;
}

this._keywordIndex = {};
for (var i = 0, l = keywords.length; i < l; i++) {
this._keywordIndex[keywords[i]] = true;
}
},

getOptionName: function() {
return 'disallowSpaceBeforeKeywords';
},

check: function(file, errors) {
var keywordIndex = this._keywordIndex;

function getCommentIfExists(start, end) {
return file.getComments().filter(function(comment) {
return start <= comment.range[0] && end >= comment.range[1];
})[0];
}

file.iterateTokensByType(['Keyword'], function(token, i, tokens) {
if (keywordIndex[token.value]) {
var prevToken = tokens[i - 1];
if (!prevToken) {
return;
}

var comment = getCommentIfExists(prevToken.range[1], token.range[0]);
prevToken = comment || prevToken;

var diff = token.range[0] - prevToken.range[1];

if (prevToken.loc.end.line === token.loc.start.line && diff !== 0) {
if (prevToken.type !== 'Punctuator' || prevToken.value !== ';') {
errors.add(
util.format.apply(null,
diff === 1 ?
[texts[0], token.value] :
[texts[1], diff, token.value]
),
token.loc.start.line,
token.loc.start.column
);
}
}
}
});
}

};
2 changes: 1 addition & 1 deletion lib/rules/require-space-after-keywords.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ module.exports.prototype = {
if (nextToken.type !== 'Punctuator' || nextToken.value !== ';') {
errors.add(
util.format.apply(null,
diff === 1 ?
diff === 0 ?
[texts[0], token.value] :
[texts[1], diff, token.value]
),
Expand Down
71 changes: 71 additions & 0 deletions lib/rules/require-space-before-keywords.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
var assert = require('assert');
var util = require('util');
var texts = [
'Missing space before "%s" keyword',
'Should be one space instead of %d, before "%s" keyword'
];

var defaultKeywords = require('../utils').spacedKeywords;

module.exports = function() {};

module.exports.prototype = {

configure: function(keywords) {
assert(
Array.isArray(keywords) || keywords === true,
'requireSpaceAfterKeywords option requires array or true value');

if (keywords === true) {
keywords = defaultKeywords;
}

this._keywordIndex = {};
for (var i = 0, l = keywords.length; i < l; i++) {
this._keywordIndex[keywords[i]] = true;
}
},

getOptionName: function() {
return 'requireSpaceBeforeKeywords';
},

check: function(file, errors) {
var keywordIndex = this._keywordIndex;

function getCommentIfExists(start, end) {
return file.getComments().filter(function(comment) {
return start <= comment.range[0] && end >= comment.range[1];
})[0];
}

file.iterateTokensByType(['Keyword'], function(token, i, tokens) {
if (keywordIndex[token.value]) {
var prevToken = tokens[i - 1];
if (!prevToken) {
return;
}

var comment = getCommentIfExists(prevToken.range[1], token.range[0]);
prevToken = comment || prevToken;

var diff = token.range[0] - prevToken.range[1];

if (prevToken.loc.end.line === token.loc.start.line && diff !== 1) {
if (prevToken.type !== 'Punctuator' || prevToken.value !== ';') {
errors.add(
util.format.apply(null,
diff === 0 ?
[texts[0], token.value] :
[texts[1], diff, token.value]
),
token.loc.start.line,
token.loc.start.column
);
}
}
}
});
}

};
2 changes: 2 additions & 0 deletions lib/string-checker.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ StringChecker.prototype = {
this.registerRule(new (require('./rules/disallow-multiple-var-decl'))());
this.registerRule(new (require('./rules/disallow-empty-blocks'))());
this.registerRule(new (require('./rules/require-space-after-keywords'))());
this.registerRule(new (require('./rules/require-space-before-keywords'))());
this.registerRule(new (require('./rules/disallow-space-after-keywords'))());
this.registerRule(new (require('./rules/disallow-space-before-keywords'))());
this.registerRule(new (require('./rules/require-parentheses-around-iife'))());

/* deprecated rules */
Expand Down
71 changes: 71 additions & 0 deletions test/rules/disallow-space-before-keywords.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
var Checker = require('../../lib/checker');
var assert = require('assert');

describe('rules/dissalow-space-before-keywords', function() {
var checker;

beforeEach(function() {
checker = new Checker();
checker.registerDefaultRules();
});

it('should report illegal space before keyword', function() {
checker.configure({ disallowSpaceBeforeKeywords: ['else'] });

var errors = checker.checkString('if (true) {\n} else { x++; }');
var error = errors.getErrorList()[0];

assert(errors.getErrorCount() === 1);
assert(errors.explainError(error).indexOf('Illegal space before "else" keyword') === 0);
});

it('should not report no space before keyword', function() {
checker.configure({ disallowSpaceBeforeKeywords: ['else'] });

assert(checker.checkString(
'if (x) {\n' +
'x++;\n' +
'}else {\n' +
'x--;\n' +
'}'
).isEmpty());
});

it('should show different error if there is more than one space', function() {
checker.configure({ disallowSpaceBeforeKeywords: ['else'] });

var errors = checker.checkString('if (true) {\n} else { x++; }');
var error = errors.getErrorList()[0];

assert(errors.explainError(error).indexOf('Should be zero spaces instead of 2, before "else" keyword') === 0);
});

it('should not trigger error for comments', function() {
checker.configure({ disallowSpaceBeforeKeywords: ['else'] });
assert(checker.checkString('if (true) {\n} /**/else { x++; }').isEmpty());
});

it('should report on all possible ES3 keywords if a value of true is supplied', function() {
checker.configure({ disallowSpaceBeforeKeywords: true });

var errors = checker.checkString('if (true) {\n} else { x++; }');
var error = errors.getErrorList()[0];
assert(errors.getErrorCount() === 1);
assert(errors.explainError(error).indexOf('Illegal space before "else" keyword') === 0);

errors = checker.checkString('/**/ if (true) {\n} else { x++; }');
error = errors.getErrorList()[0];
assert(errors.getErrorCount() === 1);
assert(errors.explainError(error).indexOf('Illegal space before "else" keyword') === 0);

errors = checker.checkString('do {\nx++;\n} while (x < 5)');
error = errors.getErrorList()[0];
assert(errors.getErrorCount() === 1);
assert(errors.explainError(error).indexOf('Illegal space before "while" keyword') === 0);

errors = checker.checkString('try {\nx++;\n} catch (e) {}');
error = errors.getErrorList()[0];
assert(errors.getErrorCount() === 1);
assert(errors.explainError(error).indexOf('Illegal space before "catch" keyword') === 0);
});
});
5 changes: 4 additions & 1 deletion test/rules/require-space-after-keywords.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ describe('rules/require-space-after-keywords', function() {

it('should report missing space after keyword', function() {
checker.configure({ requireSpaceAfterKeywords: ['if'] });
assert(checker.checkString('if(x) { x++; }').getErrorCount() === 1);
var errors = checker.checkString('if(x) { x++; }');
var error = errors.getErrorList()[0];

assert(errors.explainError(error).indexOf('Missing space after "if" keyword') === 0);
});

it('should not report space after keyword', function() {
Expand Down

0 comments on commit b09377a

Please sign in to comment.