coffeelint/lib/coffeelint.js in coffeelint-1.9.1 vs coffeelint/lib/coffeelint.js in coffeelint-1.10.0.pre.patch.1

- old
+ new

@@ -4,11 +4,11 @@ CoffeeLint Copyright (c) 2011 Matthew Perpick. CoffeeLint is freely distributable under the MIT license. */ -var ASTLinter, CoffeeScript, ERROR, ErrorReport, IGNORE, LexicalLinter, LineLinter, RULES, WARN, _rules, cache, coffeelint, defaults, difference, extend, hasSyntaxError, mergeDefaultConfig, nodeRequire, packageJSON, +var ASTLinter, CoffeeScript, ERROR, ErrorReport, IGNORE, LexicalLinter, LineLinter, RULES, WARN, _rules, cache, coffeelint, defaults, difference, extend, hasSyntaxError, mergeDefaultConfig, nodeRequire, packageJSON, sameJSON, 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; @@ -76,19 +76,70 @@ ASTLinter = require('./ast_linter.coffee'); cache = null; mergeDefaultConfig = function(userConfig) { - var config, rule, ruleConfig; + var config, rule, ruleConfig, ruleLoader; + try { + ruleLoader = nodeRequire('./ruleLoader'); + ruleLoader.loadFromConfig(coffeelint, userConfig); + } catch (_error) {} config = {}; + if (userConfig.coffeelint) { + config.coffeelint = userConfig.coffeelint; + } for (rule in RULES) { ruleConfig = RULES[rule]; config[rule] = defaults(userConfig[rule], ruleConfig); } return config; }; +sameJSON = function(a, b) { + return JSON.stringify(a) === JSON.stringify(b); +}; + +coffeelint.trimConfig = function(userConfig) { + var config, dConfig, dValue, key, newConfig, ref, rule, value; + newConfig = {}; + userConfig = mergeDefaultConfig(userConfig); + for (rule in userConfig) { + config = userConfig[rule]; + dConfig = RULES[rule]; + if (rule === 'coffeelint') { + config.transforms = config._transforms; + delete config._transforms; + config.coffeescript = config._coffeescript; + delete config._coffeescript; + newConfig[rule] = config; + } else if ((config.level === (ref = dConfig.level) && ref === 'ignore')) { + void 0; + } else if (config.level === 'ignore') { + newConfig[rule] = { + level: 'ignore' + }; + } else { + config.module = config._module; + delete config._module; + for (key in config) { + value = config[key]; + if (key === 'message' || key === 'description' || key === 'name') { + continue; + } + dValue = dConfig[key]; + if (value !== dValue && !sameJSON(value, dValue)) { + if (newConfig[rule] == null) { + newConfig[rule] = {}; + } + newConfig[rule][key] = value; + } + } + } + } + return newConfig; +}; + coffeelint.invertLiterate = function(source) { var len, line, n, newSource, ref; source = CoffeeScript.helpers.invertLiterate(source); newSource = ""; ref = source.split("\n"); @@ -219,10 +270,14 @@ coffeelint.registerRule(require('./rules/transform_messes_up_line_numbers.coffee')); coffeelint.registerRule(require('./rules/ensure_comprehensions.coffee')); +coffeelint.registerRule(require('./rules/no_this.coffee')); + +coffeelint.registerRule(require('./rules/eol_last.coffee')); + hasSyntaxError = function(source) { try { CoffeeScript.tokens(source); return false; } catch (_error) {} @@ -242,14 +297,10 @@ } if (literate == null) { literate = false; } errors = []; - 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; @@ -261,19 +312,21 @@ if ((userConfig != null ? (ref = userConfig.coffeelint) != null ? ref.transforms : void 0 : void 0) != null) { sourceLength = source.split("\n").length; ref2 = userConfig != null ? (ref1 = userConfig.coffeelint) != null ? ref1.transforms : void 0 : void 0; for (n = 0, len = ref2.length; n < len; n++) { m = ref2[n]; - transform = ruleLoader.require(m); - source = transform(source); + try { + ruleLoader = nodeRequire('./ruleLoader'); + transform = ruleLoader.require(m); + source = transform(source); + } catch (_error) {} } if (sourceLength !== source.split("\n").length && config.transform_messes_up_line_numbers.level !== 'ignore') { errors.push(extend({ lineNumber: 1, context: "File was transformed from " + sourceLength + " lines to " + (source.split("\n").length) + " lines" }, config.transform_messes_up_line_numbers)); - console.log(errors); } } if ((userConfig != null ? (ref3 = userConfig.coffeelint) != null ? ref3.coffeescript : void 0 : void 0) != null) { CoffeeScript = ruleLoader.require(userConfig.coffeelint.coffeescript); } @@ -366,15 +419,15 @@ return cache = obj; }; -},{"./../package.json":2,"./ast_linter.coffee":3,"./error_report.coffee":5,"./lexical_linter.coffee":6,"./line_linter.coffee":7,"./rules.coffee":8,"./rules/arrow_spacing.coffee":9,"./rules/braces_spacing.coffee":10,"./rules/camel_case_classes.coffee":11,"./rules/colon_assignment_spacing.coffee":12,"./rules/cyclomatic_complexity.coffee":13,"./rules/duplicate_key.coffee":14,"./rules/empty_constructor_needs_parens.coffee":15,"./rules/ensure_comprehensions.coffee":16,"./rules/indentation.coffee":17,"./rules/line_endings.coffee":18,"./rules/max_line_length.coffee":19,"./rules/missing_fat_arrows.coffee":20,"./rules/newlines_after_classes.coffee":21,"./rules/no_backticks.coffee":22,"./rules/no_debugger.coffee":23,"./rules/no_empty_functions.coffee":24,"./rules/no_empty_param_list.coffee":25,"./rules/no_implicit_braces.coffee":26,"./rules/no_implicit_parens.coffee":27,"./rules/no_interpolation_in_single_quotes.coffee":28,"./rules/no_plusplus.coffee":29,"./rules/no_stand_alone_at.coffee":30,"./rules/no_tabs.coffee":31,"./rules/no_throwing_strings.coffee":32,"./rules/no_trailing_semicolons.coffee":33,"./rules/no_trailing_whitespace.coffee":34,"./rules/no_unnecessary_double_quotes.coffee":35,"./rules/no_unnecessary_fat_arrows.coffee":36,"./rules/non_empty_constructor_needs_parens.coffee":37,"./rules/prefer_english_operator.coffee":38,"./rules/space_operators.coffee":39,"./rules/spacing_after_comma.coffee":40,"./rules/transform_messes_up_line_numbers.coffee":41}],2:[function(require,module,exports){ +},{"./../package.json":2,"./ast_linter.coffee":3,"./error_report.coffee":5,"./lexical_linter.coffee":6,"./line_linter.coffee":7,"./rules.coffee":8,"./rules/arrow_spacing.coffee":9,"./rules/braces_spacing.coffee":10,"./rules/camel_case_classes.coffee":11,"./rules/colon_assignment_spacing.coffee":12,"./rules/cyclomatic_complexity.coffee":13,"./rules/duplicate_key.coffee":14,"./rules/empty_constructor_needs_parens.coffee":15,"./rules/ensure_comprehensions.coffee":16,"./rules/eol_last.coffee":17,"./rules/indentation.coffee":18,"./rules/line_endings.coffee":19,"./rules/max_line_length.coffee":20,"./rules/missing_fat_arrows.coffee":21,"./rules/newlines_after_classes.coffee":22,"./rules/no_backticks.coffee":23,"./rules/no_debugger.coffee":24,"./rules/no_empty_functions.coffee":25,"./rules/no_empty_param_list.coffee":26,"./rules/no_implicit_braces.coffee":27,"./rules/no_implicit_parens.coffee":28,"./rules/no_interpolation_in_single_quotes.coffee":29,"./rules/no_plusplus.coffee":30,"./rules/no_stand_alone_at.coffee":31,"./rules/no_tabs.coffee":32,"./rules/no_this.coffee":33,"./rules/no_throwing_strings.coffee":34,"./rules/no_trailing_semicolons.coffee":35,"./rules/no_trailing_whitespace.coffee":36,"./rules/no_unnecessary_double_quotes.coffee":37,"./rules/no_unnecessary_fat_arrows.coffee":38,"./rules/non_empty_constructor_needs_parens.coffee":39,"./rules/prefer_english_operator.coffee":40,"./rules/space_operators.coffee":41,"./rules/spacing_after_comma.coffee":42,"./rules/transform_messes_up_line_numbers.coffee":43}],2:[function(require,module,exports){ module.exports={ "name": "coffeelint", "description": "Lint your CoffeeScript", - "version": "1.9.1", + "version": "1.10.0", "homepage": "http://www.coffeelint.org", "keywords": [ "lint", "coffeescript", "coffee-script" @@ -397,25 +450,22 @@ "coffee-script": "^1.9.1", "coffeeify": "~1.0.0", "glob": "^4.0.0", "ignore": "^2.2.15", "optimist": "^0.6.1", - "resolve": "^0.6.3" + "resolve": "^0.6.3", + "strip-json-comments": "^1.0.2" }, "devDependencies": { "vows": ">=0.6.0", "underscore": ">=1.4.4" }, - "licenses": [ - { - "type": "MIT", - "url": "http://github.com/clutchski/coffeelint/raw/master/LICENSE" - } - ], + "license": "MIT", "scripts": { "pretest": "cake compile", "test": "./vowsrunner.js --spec test/*.coffee test/*.litcoffee", + "testrule": "npm run compile && ./vowsrunner.js --spec", "posttest": "npm run lint", "prepublish": "cake prepublish", "publish": "cake publish", "install": "cake install", "lint": "cake compile && ./bin/coffeelint .", @@ -1051,15 +1101,15 @@ function ArrowSpacing() {} ArrowSpacing.prototype.rule = { name: 'arrow_spacing', level: 'ignore', - message: 'Function arrow (->) must be spaced properly', + message: 'Function arrows (-> and =>) must be spaced properly', description: "<p>This rule checks to see that there is spacing before and after\nthe arrow operator that declares a function. This rule is disabled\nby default.</p> <p>Note that if arrow_spacing is enabled, and you\npass an empty function as a parameter, arrow_spacing will accept\neither a space or no space in-between the arrow operator and the\nparenthesis</p>\n<pre><code># Both of this will not trigger an error,\n# even with arrow_spacing enabled.\nx(-> 3)\nx( -> 3)\n\n# However, this will trigger an error\nx((a,b)-> 3)\n</code>\n</pre>" }; - ArrowSpacing.prototype.tokens = ['->']; + ArrowSpacing.prototype.tokens = ['->', '=>']; ArrowSpacing.prototype.lintToken = function(token, tokenApi) { var pp; pp = tokenApi.peek(-1); if (!token.spaced && (pp[1] === "(" && (pp.generated == null)) && tokenApi.peek(1)[0] === 'INDENT' && tokenApi.peek(2)[0] === 'OUTDENT') { @@ -1098,12 +1148,13 @@ BracesSpacing.prototype.rule = { name: 'braces_spacing', level: 'ignore', spaces: 0, + empty_object_spaces: 0, message: 'Curly braces must have the proper spacing', - description: 'This rule checks to see that there is the proper spacing inside\ncurly braces. The spacing amount is specified by "spaces".\n\n<pre><code>\n# Spaces is 0\n{a: b} # Good\n{a: b } # Bad\n{ a: b} # Bad\n{ a: b } # Bad\n\n# Spaces is 1\n{a: b} # Bad\n{a: b } # Bad\n{ a: b} # Bad\n{ a: b } # Good\n{ a: b } # Bad\n{ a: b } # Bad\n{ a: b } # Bad\n</code></pre>\n\nThis rule is disabled by default.' + description: 'This rule checks to see that there is the proper spacing inside\ncurly braces. The spacing amount is specified by "spaces".\nThe spacing amount for empty objects is specified by\n"empty_object_spaces".\n\n<pre><code>\n# Spaces is 0\n{a: b} # Good\n{a: b } # Bad\n{ a: b} # Bad\n{ a: b } # Bad\n\n# Spaces is 1\n{a: b} # Bad\n{a: b } # Bad\n{ a: b} # Bad\n{ a: b } # Good\n{ a: b } # Bad\n{ a: b } # Bad\n{ a: b } # Bad\n\n# Empty Object Spaces is 0\n{} # Good\n{ } # Bad\n\n# Empty Object Spaces is 1\n{} # Bad\n{ } # Good\n</code></pre>\n\nThis rule is disabled by default.' }; BracesSpacing.prototype.tokens = ['{', '}']; BracesSpacing.prototype.distanceBetweenTokens = function(firstToken, secondToken) { @@ -1125,20 +1176,30 @@ BracesSpacing.prototype.tokensOnSameLine = function(firstToken, secondToken) { return firstToken[2].first_line === secondToken[2].first_line; }; + BracesSpacing.prototype.getExpectedSpaces = function(tokenApi, firstToken, secondToken) { + var config, ref; + config = tokenApi.config[this.rule.name]; + if (firstToken[0] === '{' && secondToken[0] === '}') { + return (ref = config.empty_object_spaces) != null ? ref : config.spaces; + } else { + return config.spaces; + } + }; + BracesSpacing.prototype.lintToken = function(token, tokenApi) { var actual, expected, firstToken, msg, ref, secondToken; if (token.generated) { return null; } ref = token[0] === '{' ? [token, this.findNearestToken(token, tokenApi, 1)] : [this.findNearestToken(token, tokenApi, -1), token], firstToken = ref[0], secondToken = ref[1]; if (!this.tokensOnSameLine(firstToken, secondToken)) { return null; } - expected = tokenApi.config[this.rule.name].spaces; + expected = this.getExpectedSpaces(tokenApi, firstToken, secondToken); actual = this.distanceBetweenTokens(firstToken, secondToken); if (actual === expected) { return null; } else { msg = "There should be " + expected + " space"; @@ -1160,21 +1221,21 @@ },{}],11:[function(require,module,exports){ var CamelCaseClasses, regexes; regexes = { - camelCase: /^[A-Z][a-zA-Z\d]*$/ + camelCase: /^[A-Z_][a-zA-Z\d]*$/ }; module.exports = CamelCaseClasses = (function() { function CamelCaseClasses() {} CamelCaseClasses.prototype.rule = { name: 'camel_case_classes', level: 'error', - message: 'Class names should be camel cased', - description: "This rule mandates that all class names are CamelCased. Camel\ncasing class names is a generally accepted way of distinguishing\nconstructor functions - which require the 'new' prefix to behave\nproperly - from plain old functions.\n<pre>\n<code># Good!\nclass BoaConstrictor\n\n# Bad!\nclass boaConstrictor\n</code>\n</pre>\nThis rule is enabled by default." + message: 'Class name should be UpperCamelCased', + description: "This rule mandates that all class names are UpperCamelCased.\nCamel casing class names is a generally accepted way of\ndistinguishing constructor functions - which require the 'new'\nprefix to behave properly - from plain old functions.\n<pre>\n<code># Good!\nclass BoaConstrictor\n\n# Bad!\nclass boaConstrictor\n</code>\n</pre>\nThis rule is enabled by default." }; CamelCaseClasses.prototype.tokens = ['CLASS']; CamelCaseClasses.prototype.lintToken = function(token, tokenApi) { @@ -1405,21 +1466,28 @@ }; EmptyConstructorNeedsParens.prototype.tokens = ['UNARY']; EmptyConstructorNeedsParens.prototype.lintToken = function(token, tokenApi) { - var expectedCallStart, expectedIdentifier, identifierIndex; + var expectedCallStart, expectedIdentifier, identifierIndex, peek, ref; if (token[1] === 'new') { + peek = tokenApi.peek.bind(tokenApi); identifierIndex = 1; while (true) { - expectedIdentifier = tokenApi.peek(identifierIndex); - expectedCallStart = tokenApi.peek(identifierIndex + 1); + expectedIdentifier = peek(identifierIndex); + expectedCallStart = peek(identifierIndex + 1); if ((expectedIdentifier != null ? expectedIdentifier[0] : void 0) === 'IDENTIFIER') { if ((expectedCallStart != null ? expectedCallStart[0] : void 0) === '.') { identifierIndex += 2; continue; } + if ((expectedCallStart != null ? expectedCallStart[0] : void 0) === 'INDEX_START') { + while (((ref = peek(identifierIndex)) != null ? ref[0] : void 0) !== 'INDEX_END') { + identifierIndex++; + } + continue; + } } break; } if ((expectedIdentifier != null ? expectedIdentifier[0] : void 0) === 'IDENTIFIER' && (expectedCallStart != null)) { return this.handleExpectedCallStart(expectedCallStart); @@ -1505,10 +1573,38 @@ })(); },{}],17:[function(require,module,exports){ +var EOLLast; + +module.exports = EOLLast = (function() { + function EOLLast() {} + + EOLLast.prototype.rule = { + name: 'eol_last', + level: 'ignore', + message: 'File does not end with a single newline', + description: "Checks that the file ends with a single newline" + }; + + EOLLast.prototype.lintLine = function(line, lineApi) { + if (!lineApi.isLastLine()) { + return null; + } + if (line.length) { + return true; + } + }; + + return EOLLast; + +})(); + + + +},{}],18:[function(require,module,exports){ var Indentation; module.exports = Indentation = (function() { Indentation.prototype.rule = { name: 'indentation', @@ -1629,11 +1725,11 @@ })(); -},{}],18:[function(require,module,exports){ +},{}],19:[function(require,module,exports){ var LineEndings; module.exports = LineEndings = (function() { function LineEndings() {} @@ -1674,11 +1770,11 @@ })(); -},{}],19:[function(require,module,exports){ +},{}],20:[function(require,module,exports){ var MaxLineLength, regexes; regexes = { literateComment: /^\#\s/, longUrlComment: /^\s*\#\s*http[^\s]+$/ @@ -1698,11 +1794,11 @@ MaxLineLength.prototype.lintLine = function(line, lineApi) { var limitComments, lineLength, max, ref, ref1; max = (ref = lineApi.config[this.rule.name]) != null ? ref.value : void 0; limitComments = (ref1 = lineApi.config[this.rule.name]) != null ? ref1.limitComments : void 0; - lineLength = line.trimRight().length; + lineLength = line.replace(/\s+$/, '').length; if (lineApi.isLiterate() && regexes.literateComment.test(line)) { lineLength -= 2; } if (max && max < lineLength && !regexes.longUrlComment.test(line)) { if (!limitComments) { @@ -1720,11 +1816,11 @@ })(); -},{}],20:[function(require,module,exports){ +},{}],21:[function(require,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) { @@ -1759,26 +1855,31 @@ } MissingFatArrows.prototype.rule = { name: 'missing_fat_arrows', level: 'ignore', + is_strict: false, message: 'Used `this` in a function without a fat arrow', - description: "Warns when you use `this` inside a function that wasn't defined\nwith a fat arrow. This rule does not apply to methods defined in a\nclass, since they have `this` bound to the class instance (or the\nclass itself, for class methods).\n\nIt is impossible to statically determine whether a function using\n`this` will be bound with the correct `this` value due to language\nfeatures like `Function.prototype.call` and\n`Function.prototype.bind`, so this rule may produce false positives." + description: "Warns when you use `this` inside a function that wasn't defined\nwith a fat arrow. This rule does not apply to methods defined in a\nclass, since they have `this` bound to the class instance (or the\nclass itself, for class methods). The option `is_strict` is\navailable for checking bindings of class methods.\n\nIt is impossible to statically determine whether a function using\n`this` will be bound with the correct `this` value due to language\nfeatures like `Function.prototype.call` and\n`Function.prototype.bind`, so this rule may produce false positives." }; MissingFatArrows.prototype.lintAST = function(node, astApi) { this.astApi = astApi; this.lintNode(node); return void 0; }; MissingFatArrows.prototype.lintNode = function(node, methods) { - var error; + var error, is_strict, ref; if (methods == null) { methods = []; } - if ((!this.isFatArrowCode(node)) && (indexOf.call(methods, node) < 0) && (this.needsFatArrow(node))) { + is_strict = (ref = this.astApi.config[this.rule.name]) != null ? ref.is_strict : void 0; + if (this.isConstructor(node)) { + return; + } + if ((!this.isFatArrowCode(node)) && (is_strict ? true : indexOf.call(methods, node) < 0) && (this.needsFatArrow(node))) { error = this.astApi.createError({ lineNumber: node.locationData.first_line + 1 }); this.errors.push(error); } @@ -1820,10 +1921,15 @@ MissingFatArrows.prototype.isFatArrowCode = function(node) { return this.isCode(node) && node.bound; }; + MissingFatArrows.prototype.isConstructor = function(node) { + var ref, ref1; + return ((ref = node.variable) != null ? (ref1 = ref.base) != null ? ref1.value : void 0 : void 0) === 'constructor'; + }; + MissingFatArrows.prototype.needsFatArrow = function(node) { return this.isCode(node) && (any(node.params, (function(_this) { return function(param) { return param.contains(_this.isThis) != null; }; @@ -1847,22 +1953,22 @@ })(); -},{}],21:[function(require,module,exports){ +},{}],22:[function(require,module,exports){ var NewlinesAfterClasses; module.exports = NewlinesAfterClasses = (function() { function NewlinesAfterClasses() {} NewlinesAfterClasses.prototype.rule = { name: 'newlines_after_classes', value: 3, level: 'ignore', message: 'Wrong count of newlines between a class and other code', - description: "Checks the number of newlines between classes and other code" + description: "<p>Checks the number of newlines between classes and other code.</p>\n\nOptions:\n- <pre><code>value</code></pre> - The number of required newlines\nafter class definitions. Defaults to 3." }; NewlinesAfterClasses.prototype.lintLine = function(line, lineApi) { var context, ending, got, lineNumber; ending = lineApi.config[this.rule.name].value; @@ -1883,11 +1989,11 @@ })(); -},{}],22:[function(require,module,exports){ +},{}],23:[function(require,module,exports){ var NoBackticks; module.exports = NoBackticks = (function() { function NoBackticks() {} @@ -1908,38 +2014,50 @@ })(); -},{}],23:[function(require,module,exports){ +},{}],24:[function(require,module,exports){ var NoDebugger; module.exports = NoDebugger = (function() { function NoDebugger() {} NoDebugger.prototype.rule = { name: 'no_debugger', level: 'warn', - message: 'Debugger statements will cause warnings', - description: "This rule detects the `debugger` statement.\nThis rule is `warn` by default." + message: 'Found debugging code', + console: false, + description: "This rule detects `debugger` and optionally `console` calls\nThis rule is `warn` by default." }; - NoDebugger.prototype.tokens = ["DEBUGGER"]; + NoDebugger.prototype.tokens = ["DEBUGGER", "IDENTIFIER"]; NoDebugger.prototype.lintToken = function(token, tokenApi) { - return { - context: "found '" + token[0] + "'" - }; + var method, ref, ref1; + if (token[0] === 'DEBUGGER') { + return { + context: "found '" + token[0] + "'" + }; + } + if ((ref = tokenApi.config[this.rule.name]) != null ? ref.console : void 0) { + if (token[1] === 'console' && ((ref1 = tokenApi.peek(1)) != null ? ref1[0] : void 0) === '.') { + method = tokenApi.peek(2); + return { + context: "found 'console." + method[1] + "'" + }; + } + } }; return NoDebugger; })(); -},{}],24:[function(require,module,exports){ +},{}],25:[function(require,module,exports){ var NoEmptyFunctions, isEmptyCode; isEmptyCode = function(node, astApi) { var nodeName; nodeName = astApi.getNodeName(node); @@ -1980,11 +2098,11 @@ })(); -},{}],25:[function(require,module,exports){ +},{}],26:[function(require,module,exports){ var NoEmptyParamList; module.exports = NoEmptyParamList = (function() { function NoEmptyParamList() {} @@ -2007,11 +2125,11 @@ })(); -},{}],26:[function(require,module,exports){ +},{}],27:[function(require,module,exports){ var NoImplicitBraces; module.exports = NoImplicitBraces = (function() { NoImplicitBraces.prototype.rule = { name: 'no_implicit_braces', @@ -2067,11 +2185,11 @@ })(); -},{}],27:[function(require,module,exports){ +},{}],28:[function(require,module,exports){ var NoImplicitParens; module.exports = NoImplicitParens = (function() { function NoImplicitParens() {} @@ -2110,11 +2228,11 @@ })(); -},{}],28:[function(require,module,exports){ +},{}],29:[function(require,module,exports){ var NoInterpolationInSingleQuotes; module.exports = NoInterpolationInSingleQuotes = (function() { function NoInterpolationInSingleQuotes() {} @@ -2128,21 +2246,21 @@ NoInterpolationInSingleQuotes.prototype.tokens = ['STRING']; NoInterpolationInSingleQuotes.prototype.lintToken = function(token, tokenApi) { var hasInterpolation, tokenValue; tokenValue = token[1]; - hasInterpolation = tokenValue.match(/#\{[^}]+\}/); + hasInterpolation = tokenValue.match(/^\'.*#\{[^}]+\}.*\'$/); return hasInterpolation; }; return NoInterpolationInSingleQuotes; })(); -},{}],29:[function(require,module,exports){ +},{}],30:[function(require,module,exports){ var NoPlusPlus; module.exports = NoPlusPlus = (function() { function NoPlusPlus() {} @@ -2165,11 +2283,11 @@ })(); -},{}],30:[function(require,module,exports){ +},{}],31:[function(require,module,exports){ var NoStandAloneAt; module.exports = NoStandAloneAt = (function() { function NoStandAloneAt() {} @@ -2202,11 +2320,11 @@ })(); -},{}],31:[function(require,module,exports){ +},{}],32:[function(require,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/; @@ -2234,11 +2352,36 @@ })(); -},{}],32:[function(require,module,exports){ +},{}],33:[function(require,module,exports){ +var NoThis; + +module.exports = NoThis = (function() { + function NoThis() {} + + NoThis.prototype.rule = { + name: 'no_this', + description: 'This rule prohibits \'this\'.\nUse \'@\' instead.', + level: 'ignore', + message: "Don't use 'this', use '@' instead" + }; + + NoThis.prototype.tokens = ['THIS']; + + NoThis.prototype.lintToken = function(token, tokenApi) { + return true; + }; + + return NoThis; + +})(); + + + +},{}],34:[function(require,module,exports){ var NoThrowingStrings; module.exports = NoThrowingStrings = (function() { function NoThrowingStrings() {} @@ -2262,11 +2405,11 @@ })(); -},{}],33:[function(require,module,exports){ +},{}],35:[function(require,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 = { @@ -2315,11 +2458,11 @@ })(); -},{}],34:[function(require,module,exports){ +},{}],36:[function(require,module,exports){ var NoTrailingWhitespace, regexes; regexes = { trailingWhitespace: /[^\s]+[\t ]+\r?$/, onlySpaces: /^[\t ]+\r?$/, @@ -2379,11 +2522,11 @@ })(); -},{}],35:[function(require,module,exports){ +},{}],37:[function(require,module,exports){ var NoUnnecessaryDoubleQuotes; module.exports = NoUnnecessaryDoubleQuotes = (function() { NoUnnecessaryDoubleQuotes.prototype.rule = { name: 'no_unnecessary_double_quotes', @@ -2398,19 +2541,22 @@ } NoUnnecessaryDoubleQuotes.prototype.tokens = ['STRING', 'STRING_START', 'STRING_END']; NoUnnecessaryDoubleQuotes.prototype.lintToken = function(token, tokenApi) { - var hasLegalConstructs, stringValue, tokenValue, type; + var hasLegalConstructs, ref, stringValue, tokenValue, type; type = token[0], tokenValue = token[1]; if (type === 'STRING_START' || type === 'STRING_END') { return this.trackParens.apply(this, arguments); } stringValue = tokenValue.match(/^\"(.*)\"$/); if (!stringValue) { return false; } + if (((ref = tokenApi.peek(2)) != null ? ref[0] : void 0) === 'REGEX_END') { + return false; + } hasLegalConstructs = this.isInterpolation || this.hasSingleQuote(tokenValue); return !hasLegalConstructs; }; NoUnnecessaryDoubleQuotes.prototype.trackParens = function(token, tokenApi) { @@ -2430,11 +2576,11 @@ })(); -},{}],36:[function(require,module,exports){ +},{}],38:[function(require,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) { @@ -2512,11 +2658,11 @@ })(); -},{}],37:[function(require,module,exports){ +},{}],39:[function(require,module,exports){ var NonEmptyConstructorNeedsParens, ParentClass, extend = 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; }, hasProp = {}.hasOwnProperty; ParentClass = require('./empty_constructor_needs_parens.coffee'); @@ -2545,11 +2691,11 @@ })(ParentClass); -},{"./empty_constructor_needs_parens.coffee":15}],38:[function(require,module,exports){ +},{"./empty_constructor_needs_parens.coffee":15}],40:[function(require,module,exports){ var RuleProcessor; module.exports = RuleProcessor = (function() { function RuleProcessor() {} @@ -2607,11 +2753,11 @@ })(); -},{}],39:[function(require,module,exports){ +},{}],41:[function(require,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 = { @@ -2712,39 +2858,60 @@ })(); -},{}],40:[function(require,module,exports){ +},{}],42:[function(require,module,exports){ var RuleProcessor; module.exports = RuleProcessor = (function() { - function RuleProcessor() {} - RuleProcessor.prototype.rule = { name: 'spacing_after_comma', description: 'This rule requires a space after commas.', level: 'ignore', message: 'Spaces are required after commas' }; - RuleProcessor.prototype.tokens = [',']; + RuleProcessor.prototype.tokens = [',', 'REGEX_START', 'REGEX_END']; + function RuleProcessor() { + this.inRegex = false; + } + RuleProcessor.prototype.lintToken = function(token, tokenApi) { - if (!(token.spaced || token.newLine)) { + var type; + type = token[0]; + if (type === 'REGEX_START') { + this.inRegex = true; + return; + } + if (type === 'REGEX_END') { + this.inRegex = false; + return; + } + if (!(token.spaced || token.newLine || token.generated || this.isRegexFlag(token, tokenApi))) { return { context: token[1] }; } }; + RuleProcessor.prototype.isRegexFlag = function(token, tokenApi) { + var maybeEnd; + if (!this.inRegex) { + return false; + } + maybeEnd = tokenApi.peek(3); + return (maybeEnd != null ? maybeEnd[0] : void 0) === 'REGEX_END'; + }; + return RuleProcessor; })(); -},{}],41:[function(require,module,exports){ +},{}],43:[function(require,module,exports){ var CamelCaseClasses; module.exports = CamelCaseClasses = (function() { function CamelCaseClasses() {} \ No newline at end of file