coffeelint 0.2.3 → 0.2.5

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
1
  ---
2
2
  SHA1:
3
- metadata.gz: 12213463c6912beabd247d01c967b81a52e1ba65
4
- data.tar.gz: 440bdcd9141c0acdb17b6bae17fee664bd561ee8
3
+ metadata.gz: 52e26570cb6aeb608b13718ee0643a3587799f5b
4
+ data.tar.gz: 87ca1b9e93e502ab77443fd76ab7f8b227c098cd
5
5
  SHA512:
6
- metadata.gz: 1b65aaf5269d62114576b8543bdcaec783e7d1cb9e7d634340dfe5cc4781ff270e0ba2a1fff7e8a65c9fdaf74e6782d1ab550b4139311ddbad97d378630e4e22
7
- data.tar.gz: 75cf7d50c532da9d6e57d8dd2066389d5e0d6f572d532d7488bc160dcac7d6046206b8246691cbc6b955e740aa6a84021e039db48749107d576b91b252204f3a
6
+ metadata.gz: 4bb4389a7e90c880e22ffb9a11f4e881a70225749c410a707d37c8e59d7e0c028c2386d979659804eaa4d612054c93bc817cba2f382ac42640f085a9ce6c5e26
7
+ data.tar.gz: 0dda5a52009fe77364cc10812362b249dd48368410d3796700e2d0c521a44ecfb53bd17419d66a4b836e9fe8bdccd5b82edd4b1fedb6199f6328254e6c55c40e
@@ -1,3 +1,3 @@
1
1
  [submodule "coffeelint"]
2
2
  path = coffeelint
