4 * Copyright 2017 Palantir Technologies, Inc.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 Object.defineProperty(exports, "__esModule", { value: true });
19 var tslib_1 = require("tslib");
20 var tsutils_1 = require("tsutils");
21 var ts = require("typescript");
22 var Lint = require("../index");
23 var Rule = /** @class */ (function (_super) {
24 tslib_1.__extends(Rule, _super);
26 return _super !== null && _super.apply(this, arguments) || this;
28 Rule.FAILURE_NEEDS_SPACE = function (count) {
29 return "Needs " + count + " whitespace" + (count > 1 ? "s" : "") + " within parentheses";
31 Rule.FAILURE_NO_EXTRA_SPACE = function (count) {
32 return "No more than " + count + " whitespace" + (count > 1 ? "s" : "") + " within parentheses allowed";
34 Rule.prototype.apply = function (sourceFile) {
35 return this.applyWithWalker(new SpaceWithinParensWalker(sourceFile, this.ruleName, parseOptions(this.ruleArguments[0])));
37 /* tslint:disable:object-literal-sort-keys */
39 ruleName: "space-within-parens",
40 description: "Enforces spaces within parentheses or disallow them. Empty parentheses () are always allowed.",
42 optionsDescription: Lint.Utils.dedent(templateObject_1 || (templateObject_1 = tslib_1.__makeTemplateObject(["\n You may enforce the amount of whitespace within parentheses.\n "], ["\n You may enforce the amount of whitespace within parentheses.\n "]))),
43 options: { type: "number", min: 0 },
45 typescriptOnly: false,
47 /* tslint:enable:object-literal-sort-keys */
48 Rule.FAILURE_NO_SPACE = "Whitespace within parentheses is not allowed";
50 }(Lint.Rules.AbstractRule));
52 function parseOptions(whitespaceSize) {
54 if (typeof whitespaceSize === "number") {
55 if (whitespaceSize >= 0) {
56 size = whitespaceSize;
59 else if (typeof whitespaceSize === "string") {
60 var parsedSize = parseInt(whitespaceSize, 10);
61 if (!Number.isNaN(parsedSize) && parsedSize >= 0) {
69 var SpaceWithinParensWalker = /** @class */ (function (_super) {
70 tslib_1.__extends(SpaceWithinParensWalker, _super);
71 function SpaceWithinParensWalker() {
72 return _super !== null && _super.apply(this, arguments) || this;
74 SpaceWithinParensWalker.prototype.walk = function (sourceFile) {
76 tsutils_1.forEachToken(sourceFile, function (token) {
77 if (token.kind === ts.SyntaxKind.OpenParenToken) {
78 if (sourceFile.text.charAt(token.end) !== ")") {
79 _this.checkOpenParenToken(token);
82 else if (token.kind === ts.SyntaxKind.CloseParenToken) {
83 if (sourceFile.text.charAt(token.end - 2) !== "(") {
84 _this.checkCloseParenToken(token);
89 SpaceWithinParensWalker.prototype.checkOpenParenToken = function (tokenNode) {
90 var currentPos = tokenNode.end;
91 var currentChar = this.sourceFile.text.charCodeAt(currentPos);
92 var allowedSpaceCount = this.options.size;
93 while (ts.isWhiteSpaceSingleLine(currentChar)) {
95 currentChar = this.sourceFile.text.charCodeAt(currentPos);
97 if (!ts.isLineBreak(currentChar)) {
98 var whitespaceCount = currentPos - tokenNode.end;
99 if (whitespaceCount !== allowedSpaceCount) {
101 var pos = tokenNode.end;
102 if (whitespaceCount > allowedSpaceCount) {
103 pos += allowedSpaceCount;
104 length = whitespaceCount - allowedSpaceCount;
106 else if (whitespaceCount > 0 && whitespaceCount < allowedSpaceCount) {
107 pos += allowedSpaceCount - whitespaceCount;
109 this.addFailureAtWithFix(pos, length, whitespaceCount);
113 SpaceWithinParensWalker.prototype.checkCloseParenToken = function (tokenNode) {
114 var currentPos = tokenNode.end - 2;
115 var currentChar = this.sourceFile.text.charCodeAt(currentPos);
116 var allowedSpaceCount = this.options.size;
117 while (ts.isWhiteSpaceSingleLine(currentChar)) {
119 currentChar = this.sourceFile.text.charCodeAt(currentPos);
122 * Number 40 is open parenthese char code, we skip this cause
123 * it's already been caught by `checkOpenParenToken`
125 if (!ts.isLineBreak(currentChar) && currentChar !== 40) {
126 var whitespaceCount = tokenNode.end - currentPos - 2;
127 if (whitespaceCount !== allowedSpaceCount) {
129 var pos = currentPos + 1;
130 if (whitespaceCount > allowedSpaceCount) {
131 length = whitespaceCount - allowedSpaceCount;
133 this.addFailureAtWithFix(pos, length, whitespaceCount);
137 SpaceWithinParensWalker.prototype.addFailureAtWithFix = function (position, length, whitespaceCount) {
140 var allowedSpaceCount = this.options.size;
141 if (allowedSpaceCount === 0) {
142 lintMsg = Rule.FAILURE_NO_SPACE;
143 lintFix = Lint.Replacement.deleteText(position, length);
145 else if (allowedSpaceCount > whitespaceCount) {
146 lintMsg = Rule.FAILURE_NEEDS_SPACE(allowedSpaceCount - whitespaceCount);
147 var whitespace = " ".repeat(allowedSpaceCount - whitespaceCount);
148 lintFix = Lint.Replacement.appendText(position, whitespace);
151 lintMsg = Rule.FAILURE_NO_EXTRA_SPACE(allowedSpaceCount);
152 lintFix = Lint.Replacement.deleteText(position, whitespaceCount - allowedSpaceCount);
154 this.addFailureAt(position, length, lintMsg, lintFix);
156 return SpaceWithinParensWalker;
157 }(Lint.AbstractWalker));
158 var templateObject_1;