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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
"use strict";
/*
* Copyright 2016 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");
// Use classes here instead of interfaces because we want runtime type data
var Line = (function () {
function Line() {
}
return Line;
}());
exports.Line = Line;
var CodeLine = (function (_super) {
tslib_1.__extends(CodeLine, _super);
function CodeLine(contents) {
var _this = _super.call(this) || this;
_this.contents = contents;
return _this;
}
return CodeLine;
}(Line));
exports.CodeLine = CodeLine;
var MessageSubstitutionLine = (function (_super) {
tslib_1.__extends(MessageSubstitutionLine, _super);
function MessageSubstitutionLine(key, message) {
var _this = _super.call(this) || this;
_this.key = key;
_this.message = message;
return _this;
}
return MessageSubstitutionLine;
}(Line));
exports.MessageSubstitutionLine = MessageSubstitutionLine;
var ErrorLine = (function (_super) {
tslib_1.__extends(ErrorLine, _super);
function ErrorLine(startCol) {
var _this = _super.call(this) || this;
_this.startCol = startCol;
return _this;
}
return ErrorLine;
}(Line));
exports.ErrorLine = ErrorLine;
var MultilineErrorLine = (function (_super) {
tslib_1.__extends(MultilineErrorLine, _super);
function MultilineErrorLine(startCol) {
return _super.call(this, startCol) || this;
}
return MultilineErrorLine;
}(ErrorLine));
exports.MultilineErrorLine = MultilineErrorLine;
var EndErrorLine = (function (_super) {
tslib_1.__extends(EndErrorLine, _super);
function EndErrorLine(startCol, endCol, message) {
var _this = _super.call(this, startCol) || this;
_this.endCol = endCol;
_this.message = message;
return _this;
}
return EndErrorLine;
}(ErrorLine));
exports.EndErrorLine = EndErrorLine;
// example matches (between the quotes):
// " ~~~~~~~~"
var multilineErrorRegex = /^\s*(~+|~nil)$/;
// " ~~~~~~~~~ [some error message]"
var endErrorRegex = /^\s*(~+|~nil)\s*\[(.+)\]\s*$/;
// "[shortcut]: full messages goes here!! "
var messageSubstitutionRegex = /^\[([-\w]+?)]: \s*(.+?)\s*$/;
exports.ZERO_LENGTH_ERROR = "~nil";
/**
* Maps a line of text from a .lint file to an appropriate Line object
*/
function parseLine(text) {
var multilineErrorMatch = text.match(multilineErrorRegex);
if (multilineErrorMatch != null) {
var startErrorCol = text.indexOf("~");
return new MultilineErrorLine(startErrorCol);
}
var endErrorMatch = text.match(endErrorRegex);
if (endErrorMatch != null) {
var squiggles = endErrorMatch[1], message = endErrorMatch[2];
var startErrorCol = text.indexOf("~");
var zeroLengthError = (squiggles === exports.ZERO_LENGTH_ERROR);
var endErrorCol = zeroLengthError ? startErrorCol : text.lastIndexOf("~") + 1;
return new EndErrorLine(startErrorCol, endErrorCol, message);
}
var messageSubstitutionMatch = text.match(messageSubstitutionRegex);
if (messageSubstitutionMatch != null) {
var key = messageSubstitutionMatch[1], message = messageSubstitutionMatch[2];
return new MessageSubstitutionLine(key, message);
}
// line doesn't match any syntax for error markup, so it's a line of code to be linted
return new CodeLine(text);
}
exports.parseLine = parseLine;
/**
* Maps a Line object to a matching line of text that could be in a .lint file.
* This is almost the inverse of parseLine.
* If you ran `printLine(parseLine(someText), code)`, the whitespace in the result may be different than in someText
* @param line - A Line object to convert to text
* @param code - If line represents error markup, this is the line of code preceding the markup.
* Otherwise, this parameter is not required.
*/
function printLine(line, code) {
if (line instanceof ErrorLine) {
if (code == null) {
throw new Error("Must supply argument for code parameter when line is an ErrorLine");
}
var leadingSpaces = " ".repeat(line.startCol);
if (line instanceof MultilineErrorLine) {
// special case for when the line of code is simply a newline.
// use "~nil" to indicate the error continues on that line
if (code.length === 0 && line.startCol === 0) {
return exports.ZERO_LENGTH_ERROR;
}
var tildes = "~".repeat(code.length - leadingSpaces.length);
return "" + leadingSpaces + tildes;
}
else if (line instanceof EndErrorLine) {
var tildes = "~".repeat(line.endCol - line.startCol);
if (code.length < line.endCol) {
// Better than crashing in String.repeat
throw new Error("Bad error marker at " + JSON.stringify(line));
}
var endSpaces = " ".repeat(code.length - line.endCol);
if (tildes.length === 0) {
tildes = exports.ZERO_LENGTH_ERROR;
// because we add "~nil" we need four less spaces than normal at the end
// always make sure we have at least one space though
endSpaces = endSpaces.substring(0, Math.max(endSpaces.length - 4, 1));
}
return "" + leadingSpaces + tildes + endSpaces + " [" + line.message + "]";
}
}
else if (line instanceof MessageSubstitutionLine) {
return "[" + line.key + "]: " + line.message;
}
else if (line instanceof CodeLine) {
return line.contents;
}
return null;
}
exports.printLine = printLine;
|