aboutsummaryrefslogtreecommitdiff
path: root/node_modules/tslint/lib/rules/noConsecutiveBlankLinesRule.js
blob: 544e5b309056f55a88926ca517f8e1761f5389e2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
"use strict";
/**
 * @license
 * Copyright 2013 Palantir Technologies, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var utils = require("tsutils");
var ts = require("typescript");
var Lint = require("../index");
var Rule = (function (_super) {
    tslib_1.__extends(Rule, _super);
    function Rule() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    /* tslint:enable:object-literal-sort-keys */
    Rule.FAILURE_STRING_FACTORY = function (allowed) {
        return allowed === 1
            ? "Consecutive blank lines are forbidden"
            : "Exceeds the " + allowed + " allowed consecutive blank lines";
    };
    /**
     * Disable the rule if the option is provided but non-numeric or less than the minimum.
     */
    Rule.prototype.isEnabled = function () {
        var option = this.ruleArguments[0];
        return _super.prototype.isEnabled.call(this) && (option === undefined || option > 0);
    };
    Rule.prototype.apply = function (sourceFile) {
        var limit = this.ruleArguments[0];
        return this.applyWithFunction(sourceFile, walk, limit !== undefined ? limit : Rule.DEFAULT_ALLOWED_BLANKS);
    };
    Rule.DEFAULT_ALLOWED_BLANKS = 1;
    /* tslint:disable:object-literal-sort-keys */
    Rule.metadata = {
        ruleName: "no-consecutive-blank-lines",
        description: "Disallows one or more blank lines in a row.",
        hasFix: true,
        rationale: "Helps maintain a readable style in your codebase.",
        optionsDescription: (_a = ["\n            An optional number of maximum allowed sequential blanks can be specified. If no value\n            is provided, a default of ", " will be used."], _a.raw = ["\n            An optional number of maximum allowed sequential blanks can be specified. If no value\n            is provided, a default of ", " will be used."], Lint.Utils.dedent(_a, Rule.DEFAULT_ALLOWED_BLANKS)),
        options: {
            type: "number",
            minimum: "1",
        },
        optionExamples: [true, [true, 2]],
        type: "style",
        typescriptOnly: false,
    };
    return Rule;
}(Lint.Rules.AbstractRule));
exports.Rule = Rule;
function walk(ctx) {
    var sourceText = ctx.sourceFile.text;
    var threshold = ctx.options + 1;
    var possibleFailures = [];
    var consecutiveBlankLines = 0;
    for (var _i = 0, _a = utils.getLineRanges(ctx.sourceFile); _i < _a.length; _i++) {
        var line = _a[_i];
        if (line.contentLength === 0 || sourceText.substr(line.pos, line.contentLength).search(/\S/) === -1) {
            ++consecutiveBlankLines;
            if (consecutiveBlankLines === threshold) {
                possibleFailures.push({
                    end: line.end,
                    pos: line.pos,
                });
            }
            else if (consecutiveBlankLines > threshold) {
                possibleFailures[possibleFailures.length - 1].end = line.end;
            }
        }
        else {
            consecutiveBlankLines = 0;
        }
    }
    if (possibleFailures.length === 0) {
        return;
    }
    var failureString = Rule.FAILURE_STRING_FACTORY(ctx.options);
    var templateRanges = getTemplateRanges(ctx.sourceFile);
    var _loop_1 = function (possibleFailure) {
        if (!templateRanges.some(function (template) { return template.pos < possibleFailure.pos && possibleFailure.pos < template.end; })) {
            ctx.addFailureAt(possibleFailure.pos, 1, failureString, [
                Lint.Replacement.deleteFromTo(
                // special handling for fixing blank lines at the end of the file
                // to fix this we need to cut off the line break of the last allowed blank line, too
                possibleFailure.end === sourceText.length ? getStartOfLineBreak(sourceText, possibleFailure.pos) : possibleFailure.pos, possibleFailure.end),
            ]);
        }
    };
    for (var _b = 0, possibleFailures_1 = possibleFailures; _b < possibleFailures_1.length; _b++) {
        var possibleFailure = possibleFailures_1[_b];
        _loop_1(possibleFailure);
    }
}
function getStartOfLineBreak(sourceText, pos) {
    return sourceText[pos - 2] === "\r" ? pos - 1 : pos - 1;
}
function getTemplateRanges(sourceFile) {
    var intervals = [];
    var cb = function (node) {
        if (node.kind >= ts.SyntaxKind.FirstTemplateToken &&
            node.kind <= ts.SyntaxKind.LastTemplateToken) {
            intervals.push({
                end: node.end,
                pos: node.getStart(sourceFile),
            });
        }
        else {
            return ts.forEachChild(node, cb);
        }
    };
    ts.forEachChild(sourceFile, cb);
    return intervals;
}
exports.getTemplateRanges = getTemplateRanges;
var _a;