Comparing version 3.0.3 to 3.0.4
@@ -71,4 +71,4 @@ var chalk = require('chalk'); | ||
message: errorInfo.message, | ||
line: errorInfo.loc && errorInfo.loc.line, | ||
column: errorInfo.loc && errorInfo.loc.column | ||
line: errorInfo.loc ? errorInfo.loc.line : 1, | ||
column: errorInfo.loc ? errorInfo.loc.column : 0 | ||
}); | ||
@@ -91,3 +91,4 @@ }, | ||
additional: errorInfo.additional, | ||
fixed: errorInfo.fixed | ||
fixed: false, | ||
fix: errorInfo.fix | ||
}); | ||
@@ -182,3 +183,3 @@ }, | ||
this._errorList.forEach(function(error) { | ||
var pos = Errors.getPosition(error.element, error.offset, tokenIndex); | ||
var pos = Errors.getPosition(error, tokenIndex); | ||
error.line = pos.line; | ||
@@ -292,8 +293,11 @@ error.column = pos.column; | ||
* | ||
* @param {Object} [element] | ||
* @param {Number} [offset] | ||
* @param {Error} [error] | ||
* @param {TokenIndex} [tokenIndex] | ||
* @return {Object} | ||
*/ | ||
Errors.getPosition = function(element, offset, tokenIndex) { | ||
Errors.getPosition = function(error, tokenIndex) { | ||
var element = error.element; | ||
var offset = error.offset; | ||
var rule = error.rule; | ||
if (!element) { | ||
@@ -304,4 +308,7 @@ return EMPTY_POS; | ||
if (offset === undefined) { | ||
if (element.getSourceCodeLength() === 1) { | ||
// TODO: probably should be generalized | ||
if (rule === 'validateQuoteMarks') { | ||
offset = 0; | ||
} else if (element.getSourceCodeLength() === 1) { | ||
offset = 0; | ||
} else { | ||
@@ -308,0 +315,0 @@ offset = (element.getNewlineCount() === 0 && Math.ceil(element.getSourceCodeLength() / 2)) || 0; |
@@ -57,3 +57,3 @@ /** | ||
nextToken: propertyNode.getFirstToken(), | ||
message: 'Object keys must go on a new line' | ||
message: 'Object keys should be on the same line' | ||
}); | ||
@@ -60,0 +60,0 @@ } |
@@ -91,3 +91,3 @@ /** | ||
errors.assert.linesBetween({ | ||
token: file.getPrevToken(token), | ||
token: file.getPrevToken(token, { includeComments: true }), | ||
nextToken: token, | ||
@@ -94,0 +94,0 @@ atMost: 1, |
@@ -72,16 +72,28 @@ /** | ||
var key = prop.key; | ||
if (key.type === 'StringLiteral' && | ||
typeof key.value === 'string' && | ||
KEY_NAME_RE.test(key.value) | ||
) { | ||
if (exceptReserved && reservedWords.check(key.value, file.getDialect(), true)) { | ||
return; | ||
} | ||
errors.cast({ | ||
message: 'Extra quotes for key', | ||
element: prop, | ||
additional: prop | ||
}); | ||
// Spread properties | ||
if (!key) { | ||
return; | ||
} | ||
if (key.type !== 'StringLiteral') { | ||
return; | ||
} | ||
if (typeof key.value !== 'string') { | ||
return; | ||
} | ||
if (!KEY_NAME_RE.test(key.value)) { | ||
return; | ||
} | ||
if (exceptReserved && reservedWords.check(key.value, file.getDialect(), true)) { | ||
return; | ||
} | ||
errors.cast({ | ||
message: 'Extra quotes for key', | ||
element: prop | ||
}); | ||
}); | ||
@@ -92,3 +104,3 @@ }); | ||
_fix: function(file, error) { | ||
var node = error.additional; | ||
var node = error.element; | ||
var key = node.key.childElements[0]; | ||
@@ -95,0 +107,0 @@ |
@@ -92,2 +92,3 @@ /** | ||
var doubleQuote = this._onlyDoubleQuote; | ||
var alreadyAdded = []; | ||
@@ -119,3 +120,3 @@ file.iterateTokensByTypeAndValue('Punctuator', '(', function(token) { | ||
errors.assert.noWhitespaceBetween({ | ||
var isAdded = errors.assert.noWhitespaceBetween({ | ||
token: token, | ||
@@ -125,2 +126,6 @@ nextToken: nextToken, | ||
}); | ||
if (isAdded) { | ||
alreadyAdded.push(token); | ||
} | ||
}); | ||
@@ -133,2 +138,7 @@ | ||
// Do not check already found errors, like "function ( ) { ..." | ||
if (alreadyAdded.indexOf(prevToken) > -1) { | ||
return; | ||
} | ||
if (doubleQuote && prevToken.type === 'String' && value[value.length - 1] === '"') { | ||
@@ -135,0 +145,0 @@ shouldReturn = false; |
@@ -40,2 +40,6 @@ /** | ||
function getUnusedNodes(node, variableMap, groupIfPossible) { | ||
if (node.type === 'AssignmentPattern') { | ||
return getUnusedNodes(node.left, variableMap, groupIfPossible); | ||
} | ||
if (node.type === 'Identifier') { | ||
@@ -98,2 +102,4 @@ var variable = variableMap[node.name]; | ||
} | ||
return []; | ||
} | ||
@@ -100,0 +106,0 @@ |
@@ -199,3 +199,3 @@ /** | ||
'Line must be at most ' + maximumLineLength + ' characters', | ||
file.getLastTokenOnLine(i + 1) | ||
file.getLastTokenOnLine(i + 1, { includeComments: true }) | ||
); | ||
@@ -202,0 +202,0 @@ } |
@@ -144,4 +144,3 @@ /** | ||
expected: referenceColumn, | ||
indentChar: ' ', | ||
silent: false | ||
indentChar: ' ' | ||
}); | ||
@@ -148,0 +147,0 @@ } |
@@ -7,10 +7,10 @@ /** | ||
* Values: | ||
* - Array of quoted keywords | ||
* - `true` to require curly braces after the following keywords | ||
* - `Object` | ||
* - `'keywords'` | ||
* - Array of quoted keywords | ||
* - `'allExcept'` | ||
* - Array of keywords inside of the block that would allow curly braces | ||
* - Ex: ["return" , "continue", "break"] | ||
* - Array of quoted keywords | ||
* - `true` to require curly braces after the following keywords | ||
* - `Object` | ||
* - `'keywords'` | ||
* - Array of quoted keywords | ||
* - `'allExcept'` | ||
* - Array of keywords inside of the block that would allow curly braces | ||
* - Ex: ["return" , "continue", "break"] | ||
* | ||
@@ -17,0 +17,0 @@ * JSHint: [`curly`](http://jshint.com/docs/options/#curly) |
@@ -7,3 +7,3 @@ /** | ||
* Values: | ||
* - `true`: disallow to use of else if the corrisponding `if` block contain a return. | ||
* - `true`: disallow to use of else if the corresponding `if` block contain a return. | ||
* | ||
@@ -10,0 +10,0 @@ * #### Example |
@@ -88,2 +88,3 @@ /** | ||
var lastValueToken; | ||
var lastProp; | ||
@@ -93,3 +94,4 @@ if (isSameLine) { | ||
firstKeyToken = file.getFirstNodeToken(node.properties[0].key); | ||
lastValueToken = file.getLastNodeToken(node.properties[node.properties.length - 1].value); | ||
lastProp = node.properties[node.properties.length - 1]; | ||
lastValueToken = file.getLastNodeToken(lastProp.value || lastProp.key); | ||
@@ -104,3 +106,4 @@ if (firstKeyToken.getLoc().end.line === lastValueToken.getLoc().start.line) { | ||
for (var i = 1; i < node.properties.length; i++) { | ||
lastValueToken = file.getLastNodeToken(node.properties[i - 1].value); | ||
var prop = node.properties[i - 1]; | ||
lastValueToken = file.getLastNodeToken(prop.value || prop.body); | ||
var comma = file.findNextToken(lastValueToken, 'Punctuator', ','); | ||
@@ -107,0 +110,0 @@ |
@@ -98,5 +98,47 @@ var Errors = require('./errors'); | ||
/** | ||
* Fix provided error. | ||
* Apply fix for common errors. | ||
* | ||
* @param {Error} error | ||
* @return {Boolean} whether the correction was carried out | ||
* @private | ||
*/ | ||
_fixCommonError: function(error) { | ||
if (error.fix) { | ||
// "error.fixed = true" should go first, so rule can | ||
// decide for itself (with "error.fixed = false") | ||
// if it can fix this particular error | ||
error.fixed = true; | ||
error.fix(); | ||
} | ||
return !!error.fixed; | ||
}, | ||
/** | ||
* Apply fix for specific error. | ||
* | ||
* @param {JsFile} file | ||
* @param {Error} error | ||
* @return {Boolean} whether the correction was carried out | ||
* @private | ||
*/ | ||
_fixSpecificError: function(file, error) { | ||
var configuration = this.getConfiguration(); | ||
var instance = configuration.getConfiguredRule(error.rule); | ||
if (instance && instance._fix) { | ||
// "error.fixed = true" should go first, so rule can | ||
// decide for itself (with "error.fixed = false") | ||
// if it can fix this particular error | ||
error.fixed = true; | ||
instance._fix(file, error); | ||
} | ||
return !!error.fixed; | ||
}, | ||
/** | ||
* Apply specific and common fixes. | ||
* | ||
* @param {JsFile} file | ||
* @param {Errors} errors | ||
@@ -106,6 +148,3 @@ * @protected | ||
_fixJsFile: function(file, errors) { | ||
var list = errors.getErrorList(); | ||
var configuration = this.getConfiguration(); | ||
list.forEach(function(error) { | ||
errors.getErrorList().forEach(function(error) { | ||
if (error.fixed) { | ||
@@ -115,22 +154,18 @@ return; | ||
var instance = configuration.getConfiguredRule(error.rule); | ||
try { | ||
// Try to apply fixes for common errors | ||
var isFixed = this._fixCommonError(error); | ||
if (instance && instance._fix) { | ||
try { | ||
// "error.fixed = true" should go first, so rule can | ||
// decide for itself (with "error.fixed = false") | ||
// if it can fix this particular error | ||
error.fixed = true; | ||
instance._fix(file, error); | ||
} catch (e) { | ||
error.fixed = undefined; | ||
errors.add( | ||
getInternalErrorMessage(error.rule, e), | ||
file.getProgram() | ||
); | ||
// Apply specific fix | ||
if (!isFixed) { | ||
this._fixSpecificError(file, error); | ||
} | ||
} catch (e) { | ||
error.fixed = false; | ||
errors.add( | ||
getInternalErrorMessage(error.rule, e), | ||
file.getProgram() | ||
); | ||
} | ||
}); | ||
}, this); | ||
}, | ||
@@ -238,3 +273,3 @@ | ||
/** | ||
* Checks file provided with a string. | ||
* Checks and fix file provided with a string. | ||
* | ||
@@ -261,7 +296,7 @@ * @param {String} source | ||
do { | ||
// Changes to current sources are made in rules through assertions. | ||
// Fill in errors list | ||
this._checkJsFile(file, errors); | ||
// If assertions weren't used but rule has "fix" method, | ||
// which we could use. | ||
// Apply fixes | ||
this._fixJsFile(file, errors); | ||
@@ -268,0 +303,0 @@ |
@@ -27,6 +27,7 @@ var utils = require('util'); | ||
* @param {Number} [options.spaces] Amount of spaces between tokens. | ||
* @return {Boolean} whether an error was found | ||
*/ | ||
TokenAssert.prototype.whitespaceBetween = function(options) { | ||
options.atLeast = 1; | ||
this.spacesBetween(options); | ||
return this.spacesBetween(options); | ||
}; | ||
@@ -42,6 +43,7 @@ | ||
* @param {Boolean} [options.disallowNewLine=false] | ||
* @return {Boolean} whether an error was found | ||
*/ | ||
TokenAssert.prototype.noWhitespaceBetween = function(options) { | ||
options.exactly = 0; | ||
this.spacesBetween(options); | ||
return this.spacesBetween(options); | ||
}; | ||
@@ -60,2 +62,3 @@ | ||
* @param {Boolean} [options.disallowNewLine=false] | ||
* @return {Boolean} whether an error was found | ||
*/ | ||
@@ -70,3 +73,3 @@ TokenAssert.prototype.spacesBetween = function(options) { | ||
if (!token || !nextToken) { | ||
return; | ||
return false; | ||
} | ||
@@ -77,3 +80,3 @@ | ||
if (!options.disallowNewLine && !this._file.isOnTheSameLine(token, nextToken)) { | ||
return; | ||
return false; | ||
} | ||
@@ -86,5 +89,5 @@ | ||
var emitError = function(countPrefix, spaceCount) { | ||
if (fixed) { | ||
var fix = function() { | ||
this._file.setWhitespaceBefore(nextToken, new Array(spaceCount + 1).join(' ')); | ||
} | ||
}.bind(this); | ||
@@ -112,3 +115,3 @@ var msgPostfix = token.value + ' and ' + nextToken.value; | ||
offset: token.getSourceCodeLength(), | ||
fixed: fixed | ||
fix: fixed ? fix : undefined | ||
}); | ||
@@ -118,9 +121,19 @@ }.bind(this); | ||
var spacesBetween = this._file.getDistanceBetween(token, nextToken); | ||
if (atLeast !== undefined && spacesBetween < atLeast) { | ||
emitError('at least', atLeast); | ||
} else if (atMost !== undefined && spacesBetween > atMost) { | ||
return true; | ||
} | ||
if (atMost !== undefined && spacesBetween > atMost) { | ||
emitError('at most', atMost); | ||
} else if (exactly !== undefined && spacesBetween !== exactly) { | ||
return true; | ||
} | ||
if (exactly !== undefined && spacesBetween !== exactly) { | ||
emitError('exactly', exactly); | ||
return true; | ||
} | ||
return false; | ||
}; | ||
@@ -136,3 +149,3 @@ | ||
* @param {String} options.token | ||
* @param {Boolean} [options.silent] if true, will suppress error emission but still fix whitespace | ||
* @return {Boolean} whether an error was found | ||
*/ | ||
@@ -147,24 +160,24 @@ TokenAssert.prototype.indentation = function(options) { | ||
if (actual === expected) { | ||
return; | ||
return false; | ||
} | ||
if (!options.silent) { | ||
this.emit('error', { | ||
message: 'Expected indentation of ' + expected + ' characters', | ||
line: lineNumber, | ||
column: expected, | ||
fixed: true | ||
}); | ||
} | ||
this.emit('error', { | ||
message: 'Expected indentation of ' + expected + ' characters', | ||
line: lineNumber, | ||
column: expected, | ||
fix: function() { | ||
var newWhitespace = (new Array(expected + 1)).join(indentChar); | ||
var newWhitespace = (new Array(expected + 1)).join(indentChar); | ||
this._updateWhitespaceByLine(token, function(lines) { | ||
lines[lines.length - 1] = newWhitespace; | ||
return lines; | ||
}); | ||
this._updateWhitespaceByLine(token, function(lines) { | ||
lines[lines.length - 1] = newWhitespace; | ||
return lines; | ||
if (token.isComment) { | ||
this._updateCommentWhitespace(token, indentChar, actual, expected); | ||
} | ||
}.bind(this) | ||
}); | ||
if (token.isComment) { | ||
this._updateCommentWhitespace(token, indentChar, actual, expected); | ||
} | ||
return true; | ||
}; | ||
@@ -176,4 +189,4 @@ | ||
* | ||
* @param {Object} token | ||
* @param {Function} callback | ||
* @param {Object} token | ||
* @param {Function} callback | ||
*/ | ||
@@ -192,6 +205,6 @@ TokenAssert.prototype._updateWhitespaceByLine = function(token, callback) { | ||
* | ||
* @param {Object} token | ||
* @param {Function} indentChar | ||
* @param {Number} actual | ||
* @param {Number} expected | ||
* @param {Object} token | ||
* @param {Function} indentChar | ||
* @param {Number} actual | ||
* @param {Number} expected | ||
*/ | ||
@@ -225,2 +238,3 @@ TokenAssert.prototype._updateCommentWhitespace = function(token, indentChar, actual, expected) { | ||
* @param {String} [options.message] | ||
* @return {Boolean} whether an error was found | ||
*/ | ||
@@ -230,3 +244,3 @@ TokenAssert.prototype.sameLine = function(options) { | ||
this.linesBetween(options); | ||
return this.linesBetween(options); | ||
}; | ||
@@ -241,2 +255,3 @@ | ||
* @param {Object} [options.message] | ||
* @return {Boolean} whether an error was found | ||
*/ | ||
@@ -246,3 +261,3 @@ TokenAssert.prototype.differentLine = function(options) { | ||
this.linesBetween(options); | ||
return this.linesBetween(options); | ||
}; | ||
@@ -263,2 +278,3 @@ | ||
* nextToken onto the previous token. | ||
* @return {Boolean} whether an error was found | ||
*/ | ||
@@ -273,3 +289,3 @@ TokenAssert.prototype.linesBetween = function(options) { | ||
if (!token || !nextToken) { | ||
return; | ||
return false; | ||
} | ||
@@ -288,2 +304,6 @@ | ||
var fix = function() { | ||
this._augmentLineCount(options, lineCount); | ||
}.bind(this); | ||
if (!options.message) { | ||
@@ -302,6 +322,2 @@ if (exactly === 0) { | ||
if (fixed) { | ||
this._augmentLineCount(options, lineCount); | ||
} | ||
this.emit('error', { | ||
@@ -311,3 +327,3 @@ message: options.message, | ||
offset: token.getSourceCodeLength(), | ||
fixed: fixed | ||
fix: fixed ? fix : undefined | ||
}); | ||
@@ -318,7 +334,16 @@ }.bind(this); | ||
emitError('at least', atLeast); | ||
} else if (atMost !== undefined && linesBetween > atMost) { | ||
return true; | ||
} | ||
if (atMost !== undefined && linesBetween > atMost) { | ||
emitError('at most', atMost); | ||
} else if (exactly !== undefined && linesBetween !== exactly) { | ||
return true; | ||
} | ||
if (exactly !== undefined && linesBetween !== exactly) { | ||
emitError('exactly', exactly); | ||
return true; | ||
} | ||
return false; | ||
}; | ||
@@ -337,2 +362,3 @@ | ||
* @throws {Error} If the options are non-sensical | ||
* @private | ||
*/ | ||
@@ -372,2 +398,3 @@ TokenAssert.prototype._validateOptions = function(options) { | ||
* @param {Number} lineCount | ||
* @private | ||
*/ | ||
@@ -374,0 +401,0 @@ TokenAssert.prototype._augmentLineCount = function(options, lineCount) { |
@@ -8,3 +8,3 @@ { | ||
"name": "jscs", | ||
"version": "3.0.3", | ||
"version": "3.0.4", | ||
"main": "lib/checker", | ||
@@ -67,3 +67,3 @@ "homepage": "http://jscs.info", | ||
"commander": "~2.9.0", | ||
"cst": "0.1.6", | ||
"cst": "^0.3.0", | ||
"estraverse": "^4.1.0", | ||
@@ -136,3 +136,3 @@ "exit": "~0.1.2", | ||
"watch": "mocha --color --watch", | ||
"autofix-tests": "node test/scripts/integration.js", | ||
"integration": "#node test/scripts/integration.js", | ||
"coverage": "unit-coverage run -p common", | ||
@@ -142,4 +142,3 @@ "coverage-html": "unit-coverage run -p common -r html -o coverage.html", | ||
"changelog": "git log `git describe --tags --abbrev=0`..HEAD --pretty=format:' * %s (%an)' | grep -v 'Merge pull request'", | ||
"release": "node publish/prepublish && npm test && npm publish", | ||
"travis": "npm run test && npm run autofix-tests && npm run coveralls" | ||
"release": "node publish/prepublish && npm test && npm publish" | ||
}, | ||
@@ -146,0 +145,0 @@ "files": [ |
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
No README
QualityPackage does not have a README. This may indicate a failed publish or a low quality 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
810350
22516
210
1
0
+ Addedcst@0.3.0(transitive)
- Removedcst@0.1.6(transitive)
Updatedcst@^0.3.0