Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80758 views
1
// Generated by CoffeeScript 1.9.1
2
var $, BOM, CJSX_ESC_COMMENT, CLOSING_TAG, COMMENT, HEREDOC, HEREGEX, JSTOKEN, OPENING_TAG, PRAGMA, ParseTreeBranchNode, ParseTreeLeafNode, Parser, REGEX, SIMPLESTR, TAG_ATTRIBUTES, TRAILING_SPACES, WHITESPACE, compact, count, invertLiterate, last, ref, repeat, starts, throwSyntaxError;
3
4
ref = require('./helpers'), count = ref.count, starts = ref.starts, compact = ref.compact, last = ref.last, repeat = ref.repeat, throwSyntaxError = ref.throwSyntaxError, invertLiterate = ref.invertLiterate;
5
6
$ = require('./symbols');
7
8
ParseTreeLeafNode = function(type, value) {
9
if (value == null) {
10
value = null;
11
}
12
return {
13
type: type,
14
value: value
15
};
16
};
17
18
ParseTreeBranchNode = function(type, value, children) {
19
if (value == null) {
20
value = null;
21
}
22
if (children == null) {
23
children = [];
24
}
25
return {
26
type: type,
27
value: value,
28
children: children
29
};
30
};
31
32
module.exports = Parser = (function() {
33
function Parser() {}
34
35
Parser.prototype.parse = function(code, opts) {
36
var consumed, i, message, ref1, ref2;
37
this.opts = opts != null ? opts : {};
38
this.parseTree = ParseTreeBranchNode(this.opts.root || $.ROOT);
39
this.activeStates = [this.parseTree];
40
this.chunkLine = 0;
41
this.chunkColumn = 0;
42
this.cjsxPragmaChecked = false;
43
code = this.clean(code);
44
i = 0;
45
while ((this.chunk = code.slice(i))) {
46
if (this.activeStates.length === 0) {
47
break;
48
}
49
consumed = ((ref1 = this.currentState()) !== $.CJSX_EL && ref1 !== $.CJSX_ATTRIBUTES ? this.csComment() || this.csHeredoc() || this.csString() || this.csRegex() || this.jsEscaped() : void 0) || this.cjsxStart() || this.cjsxAttribute() || this.cjsxComment() || this.cjsxEscape() || this.cjsxUnescape() || this.cjsxEnd() || this.cjsxText() || this.coffeescriptCode();
50
ref2 = this.getLineAndColumnFromChunk(consumed), this.chunkLine = ref2[0], this.chunkColumn = ref2[1];
51
i += consumed;
52
}
53
if ((this.activeBranchNode() != null) && this.activeBranchNode() !== this.parseTree) {
54
message = "Unexpected end of input: unclosed " + (this.currentState());
55
throwSyntaxError(message, {
56
first_line: this.chunkLine,
57
first_column: this.chunkColumn
58
});
59
}
60
this.remainder = code.slice(i);
61
if (!this.opts.recursive) {
62
if (this.remainder.length) {
63
throwSyntaxError("Unexpected return from root state", {
64
first_line: this.chunkLine,
65
first_column: this.chunkColumn
66
});
67
}
68
}
69
return this.parseTree;
70
};
71
72
Parser.prototype.csComment = function() {
73
var comment, here, match, pragmaMatch, prefix;
74
if (!(match = this.chunk.match(COMMENT))) {
75
return 0;
76
}
77
comment = match[0], here = match[1];
78
if (!this.cjsxPragmaChecked) {
79
this.cjsxPragmaChecked = true;
80
if (pragmaMatch = comment.match(PRAGMA)) {
81
if (pragmaMatch && pragmaMatch[1] && pragmaMatch[1].length) {
82
prefix = pragmaMatch[1];
83
} else {
84
prefix = 'React.DOM';
85
}
86
this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.CJSX_PRAGMA, prefix));
87
return comment.length;
88
}
89
}
90
this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.CS_COMMENT, comment));
91
return comment.length;
92
};
93
94
Parser.prototype.csHeredoc = function() {
95
var heredoc, match;
96
if (!(match = HEREDOC.exec(this.chunk))) {
97
return 0;
98
}
99
heredoc = match[0];
100
this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.CS_HEREDOC, heredoc));
101
return heredoc.length;
102
};
103
104
Parser.prototype.csString = function() {
105
var quote, string;
106
switch (quote = this.chunk.charAt(0)) {
107
case "'":
108
string = SIMPLESTR.exec(this.chunk)[0];
109
break;
110
case '"':
111
string = this.balancedString(this.chunk, '"');
112
}
113
if (!string) {
114
return 0;
115
}
116
this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.CS_STRING, string));
117
return string.length;
118
};
119
120
Parser.prototype.csRegex = function() {
121
var flags, length, match, ref1, regex;
122
if (this.chunk.charAt(0) !== '/') {
123
return 0;
124
}
125
if (length = this.csHeregex()) {
126
return length;
127
}
128
if (!(match = REGEX.exec(this.chunk))) {
129
return 0;
130
}
131
ref1 = match, match = ref1[0], regex = ref1[1], flags = ref1[2];
132
if (regex.indexOf("\n") > -1) {
133
return 0;
134
}
135
if (regex === '//') {
136
return 0;
137
}
138
this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.CS_REGEX, match));
139
return match.length;
140
};
141
142
Parser.prototype.csHeregex = function() {
143
var body, flags, heregex, match;
144
if (!(match = HEREGEX.exec(this.chunk))) {
145
return 0;
146
}
147
heregex = match[0], body = match[1], flags = match[2];
148
this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.CS_HEREGEX, heregex));
149
return heregex.length;
150
};
151
152
Parser.prototype.jsEscaped = function() {
153
var match, script;
154
if (!(this.chunk.charAt(0) === '`' && (match = JSTOKEN.exec(this.chunk)))) {
155
return 0;
156
}
157
script = match[0];
158
this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.JS_ESC, script));
159
return script.length;
160
};
161
162
Parser.prototype.cjsxStart = function() {
163
var attributesText, input, match, selfClosing, tagName;
164
if (!(match = OPENING_TAG.exec(this.chunk))) {
165
return 0;
166
}
167
input = match[0], tagName = match[1], attributesText = match[2], selfClosing = match[3];
168
if (!(selfClosing || this.chunk.indexOf("</" + tagName + ">", input.length) > -1)) {
169
return 0;
170
}
171
this.pushActiveBranchNode(ParseTreeBranchNode($.CJSX_EL, tagName));
172
this.pushActiveBranchNode(ParseTreeBranchNode($.CJSX_ATTRIBUTES));
173
return 1 + tagName.length;
174
};
175
176
Parser.prototype.cjsxAttribute = function() {
177
var attrName, bareVal, cjsxEscVal, doubleQuotedVal, input, match, singleQuotedVal, spreadAttr, whitespace;
178
if (this.currentState() !== $.CJSX_ATTRIBUTES) {
179
return 0;
180
}
181
if (this.chunk.charAt(0) === '/') {
182
if (this.chunk.charAt(1) === '>') {
183
this.popActiveBranchNode();
184
this.popActiveBranchNode();
185
return 2;
186
} else {
187
throwSyntaxError("/ without immediately following > in CJSX tag " + (this.peekActiveState(2).value), {
188
first_line: this.chunkLine,
189
first_column: this.chunkColumn
190
});
191
}
192
}
193
if (this.chunk.charAt(0) === '>') {
194
this.popActiveBranchNode();
195
return 1;
196
}
197
if (!(match = TAG_ATTRIBUTES.exec(this.chunk))) {
198
return 0;
199
}
200
input = match[0], attrName = match[1], doubleQuotedVal = match[2], singleQuotedVal = match[3], cjsxEscVal = match[4], bareVal = match[5], spreadAttr = match[6], whitespace = match[7];
201
if (attrName) {
202
if (doubleQuotedVal != null) {
203
this.addLeafNodeToActiveBranch(ParseTreeBranchNode($.CJSX_ATTR_PAIR, null, [ParseTreeLeafNode($.CJSX_ATTR_KEY, "\"" + attrName + "\""), ParseTreeLeafNode($.CJSX_ATTR_VAL, "\"" + doubleQuotedVal + "\"")]));
204
return input.length;
205
} else if (singleQuotedVal != null) {
206
this.addLeafNodeToActiveBranch(ParseTreeBranchNode($.CJSX_ATTR_PAIR, null, [ParseTreeLeafNode($.CJSX_ATTR_KEY, "\"" + attrName + "\""), ParseTreeLeafNode($.CJSX_ATTR_VAL, "'" + singleQuotedVal + "'")]));
207
return input.length;
208
} else if (cjsxEscVal) {
209
this.pushActiveBranchNode(ParseTreeBranchNode($.CJSX_ATTR_PAIR));
210
this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.CJSX_ATTR_KEY, "\"" + attrName + "\""));
211
return input.indexOf('{');
212
} else if (bareVal) {
213
this.addLeafNodeToActiveBranch(ParseTreeBranchNode($.CJSX_ATTR_PAIR, null, [ParseTreeLeafNode($.CJSX_ATTR_KEY, "\"" + attrName + "\""), ParseTreeLeafNode($.CJSX_ATTR_VAL, bareVal)]));
214
return input.length;
215
} else {
216
this.addLeafNodeToActiveBranch(ParseTreeBranchNode($.CJSX_ATTR_PAIR, null, [ParseTreeLeafNode($.CJSX_ATTR_KEY, "\"" + attrName + "\""), ParseTreeLeafNode($.CJSX_ATTR_VAL, 'true')]));
217
return input.length;
218
}
219
} else if (spreadAttr) {
220
this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.CJSX_ATTR_SPREAD, spreadAttr));
221
return input.length;
222
} else if (whitespace != null) {
223
this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.CJSX_WHITESPACE, whitespace));
224
return input.length;
225
} else {
226
return throwSyntaxError("Invalid attribute " + input + " in CJSX tag " + (this.peekActiveState(2).value), {
227
first_line: this.chunkLine,
228
first_column: this.chunkColumn
229
});
230
}
231
};
232
233
Parser.prototype.cjsxComment = function() {
234
var match;
235
match = this.chunk.match(CJSX_ESC_COMMENT);
236
if (!match) {
237
return 0;
238
}
239
this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.CJSX_COMMENT, match[1]));
240
return match[0].length;
241
};
242
243
Parser.prototype.cjsxEscape = function() {
244
var ref1;
245
if (!(this.chunk.charAt(0) === '{' && ((ref1 = this.currentState()) === $.CJSX_EL || ref1 === $.CJSX_ATTR_PAIR))) {
246
return 0;
247
}
248
this.pushActiveBranchNode(ParseTreeBranchNode($.CJSX_ESC));
249
this.activeBranchNode().stack = 1;
250
return 1;
251
};
252
253
Parser.prototype.cjsxUnescape = function() {
254
var ref1;
255
if (!(this.currentState() === $.CJSX_ESC && this.chunk.charAt(0) === '}')) {
256
return 0;
257
}
258
if (this.activeBranchNode().stack === 0) {
259
this.popActiveBranchNode();
260
if ((ref1 = this.currentState()) === $.CJSX_ATTR_PAIR) {
261
this.popActiveBranchNode();
262
}
263
return 1;
264
} else {
265
return 0;
266
}
267
};
268
269
Parser.prototype.cjsxEnd = function() {
270
var input, match, tagName;
271
if (this.currentState() !== $.CJSX_EL) {
272
return 0;
273
}
274
if (!(match = CLOSING_TAG.exec(this.chunk))) {
275
return 0;
276
}
277
input = match[0], tagName = match[1];
278
if (tagName !== this.activeBranchNode().value) {
279
throwSyntaxError("opening CJSX tag " + (this.activeBranchNode().value) + " doesn't match closing CJSX tag " + tagName, {
280
first_line: this.chunkLine,
281
first_column: this.chunkColumn
282
});
283
}
284
this.popActiveBranchNode();
285
return input.length;
286
};
287
288
Parser.prototype.cjsxText = function() {
289
if (this.currentState() !== $.CJSX_EL) {
290
return 0;
291
}
292
if (this.newestNode().type !== $.CJSX_TEXT) {
293
this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.CJSX_TEXT, ''));
294
}
295
this.newestNode().value += this.chunk.charAt(0);
296
return 1;
297
};
298
299
Parser.prototype.coffeescriptCode = function() {
300
if (this.currentState() === $.CJSX_ESC) {
301
if (this.chunk.charAt(0) === '{') {
302
this.activeBranchNode().stack++;
303
} else if (this.chunk.charAt(0) === '}') {
304
this.activeBranchNode().stack--;
305
if (this.activeBranchNode().stack === 0) {
306
return 0;
307
}
308
}
309
}
310
if (this.newestNode().type !== $.CS) {
311
this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.CS, ''));
312
}
313
this.newestNode().value += this.chunk.charAt(0);
314
return 1;
315
};
316
317
Parser.prototype.activeBranchNode = function() {
318
return last(this.activeStates);
319
};
320
321
Parser.prototype.peekActiveState = function(depth) {
322
if (depth == null) {
323
depth = 1;
324
}
325
return this.activeStates.slice(-depth)[0];
326
};
327
328
Parser.prototype.currentState = function() {
329
return this.activeBranchNode().type;
330
};
331
332
Parser.prototype.newestNode = function() {
333
return last(this.activeBranchNode().children) || this.activeBranchNode();
334
};
335
336
Parser.prototype.pushActiveBranchNode = function(node) {
337
this.activeBranchNode().children.push(node);
338
return this.activeStates.push(node);
339
};
340
341
Parser.prototype.popActiveBranchNode = function() {
342
return this.activeStates.pop();
343
};
344
345
Parser.prototype.addLeafNodeToActiveBranch = function(node) {
346
return this.activeBranchNode().children.push(node);
347
};
348
349
Parser.prototype.clean = function(code) {
350
var ref1;
351
if (code.charCodeAt(0) === BOM) {
352
code = code.slice(1);
353
}
354
code = code.replace(/\r/g, '');
355
if ((ref1 = this.opts) != null ? ref1.literate : void 0) {
356
code = invertLiterate(code);
357
}
358
return code;
359
};
360
361
Parser.prototype.getLineAndColumnFromChunk = function(offset) {
362
var column, lineCount, lines, string;
363
if (offset === 0) {
364
return [this.chunkLine, this.chunkColumn];
365
}
366
if (offset >= this.chunk.length) {
367
string = this.chunk;
368
} else {
369
string = this.chunk.slice(0, +(offset - 1) + 1 || 9e9);
370
}
371
lineCount = count(string, '\n');
372
column = this.chunkColumn;
373
if (lineCount > 0) {
374
lines = string.split('\n');
375
column = last(lines).length;
376
} else {
377
column += string.length;
378
}
379
return [this.chunkLine + lineCount, column];
380
};
381
382
Parser.prototype.balancedString = function(str, end) {
383
var continueCount, i, j, letter, match, prev, ref1, stack;
384
continueCount = 0;
385
stack = [end];
386
for (i = j = 1, ref1 = str.length; 1 <= ref1 ? j < ref1 : j > ref1; i = 1 <= ref1 ? ++j : --j) {
387
if (continueCount) {
388
--continueCount;
389
continue;
390
}
391
switch (letter = str.charAt(i)) {
392
case '\\':
393
++continueCount;
394
continue;
395
case end:
396
stack.pop();
397
if (!stack.length) {
398
return str.slice(0, +i + 1 || 9e9);
399
}
400
end = stack[stack.length - 1];
401
continue;
402
}
403
if (end === '}' && (letter === '"' || letter === "'")) {
404
stack.push(end = letter);
405
} else if (end === '}' && letter === '/' && (match = HEREGEX.exec(str.slice(i)) || REGEX.exec(str.slice(i)))) {
406
continueCount += match[0].length - 1;
407
} else if (end === '}' && letter === '{') {
408
stack.push(end = '}');
409
} else if (end === '"' && prev === '#' && letter === '{') {
410
stack.push(end = '}');
411
}
412
prev = letter;
413
}
414
return throwSyntaxError("missing " + (stack.pop()) + ", starting");
415
};
416
417
return Parser;
418
419
})();
420
421
OPENING_TAG = /^<(@?[-A-Za-z0-9_\.]+)((?:(?:(?:\s+[\w-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|(?:{[\s\S]*?})|[^>\s]+)))|\s+[\w-]+|\s+\{\.\.\.\s*?[^\s{}]+?\s*?\})?)*?\s*)(\/?)>/;
422
423
CLOSING_TAG = /^<\/(@?[-A-Za-z0-9_\.]+)[^>]*>/;
424
425
TAG_ATTRIBUTES = /(?:([-A-Za-z0-9_]+)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|(?:{((?:\\.|[\s\S])*)})|([^>\s]+)))?)|(?:\{\.\.\.(\s*?[^\s{}]+?\s*?)\})|([\s\n]+)/;
426
427
PRAGMA = /^\s*#\s*@cjsx\s+(\S*)/i;
428
429
CJSX_ESC_COMMENT = /^\{#(.*)\}/;
430
431
BOM = 65279;
432
433
WHITESPACE = /^[^\n\S]+/;
434
435
COMMENT = /^###([^#][\s\S]*?)(?:###[^\n\S]*|###$)|^(?:\s*#(?!##[^#]).*)+/;
436
437
TRAILING_SPACES = /\s+$/;
438
439
HEREDOC = /^("""|''')((?:\\[\s\S]|[^\\])*?)(?:\n[^\n\S]*)?\1/;
440
441
SIMPLESTR = /^'[^\\']*(?:\\[\s\S][^\\']*)*'/;
442
443
JSTOKEN = /^`[^\\`]*(?:\\.[^\\`]*)*`/;
444
445
REGEX = /^(\/(?![\s=])[^[\/\n\\]*(?:(?:\\[\s\S]|\[[^\]\n\\]*(?:\\[\s\S][^\]\n\\]*)*])[^[\/\n\\]*)*\/)([imgy]{0,4})(?!\w)/;
446
447
HEREGEX = /^\/{3}((?:\\?[\s\S])+?)\/{3}([imgy]{0,4})(?!\w)/;
448
449