Comparing version 1.4.5 to 1.5.1
@@ -9,2 +9,3 @@ var vowFs = require('vow-fs'); | ||
var excludeFiles = require('./options/exclude-files'); | ||
var fileExtensions = require('./options/file-extensions'); | ||
@@ -30,2 +31,3 @@ /** | ||
fileExtensions(config, this); | ||
excludeFiles(config, this, cwd); | ||
@@ -45,3 +47,3 @@ additionalRules(config, this, cwd); | ||
var _this = this; | ||
if (this._shouldProcess(path) && path.match(/\.js$/)) { | ||
if (this._shouldProcess(path)) { | ||
return vowFs.read(path, 'utf8').then(function(data) { | ||
@@ -123,3 +125,4 @@ return _this.checkString(data, path); | ||
/** | ||
* Returns true if specified path is not in exluded list. | ||
* Returns true if specified path is not in exluded list and if | ||
* the file extension matches a file extension to process. | ||
* | ||
@@ -131,2 +134,8 @@ * @returns {Boolean} | ||
var extension = path.extname(testPath).toLowerCase(); | ||
if (this._fileExtensions.indexOf(extension) < 0 && | ||
this._fileExtensions.indexOf('*') < 0) { | ||
return false; | ||
} | ||
return this._excludes.every(function(exclude) { | ||
@@ -133,0 +142,0 @@ return !exclude.match(testPath); |
@@ -10,2 +10,3 @@ /** | ||
var configFile = require('./cli-config'); | ||
var preset = require('./options/preset'); | ||
@@ -18,6 +19,6 @@ var Vow = require('vow'); | ||
module.exports = function(program) { | ||
var reporterPath, reporter; | ||
var promise = Vow.promise(); | ||
var reporterPath, reporter, config; | ||
var defer = Vow.defer(); | ||
var promise = defer.promise(); | ||
var checker = new Checker(); | ||
var config = configFile.load(program.config); | ||
var args = program.args; | ||
@@ -29,2 +30,15 @@ | ||
try { | ||
config = configFile.load(program.config); | ||
} catch (e) { | ||
console.error('Config source is corrupted -', e.toString()); | ||
defer.reject(1); | ||
return { | ||
checker: checker, | ||
reporter: program.reporter, | ||
promise: promise | ||
}; | ||
} | ||
/** | ||
@@ -41,8 +55,31 @@ * Trying to load config. | ||
return promise.reject(1); | ||
defer.reject(1); | ||
return { | ||
checker: checker, | ||
reporter: program.reporter, | ||
promise: promise | ||
}; | ||
} | ||
if (program.preset && !preset.exists(program.preset)) { | ||
console.error(preset.getDoesNotExistError(program.preset)); | ||
defer.reject(1); | ||
return { | ||
checker: checker, | ||
reporter: program.reporter, | ||
promise: promise | ||
}; | ||
} | ||
if (args.length === 0) { | ||
console.error('No input files specified. Try option --help for usage information.'); | ||
return promise.reject(1); | ||
defer.reject(1); | ||
return { | ||
checker: checker, | ||
reporter: program.reporter, | ||
promise: promise | ||
}; | ||
} | ||
@@ -74,3 +111,9 @@ | ||
console.error('Reporter "%s" doesn\'t exist.', reporterPath); | ||
return promise.reject(1); | ||
defer.reject(1); | ||
return { | ||
checker: checker, | ||
reporter: reporterPath, | ||
promise: promise | ||
}; | ||
} | ||
@@ -91,10 +134,10 @@ | ||
if (!errors.isEmpty()) { | ||
promise.reject(2); | ||
defer.reject(2); | ||
} | ||
}); | ||
promise.fulfill(0); | ||
defer.resolve(0); | ||
}).fail(function(e) { | ||
console.error(e.stack); | ||
promise.reject(1); | ||
defer.reject(1); | ||
}); | ||
@@ -101,0 +144,0 @@ |
var presets = { | ||
// https://contribute.jquery.org/style-guide/js/ | ||
jquery: require('../../presets/jquery.json'), | ||
google: require('../../presets/google.json') | ||
// https://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml | ||
google: require('../../presets/google.json'), | ||
// https://github.com/ymaps/codestyle/blob/master/js.md | ||
yandex: require('../../presets/yandex.json'), | ||
// https://www.mediawiki.org/wiki/Manual:Coding_conventions/JavaScript | ||
wikimedia: require('../../presets/wikimedia.json') | ||
}; | ||
module.exports = function(config) { | ||
if (!config.preset) { | ||
return; | ||
} | ||
module.exports = { | ||
/** | ||
* Get does not exist error | ||
* @param {String} preset | ||
* @return {String} | ||
*/ | ||
getDoesNotExistError: function(preset) { | ||
return 'Preset "' + preset + '" does not exist'; | ||
}, | ||
/** | ||
* Is preset exists in jscs | ||
* @param {String} preset | ||
* @return {Boolean} | ||
*/ | ||
exists: function(preset) { | ||
return !!presets[preset]; | ||
}, | ||
var preset = presets[config.preset]; | ||
/** | ||
* Extend jscs config with preset rules | ||
* @param {Object} config | ||
* @return {Boolean} | ||
*/ | ||
extend: function(config) { | ||
if (!config.preset) { | ||
return true; | ||
} | ||
delete config.preset; | ||
for (var rule in preset) { | ||
if (!(rule in config)) { | ||
config[rule] = preset[rule]; | ||
var preset = presets[config.preset]; | ||
if (!preset) { | ||
return false; | ||
} | ||
delete config.preset; | ||
for (var rule in preset) { | ||
if (!(rule in config)) { | ||
config[rule] = preset[rule]; | ||
} | ||
} | ||
return true; | ||
} | ||
}; |
@@ -33,3 +33,3 @@ var assert = require('assert'); | ||
var value = token.value; | ||
if ((value[0] === '_' || value.slice( -1 ) === '_') && | ||
if ((value[0] === '_' || value.slice(-1) === '_') && | ||
!allowedIdentifiers[value] | ||
@@ -36,0 +36,0 @@ ) { |
@@ -1,3 +0,1 @@ | ||
var assert = require('assert'); | ||
module.exports = function() {}; | ||
@@ -7,9 +5,3 @@ | ||
configure: function(operators) { | ||
assert(Array.isArray(operators), 'disallowLeftStickedOperators option requires array value'); | ||
this._operatorIndex = {}; | ||
for (var i = 0, l = operators.length; i < l; i++) { | ||
this._operatorIndex[operators[i]] = true; | ||
} | ||
}, | ||
configure: function() {}, | ||
@@ -21,17 +13,14 @@ getOptionName: function() { | ||
check: function(file, errors) { | ||
var operators = this._operatorIndex; | ||
file.iterateTokensByType('Punctuator', function(token, i, tokens) { | ||
if (operators[token.value]) { | ||
var prevToken = tokens[i - 1]; | ||
if (prevToken && prevToken.range[1] === token.range[0]) { | ||
errors.add( | ||
'Operator ' + token.value + ' should not stick to preceding expression', | ||
token.loc.start | ||
); | ||
} | ||
} | ||
}); | ||
errors.add( | ||
'The disallowLeftStickedOperators rule is no longer supported.' + | ||
'\nPlease use the following rules instead:' + | ||
'\n' + | ||
'\nrequireSpaceBeforeBinaryOperators' + | ||
'\nrequireSpaceBeforePostfixUnaryOperators' + | ||
'\nrequireSpacesInConditionalExpression', | ||
1, | ||
0 | ||
); | ||
} | ||
}; |
@@ -19,55 +19,25 @@ var assert = require('assert'); | ||
check: function(file, errors) { | ||
var _commentLineMap; | ||
var lines = file.getLines(); | ||
var tokens = file.getTokens(); | ||
function getCommentLines() { | ||
if (!_commentLineMap) { | ||
_commentLineMap = file.getComments().reduce(function(map, comment) { | ||
for (var x = comment.loc.start.line; x <= comment.loc.end.line; x++) { | ||
map[x] = 1; | ||
} | ||
return map; | ||
}, {}); | ||
} | ||
return _commentLineMap; | ||
} | ||
function hasEmptyLine(startLine, endLine) { | ||
var commentLines = getCommentLines(); | ||
for (var x = startLine; x < endLine; x++) { | ||
if (!commentLines[x]) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
file.iterateNodesByType('BlockStatement', function(node) { | ||
if (node.body.length === 0) { | ||
return; | ||
} | ||
var tokens = file.getTokens(); | ||
var openingBracketPos = file.getTokenPosByRangeStart(node.range[0]); | ||
var openingBracket = tokens[openingBracketPos]; | ||
var nextToken = tokens[openingBracketPos + 1]; | ||
var startLine = openingBracket.loc.start.line + 1; | ||
var nextLine = nextToken.loc.start.line; | ||
var startLine = openingBracket.loc.start.line; | ||
if (startLine < nextLine && hasEmptyLine(startLine, nextLine)) { | ||
errors.add('Expected no padding newline after opening curly brace', openingBracket.loc.end); | ||
} | ||
var closingBracketPos = file.getTokenPosByRangeStart(node.range[1] - 1); | ||
var closingBracket = tokens[closingBracketPos]; | ||
var prevToken = tokens[closingBracketPos - 1]; | ||
var closingLine = closingBracket.loc.start.line; | ||
var prevLine = prevToken.loc.start.line + 1; | ||
if (closingLine > prevLine && hasEmptyLine(prevLine, closingLine)) { | ||
errors.add('Expected no padding newline before closing curly brace', prevToken.loc.end); | ||
if (lines[startLine] === lines[closingLine]) { | ||
return; | ||
} | ||
if (lines[startLine] === '') { | ||
errors.add('Expected no padding newline after opening curly brace', openingBracket.loc.end); | ||
} | ||
if (lines[closingLine - 2] === '') { | ||
errors.add('Expected no padding newline before closing curly brace', closingBracket.loc.start); | ||
} | ||
}); | ||
@@ -74,0 +44,0 @@ } |
@@ -11,3 +11,3 @@ var assert = require('assert'); | ||
disallowQuotedKeysInObjects === true || disallowQuotedKeysInObjects === 'allButReserved', | ||
this.getOptionName() + ' options should be "true" or an array of exceptions' | ||
this.getOptionName() + ' options should be true or "allButReserved" value' | ||
); | ||
@@ -14,0 +14,0 @@ |
@@ -1,3 +0,1 @@ | ||
var assert = require('assert'); | ||
module.exports = function() {}; | ||
@@ -7,9 +5,3 @@ | ||
configure: function(operators) { | ||
assert(Array.isArray(operators), 'disallowRightStickedOperators option requires array value'); | ||
this._operatorIndex = {}; | ||
for (var i = 0, l = operators.length; i < l; i++) { | ||
this._operatorIndex[operators[i]] = true; | ||
} | ||
}, | ||
configure: function() {}, | ||
@@ -21,17 +13,14 @@ getOptionName: function() { | ||
check: function(file, errors) { | ||
var operators = this._operatorIndex; | ||
file.iterateTokensByType('Punctuator', function(token, i, tokens) { | ||
if (operators[token.value]) { | ||
var nextToken = tokens[i + 1]; | ||
if (nextToken && nextToken.range[0] === token.range[1]) { | ||
errors.add( | ||
'Operator ' + token.value + ' should not stick to following expression', | ||
token.loc.start | ||
); | ||
} | ||
} | ||
}); | ||
errors.add( | ||
'The disallowRightStickedOperators rule is no longer supported.' + | ||
'\nPlease use the following rules instead:' + | ||
'\n' + | ||
'\nrequireSpaceAfterBinaryOperators' + | ||
'\nrequireSpaceAfterPrefixUnaryOperators' + | ||
'\nrequireSpacesInConditionalExpression', | ||
1, | ||
0 | ||
); | ||
} | ||
}; |
var assert = require('assert'); | ||
var tokenHelper = require('../token-helper'); | ||
var allOperators = require('../utils').binaryOperators; | ||
@@ -7,5 +8,14 @@ module.exports = function() {}; | ||
module.exports.prototype = { | ||
configure: function(operators) { | ||
var isTrue = operators === true; | ||
configure: function(operators) { | ||
assert(Array.isArray(operators), 'disallowSpaceAfterBinaryOperators option requires array value'); | ||
assert( | ||
Array.isArray(operators) || isTrue, | ||
'disallowSpaceAfterBinaryOperators option requires array or true value' | ||
); | ||
if (isTrue) { | ||
operators = allOperators; | ||
} | ||
this._operatorIndex = {}; | ||
@@ -25,35 +35,72 @@ for (var i = 0, l = operators.length; i < l; i++) { | ||
// 2 + 2, 2 == 2 | ||
file.iterateNodesByType(['BinaryExpression'], function(node) { | ||
if (operators[node.operator]) { | ||
var part = tokenHelper.getTokenByRangeStartIfPunctuator( | ||
file, | ||
node.right.range[0] - 1, | ||
node.operator, | ||
true | ||
); | ||
file.iterateNodesByType( | ||
['BinaryExpression', 'AssignmentExpression', 'LogicalExpression'], | ||
function(node) { | ||
if (operators[node.operator]) { | ||
var indent; | ||
var range = node.right.range[0]; | ||
if (!part) { | ||
errors.add( | ||
'Operator ' + node.operator + ' should stick to following expression', | ||
tokenHelper.findOperatorByRangeStart(file, node.right.range[0], node.operator).loc.start | ||
if (tokenHelper.isTokenParenthesis(file, range - 1, true)) { | ||
indent = node.operator.length + 1; | ||
} else { | ||
indent = node.operator.length; | ||
} | ||
var part = tokenHelper.getTokenByRangeStartIfPunctuator( | ||
file, | ||
range - indent, | ||
node.operator, | ||
true | ||
); | ||
if (!part) { | ||
var loc = tokenHelper.findOperatorByRangeStart( | ||
file, node.right.range[0], node.operator, true | ||
).loc.start; | ||
errors.add( | ||
'Operator ' + node.operator + ' should stick to following expression', | ||
loc.line, | ||
tokenHelper.getPointerEntities(loc.column, node.operator.length) | ||
); | ||
} | ||
} | ||
} | ||
}); | ||
); | ||
// Comma and assignment | ||
if (operators[','] || operators['=']) { | ||
function errorIfApplicable(token, i, tokens, operator) { | ||
var nextToken = tokens[i + 1]; | ||
if (nextToken && nextToken.range[0] !== token.range[1]) { | ||
var loc = token.loc.start; | ||
errors.add( | ||
'Operator ' + operator + ' should stick to following expression', | ||
loc.line, | ||
tokenHelper.getPointerEntities(loc.column, token.value.length) | ||
); | ||
} | ||
} | ||
// ":" for object property only but not for ternar | ||
if (operators[':']) { | ||
file.iterateNodesByType(['ObjectExpression'], function(node) { | ||
node.properties.forEach(function(prop) { | ||
var token = tokenHelper.findOperatorByRangeStart(file, prop.range[0], ':'), | ||
tokens = file.getTokens(); | ||
errorIfApplicable(token, tokens.indexOf(token), tokens, ':'); | ||
}); | ||
}); | ||
} | ||
// Comma | ||
if (operators[',']) { | ||
file.iterateTokensByType('Punctuator', function(token, i, tokens) { | ||
var operator = token.value; | ||
if (operator !== ',' && operator !== '=' || !operators[operator]) { | ||
if (operator !== ',') { | ||
return; | ||
} | ||
var nextToken = tokens[i + 1]; | ||
if (nextToken && nextToken.range[0] !== token.range[1]) { | ||
errors.add( | ||
'Operator ' + operator + ' should stick to following expression', | ||
token.loc.start | ||
); | ||
} | ||
errorIfApplicable(token, i, tokens, operator); | ||
}); | ||
@@ -60,0 +107,0 @@ } |
var assert = require('assert'); | ||
var defaultOperators = require('../utils').unaryOperators; | ||
@@ -8,3 +9,13 @@ module.exports = function() {}; | ||
configure: function(operators) { | ||
assert(Array.isArray(operators), this.getOptionName() + ' option requires array value'); | ||
var isTrue = operators === true; | ||
assert( | ||
Array.isArray(operators) || isTrue, | ||
this.getOptionName() + ' option requires array or true value' | ||
); | ||
if (isTrue) { | ||
operators = defaultOperators; | ||
} | ||
this._operatorIndex = {}; | ||
@@ -11,0 +22,0 @@ for (var i = 0, l = operators.length; i < l; i++) { |
var assert = require('assert'); | ||
var tokenHelper = require('../token-helper'); | ||
var allOperators = require('../utils').binaryOperators; | ||
@@ -9,3 +10,13 @@ module.exports = function() {}; | ||
configure: function(operators) { | ||
assert(Array.isArray(operators), 'disallowSpaceBeforeBinaryOperators option requires array value'); | ||
var isTrue = operators === true; | ||
assert( | ||
Array.isArray(operators) || isTrue, | ||
'disallowSpaceBeforeBinaryOperators option requires array or true value' | ||
); | ||
if (isTrue) { | ||
operators = allOperators; | ||
} | ||
this._operatorIndex = {}; | ||
@@ -24,39 +35,64 @@ for (var i = 0, l = operators.length; i < l; i++) { | ||
// 2 + 2, 2 == 2 | ||
file.iterateNodesByType(['BinaryExpression'], function(node) { | ||
if (operators[node.operator]) { | ||
var part = tokenHelper.getTokenByRangeStartIfPunctuator( | ||
file, | ||
node.left.range[1], | ||
node.operator | ||
function errorIfApplicable(token, i, tokens, operator) { | ||
var prevToken = tokens[i - 1]; | ||
if (prevToken && prevToken.range[1] !== token.range[0]) { | ||
var loc = token.loc.start; | ||
errors.add( | ||
'Operator ' + operator + ' should stick to preceding expression', | ||
loc.line, | ||
tokenHelper.getPointerEntities(loc.column, token.value.length) | ||
); | ||
if (!part) { | ||
errors.add( | ||
'Operator ' + node.operator + ' should stick to preceding expression', | ||
tokenHelper.findOperatorByRangeStart(file, node.right.range[0], node.operator).loc.start | ||
); | ||
} | ||
} | ||
}); | ||
} | ||
// Comma and assignment | ||
if (operators[','] || operators['=']) { | ||
// ":" for object property only but not for ternar | ||
if (operators[':']) { | ||
file.iterateNodesByType(['ObjectExpression'], function(node) { | ||
node.properties.forEach(function(prop) { | ||
var token = tokenHelper.findOperatorByRangeStart(file, prop.range[0], ':'), | ||
tokens = file.getTokens(); | ||
errorIfApplicable(token, tokens.indexOf(token), tokens, ':'); | ||
}); | ||
}); | ||
} | ||
// Comma | ||
if (operators[',']) { | ||
file.iterateTokensByType('Punctuator', function(token, i, tokens) { | ||
var operator = token.value; | ||
if (operator !== ',' && operator !== '=' || !operators[operator]) { | ||
if (operator !== ',') { | ||
return; | ||
} | ||
var prevToken = tokens[i - 1]; | ||
if (prevToken && prevToken.range[1] !== token.range[0]) { | ||
errors.add( | ||
'Operator ' + operator + ' should stick to preceding expression', | ||
token.loc.start | ||
errorIfApplicable(token, i, tokens, operator); | ||
}); | ||
} | ||
// For everything else | ||
file.iterateNodesByType( | ||
['BinaryExpression', 'AssignmentExpression', 'LogicalExpression'], | ||
function(node) { | ||
if (operators[node.operator]) { | ||
var part = tokenHelper.getTokenByRangeStartIfPunctuator( | ||
file, | ||
node.left.range[1], | ||
node.operator | ||
); | ||
if (!part) { | ||
errors.add( | ||
'Operator ' + node.operator + ' should stick to preceding expression', | ||
tokenHelper.findOperatorByRangeStart( | ||
file, node.right.range[0], node.operator, true | ||
).loc.start | ||
); | ||
} | ||
} | ||
}); | ||
} | ||
} | ||
); | ||
} | ||
}; |
var assert = require('assert'); | ||
var defaultOperators = require('../utils').incrementAndDecrementOperators; | ||
@@ -8,3 +9,13 @@ module.exports = function() {}; | ||
configure: function(operators) { | ||
assert(Array.isArray(operators), this.getOptionName() + ' option requires array value'); | ||
var isTrue = operators === true; | ||
assert( | ||
Array.isArray(operators) || isTrue, | ||
this.getOptionName() + ' option requires array or true value' | ||
); | ||
if (isTrue) { | ||
operators = defaultOperators; | ||
} | ||
this._operatorIndex = {}; | ||
@@ -11,0 +22,0 @@ for (var i = 0, l = operators.length; i < l; i++) { |
@@ -48,3 +48,9 @@ var assert = require('assert'); | ||
file.iterateNodesByType(['FunctionExpression'], function(node) { | ||
var parent = node.parentNode; | ||
// Ignore syntactic sugar for getters and setters. | ||
if (parent.type === 'Property' && (parent.kind === 'get' || parent.kind === 'set')) { | ||
return; | ||
} | ||
// anonymous function expressions only | ||
@@ -51,0 +57,0 @@ if (!node.id) { |
@@ -47,3 +47,9 @@ var assert = require('assert'); | ||
file.iterateNodesByType(['FunctionDeclaration', 'FunctionExpression'], function(node) { | ||
var parent = node.parentNode; | ||
// Ignore syntactic sugar for getters and setters. | ||
if (parent.type === 'Property' && (parent.kind === 'get' || parent.kind === 'set')) { | ||
return; | ||
} | ||
if (beforeOpeningRoundBrace) { | ||
@@ -50,0 +56,0 @@ var nodeBeforeRoundBrace = node; |
@@ -9,9 +9,7 @@ var assert = require('assert'); | ||
assert( | ||
typeof disallow === 'boolean', | ||
this.getOptionName() + ' option requires boolean value' | ||
disallow === true || disallow === 'all' || disallow === 'nested', | ||
this.getOptionName() + ' option requires "all"(true value) or "nested" string' | ||
); | ||
assert( | ||
disallow === true, | ||
this.getOptionName() + ' option requires true value or should be removed' | ||
); | ||
this._mode = disallow === true ? 'all' : disallow; | ||
}, | ||
@@ -24,27 +22,42 @@ | ||
check: function(file, errors) { | ||
file.iterateNodesByType('ArrayExpression', function(node) { | ||
var mode = this._mode; | ||
file.iterateNodesByType(['ArrayExpression'], function(node) { | ||
var tokens = file.getTokens(); | ||
var openingBracketPos = file.getTokenPosByRangeStart(node.range[0]); | ||
var closingBracketPos = file.getTokenPosByRangeStart(node.range[1] - 1); | ||
var openingBracket = tokens[openingBracketPos]; | ||
var nextToken = tokens[openingBracketPos + 1]; | ||
var brackets = { | ||
opening: tokens[openingBracketPos], | ||
closing: tokens[closingBracketPos] | ||
}; | ||
if (openingBracket.loc.start.line === nextToken.loc.start.line && | ||
openingBracket.range[1] !== nextToken.range[0] | ||
) { | ||
errors.add('Illegal space after opening square brace', openingBracket.loc.end); | ||
} | ||
var insideTokens = { | ||
prev: tokens[closingBracketPos - 1], | ||
next: tokens[openingBracketPos + 1] | ||
}; | ||
var closingBracketPos = file.getTokenPosByRangeStart(node.range[1] - 1); | ||
var closingBracket = tokens[closingBracketPos]; | ||
var prevToken = tokens[closingBracketPos - 1]; | ||
if (mode === 'all') { | ||
check(brackets, errors, insideTokens); | ||
if (closingBracket.loc.start.line === prevToken.loc.start.line && | ||
closingBracket.range[0] !== prevToken.range[1] | ||
) { | ||
errors.add('Illegal space before closing square brace', prevToken.loc.end); | ||
} else if (node.parentNode.type === 'ArrayExpression') { | ||
check(brackets, errors, insideTokens); | ||
} | ||
}); | ||
} | ||
}; | ||
}; | ||
function check(brackets, errors, insideTokens) { | ||
if (brackets.opening.loc.start.line === insideTokens.next.loc.start.line && | ||
brackets.opening.range[1] !== insideTokens.next.range[0] | ||
) { | ||
errors.add('Illegal space after opening square brace', brackets.opening.loc.end); | ||
} | ||
if (brackets.closing.loc.start.line === insideTokens.prev.loc.start.line && | ||
brackets.closing.range[0] !== insideTokens.prev.range[1] | ||
) { | ||
errors.add('Illegal space before closing square brace', insideTokens.prev.loc.end); | ||
} | ||
} |
@@ -9,9 +9,8 @@ var assert = require('assert'); | ||
assert( | ||
typeof disallowSpacesInsideObjectBrackets === 'boolean', | ||
'disallowSpacesInsideObjectBrackets option requires boolean value' | ||
disallowSpacesInsideObjectBrackets === true || disallowSpacesInsideObjectBrackets === 'all' || | ||
disallowSpacesInsideObjectBrackets === 'nested', | ||
'disallowSpacesInsideObjectBrackets option requires "all"(true value) or "nested" string' | ||
); | ||
assert( | ||
disallowSpacesInsideObjectBrackets === true, | ||
'disallowSpacesInsideObjectBrackets option requires true value or should be removed' | ||
); | ||
this._mode = disallowSpacesInsideObjectBrackets === true ? 'all' : disallowSpacesInsideObjectBrackets; | ||
}, | ||
@@ -24,27 +23,42 @@ | ||
check: function(file, errors) { | ||
var mode = this._mode; | ||
file.iterateNodesByType('ObjectExpression', function(node) { | ||
var tokens = file.getTokens(); | ||
var openingBracketPos = file.getTokenPosByRangeStart(node.range[0]); | ||
var closingBracketPos = file.getTokenPosByRangeStart(node.range[1] - 1); | ||
var openingBracket = tokens[openingBracketPos]; | ||
var nextToken = tokens[openingBracketPos + 1]; | ||
var brackets = { | ||
opening: tokens[openingBracketPos], | ||
closing: tokens[closingBracketPos] | ||
}; | ||
if (openingBracket.loc.start.line === nextToken.loc.start.line && | ||
openingBracket.range[1] !== nextToken.range[0] | ||
) { | ||
errors.add('Illegal space after opening curly brace', openingBracket.loc.end); | ||
} | ||
var insideTokens = { | ||
prev: tokens[closingBracketPos - 1], | ||
next: tokens[openingBracketPos + 1] | ||
}; | ||
var closingBracketPos = file.getTokenPosByRangeStart(node.range[1] - 1); | ||
var closingBracket = tokens[closingBracketPos]; | ||
var prevToken = tokens[closingBracketPos - 1]; | ||
if (mode === 'all') { | ||
check(brackets, errors, insideTokens); | ||
if (closingBracket.loc.start.line === prevToken.loc.start.line && | ||
closingBracket.range[0] !== prevToken.range[1] | ||
) { | ||
errors.add('Illegal space before closing curly brace', prevToken.loc.end); | ||
} else if (node.parentNode.type === 'Property') { | ||
check(brackets, errors, insideTokens); | ||
} | ||
}); | ||
} | ||
}; | ||
}; | ||
function check(brackets, errors, insideTokens) { | ||
if (brackets.opening.loc.start.line === insideTokens.next.loc.start.line && | ||
brackets.opening.range[1] !== insideTokens.next.range[0] | ||
) { | ||
errors.add('Illegal space after opening curly brace', brackets.opening.loc.end); | ||
} | ||
if (brackets.closing.loc.start.line === insideTokens.prev.loc.start.line && | ||
brackets.closing.range[0] !== insideTokens.prev.range[1] | ||
) { | ||
errors.add('Illegal space before closing curly brace', insideTokens.prev.loc.end); | ||
} | ||
} |
var assert = require('assert'); | ||
var commentHelper = require('../comment-helper'); | ||
@@ -8,8 +9,31 @@ module.exports = function() {}; | ||
configure: function(maximumLineLength) { | ||
assert( | ||
typeof maximumLineLength === 'number', | ||
'maximumLineLength option requires number value' | ||
); | ||
this._tabSize = ''; | ||
this._allowRegex = false; | ||
this._allowComments = false; | ||
this._allowUrlComments = false; | ||
this._maximumLineLength = maximumLineLength; | ||
if (typeof maximumLineLength === 'object') { | ||
assert( | ||
typeof maximumLineLength.value === 'number', | ||
'maximumLineLength option requires the "value" property to be defined' | ||
); | ||
this._maximumLineLength = maximumLineLength.value; | ||
var tabSize = maximumLineLength.tabSize || 0; | ||
while (tabSize--) { | ||
this._tabSize += ' '; | ||
} | ||
this._allowRegex = (maximumLineLength.allowRegex === true); | ||
this._allowComments = (maximumLineLength.allowComments === true); | ||
this._allowUrlComments = (maximumLineLength.allowUrlComments === true); | ||
} else { | ||
assert( | ||
typeof maximumLineLength === 'number', | ||
'maximumLineLength option requires number value or options object' | ||
); | ||
this._maximumLineLength = maximumLineLength; | ||
} | ||
}, | ||
@@ -24,6 +48,30 @@ | ||
var lines = file.getLines(); | ||
var lines = this._allowComments ? commentHelper.getLinesWithCommentsRemoved(file) : file.getLines(); | ||
var line; | ||
if (this._allowRegex) { | ||
file.iterateTokensByType('RegularExpression', function(token) { | ||
for (var i = token.loc.start.line; i <= token.loc.end.line; i++) { | ||
lines[i - 1] = ''; | ||
} | ||
}); | ||
} | ||
if (this._allowUrlComments) { | ||
file.getComments().forEach(function(comment) { | ||
for (var i = comment.loc.start.line; i <= comment.loc.end.line; i++) { | ||
lines[i - 1] = lines[i - 1].replace(/(http|https|ftp):\/\/[^\s$]+/, ''); | ||
} | ||
}); | ||
} | ||
for (var i = 0, l = lines.length; i < l; i++) { | ||
if (lines[i].length > maximumLineLength) { | ||
errors.add('Line must be at most ' + maximumLineLength + ' characters', i + 1, 0); | ||
line = this._tabSize ? lines[i].replace(/\t/g, this._tabSize) : lines[i]; | ||
if (line.length > maximumLineLength) { | ||
errors.add( | ||
'Line must be at most ' + maximumLineLength + ' characters', | ||
i + 1, | ||
lines[i].length | ||
); | ||
} | ||
@@ -30,0 +78,0 @@ } |
@@ -7,11 +7,9 @@ var assert = require('assert'); | ||
configure: function(requireCamelCaseOrUpperCaseIdentifiers) { | ||
configure: function(requireCamelCase) { | ||
assert( | ||
typeof requireCamelCaseOrUpperCaseIdentifiers === 'boolean', | ||
'requireCamelCaseOrUpperCaseIdentifiers option requires boolean value' | ||
requireCamelCase === true || requireCamelCase === 'ignoreProperties', | ||
'requireCamelCaseOrUpperCaseIdentifiers option requires true value or `ignoreProperties` string' | ||
); | ||
assert( | ||
requireCamelCaseOrUpperCaseIdentifiers === true, | ||
'requireCamelCaseOrUpperCaseIdentifiers option requires true value or should be removed' | ||
); | ||
this._ignoreProperties = (requireCamelCase === 'ignoreProperties'); | ||
}, | ||
@@ -24,14 +22,23 @@ | ||
check: function(file, errors) { | ||
file.iterateTokensByType('Identifier', function(token) { | ||
file.iterateTokensByType('Identifier', function(token, index, tokens) { | ||
var value = token.value; | ||
if (value.replace(/^_+|_+$/g, '').indexOf('_') > -1 && value.toUpperCase() !== value) { | ||
errors.add( | ||
'All identifiers must be camelCase or UPPER_CASE', | ||
token.loc.start.line, | ||
token.loc.start.column | ||
); | ||
if (value.replace(/^_+|_+$/g, '').indexOf('_') === -1 || value.toUpperCase() === value) { | ||
return; | ||
} | ||
}); | ||
if (this._ignoreProperties) { | ||
if (index + 1 < tokens.length && tokens[index + 1].value === ':') { | ||
return; | ||
} | ||
if (index > 0 && tokens[index - 1].value === '.') { | ||
return; | ||
} | ||
} | ||
errors.add( | ||
'All identifiers must be camelCase or UPPER_CASE', | ||
token.loc.start.line, | ||
token.loc.start.column | ||
); | ||
}.bind(this)); | ||
} | ||
}; |
@@ -1,3 +0,1 @@ | ||
var assert = require('assert'); | ||
module.exports = function() {}; | ||
@@ -7,9 +5,3 @@ | ||
configure: function(operators) { | ||
assert(Array.isArray(operators), 'requireLeftStickedOperators option requires array value'); | ||
this._operatorIndex = {}; | ||
for (var i = 0, l = operators.length; i < l; i++) { | ||
this._operatorIndex[operators[i]] = true; | ||
} | ||
}, | ||
configure: function() {}, | ||
@@ -21,17 +13,14 @@ getOptionName: function() { | ||
check: function(file, errors) { | ||
var operators = this._operatorIndex; | ||
file.iterateTokensByType('Punctuator', function(token, i, tokens) { | ||
if (operators[token.value]) { | ||
var prevToken = tokens[i - 1]; | ||
if (prevToken && prevToken.range[1] !== token.range[0]) { | ||
errors.add( | ||
'Operator ' + token.value + ' should stick to preceding expression', | ||
token.loc.start | ||
); | ||
} | ||
} | ||
}); | ||
errors.add( | ||
'The requireLeftStickedOperators rule is no longer supported.' + | ||
'\nPlease use the following rules instead:' + | ||
'\n' + | ||
'\ndisallowSpaceBeforeBinaryOperators' + | ||
'\ndisallowSpaceBeforePostfixUnaryOperators' + | ||
'\ndisallowSpacesInConditionalExpressions', | ||
1, | ||
0 | ||
); | ||
} | ||
}; |
@@ -27,7 +27,7 @@ var assert = require('assert'); | ||
// Don't go in nested scopes | ||
if ( !firstParent && type && ['FunctionDeclaration', 'FunctionExpression'].indexOf(type) > -1) { | ||
if (!firstParent && type && ['FunctionDeclaration', 'FunctionExpression'].indexOf(type) > -1) { | ||
return false; | ||
} | ||
if ( firstParent ) { | ||
if (firstParent) { | ||
firstParent = false; | ||
@@ -34,0 +34,0 @@ } |
var assert = require('assert'); | ||
var tokenHelper = require('../token-helper'); | ||
var defaultOperators = require('../utils').binaryOperators.slice(); | ||
defaultOperators.push('?'); | ||
module.exports = function() {}; | ||
@@ -8,3 +12,13 @@ | ||
configure: function(operators) { | ||
assert(Array.isArray(operators), 'requireOperatorBeforeLineBreak option requires array value'); | ||
var isTrue = operators === true; | ||
assert( | ||
Array.isArray(operators) || isTrue, | ||
'requireOperatorBeforeLineBreak option requires array value or true value' | ||
); | ||
if (isTrue) { | ||
operators = defaultOperators; | ||
} | ||
this._operatorIndex = {}; | ||
@@ -22,16 +36,58 @@ for (var i = 0, l = operators.length; i < l; i++) { | ||
var operators = this._operatorIndex; | ||
var tokens = file.getTokens(); | ||
var throughTokens = ['?', ':', ',']; | ||
file.iterateTokensByType('Punctuator', function(token, i, tokens) { | ||
if (operators[token.value]) { | ||
var prevToken = tokens[i - 1]; | ||
if (prevToken && prevToken.loc.end.line !== token.loc.start.line) { | ||
errors.add( | ||
'Operator ' + token.value + ' should not be on a new line', | ||
token.loc.start | ||
); | ||
function errorIfApplicable(token, i, tokens) { | ||
var prevToken = tokens[i - 1]; | ||
if (prevToken && prevToken.loc.end.line !== token.loc.start.line) { | ||
var loc = token.loc.start; | ||
errors.add( | ||
'Operator ' + token.value + ' should not be on a new line', | ||
loc.line, | ||
tokenHelper.getPointerEntities(loc.column, token.value.length) | ||
); | ||
} | ||
} | ||
throughTokens = throughTokens.filter(function(operator) { | ||
return operators[operator]; | ||
}); | ||
if (throughTokens.length) { | ||
file.iterateTokensByType('Punctuator', function(token, i, tokens) { | ||
var operator = token.value; | ||
if (throughTokens.every(function() { | ||
return throughTokens.indexOf(operator) >= 0; | ||
})) { | ||
errorIfApplicable(token, i, tokens, operator); | ||
} | ||
}); | ||
} | ||
file.iterateNodesByType( | ||
['BinaryExpression', 'AssignmentExpression', 'LogicalExpression'], | ||
function(node) { | ||
var operator = node.operator; | ||
if (!operators[operator]) { | ||
return; | ||
} | ||
var token = tokenHelper.findOperatorByRangeStart( | ||
file, | ||
node.left.argument ? node.left.argument.range[0] : node.left.range[0], | ||
operator | ||
); | ||
errorIfApplicable( | ||
token, | ||
tokens.indexOf(token), | ||
tokens | ||
); | ||
} | ||
}); | ||
); | ||
} | ||
}; |
@@ -1,3 +0,1 @@ | ||
var assert = require('assert'); | ||
module.exports = function() {}; | ||
@@ -7,9 +5,3 @@ | ||
configure: function(operators) { | ||
assert(Array.isArray(operators), 'requireRightStickedOperators option requires array value'); | ||
this._operatorIndex = {}; | ||
for (var i = 0, l = operators.length; i < l; i++) { | ||
this._operatorIndex[operators[i]] = true; | ||
} | ||
}, | ||
configure: function() {}, | ||
@@ -21,17 +13,14 @@ getOptionName: function() { | ||
check: function(file, errors) { | ||
var operators = this._operatorIndex; | ||
file.iterateTokensByType('Punctuator', function(token, i, tokens) { | ||
if (operators[token.value]) { | ||
var nextToken = tokens[i + 1]; | ||
if (nextToken && nextToken.range[0] !== token.range[1]) { | ||
errors.add( | ||
'Operator ' + token.value + ' should stick to following expression', | ||
token.loc.start | ||
); | ||
} | ||
} | ||
}); | ||
errors.add( | ||
'The requireRightStickedOperators rule is no longer supported.' + | ||
'\nPlease use the following rules instead:' + | ||
'\n' + | ||
'\ndisallowSpaceAfterBinaryOperators' + | ||
'\ndisallowSpaceAfterPrefixUnaryOperators' + | ||
'\ndisallowSpacesInConditionalExpressions', | ||
1, | ||
0 | ||
); | ||
} | ||
}; |
var assert = require('assert'); | ||
var tokenHelper = require('../token-helper'); | ||
var allOperators = require('../utils').binaryOperators; | ||
@@ -9,3 +10,13 @@ module.exports = function() {}; | ||
configure: function(operators) { | ||
assert(Array.isArray(operators), 'requireSpaceAfterBinaryOperators option requires array value'); | ||
var isTrue = operators === true; | ||
assert( | ||
Array.isArray(operators) || isTrue, | ||
'requireSpaceAfterBinaryOperators option requires array or true value' | ||
); | ||
if (isTrue) { | ||
operators = allOperators; | ||
} | ||
this._operatorIndex = {}; | ||
@@ -24,40 +35,75 @@ for (var i = 0, l = operators.length; i < l; i++) { | ||
// 2 + 2, 2 == 2 | ||
file.iterateNodesByType(['BinaryExpression'], function(node) { | ||
if (operators[node.operator]) { | ||
var part = tokenHelper.getTokenByRangeStartIfPunctuator( | ||
file, | ||
node.right.range[0] - 1, | ||
node.operator, | ||
true | ||
function errorIfApplicable(token, i, tokens, operator) { | ||
var nextToken = tokens[i + 1]; | ||
if (token && nextToken && nextToken.range[0] === token.range[1]) { | ||
var loc = token.loc.start; | ||
errors.add( | ||
'Operator ' + operator + ' should not stick to following expression', | ||
loc.line, | ||
tokenHelper.getPointerEntities(loc.column, token.value.length) | ||
); | ||
if (part) { | ||
errors.add( | ||
'Operator ' + node.operator + ' should not stick to following expression', | ||
part.loc.start | ||
); | ||
} | ||
} | ||
}); | ||
} | ||
// Comma and assignment | ||
if (operators[','] || operators['=']) { | ||
// ":" for object property only but not for ternar | ||
if (operators[':']) { | ||
file.iterateNodesByType(['ObjectExpression'], function(node) { | ||
node.properties.forEach(function(prop) { | ||
var token = tokenHelper.findOperatorByRangeStart(file, prop.range[0], ':'), | ||
tokens = file.getTokens(); | ||
errorIfApplicable(token, tokens.indexOf(token), tokens, ':'); | ||
}); | ||
}); | ||
} | ||
// Comma | ||
if (operators[',']) { | ||
file.iterateTokensByType('Punctuator', function(token, i, tokens) { | ||
var operator = token.value; | ||
if (operator !== ',' && operator !== '=' || !operators[operator]) { | ||
if (operator !== ',') { | ||
return; | ||
} | ||
var nextToken = tokens[i + 1]; | ||
if (nextToken && nextToken.range[0] === token.range[1]) { | ||
errors.add( | ||
'Operator ' + operator + ' should not stick to following expression', | ||
token.loc.start | ||
errorIfApplicable(token, i, tokens, operator); | ||
}); | ||
} | ||
// For everything else | ||
file.iterateNodesByType( | ||
['BinaryExpression', 'AssignmentExpression', 'LogicalExpression'], | ||
function(node) { | ||
if (operators[node.operator]) { | ||
var indent; | ||
var range = node.right.range[0]; | ||
if (tokenHelper.isTokenParenthesis(file, range - 1, true)) { | ||
indent = node.operator.length + 1; | ||
} else { | ||
indent = node.operator.length; | ||
} | ||
var part = tokenHelper.getTokenByRangeStartIfPunctuator( | ||
file, | ||
range - indent, | ||
node.operator, | ||
true | ||
); | ||
if (part) { | ||
var loc = part.loc.start; | ||
errors.add( | ||
'Operator ' + node.operator + ' should not stick to following expression', | ||
loc.line, | ||
tokenHelper.getPointerEntities(loc.column, node.operator.length) | ||
); | ||
} | ||
} | ||
}); | ||
} | ||
} | ||
); | ||
} | ||
}; |
var assert = require('assert'); | ||
var util = require('util'); | ||
var texts = [ | ||
'Missing space after "%s" keyword', | ||
'Should be one space instead of %d, after "%s" keyword' | ||
]; | ||
@@ -22,13 +27,27 @@ module.exports = function() {}; | ||
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 nextToken = tokens[i + 1]; | ||
var comment = getCommentIfExists(token.range[1], nextToken.range[0]); | ||
nextToken = comment || nextToken; | ||
var diff = nextToken.range[0] - token.range[1]; | ||
if (nextToken && | ||
nextToken.loc.end.line === token.loc.start.line && | ||
nextToken.range[0] - token.range[1] !== 1 | ||
diff !== 1 | ||
) { | ||
if (nextToken.type !== 'Punctuator' || nextToken.value !== ';') { | ||
errors.add( | ||
'Missing space after `' + token.value + '` keyword', | ||
util.format.apply(null, | ||
diff === 1 ? | ||
[texts[0], token.value] : | ||
[texts[1], diff, token.value] | ||
), | ||
nextToken.loc.start.line, | ||
@@ -35,0 +54,0 @@ nextToken.loc.start.column |
var assert = require('assert'); | ||
var defaultOperators = require('../utils').unaryOperators; | ||
@@ -8,3 +9,13 @@ module.exports = function() {}; | ||
configure: function(operators) { | ||
assert(Array.isArray(operators), this.getOptionName() + ' option requires array value'); | ||
var isTrue = operators === true; | ||
assert( | ||
Array.isArray(operators) || isTrue, | ||
this.getOptionName() + ' option requires array or true value' | ||
); | ||
if (isTrue) { | ||
operators = defaultOperators; | ||
} | ||
this._operatorIndex = {}; | ||
@@ -27,5 +38,15 @@ for (var i = 0, l = operators.length; i < l; i++) { | ||
if (node.prefix && operatorIndex[node.operator]) { | ||
var argument = node.argument.type; | ||
var operatorTokenIndex = file.getTokenPosByRangeStart(node.range[0]); | ||
var operatorToken = tokens[operatorTokenIndex]; | ||
var nextToken = tokens[operatorTokenIndex + 1]; | ||
// Do not report consecutive operators (#405) | ||
if ( | ||
argument === 'UnaryExpression' || argument === 'UpdateExpression' && | ||
nextToken.value !== '(' | ||
) { | ||
return; | ||
} | ||
if (operatorToken.range[1] === nextToken.range[0]) { | ||
@@ -32,0 +53,0 @@ errors.add('Operator ' + node.operator + ' should not stick to operand', node.loc.start); |
var assert = require('assert'); | ||
var tokenHelper = require('../token-helper'); | ||
var allOperators = require('../utils').binaryOperators; | ||
@@ -9,3 +10,13 @@ module.exports = function() {}; | ||
configure: function(operators) { | ||
assert(Array.isArray(operators), 'requireSpaceBeforeBinaryOperators option requires array value'); | ||
var isTrue = operators === true; | ||
assert( | ||
Array.isArray(operators) || isTrue, | ||
'requireSpaceBeforeBinaryOperators option requires array or true value' | ||
); | ||
if (isTrue) { | ||
operators = allOperators; | ||
} | ||
this._operatorIndex = {}; | ||
@@ -24,39 +35,64 @@ for (var i = 0, l = operators.length; i < l; i++) { | ||
// 2 + 2, 2 == 2 | ||
file.iterateNodesByType(['BinaryExpression'], function(node) { | ||
if (operators[node.operator]) { | ||
var part = tokenHelper.getTokenByRangeStartIfPunctuator( | ||
file, | ||
node.left.range[1], | ||
node.operator | ||
function errorIfApplicable(token, i, tokens, operator) { | ||
var prevToken = tokens[i - 1]; | ||
if (prevToken && prevToken.range[1] === token.range[0]) { | ||
var loc = token.loc.start; | ||
errors.add( | ||
'Operator ' + operator + ' should not stick to preceding expression', | ||
loc.line, | ||
tokenHelper.getPointerEntities(loc.column, token.value.length) | ||
); | ||
if (part) { | ||
errors.add( | ||
'Operator ' + node.operator + ' should not stick to preceding expression', | ||
part.loc.start | ||
); | ||
} | ||
} | ||
}); | ||
} | ||
// Comma and assignment | ||
if (operators[','] || operators['=']) { | ||
// ":" for object property only but not for ternar | ||
if (operators[':']) { | ||
file.iterateNodesByType(['ObjectExpression'], function(node) { | ||
node.properties.forEach(function(prop) { | ||
var token = tokenHelper.findOperatorByRangeStart(file, prop.range[0], ':'), | ||
tokens = file.getTokens(); | ||
errorIfApplicable(token, tokens.indexOf(token), tokens, ':'); | ||
}); | ||
}); | ||
} | ||
// Comma | ||
if (operators[',']) { | ||
file.iterateTokensByType('Punctuator', function(token, i, tokens) { | ||
var operator = token.value; | ||
if (operator !== ',' && operator !== '=' || !operators[operator]) { | ||
if (operator !== ',') { | ||
return; | ||
} | ||
var prevToken = tokens[i - 1]; | ||
if (prevToken && prevToken.range[1] === token.range[0]) { | ||
errors.add( | ||
'Operator ' + operator + ' should not stick to preceding expression', | ||
token.loc.start | ||
errorIfApplicable(token, i, tokens, operator); | ||
}); | ||
} | ||
// For everything else | ||
file.iterateNodesByType( | ||
['BinaryExpression', 'AssignmentExpression', 'LogicalExpression'], | ||
function(node) { | ||
if (operators[node.operator]) { | ||
var part = tokenHelper.getTokenByRangeStartIfPunctuator( | ||
file, | ||
node.left.range[1], | ||
node.operator | ||
); | ||
if (part) { | ||
var loc = part.loc.start; | ||
errors.add( | ||
'Operator ' + node.operator + ' should not stick to following expression', | ||
loc.line, | ||
tokenHelper.getPointerEntities(loc.column, node.operator.length) | ||
); | ||
} | ||
} | ||
}); | ||
} | ||
} | ||
); | ||
} | ||
}; |
var assert = require('assert'); | ||
var defaultOperators = require('../utils').incrementAndDecrementOperators; | ||
@@ -8,3 +9,13 @@ module.exports = function() {}; | ||
configure: function(operators) { | ||
assert(Array.isArray(operators), this.getOptionName() + ' option requires array value'); | ||
var isTrue = operators === true; | ||
assert( | ||
Array.isArray(operators) || isTrue, | ||
this.getOptionName() + ' option requires array or true value' | ||
); | ||
if (isTrue) { | ||
operators = defaultOperators; | ||
} | ||
this._operatorIndex = {}; | ||
@@ -11,0 +22,0 @@ for (var i = 0, l = operators.length; i < l; i++) { |
@@ -48,3 +48,9 @@ var assert = require('assert'); | ||
file.iterateNodesByType(['FunctionExpression'], function(node) { | ||
var parent = node.parentNode; | ||
// Ignore syntactic sugar for getters and setters. | ||
if (parent.type === 'Property' && (parent.kind === 'get' || parent.kind === 'set')) { | ||
return; | ||
} | ||
if (!node.id) { | ||
@@ -51,0 +57,0 @@ |
@@ -47,3 +47,9 @@ var assert = require('assert'); | ||
file.iterateNodesByType(['FunctionDeclaration', 'FunctionExpression'], function(node) { | ||
var parent = node.parentNode; | ||
// Ignore syntactic sugar for getters and setters. | ||
if (parent.type === 'Property' && (parent.kind === 'get' || parent.kind === 'set')) { | ||
return; | ||
} | ||
if (beforeOpeningRoundBrace) { | ||
@@ -50,0 +56,0 @@ var nodeBeforeRoundBrace = node; |
@@ -48,8 +48,4 @@ var assert = require('assert'); | ||
if (closingBracket.range[0] === prevToken.range[1]) { | ||
if (!isNested) { | ||
errors.add('Missing space before closing curly brace', closingBracket.loc.start); | ||
} | ||
} else if (isNested && closingBracket.loc.start.line === prevToken.loc.start.line) { | ||
errors.add('Illegal space between closing curly braces', prevToken.loc.end); | ||
if (closingBracket.range[0] === prevToken.range[1] && !isNested) { | ||
errors.add('Missing space before closing curly brace', closingBracket.loc.start); | ||
} | ||
@@ -56,0 +52,0 @@ }); |
var assert = require('assert'); | ||
var commentHelper = require('../comment-helper'); | ||
@@ -37,32 +38,2 @@ module.exports = function() {}; | ||
check: function(file, errors) { | ||
function getLinesWithCommentsRemoved() { | ||
var lines = file.getLines().concat(); | ||
file.getComments().reverse().forEach(function(comment) { | ||
var startLine = comment.loc.start.line; | ||
var startCol = comment.loc.start.column; | ||
var endLine = comment.loc.end.line; | ||
var endCol = comment.loc.end.column; | ||
var i = startLine - 1; | ||
if (startLine === endLine) { | ||
lines[i] = lines[i].substring(0, startCol) + lines[i].substring(endCol); | ||
} else { | ||
lines[i] = lines[i].substring(0, startCol); | ||
for (var x = i + 1; x < endLine - 1; x++) { | ||
lines[x] = ''; | ||
} | ||
lines[x] = lines[x].substring(endCol + 1); | ||
if (lines[x] !== '') { | ||
errors.add( | ||
'Multiline comments should not have tokens on its ending line', | ||
x + 1, | ||
endCol | ||
); | ||
} | ||
} | ||
}); | ||
return lines; | ||
} | ||
function isMultiline(node) { | ||
@@ -80,3 +51,3 @@ return node.loc.start.line !== node.loc.end.line; | ||
var loc = node.loc; | ||
if ( popAfter ) { | ||
if (popAfter) { | ||
linesToCheck[loc.end.line - 1].popAfter = true; | ||
@@ -228,4 +199,4 @@ } else { | ||
if ( children.length > 0 && | ||
node.loc.start.column === children[0].loc.start.column ) { | ||
if (children.length > 0 && | ||
node.loc.start.column === children[0].loc.start.column) { | ||
indents = 0; | ||
@@ -282,3 +253,3 @@ } | ||
var lines = getLinesWithCommentsRemoved(); | ||
var lines = commentHelper.getLinesWithCommentsRemoved(file, errors); | ||
var indentStack = [0]; | ||
@@ -285,0 +256,0 @@ var linesToCheck = lines.map(function() { |
@@ -42,3 +42,3 @@ var assert = require('assert'); | ||
var mark = str[0]; | ||
var stripped = str.substring(1, str.length -1); | ||
var stripped = str.substring(1, str.length - 1); | ||
@@ -45,0 +45,0 @@ if (quoteMark === true) { |
@@ -62,5 +62,7 @@ var esprima = require('esprima'); | ||
this.registerRule(new (require('./rules/validate-jsdoc'))()); | ||
this.registerRule(new (require('./rules/require-yoda-conditions'))()); | ||
this.registerRule(new (require('./rules/disallow-yoda-conditions'))()); | ||
this.registerRule(new (require('./rules/require-spaces-inside-object-brackets'))()); | ||
this.registerRule(new (require('./rules/require-spaces-inside-array-brackets'))()); | ||
this.registerRule(new (require('./rules/require-spaces-inside-parentheses'))()); | ||
this.registerRule(new (require('./rules/disallow-spaces-inside-object-brackets'))()); | ||
@@ -117,2 +119,5 @@ this.registerRule(new (require('./rules/disallow-spaces-inside-array-brackets'))()); | ||
this.registerRule(new (require('./rules/require-dot-notation'))()); | ||
this.registerRule(new (require('./rules/require-space-after-line-comment'))()); | ||
this.registerRule(new (require('./rules/disallow-space-after-line-comment'))()); | ||
}, | ||
@@ -135,4 +140,9 @@ | ||
this.throwNonCamelCaseErrorIfNeeded(config); | ||
preset(config); | ||
if (config.preset && !preset.exists(config.preset)) { | ||
throw new Error(preset.getDoesNotExistError(config.preset)); | ||
} | ||
preset.extend(config); | ||
var configRules = Object.keys(config); | ||
@@ -221,3 +231,3 @@ var activeRules = this._activeRules; | ||
// Do not process the rule if it's equals to null (#203) | ||
if (this._config[rule.getOptionName()] !== null ) { | ||
if (this._config[rule.getOptionName()] !== null) { | ||
rule.check(file, errors); | ||
@@ -224,0 +234,0 @@ } |
@@ -7,3 +7,3 @@ /** | ||
* @param {Boolean} [backward=false] Direction | ||
* @returns {Object} | ||
* @returns {Object|null} | ||
*/ | ||
@@ -17,5 +17,2 @@ exports.getTokenByRangeStart = function(file, range, backward) { | ||
// we should check for "(" if we go backward | ||
var parenthesis = backward ? '(' : ')'; | ||
// if token is ")" -> get next token | ||
@@ -26,6 +23,3 @@ // for example (a) + (b) | ||
// ------------------^ | ||
if (token && | ||
token.type === 'Punctuator' && | ||
token.value === parenthesis | ||
) { | ||
if (this.isTokenParenthesis(file, range, backward)) { | ||
var pos = backward ? token.range[0] - 1 : token.range[1]; | ||
@@ -36,6 +30,27 @@ tokenPos = file.getTokenPosByRangeStart(pos); | ||
return token; | ||
return token || null; | ||
}; | ||
/** | ||
* Is next/previous token a parentheses? | ||
* | ||
* @param {JsFile} file | ||
* @param {Number} range | ||
* @param {Boolean} [backward=false] Direction | ||
* @returns {Boolean} | ||
*/ | ||
exports.isTokenParenthesis = function(file, range, backward) { | ||
var tokens = file.getTokens(); | ||
// get next token | ||
var tokenPos = file.getTokenPosByRangeStart(range); | ||
var token = tokens[tokenPos]; | ||
// we should check for "(" if we go backward | ||
var parenthesis = backward ? '(' : ')'; | ||
return token && token.type === 'Punctuator' && token.value === parenthesis; | ||
}; | ||
/** | ||
* Returns true if token is punctuator | ||
@@ -52,3 +67,3 @@ * | ||
/** | ||
* Find previous operator by range start | ||
* Find next/previous operator by range start | ||
* | ||
@@ -58,9 +73,10 @@ * @param {JsFile} file | ||
* @param {String} operator | ||
* @param {Boolean} [backward=false] Direction | ||
* @returns {Object|null} | ||
*/ | ||
exports.findOperatorByRangeStart = function(file, range, operator) { | ||
exports.findOperatorByRangeStart = function(file, range, operator, backward) { | ||
var tokens = file.getTokens(); | ||
var index = file.getTokenPosByRangeStart(range); | ||
while (index) { | ||
while (tokens[ index ]) { | ||
if (tokens[ index ].value === operator) { | ||
@@ -70,7 +86,10 @@ return tokens[ index ]; | ||
index--; | ||
if (backward) { | ||
index--; | ||
} else { | ||
index++; | ||
} | ||
} | ||
return null; | ||
}; | ||
@@ -96,1 +115,11 @@ | ||
}; | ||
/** | ||
* Get column for long entities | ||
* @param {Number} column | ||
* @param {Number} length | ||
* @return {Number} | ||
*/ | ||
exports.getPointerEntities = function(column, length) { | ||
return column - 1 + Math.ceil(length / 2); | ||
}; |
@@ -18,2 +18,3 @@ // 7.5.2 Keywords | ||
'new': true, | ||
'null': true, | ||
'return': true, | ||
@@ -97,1 +98,36 @@ 'switch': true, | ||
}; | ||
/** | ||
* All possible binary operators supported by JSCS | ||
* @type {Array} | ||
*/ | ||
exports.binaryOperators = [ | ||
// assignment operators | ||
'=', '+=', '-=', '*=', '/=', '%=', '<<=', '>>=', '>>>=', | ||
'&=', '|=', '^=', | ||
'+', '-', '*', '/', '%', '<<', '>>', '>>>', '&', | ||
'|', '^', '&&', '||', '===', '==', '>=', | ||
'<=', '<', '>', '!=', '!==', | ||
',', ':' | ||
]; | ||
/** | ||
* Increment and decrement operators | ||
* @type {Array} | ||
*/ | ||
exports.incrementAndDecrementOperators = ['++', '--']; | ||
/** | ||
* All possible unary operators supported by JSCS | ||
* @type {Array} | ||
*/ | ||
exports.unaryOperators = ['-', '+', '!', '~'].concat(exports.incrementAndDecrementOperators); | ||
/** | ||
* All possible operators support by JSCS | ||
* @type {Array} | ||
*/ | ||
exports.operators = exports.binaryOperators.concat(exports.unaryOperators); |
@@ -5,3 +5,3 @@ { | ||
"name": "jscs", | ||
"version": "1.4.5", | ||
"version": "1.5.1", | ||
"main": "lib/checker", | ||
@@ -31,16 +31,16 @@ "homepage": "https://github.com/mdevils/node-jscs", | ||
"commander": "~2.2.0", | ||
"esprima": "~1.1.1", | ||
"glob": "~3.2.9", | ||
"minimatch": "~0.2.14", | ||
"esprima": "~1.2.2", | ||
"glob": "~4.0.0", | ||
"minimatch": "~0.3.0", | ||
"strip-json-comments": "~0.1.1", | ||
"vow": "~0.3.12", | ||
"vow-fs": "~0.2.3", | ||
"vow": "~0.4.3", | ||
"vow-fs": "~0.3.1", | ||
"xmlbuilder": "~2.2.1" | ||
}, | ||
"devDependencies": { | ||
"browserify": "~3.43.0", | ||
"browserify": "~4.1.5", | ||
"hooker": "~0.2.3", | ||
"jshint": "~2.5.0", | ||
"mocha": "~1.18.2", | ||
"sinon": "~1.9.1", | ||
"mocha": "~1.20.1", | ||
"sinon": "~1.10.0", | ||
"xml2js": "~0.4.2" | ||
@@ -47,0 +47,0 @@ }, |
{ | ||
"requireCurlyBraces": ["if", "else", "for", "while", "do", "try", "catch"], | ||
"requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try", "catch"], | ||
"disallowLeftStickedOperators": ["?", "+", "-", "/", "*", "=", "==", "===", "!=", "!==", ">", ">=", "<", "<="], | ||
"disallowRightStickedOperators": ["?", "+", "/", "*", ":", "=", "==", "===", "!=", "!==", ">", ">=", "<", "<="], | ||
"requireRightStickedOperators": ["!"], | ||
"requireLeftStickedOperators": [","], | ||
"disallowImplicitTypeConversion": ["string"], | ||
"disallowKeywords": ["with"], | ||
"disallowMultipleLineBreaks": true, | ||
"disallowKeywordsOnNewLine": ["else"], | ||
"requireCurlyBraces": [ | ||
"if", | ||
"else", | ||
"for", | ||
"while", | ||
"do", | ||
"try", | ||
"catch" | ||
], | ||
"requireOperatorBeforeLineBreak": true, | ||
"requireCamelCaseOrUpperCaseIdentifiers": true, | ||
"maximumLineLength": { | ||
"value": 80, | ||
"allowComments": true, | ||
"allowRegex": true | ||
}, | ||
"validateIndentation": 2, | ||
"validateQuoteMarks": "'", | ||
"disallowMultipleLineStrings": true, | ||
"disallowMixedSpacesAndTabs": true, | ||
"disallowTrailingWhitespace": true, | ||
"requireSpaceAfterKeywords": [ | ||
"if", | ||
"else", | ||
"for", | ||
"while", | ||
"do", | ||
"switch", | ||
"return", | ||
"try", | ||
"catch" | ||
], | ||
"requireSpaceBeforeBinaryOperators": [ | ||
"=", "+=", "-=", "*=", "/=", "%=", "<<=", ">>=", ">>>=", | ||
"&=", "|=", "^=", "+=", | ||
"+", "-", "*", "/", "%", "<<", ">>", ">>>", "&", | ||
"|", "^", "&&", "||", "===", "==", ">=", | ||
"<=", "<", ">", "!=", "!==" | ||
], | ||
"requireSpaceAfterBinaryOperators": true, | ||
"requireSpacesInConditionalExpression": true, | ||
"requireSpaceBeforeBlockStatements": true, | ||
"requireLineFeedAtFileEnd": true, | ||
@@ -18,6 +52,2 @@ "requireSpacesInFunctionExpression": { | ||
}, | ||
"disallowSpacesInFunctionExpression": { | ||
"beforeOpeningRoundBrace": true | ||
}, | ||
"disallowSpacesInsideArrayBrackets": true, | ||
"validateJSDoc": { | ||
@@ -27,4 +57,4 @@ "checkParamNames": true, | ||
}, | ||
"validateIndentation": 4, | ||
"validateQuoteMarks": "'" | ||
"disallowMultipleLineBreaks": true | ||
} |
{ | ||
"requireCurlyBraces": [ "if", "else", "for", "while", "do" ], | ||
"requireSpaceAfterKeywords": [ "if", "else", "for", "while", "do", "switch", "return" ], | ||
"requireCurlyBraces": [ | ||
"if", | ||
"else", | ||
"for", | ||
"while", | ||
"do", | ||
"try", | ||
"catch" | ||
], | ||
"requireOperatorBeforeLineBreak": true, | ||
"requireParenthesesAroundIIFE": true, | ||
"requireMultipleVarDecl": "onevar", | ||
"requireCommaBeforeLineBreak": true, | ||
"requireCamelCaseOrUpperCaseIdentifiers": true, | ||
"requireDotNotation": true, | ||
"maximumLineLength": { | ||
"value": 100, | ||
"tabSize": 4, | ||
"allowUrlComments": true, | ||
"allowRegex": true | ||
}, | ||
"validateQuoteMarks": { "mark": "\"", "escape": true }, | ||
"disallowMixedSpacesAndTabs": "smart", | ||
"disallowTrailingWhitespace": true, | ||
"disallowMultipleLineStrings": true, | ||
"disallowTrailingComma": true, | ||
"requireSpacesInFunctionExpression": { | ||
"beforeOpeningCurlyBrace": true | ||
}, | ||
"disallowSpacesInFunctionExpression": { | ||
"beforeOpeningRoundBrace": true | ||
}, | ||
"requireMultipleVarDecl": true, | ||
"requireSpaceAfterKeywords": [ | ||
"if", | ||
"else", | ||
"for", | ||
"while", | ||
"do", | ||
"switch", | ||
"return", | ||
"try", | ||
"catch" | ||
], | ||
"requireSpacesInsideObjectBrackets": "all", | ||
"requireSpacesInsideArrayBrackets": "all", | ||
"disallowLeftStickedOperators": [ "?" ], | ||
"disallowRightStickedOperators": [ "?", "/", "*", ":", "=", "==", "===", "!=", "!==", ">", ">=", "<", "<=" ], | ||
"requireSpaceBeforeBinaryOperators": [ "+", "-", "/", "*", "=", "==", "===", "!=", "!==", ">", ">=", "<", "<=" ], | ||
"disallowSpaceAfterPrefixUnaryOperators": [ "++", "--", "+", "-" ], | ||
"disallowSpaceBeforePostfixUnaryOperators": [ "++", "--" ], | ||
"requireRightStickedOperators": [ "!" ], | ||
"requireLeftStickedOperators": [ "," ], | ||
"requireSpacesInConditionalExpression": true, | ||
"requireSpaceAfterBinaryOperators": true, | ||
"requireLineFeedAtFileEnd": true, | ||
"requireSpaceBeforeBinaryOperators": [ | ||
"=", "+=", "-=", "*=", "/=", "%=", "<<=", ">>=", ">>>=", | ||
"&=", "|=", "^=", "+=", | ||
"+", "-", "*", "/", "%", "<<", ">>", ">>>", "&", | ||
"|", "^", "&&", "||", "===", "==", ">=", | ||
"<=", "<", ">", "!=", "!==" | ||
], | ||
"validateLineBreaks": "LF", | ||
"disallowKeywords": [ "with" ], | ||
"disallowMultipleLineBreaks": true, | ||
"disallowKeywordsOnNewLine": [ "else" ], | ||
"requireLineFeedAtFileEnd": true, | ||
"disallowSpacesInFunctionExpression": { | ||
"beforeOpeningRoundBrace": true | ||
}, | ||
"disallowSpaceAfterObjectKeys": true, | ||
"validateLineBreaks": "LF" | ||
"disallowSpaceAfterPrefixUnaryOperators": true, | ||
"disallowSpaceBeforePostfixUnaryOperators": true, | ||
"disallowSpaceBeforeBinaryOperators": [ ",", ":" ], | ||
"disallowMultipleLineBreaks": true | ||
} |
479
README.md
@@ -5,4 +5,11 @@ # node-jscs [![Build Status](https://travis-ci.org/mdevils/node-jscs.svg?branch=master)](https://travis-ci.org/mdevils/node-jscs) [![Dependency Status](https://david-dm.org/mdevils/node-jscs.svg?theme=shields.io)](https://david-dm.org/mdevils/node-jscs) [![devDependency Status](https://david-dm.org/mdevils/node-jscs/dev-status.svg?theme=shields.io)](https://david-dm.org/mdevils/node-jscs#info=devDependencies) | ||
`jscs` is a code style checker. You can configure `jscs` for your project in detail using **over 60** validation rules. [jQuery](https://github.com/mdevils/node-jscs/blob/master/lib/presets/jquery.json) preset is also available. | ||
`jscs` is a code style checker. You can configure `jscs` for your project in detail using **over 60** validation rules, including presets from popular style guides like jQuery. | ||
## Presets | ||
* [jQuery](presets/jquery.json) - https://contribute.jquery.org/style-guide/js/ | ||
* [Wikimedia](presets/wikimedia.json) - https://www.mediawiki.org/wiki/Manual:Coding_conventions/JavaScript | ||
* [Google](presets/google.json) - https://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml | ||
* [Yandex](presets/yandex.json) - https://github.com/ymaps/codestyle/blob/master/js.md | ||
## Friendly packages | ||
@@ -102,6 +109,8 @@ | ||
If you want specifically disable preset rule assign it to `null` | ||
```js | ||
"preset": "jquery", | ||
"requireCurlyBraces": null | ||
If you want specifically disable preset rule assign it to `null`, like so: | ||
```json | ||
{ | ||
"preset": "jquery", | ||
"requireCurlyBraces": null | ||
} | ||
``` | ||
@@ -123,2 +132,22 @@ | ||
### fileExtensions | ||
Changes the set of file extensions that will be processed. | ||
Type: `Array` or `String` or `"*"` | ||
Values: A single file extension or an Array of file extensions, beginning with a `.`. The matching is case _insensitive_. If `"*"` is provided, all files regardless of extension will match. | ||
#### Example | ||
```js | ||
"fileExtensions": [".js", ".jsx"] | ||
``` | ||
#### Default | ||
```js | ||
"fileExtensions": [".js"] | ||
``` | ||
## Rules | ||
@@ -370,5 +399,5 @@ | ||
Type: `Object` or `true` | ||
Type: `Object` or `Boolean` | ||
Values: `afterTest`, `beforeConsequent`, `afterConsequent`, `beforeAlternate` as child properties, or `true` to set all properties to true. Child properties must be set to `true`. | ||
Values: `"afterTest"`, `"beforeConsequent"`, `"afterConsequent"`, `"beforeAlternate"` as child properties, or `true` to set all properties to `true`. Child properties must be set to `true`. | ||
@@ -407,5 +436,5 @@ #### Example | ||
Type: `Object` or `true` | ||
Type: `Object` or `Boolean` | ||
Values: `afterTest`, `beforeConsequent`, `afterConsequent`, `beforeAlternate` as child properties, or `true` to set all properties to true. Child properties must be set to `true`. | ||
Values: `"afterTest"`, `"beforeConsequent"`, `"afterConsequent"`, `"beforeAlternate"` as child properties, or `true` to set all properties to true. Child properties must be set to `true`. | ||
@@ -447,3 +476,3 @@ #### Example | ||
Values: `beforeOpeningRoundBrace` and `beforeOpeningCurlyBrace` as child properties. Child properties must be set to `true`. | ||
Values: `"beforeOpeningRoundBrace"` and `"beforeOpeningCurlyBrace"` as child properties. Child properties must be set to `true`. | ||
@@ -512,3 +541,3 @@ #### Example | ||
Values: `beforeOpeningRoundBrace` and `beforeOpeningCurlyBrace` as child properties. Child properties must be set to `true`. | ||
Values: `"beforeOpeningRoundBrace"` and `"beforeOpeningCurlyBrace"` as child properties. Child properties must be set to `true`. | ||
@@ -575,3 +604,3 @@ #### Example | ||
Values: `beforeOpeningRoundBrace` and `beforeOpeningCurlyBrace` as child properties. Child properties must be set to `true`. | ||
Values: `"beforeOpeningRoundBrace"` and `"beforeOpeningCurlyBrace"` as child properties. Child properties must be set to `true`. | ||
@@ -638,3 +667,3 @@ #### Example | ||
Values: `beforeOpeningRoundBrace` and `beforeOpeningCurlyBrace` as child properties. Child properties must be set to `true`. | ||
Values: `"beforeOpeningRoundBrace"` and `"beforeOpeningCurlyBrace"` as child properties. Child properties must be set to `true`. | ||
@@ -644,3 +673,3 @@ #### Example | ||
```js | ||
"requireSpacesInFunctionExpression": { | ||
"requireSpacesInFunctionDeclaration": { | ||
"beforeOpeningRoundBrace": true, | ||
@@ -676,3 +705,3 @@ "beforeOpeningCurlyBrace": true | ||
```js | ||
"disallowSpacesInFunctionExpression": { | ||
"disallowSpacesInFunctionDeclaration": { | ||
"beforeOpeningRoundBrace": true, | ||
@@ -733,6 +762,6 @@ "beforeOpeningCurlyBrace": true | ||
Values: `true` or `onevar` | ||
Values: `true` or `"onevar"` | ||
if `requireMultipleVarDecl` defined as a `boolean` value, it will report only consecutive vars, if, on the other hand, | ||
value equals to `onevar` string, `requireMultipleVarDecl` will allow only one `var` per function scope. | ||
if `requireMultipleVarDecl` defined as a `true` value, it will report only consecutive vars, if, on the other hand, | ||
value equals to `"onevar"` string, `requireMultipleVarDecl` will allow only one `var` per function scope. | ||
@@ -934,5 +963,5 @@ JSHint: [`onevar`](http://jshint.com/docs/options/#onevar) | ||
Type: `Boolean` | ||
Type: `Boolean` or `String` | ||
Values: `true` | ||
Values: `"all"` or `true` for strict mode, `"nested"` ignores closing brackets in a row. | ||
@@ -942,15 +971,21 @@ #### Example | ||
```js | ||
"disallowSpacesInsideObjectBrackets": true | ||
"disallowSpacesInsideObjectBrackets": "all" | ||
``` | ||
##### Valid | ||
##### Valid for mode `"all"` | ||
```js | ||
var x = {a: 1}; | ||
var x = {a: {b: 1}}; | ||
``` | ||
##### Valid for mode `"nested"` | ||
```js | ||
var x = { a: {b: 1} }; | ||
``` | ||
##### Invalid | ||
```js | ||
var x = { a: 1 }; | ||
var x = { a: { b: 1 } }; | ||
``` | ||
@@ -962,5 +997,5 @@ | ||
Type: `Boolean` | ||
Type: `Boolean` or `String` | ||
Values: `true` | ||
Values: `"all"` or `true` for strict mode, `"nested"` ignores closing brackets in a row. | ||
@@ -970,15 +1005,21 @@ #### Example | ||
```js | ||
"disallowSpacesInsideArrayBrackets": true | ||
"disallowSpacesInsideArrayBrackets": "all" | ||
``` | ||
##### Valid | ||
##### Valid for mode `"all"` | ||
```js | ||
var x = [1]; | ||
var x = [[1]]; | ||
``` | ||
##### Valid for mode `"nested"` | ||
```js | ||
var x = [ [1] ]; | ||
``` | ||
##### Invalid | ||
```js | ||
var x = [ 1 ]; | ||
var x = [ [ 1 ] ]; | ||
``` | ||
@@ -1050,3 +1091,3 @@ | ||
Values: "all" for strict mode, "allButNested" ignores closing brackets in a row. | ||
Values: `"all"` for strict mode, `"allButNested"` ignores closing brackets in a row. | ||
@@ -1077,2 +1118,35 @@ #### Example | ||
### requireSpacesInsideParentheses | ||
Requires space after opening round bracket and before closing. | ||
Type: `String` | ||
Values: `"all"` for strict mode, `"allButNested"` ignores nested brackets in a row. | ||
#### Example | ||
```js | ||
"requireSpacesInsideParentheses": "all" | ||
``` | ||
##### Valid for mode `"all"` | ||
```js | ||
var x = Math.pow( ( 1 + 2 ), ( 3 + 4 ) ); | ||
``` | ||
##### Valid for mode `"allButNested"` | ||
```js | ||
var x = Math.pow(( 1 + 2 ), ( 3 + 4 )); | ||
``` | ||
##### Invalid | ||
```js | ||
var x = Math.pow(1 + 2, 3 + 4); | ||
``` | ||
### disallowQuotedKeysInObjects | ||
@@ -1274,5 +1348,5 @@ | ||
Values: | ||
- `"all"` for strict mode, | ||
- `"skipWithFunction"` ignores objects if one of the property values is a function expression, | ||
- `"skipWithLineBreak"` ignores objects if there are line breaks between properties | ||
- `"all"` for strict mode, | ||
- `"skipWithFunction"` ignores objects if one of the property values is a function expression, | ||
- `"skipWithLineBreak"` ignores objects if there are line breaks between properties | ||
@@ -1306,5 +1380,5 @@ #### Example | ||
Type: `Array` | ||
Type: `Array` or `Boolean` | ||
Values: Array of quoted operators | ||
Values: Array of quoted operators or `true` to require all possible binary operators to appear before line breaks | ||
@@ -1318,2 +1392,3 @@ JSHint: [`laxbreak`](http://www.jshint.com/docs/options/#laxbreak) | ||
"?", | ||
"=", | ||
"+", | ||
@@ -1323,3 +1398,2 @@ "-", | ||
"*", | ||
"=", | ||
"==", | ||
@@ -1351,133 +1425,2 @@ "===", | ||
### disallowLeftStickedOperators | ||
Disallows sticking operators to the left. | ||
Type: `Array` | ||
Values: Array of quoted operators | ||
#### Example | ||
```js | ||
"disallowLeftStickedOperators": [ | ||
"?", | ||
"+", | ||
"-", | ||
"/", | ||
"*", | ||
"=", | ||
"==", | ||
"===", | ||
"!=", | ||
"!==", | ||
">", | ||
">=", | ||
"<", | ||
"<=" | ||
] | ||
``` | ||
##### Valid | ||
```js | ||
x = y ? 1 : 2; | ||
``` | ||
##### Invalid | ||
```js | ||
x = y? 1 : 2; | ||
``` | ||
### requireRightStickedOperators | ||
Requires sticking operators to the right. | ||
Type: `Array` | ||
Values: Array of quoted operators | ||
#### Example | ||
```js | ||
"requireRightStickedOperators": ["!"] | ||
``` | ||
##### Valid | ||
```js | ||
x = !y; | ||
``` | ||
##### Invalid | ||
```js | ||
x = ! y; | ||
``` | ||
### disallowRightStickedOperators | ||
Disallows sticking operators to the right. | ||
Type: `Array` | ||
Values: Array of quoted operators | ||
#### Example | ||
```js | ||
"disallowRightStickedOperators": [ | ||
"?", | ||
"+", | ||
"/", | ||
"*", | ||
":", | ||
"=", | ||
"==", | ||
"===", | ||
"!=", | ||
"!==", | ||
">", | ||
">=", | ||
"<", | ||
"<=" | ||
] | ||
``` | ||
##### Valid | ||
```js | ||
x = y + 1; | ||
``` | ||
##### Invalid | ||
```js | ||
x = y +1; | ||
``` | ||
### requireLeftStickedOperators | ||
Requires sticking operators to the left. | ||
Type: `Array` | ||
Values: Array of quoted operators | ||
#### Example | ||
```js | ||
"requireLeftStickedOperators": [","] | ||
``` | ||
##### Valid | ||
```js | ||
x = [1, 2]; | ||
``` | ||
##### Invalid | ||
```js | ||
x = [1 , 2]; | ||
``` | ||
### disallowSpaceAfterPrefixUnaryOperators | ||
@@ -1487,5 +1430,5 @@ | ||
Type: `Array` | ||
Type: `Array` or `Boolean` | ||
Values: Array of quoted operators | ||
Values: Array of quoted operators or `true` to disallow space after prefix for all unary operators | ||
@@ -1514,5 +1457,5 @@ #### Example | ||
Type: `Array` | ||
Type: `Array` or `Boolean` | ||
Values: Array of quoted operators | ||
Values: Array of quoted operators or `true` to require space after prefix for all unary operators | ||
@@ -1541,5 +1484,5 @@ #### Example | ||
Type: `Array` | ||
Type: `Array` or `Boolean` | ||
Values: Array of quoted operators | ||
Values: Array of quoted operators or `true` to disallow space before postfix for all unary operators (i.e. increment/decrement operators) | ||
@@ -1568,5 +1511,5 @@ #### Example | ||
Type: `Array` | ||
Type: `Array` or `Boolean` | ||
Values: Array of quoted operators | ||
Values: Array of quoted operators or `true` to require space before postfix for all unary operators (i.e. increment/decrement operators) | ||
@@ -1594,5 +1537,5 @@ #### Example | ||
Type: `Array` | ||
Type: `Array` or `Boolean` | ||
Values: Array of quoted operators | ||
Values: Array of quoted operators or `true` to disallow space before all possible binary operators | ||
@@ -1609,3 +1552,2 @@ #### Example | ||
"*", | ||
"=", | ||
"==", | ||
@@ -1615,2 +1557,3 @@ "===", | ||
"!==" | ||
// etc | ||
] | ||
@@ -1635,5 +1578,5 @@ ``` | ||
Type: `Array` | ||
Type: `Array` or `Boolean` | ||
Values: Array of quoted operators | ||
Values: Array of quoted operators or `true` to require space before all possible binary operators | ||
@@ -1650,3 +1593,2 @@ #### Example | ||
"*", | ||
"=", | ||
"==", | ||
@@ -1656,2 +1598,3 @@ "===", | ||
"!==" | ||
// etc | ||
] | ||
@@ -1676,5 +1619,5 @@ ``` | ||
Type: `Array` | ||
Type: `Array` or `Boolean` | ||
Values: Array of quoted operators | ||
Values: Array of quoted operators or `true` to disallow space after all possible binary operators | ||
@@ -1691,3 +1634,2 @@ #### Example | ||
"*", | ||
"=", | ||
"==", | ||
@@ -1697,2 +1639,3 @@ "===", | ||
"!==" | ||
// etc | ||
] | ||
@@ -1717,5 +1660,5 @@ ``` | ||
Type: `Array` | ||
Type: `Array` or `Boolean` | ||
Values: Array of quoted operators | ||
Values: Array of quoted operators or `true` to require space after all possible binary operators | ||
@@ -1732,3 +1675,2 @@ #### Example | ||
"*", | ||
"=", | ||
"==", | ||
@@ -1738,2 +1680,3 @@ "===", | ||
"!==" | ||
// etc | ||
] | ||
@@ -1790,5 +1733,5 @@ ``` | ||
Type: `Boolean` | ||
Type: `Boolean` or `String` | ||
Values: `true` | ||
Values: `true` or `"ignoreProperties"` | ||
@@ -1803,3 +1746,3 @@ JSHint: [`camelcase`](http://jshint.com/docs/options/#camelcase) | ||
##### Valid | ||
##### Valid for mode `true` | ||
@@ -1814,3 +1757,3 @@ ```js | ||
##### Invalid | ||
##### Invalid for mode `true` | ||
@@ -1823,2 +1766,23 @@ ```js | ||
##### Valid for mode `ignoreProperties` | ||
```js | ||
var camelCase = 0; | ||
var CamelCase = 1; | ||
var _camelCase = 2; | ||
var camelCase_ = 3; | ||
var UPPER_CASE = 4; | ||
var obj.snake_case = 5; | ||
var camelCase = { snake_case: 6 }; | ||
``` | ||
##### Invalid for mode `ignoreProperties` | ||
```js | ||
var lower_case = 1; | ||
var Mixed_case = 2; | ||
var mixed_Case = 3; | ||
var snake_case = { snake_case: 6 }; | ||
``` | ||
### disallowKeywords | ||
@@ -1998,3 +1962,3 @@ | ||
```js | ||
"validateIndentation": "\t", | ||
"validateIndentation": "\t" | ||
``` | ||
@@ -2271,5 +2235,12 @@ | ||
Type: `Integer` | ||
Type: `Integer` or `Object` | ||
Values: A positive integer | ||
Values: | ||
- `Integer`: lines should be at most the number of characters specified | ||
- `Object`: | ||
- `value`: lines should be at most the number of characters specified | ||
- `tabSize`: considered the tab character as number of specified spaces | ||
- `allowComments`: allows comments to break the rule | ||
- `allowUrlComments`: allows comments with long urls to break the rule | ||
- `allowRegex`: allows regular expression literals to break the rule | ||
@@ -2336,3 +2307,3 @@ JSHint: [`maxlen`](http://jshint.com/docs/options/#maxlen) | ||
```js | ||
"safeContextKeyword": [ "that" ] | ||
"safeContextKeyword": ["that"] | ||
``` | ||
@@ -2383,3 +2354,31 @@ | ||
``` | ||
### requireYodaConditions | ||
Requires the variable to be the right hand operator when doing a boolean comparison | ||
Type: `Boolean` | ||
Values: `true` | ||
#### Example | ||
```js | ||
"requireYodaConditions": true | ||
``` | ||
##### Valid | ||
```js | ||
if (1 == a) { | ||
return | ||
} | ||
``` | ||
##### Invalid | ||
```js | ||
if (a == 1) { | ||
return | ||
} | ||
``` | ||
### disallowYodaConditions | ||
@@ -2465,2 +2464,90 @@ | ||
### requireSpaceAfterLineComment | ||
Requires that a line comment (`//`) be followed by a space. | ||
Type: `Boolean` | ||
Values: `true` | ||
#### Example | ||
```js | ||
"requireSpaceAfterLineComment": true | ||
``` | ||
##### Valid | ||
```js | ||
// A comment | ||
/*A comment*/ | ||
``` | ||
##### Invalid | ||
```js | ||
//A comment | ||
``` | ||
### disallowSpaceAfterLineComment | ||
Requires that a line comment (`//`) not be followed by a space. | ||
Type: `Boolean` | ||
Values: `true` | ||
#### Example | ||
```js | ||
"disallowSpaceAfterLineComment": true | ||
``` | ||
##### Valid | ||
```js | ||
//A comment | ||
/* A comment*/ | ||
``` | ||
##### Invalid | ||
```js | ||
// A comment | ||
``` | ||
## Removed Rules | ||
### ~~disallowLeftStickedOperators~~ | ||
Use the following rules instead: | ||
* requireSpaceBeforeBinaryOperators | ||
* requireSpaceBeforePostfixUnaryOperators | ||
* requireSpacesInConditionalExpression | ||
### ~~disallowRightStickedOperators~~ | ||
Use the following rules instead: | ||
* requireSpaceAfterBinaryOperators | ||
* requireSpaceAfterPrefixUnaryOperators | ||
* requireSpacesInConditionalExpression | ||
### ~~requireLeftStickedOperators~~ | ||
Use the following rules instead: | ||
* disallowSpaceBeforeBinaryOperators | ||
* disallowSpaceBeforePostfixUnaryOperators | ||
* disallowSpacesInConditionalExpressions | ||
### ~~requireRightStickedOperators~~ | ||
Use the following rules instead: | ||
* disallowSpaceAfterBinaryOperators | ||
* disallowSpaceAfterPrefixUnaryOperators | ||
* disallowSpacesInConditionalExpressions | ||
## Browser Usage | ||
@@ -2467,0 +2554,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
234658
100
5196
2523
1
+ Addedbalanced-match@1.0.2(transitive)
+ Addedbrace-expansion@1.1.11(transitive)
+ Addedconcat-map@0.0.1(transitive)
+ Addedesprima@1.2.5(transitive)
+ Addedfs.realpath@1.0.0(transitive)
+ Addedglob@4.0.67.2.3(transitive)
+ Addedgraceful-fs@3.0.12(transitive)
+ Addedinflight@1.0.6(transitive)
+ Addedminimatch@1.0.03.1.2(transitive)
+ Addednatives@1.1.6(transitive)
+ Addedonce@1.4.0(transitive)
+ Addedpath-is-absolute@1.0.1(transitive)
+ Addeduuid@2.0.3(transitive)
+ Addedvow@0.4.20(transitive)
+ Addedvow-fs@0.3.6(transitive)
+ Addedvow-queue@0.4.3(transitive)
+ Addedwrappy@1.0.2(transitive)
- Removedesprima@1.1.1(transitive)
- Removedglob@3.2.11(transitive)
- Removedminimatch@0.2.14(transitive)
- Removednode-uuid@1.4.0(transitive)
- Removedvow@0.3.13(transitive)
- Removedvow-fs@0.2.3(transitive)
- Removedvow-queue@0.0.2(transitive)
Updatedesprima@~1.2.2
Updatedglob@~4.0.0
Updatedminimatch@~0.3.0
Updatedvow@~0.4.3
Updatedvow-fs@~0.3.1