coffeelint 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
- ---
2
- SHA512:
3
- metadata.gz: 63c4f9e432f0449966a6d8ee4fbd925664ad31306c5667924ad661ab1f64ee6a6f460b77d525af3909109697faa4566c469e21268dd1aaac2a3a28b63640c67f
4
- data.tar.gz: 9c3a1f3f7e4c9efea1518092500179ce587ce224f92ab5155e9ec9521115f742ab5f414a94adc3915c04cecdbf68ac51a2e274fa9aba5c50124cdf9e6c7431ac
5
- SHA1:
6
- metadata.gz: 0a341cc8ac4b92c7b9cd7c40ef2f5a11ef459477
7
- data.tar.gz: 076907c79408504ee070bc444f8862408a31e8f6
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3ffd964a01f745c14f47fdd18b222a3d50546380
4
+ data.tar.gz: 31713ed65784af39efa95b92f0053b4ac6a806ae
5
+ SHA512:
6
+ metadata.gz: d1b2a3f746db3dda6291fd9f83842e648c08763a8ac5b033134c03246529a3a686ef6f78810b273ed0cfdc3a2778a1e056f60513e97e19b2047b533150459be6
7
+ data.tar.gz: 5ad00bf65f2191582032dd5599b332c5a936907213db8213ea192a601233eef97c94246c643e18c4943756e60f93ccdfab18af97fc9b96e0e12ee39929a091ab
data/Rakefile CHANGED
@@ -8,3 +8,16 @@ task :console do
8
8
  sh "irb -rubygems -I lib -r coffeelint.rb"
9
9
  end
10
10
 
11
+ task :compile => [:prepare, :build]
12
+
13
+ task :prepare do
14
+ sh "git submodule init"
15
+ sh "git submodule update"
16
+
17
+ Dir.chdir('coffeelint') do
18
+ sh "npm install"
19
+ sh "npm run compile"
20
+ end
21
+
22
+ sh "rake spec"
23
+ end
@@ -14,7 +14,7 @@ Gem::Specification.new do |gem|
14
14
  gem.licenses = ["MIT"]
15
15
 
16
16
  gem.files = `git ls-files`.split($/)
17
- gem.files << 'coffeelint/src/coffeelint.coffee'
17
+ gem.files << 'coffeelint/lib/coffeelint.js'
18
18
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
19
19
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
20
20
  gem.require_paths = ["lib"]
