1 | "use strict";
|
2 | var __extends = (this && this.__extends) || (function () {
|
3 | var extendStatics = Object.setPrototypeOf ||
|
4 | ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
5 | function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
6 | return function (d, b) {
|
7 | extendStatics(d, b);
|
8 | function __() { this.constructor = d; }
|
9 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
10 | };
|
11 | })();
|
12 | Object.defineProperty(exports, "__esModule", { value: true });
|
13 | var ts = require("typescript");
|
14 | var Lint = require("tslint");
|
15 | var Rule = (function (_super) {
|
16 | __extends(Rule, _super);
|
17 | function Rule() {
|
18 | return _super !== null && _super.apply(this, arguments) || this;
|
19 | }
|
20 | Rule.prototype.apply = function (sourceFile) {
|
21 | return this.applyWithWalker(new TsxCurlySpacingWalker(sourceFile, this.getOptions()));
|
22 | };
|
23 | Rule.metadata = {
|
24 | ruleName: 'react-tsx-curly-spacing',
|
25 | type: 'style',
|
26 | description: 'Consistently use spaces around the brace characters of JSX attributes.',
|
27 | options: null,
|
28 | optionsDescription: '',
|
29 | typescriptOnly: true,
|
30 | issueClass: 'Non-SDL',
|
31 | issueType: 'Warning',
|
32 | severity: 'Low',
|
33 | level: 'Opportunity for Excellence',
|
34 | group: 'Deprecated'
|
35 | };
|
36 | return Rule;
|
37 | }(Lint.Rules.AbstractRule));
|
38 | exports.Rule = Rule;
|
39 | var Spacing;
|
40 | (function (Spacing) {
|
41 | Spacing[Spacing["always"] = 0] = "always";
|
42 | Spacing[Spacing["never"] = 1] = "never";
|
43 | })(Spacing || (Spacing = {}));
|
44 | var TsxCurlySpacingWalker = (function (_super) {
|
45 | __extends(TsxCurlySpacingWalker, _super);
|
46 | function TsxCurlySpacingWalker(sourceFile, options) {
|
47 | var _this = _super.call(this, sourceFile, options) || this;
|
48 | _this.spacing = options.ruleArguments[0] === 'never' ? Spacing.never : Spacing.always;
|
49 | _this.allowMultiline = false;
|
50 | if (options.ruleArguments[1] != null) {
|
51 | _this.allowMultiline = !(options.ruleArguments[1].allowMultiline === false);
|
52 | }
|
53 | return _this;
|
54 | }
|
55 | TsxCurlySpacingWalker.prototype.visitJsxExpression = function (node) {
|
56 | var childrenCount = node.getChildCount();
|
57 | var first = node.getFirstToken();
|
58 | var last = node.getLastToken();
|
59 | var second = node.getChildAt(1);
|
60 | var penultimate = node.getChildAt(childrenCount - 2);
|
61 | this.validateBraceSpacing(node, first, second, first);
|
62 | this.validateBraceSpacing(node, penultimate, last, last);
|
63 | };
|
64 | TsxCurlySpacingWalker.prototype.visitNode = function (node) {
|
65 | if (node.kind === ts.SyntaxKind.JsxExpression) {
|
66 | this.visitJsxExpression(node);
|
67 | this.walkChildren(node);
|
68 | }
|
69 | else {
|
70 | _super.prototype.visitNode.call(this, node);
|
71 | }
|
72 | };
|
73 | TsxCurlySpacingWalker.prototype.validateBraceSpacing = function (node, first, second, violationRoot) {
|
74 | if (this.isMultiline(first, second)) {
|
75 | if (!this.allowMultiline) {
|
76 | this.reportFailure(node, violationRoot, this.getFailureForNewLine(first, violationRoot));
|
77 | }
|
78 | }
|
79 | else if (this.spacing === Spacing.always) {
|
80 | if (!this.isSpaceBetweenTokens(first, second)) {
|
81 | this.reportFailure(node, violationRoot, this.getFailureForSpace(first, violationRoot));
|
82 | }
|
83 | }
|
84 | else {
|
85 | if (this.isSpaceBetweenTokens(first, second)) {
|
86 | this.reportFailure(node, violationRoot, this.getFailureForSpace(first, violationRoot));
|
87 | }
|
88 | }
|
89 | };
|
90 | TsxCurlySpacingWalker.prototype.getFailureForSpace = function (first, violationRoot) {
|
91 | if (this.spacing === Spacing.always) {
|
92 | if (first === violationRoot) {
|
93 | return "A space is required after '" + violationRoot.getText() + "'";
|
94 | }
|
95 | else {
|
96 | return "A space is required before '" + violationRoot.getText() + "'";
|
97 | }
|
98 | }
|
99 | else {
|
100 | if (first === violationRoot) {
|
101 | return "There should be no space after '" + violationRoot.getText() + "'";
|
102 | }
|
103 | else {
|
104 | return "There should be no space before '" + violationRoot.getText() + "'";
|
105 | }
|
106 | }
|
107 | };
|
108 | TsxCurlySpacingWalker.prototype.getFailureForNewLine = function (first, violationRoot) {
|
109 | if (first === violationRoot) {
|
110 | return "There should be no newline after '" + violationRoot.getText() + "'";
|
111 | }
|
112 | else {
|
113 | return "There should be no newline before '" + violationRoot.getText() + "'";
|
114 | }
|
115 | };
|
116 | TsxCurlySpacingWalker.prototype.reportFailure = function (start, endNode, failure) {
|
117 | this.addFailureAt(start.getStart(), endNode.getStart() - start.getStart(), failure);
|
118 | };
|
119 | TsxCurlySpacingWalker.prototype.isSpaceBetweenTokens = function (left, right) {
|
120 | var text = this.getSourceFile().getText().slice(left.getEnd(), right.getStart());
|
121 | return /\s/.test(text.replace(/\/\*.*?\*\//g, ''));
|
122 | };
|
123 | TsxCurlySpacingWalker.prototype.isMultiline = function (left, right) {
|
124 | var sourceFile = this.getSourceFile();
|
125 | var leftLine = sourceFile.getLineAndCharacterOfPosition(left.getStart()).line;
|
126 | var rightLine = sourceFile.getLineAndCharacterOfPosition(right.getStart()).line;
|
127 | return leftLine !== rightLine;
|
128 | };
|
129 | return TsxCurlySpacingWalker;
|
130 | }(Lint.RuleWalker));
|
131 |
|
\ | No newline at end of file |