3
- url = git://github.com/clutchski/coffeelint.git
3
+ url = git://github.com/zmbush/coffeelint.git
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Coffeelint [![Build Status](https://travis-ci.org/zmbush/coffeelint-ruby.svg?branch=master)](https://travis-ci.org/zmbush/coffeelint-ruby) [![Gem Version](https://badge.fury.io/rb/coffeelint.png)](http://badge.fury.io/rb/coffeelint)
2
2
 
3
- Using coffeelint version: v1.1.0
3
+ Using coffeelint version: v1.1.0-21-g5dc0408-20-gc896693
4
4
 
5
5
  Coffeelint is a set of simple ruby bindings for [coffeelint](https://github.com/clutchski/coffeelint).
6
6
 
@@ -21,6 +21,7 @@ Gem::Specification.new do |gem|
21
21
 
22
22
  gem.add_dependency "coffee-script"
23
23
  gem.add_dependency "json"
24
+ gem.add_dependency "execjs"
24
25
 
25
26
  gem.add_development_dependency 'rspec'
26
27
  gem.add_development_dependency 'rake'
@@ -25,7 +25,7 @@ module.exports={
25
25
  "optimist": ">=0.2.8",
26
26
  "coffee-script": "~1.7",
27
27
  "glob": ">=3.1.9",
28
- "browserify": "~3.x",
28
+ "browserify": "~3.37",
29
29
  "coffeeify": "~0.6.0"
30
30
  },
31
31
  "devDependencies": {
@@ -53,17 +53,61 @@ module.exports={
53
53
  }
54
54
 
55
55
  },{}],2:[function(_dereq_,module,exports){
56
- var ASTApi, ASTLinter, BaseLinter,
56
+ var ASTApi, ASTLinter, BaseLinter, hasChildren, node_children,
57
57
  __hasProp = {}.hasOwnProperty,
58
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
59
 
60
60
  BaseLinter = _dereq_('./base_linter.coffee');
61
61
 
62
+ node_children = {
63
+ Class: ['variable', 'parent', 'body'],
64
+ Code: ['params', 'body'],
65
+ For: ['body', 'source', 'guard', 'step'],
66
+ If: ['condition', 'body', 'elseBody'],
67
+ Obj: ['properties'],
68
+ Op: ['first', 'second'],
69
+ Switch: ['subject', 'cases', 'otherwise'],
70
+ Try: ['attempt', 'recovery', 'ensure'],
71
+ Value: ['base', 'properties'],
72
+ While: ['condition', 'guard', 'body']
73
+ };
74
+
75
+ hasChildren = function(node, children) {
76
+ var _ref;
77
+ return (node != null ? (_ref = node.children) != null ? _ref.length : void 0 : void 0) === children.length && (node != null ? node.children.every(function(elem, i) {
78
+ return elem === children[i];
79
+ }) : void 0);
80
+ };
81
+
62
82
  ASTApi = (function() {
63
83
  function ASTApi(config) {
64
84
  this.config = config;
65
85
  }
66
86
 
87
+ ASTApi.prototype.getNodeName = function(node) {
88
+ var children, name, _ref;
89
+ name = node != null ? (_ref = node.constructor) != null ? _ref.name : void 0 : void 0;
90
+ if (name === (function() {
91
+ var _results;
92
+ _results = [];
93
+ for (name in node_children) {
94
+ if (!__hasProp.call(node_children, name)) continue;
95
+ _results.push(name);
96
+ }
97
+ return _results;
98
+ })()) {
99
+ return name;
100
+ } else {
101
+ for (name in node_children) {
102
+ if (!__hasProp.call(node_children, name)) continue;
103
+ children = node_children[name];
104
+ if (hasChildren(node, children)) {
105
+ return name;
106
+ }
107
+ }
108
+ }
109
+ };
110
+
67
111
  return ASTApi;
68
112
 
69
113
  })();
@@ -418,6 +462,12 @@ coffeelint.registerRule(_dereq_('./rules/missing_fat_arrows.coffee'));
418
462
 
419
463
  coffeelint.registerRule(_dereq_('./rules/non_empty_constructor_needs_parens.coffee'));
420
464
 
465
+ coffeelint.registerRule(_dereq_('./rules/no_unnecessary_double_quotes.coffee'));
466
+
467
+ coffeelint.registerRule(_dereq_('./rules/no_debugger.coffee'));
468
+
469
+ coffeelint.registerRule(_dereq_('./rules/no_interpolation_in_single_quotes.coffee'));
470
+
421
471
  hasSyntaxError = function(source) {
422
472
  try {
423
473
  CoffeeScript.tokens(source);
@@ -514,7 +564,7 @@ coffeelint.lint = function(source, userConfig, literate) {
514
564
  };
515
565
 
516
566
 
517
- },{"./../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(_dereq_,module,exports){
567
+ },{"./../package.json":1,"./ast_linter.coffee":2,"./lexical_linter.coffee":5,"./line_linter.coffee":6,"./rules.coffee":7,"./rules/arrow_spacing.coffee":8,"./rules/camel_case_classes.coffee":9,"./rules/colon_assignment_spacing.coffee":10,"./rules/cyclomatic_complexity.coffee":11,"./rules/duplicate_key.coffee":12,"./rules/empty_constructor_needs_parens.coffee":13,"./rules/indentation.coffee":14,"./rules/line_endings.coffee":15,"./rules/max_line_length.coffee":16,"./rules/missing_fat_arrows.coffee":17,"./rules/newlines_after_classes.coffee":18,"./rules/no_backticks.coffee":19,"./rules/no_debugger.coffee":20,"./rules/no_empty_param_list.coffee":21,"./rules/no_implicit_braces.coffee":22,"./rules/no_implicit_parens.coffee":23,"./rules/no_interpolation_in_single_quotes.coffee":24,"./rules/no_plusplus.coffee":25,"./rules/no_stand_alone_at.coffee":26,"./rules/no_tabs.coffee":27,"./rules/no_throwing_strings.coffee":28,"./rules/no_trailing_semicolons.coffee":29,"./rules/no_trailing_whitespace.coffee":30,"./rules/no_unnecessary_double_quotes.coffee":31,"./rules/no_unnecessary_fat_arrows.coffee":32,"./rules/non_empty_constructor_needs_parens.coffee":33,"./rules/space_operators.coffee":34}],5:[function(_dereq_,module,exports){
518
568
  var BaseLinter, LexicalLinter, TokenApi,
519
569
  __hasProp = {}.hasOwnProperty,
520
570
  __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; },
@@ -978,7 +1028,7 @@ module.exports = NoTabs = (function() {
978
1028
 
979
1029
  NoTabs.prototype.getComplexity = function(node) {
980
1030
  var complexity, name, _ref;
981
- name = node.constructor.name;
1031
+ name = this.astApi.getNodeName(node);
982
1032
  complexity = name === 'If' || name === 'While' || name === 'For' || name === 'Try' ? 1 : name === 'Op' && ((_ref = node.operator) === '&&' || _ref === '||') ? 1 : name === 'Switch' ? node.cases.length : 0;
983
1033
  return complexity;
984
1034
  };
@@ -990,8 +1040,8 @@ module.exports = NoTabs = (function() {
990
1040
  };
991
1041
 
992
1042
  NoTabs.prototype.lintNode = function(node, line) {
993
- var complexity, error, name, rule;
994
- name = node.constructor.name;
1043
+ var complexity, error, name, rule, _ref;
1044
+ name = (_ref = this.astApi) != null ? _ref.getNodeName(node) : void 0;
995
1045
  complexity = this.getComplexity(node);
996
1046
  node.eachChild((function(_this) {
997
1047
  return function(childNode) {
@@ -1333,60 +1383,25 @@ module.exports = MaxLineLength = (function() {
1333
1383
 
1334
1384
 
1335
1385
  },{}],17:[function(_dereq_,module,exports){
1336
- var MissingFatArrows, any, isClass, isCode, isFatArrowCode, isObject, isThis, isValue, methodsOfClass, needsFatArrow,
1386
+ var MissingFatArrows, any,
1387
+ __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
1337
1388
  __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; };
1338
1389
 
1339
- isCode = function(node) {
1340
- return (node != null ? node.constructor.name : void 0) === 'Code';
1341
- };
1342
-
1343
- isClass = function(node) {
1344
- return node.constructor.name === 'Class';
1345
- };
1346
-
1347
- isValue = function(node) {
1348
- return node.constructor.name === 'Value';
1349
- };
1350
-
1351
- isObject = function(node) {
1352
- return node.constructor.name === 'Obj';
1353
- };
1354
-
1355
- isThis = function(node) {
1356
- return isValue(node) && node.base.value === 'this';
1357
- };
1358
-
1359
- isFatArrowCode = function(node) {
1360
- return isCode(node) && node.bound;
1361
- };
1362
-
1363
1390
  any = function(arr, test) {
1364
1391
  return arr.reduce((function(res, elt) {
1365
1392
  return res || test(elt);
1366
1393
  }), false);
1367
1394
  };
1368
1395
 
1369
- needsFatArrow = function(node) {
1370
- return isCode(node) && (any(node.params, function(param) {
1371
- return param.contains(isThis) != null;
1372
- }) || (node.body.contains(isThis) != null));
1373
- };
1374
-
1375
- methodsOfClass = function(classNode) {
1376
- var bodyNodes, returnNode;
1377
- bodyNodes = classNode.body.expressions;
1378
- returnNode = bodyNodes[bodyNodes.length - 1];
1379
- if ((returnNode != null) && isValue(returnNode) && isObject(returnNode.base)) {
1380
- return returnNode.base.properties.map(function(assignNode) {
1381
- return assignNode.value;
1382
- }).filter(isCode);
1383
- } else {
1384
- return [];
1385
- }
1386
- };
1387
-
1388
1396
  module.exports = MissingFatArrows = (function() {
1389
- function MissingFatArrows() {}
1397
+ function MissingFatArrows() {
1398
+ this.isFatArrowCode = __bind(this.isFatArrowCode, this);
1399
+ this.isThis = __bind(this.isThis, this);
1400
+ this.isObject = __bind(this.isObject, this);
1401
+ this.isValue = __bind(this.isValue, this);
1402
+ this.isClass = __bind(this.isClass, this);
1403
+ this.isCode = __bind(this.isCode, this);
1404
+ }
1390
1405
 
1391
1406
  MissingFatArrows.prototype.rule = {
1392
1407
  name: 'missing_fat_arrows',
@@ -1396,37 +1411,83 @@ module.exports = MissingFatArrows = (function() {
1396
1411
  };
1397
1412
 
1398
1413
  MissingFatArrows.prototype.lintAST = function(node, astApi) {
1399
- this.lintNode(node, astApi);
1414
+ this.astApi = astApi;
1415
+ this.lintNode(node);
1400
1416
  return void 0;
1401
1417
  };
1402
1418
 
1403
- MissingFatArrows.prototype.lintNode = function(node, astApi, methods) {
1419
+ MissingFatArrows.prototype.lintNode = function(node, methods) {
1404
1420
  var error;
1405
1421
  if (methods == null) {
1406
1422
  methods = [];
1407
1423
  }
1408
- if ((!isFatArrowCode(node)) && (__indexOf.call(methods, node) < 0) && (needsFatArrow(node))) {
1409
- error = astApi.createError({
1424
+ if ((!this.isFatArrowCode(node)) && (__indexOf.call(methods, node) < 0) && (this.needsFatArrow(node))) {
1425
+ error = this.astApi.createError({
1410
1426
  lineNumber: node.locationData.first_line + 1
1411
1427
  });
1412
1428
  this.errors.push(error);
1413
1429
  }
1414
1430
  return node.eachChild((function(_this) {
1415
1431
  return function(child) {
1416
- return _this.lintNode(child, astApi, (function() {
1432
+ return _this.lintNode(child, (function() {
1417
1433
  switch (false) {
1418
- case !isClass(node):
1419
- return methodsOfClass(node);
1420
- case !isCode(node):
1434
+ case !this.isClass(node):
1435
+ return this.methodsOfClass(node);
1436
+ case !this.isCode(node):
1421
1437
  return [];
1422
1438
  default:
1423
1439
  return methods;
1424
1440
  }
1425
- })());
1441
+ }).call(_this));
1426
1442
  };
1427
1443
  })(this));
1428
1444
  };
1429
1445
 
1446
+ MissingFatArrows.prototype.isCode = function(node) {
1447
+ return this.astApi.getNodeName(node) === 'Code';
1448
+ };
1449
+
1450
+ MissingFatArrows.prototype.isClass = function(node) {
1451
+ return this.astApi.getNodeName(node) === 'Class';
1452
+ };
1453
+
1454
+ MissingFatArrows.prototype.isValue = function(node) {
1455
+ return this.astApi.getNodeName(node) === 'Value';
1456
+ };
1457
+
1458
+ MissingFatArrows.prototype.isObject = function(node) {
1459
+ return this.astApi.getNodeName(node) === 'Obj';
1460
+ };
1461
+
1462
+ MissingFatArrows.prototype.isThis = function(node) {
1463
+ return this.isValue(node) && node.base.value === 'this';
1464
+ };
1465
+
1466
+ MissingFatArrows.prototype.isFatArrowCode = function(node) {
1467
+ return this.isCode(node) && node.bound;
1468
+ };
1469
+
1470
+ MissingFatArrows.prototype.needsFatArrow = function(node) {
1471
+ return this.isCode(node) && (any(node.params, (function(_this) {
1472
+ return function(param) {
1473
+ return param.contains(_this.isThis) != null;
1474
+ };
1475
+ })(this)) || (node.body.contains(this.isThis) != null));
1476
+ };
1477
+
1478
+ MissingFatArrows.prototype.methodsOfClass = function(classNode) {
1479
+ var bodyNodes, returnNode;
1480
+ bodyNodes = classNode.body.expressions;
1481
+ returnNode = bodyNodes[bodyNodes.length - 1];
1482
+ if ((returnNode != null) && this.isValue(returnNode) && this.isObject(returnNode.base)) {
1483
+ return returnNode.base.properties.map(function(assignNode) {
1484
+ return assignNode.value;
1485
+ }).filter(this.isCode);
1486
+ } else {
1487
+ return [];
1488
+ }
1489
+ };
1490
+
1430
1491
  return MissingFatArrows;
1431
1492
 
1432
1493
  })();
@@ -1492,6 +1553,32 @@ module.exports = NoBackticks = (function() {
1492
1553
 
1493
1554
 
1494
1555
  },{}],20:[function(_dereq_,module,exports){
1556
+ var NoDebugger;
1557
+
1558
+ module.exports = NoDebugger = (function() {
1559
+ function NoDebugger() {}
1560
+
1561
+ NoDebugger.prototype.rule = {
1562
+ name: 'no_debugger',
1563
+ level: 'warn',
1564
+ message: 'Debugger statements will cause warnings',
1565
+ description: "This rule detects the `debugger` statement.\nThis rule is `warn` by default."
1566
+ };
1567
+
1568
+ NoDebugger.prototype.tokens = ["DEBUGGER"];
1569
+
1570
+ NoDebugger.prototype.lintToken = function(token, tokenApi) {
1571
+ return {
1572
+ context: "found '" + token[0] + "'"
1573
+ };
1574
+ };
1575
+
1576
+ return NoDebugger;
1577
+
1578
+ })();
1579
+
1580
+
1581
+ },{}],21:[function(_dereq_,module,exports){
1495
1582
  var NoEmptyParamList;
1496
1583
 
1497
1584
  module.exports = NoEmptyParamList = (function() {
@@ -1517,7 +1604,7 @@ module.exports = NoEmptyParamList = (function() {
1517
1604
  })();
1518
1605
 
1519
1606
 
1520
- },{}],21:[function(_dereq_,module,exports){
1607
+ },{}],22:[function(_dereq_,module,exports){
1521
1608
  var NoImplicitBraces;
1522
1609
 
1523
1610
  module.exports = NoImplicitBraces = (function() {
@@ -1566,7 +1653,7 @@ module.exports = NoImplicitBraces = (function() {
1566
1653
  })();
1567
1654
 
1568
1655
 
1569
- },{}],22:[function(_dereq_,module,exports){
1656
+ },{}],23:[function(_dereq_,module,exports){
1570
1657
  var NoImplicitParens;
1571
1658
 
1572
1659
  module.exports = NoImplicitParens = (function() {
@@ -1574,15 +1661,33 @@ module.exports = NoImplicitParens = (function() {
1574
1661
 
1575
1662
  NoImplicitParens.prototype.rule = {
1576
1663
  name: 'no_implicit_parens',
1664
+ strict: true,
1577
1665
  level: 'ignore',
1578
1666
  message: 'Implicit parens are forbidden',
1579
1667
  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."
1580
1668
  };
1581
1669
 
1582
- NoImplicitParens.prototype.tokens = ["CALL_START"];
1670
+ NoImplicitParens.prototype.tokens = ["CALL_END"];
1583
1671
 
1584
1672
  NoImplicitParens.prototype.lintToken = function(token, tokenApi) {
1585
- return token.generated;
1673
+ var i, t;
1674
+ if (token.generated) {
1675
+ if (tokenApi.config[this.rule.name].strict !== false) {
1676
+ return true;
1677
+ } else {
1678
+ i = -1;
1679
+ while (true) {
1680
+ t = tokenApi.peek(i);
1681
+ if ((t == null) || t[0] === 'CALL_START') {
1682
+ return true;
1683
+ }
1684
+ if (t.newLine) {
1685
+ return null;
1686
+ }
1687
+ i -= 1;
1688
+ }
1689
+ }
1690
+ }
1586
1691
  };
1587
1692
 
1588
1693
  return NoImplicitParens;
@@ -1590,7 +1695,34 @@ module.exports = NoImplicitParens = (function() {
1590
1695
  })();
1591
1696
 
1592
1697
 
1593
- },{}],23:[function(_dereq_,module,exports){
1698
+ },{}],24:[function(_dereq_,module,exports){
1699
+ var NoInterpolationInSingleQuotes;
1700
+
1701
+ module.exports = NoInterpolationInSingleQuotes = (function() {
1702
+ function NoInterpolationInSingleQuotes() {}
1703
+
1704
+ NoInterpolationInSingleQuotes.prototype.rule = {
1705
+ name: 'no_interpolation_in_single_quotes',
1706
+ level: 'ignore',
1707
+ message: 'Interpolation in single quoted strings is forbidden',
1708
+ 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.'
1709
+ };
1710
+
1711
+ NoInterpolationInSingleQuotes.prototype.tokens = ['STRING'];
1712
+
1713
+ NoInterpolationInSingleQuotes.prototype.lintToken = function(token, tokenApi) {
1714
+ var hasInterpolation, tokenValue;
1715
+ tokenValue = token[1];
1716
+ hasInterpolation = tokenValue.match(/#\{[^}]+\}/);
1717
+ return hasInterpolation;
1718
+ };
1719
+
1720
+ return NoInterpolationInSingleQuotes;
1721
+
1722
+ })();
1723
+
1724
+
1725
+ },{}],25:[function(_dereq_,module,exports){
1594
1726
  var NoPlusPlus;
1595
1727
 
1596
1728
  module.exports = NoPlusPlus = (function() {
@@ -1616,7 +1748,7 @@ module.exports = NoPlusPlus = (function() {
1616
1748
  })();
1617
1749
 
1618
1750
 
1619
- },{}],24:[function(_dereq_,module,exports){
1751
+ },{}],26:[function(_dereq_,module,exports){
1620
1752
  var NoStandAloneAt;
1621
1753
 
1622
1754
  module.exports = NoStandAloneAt = (function() {
@@ -1652,7 +1784,7 @@ module.exports = NoStandAloneAt = (function() {
1652
1784
  })();
1653
1785
 
1654
1786
 
1655
- },{}],25:[function(_dereq_,module,exports){
1787
+ },{}],27:[function(_dereq_,module,exports){
1656
1788
  var NoTabs, indentationRegex,
1657
1789
  __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; };
1658
1790
 
@@ -1683,7 +1815,7 @@ module.exports = NoTabs = (function() {
1683
1815
  })();
1684
1816
 
1685
1817
 
1686
- },{}],26:[function(_dereq_,module,exports){
1818
+ },{}],28:[function(_dereq_,module,exports){
1687
1819
  var NoThrowingStrings;
1688
1820
 
1689
1821
  module.exports = NoThrowingStrings = (function() {
@@ -1710,7 +1842,7 @@ module.exports = NoThrowingStrings = (function() {
1710
1842
  })();
1711
1843
 
1712
1844
 
1713
- },{}],27:[function(_dereq_,module,exports){
1845
+ },{}],29:[function(_dereq_,module,exports){
1714
1846
  var NoTrailingSemicolons, regexes,
1715
1847
  __slice = [].slice;
1716
1848
 
@@ -1759,7 +1891,7 @@ module.exports = NoTrailingSemicolons = (function() {
1759
1891
  })();
1760
1892
 
1761
1893
 
1762
- },{}],28:[function(_dereq_,module,exports){
1894
+ },{}],30:[function(_dereq_,module,exports){
1763
1895
  var NoTrailingWhitespace, regexes;
1764
1896
 
1765
1897
  regexes = {
@@ -1822,20 +1954,62 @@ module.exports = NoTrailingWhitespace = (function() {
1822
1954
  })();
1823
1955
 
1824
1956
 
1825
- },{}],29:[function(_dereq_,module,exports){
1826
- var NoUnnecessaryFatArrows, any, isCode, isFatArrowCode, isThis, needsFatArrow;
1957
+ },{}],31:[function(_dereq_,module,exports){
1958
+ var NoUnnecessaryDoubleQuotes;
1827
1959
 
1828
- isCode = function(node) {
1829
- return node.constructor.name === 'Code';
1830
- };
1960
+ module.exports = NoUnnecessaryDoubleQuotes = (function() {
1961
+ function NoUnnecessaryDoubleQuotes() {}
1831
1962
 
1832
- isFatArrowCode = function(node) {
1833
- return isCode(node) && node.bound;
1834
- };
1963
+ NoUnnecessaryDoubleQuotes.prototype.rule = {
1964
+ name: 'no_unnecessary_double_quotes',
1965
+ level: 'ignore',
1966
+ message: 'Unnecessary double quotes are forbidden',
1967
+ 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.'
1968
+ };
1835
1969
 
1836
- isThis = function(node) {
1837
- return node.constructor.name === 'Value' && node.base.value === 'this';
1838
- };
1970
+ NoUnnecessaryDoubleQuotes.prototype.tokens = ['STRING'];
1971
+
1972
+ NoUnnecessaryDoubleQuotes.prototype.lintToken = function(token, tokenApi) {
1973
+ var hasLegalConstructs, stringValue, tokenValue;
1974
+ tokenValue = token[1];
1975
+ stringValue = tokenValue.match(/^\"(.*)\"$/);
1976
+ if (!stringValue) {
1977
+ return false;
1978
+ }
1979
+ hasLegalConstructs = this.isInterpolated(tokenApi) || this.containsSingleQuote(tokenValue);
1980
+ return !hasLegalConstructs;
1981
+ };
1982
+
1983
+ NoUnnecessaryDoubleQuotes.prototype.isInterpolated = function(tokenApi) {
1984
+ var currentIndex, i, isInterpolated, lineTokens, token, tokenName, _i, _ref;
1985
+ currentIndex = tokenApi.i;
1986
+ isInterpolated = false;
1987
+ lineTokens = tokenApi.tokensByLine[tokenApi.lineNumber];
1988
+ for (i = _i = 1; 1 <= currentIndex ? _i <= currentIndex : _i >= currentIndex; i = 1 <= currentIndex ? ++_i : --_i) {
1989
+ token = tokenApi.peek(-i);
1990
+ tokenName = token[0];
1991
+ if (tokenName === ')' && token.stringEnd) {
1992
+ break;
1993
+ } else if (tokenName === '(' && ((_ref = token.origin) != null ? _ref[1] : void 0) === "string interpolation") {
1994
+ isInterpolated = true;
1995
+ break;
1996
+ }
1997
+ }
1998
+ return isInterpolated;
1999
+ };
2000
+
2001
+ NoUnnecessaryDoubleQuotes.prototype.containsSingleQuote = function(tokenValue) {
2002
+ return tokenValue.indexOf("'") !== -1;
2003
+ };
2004
+
2005
+ return NoUnnecessaryDoubleQuotes;
2006
+
2007
+ })();
2008
+
2009
+
2010
+ },{}],32:[function(_dereq_,module,exports){
2011
+ var NoUnnecessaryFatArrows, any,
2012
+ __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
1839
2013
 
1840
2014
  any = function(arr, test) {
1841
2015
  return arr.reduce((function(res, elt) {
@@ -1843,16 +2017,11 @@ any = function(arr, test) {
1843
2017
  }), false);
1844
2018
  };
1845
2019
 
1846
- needsFatArrow = function(node) {
1847
- return isCode(node) && (any(node.params, function(param) {
1848
- return param.contains(isThis) != null;
1849
- }) || (node.body.contains(isThis) != null) || (node.body.contains(function(child) {
1850
- return isFatArrowCode(child) && needsFatArrow(child);
1851
- }) != null));
1852
- };
1853
-
1854
2020
  module.exports = NoUnnecessaryFatArrows = (function() {
1855
- function NoUnnecessaryFatArrows() {}
2021
+ function NoUnnecessaryFatArrows() {
2022
+ this.needsFatArrow = __bind(this.needsFatArrow, this);
2023
+ this.isThis = __bind(this.isThis, this);
2024
+ }
1856
2025
 
1857
2026
  NoUnnecessaryFatArrows.prototype.rule = {
1858
2027
  name: 'no_unnecessary_fat_arrows',
@@ -1862,31 +2031,60 @@ module.exports = NoUnnecessaryFatArrows = (function() {
1862
2031
  };
1863
2032
 
1864
2033
  NoUnnecessaryFatArrows.prototype.lintAST = function(node, astApi) {
1865
- this.lintNode(node, astApi);
2034
+ this.astApi = astApi;
2035
+ this.lintNode(node);
1866
2036
  return void 0;
1867
2037
  };
1868
2038
 
1869
- NoUnnecessaryFatArrows.prototype.lintNode = function(node, astApi) {
2039
+ NoUnnecessaryFatArrows.prototype.lintNode = function(node) {
1870
2040
  var error;
1871
- if ((isFatArrowCode(node)) && (!needsFatArrow(node))) {
1872
- error = astApi.createError({
2041
+ if ((this.isFatArrowCode(node)) && (!this.needsFatArrow(node))) {
2042
+ error = this.astApi.createError({
1873
2043
  lineNumber: node.locationData.first_line + 1
1874
2044
  });
1875
2045
  this.errors.push(error);
1876
2046
  }
1877
2047
  return node.eachChild((function(_this) {
1878
2048
  return function(child) {
1879
- return _this.lintNode(child, astApi);
2049
+ return _this.lintNode(child);
1880
2050
  };
1881
2051
  })(this));
1882
2052
  };
1883
2053
 
2054
+ NoUnnecessaryFatArrows.prototype.isCode = function(node) {
2055
+ return this.astApi.getNodeName(node) === 'Code';
2056
+ };
2057
+
2058
+ NoUnnecessaryFatArrows.prototype.isFatArrowCode = function(node) {
2059
+ return this.isCode(node) && node.bound;
2060
+ };
2061
+
2062
+ NoUnnecessaryFatArrows.prototype.isValue = function(node) {
2063
+ return this.astApi.getNodeName(node) === 'Value';
2064
+ };
2065
+
2066
+ NoUnnecessaryFatArrows.prototype.isThis = function(node) {
2067
+ return this.isValue(node) && node.base.value === 'this';
2068
+ };
2069
+
2070
+ NoUnnecessaryFatArrows.prototype.needsFatArrow = function(node) {
2071
+ return this.isCode(node) && (any(node.params, (function(_this) {
2072
+ return function(param) {
2073
+ return param.contains(_this.isThis) != null;
2074
+ };
2075
+ })(this)) || (node.body.contains(this.isThis) != null) || (node.body.contains((function(_this) {
2076
+ return function(child) {
2077
+ return _this.isFatArrowCode(child) && _this.needsFatArrow(child);
2078
+ };
2079
+ })(this)) != null));
2080
+ };
2081
+
1884
2082
  return NoUnnecessaryFatArrows;
1885
2083
 
1886
2084
  })();
1887
2085
 
1888
2086
 
1889
- },{}],30:[function(_dereq_,module,exports){
2087
+ },{}],33:[function(_dereq_,module,exports){
1890
2088
  var NonEmptyConstructorNeedsParens, ParentClass,
1891
2089
  __hasProp = {}.hasOwnProperty,
1892
2090
  __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; };
@@ -1918,7 +2116,7 @@ module.exports = NonEmptyConstructorNeedsParens = (function(_super) {
1918
2116
  })(ParentClass);
1919
2117
 
1920
2118
 
1921
- },{"./empty_constructor_needs_parens.coffee":13}],31:[function(_dereq_,module,exports){
2119
+ },{"./empty_constructor_needs_parens.coffee":13}],34:[function(_dereq_,module,exports){
1922
2120
  var SpaceOperators,
1923
2121
  __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; };
1924
2122
 
@@ -1,3 +1,3 @@
1
1
  module Coffeelint
2
- VERSION = "0.2.3"
2
+ VERSION = "0.2.5"
3
3
  end
@@ -18,4 +18,26 @@ describe Coffeelint do
18
18
  results = Coffeelint.lint('apple;', :config_file => "/tmp/coffeelint.json")
19
19
  results.length.should == 0
20
20
  end
21
+
22
+ it 'should report missing fat arrow' do
23
+ results = Coffeelint.lint "hey: ->\n @bort()\n", :missing_fat_arrows => { :level => "error" }
24
+ results.length.should == 1
25
+ end
26
+
27
+ it 'should report unnecessary fat arrow' do
28
+ results = Coffeelint.lint "hey: =>\n bort()\n", :no_unnecessary_fat_arrows => { :level => "error" }
29
+ results.length.should == 1
30
+ end
31
+
32
+ it 'should report cyclomatic complexity' do
33
+ results = Coffeelint.lint(<<-EOF, :cyclomatic_complexity => { :level => "error" })
34
+ x = ->
35
+ 1 and 2 and 3 and
36
+ 4 and 5 and 6 and
37
+ 7 and 8 and 9 and
38
+ 10 and 11
39
+ EOF
40
+ results.length.should == 1
41
+ results[0]['name'].should == 'cyclomatic_complexity'
42
+ end
21
43
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: coffeelint
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Zachary Bush
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-31 00:00:00.000000000 Z
11
+ date: 2014-04-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: coffee-script
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - '>='
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: execjs
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: rspec
43
57
  requirement: !ruby/object:Gem::Requirement