@@ -0,0 +1,2015 @@
1
+ (function(e){if("function"==typeof bootstrap)bootstrap("coffeelint",e);else if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else if("undefined"!=typeof ses){if(!ses.ok())return;ses.makeCoffeelint=e}else"undefined"!=typeof window?window.coffeelint=e():global.coffeelint=e()})(function(){var define,ses,bootstrap,module,exports;
2
+ return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
3
+ module.exports={
4
+ "name": "coffeelint",
5
+ "description": "Lint your CoffeeScript",
6
+ "version": "1.0.6",
7
+ "homepage": "http://www.coffeelint.org",
8
+ "keywords": [
9
+ "lint",
10
+ "coffeescript",
11
+ "coffee-script"
12
+ ],
13
+ "author": "Matthew Perpick <clutchski@gmail.com>",
14
+ "main": "./lib/coffeelint.js",
15
+ "engines": {
16
+ "node": ">=0.8.0"
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git://github.com/clutchski/coffeelint.git"
21
+ },
22
+ "bin": {
23
+ "coffeelint": "./bin/coffeelint"
24
+ },
25
+ "dependencies": {
26
+ "optimist": ">=0.2.8",
27
+ "coffee-script": ">=1.6.0",
28
+ "glob": ">=3.1.9",
29
+ "browserify": "~2.26.0",
30
+ "coffeeify": "~0.5.1"
31
+ },
32
+ "devDependencies": {
33
+ "vows": ">=0.6.0",
34
+ "underscore": ">=1.4.4"
35
+ },
36
+ "licenses": [
37
+ {
38
+ "type": "MIT",
39
+ "url": "http://github.com/clutchski/coffeelint/raw/master/LICENSE"
40
+ }
41
+ ],
42
+ "scripts": {
43
+ "pretest": "npm run compile",
44
+ "test": "vows --spec test/*.coffee test/*.litcoffee",
45
+ "posttest": "npm run lint",
46
+ "prepublish": "npm run compile",
47
+ "install": "echo 'process.exit(require(\"fs\").existsSync(\"lib/commandline.js\") ? 0 : 1)' | node || npm run compile",
48
+ "lint": "npm run compile && ./bin/coffeelint -f coffeelint.json src/*.coffee test/*.coffee test/*.litcoffee",
49
+ "lint-csv": "npm run compile && ./bin/coffeelint --csv -f coffeelint.json src/*.coffee test/*.coffee",
50
+ "lint-jslint": "npm run compile && ./bin/coffeelint --jslint -f coffeelint.json src/*.coffee test/*.coffee",
51
+ "compile": "coffee -c -o lib src && ./node_modules/browserify/bin/cmd.js -t coffeeify -s coffeelint -e src/coffeelint.coffee > lib/coffeelint.js"
52
+ }
53
+ }
54
+
55
+ },{}],2:[function(require,module,exports){
56
+ var ASTApi, ASTLinter, BaseLinter,
57
+ __hasProp = {}.hasOwnProperty,
58
+ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
59
+
60
+ BaseLinter = require('./base_linter.coffee');
61
+
62
+ ASTApi = (function() {
63
+ function ASTApi(config) {
64
+ this.config = config;
65
+ }
66
+
67
+ return ASTApi;
68
+
69
+ })();
70
+
71
+ module.exports = ASTLinter = (function(_super) {
72
+ __extends(ASTLinter, _super);
73
+
74
+ function ASTLinter(source, config, rules, CoffeeScript) {
75
+ this.CoffeeScript = CoffeeScript;
76
+ ASTLinter.__super__.constructor.call(this, source, config, rules);
77
+ this.astApi = new ASTApi(this.config);
78
+ }
79
+
80
+ ASTLinter.prototype.acceptRule = function(rule) {
81
+ return typeof rule.lintAST === 'function';
82
+ };
83
+
84
+ ASTLinter.prototype.lint = function() {
85
+ var coffeeError, err, errors, rule, v, _i, _len, _ref,
86
+ _this = this;
87
+ errors = [];
88
+ try {
89
+ this.node = this.CoffeeScript.nodes(this.source);
90
+ } catch (_error) {
91
+ coffeeError = _error;
92
+ err = this._parseCoffeeScriptError(coffeeError);
93
+ if (err != null) {
94
+ errors.push(err);
95
+ }
96
+ return errors;
97
+ }
98
+ _ref = this.rules;
99
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
100
+ rule = _ref[_i];
101
+ this.astApi.createError = function(attrs) {
102
+ if (attrs == null) {
103
+ attrs = {};
104
+ }
105
+ return _this.createError(rule.rule.name, attrs);
106
+ };
107
+ rule.errors = errors;
108
+ v = this.normalizeResult(rule, rule.lintAST(this.node, this.astApi));
109
+ if (v != null) {
110
+ return v;
111
+ }
112
+ }
113
+ return errors;
114
+ };
115
+
116
+ ASTLinter.prototype._parseCoffeeScriptError = function(coffeeError) {
117
+ var attrs, lineNumber, match, message, rule;
118
+ rule = this.config['coffeescript_error'];
119
+ message = coffeeError.toString();
120
+ lineNumber = -1;
121
+ if (coffeeError.location != null) {
122
+ lineNumber = coffeeError.location.first_line + 1;
123
+ } else {
124
+ match = /line (\d+)/.exec(message);
125
+ if ((match != null ? match.length : void 0) > 1) {
126
+ lineNumber = parseInt(match[1], 10);
127
+ }
128
+ }
129
+ attrs = {
130
+ message: message,
131
+ level: rule.level,
132
+ lineNumber: lineNumber
133
+ };
134
+ return this.createError('coffeescript_error', attrs);
135
+ };
136
+
137
+ return ASTLinter;
138
+
139
+ })(BaseLinter);
140
+
141
+
142
+ },{"./base_linter.coffee":3}],3:[function(require,module,exports){
143
+ var BaseLinter, defaults, extend,
144
+ __slice = [].slice;
145
+
146
+ extend = function() {
147
+ var destination, k, source, sources, v, _i, _len;
148
+ destination = arguments[0], sources = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
149
+ for (_i = 0, _len = sources.length; _i < _len; _i++) {
150
+ source = sources[_i];
151
+ for (k in source) {
152
+ v = source[k];
153
+ destination[k] = v;
154
+ }
155
+ }
156
+ return destination;
157
+ };
158
+
159
+ defaults = function(source, defaults) {
160
+ return extend({}, defaults, source);
161
+ };
162
+
163
+ module.exports = BaseLinter = (function() {
164
+ function BaseLinter(source, config, rules) {
165
+ this.source = source;
166
+ this.config = config;
167
+ this.setupRules(rules);
168
+ }
169
+
170
+ BaseLinter.prototype.isObject = function(obj) {
171
+ return obj === Object(obj);
172
+ };
173
+
174
+ BaseLinter.prototype.createError = function(ruleName, attrs) {
175
+ var level;
176
+ if (attrs == null) {
177
+ attrs = {};
178
+ }
179
+ if (attrs.level == null) {
180
+ attrs.level = this.config[ruleName].level;
181
+ }
182
+ level = attrs.level;
183
+ if (level !== 'ignore' && level !== 'warn' && level !== 'error') {
184
+ throw new Error("unknown level " + level);
185
+ }
186
+ if (level === 'error' || level === 'warn') {
187
+ attrs.rule = ruleName;
188
+ return defaults(attrs, this.config[ruleName]);
189
+ } else {
190
+ return null;
191
+ }
192
+ };
193
+
194
+ BaseLinter.prototype.acceptRule = function(rule) {
195
+ throw new Error("acceptRule needs to be overridden in the subclass");
196
+ };
197
+
198
+ BaseLinter.prototype.setupRules = function(rules) {
199
+ var RuleConstructor, level, name, rule, _results;
200
+ this.rules = [];
201
+ _results = [];
202
+ for (name in rules) {
203
+ RuleConstructor = rules[name];
204
+ level = this.config[name].level;
205
+ if (level === 'error' || level === 'warn') {
206
+ rule = new RuleConstructor(this, this.config);
207
+ if (this.acceptRule(rule)) {
208
+ _results.push(this.rules.push(rule));
209
+ } else {
210
+ _results.push(void 0);
211
+ }
212
+ } else if (level !== 'ignore') {
213
+ throw new Error("unknown level " + level);
214
+ } else {
215
+ _results.push(void 0);
216
+ }
217
+ }
218
+ return _results;
219
+ };
220
+
221
+ BaseLinter.prototype.normalizeResult = function(p, result) {
222
+ if (result === true) {
223
+ return this.createError(p.rule.name);
224
+ }
225
+ if (this.isObject(result)) {
226
+ return this.createError(p.rule.name, result);
227
+ }
228
+ };
229
+
230
+ return BaseLinter;
231
+
232
+ })();
233
+
234
+
235
+ },{}],4:[function(require,module,exports){
236
+ /*
237
+ CoffeeLint
238
+
239
+ Copyright (c) 2011 Matthew Perpick.
240
+ CoffeeLint is freely distributable under the MIT license.
241
+ */
242
+
243
+ var ASTLinter, CoffeeScript, ERROR, IGNORE, LexicalLinter, LineLinter, RULES, WARN, coffeelint, cs, defaults, difference, extend, hasSyntaxError, mergeDefaultConfig, packageJSON, _rules,
244
+ __slice = [].slice,
245
+ __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; };
246
+
247
+ coffeelint = exports;
248
+
249
+ if (typeof window !== "undefined" && window !== null) {
250
+ CoffeeScript = window.CoffeeScript;
251
+ } else {
252
+ cs = 'coffee-script';
253
+ CoffeeScript = require(cs);
254
+ }
255
+
256
+ packageJSON = require('./../package.json');
257
+
258
+ coffeelint.VERSION = packageJSON.version;
259
+
260
+ ERROR = 'error';
261
+
262
+ WARN = 'warn';
263
+
264
+ IGNORE = 'ignore';
265
+
266
+ coffeelint.RULES = RULES = require('./rules.coffee');
267
+
268
+ extend = function() {
269
+ var destination, k, source, sources, v, _i, _len;
270
+ destination = arguments[0], sources = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
271
+ for (_i = 0, _len = sources.length; _i < _len; _i++) {
272
+ source = sources[_i];
273
+ for (k in source) {
274
+ v = source[k];
275
+ destination[k] = v;
276
+ }
277
+ }
278
+ return destination;
279
+ };
280
+
281
+ defaults = function(source, defaults) {
282
+ return extend({}, defaults, source);
283
+ };
284
+
285
+ difference = function(a, b) {
286
+ var j, _ref, _results;
287
+ j = 0;
288
+ _results = [];
289
+ while (j < a.length) {
290
+ if (_ref = a[j], __indexOf.call(b, _ref) >= 0) {
291
+ _results.push(a.splice(j, 1));
292
+ } else {
293
+ _results.push(j++);
294
+ }
295
+ }
296
+ return _results;
297
+ };
298
+
299
+ LineLinter = require('./line_linter.coffee');
300
+
301
+ LexicalLinter = require('./lexical_linter.coffee');
302
+
303
+ ASTLinter = require('./ast_linter.coffee');
304
+
305
+ mergeDefaultConfig = function(userConfig) {
306
+ var config, rule, ruleConfig;
307
+ config = {};
308
+ for (rule in RULES) {
309
+ ruleConfig = RULES[rule];
310
+ config[rule] = defaults(userConfig[rule], ruleConfig);
311
+ }
312
+ return config;
313
+ };
314
+
315
+ coffeelint.invertLiterate = function(source) {
316
+ var line, newSource, _i, _len, _ref;
317
+ source = CoffeeScript.helpers.invertLiterate(source);
318
+ newSource = "";
319
+ _ref = source.split("\n");
320
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
321
+ line = _ref[_i];
322
+ if (line.match(/^#/)) {
323
+ line = line.replace(/\s*$/, '');
324
+ }
325
+ line = line.replace(/^\s{4}/g, '');
326
+ newSource += "" + line + "\n";
327
+ }
328
+ return newSource;
329
+ };
330
+
331
+ _rules = {};
332
+
333
+ coffeelint.registerRule = function(RuleConstructor, ruleName) {
334
+ var e, name, p, _ref, _ref1;
335
+ if (ruleName == null) {
336
+ ruleName = void 0;
337
+ }
338
+ p = new RuleConstructor;
339
+ name = (p != null ? (_ref = p.rule) != null ? _ref.name : void 0 : void 0) || "(unknown)";
340
+ e = function(msg) {
341
+ throw new Error("Invalid rule: " + name + " " + msg);
342
+ };
343
+ if (p.rule == null) {
344
+ e("Rules must provide rule attribute with a default configuration.");
345
+ }
346
+ if (p.rule.name == null) {
347
+ e("Rule defaults require a name");
348
+ }
349
+ if ((ruleName != null) && ruleName !== p.rule.name) {
350
+ e("Mismatched rule name: " + ruleName);
351
+ }
352
+ if (p.rule.message == null) {
353
+ e("Rule defaults require a message");
354
+ }
355
+ if (p.rule.description == null) {
356
+ e("Rule defaults require a description");
357
+ }
358
+ if ((_ref1 = p.rule.level) !== 'ignore' && _ref1 !== 'warn' && _ref1 !== 'error') {
359
+ e("Default level must be 'ignore', 'warn', or 'error'");
360
+ }
361
+ if (typeof p.lintToken === 'function') {
362
+ if (!p.tokens) {
363
+ e("'tokens' is required for 'lintToken'");
364
+ }
365
+ } else if (typeof p.lintLine !== 'function' && typeof p.lintAST !== 'function') {
366
+ e("Rules must implement lintToken, lintLine, or lintAST");
367
+ }
368
+ RULES[p.rule.name] = p.rule;
369
+ return _rules[p.rule.name] = RuleConstructor;
370
+ };
371
+
372
+ coffeelint.registerRule(require('./rules/arrow_spacing.coffee'));
373
+
374
+ coffeelint.registerRule(require('./rules/no_tabs.coffee'));
375
+
376
+ coffeelint.registerRule(require('./rules/no_trailing_whitespace.coffee'));
377
+
378
+ coffeelint.registerRule(require('./rules/max_line_length.coffee'));
379
+
380
+ coffeelint.registerRule(require('./rules/line_endings.coffee'));
381
+
382
+ coffeelint.registerRule(require('./rules/no_trailing_semicolons.coffee'));
383
+
384
+ coffeelint.registerRule(require('./rules/indentation.coffee'));
385
+
386
+ coffeelint.registerRule(require('./rules/camel_case_classes.coffee'));
387
+
388
+ coffeelint.registerRule(require('./rules/colon_assignment_spacing.coffee'));
389
+
390
+ coffeelint.registerRule(require('./rules/no_implicit_braces.coffee'));
391
+
392
+ coffeelint.registerRule(require('./rules/no_plusplus.coffee'));
393
+
394
+ coffeelint.registerRule(require('./rules/no_throwing_strings.coffee'));
395
+
396
+ coffeelint.registerRule(require('./rules/no_backticks.coffee'));
397
+
398
+ coffeelint.registerRule(require('./rules/no_implicit_parens.coffee'));
399
+
400
+ coffeelint.registerRule(require('./rules/no_empty_param_list.coffee'));
401
+
402
+ coffeelint.registerRule(require('./rules/no_stand_alone_at.coffee'));
403
+
404
+ coffeelint.registerRule(require('./rules/space_operators.coffee'));
405
+
406
+ coffeelint.registerRule(require('./rules/duplicate_key.coffee'));
407
+
408
+ coffeelint.registerRule(require('./rules/empty_constructor_needs_parens.coffee'));
409
+
410
+ coffeelint.registerRule(require('./rules/cyclomatic_complexity.coffee'));
411
+
412
+ coffeelint.registerRule(require('./rules/newlines_after_classes.coffee'));
413
+
414
+ coffeelint.registerRule(require('./rules/no_unnecessary_fat_arrows.coffee'));
415
+
416
+ coffeelint.registerRule(require('./rules/missing_fat_arrows.coffee'));
417
+
418
+ coffeelint.registerRule(require('./rules/non_empty_constructor_needs_parens.coffee'));
419
+
420
+ hasSyntaxError = function(source) {
421
+ try {
422
+ CoffeeScript.tokens(source);
423
+ return false;
424
+ } catch (_error) {}
425
+ return true;
426
+ };
427
+
428
+ coffeelint.lint = function(source, userConfig, literate) {
429
+ var all_errors, astErrors, block_config, cmd, config, disabled, disabled_initially, e, errors, i, l, lexErrors, lexicalLinter, lineErrors, lineLinter, next_line, r, rules, s, tokensByLine, _i, _j, _k, _len, _len1, _ref, _ref1, _ref2, _ref3, _ref4;
430
+ if (userConfig == null) {
431
+ userConfig = {};
432
+ }
433
+ if (literate == null) {
434
+ literate = false;
435
+ }
436
+ if (literate) {
437
+ source = this.invertLiterate(source);
438
+ }
439
+ config = mergeDefaultConfig(userConfig);
440
+ disabled_initially = [];
441
+ _ref = source.split('\n');
442
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
443
+ l = _ref[_i];
444
+ s = LineLinter.configStatement.exec(l);
445
+ if ((s != null ? s.length : void 0) > 2 && __indexOf.call(s, 'enable') >= 0) {
446
+ _ref1 = s.slice(1);
447
+ for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
448
+ r = _ref1[_j];
449
+ if (r !== 'enable' && r !== 'disable') {
450
+ if (!(r in config && ((_ref2 = config[r].level) === 'warn' || _ref2 === 'error'))) {
451
+ disabled_initially.push(r);
452
+ config[r] = {
453
+ level: 'error'
454
+ };
455
+ }
456
+ }
457
+ }
458
+ }
459
+ }
460
+ astErrors = new ASTLinter(source, config, _rules, CoffeeScript).lint();
461
+ errors = [].concat(astErrors);
462
+ if (!hasSyntaxError(source)) {
463
+ lexicalLinter = new LexicalLinter(source, config, _rules, CoffeeScript);
464
+ lexErrors = lexicalLinter.lint();
465
+ errors = errors.concat(lexErrors);
466
+ tokensByLine = lexicalLinter.tokensByLine;
467
+ lineLinter = new LineLinter(source, config, _rules, tokensByLine);
468
+ lineErrors = lineLinter.lint();
469
+ errors = errors.concat(lineErrors);
470
+ block_config = lineLinter.block_config;
471
+ } else {
472
+ block_config = {
473
+ enable: {},
474
+ disable: {}
475
+ };
476
+ }
477
+ errors.sort(function(a, b) {
478
+ return a.lineNumber - b.lineNumber;
479
+ });
480
+ all_errors = errors;
481
+ errors = [];
482
+ disabled = disabled_initially;
483
+ next_line = 0;
484
+ for (i = _k = 0, _ref3 = source.split('\n').length; 0 <= _ref3 ? _k < _ref3 : _k > _ref3; i = 0 <= _ref3 ? ++_k : --_k) {
485
+ for (cmd in block_config) {
486
+ rules = block_config[cmd][i];
487
+ if (rules != null) {
488
+ ({
489
+ 'disable': function() {
490
+ return disabled = disabled.concat(rules);
491
+ },
492
+ 'enable': function() {
493
+ difference(disabled, rules);
494
+ if (rules.length === 0) {
495
+ return disabled = disabled_initially;
496
+ }
497
+ }
498
+ })[cmd]();
499
+ }
500
+ }
501
+ while (next_line === i && all_errors.length > 0) {
502
+ next_line = all_errors[0].lineNumber - 1;
503
+ e = all_errors[0];
504
+ if (e.lineNumber === i + 1 || (e.lineNumber == null)) {
505
+ e = all_errors.shift();
506
+ if (_ref4 = e.rule, __indexOf.call(disabled, _ref4) < 0) {
507
+ errors.push(e);
508
+ }
509
+ }
510
+ }
511
+ }
512
+ return errors;
513
+ };
514
+
515
+
516
+ },{"./../package.json":1,"./ast_linter.coffee":2,"./lexical_linter.coffee":5,"./line_linter.coffee":6,"./rules.coffee":7,"./rules/arrow_spacing.coffee":8,"./rules/camel_case_classes.coffee":9,"./rules/colon_assignment_spacing.coffee":10,"./rules/cyclomatic_complexity.coffee":11,"./rules/duplicate_key.coffee":12,"./rules/empty_constructor_needs_parens.coffee":13,"./rules/indentation.coffee":14,"./rules/line_endings.coffee":15,"./rules/max_line_length.coffee":16,"./rules/missing_fat_arrows.coffee":17,"./rules/newlines_after_classes.coffee":18,"./rules/no_backticks.coffee":19,"./rules/no_empty_param_list.coffee":20,"./rules/no_implicit_braces.coffee":21,"./rules/no_implicit_parens.coffee":22,"./rules/no_plusplus.coffee":23,"./rules/no_stand_alone_at.coffee":24,"./rules/no_tabs.coffee":25,"./rules/no_throwing_strings.coffee":26,"./rules/no_trailing_semicolons.coffee":27,"./rules/no_trailing_whitespace.coffee":28,"./rules/no_unnecessary_fat_arrows.coffee":29,"./rules/non_empty_constructor_needs_parens.coffee":30,"./rules/space_operators.coffee":31}],5:[function(require,module,exports){
517
+ var BaseLinter, LexicalLinter, TokenApi,
518
+ __hasProp = {}.hasOwnProperty,
519
+ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
520
+ __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; };
521
+
522
+ TokenApi = (function() {
523
+ function TokenApi(CoffeeScript, source, config, tokensByLine) {
524
+ this.config = config;
525
+ this.tokensByLine = tokensByLine;
526
+ this.tokens = CoffeeScript.tokens(source);
527
+ this.lines = source.split('\n');
528
+ this.tokensByLine = {};
529
+ }
530
+
531
+ TokenApi.prototype.i = 0;
532
+
533
+ TokenApi.prototype.peek = function(n) {
534
+ if (n == null) {
535
+ n = 1;
536
+ }
537
+ return this.tokens[this.i + n] || null;
538
+ };
539
+
540
+ return TokenApi;
541
+
542
+ })();
543
+
544
+ BaseLinter = require('./base_linter.coffee');
545
+
546
+ module.exports = LexicalLinter = (function(_super) {
547
+ __extends(LexicalLinter, _super);
548
+
549
+ function LexicalLinter(source, config, rules, CoffeeScript) {
550
+ LexicalLinter.__super__.constructor.call(this, source, config, rules);
551
+ this.tokenApi = new TokenApi(CoffeeScript, source, this.config, this.tokensByLine);
552
+ this.tokensByLine = this.tokenApi.tokensByLine;
553
+ }
554
+
555
+ LexicalLinter.prototype.acceptRule = function(rule) {
556
+ return typeof rule.lintToken === 'function';
557
+ };
558
+
559
+ LexicalLinter.prototype.lint = function() {
560
+ var error, errors, i, token, _i, _j, _len, _len1, _ref, _ref1;
561
+ errors = [];
562
+ _ref = this.tokenApi.tokens;
563
+ for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
564
+ token = _ref[i];
565
+ this.tokenApi.i = i;
566
+ _ref1 = this.lintToken(token);
567
+ for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
568
+ error = _ref1[_j];
569
+ errors.push(error);
570
+ }
571
+ }
572
+ return errors;
573
+ };
574
+
575
+ LexicalLinter.prototype.lintToken = function(token) {
576
+ var errors, lineNumber, rule, type, v, value, _base, _i, _len, _ref, _ref1;
577
+ type = token[0], value = token[1], lineNumber = token[2];
578
+ if (typeof lineNumber === "object") {
579
+ if (type === 'OUTDENT' || type === 'INDENT') {
580
+ lineNumber = lineNumber.last_line;
581
+ } else {
582
+ lineNumber = lineNumber.first_line;
583
+ }
584
+ }
585
+ if ((_base = this.tokensByLine)[lineNumber] == null) {
586
+ _base[lineNumber] = [];
587
+ }
588
+ this.tokensByLine[lineNumber].push(token);
589
+ this.lineNumber = lineNumber || this.lineNumber || 0;
590
+ this.tokenApi.lineNumber = this.lineNumber;
591
+ errors = [];
592
+ _ref = this.rules;
593
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
594
+ rule = _ref[_i];
595
+ if (!(_ref1 = token[0], __indexOf.call(rule.tokens, _ref1) >= 0)) {
596
+ continue;
597
+ }
598
+ v = this.normalizeResult(rule, rule.lintToken(token, this.tokenApi));
599
+ if (v != null) {
600
+ errors.push(v);
601
+ }
602
+ }
603
+ return errors;
604
+ };
605
+
606
+ LexicalLinter.prototype.createError = function(ruleName, attrs) {
607
+ if (attrs == null) {
608
+ attrs = {};
609
+ }
610
+ attrs.lineNumber = this.lineNumber + 1;
611
+ attrs.line = this.tokenApi.lines[this.lineNumber];
612
+ return LexicalLinter.__super__.createError.call(this, ruleName, attrs);
613
+ };
614
+
615
+ return LexicalLinter;
616
+
617
+ })(BaseLinter);
618
+
619
+
620
+ },{"./base_linter.coffee":3}],6:[function(require,module,exports){
621
+ var BaseLinter, LineApi, LineLinter, configStatement,
622
+ __hasProp = {}.hasOwnProperty,
623
+ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
624
+
625
+ LineApi = (function() {
626
+ function LineApi(source, config, tokensByLine) {
627
+ this.config = config;
628
+ this.tokensByLine = tokensByLine;
629
+ this.line = null;
630
+ this.lines = source.split('\n');
631
+ this.lineCount = this.lines.length;
632
+ this.context = {
633
+ "class": {
634
+ inClass: false,
635
+ lastUnemptyLineInClass: null,
636
+ classIndents: null
637
+ }
638
+ };
639
+ }
640
+
641
+ LineApi.prototype.lineNumber = 0;
642
+
643
+ LineApi.prototype.maintainClassContext = function(line) {
644
+ if (this.context["class"].inClass) {
645
+ if (this.lineHasToken('INDENT')) {
646
+ this.context["class"].classIndents++;
647
+ } else if (this.lineHasToken('OUTDENT')) {
648
+ this.context["class"].classIndents--;
649
+ if (this.context["class"].classIndents === 0) {
650
+ this.context["class"].inClass = false;
651
+ this.context["class"].classIndents = null;
652
+ }
653
+ }
654
+ if (this.context["class"].inClass && !line.match(/^\s*$/)) {
655
+ this.context["class"].lastUnemptyLineInClass = this.lineNumber;
656
+ }
657
+ } else {
658
+ if (!line.match(/\\s*/)) {
659
+ this.context["class"].lastUnemptyLineInClass = null;
660
+ }
661
+ if (this.lineHasToken('CLASS')) {
662
+ this.context["class"].inClass = true;
663
+ this.context["class"].lastUnemptyLineInClass = this.lineNumber;
664
+ this.context["class"].classIndents = 0;
665
+ }
666
+ }
667
+ return null;
668
+ };
669
+
670
+ LineApi.prototype.isLastLine = function() {
671
+ return this.lineNumber === this.lineCount - 1;
672
+ };
673
+
674
+ LineApi.prototype.lineHasToken = function(tokenType, lineNumber) {
675
+ var token, tokens, _i, _len;
676
+ if (tokenType == null) {
677
+ tokenType = null;
678
+ }
679
+ if (lineNumber == null) {
680
+ lineNumber = null;
681
+ }
682
+ lineNumber = lineNumber != null ? lineNumber : this.lineNumber;
683
+ if (tokenType == null) {
684
+ return this.tokensByLine[lineNumber] != null;
685
+ } else {
686
+ tokens = this.tokensByLine[lineNumber];
687
+ if (tokens == null) {
688
+ return null;
689
+ }
690
+ for (_i = 0, _len = tokens.length; _i < _len; _i++) {
691
+ token = tokens[_i];
692
+ if (token[0] === tokenType) {
693
+ return true;
694
+ }
695
+ }
696
+ return false;
697
+ }
698
+ };
699
+
700
+ LineApi.prototype.getLineTokens = function() {
701
+ return this.tokensByLine[this.lineNumber] || [];
702
+ };
703
+
704
+ return LineApi;
705
+
706
+ })();
707
+
708
+ BaseLinter = require('./base_linter.coffee');
709
+
710
+ configStatement = /coffeelint:\s*(disable|enable)(?:=([\w\s,]*))?/;
711
+
712
+ module.exports = LineLinter = (function(_super) {
713
+ __extends(LineLinter, _super);
714
+
715
+ LineLinter.configStatement = configStatement;
716
+
717
+ function LineLinter(source, config, rules, tokensByLine) {
718
+ LineLinter.__super__.constructor.call(this, source, config, rules);
719
+ this.lineApi = new LineApi(source, config, tokensByLine);
720
+ this.block_config = {
721
+ enable: {},
722
+ disable: {}
723
+ };
724
+ }
725
+
726
+ LineLinter.prototype.acceptRule = function(rule) {
727
+ return typeof rule.lintLine === 'function';
728
+ };
729
+
730
+ LineLinter.prototype.lint = function() {
731
+ var error, errors, line, lineNumber, _i, _j, _len, _len1, _ref, _ref1;
732
+ errors = [];
733
+ _ref = this.lineApi.lines;
734
+ for (lineNumber = _i = 0, _len = _ref.length; _i < _len; lineNumber = ++_i) {
735
+ line = _ref[lineNumber];
736
+ this.lineApi.lineNumber = this.lineNumber = lineNumber;
737
+ this.lineApi.maintainClassContext(line);
738
+ this.collectInlineConfig(line);
739
+ _ref1 = this.lintLine(line);
740
+ for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
741
+ error = _ref1[_j];
742
+ errors.push(error);
743
+ }
744
+ }
745
+ return errors;
746
+ };
747
+
748
+ LineLinter.prototype.lintLine = function(line) {
749
+ var errors, rule, v, _i, _len, _ref;
750
+ errors = [];
751
+ _ref = this.rules;
752
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
753
+ rule = _ref[_i];
754
+ v = this.normalizeResult(rule, rule.lintLine(line, this.lineApi));
755
+ if (v != null) {
756
+ errors.push(v);
757
+ }
758
+ }
759
+ return errors;
760
+ };
761
+
762
+ LineLinter.prototype.collectInlineConfig = function(line) {
763
+ var cmd, r, result, rules, _i, _len, _ref;
764
+ result = configStatement.exec(line);
765
+ if (result != null) {
766
+ cmd = result[1];
767
+ rules = [];
768
+ if (result[2] != null) {
769
+ _ref = result[2].split(',');
770
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
771
+ r = _ref[_i];
772
+ rules.push(r.replace(/^\s+|\s+$/g, ""));
773
+ }
774
+ }
775
+ this.block_config[cmd][this.lineNumber] = rules;
776
+ }
777
+ return null;
778
+ };
779
+
780
+ LineLinter.prototype.createError = function(rule, attrs) {
781
+ var _ref;
782
+ if (attrs == null) {
783
+ attrs = {};
784
+ }
785
+ attrs.lineNumber = this.lineNumber + 1;
786
+ attrs.level = (_ref = this.config[rule]) != null ? _ref.level : void 0;
787
+ return LineLinter.__super__.createError.call(this, rule, attrs);
788
+ };
789
+
790
+ return LineLinter;
791
+
792
+ })(BaseLinter);
793
+
794
+
795
+ },{"./base_linter.coffee":3}],7:[function(require,module,exports){
796
+ var ERROR, IGNORE, WARN;
797
+
798
+ ERROR = 'error';
799
+
800
+ WARN = 'warn';
801
+
802
+ IGNORE = 'ignore';
803
+
804
+ module.exports = {
805
+ coffeescript_error: {
806
+ level: ERROR,
807
+ message: ''
808
+ }
809
+ };
810
+
811
+
812
+ },{}],8:[function(require,module,exports){
813
+ var ArrowSpacing;
814
+
815
+ module.exports = ArrowSpacing = (function() {
816
+ function ArrowSpacing() {}
817
+
818
+ ArrowSpacing.prototype.rule = {
819
+ name: 'arrow_spacing',
820
+ level: 'ignore',
821
+ message: 'Function arrow (->) must be spaced properly',
822
+ 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>"
823
+ };
824
+
825
+ ArrowSpacing.prototype.tokens = ['->'];
826
+
827
+ ArrowSpacing.prototype.lintToken = function(token, tokenApi) {
828
+ var pp;
829
+ pp = tokenApi.peek(-1);
830
+ if (!(((token.spaced != null) || (token.newLine != null) || this.atEof(tokenApi)) && (((pp.spaced != null) || pp[0] === 'TERMINATOR') || (pp.generated != null) || pp[0] === "INDENT" || (pp[1] === "(" && (pp.generated == null))))) {
831
+ return true;
832
+ } else {
833
+ return null;
834
+ }
835
+ };
836
+
837
+ ArrowSpacing.prototype.atEof = function(tokenApi) {
838
+ var i, token, tokens, _i, _len, _ref, _ref1;
839
+ tokens = tokenApi.tokens, i = tokenApi.i;
840
+ _ref = tokens.slice(i + 1);
841
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
842
+ token = _ref[_i];
843
+ if (!(token.generated || ((_ref1 = token[0]) === 'OUTDENT' || _ref1 === 'TERMINATOR'))) {
844
+ return false;
845
+ }
846
+ }
847
+ return true;
848
+ };
849
+
850
+ return ArrowSpacing;
851
+
852
+ })();
853
+
854
+
855
+ },{}],9:[function(require,module,exports){
856
+ var CamelCaseClasses, regexes;
857
+
858
+ regexes = {
859
+ camelCase: /^[A-Z][a-zA-Z\d]*$/
860
+ };
861
+
862
+ module.exports = CamelCaseClasses = (function() {
863
+ function CamelCaseClasses() {}
864
+
865
+ CamelCaseClasses.prototype.rule = {
866
+ name: 'camel_case_classes',
867
+ level: 'error',
868
+ message: 'Class names should be camel cased',
869
+ description: "This rule mandates that all class names are CamelCased. Camel\ncasing class names is a generally accepted way of distinguishing\nconstructor functions - which require the 'new' prefix to behave\nproperly - from plain old functions.\n<pre>\n<code># Good!\nclass BoaConstrictor\n\n# Bad!\nclass boaConstrictor\n</code>\n</pre>\nThis rule is enabled by default."
870
+ };
871
+
872
+ CamelCaseClasses.prototype.tokens = ['CLASS'];
873
+
874
+ CamelCaseClasses.prototype.lintToken = function(token, tokenApi) {
875
+ var className, offset, _ref, _ref1, _ref2;
876
+ if ((token.newLine != null) || ((_ref = tokenApi.peek()[0]) === 'INDENT' || _ref === 'EXTENDS')) {
877
+ return null;
878
+ }
879
+ className = null;
880
+ offset = 1;
881
+ while (!className) {
882
+ if (((_ref1 = tokenApi.peek(offset + 1)) != null ? _ref1[0] : void 0) === '.') {
883
+ offset += 2;
884
+ } else if (((_ref2 = tokenApi.peek(offset)) != null ? _ref2[0] : void 0) === '@') {
885
+ offset += 1;
886
+ } else {
887
+ className = tokenApi.peek(offset)[1];
888
+ }
889
+ }
890
+ if (!regexes.camelCase.test(className)) {
891
+ return {
892
+ context: "class name: " + className
893
+ };
894
+ }
895
+ };
896
+
897
+ return CamelCaseClasses;
898
+
899
+ })();
900
+
901
+
902
+ },{}],10:[function(require,module,exports){
903
+ var ColonAssignmentSpacing;
904
+
905
+ module.exports = ColonAssignmentSpacing = (function() {
906
+ function ColonAssignmentSpacing() {}
907
+
908
+ ColonAssignmentSpacing.prototype.rule = {
909
+ name: 'colon_assignment_spacing',
910
+ level: 'ignore',
911
+ message: 'Colon assignment without proper spacing',
912
+ spacing: {
913
+ left: 0,
914
+ right: 0
915
+ },
916
+ 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# Good\nobject = {spacing : true}\nclass Dog\n canBark : true\n\n# Bad\nobject = {spacing: true}\nclass Cat\n canBark: false\n</code></pre>"
917
+ };
918
+
919
+ ColonAssignmentSpacing.prototype.tokens = [':'];
920
+
921
+ ColonAssignmentSpacing.prototype.lintToken = function(token, tokenApi) {
922
+ var checkSpacing, getSpaceFromToken, isLeftSpaced, isRightSpaced, leftSpacing, nextToken, previousToken, rightSpacing, spacingAllowances, _ref, _ref1;
923
+ spacingAllowances = tokenApi.config[this.rule.name].spacing;
924
+ previousToken = tokenApi.peek(-1);
925
+ nextToken = tokenApi.peek(1);
926
+ getSpaceFromToken = function(direction) {
927
+ switch (direction) {
928
+ case 'left':
929
+ return token[2].first_column - previousToken[2].last_column - 1;
930
+ case 'right':
931
+ return nextToken[2].first_column - token[2].first_column - 1;
932
+ }
933
+ };
934
+ checkSpacing = function(direction) {
935
+ var isSpaced, spacing;
936
+ spacing = getSpaceFromToken(direction);
937
+ isSpaced = spacing < 0 ? true : spacing === parseInt(spacingAllowances[direction]);
938
+ return [isSpaced, spacing];
939
+ };
940
+ _ref = checkSpacing('left'), isLeftSpaced = _ref[0], leftSpacing = _ref[1];
941
+ _ref1 = checkSpacing('right'), isRightSpaced = _ref1[0], rightSpacing = _ref1[1];
942
+ if (isLeftSpaced && isRightSpaced) {
943
+ return null;
944
+ } else {
945
+ return {
946
+ context: "Incorrect spacing around column " + token[2].first_column + ".\nExpected left: " + spacingAllowances.left + ", right: " + spacingAllowances.right + ".\nGot left: " + leftSpacing + ", right: " + rightSpacing + "."
947
+ };
948
+ }
949
+ };
950
+
951
+ return ColonAssignmentSpacing;
952
+
953
+ })();
954
+
955
+
956
+ },{}],11:[function(require,module,exports){
957
+ var NoTabs;
958
+
959
+ module.exports = NoTabs = (function() {
960
+ function NoTabs() {}
961
+
962
+ NoTabs.prototype.rule = {
963
+ name: 'cyclomatic_complexity',
964
+ value: 10,
965
+ level: 'ignore',
966
+ message: 'The cyclomatic complexity is too damn high',
967
+ description: 'Examine the complexity of your application.'
968
+ };
969
+
970
+ NoTabs.prototype.getComplexity = function(node) {
971
+ var complexity, name, _ref;
972
+ name = node.constructor.name;
973
+ complexity = name === 'If' || name === 'While' || name === 'For' || name === 'Try' ? 1 : name === 'Op' && ((_ref = node.operator) === '&&' || _ref === '||') ? 1 : name === 'Switch' ? node.cases.length : 0;
974
+ return complexity;
975
+ };
976
+
977
+ NoTabs.prototype.lintAST = function(node, astApi) {
978
+ this.astApi = astApi;
979
+ this.lintNode(node);
980
+ return void 0;
981
+ };
982
+
983
+ NoTabs.prototype.lintNode = function(node, line) {
984
+ var complexity, error, name, rule,
985
+ _this = this;
986
+ name = node.constructor.name;
987
+ complexity = this.getComplexity(node);
988
+ node.eachChild(function(childNode) {
989
+ var nodeLine;
990
+ nodeLine = childNode.locationData.first_line;
991
+ if (childNode) {
992
+ return complexity += _this.lintNode(childNode, nodeLine);
993
+ }
994
+ });
995
+ rule = this.astApi.config[this.rule.name];
996
+ if (name === 'Code' && complexity >= rule.value) {
997
+ error = this.astApi.createError({
998
+ context: complexity + 1,
999
+ lineNumber: line + 1,
1000
+ lineNumberEnd: node.locationData.last_line + 1
1001
+ });
1002
+ if (error) {
1003
+ this.errors.push(error);
1004
+ }
1005
+ }
1006
+ return complexity;
1007
+ };
1008
+
1009
+ return NoTabs;
1010
+
1011
+ })();
1012
+
1013
+
1014
+ },{}],12:[function(require,module,exports){
1015
+ var DuplicateKey;
1016
+
1017
+ module.exports = DuplicateKey = (function() {
1018
+ DuplicateKey.prototype.rule = {
1019
+ name: 'duplicate_key',
1020
+ level: 'error',
1021
+ message: 'Duplicate key defined in object or class',
1022
+ description: "Prevents defining duplicate keys in object literals and classes"
1023
+ };
1024
+
1025
+ DuplicateKey.prototype.tokens = ['IDENTIFIER', "{", "}"];
1026
+
1027
+ function DuplicateKey() {
1028
+ this.braceScopes = [];
1029
+ }
1030
+
1031
+ DuplicateKey.prototype.lintToken = function(_arg, tokenApi) {
1032
+ var type;
1033
+ type = _arg[0];
1034
+ if (type === "{" || type === "}") {
1035
+ this.lintBrace.apply(this, arguments);
1036
+ return void 0;
1037
+ }
1038
+ if (type === "IDENTIFIER") {
1039
+ return this.lintIdentifier.apply(this, arguments);
1040
+ }
1041
+ };
1042
+
1043
+ DuplicateKey.prototype.lintIdentifier = function(token, tokenApi) {
1044
+ var key, nextToken, previousToken;
1045
+ key = token[1];
1046
+ if (this.currentScope == null) {
1047
+ return null;
1048
+ }
1049
+ nextToken = tokenApi.peek(1);
1050
+ if (nextToken[1] !== ':') {
1051
+ return null;
1052
+ }
1053
+ previousToken = tokenApi.peek(-1);
1054
+ if (previousToken[0] === '@') {
1055
+ key = "@" + key;
1056
+ }
1057
+ key = "identifier-" + key;
1058
+ if (this.currentScope[key]) {
1059
+ return true;
1060
+ } else {
1061
+ this.currentScope[key] = token;
1062
+ return null;
1063
+ }
1064
+ };
1065
+
1066
+ DuplicateKey.prototype.lintBrace = function(token) {
1067
+ if (token[0] === '{') {
1068
+ if (this.currentScope != null) {
1069
+ this.braceScopes.push(this.currentScope);
1070
+ }
1071
+ this.currentScope = {};
1072
+ } else {
1073
+ this.currentScope = this.braceScopes.pop();
1074
+ }
1075
+ return null;
1076
+ };
1077
+
1078
+ return DuplicateKey;
1079
+
1080
+ })();
1081
+
1082
+
1083
+ },{}],13:[function(require,module,exports){
1084
+ var EmptyConstructorNeedsParens;
1085
+
1086
+ module.exports = EmptyConstructorNeedsParens = (function() {
1087
+ function EmptyConstructorNeedsParens() {}
1088
+
1089
+ EmptyConstructorNeedsParens.prototype.rule = {
1090
+ name: 'empty_constructor_needs_parens',
1091
+ level: 'ignore',
1092
+ message: 'Invoking a constructor without parens and without arguments',
1093
+ description: "Requires constructors with no parameters to include the parens"
1094
+ };
1095
+
1096
+ EmptyConstructorNeedsParens.prototype.tokens = ['UNARY'];
1097
+
1098
+ EmptyConstructorNeedsParens.prototype.lintToken = function(token, tokenApi) {
1099
+ var expectedCallStart, expectedIdentifier, identifierIndex;
1100
+ if (token[1] === 'new') {
1101
+ identifierIndex = 1;
1102
+ while (true) {
1103
+ expectedIdentifier = tokenApi.peek(identifierIndex);
1104
+ expectedCallStart = tokenApi.peek(identifierIndex + 1);
1105
+ if ((expectedIdentifier != null ? expectedIdentifier[0] : void 0) === 'IDENTIFIER') {
1106
+ if ((expectedCallStart != null ? expectedCallStart[0] : void 0) === '.') {
1107
+ identifierIndex += 2;
1108
+ continue;
1109
+ }
1110
+ }
1111
+ break;
1112
+ }
1113
+ if ((expectedIdentifier != null ? expectedIdentifier[0] : void 0) === 'IDENTIFIER' && (expectedCallStart != null)) {
1114
+ return this.handleExpectedCallStart(expectedCallStart);
1115
+ }
1116
+ }
1117
+ };
1118
+
1119
+ EmptyConstructorNeedsParens.prototype.handleExpectedCallStart = function(expectedCallStart) {
1120
+ if (expectedCallStart[0] !== 'CALL_START') {
1121
+ return true;
1122
+ }
1123
+ };
1124
+
1125
+ return EmptyConstructorNeedsParens;
1126
+
1127
+ })();
1128
+
1129
+
1130
+ },{}],14:[function(require,module,exports){
1131
+ var Indentation;
1132
+
1133
+ module.exports = Indentation = (function() {
1134
+ Indentation.prototype.rule = {
1135
+ name: 'indentation',
1136
+ value: 2,
1137
+ level: 'error',
1138
+ message: 'Line contains inconsistent indentation',
1139
+ 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."
1140
+ };
1141
+
1142
+ Indentation.prototype.tokens = ['INDENT', "[", "]"];
1143
+
1144
+ function Indentation() {
1145
+ this.arrayTokens = [];
1146
+ }
1147
+
1148
+ Indentation.prototype.lintToken = function(token, tokenApi) {
1149
+ var currentLine, expected, ignoreIndent, isArrayIndent, isInterpIndent, isMultiline, lineNumber, lines, numIndents, prevNum, previous, previousIndentation, previousLine, previousSymbol, type, _ref;
1150
+ type = token[0], numIndents = token[1], lineNumber = token[2];
1151
+ if (type === "[" || type === "]") {
1152
+ this.lintArray(token);
1153
+ return void 0;
1154
+ }
1155
+ if (token.generated != null) {
1156
+ return null;
1157
+ }
1158
+ previous = tokenApi.peek(-2);
1159
+ isInterpIndent = previous && previous[0] === '+';
1160
+ previous = tokenApi.peek(-1);
1161
+ isArrayIndent = this.inArray() && (previous != null ? previous.newLine : void 0);
1162
+ previousSymbol = (_ref = tokenApi.peek(-1)) != null ? _ref[0] : void 0;
1163
+ isMultiline = previousSymbol === '=' || previousSymbol === ',';
1164
+ ignoreIndent = isInterpIndent || isArrayIndent || isMultiline;
1165
+ if (this.isChainedCall(tokenApi)) {
1166
+ lines = tokenApi.lines, lineNumber = tokenApi.lineNumber;
1167
+ currentLine = lines[lineNumber];
1168
+ prevNum = 1;
1169
+ while (/^\s*(#|$)/.test(lines[lineNumber - prevNum])) {
1170
+ prevNum += 1;
1171
+ }
1172
+ previousLine = lines[lineNumber - prevNum];
1173
+ previousIndentation = previousLine.match(/^(\s*)/)[1].length;
1174
+ numIndents = currentLine.match(/^(\s*)/)[1].length;
1175
+ numIndents -= previousIndentation;
1176
+ }
1177
+ expected = tokenApi.config[this.rule.name].value;
1178
+ if (!ignoreIndent && numIndents !== expected) {
1179
+ return {
1180
+ context: "Expected " + expected + " got " + numIndents
1181
+ };
1182
+ }
1183
+ };
1184
+
1185
+ Indentation.prototype.inArray = function() {
1186
+ return this.arrayTokens.length > 0;
1187
+ };
1188
+
1189
+ Indentation.prototype.lintArray = function(token) {
1190
+ if (token[0] === '[') {
1191
+ this.arrayTokens.push(token);
1192
+ } else if (token[0] === ']') {
1193
+ this.arrayTokens.pop();
1194
+ }
1195
+ return null;
1196
+ };
1197
+
1198
+ Indentation.prototype.isChainedCall = function(tokenApi) {
1199
+ var i, lastNewLineIndex, lines, t, token, tokens;
1200
+ tokens = tokenApi.tokens, i = tokenApi.i;
1201
+ lines = (function() {
1202
+ var _i, _len, _ref, _results;
1203
+ _ref = tokens.slice(0, +i + 1 || 9e9);
1204
+ _results = [];
1205
+ for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
1206
+ token = _ref[i];
1207
+ if (token.newLine != null) {
1208
+ _results.push(i);
1209
+ }
1210
+ }
1211
+ return _results;
1212
+ })();
1213
+ lastNewLineIndex = lines ? lines[lines.length - 2] : null;
1214
+ if (lastNewLineIndex == null) {
1215
+ return false;
1216
+ }
1217
+ tokens = [tokens[lastNewLineIndex], tokens[lastNewLineIndex + 1]];
1218
+ return !!((function() {
1219
+ var _i, _len, _results;
1220
+ _results = [];
1221
+ for (_i = 0, _len = tokens.length; _i < _len; _i++) {
1222
+ t = tokens[_i];
1223
+ if (t && t[0] === '.') {
1224
+ _results.push(t);
1225
+ }
1226
+ }
1227
+ return _results;
1228
+ })()).length;
1229
+ };
1230
+
1231
+ return Indentation;
1232
+
1233
+ })();
1234
+
1235
+
1236
+ },{}],15:[function(require,module,exports){
1237
+ var LineEndings;
1238
+
1239
+ module.exports = LineEndings = (function() {
1240
+ function LineEndings() {}
1241
+
1242
+ LineEndings.prototype.rule = {
1243
+ name: 'line_endings',
1244
+ level: 'ignore',
1245
+ value: 'unix',
1246
+ message: 'Line contains incorrect line endings',
1247
+ description: "This rule ensures your project uses only <tt>windows</tt> or\n<tt>unix</tt> line endings. This rule is disabled by default."
1248
+ };
1249
+
1250
+ LineEndings.prototype.lintLine = function(line, lineApi) {
1251
+ var ending, lastChar, valid, _ref;
1252
+ ending = (_ref = lineApi.config[this.rule.name]) != null ? _ref.value : void 0;
1253
+ if (!ending || lineApi.isLastLine() || !line) {
1254
+ return null;
1255
+ }
1256
+ lastChar = line[line.length - 1];
1257
+ valid = (function() {
1258
+ if (ending === 'windows') {
1259
+ return lastChar === '\r';
1260
+ } else if (ending === 'unix') {
1261
+ return lastChar !== '\r';
1262
+ } else {
1263
+ throw new Error("unknown line ending type: " + ending);
1264
+ }
1265
+ })();
1266
+ if (!valid) {
1267
+ return {
1268
+ context: "Expected " + ending
1269
+ };
1270
+ } else {
1271
+ return null;
1272
+ }
1273
+ };
1274
+
1275
+ return LineEndings;
1276
+
1277
+ })();
1278
+
1279
+
1280
+ },{}],16:[function(require,module,exports){
1281
+ var MaxLineLength, regexes;
1282
+
1283
+ regexes = {
1284
+ longUrlComment: /^\s*\#\s*http[^\s]+$/
1285
+ };
1286
+
1287
+ module.exports = MaxLineLength = (function() {
1288
+ function MaxLineLength() {}
1289
+
1290
+ MaxLineLength.prototype.rule = {
1291
+ name: 'max_line_length',
1292
+ value: 80,
1293
+ level: 'error',
1294
+ limitComments: true,
1295
+ message: 'Line exceeds maximum allowed length',
1296
+ 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."
1297
+ };
1298
+
1299
+ MaxLineLength.prototype.lintLine = function(line, lineApi) {
1300
+ var limitComments, max, _ref, _ref1;
1301
+ max = (_ref = lineApi.config[this.rule.name]) != null ? _ref.value : void 0;
1302
+ limitComments = (_ref1 = lineApi.config[this.rule.name]) != null ? _ref1.limitComments : void 0;
1303
+ if (max && max < line.length && !regexes.longUrlComment.test(line)) {
1304
+ if (!limitComments) {
1305
+ if (lineApi.getLineTokens().length === 0) {
1306
+ return;
1307
+ }
1308
+ }
1309
+ return {
1310
+ context: "Length is " + line.length + ", max is " + max
1311
+ };
1312
+ }
1313
+ };
1314
+
1315
+ return MaxLineLength;
1316
+
1317
+ })();
1318
+
1319
+
1320
+ },{}],17:[function(require,module,exports){
1321
+ var MissingFatArrows, any, isClass, isCode, isFatArrowCode, isObject, isThis, isValue, methodsOfClass, needsFatArrow,
1322
+ __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; };
1323
+
1324
+ isCode = function(node) {
1325
+ return (node != null ? node.constructor.name : void 0) === 'Code';
1326
+ };
1327
+
1328
+ isClass = function(node) {
1329
+ return node.constructor.name === 'Class';
1330
+ };
1331
+
1332
+ isValue = function(node) {
1333
+ return node.constructor.name === 'Value';
1334
+ };
1335
+
1336
+ isObject = function(node) {
1337
+ return node.constructor.name === 'Obj';
1338
+ };
1339
+
1340
+ isThis = function(node) {
1341
+ return isValue(node) && node.base.value === 'this';
1342
+ };
1343
+
1344
+ isFatArrowCode = function(node) {
1345
+ return isCode(node) && node.bound;
1346
+ };
1347
+
1348
+ any = function(arr, test) {
1349
+ return arr.reduce((function(res, elt) {
1350
+ return res || test(elt);
1351
+ }), false);
1352
+ };
1353
+
1354
+ needsFatArrow = function(node) {
1355
+ return isCode(node) && (any(node.params, function(param) {
1356
+ return param.contains(isThis) != null;
1357
+ }) || (node.body.contains(isThis) != null));
1358
+ };
1359
+
1360
+ methodsOfClass = function(classNode) {
1361
+ var bodyNodes, returnNode;
1362
+ bodyNodes = classNode.body.expressions;
1363
+ returnNode = bodyNodes[bodyNodes.length - 1];
1364
+ if ((returnNode != null) && isValue(returnNode) && isObject(returnNode.base)) {
1365
+ return returnNode.base.properties.map(function(assignNode) {
1366
+ return assignNode.value;
1367
+ }).filter(isCode);
1368
+ } else {
1369
+ return [];
1370
+ }
1371
+ };
1372
+
1373
+ module.exports = MissingFatArrows = (function() {
1374
+ function MissingFatArrows() {}
1375
+
1376
+ MissingFatArrows.prototype.rule = {
1377
+ name: 'missing_fat_arrows',
1378
+ level: 'ignore',
1379
+ message: 'Used `this` in a function without a fat arrow',
1380
+ description: "Warns when you use `this` inside a function that wasn't defined\nwith a fat arrow. This rule does not apply to methods defined in a\nclass, since they have `this` bound to the class instance (or the\nclass itself, for class methods).\n\nIt is impossible to statically determine whether a function using\n`this` will be bound with the correct `this` value due to language\nfeatures like `Function.prototype.call` and\n`Function.prototype.bind`, so this rule may produce false positives."
1381
+ };
1382
+
1383
+ MissingFatArrows.prototype.lintAST = function(node, astApi) {
1384
+ this.lintNode(node, astApi);
1385
+ return void 0;
1386
+ };
1387
+
1388
+ MissingFatArrows.prototype.lintNode = function(node, astApi, methods) {
1389
+ var error,
1390
+ _this = this;
1391
+ if (methods == null) {
1392
+ methods = [];
1393
+ }
1394
+ if ((!isFatArrowCode(node)) && (__indexOf.call(methods, node) < 0) && (needsFatArrow(node))) {
1395
+ error = astApi.createError({
1396
+ lineNumber: node.locationData.first_line + 1
1397
+ });
1398
+ this.errors.push(error);
1399
+ }
1400
+ return node.eachChild(function(child) {
1401
+ return _this.lintNode(child, astApi, (function() {
1402
+ switch (false) {
1403
+ case !isClass(node):
1404
+ return methodsOfClass(node);
1405
+ case !isCode(node):
1406
+ return [];
1407
+ default:
1408
+ return methods;
1409
+ }
1410
+ })());
1411
+ });
1412
+ };
1413
+
1414
+ return MissingFatArrows;
1415
+
1416
+ })();
1417
+
1418
+
1419
+ },{}],18:[function(require,module,exports){
1420
+ var NewlinesAfterClasses;
1421
+
1422
+ module.exports = NewlinesAfterClasses = (function() {
1423
+ function NewlinesAfterClasses() {}
1424
+
1425
+ NewlinesAfterClasses.prototype.rule = {
1426
+ name: 'newlines_after_classes',
1427
+ value: 3,
1428
+ level: 'ignore',
1429
+ message: 'Wrong count of newlines between a class and other code',
1430
+ description: "Checks the number of newlines between classes and other code"
1431
+ };
1432
+
1433
+ NewlinesAfterClasses.prototype.lintLine = function(line, lineApi) {
1434
+ var context, ending, got, lineNumber;
1435
+ ending = lineApi.config[this.rule.name].value;
1436
+ if (!ending || lineApi.isLastLine()) {
1437
+ return null;
1438
+ }
1439
+ lineNumber = lineApi.lineNumber, context = lineApi.context;
1440
+ if (!context["class"].inClass && (context["class"].lastUnemptyLineInClass != null) && (lineNumber - context["class"].lastUnemptyLineInClass) !== ending) {
1441
+ got = lineNumber - context["class"].lastUnemptyLineInClass;
1442
+ return {
1443
+ context: "Expected " + ending + " got " + got
1444
+ };
1445
+ }
1446
+ return null;
1447
+ };
1448
+
1449
+ return NewlinesAfterClasses;
1450
+
1451
+ })();
1452
+
1453
+
1454
+ },{}],19:[function(require,module,exports){
1455
+ var NoBackticks;
1456
+
1457
+ module.exports = NoBackticks = (function() {
1458
+ function NoBackticks() {}
1459
+
1460
+ NoBackticks.prototype.rule = {
1461
+ name: 'no_backticks',
1462
+ level: 'error',
1463
+ message: 'Backticks are forbidden',
1464
+ 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."
1465
+ };
1466
+
1467
+ NoBackticks.prototype.tokens = ["JS"];
1468
+
1469
+ NoBackticks.prototype.lintToken = function(token, tokenApi) {
1470
+ return true;
1471
+ };
1472
+
1473
+ return NoBackticks;
1474
+
1475
+ })();
1476
+
1477
+
1478
+ },{}],20:[function(require,module,exports){
1479
+ var NoEmptyParamList;
1480
+
1481
+ module.exports = NoEmptyParamList = (function() {
1482
+ function NoEmptyParamList() {}
1483
+
1484
+ NoEmptyParamList.prototype.rule = {
1485
+ name: 'no_empty_param_list',
1486
+ level: 'ignore',
1487
+ message: 'Empty parameter list is forbidden',
1488
+ 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."
1489
+ };
1490
+
1491
+ NoEmptyParamList.prototype.tokens = ["PARAM_START"];
1492
+
1493
+ NoEmptyParamList.prototype.lintToken = function(token, tokenApi) {
1494
+ var nextType;
1495
+ nextType = tokenApi.peek()[0];
1496
+ return nextType === 'PARAM_END';
1497
+ };
1498
+
1499
+ return NoEmptyParamList;
1500
+
1501
+ })();
1502
+
1503
+
1504
+ },{}],21:[function(require,module,exports){
1505
+ var NoImplicitBraces;
1506
+
1507
+ module.exports = NoImplicitBraces = (function() {
1508
+ function NoImplicitBraces() {}
1509
+
1510
+ NoImplicitBraces.prototype.rule = {
1511
+ name: 'no_implicit_braces',
1512
+ level: 'ignore',
1513
+ message: 'Implicit braces are forbidden',
1514
+ strict: true,
1515
+ 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."
1516
+ };
1517
+
1518
+ NoImplicitBraces.prototype.tokens = ["{"];
1519
+
1520
+ NoImplicitBraces.prototype.lintToken = function(token, tokenApi) {
1521
+ var previousToken;
1522
+ if (token.generated) {
1523
+ if (!tokenApi.config[this.rule.name].strict) {
1524
+ previousToken = tokenApi.peek(-1)[0];
1525
+ if (previousToken === 'INDENT') {
1526
+ return;
1527
+ }
1528
+ }
1529
+ return this.isPartOfClass(tokenApi);
1530
+ }
1531
+ };
1532
+
1533
+ NoImplicitBraces.prototype.isPartOfClass = function(tokenApi) {
1534
+ var i, t;
1535
+ i = -1;
1536
+ while (true) {
1537
+ t = tokenApi.peek(i);
1538
+ if ((t == null) || t[0] === 'TERMINATOR') {
1539
+ return true;
1540
+ }
1541
+ if (t[0] === 'CLASS') {
1542
+ return null;
1543
+ }
1544
+ i -= 1;
1545
+ }
1546
+ };
1547
+
1548
+ return NoImplicitBraces;
1549
+
1550
+ })();
1551
+
1552
+
1553
+ },{}],22:[function(require,module,exports){
1554
+ var NoImplicitParens;
1555
+
1556
+ module.exports = NoImplicitParens = (function() {
1557
+ function NoImplicitParens() {}
1558
+
1559
+ NoImplicitParens.prototype.rule = {
1560
+ name: 'no_implicit_parens',
1561
+ level: 'ignore',
1562
+ message: 'Implicit parens are forbidden',
1563
+ 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."
1564
+ };
1565
+
1566
+ NoImplicitParens.prototype.tokens = ["CALL_START"];
1567
+
1568
+ NoImplicitParens.prototype.lintToken = function(token, tokenApi) {
1569
+ return token.generated;
1570
+ };
1571
+
1572
+ return NoImplicitParens;
1573
+
1574
+ })();
1575
+
1576
+
1577
+ },{}],23:[function(require,module,exports){
1578
+ var NoPlusPlus;
1579
+
1580
+ module.exports = NoPlusPlus = (function() {
1581
+ function NoPlusPlus() {}
1582
+
1583
+ NoPlusPlus.prototype.rule = {
1584
+ name: 'no_plusplus',
1585
+ level: 'ignore',
1586
+ message: 'The increment and decrement operators are forbidden',
1587
+ 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."
1588
+ };
1589
+
1590
+ NoPlusPlus.prototype.tokens = ["++", "--"];
1591
+
1592
+ NoPlusPlus.prototype.lintToken = function(token, tokenApi) {
1593
+ return {
1594
+ context: "found '" + token[0] + "'"
1595
+ };
1596
+ };
1597
+
1598
+ return NoPlusPlus;
1599
+
1600
+ })();
1601
+
1602
+
1603
+ },{}],24:[function(require,module,exports){
1604
+ var NoStandAloneAt;
1605
+
1606
+ module.exports = NoStandAloneAt = (function() {
1607
+ function NoStandAloneAt() {}
1608
+
1609
+ NoStandAloneAt.prototype.rule = {
1610
+ name: 'no_stand_alone_at',
1611
+ level: 'ignore',
1612
+ message: '@ must not be used stand alone',
1613
+ description: "This rule checks that no stand alone @ are in use, they are\ndiscouraged. Further information in CoffeScript issue <a\nhref=\"https://github.com/jashkenas/coffee-script/issues/1601\">\n#1601</a>"
1614
+ };
1615
+
1616
+ NoStandAloneAt.prototype.tokens = ["@"];
1617
+
1618
+ NoStandAloneAt.prototype.lintToken = function(token, tokenApi) {
1619
+ var isDot, isIdentifier, isIndexStart, isValidProtoProperty, nextToken, protoProperty, spaced;
1620
+ nextToken = tokenApi.peek();
1621
+ spaced = token.spaced;
1622
+ isIdentifier = nextToken[0] === 'IDENTIFIER';
1623
+ isIndexStart = nextToken[0] === 'INDEX_START';
1624
+ isDot = nextToken[0] === '.';
1625
+ if (nextToken[0] === '::') {
1626
+ protoProperty = tokenApi.peek(2);
1627
+ isValidProtoProperty = protoProperty[0] === 'IDENTIFIER';
1628
+ }
1629
+ if (spaced || (!isIdentifier && !isIndexStart && !isDot && !isValidProtoProperty)) {
1630
+ return true;
1631
+ }
1632
+ };
1633
+
1634
+ return NoStandAloneAt;
1635
+
1636
+ })();
1637
+
1638
+
1639
+ },{}],25:[function(require,module,exports){
1640
+ var NoTabs, indentationRegex,
1641
+ __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; };
1642
+
1643
+ indentationRegex = /\S/;
1644
+
1645
+ module.exports = NoTabs = (function() {
1646
+ function NoTabs() {}
1647
+
1648
+ NoTabs.prototype.rule = {
1649
+ name: 'no_tabs',
1650
+ level: 'error',
1651
+ message: 'Line contains tab indentation',
1652
+ description: "This rule forbids tabs in indentation. Enough said. It is enabled by\ndefault."
1653
+ };
1654
+
1655
+ NoTabs.prototype.lintLine = function(line, lineApi) {
1656
+ var indentation;
1657
+ indentation = line.split(indentationRegex)[0];
1658
+ if (lineApi.lineHasToken() && __indexOf.call(indentation, '\t') >= 0) {
1659
+ return true;
1660
+ } else {
1661
+ return null;
1662
+ }
1663
+ };
1664
+
1665
+ return NoTabs;
1666
+
1667
+ })();
1668
+
1669
+
1670
+ },{}],26:[function(require,module,exports){
1671
+ var NoThrowingStrings;
1672
+
1673
+ module.exports = NoThrowingStrings = (function() {
1674
+ function NoThrowingStrings() {}
1675
+
1676
+ NoThrowingStrings.prototype.rule = {
1677
+ name: 'no_throwing_strings',
1678
+ level: 'error',
1679
+ message: 'Throwing strings is forbidden',
1680
+ 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."
1681
+ };
1682
+
1683
+ NoThrowingStrings.prototype.tokens = ["THROW"];
1684
+
1685
+ NoThrowingStrings.prototype.lintToken = function(token, tokenApi) {
1686
+ var n1, n2, nextIsString, _ref;
1687
+ _ref = [tokenApi.peek(), tokenApi.peek(2)], n1 = _ref[0], n2 = _ref[1];
1688
+ nextIsString = n1[0] === 'STRING' || (n1[0] === '(' && n2[0] === 'STRING');
1689
+ return nextIsString;
1690
+ };
1691
+
1692
+ return NoThrowingStrings;
1693
+
1694
+ })();
1695
+
1696
+
1697
+ },{}],27:[function(require,module,exports){
1698
+ var NoTrailingSemicolons, regexes,
1699
+ __slice = [].slice;
1700
+
1701
+ regexes = {
1702
+ trailingSemicolon: /;\r?$/
1703
+ };
1704
+
1705
+ module.exports = NoTrailingSemicolons = (function() {
1706
+ function NoTrailingSemicolons() {}
1707
+
1708
+ NoTrailingSemicolons.prototype.rule = {
1709
+ name: 'no_trailing_semicolons',
1710
+ level: 'error',
1711
+ message: 'Line contains a trailing semicolon',
1712
+ 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."
1713
+ };
1714
+
1715
+ NoTrailingSemicolons.prototype.lintLine = function(line, lineApi) {
1716
+ var first, hasNewLine, hasSemicolon, last, lineTokens, _i, _ref;
1717
+ lineTokens = lineApi.getLineTokens();
1718
+ if (lineTokens.length === 1 && lineTokens[0][0] === 'TERMINATOR') {
1719
+ return;
1720
+ }
1721
+ hasSemicolon = regexes.trailingSemicolon.test(line);
1722
+ _ref = lineApi.getLineTokens(), first = 2 <= _ref.length ? __slice.call(_ref, 0, _i = _ref.length - 1) : (_i = 0, []), last = _ref[_i++];
1723
+ hasNewLine = last && (last.newLine != null);
1724
+ if (hasSemicolon && !hasNewLine && lineApi.lineHasToken() && last[0] !== 'STRING') {
1725
+ return true;
1726
+ }
1727
+ };
1728
+
1729
+ return NoTrailingSemicolons;
1730
+
1731
+ })();
1732
+
1733
+
1734
+ },{}],28:[function(require,module,exports){
1735
+ var NoTrailingWhitespace, regexes;
1736
+
1737
+ regexes = {
1738
+ trailingWhitespace: /[^\s]+[\t ]+\r?$/,
1739
+ onlySpaces: /^[\t\s]+\r?$/,
1740
+ lineHasComment: /^\s*[^\#]*\#/
1741
+ };
1742
+
1743
+ module.exports = NoTrailingWhitespace = (function() {
1744
+ function NoTrailingWhitespace() {}
1745
+
1746
+ NoTrailingWhitespace.prototype.rule = {
1747
+ name: 'no_trailing_whitespace',
1748
+ level: 'error',
1749
+ message: 'Line ends with trailing whitespace',
1750
+ allowed_in_comments: false,
1751
+ allowed_in_empty_lines: true,
1752
+ description: "This rule forbids trailing whitespace in your code, since it is\nneedless cruft. It is enabled by default."
1753
+ };
1754
+
1755
+ NoTrailingWhitespace.prototype.lintLine = function(line, lineApi) {
1756
+ var str, token, tokens, _i, _len, _ref, _ref1, _ref2;
1757
+ if (!((_ref = lineApi.config['no_trailing_whitespace']) != null ? _ref.allowed_in_empty_lines : void 0)) {
1758
+ if (regexes.onlySpaces.test(line)) {
1759
+ return true;
1760
+ }
1761
+ }
1762
+ if (regexes.trailingWhitespace.test(line)) {
1763
+ if (!((_ref1 = lineApi.config['no_trailing_whitespace']) != null ? _ref1.allowed_in_comments : void 0)) {
1764
+ return true;
1765
+ }
1766
+ line = line;
1767
+ tokens = lineApi.tokensByLine[lineApi.lineNumber];
1768
+ if (!tokens) {
1769
+ return null;
1770
+ }
1771
+ _ref2 = (function() {
1772
+ var _j, _len, _results;
1773
+ _results = [];
1774
+ for (_j = 0, _len = tokens.length; _j < _len; _j++) {
1775
+ token = tokens[_j];
1776
+ if (token[0] === 'STRING') {
1777
+ _results.push(token[1]);
1778
+ }
1779
+ }
1780
+ return _results;
1781
+ })();
1782
+ for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
1783
+ str = _ref2[_i];
1784
+ line = line.replace(str, 'STRING');
1785
+ }
1786
+ if (!regexes.lineHasComment.test(line)) {
1787
+ return true;
1788
+ }
1789
+ }
1790
+ };
1791
+
1792
+ return NoTrailingWhitespace;
1793
+
1794
+ })();
1795
+
1796
+
1797
+ },{}],29:[function(require,module,exports){
1798
+ var NoUnnecessaryFatArrows, any, isCode, isFatArrowCode, isThis, needsFatArrow;
1799
+
1800
+ isCode = function(node) {
1801
+ return node.constructor.name === 'Code';
1802
+ };
1803
+
1804
+ isFatArrowCode = function(node) {
1805
+ return isCode(node) && node.bound;
1806
+ };
1807
+
1808
+ isThis = function(node) {
1809
+ return node.constructor.name === 'Value' && node.base.value === 'this';
1810
+ };
1811
+
1812
+ any = function(arr, test) {
1813
+ return arr.reduce((function(res, elt) {
1814
+ return res || test(elt);
1815
+ }), false);
1816
+ };
1817
+
1818
+ needsFatArrow = function(node) {
1819
+ return isCode(node) && (any(node.params, function(param) {
1820
+ return param.contains(isThis) != null;
1821
+ }) || (node.body.contains(isThis) != null) || (node.body.contains(function(child) {
1822
+ return isFatArrowCode(child) && needsFatArrow(child);
1823
+ }) != null));
1824
+ };
1825
+
1826
+ module.exports = NoUnnecessaryFatArrows = (function() {
1827
+ function NoUnnecessaryFatArrows() {}
1828
+
1829
+ NoUnnecessaryFatArrows.prototype.rule = {
1830
+ name: 'no_unnecessary_fat_arrows',
1831
+ level: 'warn',
1832
+ message: 'Unnecessary fat arrow',
1833
+ description: "Disallows defining functions with fat arrows when `this`\nis not used within the function."
1834
+ };
1835
+
1836
+ NoUnnecessaryFatArrows.prototype.lintAST = function(node, astApi) {
1837
+ this.lintNode(node, astApi);
1838
+ return void 0;
1839
+ };
1840
+
1841
+ NoUnnecessaryFatArrows.prototype.lintNode = function(node, astApi) {
1842
+ var error,
1843
+ _this = this;
1844
+ if ((isFatArrowCode(node)) && (!needsFatArrow(node))) {
1845
+ error = astApi.createError({
1846
+ lineNumber: node.locationData.first_line + 1
1847
+ });
1848
+ this.errors.push(error);
1849
+ }
1850
+ return node.eachChild(function(child) {
1851
+ return _this.lintNode(child, astApi);
1852
+ });
1853
+ };
1854
+
1855
+ return NoUnnecessaryFatArrows;
1856
+
1857
+ })();
1858
+
1859
+
1860
+ },{}],30:[function(require,module,exports){
1861
+ var NonEmptyConstructorNeedsParens, ParentClass, _ref,
1862
+ __hasProp = {}.hasOwnProperty,
1863
+ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
1864
+
1865
+ ParentClass = require('./empty_constructor_needs_parens.coffee');
1866
+
1867
+ module.exports = NonEmptyConstructorNeedsParens = (function(_super) {
1868
+ __extends(NonEmptyConstructorNeedsParens, _super);
1869
+
1870
+ function NonEmptyConstructorNeedsParens() {
1871
+ _ref = NonEmptyConstructorNeedsParens.__super__.constructor.apply(this, arguments);
1872
+ return _ref;
1873
+ }
1874
+
1875
+ NonEmptyConstructorNeedsParens.prototype.rule = {
1876
+ name: 'non_empty_constructor_needs_parens',
1877
+ level: 'ignore',
1878
+ message: 'Invoking a constructor without parens and with arguments',
1879
+ description: "Requires constructors with parameters to include the parens"
1880
+ };
1881
+
1882
+ NonEmptyConstructorNeedsParens.prototype.handleExpectedCallStart = function(expectedCallStart) {
1883
+ if (expectedCallStart[0] === 'CALL_START' && expectedCallStart.generated) {
1884
+ return true;
1885
+ }
1886
+ };
1887
+
1888
+ return NonEmptyConstructorNeedsParens;
1889
+
1890
+ })(ParentClass);
1891
+
1892
+
1893
+ },{"./empty_constructor_needs_parens.coffee":13}],31:[function(require,module,exports){
1894
+ var SpaceOperators,
1895
+ __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; };
1896
+
1897
+ module.exports = SpaceOperators = (function() {
1898
+ SpaceOperators.prototype.rule = {
1899
+ name: 'space_operators',
1900
+ level: 'ignore',
1901
+ message: 'Operators must be spaced properly',
1902
+ description: "This rule enforces that operators have space around them."
1903
+ };
1904
+
1905
+ SpaceOperators.prototype.tokens = ["+", "-", "=", "MATH", "COMPARE", "LOGIC", "COMPOUND_ASSIGN", "(", ")", "CALL_START", "CALL_END"];
1906
+
1907
+ function SpaceOperators() {
1908
+ this.callTokens = [];
1909
+ this.parenTokens = [];
1910
+ }
1911
+
1912
+ SpaceOperators.prototype.lintToken = function(_arg, tokenApi) {
1913
+ var type;
1914
+ type = _arg[0];
1915
+ if (type === "CALL_START" || type === "CALL_END") {
1916
+ this.lintCall.apply(this, arguments);
1917
+ return void 0;
1918
+ }
1919
+ if (type === "(" || type === ")") {
1920
+ this.lintParens.apply(this, arguments);
1921
+ return void 0;
1922
+ }
1923
+ if (type === "+" || type === "-") {
1924
+ return this.lintPlus.apply(this, arguments);
1925
+ } else {
1926
+ return this.lintMath.apply(this, arguments);
1927
+ }
1928
+ };
1929
+
1930
+ SpaceOperators.prototype.lintPlus = function(token, tokenApi) {
1931
+ var isUnary, p, unaries, _ref;
1932
+ if (this.isInInterpolation() || this.isInExtendedRegex()) {
1933
+ return null;
1934
+ }
1935
+ p = tokenApi.peek(-1);
1936
+ unaries = ['TERMINATOR', '(', '=', '-', '+', ',', 'CALL_START', 'INDEX_START', '..', '...', 'COMPARE', 'IF', 'THROW', 'LOGIC', 'POST_IF', ':', '[', 'INDENT', 'COMPOUND_ASSIGN', 'RETURN', 'MATH', 'BY', 'LEADING_WHEN'];
1937
+ isUnary = !p ? false : (_ref = p[0], __indexOf.call(unaries, _ref) >= 0);
1938
+ if ((isUnary && token.spaced) || (!isUnary && !token.spaced && !token.newLine)) {
1939
+ return {
1940
+ context: token[1]
1941
+ };
1942
+ } else {
1943
+ return null;
1944
+ }
1945
+ };
1946
+
1947
+ SpaceOperators.prototype.lintMath = function(token, tokenApi) {
1948
+ if (!token.spaced && !token.newLine) {
1949
+ return {
1950
+ context: token[1]
1951
+ };
1952
+ } else {
1953
+ return null;
1954
+ }
1955
+ };
1956
+
1957
+ SpaceOperators.prototype.isInExtendedRegex = function() {
1958
+ var t, _i, _len, _ref;
1959
+ _ref = this.callTokens;
1960
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1961
+ t = _ref[_i];
1962
+ if (t.isRegex) {
1963
+ return true;
1964
+ }
1965
+ }
1966
+ return false;
1967
+ };
1968
+
1969
+ SpaceOperators.prototype.lintCall = function(token, tokenApi) {
1970
+ var p;
1971
+ if (token[0] === 'CALL_START') {
1972
+ p = tokenApi.peek(-1);
1973
+ token.isRegex = p && p[0] === 'IDENTIFIER' && p[1] === 'RegExp';
1974
+ this.callTokens.push(token);
1975
+ } else {
1976
+ this.callTokens.pop();
1977
+ }
1978
+ return null;
1979
+ };
1980
+
1981
+ SpaceOperators.prototype.isInInterpolation = function() {
1982
+ var t, _i, _len, _ref;
1983
+ _ref = this.parenTokens;
1984
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1985
+ t = _ref[_i];
1986
+ if (t.isInterpolation) {
1987
+ return true;
1988
+ }
1989
+ }
1990
+ return false;
1991
+ };
1992
+
1993
+ SpaceOperators.prototype.lintParens = function(token, tokenApi) {
1994
+ var i, n1, n2, p1;
1995
+ if (token[0] === '(') {
1996
+ p1 = tokenApi.peek(-1);
1997
+ n1 = tokenApi.peek(1);
1998
+ n2 = tokenApi.peek(2);
1999
+ i = n1 && n2 && n1[0] === 'STRING' && n2[0] === '+';
2000
+ token.isInterpolation = i;
2001
+ this.parenTokens.push(token);
2002
+ } else {
2003
+ this.parenTokens.pop();
2004
+ }
2005
+ return null;
2006
+ };
2007
+
2008
+ return SpaceOperators;
2009
+
2010
+ })();
2011
+
2012
+
2013
+ },{}]},{},[4])(4)
2014
+ });
2015
+ ;