Comparing version 1.7.3 to 1.8.0
@@ -7,6 +7,3 @@ var vowFs = require('vow-fs'); | ||
var additionalRules = require('./options/additional-rules'); | ||
var excludeFiles = require('./options/exclude-files'); | ||
var fileExtensions = require('./options/file-extensions'); | ||
var esnext = require('./options/esnext'); | ||
var NodeConfiguration = require('./config/node-configuration'); | ||
@@ -30,10 +27,5 @@ /** | ||
Checker.prototype.configure = function(config) { | ||
var cwd = config.configPath ? path.dirname(config.configPath) : process.cwd(); | ||
StringChecker.prototype.configure.apply(this, arguments); | ||
fileExtensions(config, this); | ||
excludeFiles(config, this, cwd); | ||
additionalRules(config, this, cwd); | ||
esnext(config); | ||
StringChecker.prototype.configure.apply(this, arguments); | ||
this._fileExtensions = this._configuration.getFileExtensions(); | ||
}; | ||
@@ -48,14 +40,9 @@ | ||
Checker.prototype.checkFile = function(path) { | ||
var _this = this; | ||
if (!_this._isExcluded(path)) { | ||
if (!this._configuration.isFileExcluded(path)) { | ||
return vowFs.read(path, 'utf8').then(function(data) { | ||
return _this.checkString(data, path); | ||
}); | ||
return this.checkString(data, path); | ||
}, this); | ||
} | ||
var defer = Vow.defer(); | ||
defer.resolve(null); | ||
return defer.promise(); | ||
return Vow.resolve(null); | ||
}; | ||
@@ -70,4 +57,2 @@ | ||
Checker.prototype.checkDirectory = function(path) { | ||
var _this = this; | ||
return vowFs.listDir(path).then(function(filenames) { | ||
@@ -77,4 +62,3 @@ return Vow.all(filenames.map(function(filename) { | ||
// check for exclude path | ||
if (_this._isExcluded(fullname)) { | ||
if (this._configuration.isFileExcluded(fullname)) { | ||
return []; | ||
@@ -85,10 +69,10 @@ } | ||
if (stat.isDirectory()) { | ||
return _this.checkDirectory(fullname); | ||
return this.checkDirectory(fullname); | ||
} | ||
if (!_this._hasCorrectExtension(fullname)) { | ||
if (!this._hasCorrectExtension(fullname)) { | ||
return []; | ||
} | ||
return Vow.when(_this.checkFile(fullname)).then(function(errors) { | ||
return Vow.when(this.checkFile(fullname)).then(function(errors) { | ||
if (errors) { | ||
@@ -100,7 +84,7 @@ return errors; | ||
}); | ||
}); | ||
})).then(function(results) { | ||
}, this); | ||
}, this)).then(function(results) { | ||
return [].concat.apply([], results); | ||
}); | ||
}); | ||
}, this); | ||
}; | ||
@@ -165,15 +149,2 @@ | ||
/** | ||
* Returns true if specified path is in excluded list. | ||
* | ||
* @returns {Boolean} | ||
*/ | ||
Checker.prototype._isExcluded = function(testPath) { | ||
testPath = path.resolve(testPath); | ||
return !this._excludes.every(function(exclude) { | ||
return !exclude.match(testPath); | ||
}); | ||
}; | ||
/** | ||
* Returns true if the file extension matches a file extension to process. | ||
@@ -194,2 +165,12 @@ * | ||
/** | ||
* Returns new configuration instance. | ||
* | ||
* @protected | ||
* @returns {Configuration} | ||
*/ | ||
Checker.prototype._createConfiguration = function() { | ||
return new NodeConfiguration(); | ||
}; | ||
module.exports = Checker; |
@@ -10,3 +10,2 @@ /** | ||
var configFile = require('./cli-config'); | ||
var preset = require('./options/preset'); | ||
@@ -67,4 +66,4 @@ var Vow = require('vow'); | ||
if (program.preset && !preset.exists(program.preset)) { | ||
console.error(preset.getDoesNotExistError(program.preset)); | ||
if (program.preset && !checker.getConfiguration().hasPreset(program.preset)) { | ||
console.error('Preset "%s" does not exist', program.preset); | ||
defer.reject(1); | ||
@@ -87,9 +86,17 @@ | ||
if (program.preset) { | ||
config.preset = program.preset; | ||
checker.getConfiguration().override({preset: program.preset}); | ||
} | ||
if (program.maxErrors) { | ||
config.maxErrors = Number(program.maxErrors); | ||
checker.getConfiguration().override({maxErrors: Number(program.maxErrors)}); | ||
} | ||
if (program.errorFilter) { | ||
checker.getConfiguration().override({errorFilter: program.errorFilter}); | ||
} | ||
if (program.esprima) { | ||
checker.getConfiguration().override({esprima: program.esprima}); | ||
} | ||
if (program.reporter) { | ||
@@ -119,3 +126,3 @@ reporterPath = path.resolve(process.cwd(), program.reporter); | ||
checker.registerDefaultRules(); | ||
checker.getConfiguration().registerDefaultRules(); | ||
checker.configure(config); | ||
@@ -122,0 +129,0 @@ |
@@ -0,2 +1,4 @@ | ||
var assert = require('assert'); | ||
var colors = require('colors'); | ||
var TokenAssert = require('./token-assert'); | ||
@@ -15,2 +17,9 @@ /** | ||
this._verbose = verbose || false; | ||
/** | ||
* @type {TokenAssert} | ||
* @public | ||
*/ | ||
this.assert = new TokenAssert(file); | ||
this.assert.on('error', this._addError.bind(this)); | ||
}; | ||
@@ -24,3 +33,3 @@ | ||
* @param {Number|Object} line | ||
* @param {Number} [column] | ||
* @param {Number} [column] optional if line is an object | ||
*/ | ||
@@ -33,3 +42,23 @@ add: function(message, line, column) { | ||
if (!this._file.isEnabledRule(this._currentRule, line)) { | ||
// line and column numbers should be explicit | ||
assert(typeof line === 'number' && line > 0, | ||
'Unable to add an error, `line` should be a number greater than 0 but ' + line + ' given'); | ||
assert(typeof column === 'number' && column >= 0, | ||
'Unable to add an error, `column` should be a positive number but ' + column + ' given'); | ||
this._addError({ | ||
message: message, | ||
line: line, | ||
column: column | ||
}); | ||
}, | ||
/** | ||
* Adds error to error list. | ||
* | ||
* @param {Object} errorInfo | ||
* @private | ||
*/ | ||
_addError: function(errorInfo) { | ||
if (!this._file.isEnabledRule(this._currentRule, errorInfo.line)) { | ||
return; | ||
@@ -39,6 +68,7 @@ } | ||
this._errorList.push({ | ||
filename: this._file.getFilename(), | ||
rule: this._currentRule, | ||
message: this._verbose ? this._currentRule + ': ' + message : message, | ||
line: line, | ||
column: column || 0 | ||
message: this._verbose ? this._currentRule + ': ' + errorInfo.message : errorInfo.message, | ||
line: errorInfo.line, | ||
column: errorInfo.column | ||
}); | ||
@@ -93,2 +123,11 @@ }, | ||
/** | ||
* Filters out errors based on the supplied filter function | ||
* | ||
* @param {Function} filter | ||
*/ | ||
filter: function(filter) { | ||
this._errorList = this._errorList.filter(filter); | ||
}, | ||
/** | ||
* Formats error for further output. | ||
@@ -95,0 +134,0 @@ * |
var treeIterator = require('./tree-iterator'); | ||
/** | ||
* Operator list which are represented as keywords in token list. | ||
*/ | ||
var KEYWORD_OPERATORS = { | ||
'instanceof': true, | ||
'in': true | ||
}; | ||
/** | ||
* File representation for JSCS. | ||
@@ -13,3 +21,4 @@ * | ||
this._lines = source.split(/\r\n|\r|\n/); | ||
this._tokenIndex = null; | ||
this._tokenRangeStartIndex = null; | ||
this._tokenRangeEndIndex = null; | ||
var index = this._index = {}; | ||
@@ -115,4 +124,2 @@ var _this = this; | ||
rulesStr.split(',').forEach(function(rule) { | ||
var ruleLength; | ||
rule = rule.trim(); | ||
@@ -137,8 +144,11 @@ | ||
var tokens = this._tree.tokens; | ||
var tokenIndex = {}; | ||
var tokenRangeStartIndex = {}; | ||
var tokenRangeEndIndex = {}; | ||
for (var i = 0, l = tokens.length; i < l; i++) { | ||
tokenIndex[tokens[i].range[0]] = i; | ||
tokenRangeStartIndex[tokens[i].range[0]] = i; | ||
tokenRangeEndIndex[tokens[i].range[1]] = i; | ||
tokens[i]._tokenIndex = i; | ||
} | ||
this._tokenIndex = tokenIndex; | ||
this._tokenRangeStartIndex = tokenRangeStartIndex; | ||
this._tokenRangeEndIndex = tokenRangeEndIndex; | ||
}, | ||
@@ -151,3 +161,3 @@ /** | ||
getTokenPosByRangeStart: function(start) { | ||
return this._tokenIndex[start]; | ||
return this._tokenRangeStartIndex[start]; | ||
}, | ||
@@ -160,8 +170,17 @@ /** | ||
getTokenByRangeStart: function(start) { | ||
var tokenIndex = this._tokenIndex[start]; | ||
var tokenIndex = this._tokenRangeStartIndex[start]; | ||
return tokenIndex === undefined ? undefined : this._tree.tokens[tokenIndex]; | ||
}, | ||
/** | ||
* Returns first token for the node from the AST. | ||
* Returns token using range end from the index. | ||
* | ||
* @returns {Object|undefined} | ||
*/ | ||
getTokenByRangeEnd: function(end) { | ||
var tokenIndex = this._tokenRangeEndIndex[end]; | ||
return tokenIndex === undefined ? undefined : this._tree.tokens[tokenIndex]; | ||
}, | ||
/** | ||
* Returns the first token for the node from the AST. | ||
* | ||
* @param {Object} node | ||
@@ -174,2 +193,11 @@ * @returns {Object} | ||
/** | ||
* Returns the last token for the node from the AST. | ||
* | ||
* @param {Object} node | ||
* @returns {Object} | ||
*/ | ||
getLastNodeToken: function(node) { | ||
return this.getTokenByRangeEnd(node.range[1]); | ||
}, | ||
/** | ||
* Returns the first token before the given. | ||
@@ -231,2 +259,22 @@ * | ||
/** | ||
* Returns the first token before the given which matches type (and value). | ||
* | ||
* @param {Object} token | ||
* @param {String} value | ||
* @returns {Object|undefined} | ||
*/ | ||
findPrevOperatorToken: function(token, value) { | ||
return this.findPrevToken(token, value in KEYWORD_OPERATORS ? 'Keyword' : 'Punctuator', value); | ||
}, | ||
/** | ||
* Returns the first token after the given which matches type (and value). | ||
* | ||
* @param {Object} token | ||
* @param {String} value | ||
* @returns {Object|undefined} | ||
*/ | ||
findNextOperatorToken: function(token, value) { | ||
return this.findNextToken(token, value in KEYWORD_OPERATORS ? 'Keyword' : 'Punctuator', value); | ||
}, | ||
/** | ||
* Iterates through the token tree using tree iterator. | ||
@@ -248,3 +296,2 @@ * Calls passed function for every token. | ||
var result = {}; | ||
this.iterate(function(node) { | ||
@@ -255,3 +302,2 @@ if (node && node.range) { | ||
} | ||
if (number < node.range[0]) { | ||
@@ -262,3 +308,2 @@ return false; | ||
}); | ||
return result; | ||
@@ -265,0 +310,0 @@ }, |
@@ -23,12 +23,9 @@ var assert = require('assert'); | ||
check: function(file, errors) { | ||
file.iterateTokensByType('Punctuator', function(token, i, tokens) { | ||
file.iterateTokensByType('Punctuator', function(token) { | ||
if (token.value === ',') { | ||
var nextToken = tokens[i + 1]; | ||
if (nextToken && nextToken.loc.start.line !== token.loc.end.line) { | ||
errors.add( | ||
'Commas should be placed on new line', | ||
token.loc.end.line, | ||
token.loc.end.column | ||
); | ||
} | ||
errors.assert.sameLine({ | ||
token: token, | ||
nextToken: file.getNextToken(token), | ||
message: 'Commas should be placed on new line' | ||
}); | ||
} | ||
@@ -35,0 +32,0 @@ }); |
@@ -7,17 +7,37 @@ var assert = require('assert'); | ||
configure: function(disallowDanglingUnderscores) { | ||
configure: function(identifiers) { | ||
assert( | ||
typeof disallowDanglingUnderscores === 'boolean', | ||
'disallowDanglingUnderscores option requires boolean value' | ||
identifiers === true || | ||
typeof identifiers === 'object', | ||
this.getOptionName() + ' option requires the value `true` ' + | ||
'or an object with String[] `allExcept` property' | ||
); | ||
// verify first item in `allExcept` property in object (if it's an object) | ||
assert( | ||
disallowDanglingUnderscores === true, | ||
'disallowDanglingUnderscores option requires true value or should be removed' | ||
typeof identifiers !== 'object' || | ||
Array.isArray(identifiers.allExcept) && | ||
typeof identifiers.allExcept[0] === 'string', | ||
'Property `allExcept` in requireSpaceAfterLineComment should be an array of strings' | ||
); | ||
this._allowedIdentifiers = { | ||
_: true, | ||
__dirname: true, | ||
__filename: true | ||
}; | ||
var isTrue = identifiers === true; | ||
var defaultIdentifiers = [ | ||
'__proto__', | ||
'_', | ||
'__dirname', | ||
'__filename', | ||
'super_' | ||
]; | ||
if (isTrue) { | ||
identifiers = defaultIdentifiers; | ||
} else { | ||
identifiers = (identifiers.allExcept).concat(defaultIdentifiers); | ||
} | ||
this._identifierIndex = {}; | ||
for (var i = 0, l = identifiers.length; i < l; i++) { | ||
this._identifierIndex[identifiers[i]] = true; | ||
} | ||
}, | ||
@@ -30,3 +50,3 @@ | ||
check: function(file, errors) { | ||
var allowedIdentifiers = this._allowedIdentifiers; | ||
var allowedIdentifiers = this._identifierIndex; | ||
@@ -33,0 +53,0 @@ file.iterateTokensByType('Identifier', function(token) { |
@@ -54,3 +54,3 @@ var assert = require('assert'); | ||
if (line.match(test)) { | ||
errors.add('Mixed spaces and tabs found', i + 1); | ||
errors.add('Mixed spaces and tabs found', i + 1, 0); | ||
} | ||
@@ -57,0 +57,0 @@ }); |
@@ -9,7 +9,10 @@ var assert = require('assert'); | ||
assert( | ||
disallowMultipleVarDecl === true || disallowMultipleVarDecl === 'strict', | ||
'disallowMultipleVarDecl option requires true or "strict" value' | ||
disallowMultipleVarDecl === true || | ||
disallowMultipleVarDecl === 'strict' || | ||
disallowMultipleVarDecl === 'exceptUndefined', | ||
'disallowMultipleVarDecl option requires true, "strict", or "exceptUndefined" value' | ||
); | ||
this.strictMode = disallowMultipleVarDecl === 'strict'; | ||
this.exceptUndefined = disallowMultipleVarDecl === 'exceptUndefined'; | ||
}, | ||
@@ -23,9 +26,23 @@ | ||
var inStrictMode = this.strictMode; | ||
var exceptUndefined = this.exceptUndefined; | ||
file.iterateNodesByType('VariableDeclaration', function(node) { | ||
// allow multiple var declarations in for statement unless we're in strict mode | ||
// for (var i = 0, j = myArray.length; i < j; i++) {} | ||
if (node.declarations.length > 1 && (inStrictMode || node.parentNode.type !== 'ForStatement')) { | ||
errors.add('Multiple var declaration', node.loc.start); | ||
var hasDefinedVariables = node.declarations.some(function(declaration) { | ||
return !!declaration.init; | ||
}); | ||
var isForStatement = node.parentNode.type === 'ForStatement'; | ||
// allow single var declarations | ||
if (node.declarations.length === 1 || | ||
// allow multiple var declarations in for statement unless we're in strict mode | ||
// for (var i = 0, j = myArray.length; i < j; i++) {} | ||
!inStrictMode && isForStatement || | ||
// allow multiple var declarations with all undefined variables in exceptUndefined mode | ||
// var a, b, c | ||
exceptUndefined && !hasDefinedVariables) { | ||
return; | ||
} | ||
errors.add('Multiple var declaration', node.loc.start); | ||
}); | ||
@@ -32,0 +49,0 @@ } |
var assert = require('assert'); | ||
var tokenHelper = require('../token-helper'); | ||
var allOperators = require('../utils').binaryOperators; | ||
@@ -33,25 +32,12 @@ | ||
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) | ||
); | ||
} | ||
} | ||
// Comma | ||
if (operators[',']) { | ||
file.iterateTokensByType('Punctuator', function(token, i, tokens) { | ||
var operator = token.value; | ||
if (operator !== ',') { | ||
return; | ||
file.iterateTokensByType('Punctuator', function(token) { | ||
if (token.value === ',') { | ||
errors.assert.noWhitespaceBetween({ | ||
token: token, | ||
nextToken: file.getNextToken(token), | ||
message: 'Operator , should stick to following expression' | ||
}); | ||
} | ||
errorIfApplicable(token, i, tokens, operator); | ||
}); | ||
@@ -64,32 +50,30 @@ } | ||
function(node) { | ||
var isDec = node.type === 'VariableDeclarator'; | ||
var operator = isDec ? '=' : node.operator; | ||
var operator; | ||
var expression; | ||
if (!operators[operator] || node.init === null) { | ||
if (node.type === 'VariableDeclarator') { | ||
expression = node.init; | ||
operator = '='; | ||
} else { | ||
operator = node.operator; | ||
expression = node.right; | ||
} | ||
if (expression === null) { | ||
return; | ||
} | ||
var range = (isDec ? node.init : node.right).range[0]; | ||
var indent = tokenHelper.isTokenParenthesis(file, range - 1, true) ? | ||
operator.length + 1 : | ||
operator.length; | ||
var part = tokenHelper.getTokenByRangeStartIfPunctuator( | ||
file, | ||
range - indent, | ||
operator, | ||
true | ||
var operatorToken = file.findPrevOperatorToken( | ||
file.getFirstNodeToken(expression), | ||
operator | ||
); | ||
if (!part) { | ||
var loc = tokenHelper.findOperatorByRangeStart( | ||
file, range, operator, true | ||
).loc.start; | ||
var nextToken = file.getNextToken(operatorToken); | ||
errors.add( | ||
'Operator ' + operator + ' should stick to following expression', | ||
loc.line, | ||
tokenHelper.getPointerEntities(loc.column, operator.length) | ||
); | ||
if (operators[operator]) { | ||
errors.assert.noWhitespaceBetween({ | ||
token: operatorToken, | ||
nextToken: nextToken, | ||
message: 'Operator ' + node.operator + ' should stick to following expression' | ||
}); | ||
} | ||
@@ -96,0 +80,0 @@ } |
var assert = require('assert'); | ||
var tokenHelper = require('../token-helper'); | ||
var allOperators = require('../utils').binaryOperators; | ||
@@ -34,30 +33,12 @@ | ||
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) | ||
); | ||
} | ||
} | ||
// Comma | ||
if (operators[',']) { | ||
file.iterateTokensByType('Punctuator', function(token, i, tokens) { | ||
var operator = token.value; | ||
if (operator !== ',') { | ||
return; | ||
file.iterateTokensByType('Punctuator', function(token) { | ||
if (token.value === ',') { | ||
errors.assert.noWhitespaceBetween({ | ||
token: file.getPrevToken(token), | ||
nextToken: token, | ||
message: 'Operator , should stick to previous expression' | ||
}); | ||
} | ||
var prevToken = tokens[i - 1]; | ||
// Do not report error if comma not on the same line with the first operand #467 | ||
if (token.loc.start.line === prevToken.loc.start.line) { | ||
errorIfApplicable(token, i, tokens, operator); | ||
} | ||
}); | ||
@@ -70,20 +51,30 @@ } | ||
function(node) { | ||
var isDec = node.type === 'VariableDeclarator'; | ||
var operator = isDec ? '=' : node.operator; | ||
var operator; | ||
var expression; | ||
// !node.init is it's an empty assignment | ||
if (!operators[operator] || node.init === null) { | ||
if (node.type === 'VariableDeclarator') { | ||
expression = node.init; | ||
operator = '='; | ||
} else { | ||
operator = node.operator; | ||
expression = node.right; | ||
} | ||
if (expression === null) { | ||
return; | ||
} | ||
var range = (isDec ? node.id : node.left).range; | ||
var part = tokenHelper.getTokenByRangeStartIfPunctuator(file, range[1], operator); | ||
var operatorToken = file.findPrevOperatorToken( | ||
file.getFirstNodeToken(expression), | ||
operator | ||
); | ||
if (!part) { | ||
errors.add( | ||
'Operator ' + node.operator + ' should stick to preceding expression', | ||
tokenHelper.findOperatorByRangeStart( | ||
file, range[0], operator | ||
).loc.start | ||
); | ||
var prevToken = file.getPrevToken(operatorToken); | ||
if (operators[operator]) { | ||
errors.assert.noWhitespaceBetween({ | ||
token: prevToken, | ||
nextToken: operatorToken, | ||
message: 'Operator ' + node.operator + ' should stick to previous expression' | ||
}); | ||
} | ||
@@ -90,0 +81,0 @@ } |
@@ -70,3 +70,3 @@ var assert = require('assert'); | ||
'Illegal space before opening round brace', | ||
functionToken.loc.start | ||
functionToken.loc.end | ||
); | ||
@@ -73,0 +73,0 @@ } |
@@ -22,13 +22,10 @@ var assert = require('assert'); | ||
check: function(file, errors) { | ||
file.iterateTokensByType('Punctuator', function(token, i, tokens) { | ||
if (token.value === ',') { | ||
var nextToken = tokens[i + 1]; | ||
if (nextToken && nextToken.type === 'Punctuator' && | ||
(nextToken.value === '}' || nextToken.value === ']')) { | ||
errors.add( | ||
'Extra comma following the final element of an array or object literal', | ||
token.loc.start | ||
); | ||
} | ||
} | ||
file.iterateNodesByType(['ObjectExpression', 'ArrayExpression'], function(node) { | ||
var closingToken = file.getLastNodeToken(node); | ||
errors.assert.noTokenBefore({ | ||
token: closingToken, | ||
expectedTokenBefore: {type: 'Punctuator', value: ','}, | ||
message: 'Extra comma following the final element of an array or object literal' | ||
}); | ||
}); | ||
@@ -35,0 +32,0 @@ } |
var assert = require('assert'); | ||
var upperCasePattern = /[A-Z]/; | ||
var alphabeticalPattern = /[a-z|A-Z]/; | ||
module.exports = function() {}; | ||
@@ -18,4 +21,3 @@ | ||
check: function(file, errors) { | ||
var upperCasePattern = /[A-Z]/; | ||
var alphabeticalPattern = /[a-z|A-Z]/; | ||
var inTextBlock = null; | ||
@@ -25,11 +27,22 @@ file.getComments().forEach(function(comment) { | ||
var firstChar = stripped[0]; | ||
var isLetter = firstChar && alphabeticalPattern.test(firstChar); | ||
if (alphabeticalPattern.test(firstChar) && !upperCasePattern.test(firstChar)) { | ||
if (!isLetter) { | ||
inTextBlock = false; | ||
return; | ||
} | ||
var isUpperCase = upperCasePattern.test(firstChar); | ||
var isValid = isUpperCase || (inTextBlock && !isUpperCase); | ||
if (!isValid) { | ||
errors.add( | ||
'Comments must start with an uppercase letter', | ||
'Comments must start with an uppercase letter, unless it is part of a textblock', | ||
comment.loc.start | ||
); | ||
} | ||
inTextBlock = !inTextBlock ? isLetter && isUpperCase : isLetter; | ||
}); | ||
} | ||
}; |
@@ -23,12 +23,9 @@ var assert = require('assert'); | ||
check: function(file, errors) { | ||
file.iterateTokensByType('Punctuator', function(token, i, tokens) { | ||
file.iterateTokensByType('Punctuator', function(token) { | ||
if (token.value === ',') { | ||
var prevToken = tokens[i - 1]; | ||
if (prevToken && prevToken.loc.end.line !== token.loc.start.line) { | ||
errors.add( | ||
'Commas should not be placed on new line', | ||
token.loc.start.line, | ||
token.loc.start.column | ||
); | ||
} | ||
errors.assert.sameLine({ | ||
token: file.getPrevToken(token), | ||
nextToken: token, | ||
message: 'Commas should not be placed on new line' | ||
}); | ||
} | ||
@@ -35,0 +32,0 @@ }); |
var assert = require('assert'); | ||
var tokenHelper = require('../token-helper'); | ||
var allOperators = require('../utils').binaryOperators; | ||
@@ -34,25 +33,12 @@ | ||
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) | ||
); | ||
} | ||
} | ||
// Comma | ||
if (operators[',']) { | ||
file.iterateTokensByType('Punctuator', function(token, i, tokens) { | ||
var operator = token.value; | ||
if (operator !== ',') { | ||
return; | ||
file.iterateTokensByType('Punctuator', function(token) { | ||
if (token.value === ',') { | ||
errors.assert.whitespaceBetween({ | ||
token: token, | ||
nextToken: file.getNextToken(token), | ||
message: 'Operator , should not stick to following expression' | ||
}); | ||
} | ||
errorIfApplicable(token, i, tokens, operator); | ||
}); | ||
@@ -65,30 +51,30 @@ } | ||
function(node) { | ||
var isDec = node.type === 'VariableDeclarator'; | ||
var operator = isDec ? '=' : node.operator; | ||
var operator; | ||
var expression; | ||
if (!operators[operator] || node.init === null) { | ||
if (node.type === 'VariableDeclarator') { | ||
expression = node.init; | ||
operator = '='; | ||
} else { | ||
operator = node.operator; | ||
expression = node.right; | ||
} | ||
if (expression === null) { | ||
return; | ||
} | ||
var range = (isDec ? node.init : node.right).range[0]; | ||
var indent = tokenHelper.isTokenParenthesis(file, range - 1, true) ? | ||
operator.length + 1 : | ||
operator.length; | ||
var part = tokenHelper.getTokenByRangeStartIfPunctuator( | ||
file, | ||
range - indent, | ||
operator, | ||
true | ||
var operatorToken = file.findPrevOperatorToken( | ||
file.getFirstNodeToken(expression), | ||
operator | ||
); | ||
if (part) { | ||
var loc = part.loc.start; | ||
var nextToken = file.getNextToken(operatorToken); | ||
errors.add( | ||
'Operator ' + operator + ' should not stick to following expression', | ||
loc.line, | ||
tokenHelper.getPointerEntities(loc.column, operator.length) | ||
); | ||
if (operators[operator]) { | ||
errors.assert.whitespaceBetween({ | ||
token: operatorToken, | ||
nextToken: nextToken, | ||
message: 'Operator ' + node.operator + ' should not stick to following expression' | ||
}); | ||
} | ||
@@ -95,0 +81,0 @@ } |
@@ -57,3 +57,3 @@ var assert = require('assert'); | ||
util.format.apply(null, | ||
diff === 1 ? | ||
diff === 0 ? | ||
[texts[0], token.value] : | ||
@@ -60,0 +60,0 @@ [texts[1], diff, token.value] |
@@ -10,7 +10,21 @@ var assert = require('assert'); | ||
requireSpaceAfterLineComment === true || | ||
requireSpaceAfterLineComment === 'allowSlash', | ||
'requireSpaceAfterLineComment option requires the value true or `allowSlash`' | ||
requireSpaceAfterLineComment === 'allowSlash' || | ||
typeof requireSpaceAfterLineComment === 'object', | ||
'requireSpaceAfterLineComment option requires the value `true` ' + | ||
'or an object with String[] `allExcept` property' | ||
); | ||
this._allowSlash = requireSpaceAfterLineComment === 'allowSlash'; | ||
// verify first item in `allExcept` property in object (if it's an object) | ||
assert( | ||
typeof requireSpaceAfterLineComment !== 'object' || | ||
Array.isArray(requireSpaceAfterLineComment.allExcept) && | ||
typeof requireSpaceAfterLineComment.allExcept[0] === 'string', | ||
'Property `allExcept` in requireSpaceAfterLineComment should be an array of strings' | ||
); | ||
// don't check triple slashed comments, microsoft js doc convention. see #593 | ||
// exceptions. see #592 | ||
// need to drop allowSlash support in 2.0. Fixes #697 | ||
this._allExcept = requireSpaceAfterLineComment === 'allowSlash' ? ['/'] : | ||
requireSpaceAfterLineComment.allExcept || []; | ||
}, | ||
@@ -24,3 +38,3 @@ | ||
var comments = file.getComments(); | ||
var allowSlash = this._allowSlash; | ||
var allExcept = this._allExcept; | ||
@@ -31,6 +45,8 @@ comments.forEach(function(comment) { | ||
// don't check triple slashed comments, microsoft js doc convention. see #593 | ||
if (allowSlash && value[0] === '/') { | ||
value = value.substr(1); | ||
} | ||
// cutout exceptions | ||
allExcept.forEach(function(el) { | ||
if (value.indexOf(el) === 0) { | ||
value = value.substr(el.length); | ||
} | ||
}); | ||
@@ -37,0 +53,0 @@ if (value.length === 0) { |
var assert = require('assert'); | ||
var tokenHelper = require('../token-helper'); | ||
var allOperators = require('../../lib/utils').binaryOperators.filter(function(operator) { | ||
@@ -36,25 +35,12 @@ return 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) | ||
); | ||
} | ||
} | ||
// Comma | ||
if (operators[',']) { | ||
file.iterateTokensByType('Punctuator', function(token, i, tokens) { | ||
var operator = token.value; | ||
if (operator !== ',') { | ||
return; | ||
file.iterateTokensByType('Punctuator', function(token) { | ||
if (token.value === ',') { | ||
errors.assert.whitespaceBetween({ | ||
token: file.getPrevToken(token), | ||
nextToken: token, | ||
message: 'Operator , should not stick to preceding expression' | ||
}); | ||
} | ||
errorIfApplicable(token, i, tokens, operator); | ||
}); | ||
@@ -67,19 +53,30 @@ } | ||
function(node) { | ||
var isDec = node.type === 'VariableDeclarator'; | ||
var operator = isDec ? '=' : node.operator; | ||
var operator; | ||
var expression; | ||
if (!operators[operator]) { | ||
if (node.type === 'VariableDeclarator') { | ||
expression = node.init; | ||
operator = '='; | ||
} else { | ||
operator = node.operator; | ||
expression = node.right; | ||
} | ||
if (expression === null) { | ||
return; | ||
} | ||
var range = (isDec ? node.id : node.left).range[1]; | ||
var part = tokenHelper.getTokenByRangeStartIfPunctuator(file, range, operator); | ||
var operatorToken = file.findPrevOperatorToken( | ||
file.getFirstNodeToken(expression), | ||
operator | ||
); | ||
if (part) { | ||
var loc = part.loc.start; | ||
errors.add( | ||
'Operator ' + operator + ' should not stick to following expression', | ||
loc.line, | ||
tokenHelper.getPointerEntities(loc.column, operator.length) | ||
); | ||
var prevToken = file.getPrevToken(operatorToken); | ||
if (operators[operator]) { | ||
errors.assert.whitespaceBetween({ | ||
token: prevToken, | ||
nextToken: operatorToken, | ||
message: 'Operator ' + node.operator + ' should not stick to preceding expression' | ||
}); | ||
} | ||
@@ -86,0 +83,0 @@ } |
var assert = require('assert'); | ||
var tokenHelper = require('../token-helper'); | ||
@@ -8,9 +7,18 @@ module.exports = function() {}; | ||
configure: function(requireTrailingComma) { | ||
if (typeof requireTrailingComma === 'object') { | ||
assert( | ||
requireTrailingComma.ignoreSingleValue === true, | ||
'requireTrailingComma option ignoreSingleValue requires true value or should be removed' | ||
); | ||
this._ignoreSingleValue = true; | ||
if ('ignoreSingleValue' in requireTrailingComma) { | ||
assert( | ||
requireTrailingComma.ignoreSingleValue === true, | ||
'requireTrailingComma option ignoreSingleValue requires true value or should be removed' | ||
); | ||
this._ignoreSingleValue = true; | ||
} | ||
if ('ignoreSingleLine' in requireTrailingComma) { | ||
assert( | ||
requireTrailingComma.ignoreSingleLine === true, | ||
'requireTrailingComma option ignoreSingleLine requires true value or should be removed' | ||
); | ||
this._ignoreSingleLine = true; | ||
} | ||
} else { | ||
@@ -33,19 +41,23 @@ assert( | ||
var isObject = node.type === 'ObjectExpression'; | ||
var message = 'Missing comma before closing ' + (isObject ? ' curly brace' : ' bracket'); | ||
var entities = isObject ? node.properties : node.elements; | ||
var last; | ||
var hasTrailingComma; | ||
if (entities.length) { | ||
if (_this._ignoreSingleValue && entities.length === 1) { | ||
return; | ||
} | ||
if (entities.length === 0) { | ||
return; | ||
} | ||
last = entities[entities.length - 1]; | ||
hasTrailingComma = tokenHelper.getTokenByRangeStartIfPunctuator(file, last.range[1], ','); | ||
if (_this._ignoreSingleValue && entities.length === 1) { | ||
return; | ||
} | ||
if (!hasTrailingComma) { | ||
errors.add(message, node.loc.end); | ||
} | ||
if (_this._ignoreSingleLine && node.loc.start.line === node.loc.end.line) { | ||
return; | ||
} | ||
var closingToken = file.getLastNodeToken(node); | ||
errors.assert.tokenBefore({ | ||
token: closingToken, | ||
expectedTokenBefore: {type: 'Punctuator', value: ','}, | ||
message: 'Missing comma before closing ' + (isObject ? ' curly brace' : ' bracket') | ||
}); | ||
}); | ||
@@ -52,0 +64,0 @@ } |
@@ -22,46 +22,45 @@ var assert = require('assert'); | ||
var tokens = file.getTokens(); | ||
var validateTokens = this._separator.split(''); | ||
var separatorBefore = validateTokens[0]; | ||
var separatorAfter = validateTokens[validateTokens.length - 1]; | ||
var separators = this._separator.split(','); | ||
var whitespaceBeforeComma = Boolean(separators.shift()); | ||
var whitespaceAfterComma = Boolean(separators.pop()); | ||
file.iterateNodesByType(['FunctionDeclaration', 'FunctionExpression'], function(node) { | ||
node.params.forEach(function(param) { | ||
node.params.forEach(function(paramNode) { | ||
var paramTokenPos = file.getTokenPosByRangeStart(param.range[0]); | ||
var punctuatorToken = tokens[paramTokenPos + 1]; | ||
var prevParamToken = file.getFirstNodeToken(paramNode); | ||
var punctuatorToken = file.getNextToken(prevParamToken); | ||
if (punctuatorToken.value === ',') { | ||
var nextParamToken = tokens[paramTokenPos + 2]; | ||
if (separatorBefore === ',' && | ||
punctuatorToken.range[0] !== param.range[1] && | ||
param.loc.start.line === nextParamToken.loc.start.line) { | ||
errors.add( | ||
'Unexpected space after function parameter \'' + param.name + '\'', | ||
punctuatorToken.loc.start | ||
); | ||
} else if (separatorBefore === ' ' && punctuatorToken.range[0] === param.range[1]) { | ||
errors.add( | ||
'Missing space after function parameter \'' + param.name + '\'', | ||
punctuatorToken.loc.start | ||
); | ||
if (whitespaceBeforeComma) { | ||
errors.assert.whitespaceBetween({ | ||
token: prevParamToken, | ||
nextToken: punctuatorToken, | ||
spaces: 1, | ||
message: 'Missing space after function parameter \'' + prevParamToken.value + '\'' | ||
}); | ||
} else { | ||
errors.assert.noWhitespaceBetween({ | ||
token: prevParamToken, | ||
nextToken: punctuatorToken, | ||
message: 'Unexpected space after function parameter \'' + prevParamToken.value + '\'' | ||
}); | ||
} | ||
if (separatorAfter === ',' && | ||
punctuatorToken.range[1] < nextParamToken.range[0] && | ||
param.loc.start.line === nextParamToken.loc.start.line) { | ||
var nextParamToken = file.getNextToken(punctuatorToken); | ||
errors.add( | ||
'Unexpected space before function parameter \'' + nextParamToken.value + '\'', | ||
nextParamToken.loc.start | ||
); | ||
} else if (separatorAfter === ' ' && punctuatorToken.range[1] === nextParamToken.range[0]) { | ||
errors.add( | ||
'Missing space before function parameter \'' + nextParamToken.value + '\'', | ||
nextParamToken.loc.start | ||
); | ||
if (whitespaceAfterComma) { | ||
errors.assert.whitespaceBetween({ | ||
token: punctuatorToken, | ||
nextToken: nextParamToken, | ||
spaces: 1, | ||
message: 'Missing space before function parameter \'' + nextParamToken.value + '\'' | ||
}); | ||
} else { | ||
errors.assert.noWhitespaceBetween({ | ||
token: punctuatorToken, | ||
nextToken: nextParamToken, | ||
message: 'Unexpected space before function parameter \'' + nextParamToken.value + '\'' | ||
}); | ||
} | ||
@@ -68,0 +67,0 @@ } |
@@ -5,4 +5,3 @@ var defaultEsprima = require('esprima'); | ||
var JsFile = require('./js-file'); | ||
var preset = require('./options/preset'); | ||
var maxErrors = require('./options/max-errors'); | ||
var Configuration = require('./config/configuration'); | ||
@@ -19,8 +18,10 @@ /** | ||
var StringChecker = function(options) { | ||
this._rules = []; | ||
this._activeRules = []; | ||
this._config = {}; | ||
this._configuredRules = []; | ||
this._errorsFound = 0; | ||
this._maxErrorsExceeded = false; | ||
this._configuration = this._createConfiguration(); | ||
this._configuration.registerDefaultPresets(); | ||
if (typeof options === 'boolean') { | ||
@@ -42,129 +43,19 @@ this._verbose = options; | ||
registerRule: function(rule) { | ||
this._rules.push(rule); | ||
this._configuration.registerRule(rule); | ||
}, | ||
/** | ||
* Registers built-in Code Style cheking rules. | ||
* Registers built-in Code Style checking rules. | ||
*/ | ||
registerDefaultRules: function() { | ||
this.registerRule(new (require('./rules/require-curly-braces'))()); | ||
this.registerRule(new (require('./rules/require-multiple-var-decl'))()); | ||
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/disallow-space-after-keywords'))()); | ||
this.registerRule(new (require('./rules/require-parentheses-around-iife'))()); | ||
/* deprecated rules */ | ||
this.registerRule(new (require('./rules/require-left-sticked-operators'))()); | ||
this.registerRule(new (require('./rules/disallow-left-sticked-operators'))()); | ||
this.registerRule(new (require('./rules/require-right-sticked-operators'))()); | ||
this.registerRule(new (require('./rules/disallow-right-sticked-operators'))()); | ||
this.registerRule(new (require('./rules/validate-jsdoc'))()); | ||
/* deprecated rules (end) */ | ||
this.registerRule(new (require('./rules/require-operator-before-line-break'))()); | ||
this.registerRule(new (require('./rules/disallow-implicit-type-conversion'))()); | ||
this.registerRule(new (require('./rules/require-camelcase-or-uppercase-identifiers'))()); | ||
this.registerRule(new (require('./rules/disallow-keywords'))()); | ||
this.registerRule(new (require('./rules/disallow-multiple-line-breaks'))()); | ||
this.registerRule(new (require('./rules/disallow-multiple-line-strings'))()); | ||
this.registerRule(new (require('./rules/validate-line-breaks'))()); | ||
this.registerRule(new (require('./rules/validate-quote-marks'))()); | ||
this.registerRule(new (require('./rules/validate-indentation'))()); | ||
this.registerRule(new (require('./rules/disallow-trailing-whitespace'))()); | ||
this.registerRule(new (require('./rules/disallow-mixed-spaces-and-tabs'))()); | ||
this.registerRule(new (require('./rules/require-keywords-on-new-line'))()); | ||
this.registerRule(new (require('./rules/disallow-keywords-on-new-line'))()); | ||
this.registerRule(new (require('./rules/require-line-feed-at-file-end'))()); | ||
this.registerRule(new (require('./rules/maximum-line-length'))()); | ||
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'))()); | ||
this.registerRule(new (require('./rules/disallow-spaces-inside-array-brackets'))()); | ||
this.registerRule(new (require('./rules/disallow-spaces-inside-parentheses'))()); | ||
this.registerRule(new (require('./rules/require-blocks-on-newline'))()); | ||
this.registerRule(new (require('./rules/require-space-after-object-keys'))()); | ||
this.registerRule(new (require('./rules/require-space-before-object-values'))()); | ||
this.registerRule(new (require('./rules/disallow-space-after-object-keys'))()); | ||
this.registerRule(new (require('./rules/disallow-space-before-object-values'))()); | ||
this.registerRule(new (require('./rules/disallow-quoted-keys-in-objects'))()); | ||
this.registerRule(new (require('./rules/disallow-dangling-underscores'))()); | ||
this.registerRule(new (require('./rules/require-aligned-object-values'))()); | ||
this.registerRule(new (require('./rules/disallow-padding-newlines-in-blocks'))()); | ||
this.registerRule(new (require('./rules/require-padding-newlines-in-blocks'))()); | ||
this.registerRule(new (require('./rules/require-padding-newlines-in-objects'))()); | ||
this.registerRule(new (require('./rules/disallow-padding-newlines-in-objects'))()); | ||
this.registerRule(new (require('./rules/require-newline-before-block-statements'))()); | ||
this.registerRule(new (require('./rules/disallow-newline-before-block-statements'))()); | ||
this.registerRule(new (require('./rules/disallow-trailing-comma'))()); | ||
this.registerRule(new (require('./rules/require-trailing-comma'))()); | ||
this.registerRule(new (require('./rules/disallow-comma-before-line-break'))()); | ||
this.registerRule(new (require('./rules/require-comma-before-line-break'))()); | ||
this.registerRule(new (require('./rules/disallow-space-before-block-statements.js'))()); | ||
this.registerRule(new (require('./rules/require-space-before-block-statements.js'))()); | ||
this.registerRule(new (require('./rules/disallow-space-before-postfix-unary-operators.js'))()); | ||
this.registerRule(new (require('./rules/require-space-before-postfix-unary-operators.js'))()); | ||
this.registerRule(new (require('./rules/disallow-space-after-prefix-unary-operators.js'))()); | ||
this.registerRule(new (require('./rules/require-space-after-prefix-unary-operators.js'))()); | ||
this.registerRule(new (require('./rules/disallow-space-before-binary-operators'))()); | ||
this.registerRule(new (require('./rules/require-space-before-binary-operators'))()); | ||
this.registerRule(new (require('./rules/disallow-space-after-binary-operators'))()); | ||
this.registerRule(new (require('./rules/require-space-after-binary-operators'))()); | ||
this.registerRule(new (require('./rules/require-spaces-in-conditional-expression'))()); | ||
this.registerRule(new (require('./rules/disallow-spaces-in-conditional-expression'))()); | ||
this.registerRule(new (require('./rules/require-spaces-in-function'))()); | ||
this.registerRule(new (require('./rules/disallow-spaces-in-function'))()); | ||
this.registerRule(new (require('./rules/require-spaces-in-function-expression'))()); | ||
this.registerRule(new (require('./rules/disallow-spaces-in-function-expression'))()); | ||
this.registerRule(new (require('./rules/require-spaces-in-anonymous-function-expression'))()); | ||
this.registerRule(new (require('./rules/disallow-spaces-in-anonymous-function-expression'))()); | ||
this.registerRule(new (require('./rules/require-spaces-in-named-function-expression'))()); | ||
this.registerRule(new (require('./rules/disallow-spaces-in-named-function-expression'))()); | ||
this.registerRule(new (require('./rules/require-spaces-in-function-declaration'))()); | ||
this.registerRule(new (require('./rules/disallow-spaces-in-function-declaration'))()); | ||
this.registerRule(new (require('./rules/require-spaces-in-call-expression'))()); | ||
this.registerRule(new (require('./rules/disallow-spaces-in-call-expression'))()); | ||
this.registerRule(new (require('./rules/validate-parameter-separator'))()); | ||
this.registerRule(new (require('./rules/require-capitalized-constructors'))()); | ||
this.registerRule(new (require('./rules/safe-context-keyword'))()); | ||
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'))()); | ||
this.registerRule(new (require('./rules/require-anonymous-functions'))()); | ||
this.registerRule(new (require('./rules/disallow-anonymous-functions'))()); | ||
this.registerRule(new (require('./rules/require-function-declarations'))()); | ||
this.registerRule(new (require('./rules/disallow-function-declarations'))()); | ||
this.registerRule(new (require('./rules/require-capitalized-comments'))()); | ||
this.registerRule(new (require('./rules/disallow-capitalized-comments'))()); | ||
this._configuration.registerDefaultRules(); | ||
}, | ||
/** | ||
* Get processed config | ||
* Get processed config. | ||
* | ||
* @return {Object} | ||
*/ | ||
getProcessedConfig: function() { | ||
return this._config; | ||
return this._configuration.getProcessedConfig(); | ||
}, | ||
@@ -178,80 +69,15 @@ | ||
configure: function(config) { | ||
maxErrors(config, this); | ||
this._configuration.load(config); | ||
this.throwNonCamelCaseErrorIfNeeded(config); | ||
if (config.preset && !preset.exists(config.preset)) { | ||
throw new Error(preset.getDoesNotExistError(config.preset)); | ||
} | ||
preset.extend(config); | ||
if (config.esnext) { | ||
if (this._configuration.hasCustomEsprima()) { | ||
this._esprima = this._configuration.getCustomEsprima(); | ||
} else if (this._configuration.isESNextEnabled()) { | ||
this._esprima = harmonyEsprima; | ||
} | ||
var configRules = Object.keys(config); | ||
var activeRules = this._activeRules; | ||
this._config = config; | ||
this._rules.forEach(function(rule) { | ||
var ruleOptionName = rule.getOptionName(); | ||
if (config.hasOwnProperty(ruleOptionName)) { | ||
// Do not configure the rule if it's equals to null (#203) | ||
if (config[ruleOptionName] !== null) { | ||
rule.configure(config[ruleOptionName]); | ||
} | ||
activeRules.push(rule); | ||
configRules.splice(configRules.indexOf(ruleOptionName), 1); | ||
} | ||
}); | ||
if (configRules.length > 0) { | ||
throw new Error('Unsupported rules: ' + configRules.join(', ')); | ||
} | ||
this._configuredRules = this._configuration.getConfiguredRules(); | ||
this._maxErrors = this._configuration.getMaxErrors(); | ||
}, | ||
/** | ||
* Throws error for non camel-case options. | ||
* | ||
* @param {Object} config | ||
*/ | ||
throwNonCamelCaseErrorIfNeeded: function(config) { | ||
function symbolToUpperCase(s, symbol) { | ||
return symbol.toUpperCase(); | ||
} | ||
function fixConfig(originConfig) { | ||
var result = {}; | ||
for (var i in originConfig) { | ||
if (originConfig.hasOwnProperty(i)) { | ||
var camelCaseName = i.replace(/_([a-zA-Z])/g, symbolToUpperCase); | ||
var value = originConfig[i]; | ||
if (typeof value === 'object' && value !== null && !Array.isArray(value)) { | ||
value = fixConfig(value); | ||
} | ||
result[camelCaseName] = value; | ||
} | ||
} | ||
return result; | ||
} | ||
var hasOldStyleConfigParams = false; | ||
for (var i in config) { | ||
if (config.hasOwnProperty(i)) { | ||
if (i.indexOf('_') !== -1) { | ||
hasOldStyleConfigParams = true; | ||
break; | ||
} | ||
} | ||
} | ||
if (hasOldStyleConfigParams) { | ||
throw new Error('JSCS now accepts configuration options in camel case. Sorry for inconvenience. ' + | ||
'On the bright side, we tried to convert your jscs config to camel case.\n' + | ||
'----------------------------------------\n' + | ||
JSON.stringify(fixConfig(config), null, 4) + | ||
'\n----------------------------------------\n'); | ||
} | ||
}, | ||
/** | ||
* Checks file provided with a string. | ||
@@ -276,2 +102,3 @@ * @param {String} str | ||
var errors = new Errors(file, this._verbose); | ||
var errorFilter = this._configuration.getErrorFilter(); | ||
@@ -286,10 +113,11 @@ if (!this._maxErrorsExceeded) { | ||
this._activeRules.forEach(function(rule) { | ||
// Do not process the rule if it's equals to null (#203) | ||
if (this._config[rule.getOptionName()] !== null) { | ||
errors.setCurrentRule(rule.getOptionName()); | ||
rule.check(file, errors); | ||
} | ||
this._configuredRules.forEach(function(rule) { | ||
errors.setCurrentRule(rule.getOptionName()); | ||
rule.check(file, errors); | ||
}, this); | ||
this._configuration.getUnsupportedRuleNames().forEach(function(rulename) { | ||
errors.add('Unsupported rule: ' + rulename, 1, 0); | ||
}); | ||
// sort errors list to show errors as they appear in source | ||
@@ -300,3 +128,7 @@ errors.getErrorList().sort(function(a, b) { | ||
if (!isNaN(this._maxErrors)) { | ||
if (errorFilter) { | ||
errors.filter(errorFilter); | ||
} | ||
if (this._maxErrors !== null && !isNaN(this._maxErrors)) { | ||
if (!this._maxErrorsExceeded) { | ||
@@ -321,2 +153,21 @@ this._maxErrorsExceeded = this._errorsFound + errors.getErrorCount() > this._maxErrors; | ||
return this._maxErrorsExceeded; | ||
}, | ||
/** | ||
* Returns new configuration instance. | ||
* | ||
* @protected | ||
* @returns {Configuration} | ||
*/ | ||
_createConfiguration: function() { | ||
return new Configuration(); | ||
}, | ||
/** | ||
* Returns current configuration instance. | ||
* | ||
* @returns {Configuration} | ||
*/ | ||
getConfiguration: function() { | ||
return this._configuration; | ||
} | ||
@@ -323,0 +174,0 @@ }; |
@@ -55,2 +55,5 @@ module.exports = { | ||
// export (ES6) | ||
'declaration': true, | ||
// xxx.yyy | ||
@@ -57,0 +60,0 @@ 'property': true |
@@ -81,2 +81,3 @@ // 7.5.2 Keywords | ||
'catch', | ||
'finally', | ||
'void', | ||
@@ -83,0 +84,0 @@ 'while', |
@@ -5,3 +5,3 @@ { | ||
"name": "jscs", | ||
"version": "1.7.3", | ||
"version": "1.8.0", | ||
"main": "lib/checker", | ||
@@ -30,4 +30,4 @@ "homepage": "https://github.com/jscs-dev/node-jscs", | ||
"dependencies": { | ||
"colors": "~0.6.2", | ||
"commander": "~2.3.0", | ||
"colors": "~1.0.3", | ||
"commander": "~2.5.0", | ||
"esprima": "~1.2.2", | ||
@@ -42,6 +42,6 @@ "esprima-harmony-jscs": "1.1.0-dev-harmony", | ||
"xmlbuilder": "~2.4.0", | ||
"supports-color": "~1.1.0" | ||
"supports-color": "~1.2.0" | ||
}, | ||
"devDependencies": { | ||
"browserify": "~5.10.0", | ||
"browserify": "~6.2.0", | ||
"coveralls": "~2.11.1", | ||
@@ -51,6 +51,6 @@ "has-ansi": "~1.0.0", | ||
"jshint": "~2.5.0", | ||
"mocha": "~1.21.4", | ||
"mocha": "~2.0.1", | ||
"rewire": "~2.1.0", | ||
"separated-coverage": "~2.3.0", | ||
"sinon": "~1.10.0", | ||
"unit-coverage": "~3.2.0", | ||
"sinon": "~1.11.0", | ||
"xml2js": "~0.4.2" | ||
@@ -61,3 +61,3 @@ }, | ||
}, | ||
"separated-coverage": { | ||
"unit-coverage": { | ||
"common": [ | ||
@@ -83,4 +83,4 @@ "-a", | ||
"test": "npm run lint && mocha", | ||
"coverage": "scov run -p common", | ||
"coverage-html": "scov run -p common -r html -o coverage.html", | ||
"coverage": "unit-coverage run -p common", | ||
"coverage-html": "unit-coverage run -p common -r html -o coverage.html", | ||
"browserify": "browserify --standalone JscsStringChecker lib/string-checker.js -o jscs-browser.js", | ||
@@ -90,3 +90,3 @@ "changelog": "git log `git describe --tags --abbrev=0`..HEAD --pretty=format:' * %s (%an)' | grep -v 'Merge pull request'", | ||
"postpublish": "node publish/postpublish", | ||
"travis": "npm run test && scov run -p common -r lcov -o out.lcov && cat out.lcov | coveralls" | ||
"travis": "npm run test && unit-coverage run -p common -r lcov -o out.lcov && cat out.lcov | coveralls" | ||
}, | ||
@@ -93,0 +93,0 @@ "files": [ |
@@ -52,3 +52,2 @@ { | ||
"disallowKeywords": [ "with" ], | ||
"disallowMultipleLineBreaks": true, | ||
"validateQuoteMarks": "'", | ||
@@ -55,0 +54,0 @@ "validateIndentation": 4, |
488
README.md
# node-jscs | ||
[![Build Status](https://travis-ci.org/jscs-dev/node-jscs.svg?branch=master)](https://travis-ci.org/jscs-dev/node-jscs) [![Coverage Status](https://img.shields.io/coveralls/jscs-dev/node-jscs.svg)](https://coveralls.io/r/jscs-dev/node-jscs?branch=master) [![Dependency Status](https://david-dm.org/jscs-dev/node-jscs.svg?theme=shields.io)](https://david-dm.org/jscs-dev/node-jscs) [![devDependency Status](https://david-dm.org/jscs-dev/node-jscs/dev-status.svg?theme=shields.io)](https://david-dm.org/jscs-dev/node-jscs#info=devDependencies) | ||
JSCS — JavaScript Code Style. | ||
JSCS — JavaScript Code Style. [Twitter](https://twitter.com/jscs_dev) | [Mailing List](https://groups.google.com/group/jscs-dev) | ||
@@ -21,2 +22,3 @@ | ||
- [Rules](#rules) | ||
- [Plugins](#plugins) | ||
- [Removed Rules](#removed-rules) | ||
@@ -31,6 +33,7 @@ - [Browser Usage](#browser-usage) | ||
* [Google](presets/google.json) - https://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml | ||
* [Grunt](presets/grunt.json) - http://gruntjs.com/contributing#syntax | ||
* [jQuery](presets/jquery.json) - https://contribute.jquery.org/style-guide/js/ | ||
* [MDCS](presets/mdcs.json) - https://github.com/mrdoob/three.js/wiki/Mr.doob's-Code-Style%E2%84%A2 | ||
* [Wikimedia](presets/wikimedia.json) - https://www.mediawiki.org/wiki/Manual:Coding_conventions/JavaScript | ||
* [Yandex](presets/yandex.json) - https://github.com/ymaps/codestyle/blob/master/js.md | ||
* [Yandex](presets/yandex.json) - https://github.com/ymaps/codestyle/blob/master/javascript.md | ||
@@ -81,3 +84,3 @@ ## Friendly packages | ||
If there is no `--config` option specified, `jscs` it will consequentially search for `jscsConfig` option in `package.json` file then for `.jscsrc` and `.jscs.json` files in the current working directory then in nearest ancestor until it hits the system root. | ||
If there is no `--config` option specified, `jscs` it will consequentially search for `jscsConfig` option in `package.json` file then for `.jscsrc` (which is a just JSON with comments) and `.jscs.json` files in the current working directory then in nearest ancestor until it hits the system root. | ||
@@ -104,2 +107,14 @@ ### `--preset` | ||
### `--esprima` | ||
Attempts to parse your code with a custom Esprima version. | ||
``` | ||
jscs path[ path[...]] --esprima=esprima-fb | ||
``` | ||
### `--error-filter` | ||
The path to a module that determines whether or not an error should be reported. | ||
``` | ||
jscs path[ path[...]] --error-filter=path/to/my/module.js | ||
``` | ||
### `--no-colors` | ||
@@ -122,2 +137,12 @@ Clean output without colors. | ||
### plugins | ||
Paths to load plugins. See the wiki page for more details about the [Plugin API](https://github.com/jscs-dev/node-jscs/wiki/Plugin-API) | ||
Values: Array of NPM package names or paths | ||
```js | ||
"plugins": ["jscs-plugin", "./lib/project-jscs-plugin"] | ||
``` | ||
### additionalRules | ||
@@ -221,2 +246,17 @@ | ||
### errorFilter | ||
A filter function that determines whether or not to report an error. | ||
This will be called for every found error. | ||
Type: `String` | ||
#### Example | ||
```js | ||
"errorFilter": "path/to/my/filter.js" | ||
``` | ||
See [how to define an error filter](https://github.com/jscs-dev/node-jscs/wiki/Error-Filters). | ||
## Error Suppression | ||
@@ -303,16 +343,2 @@ | ||
```js | ||
[ | ||
'if', | ||
'else', | ||
'for', | ||
'while', | ||
'do', | ||
'try', | ||
'catch', | ||
'case', | ||
'default' | ||
] | ||
``` | ||
JSHint: [`curly`](http://jshint.com/docs/options/#curly) | ||
@@ -350,2 +376,36 @@ | ||
### 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 | ||
@@ -426,2 +486,35 @@ | ||
### 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 | ||
@@ -445,11 +538,11 @@ | ||
if (cond) { | ||
foo(); | ||
foo(); | ||
} | ||
for (var e in elements) { | ||
bar(e); | ||
bar(e); | ||
} | ||
while (cond) { | ||
foo(); | ||
foo(); | ||
} | ||
@@ -462,11 +555,11 @@ ``` | ||
if (cond){ | ||
foo(); | ||
foo(); | ||
} | ||
for (var e in elements){ | ||
bar(e); | ||
bar(e); | ||
} | ||
while (cond){ | ||
foo(); | ||
foo(); | ||
} | ||
@@ -494,11 +587,11 @@ ``` | ||
if (cond){ | ||
foo(); | ||
foo(); | ||
} | ||
for (var e in elements){ | ||
bar(e); | ||
bar(e); | ||
} | ||
while (cond){ | ||
foo(); | ||
foo(); | ||
} | ||
@@ -511,11 +604,11 @@ ``` | ||
if (cond) { | ||
foo(); | ||
foo(); | ||
} | ||
for (var e in elements) { | ||
bar(e); | ||
bar(e); | ||
} | ||
while (cond) { | ||
foo(); | ||
foo(); | ||
} | ||
@@ -603,4 +696,14 @@ ``` | ||
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`. These token names correspond to: | ||
``` | ||
var a = b ? c : d; | ||
^ ^ ^ ^ | ||
| | | | | ||
| | | └- beforeAlternate | ||
| | └--- afterConsequent | ||
| └-------- beforeConsequent | ||
└---------- afterTest | ||
``` | ||
#### Example | ||
@@ -637,3 +740,3 @@ | ||
Requires space before `()` or `{}` in function expressions (both named and anonymous). | ||
Requires space before `()` or `{}` in function expressions (both [named](#requirespacesinnamedfunctionexpression) and [anonymous](#requirespacesinanonymousfunctionexpression)). | ||
@@ -656,4 +759,4 @@ Type: `Object` | ||
```js | ||
function () {} | ||
function a () {} | ||
var x = function () {}; | ||
var x = function a () {}; | ||
``` | ||
@@ -664,4 +767,4 @@ | ||
```js | ||
function() {} | ||
function (){} | ||
var x = function() {}; | ||
var x = function a(){}; | ||
``` | ||
@@ -672,3 +775,3 @@ | ||
Disallows space before `()` or `{}` in function expressions (both named and anonymous). | ||
Disallows space before `()` or `{}` in function expressions (both [named](#disallowspacesinnamedfunctionexpression) and [anonymous](#disallowspacesinanonymousfunctionexpression)). | ||
@@ -691,4 +794,4 @@ Type: `Object` | ||
```js | ||
function(){} | ||
function a(){} | ||
var x = function(){}; | ||
var x = function a(){}; | ||
``` | ||
@@ -699,4 +802,4 @@ | ||
```js | ||
function () {} | ||
function a (){} | ||
var x = function () {}; | ||
var x = function a (){}; | ||
``` | ||
@@ -725,3 +828,7 @@ | ||
```js | ||
function () {} | ||
var foo = function () {}; | ||
var Foo = { | ||
foo: function () {}; | ||
} | ||
array.map(function () {}); | ||
``` | ||
@@ -732,4 +839,7 @@ | ||
```js | ||
function() {} | ||
function (){} | ||
var foo = function() {}; | ||
var Foo = { | ||
foo: function (){}; | ||
} | ||
array.map(function(){}); | ||
``` | ||
@@ -758,3 +868,7 @@ | ||
```js | ||
function(){} | ||
var foo = function(){}; | ||
var Foo = { | ||
foo: function(){}; | ||
} | ||
array.map(function(){}); | ||
``` | ||
@@ -765,4 +879,7 @@ | ||
```js | ||
function () {} | ||
function (){} | ||
var foo = function () {}; | ||
var Foo = { | ||
foo: function (){}; | ||
} | ||
array.map(function() {}); | ||
``` | ||
@@ -791,3 +908,3 @@ | ||
```js | ||
var x = function a () {} | ||
var x = function a () {}; | ||
``` | ||
@@ -798,4 +915,4 @@ | ||
```js | ||
var x = function a() {} | ||
var x = function a(){} | ||
var x = function a() {}; | ||
var x = function a(){}; | ||
``` | ||
@@ -824,3 +941,3 @@ | ||
```js | ||
function a(){} | ||
var x = function a(){}; | ||
``` | ||
@@ -831,4 +948,4 @@ | ||
```js | ||
function a () {} | ||
function a (){} | ||
var x = function a () {}; | ||
var x = function a (){}; | ||
``` | ||
@@ -901,3 +1018,3 @@ | ||
Requires space before `()` or `{}` in function declarations and expressions. | ||
Requires space before `()` or `{}` in function [declarations](#requirespacesinfunctiondeclaration) and [expressions](#requirespacesinfunctionexpression). | ||
@@ -921,2 +1038,4 @@ Type: `Object` | ||
function a () {} | ||
var x = function a () {}; | ||
``` | ||
@@ -929,2 +1048,5 @@ | ||
function a (){} | ||
var x = function a() {}; | ||
var x = function a () {}; | ||
``` | ||
@@ -935,3 +1057,3 @@ | ||
Disallows space before `()` or `{}` in function declarations and expressions. | ||
Disallows space before `()` or `{}` in function [declarations](#disallowspacesinfunctiondeclaration) and [expressions](#disallowspacesinfunctionexpression). | ||
@@ -955,2 +1077,4 @@ Type: `Object` | ||
function a(){} | ||
var x = function a(){}; | ||
``` | ||
@@ -963,2 +1087,5 @@ | ||
function a (){} | ||
var x = function a () {}; | ||
var x = function a (){}; | ||
``` | ||
@@ -1027,4 +1154,8 @@ | ||
Values: `true` or 'strict' (to disallow multiple variable declarations within a for loop) | ||
Values: | ||
- `true` disallows multiple variable declarations except within a for loop | ||
- `'strict'` disallows all multiple variable declarations | ||
- `'exceptUndefined'` allows declarations where all variables are not defined | ||
#### Example | ||
@@ -1036,3 +1167,3 @@ | ||
##### Valid | ||
##### Valid for `true` | ||
@@ -1046,2 +1177,19 @@ ```js | ||
##### Valid for `strict` | ||
```js | ||
var x = 1; | ||
var y = 2; | ||
``` | ||
##### Valid for `exceptUndefined` | ||
```js | ||
var a, b; | ||
var x = 1; | ||
var y = 2; | ||
for (var i = 0, j = arr.length; i < j; i++) {} | ||
``` | ||
##### Invalid | ||
@@ -1052,2 +1200,4 @@ | ||
y = 2; | ||
var x, y = 2, z; | ||
``` | ||
@@ -1296,2 +1446,130 @@ | ||
### requirePaddingNewlinesBeforeKeywords | ||
Requires an empty line above the specified keywords unless the keyword is the first expression in a block. | ||
Type: `Array` or `Boolean` | ||
Values: Array of quoted types or `true` to require padding new lines before all of the keywords below. | ||
#### Example | ||
```js | ||
"requirePaddingNewlinesBeforeKeywords": [ | ||
"do", | ||
"for", | ||
"if", | ||
"else", | ||
"switch", | ||
"case", | ||
"try", | ||
"catch", | ||
"void", | ||
"while", | ||
"with", | ||
"return", | ||
"typeof", | ||
"function" | ||
] | ||
``` | ||
##### Valid | ||
```js | ||
function(a) { | ||
if (!a) { | ||
return false; | ||
} | ||
for (var i = 0; i < b; i++) { | ||
if (!a[i]) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
``` | ||
##### Invalid | ||
```js | ||
function(a) { | ||
if (!a) { | ||
return false; | ||
} | ||
for (var i = 0; i < b; i++) { | ||
if (!a[i]) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
``` | ||
### disallowPaddingNewlinesBeforeKeywords | ||
Disallow an empty line above the specified keywords. | ||
Type: `Array` or `Boolean` | ||
Values: Array of quoted types or `true` to disallow padding new lines after all of the keywords below. | ||
#### Example | ||
```js | ||
"requirePaddingNewlinesBeforeKeywords": [ | ||
"do", | ||
"for", | ||
"if", | ||
"else", | ||
"switch", | ||
"case", | ||
"try", | ||
"catch", | ||
"void", | ||
"while", | ||
"with", | ||
"return", | ||
"typeof", | ||
"function" | ||
] | ||
``` | ||
##### Valid | ||
```js | ||
function(a) { | ||
if (!a) { | ||
return false; | ||
} | ||
for (var i = 0; i < b; i++) { | ||
if (!a[i]) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
``` | ||
##### Invalid | ||
```js | ||
function(a) { | ||
if (!a) { | ||
return false; | ||
} | ||
for (var i = 0; i < b; i++) { | ||
if (!a[i]) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
``` | ||
### disallowEmptyBlocks | ||
@@ -1570,11 +1848,16 @@ | ||
Disallows identifiers that start or end in `_`, except for some popular exceptions: | ||
Disallows identifiers that start or end in `_`. Some popular identifiers are automatically listed as exceptions: | ||
- `__proto__` (javascript) | ||
- `_` (underscore.js) | ||
- `__filename` (node.js global) | ||
- `__dirname` (node.js global) | ||
- `super_` (node.js, used by [`util.inherits`](http://nodejs.org/docs/latest/api/util.html#util_util_inherits_constructor_superconstructor)) | ||
Type: `Boolean` | ||
Type: `Boolean` or `Object` | ||
Values: `true` | ||
Values: | ||
- `true` | ||
- `Object`: | ||
- `allExcept`: array of quoted identifiers | ||
@@ -1586,3 +1869,3 @@ JSHint: [`nomen`](http://www.jshint.com/docs/options/#nomen) | ||
```js | ||
"disallowDanglingUnderscores": true | ||
"disallowDanglingUnderscores": { allExcept: ["_exception"] } | ||
``` | ||
@@ -1594,2 +1877,3 @@ | ||
var x = 1; | ||
var o = obj.__proto__; | ||
var y = _.extend; | ||
@@ -1599,2 +1883,3 @@ var z = __dirname; | ||
var x_y = 1; | ||
var v = _exception; | ||
``` | ||
@@ -2326,2 +2611,37 @@ | ||
### disallowOperatorBeforeLineBreak | ||
Requires putting certain operators on the next line rather than on the current line before a line break. | ||
Type: `Array` or `Boolean` | ||
Values: Array of operators to apply to or `true` | ||
#### Example | ||
```js | ||
"disallowOperatorBeforeLineBreak": ["+", "."] | ||
``` | ||
##### Valid | ||
```js | ||
$el.on( 'click', fn ) | ||
.appendTo( 'body' ); | ||
var x = 4 + 5 + | ||
12 + 13; | ||
``` | ||
##### Invalid | ||
```js | ||
$el.on( 'click', fn ). | ||
appendTo( 'body' ); | ||
var x = 4 + 5 | ||
+ 12 + 13; | ||
``` | ||
### disallowTrailingWhitespace | ||
@@ -2395,3 +2715,4 @@ | ||
- `Object`: | ||
- `ignoreSingleValue`: allows single property objects and single element arrays to not require a trailing comma | ||
- `ignoreSingleValue`: allows single property objects and single element arrays to not require a trailing comma | ||
- `ignoreSingleLine`: allows objects and arrays on a single line to not require a trailing comma | ||
@@ -2418,2 +2739,9 @@ #### Example | ||
##### Valid with ignoreSingleLine | ||
```js | ||
var car = [1, 2, 3]; | ||
var dar = {a: "a", b: "b"}; | ||
``` | ||
##### Invalid | ||
@@ -2623,3 +2951,3 @@ | ||
if (1 == a) { | ||
return | ||
return | ||
} | ||
@@ -2632,3 +2960,3 @@ ``` | ||
if (a == 1) { | ||
return | ||
return | ||
} | ||
@@ -2655,3 +2983,3 @@ ``` | ||
if (a == 1) { | ||
return | ||
return | ||
} | ||
@@ -2664,3 +2992,3 @@ ``` | ||
if (1 == a) { | ||
return | ||
return | ||
} | ||
@@ -2671,7 +2999,11 @@ ``` | ||
Requires that a line comment (`//`) be followed by a space or slash space (`/// `). | ||
Requires that a line comment (`//`) be followed by a space. | ||
Type: `Boolean` or `String` | ||
Type: `Boolean` or `Object` or `String` | ||
Values: `true` or `'allowSlash'` | ||
Values: | ||
- `true` | ||
- `"allowSlash"` (*deprecated* use `"except": ["/"]`) allows `/// ` format | ||
- `Object`: | ||
- `allExcept`: array of allowed strings before space `//(here) ` | ||
@@ -2681,3 +3013,3 @@ #### Example | ||
```js | ||
"requireSpaceAfterLineComment": true | ||
"requireSpaceAfterLineComment": { "allExcept": ["#", "="] } | ||
``` | ||
@@ -2690,2 +3022,4 @@ | ||
/*A comment*/ | ||
//# sourceURL=filename.js | ||
//= require something | ||
``` | ||
@@ -2787,3 +3121,3 @@ | ||
};) | ||
}) | ||
``` | ||
@@ -2800,3 +3134,3 @@ | ||
};) | ||
}); | ||
``` | ||
@@ -3211,3 +3545,3 @@ | ||
Requires the first alphabetical character of a comment to be uppercase | ||
Requires the first alphabetical character of a comment to be uppercase, unless it is part of a multi-line textblock. | ||
@@ -3236,3 +3570,13 @@ Type: `Boolean` | ||
// A textblock is a set of lines | ||
// that starts with a capitalized letter | ||
// and has one or more non-capitalized lines | ||
// afterwards | ||
// A textblock may also have multiple lines. | ||
// Those lines can be uppercase as well to support | ||
// sentense breaks in textblocks | ||
// 123 or any non-alphabetical starting character | ||
// @are also valid anywhere | ||
``` | ||
@@ -3239,0 +3583,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
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
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
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
999533
127
25066
3660
27
+ Addedcolors@1.0.3(transitive)
+ Addedcommander@2.5.1(transitive)
+ Addedsupports-color@1.2.1(transitive)
- Removedcolors@0.6.2(transitive)
- Removedcommander@2.3.0(transitive)
- Removedsupports-color@1.1.0(transitive)
Updatedcolors@~1.0.3
Updatedcommander@~2.5.0
Updatedsupports-color@~1.2.0