coffeelint/lib/coffeelint.js in coffeelint-0.3.0 vs coffeelint/lib/coffeelint.js in coffeelint-0.4.0
- old
+ new
@@ -1,19 +1,20 @@
!function(e){if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.coffeelint=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
module.exports={
"name": "coffeelint",
"description": "Lint your CoffeeScript",
- "version": "1.4.1",
+ "version": "1.6.1",
"homepage": "http://www.coffeelint.org",
"keywords": [
"lint",
"coffeescript",
"coffee-script"
],
"author": "Matthew Perpick <clutchski@gmail.com>",
"main": "./lib/coffeelint.js",
"engines": {
+ "npm": ">=1.3.7",
"node": ">=0.8.0"
},
"repository": {
"type": "git",
"url": "git://github.com/clutchski/coffeelint.git"
@@ -23,12 +24,13 @@
},
"dependencies": {
"browserify": "~3.37",
"coffee-script": "~1.7",
"coffeeify": "~0.6.0",
- "glob": ">=3.1.9",
- "optimist": ">=0.2.8",
+ "glob": "^4.0.0",
+ "ignore": "^2.2.15",
+ "optimist": "^0.6.1",
"resolve": "^0.6.3"
},
"devDependencies": {
"vows": ">=0.6.0",
"underscore": ">=1.4.4"
@@ -39,18 +41,18 @@
"url": "http://github.com/clutchski/coffeelint/raw/master/LICENSE"
}
],
"scripts": {
"pretest": "cake compile",
- "test": "coffee vowsrunner.coffee --spec test/*.coffee test/*.litcoffee",
+ "test": "./vowsrunner.js --spec test/*.coffee test/*.litcoffee",
"posttest": "npm run lint",
"prepublish": "cake prepublish",
"publish": "cake publish",
"install": "cake install",
- "lint": "cake compile && ./bin/coffeelint -f coffeelint.json src/*.coffee test/*.coffee test/*.litcoffee",
- "lint-csv": "cake compile && ./bin/coffeelint --csv -f coffeelint.json src/*.coffee test/*.coffee",
- "lint-jslint": "cake compile && ./bin/coffeelint --jslint -f coffeelint.json src/*.coffee test/*.coffee",
+ "lint": "cake compile && ./bin/coffeelint .",
+ "lint-csv": "cake compile && ./bin/coffeelint --csv .",
+ "lint-jslint": "cake compile && ./bin/coffeelint --jslint .",
"compile": "cake compile"
}
}
},{}],2:[function(_dereq_,module,exports){
@@ -276,21 +278,22 @@
CoffeeLint
Copyright (c) 2011 Matthew Perpick.
CoffeeLint is freely distributable under the MIT license.
*/
-var ASTLinter, CoffeeScript, ERROR, IGNORE, LexicalLinter, LineLinter, RULES, WARN, coffeelint, cs, defaults, difference, extend, hasSyntaxError, mergeDefaultConfig, packageJSON, _rules,
+var ASTLinter, CoffeeScript, ERROR, ErrorReport, IGNORE, LexicalLinter, LineLinter, RULES, WARN, cache, coffeelint, defaults, difference, extend, hasSyntaxError, mergeDefaultConfig, nodeRequire, packageJSON, _rules,
__slice = [].slice,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
coffeelint = exports;
+nodeRequire = _dereq_;
+
if (typeof window !== "undefined" && window !== null) {
CoffeeScript = window.CoffeeScript;
} else {
- cs = 'coffee-script';
- CoffeeScript = _dereq_(cs);
+ CoffeeScript = nodeRequire('coffee-script');
}
packageJSON = _dereq_('./../package.json');
coffeelint.VERSION = packageJSON.version;
@@ -338,10 +341,12 @@
LexicalLinter = _dereq_('./lexical_linter.coffee');
ASTLinter = _dereq_('./ast_linter.coffee');
+cache = null;
+
mergeDefaultConfig = function(userConfig) {
var config, rule, ruleConfig;
config = {};
for (rule in RULES) {
ruleConfig = RULES[rule];
@@ -405,10 +410,21 @@
}
RULES[p.rule.name] = p.rule;
return _rules[p.rule.name] = RuleConstructor;
};
+coffeelint.getRules = function() {
+ var key, output, _i, _len, _ref;
+ output = {};
+ _ref = Object.keys(RULES).sort();
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ key = _ref[_i];
+ output[key] = RULES[key];
+ }
+ return output;
+};
+
coffeelint.registerRule(_dereq_('./rules/arrow_spacing.coffee'));
coffeelint.registerRule(_dereq_('./rules/no_tabs.coffee'));
coffeelint.registerRule(_dereq_('./rules/no_trailing_whitespace.coffee'));
@@ -461,26 +477,44 @@
coffeelint.registerRule(_dereq_('./rules/no_interpolation_in_single_quotes.coffee'));
coffeelint.registerRule(_dereq_('./rules/no_empty_functions.coffee'));
+coffeelint.registerRule(_dereq_('./rules/prefer_english_operator.coffee'));
+
hasSyntaxError = function(source) {
try {
CoffeeScript.tokens(source);
return false;
} catch (_error) {}
return true;
};
+ErrorReport = _dereq_('./error_report.coffee');
+
+coffeelint.getErrorReport = function() {
+ return new ErrorReport(coffeelint);
+};
+
coffeelint.lint = function(source, userConfig, literate) {
- var all_errors, astErrors, block_config, cmd, config, disabled, disabled_initially, e, errors, i, l, lexErrors, lexicalLinter, lineErrors, lineLinter, name, next_line, r, rules, s, tokensByLine, _i, _j, _k, _len, _len1, _ref, _ref1, _ref2, _ref3, _ref4;
+ var all_errors, astErrors, block_config, cmd, config, disabled, disabled_initially, e, errors, i, l, lexErrors, lexicalLinter, lineErrors, lineLinter, name, next_line, r, ruleLoader, rules, s, tokensByLine, _i, _j, _k, _len, _len1, _ref, _ref1, _ref2, _ref3, _ref4;
if (userConfig == null) {
userConfig = {};
}
if (literate == null) {
literate = false;
}
+ try {
+ ruleLoader = nodeRequire('./ruleLoader');
+ ruleLoader.loadFromConfig(this, userConfig);
+ } catch (_error) {}
+ if (cache != null) {
+ cache.setConfig(userConfig);
+ }
+ if (cache != null ? cache.has(source) : void 0) {
+ return cache != null ? cache.get(source) : void 0;
+ }
if (literate) {
source = this.invertLiterate(source);
}
for (name in userConfig) {
if (name !== 'coffeescript_error' && name !== '_comment') {
@@ -560,15 +594,114 @@
errors.push(e);
}
}
}
}
+ if (cache != null) {
+ cache.set(source, errors);
+ }
return errors;
};
+coffeelint.setCache = function(obj) {
+ return cache = obj;
+};
-},{"./../package.json":1,"./ast_linter.coffee":2,"./lexical_linter.coffee":5,"./line_linter.coffee":6,"./rules.coffee":7,"./rules/arrow_spacing.coffee":8,"./rules/camel_case_classes.coffee":9,"./rules/colon_assignment_spacing.coffee":10,"./rules/cyclomatic_complexity.coffee":11,"./rules/duplicate_key.coffee":12,"./rules/empty_constructor_needs_parens.coffee":13,"./rules/indentation.coffee":14,"./rules/line_endings.coffee":15,"./rules/max_line_length.coffee":16,"./rules/missing_fat_arrows.coffee":17,"./rules/newlines_after_classes.coffee":18,"./rules/no_backticks.coffee":19,"./rules/no_debugger.coffee":20,"./rules/no_empty_functions.coffee":21,"./rules/no_empty_param_list.coffee":22,"./rules/no_implicit_braces.coffee":23,"./rules/no_implicit_parens.coffee":24,"./rules/no_interpolation_in_single_quotes.coffee":25,"./rules/no_plusplus.coffee":26,"./rules/no_stand_alone_at.coffee":27,"./rules/no_tabs.coffee":28,"./rules/no_throwing_strings.coffee":29,"./rules/no_trailing_semicolons.coffee":30,"./rules/no_trailing_whitespace.coffee":31,"./rules/no_unnecessary_double_quotes.coffee":32,"./rules/no_unnecessary_fat_arrows.coffee":33,"./rules/non_empty_constructor_needs_parens.coffee":34,"./rules/space_operators.coffee":35}],5:[function(_dereq_,module,exports){
+
+},{"./../package.json":1,"./ast_linter.coffee":2,"./error_report.coffee":5,"./lexical_linter.coffee":6,"./line_linter.coffee":7,"./rules.coffee":8,"./rules/arrow_spacing.coffee":9,"./rules/camel_case_classes.coffee":10,"./rules/colon_assignment_spacing.coffee":11,"./rules/cyclomatic_complexity.coffee":12,"./rules/duplicate_key.coffee":13,"./rules/empty_constructor_needs_parens.coffee":14,"./rules/indentation.coffee":15,"./rules/line_endings.coffee":16,"./rules/max_line_length.coffee":17,"./rules/missing_fat_arrows.coffee":18,"./rules/newlines_after_classes.coffee":19,"./rules/no_backticks.coffee":20,"./rules/no_debugger.coffee":21,"./rules/no_empty_functions.coffee":22,"./rules/no_empty_param_list.coffee":23,"./rules/no_implicit_braces.coffee":24,"./rules/no_implicit_parens.coffee":25,"./rules/no_interpolation_in_single_quotes.coffee":26,"./rules/no_plusplus.coffee":27,"./rules/no_stand_alone_at.coffee":28,"./rules/no_tabs.coffee":29,"./rules/no_throwing_strings.coffee":30,"./rules/no_trailing_semicolons.coffee":31,"./rules/no_trailing_whitespace.coffee":32,"./rules/no_unnecessary_double_quotes.coffee":33,"./rules/no_unnecessary_fat_arrows.coffee":34,"./rules/non_empty_constructor_needs_parens.coffee":35,"./rules/prefer_english_operator.coffee":36,"./rules/space_operators.coffee":37}],5:[function(_dereq_,module,exports){
+var ErrorReport;
+
+module.exports = ErrorReport = (function() {
+ function ErrorReport(coffeelint) {
+ this.coffeelint = coffeelint;
+ this.paths = {};
+ }
+
+ ErrorReport.prototype.lint = function(filename, source, config, literate) {
+ if (config == null) {
+ config = {};
+ }
+ if (literate == null) {
+ literate = false;
+ }
+ return this.paths[filename] = this.coffeelint.lint(source, config, literate);
+ };
+
+ ErrorReport.prototype.getExitCode = function() {
+ var path;
+ for (path in this.paths) {
+ if (this.pathHasError(path)) {
+ return 1;
+ }
+ }
+ return 0;
+ };
+
+ ErrorReport.prototype.getSummary = function() {
+ var error, errorCount, errors, path, pathCount, warningCount, _i, _len, _ref;
+ pathCount = errorCount = warningCount = 0;
+ _ref = this.paths;
+ for (path in _ref) {
+ errors = _ref[path];
+ pathCount++;
+ for (_i = 0, _len = errors.length; _i < _len; _i++) {
+ error = errors[_i];
+ if (error.level === 'error') {
+ errorCount++;
+ }
+ if (error.level === 'warn') {
+ warningCount++;
+ }
+ }
+ }
+ return {
+ errorCount: errorCount,
+ warningCount: warningCount,
+ pathCount: pathCount
+ };
+ };
+
+ ErrorReport.prototype.getErrors = function(path) {
+ return this.paths[path];
+ };
+
+ ErrorReport.prototype.pathHasWarning = function(path) {
+ return this._hasLevel(path, 'warn');
+ };
+
+ ErrorReport.prototype.pathHasError = function(path) {
+ return this._hasLevel(path, 'error');
+ };
+
+ ErrorReport.prototype.hasError = function() {
+ var path;
+ for (path in this.paths) {
+ if (this.pathHasError(path)) {
+ return true;
+ }
+ }
+ return false;
+ };
+
+ ErrorReport.prototype._hasLevel = function(path, level) {
+ var error, _i, _len, _ref;
+ _ref = this.paths[path];
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ error = _ref[_i];
+ if (error.level === level) {
+ return true;
+ }
+ }
+ return false;
+ };
+
+ return ErrorReport;
+
+})();
+
+
+},{}],6:[function(_dereq_,module,exports){
var BaseLinter, LexicalLinter, TokenApi,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
@@ -668,11 +801,11 @@
return LexicalLinter;
})(BaseLinter);
-},{"./base_linter.coffee":3}],6:[function(_dereq_,module,exports){
+},{"./base_linter.coffee":3}],7:[function(_dereq_,module,exports){
var BaseLinter, LineApi, LineLinter, configStatement,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
LineApi = (function() {
@@ -851,11 +984,11 @@
return LineLinter;
})(BaseLinter);
-},{"./base_linter.coffee":3}],7:[function(_dereq_,module,exports){
+},{"./base_linter.coffee":3}],8:[function(_dereq_,module,exports){
var ERROR, IGNORE, WARN;
ERROR = 'error';
WARN = 'warn';
@@ -868,11 +1001,11 @@
message: ''
}
};
-},{}],8:[function(_dereq_,module,exports){
+},{}],9:[function(_dereq_,module,exports){
var ArrowSpacing;
module.exports = ArrowSpacing = (function() {
function ArrowSpacing() {}
@@ -886,11 +1019,13 @@
ArrowSpacing.prototype.tokens = ['->'];
ArrowSpacing.prototype.lintToken = function(token, tokenApi) {
var pp;
pp = tokenApi.peek(-1);
- if (!(((token.spaced != null) || (token.newLine != null) || this.atEof(tokenApi)) && (((pp.spaced != null) || pp[0] === 'TERMINATOR') || (pp.generated != null) || pp[0] === "INDENT" || (pp[1] === "(" && (pp.generated == null))))) {
+ if (!token.spaced && (pp[1] === "(" && (pp.generated == null)) && tokenApi.peek(1)[0] === 'INDENT' && tokenApi.peek(2)[0] === 'OUTDENT') {
+ return null;
+ } else if (!(((token.spaced != null) || (token.newLine != null) || this.atEof(tokenApi)) && (((pp.spaced != null) || pp[0] === 'TERMINATOR') || (pp.generated != null) || pp[0] === "INDENT" || (pp[1] === "(" && (pp.generated == null))))) {
return true;
} else {
return null;
}
};
@@ -911,11 +1046,11 @@
return ArrowSpacing;
})();
-},{}],9:[function(_dereq_,module,exports){
+},{}],10:[function(_dereq_,module,exports){
var CamelCaseClasses, regexes;
regexes = {
camelCase: /^[A-Z][a-zA-Z\d]*$/
};
@@ -958,11 +1093,11 @@
return CamelCaseClasses;
})();
-},{}],10:[function(_dereq_,module,exports){
+},{}],11:[function(_dereq_,module,exports){
var ColonAssignmentSpacing;
module.exports = ColonAssignmentSpacing = (function() {
function ColonAssignmentSpacing() {}
@@ -978,12 +1113,12 @@
};
ColonAssignmentSpacing.prototype.tokens = [':'];
ColonAssignmentSpacing.prototype.lintToken = function(token, tokenApi) {
- var checkSpacing, getSpaceFromToken, isLeftSpaced, isRightSpaced, leftSpacing, nextToken, previousToken, rightSpacing, spacingAllowances, _ref, _ref1;
- spacingAllowances = tokenApi.config[this.rule.name].spacing;
+ var checkSpacing, getSpaceFromToken, isLeftSpaced, isRightSpaced, leftSpacing, nextToken, previousToken, rightSpacing, spaceRules, _ref, _ref1;
+ spaceRules = tokenApi.config[this.rule.name].spacing;
previousToken = tokenApi.peek(-1);
nextToken = tokenApi.peek(1);
getSpaceFromToken = function(direction) {
switch (direction) {
case 'left':
@@ -993,30 +1128,30 @@
}
};
checkSpacing = function(direction) {
var isSpaced, spacing;
spacing = getSpaceFromToken(direction);
- isSpaced = spacing < 0 ? true : spacing === parseInt(spacingAllowances[direction]);
+ isSpaced = spacing < 0 ? true : spacing === parseInt(spaceRules[direction]);
return [isSpaced, spacing];
};
_ref = checkSpacing('left'), isLeftSpaced = _ref[0], leftSpacing = _ref[1];
_ref1 = checkSpacing('right'), isRightSpaced = _ref1[0], rightSpacing = _ref1[1];
if (isLeftSpaced && isRightSpaced) {
return null;
} else {
return {
- context: "Incorrect spacing around column " + token[2].first_column + ".\nExpected left: " + spacingAllowances.left + ", right: " + spacingAllowances.right + ".\nGot left: " + leftSpacing + ", right: " + rightSpacing + "."
+ context: "Incorrect spacing around column " + token[2].first_column + ".\nExpected left: " + spaceRules.left + ", right: " + spaceRules.right + ".\nGot left: " + leftSpacing + ", right: " + rightSpacing + "."
};
}
};
return ColonAssignmentSpacing;
})();
-},{}],11:[function(_dereq_,module,exports){
+},{}],12:[function(_dereq_,module,exports){
var NoTabs;
module.exports = NoTabs = (function() {
function NoTabs() {}
@@ -1071,35 +1206,35 @@
return NoTabs;
})();
-},{}],12:[function(_dereq_,module,exports){
+},{}],13:[function(_dereq_,module,exports){
var DuplicateKey;
module.exports = DuplicateKey = (function() {
DuplicateKey.prototype.rule = {
name: 'duplicate_key',
level: 'error',
message: 'Duplicate key defined in object or class',
description: "Prevents defining duplicate keys in object literals and classes"
};
- DuplicateKey.prototype.tokens = ['IDENTIFIER', "{", "}"];
+ DuplicateKey.prototype.tokens = ['IDENTIFIER', '{', '}'];
function DuplicateKey() {
this.braceScopes = [];
}
DuplicateKey.prototype.lintToken = function(_arg, tokenApi) {
var type;
type = _arg[0];
- if (type === "{" || type === "}") {
+ if (type === '{' || type === '}') {
this.lintBrace.apply(this, arguments);
return void 0;
}
- if (type === "IDENTIFIER") {
+ if (type === 'IDENTIFIER') {
return this.lintIdentifier.apply(this, arguments);
}
};
DuplicateKey.prototype.lintIdentifier = function(token, tokenApi) {
@@ -1140,11 +1275,11 @@
return DuplicateKey;
})();
-},{}],13:[function(_dereq_,module,exports){
+},{}],14:[function(_dereq_,module,exports){
var EmptyConstructorNeedsParens;
module.exports = EmptyConstructorNeedsParens = (function() {
function EmptyConstructorNeedsParens() {}
@@ -1187,11 +1322,11 @@
return EmptyConstructorNeedsParens;
})();
-},{}],14:[function(_dereq_,module,exports){
+},{}],15:[function(_dereq_,module,exports){
var Indentation;
module.exports = Indentation = (function() {
Indentation.prototype.rule = {
name: 'indentation',
@@ -1199,46 +1334,43 @@
level: 'error',
message: 'Line contains inconsistent indentation',
description: "This rule imposes a standard number of spaces to be used for\nindentation. Since whitespace is significant in CoffeeScript, it's\ncritical that a project chooses a standard indentation format and\nstays consistent. Other roads lead to darkness. <pre> <code>#\nEnabling this option will prevent this ugly\n# but otherwise valid CoffeeScript.\ntwoSpaces = () ->\n fourSpaces = () ->\n eightSpaces = () ->\n 'this is valid CoffeeScript'\n\n</code>\n</pre>\nTwo space indentation is enabled by default."
};
- Indentation.prototype.tokens = ['INDENT', "[", "]"];
+ Indentation.prototype.tokens = ['INDENT', '[', ']', '.'];
function Indentation() {
this.arrayTokens = [];
}
Indentation.prototype.lintToken = function(token, tokenApi) {
- var currentLine, expected, ignoreIndent, isArrayIndent, isInterpIndent, isMultiline, lineNumber, lines, numIndents, prevNum, previous, previousIndentation, previousLine, previousSymbol, type, _ref;
- type = token[0], numIndents = token[1], lineNumber = token[2];
- if (type === "[" || type === "]") {
+ var currentLine, expected, ignoreIndent, isArrayIndent, isInterpIndent, isMultiline, lineNumber, lines, numIndents, previous, previousSymbol, type, _ref, _ref1, _ref2;
+ type = token[0], numIndents = token[1], (_ref = token[2], lineNumber = _ref.first_line);
+ lines = tokenApi.lines, lineNumber = tokenApi.lineNumber;
+ expected = tokenApi.config[this.rule.name].value;
+ if (type === '.') {
+ currentLine = lines[lineNumber];
+ if (((_ref1 = currentLine.match(/\S/i)) != null ? _ref1[0] : void 0) === '.') {
+ return this.handleChain(tokenApi, expected);
+ }
+ return void 0;
+ }
+ if (type === '[' || type === ']') {
this.lintArray(token);
return void 0;
}
if (token.generated != null) {
return null;
}
previous = tokenApi.peek(-2);
isInterpIndent = previous && previous[0] === '+';
previous = tokenApi.peek(-1);
isArrayIndent = this.inArray() && (previous != null ? previous.newLine : void 0);
- previousSymbol = (_ref = tokenApi.peek(-1)) != null ? _ref[0] : void 0;
+ previousSymbol = (_ref2 = tokenApi.peek(-1)) != null ? _ref2[0] : void 0;
isMultiline = previousSymbol === '=' || previousSymbol === ',';
ignoreIndent = isInterpIndent || isArrayIndent || isMultiline;
- if (this.isChainedCall(tokenApi)) {
- lines = tokenApi.lines, lineNumber = tokenApi.lineNumber;
- currentLine = lines[lineNumber];
- prevNum = 1;
- while (/^\s*(#|$)/.test(lines[lineNumber - prevNum])) {
- prevNum += 1;
- }
- previousLine = lines[lineNumber - prevNum];
- previousIndentation = previousLine.match(/^(\s*)/)[1].length;
- numIndents = currentLine.match(/^(\s*)/)[1].length;
- numIndents -= previousIndentation;
- }
- expected = tokenApi.config[this.rule.name].value;
+ numIndents = this.getCorrectIndent(tokenApi);
if (!ignoreIndent && numIndents !== expected) {
return {
context: "Expected " + expected + " got " + numIndents
};
}
@@ -1255,49 +1387,70 @@
this.arrayTokens.pop();
}
return null;
};
- Indentation.prototype.isChainedCall = function(tokenApi) {
- var i, lastNewLineIndex, lines, t, token, tokens;
- tokens = tokenApi.tokens, i = tokenApi.i;
- lines = (function() {
- var _i, _len, _ref, _results;
- _ref = tokens.slice(0, +i + 1 || 9e9);
- _results = [];
- for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
- token = _ref[i];
- if (token.newLine != null) {
- _results.push(i);
- }
- }
- return _results;
- })();
- lastNewLineIndex = lines ? lines[lines.length - 2] : null;
- if (lastNewLineIndex == null) {
- return false;
+ Indentation.prototype.handleChain = function(tokenApi, expected) {
+ var callStart, checkNum, currIsIndent, currentLine, currentSpaces, findCallStart, lastCheck, lineNumber, lines, numIndents, prevIsIndent, prevLine, prevNum, prevSpaces, _ref, _ref1;
+ lastCheck = 1;
+ callStart = 1;
+ prevNum = 1;
+ lineNumber = tokenApi.lineNumber, lines = tokenApi.lines;
+ currentLine = lines[lineNumber];
+ findCallStart = tokenApi.peek(-callStart);
+ while (findCallStart && findCallStart[0] !== 'TERMINATOR') {
+ lastCheck = findCallStart[2].first_line;
+ callStart += 1;
+ findCallStart = tokenApi.peek(-callStart);
}
- tokens = [tokens[lastNewLineIndex], tokens[lastNewLineIndex + 1]];
- return !!((function() {
- var _i, _len, _results;
- _results = [];
- for (_i = 0, _len = tokens.length; _i < _len; _i++) {
- t = tokens[_i];
- if (t && t[0] === '.') {
- _results.push(t);
+ while ((lineNumber - prevNum > lastCheck) && !/^\s*\./.test(lines[lineNumber - prevNum])) {
+ prevNum += 1;
+ }
+ checkNum = lineNumber - prevNum;
+ if (checkNum >= 0) {
+ prevLine = lines[checkNum];
+ if (prevLine.match(/\S/i)[0] === '.' || checkNum === lastCheck) {
+ currentSpaces = (_ref = currentLine.match(/\S/i)) != null ? _ref.index : void 0;
+ prevSpaces = (_ref1 = prevLine.match(/\S/i)) != null ? _ref1.index : void 0;
+ numIndents = currentSpaces - prevSpaces;
+ prevIsIndent = prevSpaces % expected !== 0;
+ currIsIndent = currentSpaces % expected !== 0;
+ if (prevIsIndent && currIsIndent) {
+ numIndents = currentSpaces;
}
+ if (numIndents % expected !== 0) {
+ return {
+ context: "Expected " + expected + " got " + numIndents
+ };
+ }
}
- return _results;
- })()).length;
+ }
};
+ Indentation.prototype.getCorrectIndent = function(tokenApi) {
+ var curIndent, i, lineNumber, lines, prevIndent, prevLine, prevNum, tokens, _ref, _ref1, _ref2;
+ lineNumber = tokenApi.lineNumber, lines = tokenApi.lines, tokens = tokenApi.tokens, i = tokenApi.i;
+ curIndent = (_ref = lines[lineNumber].match(/\S/)) != null ? _ref.index : void 0;
+ prevNum = 1;
+ while (/^\s*(#|$)/.test(lines[lineNumber - prevNum])) {
+ prevNum += 1;
+ }
+ prevLine = lines[lineNumber - prevNum];
+ prevIndent = (_ref1 = prevLine.match(/^(\s*)\./)) != null ? _ref1[1].length : void 0;
+ if (prevIndent > 0) {
+ return curIndent - ((_ref2 = prevLine.match(/\S/)) != null ? _ref2.index : void 0);
+ } else {
+ return tokens[i][1];
+ }
+ };
+
return Indentation;
})();
-},{}],15:[function(_dereq_,module,exports){
+},{}],16:[function(_dereq_,module,exports){
var LineEndings;
module.exports = LineEndings = (function() {
function LineEndings() {}
@@ -1337,11 +1490,11 @@
return LineEndings;
})();
-},{}],16:[function(_dereq_,module,exports){
+},{}],17:[function(_dereq_,module,exports){
var MaxLineLength, regexes;
regexes = {
literateComment: /^\#\s/,
longUrlComment: /^\s*\#\s*http[^\s]+$/
@@ -1382,21 +1535,36 @@
return MaxLineLength;
})();
-},{}],17:[function(_dereq_,module,exports){
-var MissingFatArrows, any,
+},{}],18:[function(_dereq_,module,exports){
+var MissingFatArrows, any, containsButIsnt,
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
any = function(arr, test) {
return arr.reduce((function(res, elt) {
return res || test(elt);
}), false);
};
+containsButIsnt = function(node, nIsThis, nIsClass) {
+ var target;
+ target = void 0;
+ node.traverseChildren(false, function(n) {
+ if (nIsClass(n)) {
+ return false;
+ }
+ if (nIsThis(n)) {
+ target = n;
+ return false;
+ }
+ });
+ return target;
+};
+
module.exports = MissingFatArrows = (function() {
function MissingFatArrows() {
this.isFatArrowCode = __bind(this.isFatArrowCode, this);
this.isThis = __bind(this.isThis, this);
this.isObject = __bind(this.isObject, this);
@@ -1472,11 +1640,11 @@
MissingFatArrows.prototype.needsFatArrow = function(node) {
return this.isCode(node) && (any(node.params, (function(_this) {
return function(param) {
return param.contains(_this.isThis) != null;
};
- })(this)) || (node.body.contains(this.isThis) != null));
+ })(this)) || containsButIsnt(node.body, this.isThis, this.isClass));
};
MissingFatArrows.prototype.methodsOfClass = function(classNode) {
var bodyNodes, returnNode;
bodyNodes = classNode.body.expressions;
@@ -1493,11 +1661,11 @@
return MissingFatArrows;
})();
-},{}],18:[function(_dereq_,module,exports){
+},{}],19:[function(_dereq_,module,exports){
var NewlinesAfterClasses;
module.exports = NewlinesAfterClasses = (function() {
function NewlinesAfterClasses() {}
@@ -1528,11 +1696,11 @@
return NewlinesAfterClasses;
})();
-},{}],19:[function(_dereq_,module,exports){
+},{}],20:[function(_dereq_,module,exports){
var NoBackticks;
module.exports = NoBackticks = (function() {
function NoBackticks() {}
@@ -1552,11 +1720,11 @@
return NoBackticks;
})();
-},{}],20:[function(_dereq_,module,exports){
+},{}],21:[function(_dereq_,module,exports){
var NoDebugger;
module.exports = NoDebugger = (function() {
function NoDebugger() {}
@@ -1578,11 +1746,11 @@
return NoDebugger;
})();
-},{}],21:[function(_dereq_,module,exports){
+},{}],22:[function(_dereq_,module,exports){
var NoEmptyFunctions, isEmptyCode;
isEmptyCode = function(node, astApi) {
var nodeName;
nodeName = astApi.getNodeName(node);
@@ -1622,11 +1790,11 @@
return NoEmptyFunctions;
})();
-},{}],22:[function(_dereq_,module,exports){
+},{}],23:[function(_dereq_,module,exports){
var NoEmptyParamList;
module.exports = NoEmptyParamList = (function() {
function NoEmptyParamList() {}
@@ -1648,11 +1816,11 @@
return NoEmptyParamList;
})();
-},{}],23:[function(_dereq_,module,exports){
+},{}],24:[function(_dereq_,module,exports){
var NoImplicitBraces;
module.exports = NoImplicitBraces = (function() {
function NoImplicitBraces() {}
@@ -1697,11 +1865,11 @@
return NoImplicitBraces;
})();
-},{}],24:[function(_dereq_,module,exports){
+},{}],25:[function(_dereq_,module,exports){
var NoImplicitParens;
module.exports = NoImplicitParens = (function() {
function NoImplicitParens() {}
@@ -1711,25 +1879,25 @@
level: 'ignore',
message: 'Implicit parens are forbidden',
description: "This rule prohibits implicit parens on function calls.\n<pre>\n<code># Some folks don't like this style of coding.\nmyFunction a, b, c\n\n# And would rather it always be written like this:\nmyFunction(a, b, c)\n</code>\n</pre>\nImplicit parens are permitted by default, since their use is\nidiomatic CoffeeScript."
};
- NoImplicitParens.prototype.tokens = ["CALL_END"];
+ NoImplicitParens.prototype.tokens = ['CALL_END'];
NoImplicitParens.prototype.lintToken = function(token, tokenApi) {
var i, t;
if (token.generated) {
if (tokenApi.config[this.rule.name].strict !== false) {
return true;
} else {
i = -1;
while (true) {
t = tokenApi.peek(i);
- if ((t == null) || t[0] === 'CALL_START') {
+ if ((t == null) || (t[0] === 'CALL_START' && t.generated)) {
return true;
}
- if (t.newLine) {
+ if (t[2].first_line !== token[2].first_line) {
return null;
}
i -= 1;
}
}
@@ -1739,21 +1907,21 @@
return NoImplicitParens;
})();
-},{}],25:[function(_dereq_,module,exports){
+},{}],26:[function(_dereq_,module,exports){
var NoInterpolationInSingleQuotes;
module.exports = NoInterpolationInSingleQuotes = (function() {
function NoInterpolationInSingleQuotes() {}
NoInterpolationInSingleQuotes.prototype.rule = {
name: 'no_interpolation_in_single_quotes',
level: 'ignore',
message: 'Interpolation in single quoted strings is forbidden',
- description: 'This rule prohibits string interpolation in a single quoted string.\n<pre>\n<code># String interpolation in single quotes is not allowed:\nfoo = \'#{bar}\'\n\n# Double quotes is OK of course\nfoo = "#{bar}"\n</code>\n</pre>\nString interpolation in single quoted strings is permitted by \ndefault.'
+ description: 'This rule prohibits string interpolation in a single quoted string.\n<pre>\n<code># String interpolation in single quotes is not allowed:\nfoo = \'#{bar}\'\n\n# Double quotes is OK of course\nfoo = "#{bar}"\n</code>\n</pre>\nString interpolation in single quoted strings is permitted by\ndefault.'
};
NoInterpolationInSingleQuotes.prototype.tokens = ['STRING'];
NoInterpolationInSingleQuotes.prototype.lintToken = function(token, tokenApi) {
@@ -1766,11 +1934,11 @@
return NoInterpolationInSingleQuotes;
})();
-},{}],26:[function(_dereq_,module,exports){
+},{}],27:[function(_dereq_,module,exports){
var NoPlusPlus;
module.exports = NoPlusPlus = (function() {
function NoPlusPlus() {}
@@ -1792,11 +1960,11 @@
return NoPlusPlus;
})();
-},{}],27:[function(_dereq_,module,exports){
+},{}],28:[function(_dereq_,module,exports){
var NoStandAloneAt;
module.exports = NoStandAloneAt = (function() {
function NoStandAloneAt() {}
@@ -1805,11 +1973,11 @@
level: 'ignore',
message: '@ must not be used stand alone',
description: "This rule checks that no stand alone @ are in use, they are\ndiscouraged. Further information in CoffeScript issue <a\nhref=\"https://github.com/jashkenas/coffee-script/issues/1601\">\n#1601</a>"
};
- NoStandAloneAt.prototype.tokens = ["@"];
+ NoStandAloneAt.prototype.tokens = ['@'];
NoStandAloneAt.prototype.lintToken = function(token, tokenApi) {
var isDot, isIdentifier, isIndexStart, isValidProtoProperty, nextToken, protoProperty, spaced;
nextToken = tokenApi.peek();
spaced = token.spaced;
@@ -1828,11 +1996,11 @@
return NoStandAloneAt;
})();
-},{}],28:[function(_dereq_,module,exports){
+},{}],29:[function(_dereq_,module,exports){
var NoTabs, indentationRegex,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
indentationRegex = /\S/;
@@ -1859,11 +2027,11 @@
return NoTabs;
})();
-},{}],29:[function(_dereq_,module,exports){
+},{}],30:[function(_dereq_,module,exports){
var NoThrowingStrings;
module.exports = NoThrowingStrings = (function() {
function NoThrowingStrings() {}
@@ -1872,11 +2040,11 @@
level: 'error',
message: 'Throwing strings is forbidden',
description: "This rule forbids throwing string literals or interpolations. While\nJavaScript (and CoffeeScript by extension) allow any expression to\nbe thrown, it is best to only throw <a\nhref=\"https://developer.mozilla.org\n/en/JavaScript/Reference/Global_Objects/Error\"> Error</a> objects,\nbecause they contain valuable debugging information like the stack\ntrace. Because of JavaScript's dynamic nature, CoffeeLint cannot\nensure you are always throwing instances of <tt>Error</tt>. It will\nonly catch the simple but real case of throwing literal strings.\n<pre>\n<code># CoffeeLint will catch this:\nthrow \"i made a boo boo\"\n\n# ... but not this:\nthrow getSomeString()\n</code>\n</pre>\nThis rule is enabled by default."
};
- NoThrowingStrings.prototype.tokens = ["THROW"];
+ NoThrowingStrings.prototype.tokens = ['THROW'];
NoThrowingStrings.prototype.lintToken = function(token, tokenApi) {
var n1, n2, nextIsString, _ref;
_ref = [tokenApi.peek(), tokenApi.peek(2)], n1 = _ref[0], n2 = _ref[1];
nextIsString = n1[0] === 'STRING' || (n1[0] === '(' && n2[0] === 'STRING');
@@ -1886,12 +2054,13 @@
return NoThrowingStrings;
})();
-},{}],30:[function(_dereq_,module,exports){
+},{}],31:[function(_dereq_,module,exports){
var NoTrailingSemicolons, regexes,
+ __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
__slice = [].slice;
regexes = {
trailingSemicolon: /;\r?$/
};
@@ -1905,41 +2074,43 @@
message: 'Line contains a trailing semicolon',
description: "This rule prohibits trailing semicolons, since they are needless\ncruft in CoffeeScript.\n<pre>\n<code># This semicolon is meaningful.\nx = '1234'; console.log(x)\n\n# This semicolon is redundant.\nalert('end of line');\n</code>\n</pre>\nTrailing semicolons are forbidden by default."
};
NoTrailingSemicolons.prototype.lintLine = function(line, lineApi) {
- var endPos, first, hasNewLine, hasSemicolon, last, lineTokens, newLine, startCounter, startPos, _i, _ref;
+ var endPos, first, hasNewLine, hasSemicolon, last, lineTokens, newLine, startCounter, startPos, stopTokens, tokenLen, _i, _ref, _ref1;
lineTokens = lineApi.getLineTokens();
- if (lineTokens.length === 1 && ((_ref = lineTokens[0][0]) === 'TERMINATOR' || _ref === 'HERECOMMENT')) {
+ tokenLen = lineTokens.length;
+ stopTokens = ['TERMINATOR', 'HERECOMMENT'];
+ if (tokenLen === 1 && (_ref = lineTokens[0][0], __indexOf.call(stopTokens, _ref) >= 0)) {
return;
}
newLine = line;
- if (lineTokens.length > 1 && lineTokens[lineTokens.length - 1][0] === 'TERMINATOR') {
- startPos = lineTokens[lineTokens.length - 2][2].last_column + 1;
- endPos = lineTokens[lineTokens.length - 1][2].first_column;
+ if (tokenLen > 1 && lineTokens[tokenLen - 1][0] === 'TERMINATOR') {
+ startPos = lineTokens[tokenLen - 2][2].last_column + 1;
+ endPos = lineTokens[tokenLen - 1][2].first_column;
if (startPos !== endPos) {
startCounter = startPos;
- while (line[startCounter] !== "#" && startCounter < line.length) {
+ while (line[startCounter] !== '#' && startCounter < line.length) {
startCounter++;
}
newLine = line.substring(0, startCounter).replace(/\s*$/, '');
}
}
hasSemicolon = regexes.trailingSemicolon.test(newLine);
first = 2 <= lineTokens.length ? __slice.call(lineTokens, 0, _i = lineTokens.length - 1) : (_i = 0, []), last = lineTokens[_i++];
hasNewLine = last && (last.newLine != null);
- if (hasSemicolon && !hasNewLine && lineApi.lineHasToken() && last[0] !== 'STRING') {
+ if (hasSemicolon && !hasNewLine && lineApi.lineHasToken() && !((_ref1 = last[0]) === 'STRING' || _ref1 === 'IDENTIFIER' || _ref1 === 'CALL_END')) {
return true;
}
};
return NoTrailingSemicolons;
})();
-},{}],31:[function(_dereq_,module,exports){
+},{}],32:[function(_dereq_,module,exports){
var NoTrailingWhitespace, regexes;
regexes = {
trailingWhitespace: /[^\s]+[\t ]+\r?$/,
onlySpaces: /^[\t ]+\r?$/,
@@ -1998,47 +2169,99 @@
return NoTrailingWhitespace;
})();
-},{}],32:[function(_dereq_,module,exports){
+},{}],33:[function(_dereq_,module,exports){
var NoUnnecessaryDoubleQuotes;
module.exports = NoUnnecessaryDoubleQuotes = (function() {
- function NoUnnecessaryDoubleQuotes() {}
-
NoUnnecessaryDoubleQuotes.prototype.rule = {
name: 'no_unnecessary_double_quotes',
level: 'ignore',
message: 'Unnecessary double quotes are forbidden',
- description: 'This rule prohibits double quotes unless string interpolation is \nused or the string contains single quotes.\n<pre>\n<code># Double quotes are discouraged:\nfoo = "bar"\n\n# Unless string interpolation is used:\nfoo = "#{bar}baz"\n\n# Or they prevent cumbersome escaping:\nfoo = "I\'m just following the \'rules\'"\n</code>\n</pre>\nDouble quotes are permitted by default.'
+ description: 'This rule prohibits double quotes unless string interpolation is\nused or the string contains single quotes.\n<pre>\n<code># Double quotes are discouraged:\nfoo = "bar"\n\n# Unless string interpolation is used:\nfoo = "#{bar}baz"\n\n# Or they prevent cumbersome escaping:\nfoo = "I\'m just following the \'rules\'"\n</code>\n</pre>\nDouble quotes are permitted by default.'
};
+ function NoUnnecessaryDoubleQuotes() {
+ this.regexps = [];
+ }
+
NoUnnecessaryDoubleQuotes.prototype.tokens = ['STRING'];
NoUnnecessaryDoubleQuotes.prototype.lintToken = function(token, tokenApi) {
- var hasLegalConstructs, stringValue, tokenValue;
+ var e, hasLegalConstructs, i, notInBlock, s, stringValue, tokenValue;
tokenValue = token[1];
+ i = tokenApi.i;
stringValue = tokenValue.match(/^\"(.*)\"$/);
- if (!stringValue) {
+ if (this.regexps.length === 0) {
+ this.regexps = this.getBlockRegExps(tokenApi);
+ }
+ notInBlock = ((function() {
+ var _i, _len, _ref, _ref1, _results;
+ _ref = this.regexps;
+ _results = [];
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ _ref1 = _ref[_i], s = _ref1[0], e = _ref1[1];
+ if ((s < i && i < e)) {
+ _results.push(1);
+ }
+ }
+ return _results;
+ }).call(this)).length === 0;
+ if (!(stringValue && notInBlock)) {
return false;
}
hasLegalConstructs = this.isInterpolated(tokenApi) || this.containsSingleQuote(tokenValue);
return !hasLegalConstructs;
};
+ NoUnnecessaryDoubleQuotes.prototype.getBlockRegExps = function(tokenApi) {
+ var callEnds, col, curTok, i, idx, ii, lin, lines, regexps, t, tokens, _i, _j, _len, _len1, _ref;
+ lines = tokenApi.lines, tokens = tokenApi.tokens;
+ regexps = [];
+ for (i = _i = 0, _len = tokens.length; _i < _len; i = ++_i) {
+ t = tokens[i];
+ if (!(t[0] === 'IDENTIFIER' && t[1] === 'RegExp')) {
+ continue;
+ }
+ _ref = t[2], lin = _ref.first_line, col = _ref.first_column;
+ if (lines[lin].slice(col, +(col + 2) + 1 || 9e9) === "///") {
+ regexps.push([i, 0]);
+ }
+ }
+ for (idx = _j = 0, _len1 = regexps.length; _j < _len1; idx = ++_j) {
+ i = regexps[idx][0];
+ ii = 2;
+ callEnds = 1;
+ while (callEnds > 0 && (curTok = tokens[i + ii][0])) {
+ if (curTok === 'CALL_END') {
+ callEnds--;
+ }
+ if (curTok === 'CALL_START') {
+ callEnds++;
+ }
+ ii++;
+ }
+ regexps[idx][1] = i + ii - 1;
+ }
+ return regexps;
+ };
+
NoUnnecessaryDoubleQuotes.prototype.isInterpolated = function(tokenApi) {
- var currentIndex, i, isInterpolated, lineTokens, token, tokenName, _i, _ref;
- currentIndex = tokenApi.i;
+ var i, idx, isInterpolated, token, tokenName, _i, _ref;
+ idx = tokenApi.i;
isInterpolated = false;
- lineTokens = tokenApi.tokensByLine[tokenApi.lineNumber];
- for (i = _i = 1; 1 <= currentIndex ? _i <= currentIndex : _i >= currentIndex; i = 1 <= currentIndex ? ++_i : --_i) {
+ for (i = _i = 1; 1 <= idx ? _i <= idx : _i >= idx; i = 1 <= idx ? ++_i : --_i) {
token = tokenApi.peek(-i);
+ if (token == null) {
+ break;
+ }
tokenName = token[0];
if (tokenName === ')' && token.stringEnd) {
break;
- } else if (tokenName === '(' && ((_ref = token.origin) != null ? _ref[1] : void 0) === "string interpolation") {
+ } else if (tokenName === '(' && ((_ref = token.origin) != null ? _ref[1] : void 0) === 'string interpolation') {
isInterpolated = true;
break;
}
}
return isInterpolated;
@@ -2051,11 +2274,11 @@
return NoUnnecessaryDoubleQuotes;
})();
-},{}],33:[function(_dereq_,module,exports){
+},{}],34:[function(_dereq_,module,exports){
var NoUnnecessaryFatArrows, any,
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
any = function(arr, test) {
return arr.reduce((function(res, elt) {
@@ -2118,21 +2341,25 @@
return function(param) {
return param.contains(_this.isThis) != null;
};
})(this)) || (node.body.contains(this.isThis) != null) || (node.body.contains((function(_this) {
return function(child) {
- return _this.isFatArrowCode(child) && _this.needsFatArrow(child);
+ if (!_this.astApi.getNodeName(child)) {
+ return (child.isSuper != null) && child.isSuper;
+ } else {
+ return _this.isFatArrowCode(child) && _this.needsFatArrow(child);
+ }
};
})(this)) != null));
};
return NoUnnecessaryFatArrows;
})();
-},{}],34:[function(_dereq_,module,exports){
+},{}],35:[function(_dereq_,module,exports){
var NonEmptyConstructorNeedsParens, ParentClass,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
ParentClass = _dereq_('./empty_constructor_needs_parens.coffee');
@@ -2160,11 +2387,72 @@
return NonEmptyConstructorNeedsParens;
})(ParentClass);
-},{"./empty_constructor_needs_parens.coffee":13}],35:[function(_dereq_,module,exports){
+},{"./empty_constructor_needs_parens.coffee":14}],36:[function(_dereq_,module,exports){
+var RuleProcessor;
+
+module.exports = RuleProcessor = (function() {
+ function RuleProcessor() {}
+
+ RuleProcessor.prototype.rule = {
+ name: 'prefer_english_operator',
+ description: 'This rule prohibits &&, ||, ==, != and !.\nUse and, or, is, isnt, and not instead.\n!! for converting to a boolean is ignored.',
+ level: 'ignore',
+ doubleNotLevel: 'ignore',
+ message: 'Don\'t use &&, ||, ==, !=, or !'
+ };
+
+ RuleProcessor.prototype.tokens = ['COMPARE', 'UNARY_MATH', 'LOGIC'];
+
+ RuleProcessor.prototype.lintToken = function(token, tokenApi) {
+ var actual_token, config, context, first_column, last_column, level, line, _ref;
+ config = tokenApi.config[this.rule.name];
+ level = config.level;
+ _ref = token[2], first_column = _ref.first_column, last_column = _ref.last_column;
+ line = tokenApi.lines[tokenApi.lineNumber];
+ actual_token = line.slice(first_column, +last_column + 1 || 9e9);
+ context = (function() {
+ var _ref1, _ref2;
+ switch (actual_token) {
+ case '==':
+ return 'Replace "==" with "is"';
+ case '!=':
+ return 'Replace "!=" with "isnt"';
+ case '||':
+ return 'Replace "||" with "or"';
+ case '&&':
+ return 'Replace "&&" with "and"';
+ case '!':
+ if (((_ref1 = tokenApi.peek(1)) != null ? _ref1[0] : void 0) === 'UNARY_MATH') {
+ level = config.doubleNotLevel;
+ return '"?" is usually better than "!!"';
+ } else if (((_ref2 = tokenApi.peek(-1)) != null ? _ref2[0] : void 0) === 'UNARY_MATH') {
+ return void 0;
+ } else {
+ return 'Replace "!" with "not"';
+ }
+ break;
+ default:
+ return void 0;
+ }
+ })();
+ if (context != null) {
+ return {
+ level: level,
+ context: context
+ };
+ }
+ };
+
+ return RuleProcessor;
+
+})();
+
+
+},{}],37:[function(_dereq_,module,exports){
var SpaceOperators,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
module.exports = SpaceOperators = (function() {
SpaceOperators.prototype.rule = {
@@ -2172,29 +2460,29 @@
level: 'ignore',
message: 'Operators must be spaced properly',
description: "This rule enforces that operators have space around them."
};
- SpaceOperators.prototype.tokens = ["+", "-", "=", "**", "MATH", "COMPARE", "LOGIC", "COMPOUND_ASSIGN", "(", ")", "CALL_START", "CALL_END"];
+ SpaceOperators.prototype.tokens = ['+', '-', '=', '**', 'MATH', 'COMPARE', 'LOGIC', 'COMPOUND_ASSIGN', '(', ')', 'CALL_START', 'CALL_END'];
function SpaceOperators() {
this.callTokens = [];
this.parenTokens = [];
}
SpaceOperators.prototype.lintToken = function(_arg, tokenApi) {
var type;
type = _arg[0];
- if (type === "CALL_START" || type === "CALL_END") {
+ if (type === 'CALL_START' || type === 'CALL_END') {
this.lintCall.apply(this, arguments);
return void 0;
}
- if (type === "(" || type === ")") {
+ if (type === '(' || type === ')') {
this.lintParens.apply(this, arguments);
return void 0;
}
- if (type === "+" || type === "-") {
+ if (type === '+' || type === '-') {
return this.lintPlus.apply(this, arguments);
} else {
return this.lintMath.apply(this, arguments);
}
};
@@ -2205,20 +2493,22 @@
return null;
}
p = tokenApi.peek(-1);
unaries = ['TERMINATOR', '(', '=', '-', '+', ',', 'CALL_START', 'INDEX_START', '..', '...', 'COMPARE', 'IF', 'THROW', 'LOGIC', 'POST_IF', ':', '[', 'INDENT', 'COMPOUND_ASSIGN', 'RETURN', 'MATH', 'BY', 'LEADING_WHEN'];
isUnary = !p ? false : (_ref = p[0], __indexOf.call(unaries, _ref) >= 0);
- if ((isUnary && token.spaced) || (!isUnary && !token.spaced && !token.newLine)) {
+ if ((isUnary && token.spaced) || (!isUnary && !token.newLine && (!token.spaced || (p && !p.spaced)))) {
return {
context: token[1]
};
} else {
return null;
}
};
SpaceOperators.prototype.lintMath = function(token, tokenApi) {
- if (!token.spaced && !token.newLine) {
+ var p;
+ p = tokenApi.peek(-1);
+ if (!token.newLine && (!token.spaced || (p && !p.spaced))) {
return {
context: token[1]
};
} else {
return null;
\ No newline at end of file