UNPKG

104 kBJavaScriptView Raw
1!function(e){if("object"==typeof exports&&"undefined"!=typeof module)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);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.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(require,module,exports){
2
3/*
4CoffeeLint
5
6Copyright (c) 2011 Matthew Perpick.
7CoffeeLint is freely distributable under the MIT license.
8 */
9var ASTLinter, CoffeeScript, ERROR, ErrorReport, IGNORE, LexicalLinter, LineLinter, RULES, WARN, _rules, cache, coffeelint, defaults, difference, extend, hasSyntaxError, mergeDefaultConfig, nodeRequire, packageJSON, sameJSON,
10 slice = [].slice,
11 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; };
12
13coffeelint = exports;
14
15nodeRequire = require;
16
17if (typeof window !== "undefined" && window !== null) {
18 CoffeeScript = window.CoffeeScript;
19}
20
21if (CoffeeScript == null) {
22 CoffeeScript = nodeRequire('coffee-script');
23}
24
25if (CoffeeScript == null) {
26 throw new Error('Unable to find CoffeeScript');
27}
28
29packageJSON = require('./../package.json');
30
31coffeelint.VERSION = packageJSON.version;
32
33ERROR = 'error';
34
35WARN = 'warn';
36
37IGNORE = 'ignore';
38
39coffeelint.RULES = RULES = require('./rules.coffee');
40
41extend = function() {
42 var destination, k, len, n, source, sources, v;
43 destination = arguments[0], sources = 2 <= arguments.length ? slice.call(arguments, 1) : [];
44 for (n = 0, len = sources.length; n < len; n++) {
45 source = sources[n];
46 for (k in source) {
47 v = source[k];
48 destination[k] = v;
49 }
50 }
51 return destination;
52};
53
54defaults = function(source, defaults) {
55 return extend({}, defaults, source);
56};
57
58difference = function(a, b) {
59 var j, ref, results;
60 j = 0;
61 results = [];
62 while (j < a.length) {
63 if (ref = a[j], indexOf.call(b, ref) >= 0) {
64 results.push(a.splice(j, 1));
65 } else {
66 results.push(j++);
67 }
68 }
69 return results;
70};
71
72LineLinter = require('./line_linter.coffee');
73
74LexicalLinter = require('./lexical_linter.coffee');
75
76ASTLinter = require('./ast_linter.coffee');
77
78cache = null;
79
80mergeDefaultConfig = function(userConfig) {
81 var config, rule, ruleConfig, ruleLoader;
82 try {
83 ruleLoader = nodeRequire('./ruleLoader');
84 ruleLoader.loadFromConfig(coffeelint, userConfig);
85 } catch (undefined) {}
86 config = {};
87 if (userConfig.coffeelint) {
88 config.coffeelint = userConfig.coffeelint;
89 }
90 for (rule in RULES) {
91 ruleConfig = RULES[rule];
92 config[rule] = defaults(userConfig[rule], ruleConfig);
93 }
94 return config;
95};
96
97sameJSON = function(a, b) {
98 return JSON.stringify(a) === JSON.stringify(b);
99};
100
101coffeelint.trimConfig = function(userConfig) {
102 var config, dConfig, dValue, key, newConfig, ref, rule, value;
103 newConfig = {};
104 userConfig = mergeDefaultConfig(userConfig);
105 for (rule in userConfig) {
106 config = userConfig[rule];
107 dConfig = RULES[rule];
108 if (rule === 'coffeelint') {
109 config.transforms = config._transforms;
110 delete config._transforms;
111 config.coffeescript = config._coffeescript;
112 delete config._coffeescript;
113 newConfig[rule] = config;
114 } else if ((config.level === (ref = dConfig.level) && ref === 'ignore')) {
115 void 0;
116 } else if (config.level === 'ignore') {
117 newConfig[rule] = {
118 level: 'ignore'
119 };
120 } else {
121 config.module = config._module;
122 delete config._module;
123 for (key in config) {
124 value = config[key];
125 if (key === 'message' || key === 'description' || key === 'name') {
126 continue;
127 }
128 dValue = dConfig[key];
129 if (value !== dValue && !sameJSON(value, dValue)) {
130 if (newConfig[rule] == null) {
131 newConfig[rule] = {};
132 }
133 newConfig[rule][key] = value;
134 }
135 }
136 }
137 }
138 return newConfig;
139};
140
141coffeelint.invertLiterate = function(source) {
142 var len, line, n, newSource, ref;
143 source = CoffeeScript.helpers.invertLiterate(source);
144 newSource = '';
145 ref = source.split('\n');
146 for (n = 0, len = ref.length; n < len; n++) {
147 line = ref[n];
148 if (line.match(/^#/)) {
149 line = line.replace(/\s*$/, '');
150 }
151 line = line.replace(/^\s{4}/g, '');
152 newSource += line + "\n";
153 }
154 return newSource;
155};
156
157_rules = {};
158
159coffeelint.registerRule = function(RuleConstructor, ruleName) {
160 var e, name, p, ref, ref1;
161 if (ruleName == null) {
162 ruleName = void 0;
163 }
164 p = new RuleConstructor;
165 name = (p != null ? (ref = p.rule) != null ? ref.name : void 0 : void 0) || '(unknown)';
166 e = function(msg) {
167 throw new Error("Invalid rule: " + name + " " + msg);
168 };
169 if (p.rule == null) {
170 e('Rules must provide rule attribute with a default configuration.');
171 }
172 if (p.rule.name == null) {
173 e('Rule defaults require a name');
174 }
175 if ((ruleName != null) && ruleName !== p.rule.name) {
176 e("Mismatched rule name: " + ruleName);
177 }
178 if (p.rule.message == null) {
179 e('Rule defaults require a message');
180 }
181 if (p.rule.description == null) {
182 e('Rule defaults require a description');
183 }
184 if ((ref1 = p.rule.level) !== 'ignore' && ref1 !== 'warn' && ref1 !== 'error') {
185 e("Default level must be 'ignore', 'warn', or 'error'");
186 }
187 if (typeof p.lintToken === 'function') {
188 if (!p.tokens) {
189 e("'tokens' is required for 'lintToken'");
190 }
191 } else if (typeof p.lintLine !== 'function' && typeof p.lintAST !== 'function') {
192 e('Rules must implement lintToken, lintLine, or lintAST');
193 }
194 RULES[p.rule.name] = p.rule;
195 return _rules[p.rule.name] = RuleConstructor;
196};
197
198coffeelint.getRules = function() {
199 var key, len, n, output, ref;
200 output = {};
201 ref = Object.keys(RULES).sort();
202 for (n = 0, len = ref.length; n < len; n++) {
203 key = ref[n];
204 output[key] = RULES[key];
205 }
206 return output;
207};
208
209coffeelint.registerRule(require('./rules/arrow_spacing.coffee'));
210
211coffeelint.registerRule(require('./rules/braces_spacing.coffee'));
212
213coffeelint.registerRule(require('./rules/no_tabs.coffee'));
214
215coffeelint.registerRule(require('./rules/no_trailing_whitespace.coffee'));
216
217coffeelint.registerRule(require('./rules/max_line_length.coffee'));
218
219coffeelint.registerRule(require('./rules/line_endings.coffee'));
220
221coffeelint.registerRule(require('./rules/no_trailing_semicolons.coffee'));
222
223coffeelint.registerRule(require('./rules/indentation.coffee'));
224
225coffeelint.registerRule(require('./rules/camel_case_classes.coffee'));
226
227coffeelint.registerRule(require('./rules/colon_assignment_spacing.coffee'));
228
229coffeelint.registerRule(require('./rules/no_implicit_braces.coffee'));
230
231coffeelint.registerRule(require('./rules/no_nested_string_interpolation.coffee'));
232
233coffeelint.registerRule(require('./rules/no_plusplus.coffee'));
234
235coffeelint.registerRule(require('./rules/no_throwing_strings.coffee'));
236
237coffeelint.registerRule(require('./rules/no_backticks.coffee'));
238
239coffeelint.registerRule(require('./rules/no_implicit_parens.coffee'));
240
241coffeelint.registerRule(require('./rules/no_empty_param_list.coffee'));
242
243coffeelint.registerRule(require('./rules/no_stand_alone_at.coffee'));
244
245coffeelint.registerRule(require('./rules/space_operators.coffee'));
246
247coffeelint.registerRule(require('./rules/duplicate_key.coffee'));
248
249coffeelint.registerRule(require('./rules/empty_constructor_needs_parens.coffee'));
250
251coffeelint.registerRule(require('./rules/cyclomatic_complexity.coffee'));
252
253coffeelint.registerRule(require('./rules/newlines_after_classes.coffee'));
254
255coffeelint.registerRule(require('./rules/no_unnecessary_fat_arrows.coffee'));
256
257coffeelint.registerRule(require('./rules/missing_fat_arrows.coffee'));
258
259coffeelint.registerRule(require('./rules/non_empty_constructor_needs_parens.coffee'));
260
261coffeelint.registerRule(require('./rules/no_unnecessary_double_quotes.coffee'));
262
263coffeelint.registerRule(require('./rules/no_debugger.coffee'));
264
265coffeelint.registerRule(require('./rules/no_interpolation_in_single_quotes.coffee'));
266
267coffeelint.registerRule(require('./rules/no_empty_functions.coffee'));
268
269coffeelint.registerRule(require('./rules/prefer_english_operator.coffee'));
270
271coffeelint.registerRule(require('./rules/spacing_after_comma.coffee'));
272
273coffeelint.registerRule(require('./rules/transform_messes_up_line_numbers.coffee'));
274
275coffeelint.registerRule(require('./rules/ensure_comprehensions.coffee'));
276
277coffeelint.registerRule(require('./rules/no_this.coffee'));
278
279coffeelint.registerRule(require('./rules/eol_last.coffee'));
280
281coffeelint.registerRule(require('./rules/no_private_function_fat_arrows.coffee'));
282
283hasSyntaxError = function(source) {
284 try {
285 CoffeeScript.tokens(source);
286 return false;
287 } catch (undefined) {}
288 return true;
289};
290
291ErrorReport = require('./error_report.coffee');
292
293coffeelint.getErrorReport = function() {
294 return new ErrorReport(coffeelint);
295};
296
297coffeelint.lint = function(source, userConfig, literate) {
298 var allErrors, astErrors, cmd, config, disabled, disabledInitially, e, errors, i, inlineConfig, l, len, len1, lexErrors, lexicalLinter, lineErrors, lineLinter, m, n, name, nextLine, o, q, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, ref8, regex, rule, ruleLoader, rules, set, sourceLength, tokensByLine, transform;
299 if (userConfig == null) {
300 userConfig = {};
301 }
302 if (literate == null) {
303 literate = false;
304 }
305 errors = [];
306 if (cache != null) {
307 cache.setConfig(userConfig);
308 }
309 if (cache != null ? cache.has(source) : void 0) {
310 return cache != null ? cache.get(source) : void 0;
311 }
312 config = mergeDefaultConfig(userConfig);
313 if (literate) {
314 source = this.invertLiterate(source);
315 }
316 if ((userConfig != null ? (ref = userConfig.coffeelint) != null ? ref.transforms : void 0 : void 0) != null) {
317 sourceLength = source.split('\n').length;
318 ref2 = userConfig != null ? (ref1 = userConfig.coffeelint) != null ? ref1.transforms : void 0 : void 0;
319 for (n = 0, len = ref2.length; n < len; n++) {
320 m = ref2[n];
321 try {
322 ruleLoader = nodeRequire('./ruleLoader');
323 transform = ruleLoader.require(m);
324 source = transform(source);
325 } catch (undefined) {}
326 }
327 if (sourceLength !== source.split('\n').length && config.transform_messes_up_line_numbers.level !== 'ignore') {
328 errors.push(extend({
329 lineNumber: 1,
330 context: "File was transformed from " + sourceLength + " lines to " + (source.split("\n").length) + " lines"
331 }, config.transform_messes_up_line_numbers));
332 }
333 }
334 if ((userConfig != null ? (ref3 = userConfig.coffeelint) != null ? ref3.coffeescript : void 0 : void 0) != null) {
335 CoffeeScript = ruleLoader.require(userConfig.coffeelint.coffeescript);
336 }
337 for (name in userConfig) {
338 if (name !== 'coffeescript_error' && name !== '_comment') {
339 if (_rules[name] == null) {
340 void 0;
341 }
342 }
343 }
344 disabledInitially = [];
345 ref4 = source.split('\n');
346 for (o = 0, len1 = ref4.length; o < len1; o++) {
347 l = ref4[o];
348 ref5 = LineLinter.configStatement.exec(l) || [], regex = ref5[0], set = ref5[1], rule = ref5[2];
349 if (set === 'enable' && ((ref6 = config[rule]) != null ? ref6.level : void 0) === 'ignore') {
350 disabledInitially.push(rule);
351 config[rule].level = 'error';
352 }
353 }
354 astErrors = new ASTLinter(source, config, _rules, CoffeeScript).lint();
355 errors = errors.concat(astErrors);
356 if (!hasSyntaxError(source)) {
357 lexicalLinter = new LexicalLinter(source, config, _rules, CoffeeScript);
358 lexErrors = lexicalLinter.lint();
359 errors = errors.concat(lexErrors);
360 tokensByLine = lexicalLinter.tokensByLine;
361 lineLinter = new LineLinter(source, config, _rules, tokensByLine, literate);
362 lineErrors = lineLinter.lint();
363 errors = errors.concat(lineErrors);
364 inlineConfig = lineLinter.inlineConfig;
365 } else {
366 inlineConfig = {
367 enable: {},
368 disable: {}
369 };
370 }
371 errors.sort(function(a, b) {
372 return a.lineNumber - b.lineNumber;
373 });
374 allErrors = errors;
375 errors = [];
376 disabled = disabledInitially;
377 nextLine = 0;
378 for (i = q = 0, ref7 = source.split('\n').length; 0 <= ref7 ? q < ref7 : q > ref7; i = 0 <= ref7 ? ++q : --q) {
379 for (cmd in inlineConfig) {
380 rules = inlineConfig[cmd][i];
381 if (rules != null) {
382 ({
383 'disable': function() {
384 return disabled = disabled.concat(rules);
385 },
386 'enable': function() {
387 difference(disabled, rules);
388 if (rules.length === 0) {
389 return disabled = disabledInitially;
390 }
391 }
392 })[cmd]();
393 }
394 }
395 while (nextLine === i && allErrors.length > 0) {
396 nextLine = allErrors[0].lineNumber - 1;
397 e = allErrors[0];
398 if (e.lineNumber === i + 1 || (e.lineNumber == null)) {
399 e = allErrors.shift();
400 if (ref8 = e.rule, indexOf.call(disabled, ref8) < 0) {
401 errors.push(e);
402 }
403 }
404 }
405 }
406 if (cache != null) {
407 cache.set(source, errors);
408 }
409 return errors;
410};
411
412coffeelint.setCache = function(obj) {
413 return cache = obj;
414};
415
416
417
418},{"./../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_nested_string_interpolation.coffee":30,"./rules/no_plusplus.coffee":31,"./rules/no_private_function_fat_arrows.coffee":32,"./rules/no_stand_alone_at.coffee":33,"./rules/no_tabs.coffee":34,"./rules/no_this.coffee":35,"./rules/no_throwing_strings.coffee":36,"./rules/no_trailing_semicolons.coffee":37,"./rules/no_trailing_whitespace.coffee":38,"./rules/no_unnecessary_double_quotes.coffee":39,"./rules/no_unnecessary_fat_arrows.coffee":40,"./rules/non_empty_constructor_needs_parens.coffee":41,"./rules/prefer_english_operator.coffee":42,"./rules/space_operators.coffee":43,"./rules/spacing_after_comma.coffee":44,"./rules/transform_messes_up_line_numbers.coffee":45}],2:[function(require,module,exports){
419module.exports={
420 "name": "coffeelint",
421 "description": "Lint your CoffeeScript",
422 "version": "1.14.1",
423 "homepage": "http://www.coffeelint.org",
424 "keywords": [
425 "lint",
426 "coffeescript",
427 "coffee-script"
428 ],
429 "author": "Matthew Perpick <clutchski@gmail.com>",
430 "main": "./lib/coffeelint.js",
431 "engines": {
432 "npm": ">=1.3.7",
433 "node": ">=0.8.0"
434 },
435 "repository": {
436 "type": "git",
437 "url": "git://github.com/clutchski/coffeelint.git"
438 },
439 "bin": {
440 "coffeelint": "./bin/coffeelint"
441 },
442 "dependencies": {
443 "coffee-script": "^1.9.1",
444 "glob": "^4.0.0",
445 "ignore": "^2.2.15",
446 "optimist": "^0.6.1",
447 "resolve": "^0.6.3",
448 "strip-json-comments": "^1.0.2"
449 },
450 "devDependencies": {
451 "vows": ">=0.6.0",
452 "underscore": ">=1.4.4"
453 },
454 "license": "MIT",
455 "scripts": {
456 "pretest": "cake compile",
457 "test": "./vowsrunner.js --spec test/*.coffee test/*.litcoffee",
458 "testrule": "npm run compile && ./vowsrunner.js --spec",
459 "posttest": "npm run lint",
460 "prepublish": "cake prepublish",
461 "postpublish": "cake postpublish",
462 "publish": "cake publish",
463 "lint": "cake compile && ./bin/coffeelint .",
464 "lint-csv": "cake compile && ./bin/coffeelint --csv .",
465 "lint-jslint": "cake compile && ./bin/coffeelint --jslint .",
466 "compile": "cake compile"
467 }
468}
469},{}],3:[function(require,module,exports){
470var ASTApi, ASTLinter, BaseLinter, hasChildren, node_children,
471 hasProp = {}.hasOwnProperty,
472 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; };
473
474BaseLinter = require('./base_linter.coffee');
475
476node_children = {
477 Class: ['variable', 'parent', 'body'],
478 Code: ['params', 'body'],
479 For: ['body', 'source', 'guard', 'step'],
480 If: ['condition', 'body', 'elseBody'],
481 Obj: ['properties'],
482 Op: ['first', 'second'],
483 Switch: ['subject', 'cases', 'otherwise'],
484 Try: ['attempt', 'recovery', 'ensure'],
485 Value: ['base', 'properties'],
486 While: ['condition', 'guard', 'body']
487};
488
489hasChildren = function(node, children) {
490 var ref;
491 return (node != null ? (ref = node.children) != null ? ref.length : void 0 : void 0) === children.length && (node != null ? node.children.every(function(elem, i) {
492 return elem === children[i];
493 }) : void 0);
494};
495
496ASTApi = (function() {
497 function ASTApi(config1) {
498 this.config = config1;
499 }
500
501 ASTApi.prototype.getNodeName = function(node) {
502 var children, name, ref;
503 name = node != null ? (ref = node.constructor) != null ? ref.name : void 0 : void 0;
504 if (node_children[name]) {
505 return name;
506 } else {
507 for (name in node_children) {
508 if (!hasProp.call(node_children, name)) continue;
509 children = node_children[name];
510 if (hasChildren(node, children)) {
511 return name;
512 }
513 }
514 }
515 };
516
517 return ASTApi;
518
519})();
520
521module.exports = ASTLinter = (function(superClass) {
522 extend(ASTLinter, superClass);
523
524 function ASTLinter(source, config, rules, CoffeeScript) {
525 this.CoffeeScript = CoffeeScript;
526 ASTLinter.__super__.constructor.call(this, source, config, rules);
527 this.astApi = new ASTApi(this.config);
528 }
529
530 ASTLinter.prototype.acceptRule = function(rule) {
531 return typeof rule.lintAST === 'function';
532 };
533
534 ASTLinter.prototype.lint = function() {
535 var coffeeError, err, error, errors, j, len, ref, rule, v;
536 errors = [];
537 try {
538 this.node = this.CoffeeScript.nodes(this.source);
539 } catch (error) {
540 coffeeError = error;
541 err = this._parseCoffeeScriptError(coffeeError);
542 if (err != null) {
543 errors.push(err);
544 }
545 return errors;
546 }
547 ref = this.rules;
548 for (j = 0, len = ref.length; j < len; j++) {
549 rule = ref[j];
550 this.astApi.createError = (function(_this) {
551 return function(attrs) {
552 if (attrs == null) {
553 attrs = {};
554 }
555 return _this.createError(rule.rule.name, attrs);
556 };
557 })(this);
558 rule.errors = errors;
559 v = this.normalizeResult(rule, rule.lintAST(this.node, this.astApi));
560 if (v != null) {
561 return v;
562 }
563 }
564 return errors;
565 };
566
567 ASTLinter.prototype._parseCoffeeScriptError = function(coffeeError) {
568 var attrs, lineNumber, match, message, rule;
569 rule = this.config['coffeescript_error'];
570 message = coffeeError.toString();
571 lineNumber = -1;
572 if (coffeeError.location != null) {
573 lineNumber = coffeeError.location.first_line + 1;
574 } else {
575 match = /line (\d+)/.exec(message);
576 if ((match != null ? match.length : void 0) > 1) {
577 lineNumber = parseInt(match[1], 10);
578 }
579 }
580 attrs = {
581 message: message,
582 level: rule.level,
583 lineNumber: lineNumber
584 };
585 return this.createError('coffeescript_error', attrs);
586 };
587
588 return ASTLinter;
589
590})(BaseLinter);
591
592
593
594},{"./base_linter.coffee":4}],4:[function(require,module,exports){
595var BaseLinter, defaults, extend,
596 slice = [].slice;
597
598extend = function() {
599 var destination, i, k, len, source, sources, v;
600 destination = arguments[0], sources = 2 <= arguments.length ? slice.call(arguments, 1) : [];
601 for (i = 0, len = sources.length; i < len; i++) {
602 source = sources[i];
603 for (k in source) {
604 v = source[k];
605 destination[k] = v;
606 }
607 }
608 return destination;
609};
610
611defaults = function(source, defaults) {
612 return extend({}, defaults, source);
613};
614
615module.exports = BaseLinter = (function() {
616 function BaseLinter(source1, config, rules) {
617 this.source = source1;
618 this.config = config;
619 this.setupRules(rules);
620 }
621
622 BaseLinter.prototype.isObject = function(obj) {
623 return obj === Object(obj);
624 };
625
626 BaseLinter.prototype.createError = function(ruleName, attrs) {
627 var level;
628 if (attrs == null) {
629 attrs = {};
630 }
631 if (attrs.level == null) {
632 attrs.level = this.config[ruleName].level;
633 }
634 level = attrs.level;
635 if (level !== 'ignore' && level !== 'warn' && level !== 'error') {
636 throw new Error("unknown level " + level + " for rule: " + ruleName);
637 }
638 if (level === 'error' || level === 'warn') {
639 attrs.rule = ruleName;
640 return defaults(attrs, this.config[ruleName]);
641 } else {
642 return null;
643 }
644 };
645
646 BaseLinter.prototype.acceptRule = function(rule) {
647 throw new Error('acceptRule needs to be overridden in the subclass');
648 };
649
650 BaseLinter.prototype.setupRules = function(rules) {
651 var RuleConstructor, level, name, results, rule;
652 this.rules = [];
653 results = [];
654 for (name in rules) {
655 RuleConstructor = rules[name];
656 level = this.config[name].level;
657 if (level === 'error' || level === 'warn') {
658 rule = new RuleConstructor(this, this.config);
659 if (this.acceptRule(rule)) {
660 results.push(this.rules.push(rule));
661 } else {
662 results.push(void 0);
663 }
664 } else if (level !== 'ignore') {
665 throw new Error("unknown level " + level + " for rule: " + rule);
666 } else {
667 results.push(void 0);
668 }
669 }
670 return results;
671 };
672
673 BaseLinter.prototype.normalizeResult = function(p, result) {
674 if (result === true) {
675 return this.createError(p.rule.name);
676 }
677 if (this.isObject(result)) {
678 return this.createError(p.rule.name, result);
679 }
680 };
681
682 return BaseLinter;
683
684})();
685
686
687
688},{}],5:[function(require,module,exports){
689var ErrorReport;
690
691module.exports = ErrorReport = (function() {
692 function ErrorReport(coffeelint) {
693 this.coffeelint = coffeelint;
694 this.paths = {};
695 }
696
697 ErrorReport.prototype.lint = function(filename, source, config, literate) {
698 if (config == null) {
699 config = {};
700 }
701 if (literate == null) {
702 literate = false;
703 }
704 return this.paths[filename] = this.coffeelint.lint(source, config, literate);
705 };
706
707 ErrorReport.prototype.getExitCode = function() {
708 var path;
709 for (path in this.paths) {
710 if (this.pathHasError(path)) {
711 return 1;
712 }
713 }
714 return 0;
715 };
716
717 ErrorReport.prototype.getSummary = function() {
718 var error, errorCount, errors, i, len, path, pathCount, ref, warningCount;
719 pathCount = errorCount = warningCount = 0;
720 ref = this.paths;
721 for (path in ref) {
722 errors = ref[path];
723 pathCount++;
724 for (i = 0, len = errors.length; i < len; i++) {
725 error = errors[i];
726 if (error.level === 'error') {
727 errorCount++;
728 }
729 if (error.level === 'warn') {
730 warningCount++;
731 }
732 }
733 }
734 return {
735 errorCount: errorCount,
736 warningCount: warningCount,
737 pathCount: pathCount
738 };
739 };
740
741 ErrorReport.prototype.getErrors = function(path) {
742 return this.paths[path];
743 };
744
745 ErrorReport.prototype.pathHasWarning = function(path) {
746 return this._hasLevel(path, 'warn');
747 };
748
749 ErrorReport.prototype.pathHasError = function(path) {
750 return this._hasLevel(path, 'error');
751 };
752
753 ErrorReport.prototype.hasError = function() {
754 var path;
755 for (path in this.paths) {
756 if (this.pathHasError(path)) {
757 return true;
758 }
759 }
760 return false;
761 };
762
763 ErrorReport.prototype._hasLevel = function(path, level) {
764 var error, i, len, ref;
765 ref = this.paths[path];
766 for (i = 0, len = ref.length; i < len; i++) {
767 error = ref[i];
768 if (error.level === level) {
769 return true;
770 }
771 }
772 return false;
773 };
774
775 return ErrorReport;
776
777})();
778
779
780
781},{}],6:[function(require,module,exports){
782var BaseLinter, LexicalLinter, TokenApi,
783 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; },
784 hasProp = {}.hasOwnProperty,
785 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; };
786
787TokenApi = (function() {
788 function TokenApi(CoffeeScript, source, config1, tokensByLine) {
789 this.config = config1;
790 this.tokensByLine = tokensByLine;
791 this.tokens = CoffeeScript.tokens(source);
792 this.lines = source.split('\n');
793 this.tokensByLine = {};
794 }
795
796 TokenApi.prototype.i = 0;
797
798 TokenApi.prototype.peek = function(n) {
799 if (n == null) {
800 n = 1;
801 }
802 return this.tokens[this.i + n] || null;
803 };
804
805 return TokenApi;
806
807})();
808
809BaseLinter = require('./base_linter.coffee');
810
811module.exports = LexicalLinter = (function(superClass) {
812 extend(LexicalLinter, superClass);
813
814 function LexicalLinter(source, config, rules, CoffeeScript) {
815 LexicalLinter.__super__.constructor.call(this, source, config, rules);
816 this.tokenApi = new TokenApi(CoffeeScript, source, this.config, this.tokensByLine);
817 this.tokensByLine = this.tokenApi.tokensByLine;
818 }
819
820 LexicalLinter.prototype.acceptRule = function(rule) {
821 return typeof rule.lintToken === 'function';
822 };
823
824 LexicalLinter.prototype.lint = function() {
825 var error, errors, i, j, k, len, len1, ref, ref1, token;
826 errors = [];
827 ref = this.tokenApi.tokens;
828 for (i = j = 0, len = ref.length; j < len; i = ++j) {
829 token = ref[i];
830 this.tokenApi.i = i;
831 ref1 = this.lintToken(token);
832 for (k = 0, len1 = ref1.length; k < len1; k++) {
833 error = ref1[k];
834 errors.push(error);
835 }
836 }
837 return errors;
838 };
839
840 LexicalLinter.prototype.lintToken = function(token) {
841 var base, errors, j, len, lineNumber, ref, ref1, ref2, rule, type, v, value;
842 type = token[0], value = token[1], (ref = token[2], lineNumber = ref.first_line);
843 if ((base = this.tokensByLine)[lineNumber] == null) {
844 base[lineNumber] = [];
845 }
846 this.tokensByLine[lineNumber].push(token);
847 this.lineNumber = lineNumber || this.lineNumber || 0;
848 this.tokenApi.lineNumber = this.lineNumber;
849 errors = [];
850 ref1 = this.rules;
851 for (j = 0, len = ref1.length; j < len; j++) {
852 rule = ref1[j];
853 if (!(ref2 = token[0], indexOf.call(rule.tokens, ref2) >= 0)) {
854 continue;
855 }
856 v = this.normalizeResult(rule, rule.lintToken(token, this.tokenApi));
857 if (v != null) {
858 errors.push(v);
859 }
860 }
861 return errors;
862 };
863
864 LexicalLinter.prototype.createError = function(ruleName, attrs) {
865 if (attrs == null) {
866 attrs = {};
867 }
868 if (attrs.lineNumber == null) {
869 attrs.lineNumber = this.lineNumber;
870 }
871 attrs.lineNumber += 1;
872 attrs.line = this.tokenApi.lines[attrs.lineNumber - 1];
873 return LexicalLinter.__super__.createError.call(this, ruleName, attrs);
874 };
875
876 return LexicalLinter;
877
878})(BaseLinter);
879
880
881
882},{"./base_linter.coffee":4}],7:[function(require,module,exports){
883var BaseLinter, LineApi, LineLinter, configStatement,
884 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; },
885 hasProp = {}.hasOwnProperty;
886
887LineApi = (function() {
888 function LineApi(source, config1, tokensByLine1, literate1) {
889 this.config = config1;
890 this.tokensByLine = tokensByLine1;
891 this.literate = literate1;
892 this.line = null;
893 this.lines = source.split('\n');
894 this.lineCount = this.lines.length;
895 this.context = {
896 "class": {
897 inClass: false,
898 lastUnemptyLineInClass: null,
899 classIndents: null
900 }
901 };
902 }
903
904 LineApi.prototype.lineNumber = 0;
905
906 LineApi.prototype.isLiterate = function() {
907 return this.literate;
908 };
909
910 LineApi.prototype.maintainClassContext = function(line) {
911 if (this.context["class"].inClass) {
912 if (this.lineHasToken('INDENT')) {
913 this.context["class"].classIndents++;
914 } else if (this.lineHasToken('OUTDENT')) {
915 this.context["class"].classIndents--;
916 if (this.context["class"].classIndents === 0) {
917 this.context["class"].inClass = false;
918 this.context["class"].classIndents = null;
919 }
920 }
921 if (!line.match(/^\s*$/)) {
922 this.context["class"].lastUnemptyLineInClass = this.lineNumber;
923 }
924 } else {
925 if (!line.match(/\\s*/)) {
926 this.context["class"].lastUnemptyLineInClass = null;
927 }
928 if (this.lineHasToken('CLASS')) {
929 this.context["class"].inClass = true;
930 this.context["class"].lastUnemptyLineInClass = this.lineNumber;
931 this.context["class"].classIndents = 0;
932 }
933 }
934 return null;
935 };
936
937 LineApi.prototype.isLastLine = function() {
938 return this.lineNumber === this.lineCount - 1;
939 };
940
941 LineApi.prototype.lineHasToken = function(tokenType, lineNumber) {
942 var i, len, token, tokens;
943 if (tokenType == null) {
944 tokenType = null;
945 }
946 if (lineNumber == null) {
947 lineNumber = null;
948 }
949 lineNumber = lineNumber != null ? lineNumber : this.lineNumber;
950 if (tokenType == null) {
951 return this.tokensByLine[lineNumber] != null;
952 } else {
953 tokens = this.tokensByLine[lineNumber];
954 if (tokens == null) {
955 return null;
956 }
957 for (i = 0, len = tokens.length; i < len; i++) {
958 token = tokens[i];
959 if (token[0] === tokenType) {
960 return true;
961 }
962 }
963 return false;
964 }
965 };
966
967 LineApi.prototype.getLineTokens = function() {
968 return this.tokensByLine[this.lineNumber] || [];
969 };
970
971 return LineApi;
972
973})();
974
975BaseLinter = require('./base_linter.coffee');
976
977configStatement = /coffeelint:\s*(disable|enable)(?:=([\w\s,]*))?/;
978
979module.exports = LineLinter = (function(superClass) {
980 extend(LineLinter, superClass);
981
982 LineLinter.configStatement = configStatement;
983
984 function LineLinter(source, config, rules, tokensByLine, literate) {
985 if (literate == null) {
986 literate = false;
987 }
988 LineLinter.__super__.constructor.call(this, source, config, rules);
989 this.lineApi = new LineApi(source, config, tokensByLine, literate);
990 this.inlineConfig = {
991 enable: {},
992 disable: {}
993 };
994 }
995
996 LineLinter.prototype.acceptRule = function(rule) {
997 return typeof rule.lintLine === 'function';
998 };
999
1000 LineLinter.prototype.lint = function() {
1001 var error, errors, i, j, len, len1, line, lineNumber, ref, ref1;
1002 errors = [];
1003 ref = this.lineApi.lines;
1004 for (lineNumber = i = 0, len = ref.length; i < len; lineNumber = ++i) {
1005 line = ref[lineNumber];
1006 this.lineApi.lineNumber = this.lineNumber = lineNumber;
1007 this.lineApi.line = this.lineApi.lines[lineNumber];
1008 this.lineApi.maintainClassContext(line);
1009 this.collectInlineConfig(line);
1010 ref1 = this.lintLine(line);
1011 for (j = 0, len1 = ref1.length; j < len1; j++) {
1012 error = ref1[j];
1013 errors.push(error);
1014 }
1015 }
1016 return errors;
1017 };
1018
1019 LineLinter.prototype.lintLine = function(line) {
1020 var errors, i, len, ref, rule, v;
1021 errors = [];
1022 ref = this.rules;
1023 for (i = 0, len = ref.length; i < len; i++) {
1024 rule = ref[i];
1025 v = this.normalizeResult(rule, rule.lintLine(line, this.lineApi));
1026 if (v != null) {
1027 errors.push(v);
1028 }
1029 }
1030 return errors;
1031 };
1032
1033 LineLinter.prototype.collectInlineConfig = function(line) {
1034 var cmd, i, len, r, ref, result, rules;
1035 result = configStatement.exec(line);
1036 if (result != null) {
1037 cmd = result[1];
1038 rules = [];
1039 if (result[2] != null) {
1040 ref = result[2].split(',');
1041 for (i = 0, len = ref.length; i < len; i++) {
1042 r = ref[i];
1043 rules.push(r.replace(/^\s+|\s+$/g, ''));
1044 }
1045 }
1046 this.inlineConfig[cmd][this.lineNumber] = rules;
1047 }
1048 return null;
1049 };
1050
1051 LineLinter.prototype.createError = function(rule, attrs) {
1052 var ref;
1053 if (attrs == null) {
1054 attrs = {};
1055 }
1056 attrs.lineNumber = this.lineNumber + 1;
1057 attrs.level = (ref = this.config[rule]) != null ? ref.level : void 0;
1058 return LineLinter.__super__.createError.call(this, rule, attrs);
1059 };
1060
1061 return LineLinter;
1062
1063})(BaseLinter);
1064
1065
1066
1067},{"./base_linter.coffee":4}],8:[function(require,module,exports){
1068var ERROR, IGNORE, WARN;
1069
1070ERROR = 'error';
1071
1072WARN = 'warn';
1073
1074IGNORE = 'ignore';
1075
1076module.exports = {
1077 coffeescript_error: {
1078 level: ERROR,
1079 message: ''
1080 }
1081};
1082
1083
1084
1085},{}],9:[function(require,module,exports){
1086var ArrowSpacing;
1087
1088module.exports = ArrowSpacing = (function() {
1089 function ArrowSpacing() {}
1090
1091 ArrowSpacing.prototype.rule = {
1092 name: 'arrow_spacing',
1093 level: 'ignore',
1094 message: 'Function arrows (-> and =>) must be spaced properly',
1095 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>'
1096 };
1097
1098 ArrowSpacing.prototype.tokens = ['->', '=>'];
1099
1100 ArrowSpacing.prototype.lintToken = function(token, tokenApi) {
1101 var pp;
1102 pp = tokenApi.peek(-1);
1103 if (!pp) {
1104 return;
1105 }
1106 if (!token.spaced && tokenApi.peek(1)[0] === 'INDENT' && tokenApi.peek(2)[0] === 'OUTDENT') {
1107 return null;
1108 } else if (!(((token.spaced != null) || (token.newLine != null)) && (((pp.spaced != null) || pp[0] === 'TERMINATOR') || (pp.generated != null) || pp[0] === 'INDENT' || (pp[1] === '(' && (pp.generated == null))))) {
1109 return true;
1110 } else {
1111 return null;
1112 }
1113 };
1114
1115 return ArrowSpacing;
1116
1117})();
1118
1119
1120
1121},{}],10:[function(require,module,exports){
1122var BracesSpacing;
1123
1124module.exports = BracesSpacing = (function() {
1125 function BracesSpacing() {}
1126
1127 BracesSpacing.prototype.rule = {
1128 name: 'braces_spacing',
1129 level: 'ignore',
1130 spaces: 0,
1131 empty_object_spaces: 0,
1132 message: 'Curly braces must have the proper spacing',
1133 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.'
1134 };
1135
1136 BracesSpacing.prototype.tokens = ['{', '}'];
1137
1138 BracesSpacing.prototype.distanceBetweenTokens = function(firstToken, secondToken) {
1139 return secondToken[2].first_column - firstToken[2].last_column - 1;
1140 };
1141
1142 BracesSpacing.prototype.findNearestToken = function(token, tokenApi, difference) {
1143 var nearestToken, totalDifference;
1144 totalDifference = 0;
1145 while (true) {
1146 totalDifference += difference;
1147 nearestToken = tokenApi.peek(totalDifference);
1148 if (nearestToken[0] === 'OUTDENT' || (nearestToken.generated != null)) {
1149 continue;
1150 }
1151 return nearestToken;
1152 }
1153 };
1154
1155 BracesSpacing.prototype.tokensOnSameLine = function(firstToken, secondToken) {
1156 return firstToken[2].first_line === secondToken[2].first_line;
1157 };
1158
1159 BracesSpacing.prototype.getExpectedSpaces = function(tokenApi, firstToken, secondToken) {
1160 var config, ref;
1161 config = tokenApi.config[this.rule.name];
1162 if (firstToken[0] === '{' && secondToken[0] === '}') {
1163 return (ref = config.empty_object_spaces) != null ? ref : config.spaces;
1164 } else {
1165 return config.spaces;
1166 }
1167 };
1168
1169 BracesSpacing.prototype.lintToken = function(token, tokenApi) {
1170 var actual, expected, firstToken, msg, ref, secondToken;
1171 if (token.generated) {
1172 return null;
1173 }
1174 ref = token[0] === '{' ? [token, this.findNearestToken(token, tokenApi, 1)] : [this.findNearestToken(token, tokenApi, -1), token], firstToken = ref[0], secondToken = ref[1];
1175 if (!this.tokensOnSameLine(firstToken, secondToken)) {
1176 return null;
1177 }
1178 expected = this.getExpectedSpaces(tokenApi, firstToken, secondToken);
1179 actual = this.distanceBetweenTokens(firstToken, secondToken);
1180 if (actual === expected) {
1181 return null;
1182 } else {
1183 msg = "There should be " + expected + " space";
1184 if (expected !== 1) {
1185 msg += 's';
1186 }
1187 msg += " inside \"" + token[0] + "\"";
1188 return {
1189 context: msg
1190 };
1191 }
1192 };
1193
1194 return BracesSpacing;
1195
1196})();
1197
1198
1199
1200},{}],11:[function(require,module,exports){
1201var CamelCaseClasses, regexes;
1202
1203regexes = {
1204 camelCase: /^[A-Z_][a-zA-Z\d]*$/
1205};
1206
1207module.exports = CamelCaseClasses = (function() {
1208 function CamelCaseClasses() {}
1209
1210 CamelCaseClasses.prototype.rule = {
1211 name: 'camel_case_classes',
1212 level: 'error',
1213 message: 'Class name should be UpperCamelCased',
1214 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.'
1215 };
1216
1217 CamelCaseClasses.prototype.tokens = ['CLASS'];
1218
1219 CamelCaseClasses.prototype.lintToken = function(token, tokenApi) {
1220 var className, offset, ref, ref1, ref2;
1221 if ((token.newLine != null) || ((ref = tokenApi.peek()[0]) === 'INDENT' || ref === 'EXTENDS')) {
1222 return null;
1223 }
1224 className = null;
1225 offset = 1;
1226 while (!className) {
1227 if (((ref1 = tokenApi.peek(offset + 1)) != null ? ref1[0] : void 0) === '.') {
1228 offset += 2;
1229 } else if (((ref2 = tokenApi.peek(offset)) != null ? ref2[0] : void 0) === '@') {
1230 offset += 1;
1231 } else {
1232 className = tokenApi.peek(offset)[1];
1233 }
1234 }
1235 if (!regexes.camelCase.test(className)) {
1236 return {
1237 context: "class name: " + className
1238 };
1239 }
1240 };
1241
1242 return CamelCaseClasses;
1243
1244})();
1245
1246
1247
1248},{}],12:[function(require,module,exports){
1249var ColonAssignmentSpacing;
1250
1251module.exports = ColonAssignmentSpacing = (function() {
1252 function ColonAssignmentSpacing() {}
1253
1254 ColonAssignmentSpacing.prototype.rule = {
1255 name: 'colon_assignment_spacing',
1256 level: 'ignore',
1257 message: 'Colon assignment without proper spacing',
1258 spacing: {
1259 left: 0,
1260 right: 0
1261 },
1262 description: '<p>This rule checks to see that there is spacing before and\nafter the colon in a colon assignment (i.e., classes, objects).\nThe spacing amount is specified by\nspacing.left and spacing.right, respectively.\nA zero value means no spacing required.\n</p>\n<pre><code>\n#\n# If spacing.left and spacing.right is 1\n#\n\n# Doesn\'t throw an error\nobject = {spacing : true}\nclass Dog\n canBark : true\n\n# Throws an error\nobject = {spacing: true}\nclass Cat\n canBark: false\n</code></pre>'
1263 };
1264
1265 ColonAssignmentSpacing.prototype.tokens = [':'];
1266
1267 ColonAssignmentSpacing.prototype.lintToken = function(token, tokenApi) {
1268 var checkSpacing, getSpaceFromToken, isLeftSpaced, isRightSpaced, leftSpacing, nextToken, previousToken, ref, ref1, rightSpacing, spaceRules;
1269 spaceRules = tokenApi.config[this.rule.name].spacing;
1270 previousToken = tokenApi.peek(-1);
1271 nextToken = tokenApi.peek(1);
1272 getSpaceFromToken = function(direction) {
1273 switch (direction) {
1274 case 'left':
1275 return token[2].first_column - previousToken[2].last_column - 1;
1276 case 'right':
1277 return nextToken[2].first_column - token[2].first_column - 1;
1278 }
1279 };
1280 checkSpacing = function(direction) {
1281 var isSpaced, spacing;
1282 spacing = getSpaceFromToken(direction);
1283 isSpaced = spacing < 0 ? true : spacing === parseInt(spaceRules[direction]);
1284 return [isSpaced, spacing];
1285 };
1286 ref = checkSpacing('left'), isLeftSpaced = ref[0], leftSpacing = ref[1];
1287 ref1 = checkSpacing('right'), isRightSpaced = ref1[0], rightSpacing = ref1[1];
1288 if (isLeftSpaced && isRightSpaced) {
1289 return null;
1290 } else {
1291 return {
1292 context: "Incorrect spacing around column " + token[2].first_column
1293 };
1294 }
1295 };
1296
1297 return ColonAssignmentSpacing;
1298
1299})();
1300
1301
1302
1303},{}],13:[function(require,module,exports){
1304var CyclomaticComplexity;
1305
1306module.exports = CyclomaticComplexity = (function() {
1307 function CyclomaticComplexity() {}
1308
1309 CyclomaticComplexity.prototype.rule = {
1310 name: 'cyclomatic_complexity',
1311 level: 'ignore',
1312 message: 'The cyclomatic complexity is too damn high',
1313 value: 10,
1314 description: 'Examine the complexity of your function.'
1315 };
1316
1317 CyclomaticComplexity.prototype.getComplexity = function(node) {
1318 var complexity, name, ref;
1319 name = this.astApi.getNodeName(node);
1320 complexity = name === 'If' || name === 'While' || name === 'For' || name === 'Try' ? 1 : name === 'Op' && ((ref = node.operator) === '&&' || ref === '||') ? 1 : name === 'Switch' ? node.cases.length : 0;
1321 return complexity;
1322 };
1323
1324 CyclomaticComplexity.prototype.lintAST = function(node, astApi) {
1325 this.astApi = astApi;
1326 this.lintNode(node);
1327 return void 0;
1328 };
1329
1330 CyclomaticComplexity.prototype.lintNode = function(node) {
1331 var complexity, error, name, ref, rule;
1332 name = (ref = this.astApi) != null ? ref.getNodeName(node) : void 0;
1333 complexity = this.getComplexity(node);
1334 node.eachChild((function(_this) {
1335 return function(childNode) {
1336 var childComplexity, ref1;
1337 childComplexity = _this.lintNode(childNode);
1338 if (((ref1 = _this.astApi) != null ? ref1.getNodeName(childNode) : void 0) !== 'Code') {
1339 return complexity += childComplexity;
1340 }
1341 };
1342 })(this));
1343 rule = this.astApi.config[this.rule.name];
1344 if (name === 'Code' && complexity >= rule.value) {
1345 error = this.astApi.createError({
1346 context: complexity + 1,
1347 lineNumber: node.locationData.first_line + 1,
1348 lineNumberEnd: node.locationData.last_line + 1
1349 });
1350 if (error) {
1351 this.errors.push(error);
1352 }
1353 }
1354 return complexity;
1355 };
1356
1357 return CyclomaticComplexity;
1358
1359})();
1360
1361
1362
1363},{}],14:[function(require,module,exports){
1364var DuplicateKey;
1365
1366module.exports = DuplicateKey = (function() {
1367 DuplicateKey.prototype.rule = {
1368 name: 'duplicate_key',
1369 level: 'error',
1370 message: 'Duplicate key defined in object or class',
1371 description: 'Prevents defining duplicate keys in object literals and classes'
1372 };
1373
1374 DuplicateKey.prototype.tokens = ['IDENTIFIER', '{', '}'];
1375
1376 function DuplicateKey() {
1377 this.braceScopes = [];
1378 }
1379
1380 DuplicateKey.prototype.lintToken = function(arg, tokenApi) {
1381 var type;
1382 type = arg[0];
1383 if (type === '{' || type === '}') {
1384 this.lintBrace.apply(this, arguments);
1385 return void 0;
1386 }
1387 if (type === 'IDENTIFIER') {
1388 return this.lintIdentifier.apply(this, arguments);
1389 }
1390 };
1391
1392 DuplicateKey.prototype.lintIdentifier = function(token, tokenApi) {
1393 var key, nextToken, previousToken;
1394 key = token[1];
1395 if (this.currentScope == null) {
1396 return null;
1397 }
1398 nextToken = tokenApi.peek(1);
1399 if (nextToken[1] !== ':') {
1400 return null;
1401 }
1402 previousToken = tokenApi.peek(-1);
1403 if (previousToken[0] === '@') {
1404 key = "@" + key;
1405 }
1406 key = "identifier-" + key;
1407 if (this.currentScope[key]) {
1408 return true;
1409 } else {
1410 this.currentScope[key] = token;
1411 return null;
1412 }
1413 };
1414
1415 DuplicateKey.prototype.lintBrace = function(token) {
1416 if (token[0] === '{') {
1417 if (this.currentScope != null) {
1418 this.braceScopes.push(this.currentScope);
1419 }
1420 this.currentScope = {};
1421 } else {
1422 this.currentScope = this.braceScopes.pop();
1423 }
1424 return null;
1425 };
1426
1427 return DuplicateKey;
1428
1429})();
1430
1431
1432
1433},{}],15:[function(require,module,exports){
1434var EmptyConstructorNeedsParens;
1435
1436module.exports = EmptyConstructorNeedsParens = (function() {
1437 function EmptyConstructorNeedsParens() {}
1438
1439 EmptyConstructorNeedsParens.prototype.rule = {
1440 name: 'empty_constructor_needs_parens',
1441 level: 'ignore',
1442 message: 'Invoking a constructor without parens and without arguments',
1443 description: 'Requires constructors with no parameters to include the parens'
1444 };
1445
1446 EmptyConstructorNeedsParens.prototype.tokens = ['UNARY'];
1447
1448 EmptyConstructorNeedsParens.prototype.lintToken = function(token, tokenApi) {
1449 var expectedCallStart, expectedIdentifier, identifierIndex, peek, ref;
1450 if (token[1] === 'new') {
1451 peek = tokenApi.peek.bind(tokenApi);
1452 identifierIndex = 1;
1453 while (true) {
1454 expectedIdentifier = peek(identifierIndex);
1455 expectedCallStart = peek(identifierIndex + 1);
1456 if ((expectedIdentifier != null ? expectedIdentifier[0] : void 0) === 'IDENTIFIER') {
1457 if ((expectedCallStart != null ? expectedCallStart[0] : void 0) === '.') {
1458 identifierIndex += 2;
1459 continue;
1460 }
1461 if ((expectedCallStart != null ? expectedCallStart[0] : void 0) === 'INDEX_START') {
1462 while (((ref = peek(identifierIndex)) != null ? ref[0] : void 0) !== 'INDEX_END') {
1463 identifierIndex++;
1464 }
1465 continue;
1466 }
1467 }
1468 break;
1469 }
1470 if ((expectedIdentifier != null ? expectedIdentifier[0] : void 0) === 'IDENTIFIER' && (expectedCallStart != null)) {
1471 return this.handleExpectedCallStart(expectedCallStart);
1472 }
1473 }
1474 };
1475
1476 EmptyConstructorNeedsParens.prototype.handleExpectedCallStart = function(expectedCallStart) {
1477 if (expectedCallStart[0] !== 'CALL_START') {
1478 return true;
1479 }
1480 };
1481
1482 return EmptyConstructorNeedsParens;
1483
1484})();
1485
1486
1487
1488},{}],16:[function(require,module,exports){
1489var EnsureComprehensions,
1490 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; };
1491
1492module.exports = EnsureComprehensions = (function() {
1493 function EnsureComprehensions() {}
1494
1495 EnsureComprehensions.prototype.rule = {
1496 name: 'ensure_comprehensions',
1497 level: 'warn',
1498 message: 'Comprehensions must have parentheses around them',
1499 description: 'This rule makes sure that parentheses are around comprehensions.'
1500 };
1501
1502 EnsureComprehensions.prototype.tokens = ['FOR'];
1503
1504 EnsureComprehensions.prototype.forBlock = false;
1505
1506 EnsureComprehensions.prototype.lintToken = function(token, tokenApi) {
1507 var atEqual, idents, numCallEnds, numCallStarts, numParenEnds, numParenStarts, peeker, prevIdents, prevToken, ref, ref1;
1508 idents = this.findIdents(tokenApi);
1509 if (this.forBlock) {
1510 this.forBlock = false;
1511 return;
1512 }
1513 peeker = -1;
1514 atEqual = false;
1515 numCallEnds = 0;
1516 numCallStarts = 0;
1517 numParenStarts = 0;
1518 numParenEnds = 0;
1519 prevIdents = [];
1520 while ((prevToken = tokenApi.peek(peeker))) {
1521 if (prevToken[0] === 'CALL_END') {
1522 numCallEnds++;
1523 }
1524 if (prevToken[0] === 'CALL_START') {
1525 numCallStarts++;
1526 }
1527 if (prevToken[0] === '(') {
1528 numParenStarts++;
1529 }
1530 if (prevToken[0] === ')') {
1531 numParenEnds++;
1532 }
1533 if (prevToken[0] === 'IDENTIFIER') {
1534 if (!atEqual) {
1535 prevIdents.push(prevToken[1]);
1536 } else if (ref = prevToken[1], indexOf.call(idents, ref) >= 0) {
1537 return;
1538 }
1539 }
1540 if (((ref1 = prevToken[0]) === '(' || ref1 === '->' || ref1 === 'TERMINATOR') || (prevToken.newLine != null)) {
1541 break;
1542 }
1543 if (prevToken[0] === '=' && numParenEnds === numParenStarts) {
1544 atEqual = true;
1545 }
1546 peeker--;
1547 }
1548 if (atEqual && numCallStarts === numCallEnds) {
1549 return {
1550 context: ''
1551 };
1552 }
1553 };
1554
1555 EnsureComprehensions.prototype.findIdents = function(tokenApi) {
1556 var idents, nextToken, peeker, ref;
1557 peeker = 1;
1558 idents = [];
1559 while ((nextToken = tokenApi.peek(peeker))) {
1560 if (nextToken[0] === 'IDENTIFIER') {
1561 idents.push(nextToken[1]);
1562 }
1563 if ((ref = nextToken[0]) === 'FORIN' || ref === 'FOROF') {
1564 break;
1565 }
1566 peeker++;
1567 }
1568 while ((nextToken = tokenApi.peek(peeker))) {
1569 if (nextToken[0] === 'TERMINATOR') {
1570 break;
1571 }
1572 if (nextToken[0] === 'INDENT') {
1573 this.forBlock = true;
1574 break;
1575 }
1576 peeker++;
1577 }
1578 return idents;
1579 };
1580
1581 return EnsureComprehensions;
1582
1583})();
1584
1585
1586
1587},{}],17:[function(require,module,exports){
1588var EOLLast;
1589
1590module.exports = EOLLast = (function() {
1591 function EOLLast() {}
1592
1593 EOLLast.prototype.rule = {
1594 name: 'eol_last',
1595 level: 'ignore',
1596 message: 'File does not end with a single newline',
1597 description: 'Checks that the file ends with a single newline'
1598 };
1599
1600 EOLLast.prototype.lintLine = function(line, lineApi) {
1601 var isNewline, previousIsNewline;
1602 if (!lineApi.isLastLine()) {
1603 return null;
1604 }
1605 isNewline = line.length === 0;
1606 previousIsNewline = lineApi.lineCount > 1 ? lineApi.lines[lineApi.lineNumber - 1].length === 0 : false;
1607 if (!(isNewline && !previousIsNewline)) {
1608 return true;
1609 }
1610 };
1611
1612 return EOLLast;
1613
1614})();
1615
1616
1617
1618},{}],18:[function(require,module,exports){
1619var Indentation,
1620 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; };
1621
1622module.exports = Indentation = (function() {
1623 Indentation.prototype.rule = {
1624 name: 'indentation',
1625 value: 2,
1626 level: 'error',
1627 message: 'Line contains inconsistent indentation',
1628 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.'
1629 };
1630
1631 Indentation.prototype.tokens = ['INDENT', '[', ']', '.'];
1632
1633 Indentation.prototype.keywords = ['->', '=>', '@', 'CATCH', 'CLASS', 'ELSE', 'FINALLY', 'FOR', 'FORIN', 'FOROF', 'IDENTIFIER', 'IF', 'LEADING_WHEN', 'LOOP', 'RETURN', 'SWITCH', 'THROW', 'TRY', 'UNTIL', 'WHEN', 'WHILE', 'YIELD'];
1634
1635 function Indentation() {
1636 this.arrayTokens = [];
1637 }
1638
1639 Indentation.prototype.lintToken = function(token, tokenApi) {
1640 var currentLine, expected, ignoreIndent, isArrayIndent, isMultiline, lineNumber, lines, numIndents, previous, previousSymbol, ref, ref1, ref2, type;
1641 type = token[0], numIndents = token[1], (ref = token[2], lineNumber = ref.first_line);
1642 lines = tokenApi.lines, lineNumber = tokenApi.lineNumber;
1643 expected = tokenApi.config[this.rule.name].value;
1644 if (type === '.') {
1645 currentLine = lines[lineNumber];
1646 if (((ref1 = currentLine.match(/\S/)) != null ? ref1[0] : void 0) === '.') {
1647 return this.handleChain(tokenApi, expected);
1648 }
1649 return void 0;
1650 }
1651 if (type === '[' || type === ']') {
1652 this.lintArray(token);
1653 return void 0;
1654 }
1655 if ((token.generated != null) || (token.explicit != null)) {
1656 return null;
1657 }
1658 previous = tokenApi.peek(-1);
1659 isArrayIndent = this.inArray() && (previous != null ? previous.newLine : void 0);
1660 previousSymbol = (ref2 = tokenApi.peek(-1)) != null ? ref2[0] : void 0;
1661 isMultiline = previousSymbol === '=' || previousSymbol === ',';
1662 ignoreIndent = isArrayIndent || isMultiline;
1663 numIndents = this.getCorrectIndent(tokenApi);
1664 if (!ignoreIndent && !(indexOf.call(numIndents, expected) >= 0)) {
1665 return {
1666 context: "Expected " + expected + " got " + numIndents[0]
1667 };
1668 }
1669 };
1670
1671 Indentation.prototype.inArray = function() {
1672 return this.arrayTokens.length > 0;
1673 };
1674
1675 Indentation.prototype.lintArray = function(token) {
1676 if (token[0] === '[') {
1677 this.arrayTokens.push(token);
1678 } else if (token[0] === ']') {
1679 this.arrayTokens.pop();
1680 }
1681 return null;
1682 };
1683
1684 Indentation.prototype.handleChain = function(tokenApi, expected) {
1685 var callStart, checkNum, currIsIndent, currentLine, currentSpaces, findCallStart, lastCheck, lineNumber, lines, numIndents, prevIsIndent, prevLine, prevNum, prevSpaces, ref, ref1;
1686 lastCheck = 1;
1687 callStart = 1;
1688 prevNum = 1;
1689 lineNumber = tokenApi.lineNumber, lines = tokenApi.lines;
1690 currentLine = lines[lineNumber];
1691 findCallStart = tokenApi.peek(-callStart);
1692 while (findCallStart && findCallStart[0] !== 'TERMINATOR') {
1693 lastCheck = findCallStart[2].first_line;
1694 callStart += 1;
1695 findCallStart = tokenApi.peek(-callStart);
1696 }
1697 while ((lineNumber - prevNum > lastCheck) && !/^\s*\./.test(lines[lineNumber - prevNum])) {
1698 prevNum += 1;
1699 }
1700 checkNum = lineNumber - prevNum;
1701 if (checkNum >= 0) {
1702 prevLine = lines[checkNum];
1703 if (prevLine.match(/\S/)[0] === '.' || checkNum === lastCheck) {
1704 currentSpaces = (ref = currentLine.match(/\S/)) != null ? ref.index : void 0;
1705 prevSpaces = (ref1 = prevLine.match(/\S/)) != null ? ref1.index : void 0;
1706 numIndents = currentSpaces - prevSpaces;
1707 prevIsIndent = prevSpaces % expected !== 0;
1708 currIsIndent = currentSpaces % expected !== 0;
1709 if (prevIsIndent && currIsIndent) {
1710 numIndents = currentSpaces;
1711 }
1712 if (numIndents % expected !== 0) {
1713 return {
1714 context: "Expected " + expected + " got " + numIndents
1715 };
1716 }
1717 }
1718 }
1719 };
1720
1721 Indentation.prototype.grabLineTokens = function(tokenApi, lineNumber, all) {
1722 var i, k, len, len1, ref, ref1, results, results1, tok, tokensByLine;
1723 if (all == null) {
1724 all = false;
1725 }
1726 tokensByLine = tokenApi.tokensByLine;
1727 while (!((tokensByLine[lineNumber] != null) || lineNumber === 0)) {
1728 lineNumber--;
1729 }
1730 if (all) {
1731 ref = tokensByLine[lineNumber];
1732 results = [];
1733 for (i = 0, len = ref.length; i < len; i++) {
1734 tok = ref[i];
1735 results.push(tok);
1736 }
1737 return results;
1738 } else {
1739 ref1 = tokensByLine[lineNumber];
1740 results1 = [];
1741 for (k = 0, len1 = ref1.length; k < len1; k++) {
1742 tok = ref1[k];
1743 if ((tok.generated == null) && tok[0] !== 'OUTDENT') {
1744 results1.push(tok);
1745 }
1746 }
1747 return results1;
1748 }
1749 };
1750
1751 Indentation.prototype.getCorrectIndent = function(tokenApi) {
1752 var _, curIndent, i, j, len, lineNumber, lines, prevIndent, prevNum, prevTokens, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, ret, skipAssign, t, tokens, tryLine;
1753 lineNumber = tokenApi.lineNumber, lines = tokenApi.lines, tokens = tokenApi.tokens;
1754 curIndent = (ref = lines[lineNumber].match(/\S/)) != null ? ref.index : void 0;
1755 prevNum = 1;
1756 while (/^\s*(#|$)/.test(lines[lineNumber - prevNum])) {
1757 prevNum += 1;
1758 }
1759 prevTokens = this.grabLineTokens(tokenApi, lineNumber - prevNum);
1760 if (((ref1 = prevTokens[0]) != null ? ref1[0] : void 0) === 'INDENT') {
1761 return [curIndent - ((ref2 = prevTokens[1]) != null ? ref2[2].first_column : void 0), curIndent - prevTokens[0][1]];
1762 } else {
1763 prevIndent = (ref3 = prevTokens[0]) != null ? ref3[2].first_column : void 0;
1764 for (j = i = 0, len = prevTokens.length; i < len; j = ++i) {
1765 _ = prevTokens[j];
1766 if (!(prevTokens[j][0] === '=' && ((ref4 = prevTokens[j + 1]) != null ? ref4[0] : void 0) === 'IF')) {
1767 continue;
1768 }
1769 skipAssign = curIndent - prevTokens[j + 1][2].first_column;
1770 ret = curIndent - prevIndent;
1771 if (skipAssign < 0) {
1772 return [ret];
1773 }
1774 return [skipAssign, ret];
1775 }
1776 while (prevIndent > curIndent) {
1777 tryLine = lineNumber - prevNum;
1778 prevTokens = this.grabLineTokens(tokenApi, tryLine, true);
1779 if (((ref5 = prevTokens[0]) != null ? ref5[0] : void 0) === 'INDENT') {
1780 prevIndent = prevTokens[0][1];
1781 prevTokens = prevTokens.slice(1);
1782 }
1783 t = 0;
1784 while (!((prevTokens[t] == null) || (ref6 = prevTokens[t][0], indexOf.call(this.keywords, ref6) >= 0))) {
1785 t++;
1786 }
1787 prevTokens = prevTokens.slice(t);
1788 prevNum++;
1789 if (prevTokens[0] == null) {
1790 continue;
1791 }
1792 prevIndent = (ref7 = prevTokens[0]) != null ? ref7[2].first_column : void 0;
1793 }
1794 }
1795 return [curIndent - prevIndent];
1796 };
1797
1798 return Indentation;
1799
1800})();
1801
1802
1803
1804},{}],19:[function(require,module,exports){
1805var LineEndings;
1806
1807module.exports = LineEndings = (function() {
1808 function LineEndings() {}
1809
1810 LineEndings.prototype.rule = {
1811 name: 'line_endings',
1812 level: 'ignore',
1813 value: 'unix',
1814 message: 'Line contains incorrect line endings',
1815 description: 'This rule ensures your project uses only <tt>windows</tt> or\n<tt>unix</tt> line endings. This rule is disabled by default.'
1816 };
1817
1818 LineEndings.prototype.lintLine = function(line, lineApi) {
1819 var ending, lastChar, ref, valid;
1820 ending = (ref = lineApi.config[this.rule.name]) != null ? ref.value : void 0;
1821 if (!ending || lineApi.isLastLine() || !line) {
1822 return null;
1823 }
1824 lastChar = line[line.length - 1];
1825 valid = (function() {
1826 if (ending === 'windows') {
1827 return lastChar === '\r';
1828 } else if (ending === 'unix') {
1829 return lastChar !== '\r';
1830 } else {
1831 throw new Error("unknown line ending type: " + ending);
1832 }
1833 })();
1834 if (!valid) {
1835 return {
1836 context: "Expected " + ending
1837 };
1838 } else {
1839 return null;
1840 }
1841 };
1842
1843 return LineEndings;
1844
1845})();
1846
1847
1848
1849},{}],20:[function(require,module,exports){
1850var MaxLineLength, regexes;
1851
1852regexes = {
1853 literateComment: /^\#\s/,
1854 longUrlComment: /^\s*\#\s*http[^\s]+$/
1855};
1856
1857module.exports = MaxLineLength = (function() {
1858 function MaxLineLength() {}
1859
1860 MaxLineLength.prototype.rule = {
1861 name: 'max_line_length',
1862 value: 80,
1863 level: 'error',
1864 limitComments: true,
1865 message: 'Line exceeds maximum allowed length',
1866 description: 'This rule imposes a maximum line length on your code. <a\nhref="http://www.python.org/dev/peps/pep-0008/">Python\'s style\nguide</a> does a good job explaining why you might want to limit the\nlength of your lines, though this is a matter of taste.\n\nLines can be no longer than eighty characters by default.'
1867 };
1868
1869 MaxLineLength.prototype.lintLine = function(line, lineApi) {
1870 var limitComments, lineLength, max, ref, ref1;
1871 max = (ref = lineApi.config[this.rule.name]) != null ? ref.value : void 0;
1872 limitComments = (ref1 = lineApi.config[this.rule.name]) != null ? ref1.limitComments : void 0;
1873 lineLength = line.replace(/\s+$/, '').length;
1874 if (lineApi.isLiterate() && regexes.literateComment.test(line)) {
1875 lineLength -= 2;
1876 }
1877 if (max && max < lineLength && !regexes.longUrlComment.test(line)) {
1878 if (!limitComments) {
1879 if (lineApi.getLineTokens().length === 0) {
1880 return;
1881 }
1882 }
1883 return {
1884 context: "Length is " + lineLength + ", max is " + max
1885 };
1886 }
1887 };
1888
1889 return MaxLineLength;
1890
1891})();
1892
1893
1894
1895},{}],21:[function(require,module,exports){
1896var MissingFatArrows, any, containsButIsnt,
1897 bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
1898 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; };
1899
1900any = function(arr, test) {
1901 return arr.reduce((function(res, elt) {
1902 return res || test(elt);
1903 }), false);
1904};
1905
1906containsButIsnt = function(node, nIsThis, nIsClass) {
1907 var target;
1908 target = void 0;
1909 node.traverseChildren(false, function(n) {
1910 if (nIsClass(n)) {
1911 return false;
1912 }
1913 if (nIsThis(n)) {
1914 target = n;
1915 return false;
1916 }
1917 });
1918 return target;
1919};
1920
1921module.exports = MissingFatArrows = (function() {
1922 function MissingFatArrows() {
1923 this.isFatArrowCode = bind(this.isFatArrowCode, this);
1924 this.isThis = bind(this.isThis, this);
1925 this.isObject = bind(this.isObject, this);
1926 this.isValue = bind(this.isValue, this);
1927 this.isClass = bind(this.isClass, this);
1928 this.isCode = bind(this.isCode, this);
1929 }
1930
1931 MissingFatArrows.prototype.rule = {
1932 name: 'missing_fat_arrows',
1933 level: 'ignore',
1934 is_strict: false,
1935 message: 'Used `this` in a function without a fat arrow',
1936 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.'
1937 };
1938
1939 MissingFatArrows.prototype.lintAST = function(node, astApi) {
1940 this.astApi = astApi;
1941 this.lintNode(node);
1942 return void 0;
1943 };
1944
1945 MissingFatArrows.prototype.lintNode = function(node, methods) {
1946 var error, isStrict, ref;
1947 if (methods == null) {
1948 methods = [];
1949 }
1950 isStrict = (ref = this.astApi.config[this.rule.name]) != null ? ref.is_strict : void 0;
1951 if (this.isPrototype(node)) {
1952 return;
1953 }
1954 if (this.isConstructor(node)) {
1955 return;
1956 }
1957 if ((!this.isFatArrowCode(node)) && (isStrict ? true : indexOf.call(methods, node) < 0) && (this.needsFatArrow(node))) {
1958 error = this.astApi.createError({
1959 lineNumber: node.locationData.first_line + 1
1960 });
1961 this.errors.push(error);
1962 }
1963 return node.eachChild((function(_this) {
1964 return function(child) {
1965 return _this.lintNode(child, (function() {
1966 switch (false) {
1967 case !this.isClass(node):
1968 return this.methodsOfClass(node);
1969 case !this.isCode(node):
1970 return [];
1971 default:
1972 return methods;
1973 }
1974 }).call(_this));
1975 };
1976 })(this));
1977 };
1978
1979 MissingFatArrows.prototype.isCode = function(node) {
1980 return this.astApi.getNodeName(node) === 'Code';
1981 };
1982
1983 MissingFatArrows.prototype.isClass = function(node) {
1984 return this.astApi.getNodeName(node) === 'Class';
1985 };
1986
1987 MissingFatArrows.prototype.isValue = function(node) {
1988 return this.astApi.getNodeName(node) === 'Value';
1989 };
1990
1991 MissingFatArrows.prototype.isObject = function(node) {
1992 return this.astApi.getNodeName(node) === 'Obj';
1993 };
1994
1995 MissingFatArrows.prototype.isPrototype = function(node) {
1996 var i, ident, len, props, ref, ref1;
1997 props = (node != null ? (ref = node.variable) != null ? ref.properties : void 0 : void 0) || [];
1998 for (i = 0, len = props.length; i < len; i++) {
1999 ident = props[i];
2000 if (((ref1 = ident.name) != null ? ref1.value : void 0) === 'prototype') {
2001 return true;
2002 }
2003 }
2004 return false;
2005 };
2006
2007 MissingFatArrows.prototype.isThis = function(node) {
2008 return this.isValue(node) && node.base.value === 'this';
2009 };
2010
2011 MissingFatArrows.prototype.isFatArrowCode = function(node) {
2012 return this.isCode(node) && node.bound;
2013 };
2014
2015 MissingFatArrows.prototype.isConstructor = function(node) {
2016 var ref, ref1;
2017 return ((ref = node.variable) != null ? (ref1 = ref.base) != null ? ref1.value : void 0 : void 0) === 'constructor';
2018 };
2019
2020 MissingFatArrows.prototype.needsFatArrow = function(node) {
2021 return this.isCode(node) && (any(node.params, (function(_this) {
2022 return function(param) {
2023 return param.contains(_this.isThis) != null;
2024 };
2025 })(this)) || containsButIsnt(node.body, this.isThis, this.isClass));
2026 };
2027
2028 MissingFatArrows.prototype.methodsOfClass = function(classNode) {
2029 var bodyNodes, returnNode;
2030 bodyNodes = classNode.body.expressions;
2031 returnNode = bodyNodes[bodyNodes.length - 1];
2032 if ((returnNode != null) && this.isValue(returnNode) && this.isObject(returnNode.base)) {
2033 return returnNode.base.properties.map(function(assignNode) {
2034 return assignNode.value;
2035 }).filter(this.isCode);
2036 } else {
2037 return [];
2038 }
2039 };
2040
2041 return MissingFatArrows;
2042
2043})();
2044
2045
2046
2047},{}],22:[function(require,module,exports){
2048var NewlinesAfterClasses;
2049
2050module.exports = NewlinesAfterClasses = (function() {
2051 function NewlinesAfterClasses() {}
2052
2053 NewlinesAfterClasses.prototype.rule = {
2054 name: 'newlines_after_classes',
2055 value: 3,
2056 level: 'ignore',
2057 message: 'Wrong count of newlines between a class and other code',
2058 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.'
2059 };
2060
2061 NewlinesAfterClasses.prototype.tokens = ['CLASS', '}', '{'];
2062
2063 NewlinesAfterClasses.prototype.classBracesCount = 0;
2064
2065 NewlinesAfterClasses.prototype.classCount = 0;
2066
2067 NewlinesAfterClasses.prototype.lintToken = function(token, tokenApi) {
2068 var afters, befores, comment, ending, got, lineNumber, lines, numIndents, outdent, ref, ref1, ref2, start, trueLine, type;
2069 type = token[0], numIndents = token[1], (ref = token[2], lineNumber = ref.first_line);
2070 lines = tokenApi.lines;
2071 ending = tokenApi.config[this.rule.name].value;
2072 if (type === 'CLASS') {
2073 this.classCount++;
2074 }
2075 if (this.classCount > 0 && (token.generated != null)) {
2076 if (type === '{' && ((ref1 = token.origin) != null ? ref1[0] : void 0) === ':') {
2077 this.classBracesCount++;
2078 }
2079 if (type === '}' && ((ref2 = token.origin) != null ? ref2[0] : void 0) === 'OUTDENT') {
2080 this.classBracesCount--;
2081 this.classCount--;
2082 if (this.classCount === 0 && this.classBracesCount === 0) {
2083 befores = 1;
2084 afters = 1;
2085 comment = 0;
2086 outdent = token.origin[2].first_line;
2087 start = Math.min(lineNumber, outdent);
2088 trueLine = Infinity;
2089 while (/^\s*(#|$)/.test(lines[start + afters])) {
2090 if (/^\s*#/.test(lines[start + afters])) {
2091 comment += 1;
2092 } else {
2093 trueLine = Math.min(trueLine, start + afters);
2094 }
2095 afters += 1;
2096 }
2097 while (/^\s*(#|$)/.test(lines[start - befores])) {
2098 if (/^\s*#/.test(lines[start - befores])) {
2099 comment += 1;
2100 } else {
2101 trueLine = Math.min(trueLine, start - befores);
2102 }
2103 befores += 1;
2104 }
2105 got = afters + befores - comment - 2;
2106 if (got !== ending && trueLine + ending <= lines.length) {
2107 return {
2108 context: "Expected " + ending + " got " + got,
2109 lineNumber: trueLine
2110 };
2111 }
2112 }
2113 }
2114 }
2115 };
2116
2117 return NewlinesAfterClasses;
2118
2119})();
2120
2121
2122
2123},{}],23:[function(require,module,exports){
2124var NoBackticks;
2125
2126module.exports = NoBackticks = (function() {
2127 function NoBackticks() {}
2128
2129 NoBackticks.prototype.rule = {
2130 name: 'no_backticks',
2131 level: 'error',
2132 message: 'Backticks are forbidden',
2133 description: 'Backticks allow snippets of JavaScript to be embedded in\nCoffeeScript. While some folks consider backticks useful in a few\nniche circumstances, they should be avoided because so none of\nJavaScript\'s "bad parts", like <tt>with</tt> and <tt>eval</tt>,\nsneak into CoffeeScript.\nThis rule is enabled by default.'
2134 };
2135
2136 NoBackticks.prototype.tokens = ['JS'];
2137
2138 NoBackticks.prototype.lintToken = function(token, tokenApi) {
2139 return true;
2140 };
2141
2142 return NoBackticks;
2143
2144})();
2145
2146
2147
2148},{}],24:[function(require,module,exports){
2149var NoDebugger;
2150
2151module.exports = NoDebugger = (function() {
2152 function NoDebugger() {}
2153
2154 NoDebugger.prototype.rule = {
2155 name: 'no_debugger',
2156 level: 'warn',
2157 message: 'Found debugging code',
2158 console: false,
2159 description: 'This rule detects `debugger` and optionally `console` calls\nThis rule is `warn` by default.'
2160 };
2161
2162 NoDebugger.prototype.tokens = ['DEBUGGER', 'IDENTIFIER'];
2163
2164 NoDebugger.prototype.lintToken = function(token, tokenApi) {
2165 var method, ref, ref1;
2166 if (token[0] === 'DEBUGGER') {
2167 return {
2168 context: "found '" + token[0] + "'"
2169 };
2170 }
2171 if ((ref = tokenApi.config[this.rule.name]) != null ? ref.console : void 0) {
2172 if (token[1] === 'console' && ((ref1 = tokenApi.peek(1)) != null ? ref1[0] : void 0) === '.') {
2173 method = tokenApi.peek(2);
2174 return {
2175 context: "found 'console." + method[1] + "'"
2176 };
2177 }
2178 }
2179 };
2180
2181 return NoDebugger;
2182
2183})();
2184
2185
2186
2187},{}],25:[function(require,module,exports){
2188var NoEmptyFunctions, isEmptyCode;
2189
2190isEmptyCode = function(node, astApi) {
2191 var nodeName;
2192 nodeName = astApi.getNodeName(node);
2193 return nodeName === 'Code' && node.body.isEmpty();
2194};
2195
2196module.exports = NoEmptyFunctions = (function() {
2197 function NoEmptyFunctions() {}
2198
2199 NoEmptyFunctions.prototype.rule = {
2200 name: 'no_empty_functions',
2201 level: 'ignore',
2202 message: 'Empty function',
2203 description: 'Disallows declaring empty functions. The goal of this rule is that\nunintentional empty callbacks can be detected:\n<pre>\n<code>someFunctionWithCallback ->\ndoSomethingSignificant()\n</code>\n</pre>\nThe problem is that the call to\n<tt>doSomethingSignificant</tt> will be made regardless\nof <tt>someFunctionWithCallback</tt>\'s execution. It can\nbe because you did not indent the call to\n<tt>doSomethingSignificant</tt> properly.\n\nIf you really meant that <tt>someFunctionWithCallback</tt>\nshould call a callback that does nothing, you can write your code\nthis way:\n<pre>\n<code>someFunctionWithCallback ->\n undefined\ndoSomethingSignificant()\n</code>\n</pre>'
2204 };
2205
2206 NoEmptyFunctions.prototype.lintAST = function(node, astApi) {
2207 this.lintNode(node, astApi);
2208 return void 0;
2209 };
2210
2211 NoEmptyFunctions.prototype.lintNode = function(node, astApi) {
2212 var error;
2213 if (isEmptyCode(node, astApi)) {
2214 error = astApi.createError({
2215 lineNumber: node.locationData.first_line + 1
2216 });
2217 this.errors.push(error);
2218 }
2219 return node.eachChild((function(_this) {
2220 return function(child) {
2221 return _this.lintNode(child, astApi);
2222 };
2223 })(this));
2224 };
2225
2226 return NoEmptyFunctions;
2227
2228})();
2229
2230
2231
2232},{}],26:[function(require,module,exports){
2233var NoEmptyParamList;
2234
2235module.exports = NoEmptyParamList = (function() {
2236 function NoEmptyParamList() {}
2237
2238 NoEmptyParamList.prototype.rule = {
2239 name: 'no_empty_param_list',
2240 level: 'ignore',
2241 message: 'Empty parameter list is forbidden',
2242 description: 'This rule prohibits empty parameter lists in function definitions.\n<pre>\n<code># The empty parameter list in here is unnecessary:\nmyFunction = () -&gt;\n\n# We might favor this instead:\nmyFunction = -&gt;\n</code>\n</pre>\nEmpty parameter lists are permitted by default.'
2243 };
2244
2245 NoEmptyParamList.prototype.tokens = ['PARAM_START'];
2246
2247 NoEmptyParamList.prototype.lintToken = function(token, tokenApi) {
2248 var nextType;
2249 nextType = tokenApi.peek()[0];
2250 return nextType === 'PARAM_END';
2251 };
2252
2253 return NoEmptyParamList;
2254
2255})();
2256
2257
2258
2259},{}],27:[function(require,module,exports){
2260var NoImplicitBraces;
2261
2262module.exports = NoImplicitBraces = (function() {
2263 NoImplicitBraces.prototype.rule = {
2264 name: 'no_implicit_braces',
2265 level: 'ignore',
2266 message: 'Implicit braces are forbidden',
2267 strict: true,
2268 description: 'This rule prohibits implicit braces when declaring object literals.\nImplicit braces can make code more difficult to understand,\nespecially when used in combination with optional parenthesis.\n<pre>\n<code># Do you find this code ambiguous? Is it a\n# function call with three arguments or four?\nmyFunction a, b, 1:2, 3:4\n\n# While the same code written in a more\n# explicit manner has no ambiguity.\nmyFunction(a, b, {1:2, 3:4})\n</code>\n</pre>\nImplicit braces are permitted by default, since their use is\nidiomatic CoffeeScript.'
2269 };
2270
2271 NoImplicitBraces.prototype.tokens = ['{', 'OUTDENT', 'CLASS', 'IDENTIFIER'];
2272
2273 function NoImplicitBraces() {
2274 this.isClass = false;
2275 this.className = void 0;
2276 }
2277
2278 NoImplicitBraces.prototype.lintToken = function(token, tokenApi) {
2279 var lineNum, peekTwo, prevToken, type, val;
2280 type = token[0], val = token[1], lineNum = token[2];
2281 if (type === 'OUTDENT' || type === 'CLASS') {
2282 return this.trackClass.apply(this, arguments);
2283 }
2284 if (type === 'IDENTIFIER' && this.isClass && ((this.className == null) || tokenApi.peek(-1)[0] === 'EXTENDS')) {
2285 this.className = val;
2286 }
2287 if (token.generated && type === '{') {
2288 if (!tokenApi.config[this.rule.name].strict) {
2289 prevToken = tokenApi.peek(-1)[0];
2290 if (prevToken === 'INDENT' || prevToken === 'TERMINATOR') {
2291 return;
2292 }
2293 }
2294 if (this.isClass) {
2295 prevToken = tokenApi.peek(-1)[0];
2296 if (prevToken === 'TERMINATOR') {
2297 return;
2298 }
2299 peekTwo = tokenApi.peek(-2);
2300 if (peekTwo[0] === 'IDENTIFIER' && peekTwo[1] === this.className) {
2301 return;
2302 }
2303 }
2304 return true;
2305 }
2306 };
2307
2308 NoImplicitBraces.prototype.trackClass = function(token, tokenApi) {
2309 var ln, n0, n1, ref, ref1, ref2;
2310 ref = [token, tokenApi.peek()], (ref1 = ref[0], n0 = ref1[0], ln = ref1[ref1.length - 1]), (ref2 = ref[1], n1 = ref2[0]);
2311 if (n0 === 'OUTDENT' && n1 === 'TERMINATOR') {
2312 this.isClass = false;
2313 }
2314 if (n0 === 'CLASS') {
2315 this.isClass = true;
2316 this.className = void 0;
2317 }
2318 return null;
2319 };
2320
2321 return NoImplicitBraces;
2322
2323})();
2324
2325
2326
2327},{}],28:[function(require,module,exports){
2328var NoImplicitParens;
2329
2330module.exports = NoImplicitParens = (function() {
2331 function NoImplicitParens() {}
2332
2333 NoImplicitParens.prototype.rule = {
2334 name: 'no_implicit_parens',
2335 level: 'ignore',
2336 message: 'Implicit parens are forbidden',
2337 strict: true,
2338 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.'
2339 };
2340
2341 NoImplicitParens.prototype.tokens = ['CALL_END'];
2342
2343 NoImplicitParens.prototype.lintToken = function(token, tokenApi) {
2344 var i, t;
2345 if (token.generated) {
2346 if (tokenApi.config[this.rule.name].strict !== false) {
2347 return true;
2348 } else {
2349 i = -1;
2350 while (true) {
2351 t = tokenApi.peek(i);
2352 if ((t == null) || (t[0] === 'CALL_START' && t.generated)) {
2353 return true;
2354 }
2355 if (t[2].first_line !== token[2].first_line) {
2356 return null;
2357 }
2358 i -= 1;
2359 }
2360 }
2361 }
2362 };
2363
2364 return NoImplicitParens;
2365
2366})();
2367
2368
2369
2370},{}],29:[function(require,module,exports){
2371var NoInterpolationInSingleQuotes;
2372
2373module.exports = NoInterpolationInSingleQuotes = (function() {
2374 function NoInterpolationInSingleQuotes() {}
2375
2376 NoInterpolationInSingleQuotes.prototype.rule = {
2377 name: 'no_interpolation_in_single_quotes',
2378 level: 'ignore',
2379 message: 'Interpolation in single quoted strings is forbidden',
2380 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.'
2381 };
2382
2383 NoInterpolationInSingleQuotes.prototype.tokens = ['STRING'];
2384
2385 NoInterpolationInSingleQuotes.prototype.lintToken = function(token, tokenApi) {
2386 var hasInterpolation, tokenValue;
2387 tokenValue = token[1];
2388 hasInterpolation = tokenValue.match(/^\'.*#\{[^}]+\}.*\'$/);
2389 return hasInterpolation;
2390 };
2391
2392 return NoInterpolationInSingleQuotes;
2393
2394})();
2395
2396
2397
2398},{}],30:[function(require,module,exports){
2399var NoNestedStringInterpolation;
2400
2401module.exports = NoNestedStringInterpolation = (function() {
2402 NoNestedStringInterpolation.prototype.rule = {
2403 name: 'no_nested_string_interpolation',
2404 level: 'warn',
2405 message: 'Nested string interpolation is forbidden',
2406 description: 'This rule warns about nested string interpolation,\nas it tends to make code harder to read and understand.\n<pre>\n<code># Good!\nstr = "Book by #{firstName.toUpperCase()} #{lastName.toUpperCase()}"\n\n# Bad!\nstr = "Book by #{"#{firstName} #{lastName}".toUpperCase()}"\n</code>\n</pre>'
2407 };
2408
2409 NoNestedStringInterpolation.prototype.tokens = ['STRING_START', 'STRING_END'];
2410
2411 function NoNestedStringInterpolation() {
2412 this.startedStrings = 0;
2413 this.generatedError = false;
2414 }
2415
2416 NoNestedStringInterpolation.prototype.lintToken = function(arg, tokenApi) {
2417 var type;
2418 type = arg[0];
2419 if (type === 'STRING_START') {
2420 return this.trackStringStart();
2421 } else {
2422 return this.trackStringEnd();
2423 }
2424 };
2425
2426 NoNestedStringInterpolation.prototype.trackStringStart = function() {
2427 this.startedStrings += 1;
2428 if (this.startedStrings <= 1 || this.generatedError) {
2429 return;
2430 }
2431 this.generatedError = true;
2432 return true;
2433 };
2434
2435 NoNestedStringInterpolation.prototype.trackStringEnd = function() {
2436 this.startedStrings -= 1;
2437 if (this.startedStrings === 1) {
2438 return this.generatedError = false;
2439 }
2440 };
2441
2442 return NoNestedStringInterpolation;
2443
2444})();
2445
2446
2447
2448},{}],31:[function(require,module,exports){
2449var NoPlusPlus;
2450
2451module.exports = NoPlusPlus = (function() {
2452 function NoPlusPlus() {}
2453
2454 NoPlusPlus.prototype.rule = {
2455 name: 'no_plusplus',
2456 level: 'ignore',
2457 message: 'The increment and decrement operators are forbidden',
2458 description: 'This rule forbids the increment and decrement arithmetic operators.\nSome people believe the <tt>++</tt> and <tt>--</tt> to be cryptic\nand the cause of bugs due to misunderstandings of their precedence\nrules.\nThis rule is disabled by default.'
2459 };
2460
2461 NoPlusPlus.prototype.tokens = ['++', '--'];
2462
2463 NoPlusPlus.prototype.lintToken = function(token, tokenApi) {
2464 return {
2465 context: "found '" + token[0] + "'"
2466 };
2467 };
2468
2469 return NoPlusPlus;
2470
2471})();
2472
2473
2474
2475},{}],32:[function(require,module,exports){
2476var NoPrivateFunctionFatArrows,
2477 bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
2478 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; };
2479
2480module.exports = NoPrivateFunctionFatArrows = (function() {
2481 function NoPrivateFunctionFatArrows() {
2482 this.isFatArrowCode = bind(this.isFatArrowCode, this);
2483 this.isObject = bind(this.isObject, this);
2484 this.isValue = bind(this.isValue, this);
2485 this.isClass = bind(this.isClass, this);
2486 this.isCode = bind(this.isCode, this);
2487 }
2488
2489 NoPrivateFunctionFatArrows.prototype.rule = {
2490 name: 'no_private_function_fat_arrows',
2491 level: 'warn',
2492 message: 'Used the fat arrow for a private function',
2493 description: 'Warns when you use the fat arrow for a private function\ninside a class definition scope. It is not necessary and\nit does not do anything.'
2494 };
2495
2496 NoPrivateFunctionFatArrows.prototype.lintAST = function(node, astApi) {
2497 this.astApi = astApi;
2498 this.lintNode(node);
2499 return void 0;
2500 };
2501
2502 NoPrivateFunctionFatArrows.prototype.lintNode = function(node, functions) {
2503 var error;
2504 if (functions == null) {
2505 functions = [];
2506 }
2507 if (this.isFatArrowCode(node) && indexOf.call(functions, node) >= 0) {
2508 error = this.astApi.createError({
2509 lineNumber: node.locationData.first_line + 1
2510 });
2511 this.errors.push(error);
2512 }
2513 return node.eachChild((function(_this) {
2514 return function(child) {
2515 return _this.lintNode(child, (function() {
2516 switch (false) {
2517 case !this.isClass(node):
2518 return this.functionsOfClass(node);
2519 case !this.isCode(node):
2520 return [];
2521 default:
2522 return functions;
2523 }
2524 }).call(_this));
2525 };
2526 })(this));
2527 };
2528
2529 NoPrivateFunctionFatArrows.prototype.isCode = function(node) {
2530 return this.astApi.getNodeName(node) === 'Code';
2531 };
2532
2533 NoPrivateFunctionFatArrows.prototype.isClass = function(node) {
2534 return this.astApi.getNodeName(node) === 'Class';
2535 };
2536
2537 NoPrivateFunctionFatArrows.prototype.isValue = function(node) {
2538 return this.astApi.getNodeName(node) === 'Value';
2539 };
2540
2541 NoPrivateFunctionFatArrows.prototype.isObject = function(node) {
2542 return this.astApi.getNodeName(node) === 'Obj';
2543 };
2544
2545 NoPrivateFunctionFatArrows.prototype.isFatArrowCode = function(node) {
2546 return this.isCode(node) && node.bound;
2547 };
2548
2549 NoPrivateFunctionFatArrows.prototype.functionsOfClass = function(classNode) {
2550 var bodyNode, bodyValues;
2551 bodyValues = (function() {
2552 var i, len, ref, results;
2553 ref = classNode.body.expressions;
2554 results = [];
2555 for (i = 0, len = ref.length; i < len; i++) {
2556 bodyNode = ref[i];
2557 if (this.isValue(bodyNode) && this.isObject(bodyNode.base)) {
2558 continue;
2559 }
2560 results.push(bodyNode.value);
2561 }
2562 return results;
2563 }).call(this);
2564 return bodyValues.filter(this.isCode);
2565 };
2566
2567 return NoPrivateFunctionFatArrows;
2568
2569})();
2570
2571
2572
2573},{}],33:[function(require,module,exports){
2574var NoStandAloneAt;
2575
2576module.exports = NoStandAloneAt = (function() {
2577 function NoStandAloneAt() {}
2578
2579 NoStandAloneAt.prototype.rule = {
2580 name: 'no_stand_alone_at',
2581 level: 'ignore',
2582 message: '@ must not be used stand alone',
2583 description: 'This rule checks that no stand alone @ are in use, they are\ndiscouraged. Further information in CoffeeScript issue <a\nhref="https://github.com/jashkenas/coffee-script/issues/1601">\n#1601</a>'
2584 };
2585
2586 NoStandAloneAt.prototype.tokens = ['@'];
2587
2588 NoStandAloneAt.prototype.lintToken = function(token, tokenApi) {
2589 var isDot, isIdentifier, isIndexStart, isValidProtoProperty, nextToken, protoProperty, spaced;
2590 nextToken = tokenApi.peek();
2591 spaced = token.spaced;
2592 isIdentifier = nextToken[0] === 'IDENTIFIER';
2593 isIndexStart = nextToken[0] === 'INDEX_START';
2594 isDot = nextToken[0] === '.';
2595 if (nextToken[0] === '::') {
2596 protoProperty = tokenApi.peek(2);
2597 isValidProtoProperty = protoProperty[0] === 'IDENTIFIER';
2598 }
2599 if (spaced || (!isIdentifier && !isIndexStart && !isDot && !isValidProtoProperty)) {
2600 return true;
2601 }
2602 };
2603
2604 return NoStandAloneAt;
2605
2606})();
2607
2608
2609
2610},{}],34:[function(require,module,exports){
2611var NoTabs, indentationRegex,
2612 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; };
2613
2614indentationRegex = /\S/;
2615
2616module.exports = NoTabs = (function() {
2617 function NoTabs() {}
2618
2619 NoTabs.prototype.rule = {
2620 name: 'no_tabs',
2621 level: 'error',
2622 message: 'Line contains tab indentation',
2623 description: 'This rule forbids tabs in indentation. Enough said. It is enabled by\ndefault.'
2624 };
2625
2626 NoTabs.prototype.lintLine = function(line, lineApi) {
2627 var indentation;
2628 indentation = line.split(indentationRegex)[0];
2629 if (lineApi.lineHasToken() && indexOf.call(indentation, '\t') >= 0) {
2630 return true;
2631 } else {
2632 return null;
2633 }
2634 };
2635
2636 return NoTabs;
2637
2638})();
2639
2640
2641
2642},{}],35:[function(require,module,exports){
2643var NoThis;
2644
2645module.exports = NoThis = (function() {
2646 function NoThis() {}
2647
2648 NoThis.prototype.rule = {
2649 name: 'no_this',
2650 level: 'ignore',
2651 message: "Don't use 'this', use '@' instead",
2652 description: 'This rule prohibits \'this\'.\nUse \'@\' instead.'
2653 };
2654
2655 NoThis.prototype.tokens = ['THIS'];
2656
2657 NoThis.prototype.lintToken = function(token, tokenApi) {
2658 var level, nextToken, ref;
2659 level = tokenApi.config.no_stand_alone_at.level;
2660 nextToken = (ref = tokenApi.peek(1)) != null ? ref[0] : void 0;
2661 if (!(level !== 'ignore' && nextToken !== '.')) {
2662 return true;
2663 }
2664 };
2665
2666 return NoThis;
2667
2668})();
2669
2670
2671
2672},{}],36:[function(require,module,exports){
2673var NoThrowingStrings;
2674
2675module.exports = NoThrowingStrings = (function() {
2676 function NoThrowingStrings() {}
2677
2678 NoThrowingStrings.prototype.rule = {
2679 name: 'no_throwing_strings',
2680 level: 'error',
2681 message: 'Throwing strings is forbidden',
2682 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.'
2683 };
2684
2685 NoThrowingStrings.prototype.tokens = ['THROW'];
2686
2687 NoThrowingStrings.prototype.lintToken = function(token, tokenApi) {
2688 var n1, nextIsString, ref;
2689 ref = tokenApi.peek(), n1 = ref[0];
2690 nextIsString = n1 === 'STRING' || n1 === 'STRING_START';
2691 return nextIsString;
2692 };
2693
2694 return NoThrowingStrings;
2695
2696})();
2697
2698
2699
2700},{}],37:[function(require,module,exports){
2701var NoTrailingSemicolons, regexes,
2702 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; },
2703 slice = [].slice;
2704
2705regexes = {
2706 trailingSemicolon: /;\r?$/
2707};
2708
2709module.exports = NoTrailingSemicolons = (function() {
2710 function NoTrailingSemicolons() {}
2711
2712 NoTrailingSemicolons.prototype.rule = {
2713 name: 'no_trailing_semicolons',
2714 level: 'error',
2715 message: 'Line contains a trailing semicolon',
2716 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.'
2717 };
2718
2719 NoTrailingSemicolons.prototype.lintLine = function(line, lineApi) {
2720 var endPos, first, hasNewLine, hasSemicolon, i, last, lineTokens, newLine, ref, ref1, startCounter, startPos, stopTokens, tokenLen;
2721 lineTokens = lineApi.getLineTokens();
2722 tokenLen = lineTokens.length;
2723 stopTokens = ['TERMINATOR', 'HERECOMMENT'];
2724 if (tokenLen === 1 && (ref = lineTokens[0][0], indexOf.call(stopTokens, ref) >= 0)) {
2725 return;
2726 }
2727 newLine = line;
2728 if (tokenLen > 1 && lineTokens[tokenLen - 1][0] === 'TERMINATOR') {
2729 startPos = lineTokens[tokenLen - 2][2].last_column + 1;
2730 endPos = lineTokens[tokenLen - 1][2].first_column;
2731 if (startPos !== endPos) {
2732 startCounter = startPos;
2733 while (line[startCounter] !== '#' && startCounter < line.length) {
2734 startCounter++;
2735 }
2736 newLine = line.substring(0, startCounter).replace(/\s*$/, '');
2737 }
2738 }
2739 hasSemicolon = regexes.trailingSemicolon.test(newLine);
2740 first = 2 <= lineTokens.length ? slice.call(lineTokens, 0, i = lineTokens.length - 1) : (i = 0, []), last = lineTokens[i++];
2741 hasNewLine = last && (last.newLine != null);
2742 if (hasSemicolon && !hasNewLine && lineApi.lineHasToken() && !((ref1 = last[0]) === 'STRING' || ref1 === 'IDENTIFIER' || ref1 === 'STRING_END')) {
2743 return true;
2744 }
2745 };
2746
2747 return NoTrailingSemicolons;
2748
2749})();
2750
2751
2752
2753},{}],38:[function(require,module,exports){
2754var NoTrailingWhitespace, regexes;
2755
2756regexes = {
2757 trailingWhitespace: /[^\s]+[\t ]+\r?$/,
2758 onlySpaces: /^[\t ]+\r?$/,
2759 lineHasComment: /^\s*[^\#]*\#/
2760};
2761
2762module.exports = NoTrailingWhitespace = (function() {
2763 function NoTrailingWhitespace() {}
2764
2765 NoTrailingWhitespace.prototype.rule = {
2766 name: 'no_trailing_whitespace',
2767 level: 'error',
2768 message: 'Line ends with trailing whitespace',
2769 allowed_in_comments: false,
2770 allowed_in_empty_lines: true,
2771 description: 'This rule forbids trailing whitespace in your code, since it is\nneedless cruft. It is enabled by default.'
2772 };
2773
2774 NoTrailingWhitespace.prototype.lintLine = function(line, lineApi) {
2775 var i, len, ref, ref1, ref2, str, token, tokens;
2776 if (!((ref = lineApi.config['no_trailing_whitespace']) != null ? ref.allowed_in_empty_lines : void 0)) {
2777 if (regexes.onlySpaces.test(line)) {
2778 return true;
2779 }
2780 }
2781 if (regexes.trailingWhitespace.test(line)) {
2782 if (!((ref1 = lineApi.config['no_trailing_whitespace']) != null ? ref1.allowed_in_comments : void 0)) {
2783 return true;
2784 }
2785 line = line;
2786 tokens = lineApi.tokensByLine[lineApi.lineNumber];
2787 if (!tokens) {
2788 return null;
2789 }
2790 ref2 = (function() {
2791 var j, len, results;
2792 results = [];
2793 for (j = 0, len = tokens.length; j < len; j++) {
2794 token = tokens[j];
2795 if (token[0] === 'STRING') {
2796 results.push(token[1]);
2797 }
2798 }
2799 return results;
2800 })();
2801 for (i = 0, len = ref2.length; i < len; i++) {
2802 str = ref2[i];
2803 line = line.replace(str, 'STRING');
2804 }
2805 if (!regexes.lineHasComment.test(line)) {
2806 return true;
2807 }
2808 }
2809 };
2810
2811 return NoTrailingWhitespace;
2812
2813})();
2814
2815
2816
2817},{}],39:[function(require,module,exports){
2818var NoUnnecessaryDoubleQuotes;
2819
2820module.exports = NoUnnecessaryDoubleQuotes = (function() {
2821 NoUnnecessaryDoubleQuotes.prototype.rule = {
2822 name: 'no_unnecessary_double_quotes',
2823 level: 'ignore',
2824 message: 'Unnecessary double quotes are forbidden',
2825 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.'
2826 };
2827
2828 function NoUnnecessaryDoubleQuotes() {
2829 this.regexps = [];
2830 this.interpolationLevel = 0;
2831 }
2832
2833 NoUnnecessaryDoubleQuotes.prototype.tokens = ['STRING', 'STRING_START', 'STRING_END'];
2834
2835 NoUnnecessaryDoubleQuotes.prototype.lintToken = function(token, tokenApi) {
2836 var hasLegalConstructs, ref, stringValue, tokenValue, type;
2837 type = token[0], tokenValue = token[1];
2838 if (type === 'STRING_START' || type === 'STRING_END') {
2839 return this.trackParens.apply(this, arguments);
2840 }
2841 stringValue = tokenValue.match(/^\"(.*)\"$/);
2842 if (!stringValue) {
2843 return false;
2844 }
2845 if (((ref = tokenApi.peek(2)) != null ? ref[0] : void 0) === 'REGEX_END') {
2846 return false;
2847 }
2848 hasLegalConstructs = this.isInInterpolation() || this.hasSingleQuote(tokenValue);
2849 return !hasLegalConstructs;
2850 };
2851
2852 NoUnnecessaryDoubleQuotes.prototype.isInInterpolation = function() {
2853 return this.interpolationLevel > 0;
2854 };
2855
2856 NoUnnecessaryDoubleQuotes.prototype.trackParens = function(token, tokenApi) {
2857 if (token[0] === 'STRING_START') {
2858 this.interpolationLevel += 1;
2859 } else if (token[0] === 'STRING_END') {
2860 this.interpolationLevel -= 1;
2861 }
2862 return null;
2863 };
2864
2865 NoUnnecessaryDoubleQuotes.prototype.hasSingleQuote = function(tokenValue) {
2866 return tokenValue.indexOf("'") !== -1;
2867 };
2868
2869 return NoUnnecessaryDoubleQuotes;
2870
2871})();
2872
2873
2874
2875},{}],40:[function(require,module,exports){
2876var NoUnnecessaryFatArrows, any,
2877 bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
2878
2879any = function(arr, test) {
2880 return arr.reduce((function(res, elt) {
2881 return res || test(elt);
2882 }), false);
2883};
2884
2885module.exports = NoUnnecessaryFatArrows = (function() {
2886 function NoUnnecessaryFatArrows() {
2887 this.needsFatArrow = bind(this.needsFatArrow, this);
2888 this.isThis = bind(this.isThis, this);
2889 }
2890
2891 NoUnnecessaryFatArrows.prototype.rule = {
2892 name: 'no_unnecessary_fat_arrows',
2893 level: 'warn',
2894 message: 'Unnecessary fat arrow',
2895 description: 'Disallows defining functions with fat arrows when `this`\nis not used within the function.'
2896 };
2897
2898 NoUnnecessaryFatArrows.prototype.lintAST = function(node, astApi) {
2899 this.astApi = astApi;
2900 this.lintNode(node);
2901 return void 0;
2902 };
2903
2904 NoUnnecessaryFatArrows.prototype.lintNode = function(node) {
2905 var error;
2906 if ((this.isFatArrowCode(node)) && (!this.needsFatArrow(node))) {
2907 error = this.astApi.createError({
2908 lineNumber: node.locationData.first_line + 1
2909 });
2910 this.errors.push(error);
2911 }
2912 return node.eachChild((function(_this) {
2913 return function(child) {
2914 return _this.lintNode(child);
2915 };
2916 })(this));
2917 };
2918
2919 NoUnnecessaryFatArrows.prototype.isCode = function(node) {
2920 return this.astApi.getNodeName(node) === 'Code';
2921 };
2922
2923 NoUnnecessaryFatArrows.prototype.isFatArrowCode = function(node) {
2924 return this.isCode(node) && node.bound;
2925 };
2926
2927 NoUnnecessaryFatArrows.prototype.isValue = function(node) {
2928 return this.astApi.getNodeName(node) === 'Value';
2929 };
2930
2931 NoUnnecessaryFatArrows.prototype.isThis = function(node) {
2932 return this.isValue(node) && node.base.value === 'this';
2933 };
2934
2935 NoUnnecessaryFatArrows.prototype.needsFatArrow = function(node) {
2936 return this.isCode(node) && (any(node.params, (function(_this) {
2937 return function(param) {
2938 return param.contains(_this.isThis) != null;
2939 };
2940 })(this)) || (node.body.contains(this.isThis) != null) || (node.body.contains((function(_this) {
2941 return function(child) {
2942 if (!_this.astApi.getNodeName(child)) {
2943 return (child.isSuper != null) && child.isSuper;
2944 } else {
2945 return _this.isFatArrowCode(child) && _this.needsFatArrow(child);
2946 }
2947 };
2948 })(this)) != null));
2949 };
2950
2951 return NoUnnecessaryFatArrows;
2952
2953})();
2954
2955
2956
2957},{}],41:[function(require,module,exports){
2958var NonEmptyConstructorNeedsParens, ParentClass,
2959 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; },
2960 hasProp = {}.hasOwnProperty;
2961
2962ParentClass = require('./empty_constructor_needs_parens.coffee');
2963
2964module.exports = NonEmptyConstructorNeedsParens = (function(superClass) {
2965 extend(NonEmptyConstructorNeedsParens, superClass);
2966
2967 function NonEmptyConstructorNeedsParens() {
2968 return NonEmptyConstructorNeedsParens.__super__.constructor.apply(this, arguments);
2969 }
2970
2971 NonEmptyConstructorNeedsParens.prototype.rule = {
2972 name: 'non_empty_constructor_needs_parens',
2973 level: 'ignore',
2974 message: 'Invoking a constructor without parens and with arguments',
2975 description: 'Requires constructors with parameters to include the parens'
2976 };
2977
2978 NonEmptyConstructorNeedsParens.prototype.handleExpectedCallStart = function(expectedCallStart) {
2979 if (expectedCallStart[0] === 'CALL_START' && expectedCallStart.generated) {
2980 return true;
2981 }
2982 };
2983
2984 return NonEmptyConstructorNeedsParens;
2985
2986})(ParentClass);
2987
2988
2989
2990},{"./empty_constructor_needs_parens.coffee":15}],42:[function(require,module,exports){
2991var PreferEnglishOperator;
2992
2993module.exports = PreferEnglishOperator = (function() {
2994 function PreferEnglishOperator() {}
2995
2996 PreferEnglishOperator.prototype.rule = {
2997 name: 'prefer_english_operator',
2998 level: 'ignore',
2999 message: 'Don\'t use &&, ||, ==, !=, or !',
3000 doubleNotLevel: 'ignore',
3001 description: 'This rule prohibits &&, ||, ==, != and !.\nUse and, or, is, isnt, and not instead.\n!! for converting to a boolean is ignored.'
3002 };
3003
3004 PreferEnglishOperator.prototype.tokens = ['COMPARE', 'UNARY_MATH', 'LOGIC'];
3005
3006 PreferEnglishOperator.prototype.lintToken = function(token, tokenApi) {
3007 var actual_token, config, context, first_column, last_column, level, line, ref;
3008 config = tokenApi.config[this.rule.name];
3009 level = config.level;
3010 ref = token[2], first_column = ref.first_column, last_column = ref.last_column;
3011 line = tokenApi.lines[tokenApi.lineNumber];
3012 actual_token = line.slice(first_column, +last_column + 1 || 9e9);
3013 context = (function() {
3014 var ref1, ref2;
3015 switch (actual_token) {
3016 case '==':
3017 return 'Replace "==" with "is"';
3018 case '!=':
3019 return 'Replace "!=" with "isnt"';
3020 case '||':
3021 return 'Replace "||" with "or"';
3022 case '&&':
3023 return 'Replace "&&" with "and"';
3024 case '!':
3025 if (((ref1 = tokenApi.peek(1)) != null ? ref1[0] : void 0) === 'UNARY_MATH') {
3026 level = config.doubleNotLevel;
3027 return '"?" is usually better than "!!"';
3028 } else if (((ref2 = tokenApi.peek(-1)) != null ? ref2[0] : void 0) === 'UNARY_MATH') {
3029 return void 0;
3030 } else {
3031 return 'Replace "!" with "not"';
3032 }
3033 break;
3034 default:
3035 return void 0;
3036 }
3037 })();
3038 if (context != null) {
3039 return {
3040 level: level,
3041 context: context
3042 };
3043 }
3044 };
3045
3046 return PreferEnglishOperator;
3047
3048})();
3049
3050
3051
3052},{}],43:[function(require,module,exports){
3053var SpaceOperators,
3054 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; };
3055
3056module.exports = SpaceOperators = (function() {
3057 SpaceOperators.prototype.rule = {
3058 name: 'space_operators',
3059 level: 'ignore',
3060 message: 'Operators must be spaced properly',
3061 description: 'This rule enforces that operators have spaces around them.'
3062 };
3063
3064 SpaceOperators.prototype.tokens = ['+', '-', '=', '**', 'MATH', 'COMPARE', 'LOGIC', 'COMPOUND_ASSIGN', 'STRING_START', 'STRING_END', 'CALL_START', 'CALL_END'];
3065
3066 function SpaceOperators() {
3067 this.callTokens = [];
3068 this.parenTokens = [];
3069 this.interpolationLevel = 0;
3070 }
3071
3072 SpaceOperators.prototype.lintToken = function(arg, tokenApi) {
3073 var type;
3074 type = arg[0];
3075 if (type === 'CALL_START' || type === 'CALL_END') {
3076 this.trackCall.apply(this, arguments);
3077 return;
3078 }
3079 if (type === 'STRING_START' || type === 'STRING_END') {
3080 return this.trackParens.apply(this, arguments);
3081 }
3082 if (type === '+' || type === '-') {
3083 return this.lintPlus.apply(this, arguments);
3084 } else {
3085 return this.lintMath.apply(this, arguments);
3086 }
3087 };
3088
3089 SpaceOperators.prototype.lintPlus = function(token, tokenApi) {
3090 var isUnary, p, ref, unaries;
3091 if (this.isInInterpolation() || this.isInExtendedRegex()) {
3092 return null;
3093 }
3094 p = tokenApi.peek(-1);
3095 unaries = ['TERMINATOR', '(', '=', '-', '+', ',', 'CALL_START', 'INDEX_START', '..', '...', 'COMPARE', 'IF', 'THROW', 'LOGIC', 'POST_IF', ':', '[', 'INDENT', 'COMPOUND_ASSIGN', 'RETURN', 'MATH', 'BY', 'LEADING_WHEN'];
3096 isUnary = !p ? false : (ref = p[0], indexOf.call(unaries, ref) >= 0);
3097 if ((isUnary && (token.spaced != null)) || (!isUnary && !token.newLine && (!token.spaced || (p && !p.spaced)))) {
3098 return {
3099 context: token[1]
3100 };
3101 } else {
3102 return null;
3103 }
3104 };
3105
3106 SpaceOperators.prototype.lintMath = function(token, tokenApi) {
3107 var p;
3108 p = tokenApi.peek(-1);
3109 if (!token.newLine && (!token.spaced || (p && !p.spaced))) {
3110 return {
3111 context: token[1]
3112 };
3113 } else {
3114 return null;
3115 }
3116 };
3117
3118 SpaceOperators.prototype.isInExtendedRegex = function() {
3119 var i, len, ref, t;
3120 ref = this.callTokens;
3121 for (i = 0, len = ref.length; i < len; i++) {
3122 t = ref[i];
3123 if (t.isRegex) {
3124 return true;
3125 }
3126 }
3127 return false;
3128 };
3129
3130 SpaceOperators.prototype.isInInterpolation = function() {
3131 return this.interpolationLevel > 0;
3132 };
3133
3134 SpaceOperators.prototype.trackCall = function(token, tokenApi) {
3135 var p;
3136 if (token[0] === 'CALL_START') {
3137 p = tokenApi.peek(-1);
3138 token.isRegex = p && p[0] === 'IDENTIFIER' && p[1] === 'RegExp';
3139 this.callTokens.push(token);
3140 } else {
3141 this.callTokens.pop();
3142 }
3143 return null;
3144 };
3145
3146 SpaceOperators.prototype.trackParens = function(token, tokenApi) {
3147 if (token[0] === 'STRING_START') {
3148 this.interpolationLevel += 1;
3149 } else if (token[0] === 'STRING_END') {
3150 this.interpolationLevel -= 1;
3151 }
3152 return null;
3153 };
3154
3155 return SpaceOperators;
3156
3157})();
3158
3159
3160
3161},{}],44:[function(require,module,exports){
3162var SpacingAfterComma;
3163
3164module.exports = SpacingAfterComma = (function() {
3165 SpacingAfterComma.prototype.rule = {
3166 name: 'spacing_after_comma',
3167 level: 'ignore',
3168 message: 'a space is required after commas',
3169 description: 'This rule checks to make sure you have a space after commas.'
3170 };
3171
3172 SpacingAfterComma.prototype.tokens = [',', 'REGEX_START', 'REGEX_END'];
3173
3174 function SpacingAfterComma() {
3175 this.inRegex = false;
3176 }
3177
3178 SpacingAfterComma.prototype.lintToken = function(token, tokenApi) {
3179 var type;
3180 type = token[0];
3181 if (type === 'REGEX_START') {
3182 this.inRegex = true;
3183 return;
3184 }
3185 if (type === 'REGEX_END') {
3186 this.inRegex = false;
3187 return;
3188 }
3189 if (!(token.spaced || token.newLine || token.generated || this.isRegexFlag(token, tokenApi))) {
3190 return true;
3191 }
3192 };
3193
3194 SpacingAfterComma.prototype.isRegexFlag = function(token, tokenApi) {
3195 var maybeEnd;
3196 if (!this.inRegex) {
3197 return false;
3198 }
3199 maybeEnd = tokenApi.peek(3);
3200 return (maybeEnd != null ? maybeEnd[0] : void 0) === 'REGEX_END';
3201 };
3202
3203 return SpacingAfterComma;
3204
3205})();
3206
3207
3208
3209},{}],45:[function(require,module,exports){
3210var TransformMessesUpLineNumbers;
3211
3212module.exports = TransformMessesUpLineNumbers = (function() {
3213 function TransformMessesUpLineNumbers() {}
3214
3215 TransformMessesUpLineNumbers.prototype.rule = {
3216 name: 'transform_messes_up_line_numbers',
3217 level: 'warn',
3218 message: 'Transforming source messes up line numbers',
3219 description: 'This rule detects when changes are made by transform function,\nand warns that line numbers are probably incorrect.'
3220 };
3221
3222 TransformMessesUpLineNumbers.prototype.tokens = [];
3223
3224 TransformMessesUpLineNumbers.prototype.lintToken = function(token, tokenApi) {};
3225
3226 return TransformMessesUpLineNumbers;
3227
3228})();
3229
3230
3231
3232},{}]},{},[1])(1)
3233});
\No newline at end of file