variableNameRule.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. "use strict";
  2. var __extends = (this && this.__extends) || function (d, b) {
  3. for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
  4. function __() { this.constructor = d; }
  5. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  6. };
  7. var ts = require("typescript");
  8. var Lint = require("../lint");
  9. var BANNED_KEYWORDS = ["any", "Number", "number", "String", "string", "Boolean", "boolean", "Undefined", "undefined"];
  10. var OPTION_LEADING_UNDERSCORE = "allow-leading-underscore";
  11. var OPTION_TRAILING_UNDERSCORE = "allow-trailing-underscore";
  12. var OPTION_BAN_KEYWORDS = "ban-keywords";
  13. var OPTION_CHECK_FORMAT = "check-format";
  14. var Rule = (function (_super) {
  15. __extends(Rule, _super);
  16. function Rule() {
  17. _super.apply(this, arguments);
  18. }
  19. Rule.prototype.apply = function (sourceFile) {
  20. var variableNameWalker = new VariableNameWalker(sourceFile, this.getOptions());
  21. return this.applyWithWalker(variableNameWalker);
  22. };
  23. Rule.FORMAT_FAILURE = "variable name must be in camelcase or uppercase";
  24. Rule.KEYWORD_FAILURE = "variable name clashes with keyword/type";
  25. return Rule;
  26. }(Lint.Rules.AbstractRule));
  27. exports.Rule = Rule;
  28. var VariableNameWalker = (function (_super) {
  29. __extends(VariableNameWalker, _super);
  30. function VariableNameWalker(sourceFile, options) {
  31. _super.call(this, sourceFile, options);
  32. this.shouldBanKeywords = this.hasOption(OPTION_BAN_KEYWORDS);
  33. this.shouldCheckFormat = !this.shouldBanKeywords || this.hasOption(OPTION_CHECK_FORMAT);
  34. }
  35. VariableNameWalker.prototype.visitBindingElement = function (node) {
  36. if (node.name.kind === ts.SyntaxKind.Identifier) {
  37. var identifier = node.name;
  38. this.handleVariableNameFormat(identifier);
  39. this.handleVariableNameKeyword(identifier);
  40. }
  41. _super.prototype.visitBindingElement.call(this, node);
  42. };
  43. VariableNameWalker.prototype.visitParameterDeclaration = function (node) {
  44. if (node.name.kind === ts.SyntaxKind.Identifier) {
  45. var identifier = node.name;
  46. this.handleVariableNameFormat(identifier);
  47. this.handleVariableNameKeyword(identifier);
  48. }
  49. _super.prototype.visitParameterDeclaration.call(this, node);
  50. };
  51. VariableNameWalker.prototype.visitPropertyDeclaration = function (node) {
  52. if (node.name != null && node.name.kind === ts.SyntaxKind.Identifier) {
  53. var identifier = node.name;
  54. this.handleVariableNameFormat(identifier);
  55. }
  56. _super.prototype.visitPropertyDeclaration.call(this, node);
  57. };
  58. VariableNameWalker.prototype.visitVariableDeclaration = function (node) {
  59. if (node.name.kind === ts.SyntaxKind.Identifier) {
  60. var identifier = node.name;
  61. this.handleVariableNameFormat(identifier);
  62. this.handleVariableNameKeyword(identifier);
  63. }
  64. _super.prototype.visitVariableDeclaration.call(this, node);
  65. };
  66. VariableNameWalker.prototype.visitVariableStatement = function (node) {
  67. if (!Lint.hasModifier(node.modifiers, ts.SyntaxKind.DeclareKeyword)) {
  68. _super.prototype.visitVariableStatement.call(this, node);
  69. }
  70. };
  71. VariableNameWalker.prototype.handleVariableNameFormat = function (name) {
  72. var variableName = name.text;
  73. if (this.shouldCheckFormat && !this.isCamelCase(variableName) && !isUpperCase(variableName)) {
  74. this.addFailure(this.createFailure(name.getStart(), name.getWidth(), Rule.FORMAT_FAILURE));
  75. }
  76. };
  77. VariableNameWalker.prototype.handleVariableNameKeyword = function (name) {
  78. var variableName = name.text;
  79. if (this.shouldBanKeywords && BANNED_KEYWORDS.indexOf(variableName) !== -1) {
  80. this.addFailure(this.createFailure(name.getStart(), name.getWidth(), Rule.KEYWORD_FAILURE));
  81. }
  82. };
  83. VariableNameWalker.prototype.isCamelCase = function (name) {
  84. var firstCharacter = name.charAt(0);
  85. var lastCharacter = name.charAt(name.length - 1);
  86. var middle = name.substr(1, name.length - 2);
  87. if (name.length <= 0) {
  88. return true;
  89. }
  90. if (!this.hasOption(OPTION_LEADING_UNDERSCORE) && firstCharacter === "_") {
  91. return false;
  92. }
  93. if (!this.hasOption(OPTION_TRAILING_UNDERSCORE) && lastCharacter === "_") {
  94. return false;
  95. }
  96. return firstCharacter === firstCharacter.toLowerCase() && middle.indexOf("_") === -1;
  97. };
  98. return VariableNameWalker;
  99. }(Lint.RuleWalker));
  100. function isUpperCase(name) {
  101. return name === name.toUpperCase();
  102. }