importDestructuringSpacingRule.js 3.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. "use strict";
  2. var __extends = (this && this.__extends) || (function () {
  3. var extendStatics = function (d, b) {
  4. extendStatics = Object.setPrototypeOf ||
  5. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  6. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  7. return extendStatics(d, b);
  8. };
  9. return function (d, b) {
  10. extendStatics(d, b);
  11. function __() { this.constructor = d; }
  12. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  13. };
  14. })();
  15. Object.defineProperty(exports, "__esModule", { value: true });
  16. var lib_1 = require("tslint/lib");
  17. var rules_1 = require("tslint/lib/rules");
  18. var typescript_1 = require("typescript/lib/typescript");
  19. var Rule = (function (_super) {
  20. __extends(Rule, _super);
  21. function Rule() {
  22. return _super !== null && _super.apply(this, arguments) || this;
  23. }
  24. Rule.prototype.apply = function (sourceFile) {
  25. return this.applyWithFunction(sourceFile, walk);
  26. };
  27. Rule.metadata = {
  28. description: 'Ensures imports are consistent and tidy.',
  29. hasFix: true,
  30. options: null,
  31. optionsDescription: 'Not configurable.',
  32. rationale: "Imports are easier for the reader to look at when they're tidy.",
  33. ruleName: 'import-destructuring-spacing',
  34. type: 'style',
  35. typescriptOnly: true
  36. };
  37. Rule.FAILURE_STRING = "Import statement's curly braces must be spaced exactly by a space to the right and a space to the left";
  38. return Rule;
  39. }(rules_1.AbstractRule));
  40. exports.Rule = Rule;
  41. var BLANK_MULTILINE_PATTERN = /^\{\s*\}$|\n/;
  42. var LEADING_SPACES_PATTERN = /^\{(\s*)/;
  43. var TRAILING_SPACES_PATTERN = /(\s*)}$/;
  44. var isBlankOrMultilineImport = function (value) { return BLANK_MULTILINE_PATTERN.test(value); };
  45. var getReplacements = function (node, totalLeadingSpaces, totalTrailingSpaces) {
  46. var nodeStartPos = node.getStart();
  47. var nodeEndPos = node.getEnd();
  48. var replacements = [];
  49. var textToAppend = ' ';
  50. if (totalLeadingSpaces === 0) {
  51. replacements.push(lib_1.Replacement.appendText(nodeStartPos + 1, textToAppend));
  52. }
  53. else if (totalLeadingSpaces > 1) {
  54. replacements.push(lib_1.Replacement.deleteText(nodeStartPos + 1, totalLeadingSpaces - 1));
  55. }
  56. if (totalTrailingSpaces === 0) {
  57. replacements.push(lib_1.Replacement.appendText(nodeEndPos - 1, textToAppend));
  58. }
  59. else if (totalTrailingSpaces > 1) {
  60. replacements.push(lib_1.Replacement.deleteText(nodeEndPos - totalTrailingSpaces, totalTrailingSpaces - 1));
  61. }
  62. return replacements;
  63. };
  64. var validateNamedImports = function (context, node) {
  65. var nodeText = node.getText();
  66. if (isBlankOrMultilineImport(nodeText))
  67. return;
  68. var leadingSpacesMatches = nodeText.match(LEADING_SPACES_PATTERN);
  69. var trailingSpacesMatches = nodeText.match(TRAILING_SPACES_PATTERN);
  70. var totalLeadingSpaces = leadingSpacesMatches ? leadingSpacesMatches[1].length : 1;
  71. var totalTrailingSpaces = trailingSpacesMatches ? trailingSpacesMatches[1].length : 1;
  72. if (totalLeadingSpaces === 1 && totalTrailingSpaces === 1)
  73. return;
  74. var replacements = getReplacements(node, totalLeadingSpaces, totalTrailingSpaces);
  75. context.addFailureAtNode(node, Rule.FAILURE_STRING, replacements);
  76. };
  77. var walk = function (context) {
  78. var sourceFile = context.sourceFile;
  79. var callback = function (node) {
  80. if (typescript_1.isNamedImports(node))
  81. validateNamedImports(context, node);
  82. typescript_1.forEachChild(node, callback);
  83. };
  84. typescript_1.forEachChild(sourceFile, callback);
  85. };