Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80629 views
1
/**
2
* JSXTransformer v0.13.3
3
*/
4
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.JSXTransformer = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
5
/**
6
* Copyright 2013-2015, Facebook, Inc.
7
* All rights reserved.
8
*
9
* This source code is licensed under the BSD-style license found in the
10
* LICENSE file in the root directory of this source tree. An additional grant
11
* of patent rights can be found in the PATENTS file in the same directory.
12
*/
13
/* jshint browser: true */
14
/* jslint evil: true */
15
/*eslint-disable no-eval */
16
/*eslint-disable block-scoped-var */
17
18
'use strict';
19
20
var ReactTools = _dereq_('../main');
21
var inlineSourceMap = _dereq_('./inline-source-map');
22
23
var headEl;
24
var dummyAnchor;
25
var inlineScriptCount = 0;
26
27
// The source-map library relies on Object.defineProperty, but IE8 doesn't
28
// support it fully even with es5-sham. Indeed, es5-sham's defineProperty
29
// throws when Object.prototype.__defineGetter__ is missing, so we skip building
30
// the source map in that case.
31
var supportsAccessors = Object.prototype.hasOwnProperty('__defineGetter__');
32
33
/**
34
* Run provided code through jstransform.
35
*
36
* @param {string} source Original source code
37
* @param {object?} options Options to pass to jstransform
38
* @return {object} object as returned from jstransform
39
*/
40
function transformReact(source, options) {
41
options = options || {};
42
43
// Force the sourcemaps option manually. We don't want to use it if it will
44
// break (see above note about supportsAccessors). We'll only override the
45
// value here if sourceMap was specified and is truthy. This guarantees that
46
// we won't override any user intent (since this method is exposed publicly).
47
if (options.sourceMap) {
48
options.sourceMap = supportsAccessors;
49
}
50
51
// Otherwise just pass all options straight through to react-tools.
52
return ReactTools.transformWithDetails(source, options);
53
}
54
55
/**
56
* Eval provided source after transforming it.
57
*
58
* @param {string} source Original source code
59
* @param {object?} options Options to pass to jstransform
60
*/
61
function exec(source, options) {
62
return eval(transformReact(source, options).code);
63
}
64
65
/**
66
* This method returns a nicely formated line of code pointing to the exact
67
* location of the error `e`. The line is limited in size so big lines of code
68
* are also shown in a readable way.
69
*
70
* Example:
71
* ... x', overflow:'scroll'}} id={} onScroll={this.scroll} class=" ...
72
* ^
73
*
74
* @param {string} code The full string of code
75
* @param {Error} e The error being thrown
76
* @return {string} formatted message
77
* @internal
78
*/
79
function createSourceCodeErrorMessage(code, e) {
80
var sourceLines = code.split('\n');
81
// e.lineNumber is non-standard so we can't depend on its availability. If
82
// we're in a browser where it isn't supported, don't even bother trying to
83
// format anything. We may also hit a case where the line number is reported
84
// incorrectly and is outside the bounds of the actual code. Handle that too.
85
if (!e.lineNumber || e.lineNumber > sourceLines.length) {
86
return '';
87
}
88
var erroneousLine = sourceLines[e.lineNumber - 1];
89
90
// Removes any leading indenting spaces and gets the number of
91
// chars indenting the `erroneousLine`
92
var indentation = 0;
93
erroneousLine = erroneousLine.replace(/^\s+/, function(leadingSpaces) {
94
indentation = leadingSpaces.length;
95
return '';
96
});
97
98
// Defines the number of characters that are going to show
99
// before and after the erroneous code
100
var LIMIT = 30;
101
var errorColumn = e.column - indentation;
102
103
if (errorColumn > LIMIT) {
104
erroneousLine = '... ' + erroneousLine.slice(errorColumn - LIMIT);
105
errorColumn = 4 + LIMIT;
106
}
107
if (erroneousLine.length - errorColumn > LIMIT) {
108
erroneousLine = erroneousLine.slice(0, errorColumn + LIMIT) + ' ...';
109
}
110
var message = '\n\n' + erroneousLine + '\n';
111
message += new Array(errorColumn - 1).join(' ') + '^';
112
return message;
113
}
114
115
/**
116
* Actually transform the code.
117
*
118
* @param {string} code
119
* @param {string?} url
120
* @param {object?} options
121
* @return {string} The transformed code.
122
* @internal
123
*/
124
function transformCode(code, url, options) {
125
try {
126
var transformed = transformReact(code, options);
127
} catch(e) {
128
e.message += '\n at ';
129
if (url) {
130
if ('fileName' in e) {
131
// We set `fileName` if it's supported by this error object and
132
// a `url` was provided.
133
// The error will correctly point to `url` in Firefox.
134
e.fileName = url;
135
}
136
e.message += url + ':' + e.lineNumber + ':' + e.columnNumber;
137
} else {
138
e.message += location.href;
139
}
140
e.message += createSourceCodeErrorMessage(code, e);
141
throw e;
142
}
143
144
if (!transformed.sourceMap) {
145
return transformed.code;
146
}
147
148
var source;
149
if (url == null) {
150
source = 'Inline JSX script';
151
inlineScriptCount++;
152
if (inlineScriptCount > 1) {
153
source += ' (' + inlineScriptCount + ')';
154
}
155
} else if (dummyAnchor) {
156
// Firefox has problems when the sourcemap source is a proper URL with a
157
// protocol and hostname, so use the pathname. We could use just the
158
// filename, but hopefully using the full path will prevent potential
159
// issues where the same filename exists in multiple directories.
160
dummyAnchor.href = url;
161
source = dummyAnchor.pathname.substr(1);
162
}
163
164
return (
165
transformed.code +
166
'\n' +
167
inlineSourceMap(transformed.sourceMap, code, source)
168
);
169
}
170
171
172
/**
173
* Appends a script element at the end of the <head> with the content of code,
174
* after transforming it.
175
*
176
* @param {string} code The original source code
177
* @param {string?} url Where the code came from. null if inline
178
* @param {object?} options Options to pass to jstransform
179
* @internal
180
*/
181
function run(code, url, options) {
182
var scriptEl = document.createElement('script');
183
scriptEl.text = transformCode(code, url, options);
184
headEl.appendChild(scriptEl);
185
}
186
187
/**
188
* Load script from the provided url and pass the content to the callback.
189
*
190
* @param {string} url The location of the script src
191
* @param {function} callback Function to call with the content of url
192
* @internal
193
*/
194
function load(url, successCallback, errorCallback) {
195
var xhr;
196
xhr = window.ActiveXObject ? new window.ActiveXObject('Microsoft.XMLHTTP')
197
: new XMLHttpRequest();
198
199
// async, however scripts will be executed in the order they are in the
200
// DOM to mirror normal script loading.
201
xhr.open('GET', url, true);
202
if ('overrideMimeType' in xhr) {
203
xhr.overrideMimeType('text/plain');
204
}
205
xhr.onreadystatechange = function() {
206
if (xhr.readyState === 4) {
207
if (xhr.status === 0 || xhr.status === 200) {
208
successCallback(xhr.responseText);
209
} else {
210
errorCallback();
211
throw new Error('Could not load ' + url);
212
}
213
}
214
};
215
return xhr.send(null);
216
}
217
218
/**
219
* Loop over provided script tags and get the content, via innerHTML if an
220
* inline script, or by using XHR. Transforms are applied if needed. The scripts
221
* are executed in the order they are found on the page.
222
*
223
* @param {array} scripts The <script> elements to load and run.
224
* @internal
225
*/
226
function loadScripts(scripts) {
227
var result = [];
228
var count = scripts.length;
229
230
function check() {
231
var script, i;
232
233
for (i = 0; i < count; i++) {
234
script = result[i];
235
236
if (script.loaded && !script.executed) {
237
script.executed = true;
238
run(script.content, script.url, script.options);
239
} else if (!script.loaded && !script.error && !script.async) {
240
break;
241
}
242
}
243
}
244
245
scripts.forEach(function(script, i) {
246
var options = {
247
sourceMap: true
248
};
249
if (/;harmony=true(;|$)/.test(script.type)) {
250
options.harmony = true;
251
}
252
if (/;stripTypes=true(;|$)/.test(script.type)) {
253
options.stripTypes = true;
254
}
255
256
// script.async is always true for non-javascript script tags
257
var async = script.hasAttribute('async');
258
259
if (script.src) {
260
result[i] = {
261
async: async,
262
error: false,
263
executed: false,
264
content: null,
265
loaded: false,
266
url: script.src,
267
options: options
268
};
269
270
load(script.src, function(content) {
271
result[i].loaded = true;
272
result[i].content = content;
273
check();
274
}, function() {
275
result[i].error = true;
276
check();
277
});
278
} else {
279
result[i] = {
280
async: async,
281
error: false,
282
executed: false,
283
content: script.innerHTML,
284
loaded: true,
285
url: null,
286
options: options
287
};
288
}
289
});
290
291
check();
292
}
293
294
/**
295
* Find and run all script tags with type="text/jsx".
296
*
297
* @internal
298
*/
299
function runScripts() {
300
var scripts = document.getElementsByTagName('script');
301
302
// Array.prototype.slice cannot be used on NodeList on IE8
303
var jsxScripts = [];
304
for (var i = 0; i < scripts.length; i++) {
305
if (/^text\/jsx(;|$)/.test(scripts.item(i).type)) {
306
jsxScripts.push(scripts.item(i));
307
}
308
}
309
310
if (jsxScripts.length < 1) {
311
return;
312
}
313
314
console.warn(
315
'You are using the in-browser JSX transformer. Be sure to precompile ' +
316
'your JSX for production - ' +
317
'http://facebook.github.io/react/docs/tooling-integration.html#jsx'
318
);
319
320
loadScripts(jsxScripts);
321
}
322
323
// Listen for load event if we're in a browser and then kick off finding and
324
// running of scripts.
325
if (typeof window !== 'undefined' && window !== null) {
326
headEl = document.getElementsByTagName('head')[0];
327
dummyAnchor = document.createElement('a');
328
329
if (window.addEventListener) {
330
window.addEventListener('DOMContentLoaded', runScripts, false);
331
} else {
332
window.attachEvent('onload', runScripts);
333
}
334
}
335
336
module.exports = {
337
transform: transformReact,
338
exec: exec
339
};
340
341
},{"../main":2,"./inline-source-map":41}],2:[function(_dereq_,module,exports){
342
/**
343
* Copyright 2013-2015, Facebook, Inc.
344
* All rights reserved.
345
*
346
* This source code is licensed under the BSD-style license found in the
347
* LICENSE file in the root directory of this source tree. An additional grant
348
* of patent rights can be found in the PATENTS file in the same directory.
349
*/
350
351
'use strict';
352
/*eslint-disable no-undef*/
353
var visitors = _dereq_('./vendor/fbtransform/visitors');
354
var transform = _dereq_('jstransform').transform;
355
var typesSyntax = _dereq_('jstransform/visitors/type-syntax');
356
var inlineSourceMap = _dereq_('./vendor/inline-source-map');
357
358
module.exports = {
359
transform: function(input, options) {
360
options = processOptions(options);
361
var output = innerTransform(input, options);
362
var result = output.code;
363
if (options.sourceMap) {
364
var map = inlineSourceMap(
365
output.sourceMap,
366
input,
367
options.filename
368
);
369
result += '\n' + map;
370
}
371
return result;
372
},
373
transformWithDetails: function(input, options) {
374
options = processOptions(options);
375
var output = innerTransform(input, options);
376
var result = {};
377
result.code = output.code;
378
if (options.sourceMap) {
379
result.sourceMap = output.sourceMap.toJSON();
380
}
381
if (options.filename) {
382
result.sourceMap.sources = [options.filename];
383
}
384
return result;
385
}
386
};
387
388
/**
389
* Only copy the values that we need. We'll do some preprocessing to account for
390
* converting command line flags to options that jstransform can actually use.
391
*/
392
function processOptions(opts) {
393
opts = opts || {};
394
var options = {};
395
396
options.harmony = opts.harmony;
397
options.stripTypes = opts.stripTypes;
398
options.sourceMap = opts.sourceMap;
399
options.filename = opts.sourceFilename;
400
401
if (opts.es6module) {
402
options.sourceType = 'module';
403
}
404
if (opts.nonStrictEs6module) {
405
options.sourceType = 'nonStrictModule';
406
}
407
408
// Instead of doing any fancy validation, only look for 'es3'. If we have
409
// that, then use it. Otherwise use 'es5'.
410
options.es3 = opts.target === 'es3';
411
options.es5 = !options.es3;
412
413
return options;
414
}
415
416
function innerTransform(input, options) {
417
var visitorSets = ['react'];
418
if (options.harmony) {
419
visitorSets.push('harmony');
420
}
421
422
if (options.es3) {
423
visitorSets.push('es3');
424
}
425
426
if (options.stripTypes) {
427
// Stripping types needs to happen before the other transforms
428
// unfortunately, due to bad interactions. For example,
429
// es6-rest-param-visitors conflict with stripping rest param type
430
// annotation
431
input = transform(typesSyntax.visitorList, input, options).code;
432
}
433
434
var visitorList = visitors.getVisitorsBySet(visitorSets);
435
return transform(visitorList, input, options);
436
}
437
438
},{"./vendor/fbtransform/visitors":40,"./vendor/inline-source-map":41,"jstransform":22,"jstransform/visitors/type-syntax":36}],3:[function(_dereq_,module,exports){
439
/*!
440
* The buffer module from node.js, for the browser.
441
*
442
* @author Feross Aboukhadijeh <[email protected]> <http://feross.org>
443
* @license MIT
444
*/
445
446
var base64 = _dereq_('base64-js')
447
var ieee754 = _dereq_('ieee754')
448
var isArray = _dereq_('is-array')
449
450
exports.Buffer = Buffer
451
exports.SlowBuffer = SlowBuffer
452
exports.INSPECT_MAX_BYTES = 50
453
Buffer.poolSize = 8192 // not used by this implementation
454
455
var kMaxLength = 0x3fffffff
456
var rootParent = {}
457
458
/**
459
* If `Buffer.TYPED_ARRAY_SUPPORT`:
460
* === true Use Uint8Array implementation (fastest)
461
* === false Use Object implementation (most compatible, even IE6)
462
*
463
* Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
464
* Opera 11.6+, iOS 4.2+.
465
*
466
* Note:
467
*
468
* - Implementation must support adding new properties to `Uint8Array` instances.
469
* Firefox 4-29 lacked support, fixed in Firefox 30+.
470
* See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.
471
*
472
* - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.
473
*
474
* - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of
475
* incorrect length in some situations.
476
*
477
* We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they will
478
* get the Object implementation, which is slower but will work correctly.
479
*/
480
Buffer.TYPED_ARRAY_SUPPORT = (function () {
481
try {
482
var buf = new ArrayBuffer(0)
483
var arr = new Uint8Array(buf)
484
arr.foo = function () { return 42 }
485
return arr.foo() === 42 && // typed array instances can be augmented
486
typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`
487
new Uint8Array(1).subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`
488
} catch (e) {
489
return false
490
}
491
})()
492
493
/**
494
* Class: Buffer
495
* =============
496
*
497
* The Buffer constructor returns instances of `Uint8Array` that are augmented
498
* with function properties for all the node `Buffer` API functions. We use
499
* `Uint8Array` so that square bracket notation works as expected -- it returns
500
* a single octet.
501
*
502
* By augmenting the instances, we can avoid modifying the `Uint8Array`
503
* prototype.
504
*/
505
function Buffer (subject, encoding) {
506
var self = this
507
if (!(self instanceof Buffer)) return new Buffer(subject, encoding)
508
509
var type = typeof subject
510
var length
511
512
if (type === 'number') {
513
length = +subject
514
} else if (type === 'string') {
515
length = Buffer.byteLength(subject, encoding)
516
} else if (type === 'object' && subject !== null) {
517
// assume object is array-like
518
if (subject.type === 'Buffer' && isArray(subject.data)) subject = subject.data
519
length = +subject.length
520
} else {
521
throw new TypeError('must start with number, buffer, array or string')
522
}
523
524
if (length > kMaxLength) {
525
throw new RangeError('Attempt to allocate Buffer larger than maximum size: 0x' +
526
kMaxLength.toString(16) + ' bytes')
527
}
528
529
if (length < 0) length = 0
530
else length >>>= 0 // coerce to uint32
531
532
if (Buffer.TYPED_ARRAY_SUPPORT) {
533
// Preferred: Return an augmented `Uint8Array` instance for best performance
534
self = Buffer._augment(new Uint8Array(length)) // eslint-disable-line consistent-this
535
} else {
536
// Fallback: Return THIS instance of Buffer (created by `new`)
537
self.length = length
538
self._isBuffer = true
539
}
540
541
var i
542
if (Buffer.TYPED_ARRAY_SUPPORT && typeof subject.byteLength === 'number') {
543
// Speed optimization -- use set if we're copying from a typed array
544
self._set(subject)
545
} else if (isArrayish(subject)) {
546
// Treat array-ish objects as a byte array
547
if (Buffer.isBuffer(subject)) {
548
for (i = 0; i < length; i++) {
549
self[i] = subject.readUInt8(i)
550
}
551
} else {
552
for (i = 0; i < length; i++) {
553
self[i] = ((subject[i] % 256) + 256) % 256
554
}
555
}
556
} else if (type === 'string') {
557
self.write(subject, 0, encoding)
558
} else if (type === 'number' && !Buffer.TYPED_ARRAY_SUPPORT) {
559
for (i = 0; i < length; i++) {
560
self[i] = 0
561
}
562
}
563
564
if (length > 0 && length <= Buffer.poolSize) self.parent = rootParent
565
566
return self
567
}
568
569
function SlowBuffer (subject, encoding) {
570
if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding)
571
572
var buf = new Buffer(subject, encoding)
573
delete buf.parent
574
return buf
575
}
576
577
Buffer.isBuffer = function isBuffer (b) {
578
return !!(b != null && b._isBuffer)
579
}
580
581
Buffer.compare = function compare (a, b) {
582
if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
583
throw new TypeError('Arguments must be Buffers')
584
}
585
586
if (a === b) return 0
587
588
var x = a.length
589
var y = b.length
590
for (var i = 0, len = Math.min(x, y); i < len && a[i] === b[i]; i++) {}
591
if (i !== len) {
592
x = a[i]
593
y = b[i]
594
}
595
if (x < y) return -1
596
if (y < x) return 1
597
return 0
598
}
599
600
Buffer.isEncoding = function isEncoding (encoding) {
601
switch (String(encoding).toLowerCase()) {
602
case 'hex':
603
case 'utf8':
604
case 'utf-8':
605
case 'ascii':
606
case 'binary':
607
case 'base64':
608
case 'raw':
609
case 'ucs2':
610
case 'ucs-2':
611
case 'utf16le':
612
case 'utf-16le':
613
return true
614
default:
615
return false
616
}
617
}
618
619
Buffer.concat = function concat (list, totalLength) {
620
if (!isArray(list)) throw new TypeError('list argument must be an Array of Buffers.')
621
622
if (list.length === 0) {
623
return new Buffer(0)
624
} else if (list.length === 1) {
625
return list[0]
626
}
627
628
var i
629
if (totalLength === undefined) {
630
totalLength = 0
631
for (i = 0; i < list.length; i++) {
632
totalLength += list[i].length
633
}
634
}
635
636
var buf = new Buffer(totalLength)
637
var pos = 0
638
for (i = 0; i < list.length; i++) {
639
var item = list[i]
640
item.copy(buf, pos)
641
pos += item.length
642
}
643
return buf
644
}
645
646
Buffer.byteLength = function byteLength (str, encoding) {
647
var ret
648
str = str + ''
649
switch (encoding || 'utf8') {
650
case 'ascii':
651
case 'binary':
652
case 'raw':
653
ret = str.length
654
break
655
case 'ucs2':
656
case 'ucs-2':
657
case 'utf16le':
658
case 'utf-16le':
659
ret = str.length * 2
660
break
661
case 'hex':
662
ret = str.length >>> 1
663
break
664
case 'utf8':
665
case 'utf-8':
666
ret = utf8ToBytes(str).length
667
break
668
case 'base64':
669
ret = base64ToBytes(str).length
670
break
671
default:
672
ret = str.length
673
}
674
return ret
675
}
676
677
// pre-set for values that may exist in the future
678
Buffer.prototype.length = undefined
679
Buffer.prototype.parent = undefined
680
681
// toString(encoding, start=0, end=buffer.length)
682
Buffer.prototype.toString = function toString (encoding, start, end) {
683
var loweredCase = false
684
685
start = start >>> 0
686
end = end === undefined || end === Infinity ? this.length : end >>> 0
687
688
if (!encoding) encoding = 'utf8'
689
if (start < 0) start = 0
690
if (end > this.length) end = this.length
691
if (end <= start) return ''
692
693
while (true) {
694
switch (encoding) {
695
case 'hex':
696
return hexSlice(this, start, end)
697
698
case 'utf8':
699
case 'utf-8':
700
return utf8Slice(this, start, end)
701
702
case 'ascii':
703
return asciiSlice(this, start, end)
704
705
case 'binary':
706
return binarySlice(this, start, end)
707
708
case 'base64':
709
return base64Slice(this, start, end)
710
711
case 'ucs2':
712
case 'ucs-2':
713
case 'utf16le':
714
case 'utf-16le':
715
return utf16leSlice(this, start, end)
716
717
default:
718
if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
719
encoding = (encoding + '').toLowerCase()
720
loweredCase = true
721
}
722
}
723
}
724
725
Buffer.prototype.equals = function equals (b) {
726
if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
727
if (this === b) return true
728
return Buffer.compare(this, b) === 0
729
}
730
731
Buffer.prototype.inspect = function inspect () {
732
var str = ''
733
var max = exports.INSPECT_MAX_BYTES
734
if (this.length > 0) {
735
str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')
736
if (this.length > max) str += ' ... '
737
}
738
return '<Buffer ' + str + '>'
739
}
740
741
Buffer.prototype.compare = function compare (b) {
742
if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
743
if (this === b) return 0
744
return Buffer.compare(this, b)
745
}
746
747
Buffer.prototype.indexOf = function indexOf (val, byteOffset) {
748
if (byteOffset > 0x7fffffff) byteOffset = 0x7fffffff
749
else if (byteOffset < -0x80000000) byteOffset = -0x80000000
750
byteOffset >>= 0
751
752
if (this.length === 0) return -1
753
if (byteOffset >= this.length) return -1
754
755
// Negative offsets start from the end of the buffer
756
if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0)
757
758
if (typeof val === 'string') {
759
if (val.length === 0) return -1 // special case: looking for empty string always fails
760
return String.prototype.indexOf.call(this, val, byteOffset)
761
}
762
if (Buffer.isBuffer(val)) {
763
return arrayIndexOf(this, val, byteOffset)
764
}
765
if (typeof val === 'number') {
766
if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') {
767
return Uint8Array.prototype.indexOf.call(this, val, byteOffset)
768
}
769
return arrayIndexOf(this, [ val ], byteOffset)
770
}
771
772
function arrayIndexOf (arr, val, byteOffset) {
773
var foundIndex = -1
774
for (var i = 0; byteOffset + i < arr.length; i++) {
775
if (arr[byteOffset + i] === val[foundIndex === -1 ? 0 : i - foundIndex]) {
776
if (foundIndex === -1) foundIndex = i
777
if (i - foundIndex + 1 === val.length) return byteOffset + foundIndex
778
} else {
779
foundIndex = -1
780
}
781
}
782
return -1
783
}
784
785
throw new TypeError('val must be string, number or Buffer')
786
}
787
788
// `get` will be removed in Node 0.13+
789
Buffer.prototype.get = function get (offset) {
790
console.log('.get() is deprecated. Access using array indexes instead.')
791
return this.readUInt8(offset)
792
}
793
794
// `set` will be removed in Node 0.13+
795
Buffer.prototype.set = function set (v, offset) {
796
console.log('.set() is deprecated. Access using array indexes instead.')
797
return this.writeUInt8(v, offset)
798
}
799
800
function hexWrite (buf, string, offset, length) {
801
offset = Number(offset) || 0
802
var remaining = buf.length - offset
803
if (!length) {
804
length = remaining
805
} else {
806
length = Number(length)
807
if (length > remaining) {
808
length = remaining
809
}
810
}
811
812
// must be an even number of digits
813
var strLen = string.length
814
if (strLen % 2 !== 0) throw new Error('Invalid hex string')
815
816
if (length > strLen / 2) {
817
length = strLen / 2
818
}
819
for (var i = 0; i < length; i++) {
820
var parsed = parseInt(string.substr(i * 2, 2), 16)
821
if (isNaN(parsed)) throw new Error('Invalid hex string')
822
buf[offset + i] = parsed
823
}
824
return i
825
}
826
827
function utf8Write (buf, string, offset, length) {
828
var charsWritten = blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
829
return charsWritten
830
}
831
832
function asciiWrite (buf, string, offset, length) {
833
var charsWritten = blitBuffer(asciiToBytes(string), buf, offset, length)
834
return charsWritten
835
}
836
837
function binaryWrite (buf, string, offset, length) {
838
return asciiWrite(buf, string, offset, length)
839
}
840
841
function base64Write (buf, string, offset, length) {
842
var charsWritten = blitBuffer(base64ToBytes(string), buf, offset, length)
843
return charsWritten
844
}
845
846
function utf16leWrite (buf, string, offset, length) {
847
var charsWritten = blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
848
return charsWritten
849
}
850
851
Buffer.prototype.write = function write (string, offset, length, encoding) {
852
// Support both (string, offset, length, encoding)
853
// and the legacy (string, encoding, offset, length)
854
if (isFinite(offset)) {
855
if (!isFinite(length)) {
856
encoding = length
857
length = undefined
858
}
859
} else { // legacy
860
var swap = encoding
861
encoding = offset
862
offset = length
863
length = swap
864
}
865
866
offset = Number(offset) || 0
867
868
if (length < 0 || offset < 0 || offset > this.length) {
869
throw new RangeError('attempt to write outside buffer bounds')
870
}
871
872
var remaining = this.length - offset
873
if (!length) {
874
length = remaining
875
} else {
876
length = Number(length)
877
if (length > remaining) {
878
length = remaining
879
}
880
}
881
encoding = String(encoding || 'utf8').toLowerCase()
882
883
var ret
884
switch (encoding) {
885
case 'hex':
886
ret = hexWrite(this, string, offset, length)
887
break
888
case 'utf8':
889
case 'utf-8':
890
ret = utf8Write(this, string, offset, length)
891
break
892
case 'ascii':
893
ret = asciiWrite(this, string, offset, length)
894
break
895
case 'binary':
896
ret = binaryWrite(this, string, offset, length)
897
break
898
case 'base64':
899
ret = base64Write(this, string, offset, length)
900
break
901
case 'ucs2':
902
case 'ucs-2':
903
case 'utf16le':
904
case 'utf-16le':
905
ret = utf16leWrite(this, string, offset, length)
906
break
907
default:
908
throw new TypeError('Unknown encoding: ' + encoding)
909
}
910
return ret
911
}
912
913
Buffer.prototype.toJSON = function toJSON () {
914
return {
915
type: 'Buffer',
916
data: Array.prototype.slice.call(this._arr || this, 0)
917
}
918
}
919
920
function base64Slice (buf, start, end) {
921
if (start === 0 && end === buf.length) {
922
return base64.fromByteArray(buf)
923
} else {
924
return base64.fromByteArray(buf.slice(start, end))
925
}
926
}
927
928
function utf8Slice (buf, start, end) {
929
var res = ''
930
var tmp = ''
931
end = Math.min(buf.length, end)
932
933
for (var i = start; i < end; i++) {
934
if (buf[i] <= 0x7F) {
935
res += decodeUtf8Char(tmp) + String.fromCharCode(buf[i])
936
tmp = ''
937
} else {
938
tmp += '%' + buf[i].toString(16)
939
}
940
}
941
942
return res + decodeUtf8Char(tmp)
943
}
944
945
function asciiSlice (buf, start, end) {
946
var ret = ''
947
end = Math.min(buf.length, end)
948
949
for (var i = start; i < end; i++) {
950
ret += String.fromCharCode(buf[i] & 0x7F)
951
}
952
return ret
953
}
954
955
function binarySlice (buf, start, end) {
956
var ret = ''
957
end = Math.min(buf.length, end)
958
959
for (var i = start; i < end; i++) {
960
ret += String.fromCharCode(buf[i])
961
}
962
return ret
963
}
964
965
function hexSlice (buf, start, end) {
966
var len = buf.length
967
968
if (!start || start < 0) start = 0
969
if (!end || end < 0 || end > len) end = len
970
971
var out = ''
972
for (var i = start; i < end; i++) {
973
out += toHex(buf[i])
974
}
975
return out
976
}
977
978
function utf16leSlice (buf, start, end) {
979
var bytes = buf.slice(start, end)
980
var res = ''
981
for (var i = 0; i < bytes.length; i += 2) {
982
res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)
983
}
984
return res
985
}
986
987
Buffer.prototype.slice = function slice (start, end) {
988
var len = this.length
989
start = ~~start
990
end = end === undefined ? len : ~~end
991
992
if (start < 0) {
993
start += len
994
if (start < 0) start = 0
995
} else if (start > len) {
996
start = len
997
}
998
999
if (end < 0) {
1000
end += len
1001
if (end < 0) end = 0
1002
} else if (end > len) {
1003
end = len
1004
}
1005
1006
if (end < start) end = start
1007
1008
var newBuf
1009
if (Buffer.TYPED_ARRAY_SUPPORT) {
1010
newBuf = Buffer._augment(this.subarray(start, end))
1011
} else {
1012
var sliceLen = end - start
1013
newBuf = new Buffer(sliceLen, undefined)
1014
for (var i = 0; i < sliceLen; i++) {
1015
newBuf[i] = this[i + start]
1016
}
1017
}
1018
1019
if (newBuf.length) newBuf.parent = this.parent || this
1020
1021
return newBuf
1022
}
1023
1024
/*
1025
* Need to make sure that buffer isn't trying to write out of bounds.
1026
*/
1027
function checkOffset (offset, ext, length) {
1028
if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
1029
if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
1030
}
1031
1032
Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
1033
offset = offset >>> 0
1034
byteLength = byteLength >>> 0
1035
if (!noAssert) checkOffset(offset, byteLength, this.length)
1036
1037
var val = this[offset]
1038
var mul = 1
1039
var i = 0
1040
while (++i < byteLength && (mul *= 0x100)) {
1041
val += this[offset + i] * mul
1042
}
1043
1044
return val
1045
}
1046
1047
Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
1048
offset = offset >>> 0
1049
byteLength = byteLength >>> 0
1050
if (!noAssert) {
1051
checkOffset(offset, byteLength, this.length)
1052
}
1053
1054
var val = this[offset + --byteLength]
1055
var mul = 1
1056
while (byteLength > 0 && (mul *= 0x100)) {
1057
val += this[offset + --byteLength] * mul
1058
}
1059
1060
return val
1061
}
1062
1063
Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
1064
if (!noAssert) checkOffset(offset, 1, this.length)
1065
return this[offset]
1066
}
1067
1068
Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
1069
if (!noAssert) checkOffset(offset, 2, this.length)
1070
return this[offset] | (this[offset + 1] << 8)
1071
}
1072
1073
Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
1074
if (!noAssert) checkOffset(offset, 2, this.length)
1075
return (this[offset] << 8) | this[offset + 1]
1076
}
1077
1078
Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
1079
if (!noAssert) checkOffset(offset, 4, this.length)
1080
1081
return ((this[offset]) |
1082
(this[offset + 1] << 8) |
1083
(this[offset + 2] << 16)) +
1084
(this[offset + 3] * 0x1000000)
1085
}
1086
1087
Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
1088
if (!noAssert) checkOffset(offset, 4, this.length)
1089
1090
return (this[offset] * 0x1000000) +
1091
((this[offset + 1] << 16) |
1092
(this[offset + 2] << 8) |
1093
this[offset + 3])
1094
}
1095
1096
Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
1097
offset = offset >>> 0
1098
byteLength = byteLength >>> 0
1099
if (!noAssert) checkOffset(offset, byteLength, this.length)
1100
1101
var val = this[offset]
1102
var mul = 1
1103
var i = 0
1104
while (++i < byteLength && (mul *= 0x100)) {
1105
val += this[offset + i] * mul
1106
}
1107
mul *= 0x80
1108
1109
if (val >= mul) val -= Math.pow(2, 8 * byteLength)
1110
1111
return val
1112
}
1113
1114
Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
1115
offset = offset >>> 0
1116
byteLength = byteLength >>> 0
1117
if (!noAssert) checkOffset(offset, byteLength, this.length)
1118
1119
var i = byteLength
1120
var mul = 1
1121
var val = this[offset + --i]
1122
while (i > 0 && (mul *= 0x100)) {
1123
val += this[offset + --i] * mul
1124
}
1125
mul *= 0x80
1126
1127
if (val >= mul) val -= Math.pow(2, 8 * byteLength)
1128
1129
return val
1130
}
1131
1132
Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
1133
if (!noAssert) checkOffset(offset, 1, this.length)
1134
if (!(this[offset] & 0x80)) return (this[offset])
1135
return ((0xff - this[offset] + 1) * -1)
1136
}
1137
1138
Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
1139
if (!noAssert) checkOffset(offset, 2, this.length)
1140
var val = this[offset] | (this[offset + 1] << 8)
1141
return (val & 0x8000) ? val | 0xFFFF0000 : val
1142
}
1143
1144
Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
1145
if (!noAssert) checkOffset(offset, 2, this.length)
1146
var val = this[offset + 1] | (this[offset] << 8)
1147
return (val & 0x8000) ? val | 0xFFFF0000 : val
1148
}
1149
1150
Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
1151
if (!noAssert) checkOffset(offset, 4, this.length)
1152
1153
return (this[offset]) |
1154
(this[offset + 1] << 8) |
1155
(this[offset + 2] << 16) |
1156
(this[offset + 3] << 24)
1157
}
1158
1159
Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
1160
if (!noAssert) checkOffset(offset, 4, this.length)
1161
1162
return (this[offset] << 24) |
1163
(this[offset + 1] << 16) |
1164
(this[offset + 2] << 8) |
1165
(this[offset + 3])
1166
}
1167
1168
Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
1169
if (!noAssert) checkOffset(offset, 4, this.length)
1170
return ieee754.read(this, offset, true, 23, 4)
1171
}
1172
1173
Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
1174
if (!noAssert) checkOffset(offset, 4, this.length)
1175
return ieee754.read(this, offset, false, 23, 4)
1176
}
1177
1178
Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
1179
if (!noAssert) checkOffset(offset, 8, this.length)
1180
return ieee754.read(this, offset, true, 52, 8)
1181
}
1182
1183
Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
1184
if (!noAssert) checkOffset(offset, 8, this.length)
1185
return ieee754.read(this, offset, false, 52, 8)
1186
}
1187
1188
function checkInt (buf, value, offset, ext, max, min) {
1189
if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance')
1190
if (value > max || value < min) throw new RangeError('value is out of bounds')
1191
if (offset + ext > buf.length) throw new RangeError('index out of range')
1192
}
1193
1194
Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
1195
value = +value
1196
offset = offset >>> 0
1197
byteLength = byteLength >>> 0
1198
if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)
1199
1200
var mul = 1
1201
var i = 0
1202
this[offset] = value & 0xFF
1203
while (++i < byteLength && (mul *= 0x100)) {
1204
this[offset + i] = (value / mul) >>> 0 & 0xFF
1205
}
1206
1207
return offset + byteLength
1208
}
1209
1210
Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
1211
value = +value
1212
offset = offset >>> 0
1213
byteLength = byteLength >>> 0
1214
if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)
1215
1216
var i = byteLength - 1
1217
var mul = 1
1218
this[offset + i] = value & 0xFF
1219
while (--i >= 0 && (mul *= 0x100)) {
1220
this[offset + i] = (value / mul) >>> 0 & 0xFF
1221
}
1222
1223
return offset + byteLength
1224
}
1225
1226
Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
1227
value = +value
1228
offset = offset >>> 0
1229
if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
1230
if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
1231
this[offset] = value
1232
return offset + 1
1233
}
1234
1235
function objectWriteUInt16 (buf, value, offset, littleEndian) {
1236
if (value < 0) value = 0xffff + value + 1
1237
for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) {
1238
buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>
1239
(littleEndian ? i : 1 - i) * 8
1240
}
1241
}
1242
1243
Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
1244
value = +value
1245
offset = offset >>> 0
1246
if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
1247
if (Buffer.TYPED_ARRAY_SUPPORT) {
1248
this[offset] = value
1249
this[offset + 1] = (value >>> 8)
1250
} else {
1251
objectWriteUInt16(this, value, offset, true)
1252
}
1253
return offset + 2
1254
}
1255
1256
Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
1257
value = +value
1258
offset = offset >>> 0
1259
if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
1260
if (Buffer.TYPED_ARRAY_SUPPORT) {
1261
this[offset] = (value >>> 8)
1262
this[offset + 1] = value
1263
} else {
1264
objectWriteUInt16(this, value, offset, false)
1265
}
1266
return offset + 2
1267
}
1268
1269
function objectWriteUInt32 (buf, value, offset, littleEndian) {
1270
if (value < 0) value = 0xffffffff + value + 1
1271
for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) {
1272
buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff
1273
}
1274
}
1275
1276
Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
1277
value = +value
1278
offset = offset >>> 0
1279
if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
1280
if (Buffer.TYPED_ARRAY_SUPPORT) {
1281
this[offset + 3] = (value >>> 24)
1282
this[offset + 2] = (value >>> 16)
1283
this[offset + 1] = (value >>> 8)
1284
this[offset] = value
1285
} else {
1286
objectWriteUInt32(this, value, offset, true)
1287
}
1288
return offset + 4
1289
}
1290
1291
Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
1292
value = +value
1293
offset = offset >>> 0
1294
if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
1295
if (Buffer.TYPED_ARRAY_SUPPORT) {
1296
this[offset] = (value >>> 24)
1297
this[offset + 1] = (value >>> 16)
1298
this[offset + 2] = (value >>> 8)
1299
this[offset + 3] = value
1300
} else {
1301
objectWriteUInt32(this, value, offset, false)
1302
}
1303
return offset + 4
1304
}
1305
1306
Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
1307
value = +value
1308
offset = offset >>> 0
1309
if (!noAssert) {
1310
checkInt(
1311
this, value, offset, byteLength,
1312
Math.pow(2, 8 * byteLength - 1) - 1,
1313
-Math.pow(2, 8 * byteLength - 1)
1314
)
1315
}
1316
1317
var i = 0
1318
var mul = 1
1319
var sub = value < 0 ? 1 : 0
1320
this[offset] = value & 0xFF
1321
while (++i < byteLength && (mul *= 0x100)) {
1322
this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
1323
}
1324
1325
return offset + byteLength
1326
}
1327
1328
Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
1329
value = +value
1330
offset = offset >>> 0
1331
if (!noAssert) {
1332
checkInt(
1333
this, value, offset, byteLength,
1334
Math.pow(2, 8 * byteLength - 1) - 1,
1335
-Math.pow(2, 8 * byteLength - 1)
1336
)
1337
}
1338
1339
var i = byteLength - 1
1340
var mul = 1
1341
var sub = value < 0 ? 1 : 0
1342
this[offset + i] = value & 0xFF
1343
while (--i >= 0 && (mul *= 0x100)) {
1344
this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
1345
}
1346
1347
return offset + byteLength
1348
}
1349
1350
Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
1351
value = +value
1352
offset = offset >>> 0
1353
if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
1354
if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
1355
if (value < 0) value = 0xff + value + 1
1356
this[offset] = value
1357
return offset + 1
1358
}
1359
1360
Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
1361
value = +value
1362
offset = offset >>> 0
1363
if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
1364
if (Buffer.TYPED_ARRAY_SUPPORT) {
1365
this[offset] = value
1366
this[offset + 1] = (value >>> 8)
1367
} else {
1368
objectWriteUInt16(this, value, offset, true)
1369
}
1370
return offset + 2
1371
}
1372
1373
Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
1374
value = +value
1375
offset = offset >>> 0
1376
if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
1377
if (Buffer.TYPED_ARRAY_SUPPORT) {
1378
this[offset] = (value >>> 8)
1379
this[offset + 1] = value
1380
} else {
1381
objectWriteUInt16(this, value, offset, false)
1382
}
1383
return offset + 2
1384
}
1385
1386
Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
1387
value = +value
1388
offset = offset >>> 0
1389
if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
1390
if (Buffer.TYPED_ARRAY_SUPPORT) {
1391
this[offset] = value
1392
this[offset + 1] = (value >>> 8)
1393
this[offset + 2] = (value >>> 16)
1394
this[offset + 3] = (value >>> 24)
1395
} else {
1396
objectWriteUInt32(this, value, offset, true)
1397
}
1398
return offset + 4
1399
}
1400
1401
Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
1402
value = +value
1403
offset = offset >>> 0
1404
if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
1405
if (value < 0) value = 0xffffffff + value + 1
1406
if (Buffer.TYPED_ARRAY_SUPPORT) {
1407
this[offset] = (value >>> 24)
1408
this[offset + 1] = (value >>> 16)
1409
this[offset + 2] = (value >>> 8)
1410
this[offset + 3] = value
1411
} else {
1412
objectWriteUInt32(this, value, offset, false)
1413
}
1414
return offset + 4
1415
}
1416
1417
function checkIEEE754 (buf, value, offset, ext, max, min) {
1418
if (value > max || value < min) throw new RangeError('value is out of bounds')
1419
if (offset + ext > buf.length) throw new RangeError('index out of range')
1420
if (offset < 0) throw new RangeError('index out of range')
1421
}
1422
1423
function writeFloat (buf, value, offset, littleEndian, noAssert) {
1424
if (!noAssert) {
1425
checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
1426
}
1427
ieee754.write(buf, value, offset, littleEndian, 23, 4)
1428
return offset + 4
1429
}
1430
1431
Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
1432
return writeFloat(this, value, offset, true, noAssert)
1433
}
1434
1435
Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
1436
return writeFloat(this, value, offset, false, noAssert)
1437
}
1438
1439
function writeDouble (buf, value, offset, littleEndian, noAssert) {
1440
if (!noAssert) {
1441
checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
1442
}
1443
ieee754.write(buf, value, offset, littleEndian, 52, 8)
1444
return offset + 8
1445
}
1446
1447
Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
1448
return writeDouble(this, value, offset, true, noAssert)
1449
}
1450
1451
Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
1452
return writeDouble(this, value, offset, false, noAssert)
1453
}
1454
1455
// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
1456
Buffer.prototype.copy = function copy (target, target_start, start, end) {
1457
if (!start) start = 0
1458
if (!end && end !== 0) end = this.length
1459
if (target_start >= target.length) target_start = target.length
1460
if (!target_start) target_start = 0
1461
if (end > 0 && end < start) end = start
1462
1463
// Copy 0 bytes; we're done
1464
if (end === start) return 0
1465
if (target.length === 0 || this.length === 0) return 0
1466
1467
// Fatal error conditions
1468
if (target_start < 0) {
1469
throw new RangeError('targetStart out of bounds')
1470
}
1471
if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')
1472
if (end < 0) throw new RangeError('sourceEnd out of bounds')
1473
1474
// Are we oob?
1475
if (end > this.length) end = this.length
1476
if (target.length - target_start < end - start) {
1477
end = target.length - target_start + start
1478
}
1479
1480
var len = end - start
1481
1482
if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {
1483
for (var i = 0; i < len; i++) {
1484
target[i + target_start] = this[i + start]
1485
}
1486
} else {
1487
target._set(this.subarray(start, start + len), target_start)
1488
}
1489
1490
return len
1491
}
1492
1493
// fill(value, start=0, end=buffer.length)
1494
Buffer.prototype.fill = function fill (value, start, end) {
1495
if (!value) value = 0
1496
if (!start) start = 0
1497
if (!end) end = this.length
1498
1499
if (end < start) throw new RangeError('end < start')
1500
1501
// Fill 0 bytes; we're done
1502
if (end === start) return
1503
if (this.length === 0) return
1504
1505
if (start < 0 || start >= this.length) throw new RangeError('start out of bounds')
1506
if (end < 0 || end > this.length) throw new RangeError('end out of bounds')
1507
1508
var i
1509
if (typeof value === 'number') {
1510
for (i = start; i < end; i++) {
1511
this[i] = value
1512
}
1513
} else {
1514
var bytes = utf8ToBytes(value.toString())
1515
var len = bytes.length
1516
for (i = start; i < end; i++) {
1517
this[i] = bytes[i % len]
1518
}
1519
}
1520
1521
return this
1522
}
1523
1524
/**
1525
* Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance.
1526
* Added in Node 0.12. Only available in browsers that support ArrayBuffer.
1527
*/
1528
Buffer.prototype.toArrayBuffer = function toArrayBuffer () {
1529
if (typeof Uint8Array !== 'undefined') {
1530
if (Buffer.TYPED_ARRAY_SUPPORT) {
1531
return (new Buffer(this)).buffer
1532
} else {
1533
var buf = new Uint8Array(this.length)
1534
for (var i = 0, len = buf.length; i < len; i += 1) {
1535
buf[i] = this[i]
1536
}
1537
return buf.buffer
1538
}
1539
} else {
1540
throw new TypeError('Buffer.toArrayBuffer not supported in this browser')
1541
}
1542
}
1543
1544
// HELPER FUNCTIONS
1545
// ================
1546
1547
var BP = Buffer.prototype
1548
1549
/**
1550
* Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods
1551
*/
1552
Buffer._augment = function _augment (arr) {
1553
arr.constructor = Buffer
1554
arr._isBuffer = true
1555
1556
// save reference to original Uint8Array set method before overwriting
1557
arr._set = arr.set
1558
1559
// deprecated, will be removed in node 0.13+
1560
arr.get = BP.get
1561
arr.set = BP.set
1562
1563
arr.write = BP.write
1564
arr.toString = BP.toString
1565
arr.toLocaleString = BP.toString
1566
arr.toJSON = BP.toJSON
1567
arr.equals = BP.equals
1568
arr.compare = BP.compare
1569
arr.indexOf = BP.indexOf
1570
arr.copy = BP.copy
1571
arr.slice = BP.slice
1572
arr.readUIntLE = BP.readUIntLE
1573
arr.readUIntBE = BP.readUIntBE
1574
arr.readUInt8 = BP.readUInt8
1575
arr.readUInt16LE = BP.readUInt16LE
1576
arr.readUInt16BE = BP.readUInt16BE
1577
arr.readUInt32LE = BP.readUInt32LE
1578
arr.readUInt32BE = BP.readUInt32BE
1579
arr.readIntLE = BP.readIntLE
1580
arr.readIntBE = BP.readIntBE
1581
arr.readInt8 = BP.readInt8
1582
arr.readInt16LE = BP.readInt16LE
1583
arr.readInt16BE = BP.readInt16BE
1584
arr.readInt32LE = BP.readInt32LE
1585
arr.readInt32BE = BP.readInt32BE
1586
arr.readFloatLE = BP.readFloatLE
1587
arr.readFloatBE = BP.readFloatBE
1588
arr.readDoubleLE = BP.readDoubleLE
1589
arr.readDoubleBE = BP.readDoubleBE
1590
arr.writeUInt8 = BP.writeUInt8
1591
arr.writeUIntLE = BP.writeUIntLE
1592
arr.writeUIntBE = BP.writeUIntBE
1593
arr.writeUInt16LE = BP.writeUInt16LE
1594
arr.writeUInt16BE = BP.writeUInt16BE
1595
arr.writeUInt32LE = BP.writeUInt32LE
1596
arr.writeUInt32BE = BP.writeUInt32BE
1597
arr.writeIntLE = BP.writeIntLE
1598
arr.writeIntBE = BP.writeIntBE
1599
arr.writeInt8 = BP.writeInt8
1600
arr.writeInt16LE = BP.writeInt16LE
1601
arr.writeInt16BE = BP.writeInt16BE
1602
arr.writeInt32LE = BP.writeInt32LE
1603
arr.writeInt32BE = BP.writeInt32BE
1604
arr.writeFloatLE = BP.writeFloatLE
1605
arr.writeFloatBE = BP.writeFloatBE
1606
arr.writeDoubleLE = BP.writeDoubleLE
1607
arr.writeDoubleBE = BP.writeDoubleBE
1608
arr.fill = BP.fill
1609
arr.inspect = BP.inspect
1610
arr.toArrayBuffer = BP.toArrayBuffer
1611
1612
return arr
1613
}
1614
1615
var INVALID_BASE64_RE = /[^+\/0-9A-z\-]/g
1616
1617
function base64clean (str) {
1618
// Node strips out invalid characters like \n and \t from the string, base64-js does not
1619
str = stringtrim(str).replace(INVALID_BASE64_RE, '')
1620
// Node converts strings with length < 2 to ''
1621
if (str.length < 2) return ''
1622
// Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
1623
while (str.length % 4 !== 0) {
1624
str = str + '='
1625
}
1626
return str
1627
}
1628
1629
function stringtrim (str) {
1630
if (str.trim) return str.trim()
1631
return str.replace(/^\s+|\s+$/g, '')
1632
}
1633
1634
function isArrayish (subject) {
1635
return isArray(subject) || Buffer.isBuffer(subject) ||
1636
subject && typeof subject === 'object' &&
1637
typeof subject.length === 'number'
1638
}
1639
1640
function toHex (n) {
1641
if (n < 16) return '0' + n.toString(16)
1642
return n.toString(16)
1643
}
1644
1645
function utf8ToBytes (string, units) {
1646
units = units || Infinity
1647
var codePoint
1648
var length = string.length
1649
var leadSurrogate = null
1650
var bytes = []
1651
var i = 0
1652
1653
for (; i < length; i++) {
1654
codePoint = string.charCodeAt(i)
1655
1656
// is surrogate component
1657
if (codePoint > 0xD7FF && codePoint < 0xE000) {
1658
// last char was a lead
1659
if (leadSurrogate) {
1660
// 2 leads in a row
1661
if (codePoint < 0xDC00) {
1662
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
1663
leadSurrogate = codePoint
1664
continue
1665
} else {
1666
// valid surrogate pair
1667
codePoint = leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00 | 0x10000
1668
leadSurrogate = null
1669
}
1670
} else {
1671
// no lead yet
1672
1673
if (codePoint > 0xDBFF) {
1674
// unexpected trail
1675
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
1676
continue
1677
} else if (i + 1 === length) {
1678
// unpaired lead
1679
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
1680
continue
1681
} else {
1682
// valid lead
1683
leadSurrogate = codePoint
1684
continue
1685
}
1686
}
1687
} else if (leadSurrogate) {
1688
// valid bmp char, but last char was a lead
1689
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
1690
leadSurrogate = null
1691
}
1692
1693
// encode utf8
1694
if (codePoint < 0x80) {
1695
if ((units -= 1) < 0) break
1696
bytes.push(codePoint)
1697
} else if (codePoint < 0x800) {
1698
if ((units -= 2) < 0) break
1699
bytes.push(
1700
codePoint >> 0x6 | 0xC0,
1701
codePoint & 0x3F | 0x80
1702
)
1703
} else if (codePoint < 0x10000) {
1704
if ((units -= 3) < 0) break
1705
bytes.push(
1706
codePoint >> 0xC | 0xE0,
1707
codePoint >> 0x6 & 0x3F | 0x80,
1708
codePoint & 0x3F | 0x80
1709
)
1710
} else if (codePoint < 0x200000) {
1711
if ((units -= 4) < 0) break
1712
bytes.push(
1713
codePoint >> 0x12 | 0xF0,
1714
codePoint >> 0xC & 0x3F | 0x80,
1715
codePoint >> 0x6 & 0x3F | 0x80,
1716
codePoint & 0x3F | 0x80
1717
)
1718
} else {
1719
throw new Error('Invalid code point')
1720
}
1721
}
1722
1723
return bytes
1724
}
1725
1726
function asciiToBytes (str) {
1727
var byteArray = []
1728
for (var i = 0; i < str.length; i++) {
1729
// Node's code seems to be doing this and not & 0x7F..
1730
byteArray.push(str.charCodeAt(i) & 0xFF)
1731
}
1732
return byteArray
1733
}
1734
1735
function utf16leToBytes (str, units) {
1736
var c, hi, lo
1737
var byteArray = []
1738
for (var i = 0; i < str.length; i++) {
1739
if ((units -= 2) < 0) break
1740
1741
c = str.charCodeAt(i)
1742
hi = c >> 8
1743
lo = c % 256
1744
byteArray.push(lo)
1745
byteArray.push(hi)
1746
}
1747
1748
return byteArray
1749
}
1750
1751
function base64ToBytes (str) {
1752
return base64.toByteArray(base64clean(str))
1753
}
1754
1755
function blitBuffer (src, dst, offset, length) {
1756
for (var i = 0; i < length; i++) {
1757
if ((i + offset >= dst.length) || (i >= src.length)) break
1758
dst[i + offset] = src[i]
1759
}
1760
return i
1761
}
1762
1763
function decodeUtf8Char (str) {
1764
try {
1765
return decodeURIComponent(str)
1766
} catch (err) {
1767
return String.fromCharCode(0xFFFD) // UTF 8 invalid char
1768
}
1769
}
1770
1771
},{"base64-js":4,"ieee754":5,"is-array":6}],4:[function(_dereq_,module,exports){
1772
var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
1773
1774
;(function (exports) {
1775
'use strict';
1776
1777
var Arr = (typeof Uint8Array !== 'undefined')
1778
? Uint8Array
1779
: Array
1780
1781
var PLUS = '+'.charCodeAt(0)
1782
var SLASH = '/'.charCodeAt(0)
1783
var NUMBER = '0'.charCodeAt(0)
1784
var LOWER = 'a'.charCodeAt(0)
1785
var UPPER = 'A'.charCodeAt(0)
1786
var PLUS_URL_SAFE = '-'.charCodeAt(0)
1787
var SLASH_URL_SAFE = '_'.charCodeAt(0)
1788
1789
function decode (elt) {
1790
var code = elt.charCodeAt(0)
1791
if (code === PLUS ||
1792
code === PLUS_URL_SAFE)
1793
return 62 // '+'
1794
if (code === SLASH ||
1795
code === SLASH_URL_SAFE)
1796
return 63 // '/'
1797
if (code < NUMBER)
1798
return -1 //no match
1799
if (code < NUMBER + 10)
1800
return code - NUMBER + 26 + 26
1801
if (code < UPPER + 26)
1802
return code - UPPER
1803
if (code < LOWER + 26)
1804
return code - LOWER + 26
1805
}
1806
1807
function b64ToByteArray (b64) {
1808
var i, j, l, tmp, placeHolders, arr
1809
1810
if (b64.length % 4 > 0) {
1811
throw new Error('Invalid string. Length must be a multiple of 4')
1812
}
1813
1814
// the number of equal signs (place holders)
1815
// if there are two placeholders, than the two characters before it
1816
// represent one byte
1817
// if there is only one, then the three characters before it represent 2 bytes
1818
// this is just a cheap hack to not do indexOf twice
1819
var len = b64.length
1820
placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0
1821
1822
// base64 is 4/3 + up to two characters of the original data
1823
arr = new Arr(b64.length * 3 / 4 - placeHolders)
1824
1825
// if there are placeholders, only get up to the last complete 4 chars
1826
l = placeHolders > 0 ? b64.length - 4 : b64.length
1827
1828
var L = 0
1829
1830
function push (v) {
1831
arr[L++] = v
1832
}
1833
1834
for (i = 0, j = 0; i < l; i += 4, j += 3) {
1835
tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3))
1836
push((tmp & 0xFF0000) >> 16)
1837
push((tmp & 0xFF00) >> 8)
1838
push(tmp & 0xFF)
1839
}
1840
1841
if (placeHolders === 2) {
1842
tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4)
1843
push(tmp & 0xFF)
1844
} else if (placeHolders === 1) {
1845
tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2)
1846
push((tmp >> 8) & 0xFF)
1847
push(tmp & 0xFF)
1848
}
1849
1850
return arr
1851
}
1852
1853
function uint8ToBase64 (uint8) {
1854
var i,
1855
extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes
1856
output = "",
1857
temp, length
1858
1859
function encode (num) {
1860
return lookup.charAt(num)
1861
}
1862
1863
function tripletToBase64 (num) {
1864
return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F)
1865
}
1866
1867
// go through the array every three bytes, we'll deal with trailing stuff later
1868
for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) {
1869
temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])
1870
output += tripletToBase64(temp)
1871
}
1872
1873
// pad the end with zeros, but make sure to not forget the extra bytes
1874
switch (extraBytes) {
1875
case 1:
1876
temp = uint8[uint8.length - 1]
1877
output += encode(temp >> 2)
1878
output += encode((temp << 4) & 0x3F)
1879
output += '=='
1880
break
1881
case 2:
1882
temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1])
1883
output += encode(temp >> 10)
1884
output += encode((temp >> 4) & 0x3F)
1885
output += encode((temp << 2) & 0x3F)
1886
output += '='
1887
break
1888
}
1889
1890
return output
1891
}
1892
1893
exports.toByteArray = b64ToByteArray
1894
exports.fromByteArray = uint8ToBase64
1895
}(typeof exports === 'undefined' ? (this.base64js = {}) : exports))
1896
1897
},{}],5:[function(_dereq_,module,exports){
1898
exports.read = function(buffer, offset, isLE, mLen, nBytes) {
1899
var e, m,
1900
eLen = nBytes * 8 - mLen - 1,
1901
eMax = (1 << eLen) - 1,
1902
eBias = eMax >> 1,
1903
nBits = -7,
1904
i = isLE ? (nBytes - 1) : 0,
1905
d = isLE ? -1 : 1,
1906
s = buffer[offset + i];
1907
1908
i += d;
1909
1910
e = s & ((1 << (-nBits)) - 1);
1911
s >>= (-nBits);
1912
nBits += eLen;
1913
for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8);
1914
1915
m = e & ((1 << (-nBits)) - 1);
1916
e >>= (-nBits);
1917
nBits += mLen;
1918
for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8);
1919
1920
if (e === 0) {
1921
e = 1 - eBias;
1922
} else if (e === eMax) {
1923
return m ? NaN : ((s ? -1 : 1) * Infinity);
1924
} else {
1925
m = m + Math.pow(2, mLen);
1926
e = e - eBias;
1927
}
1928
return (s ? -1 : 1) * m * Math.pow(2, e - mLen);
1929
};
1930
1931
exports.write = function(buffer, value, offset, isLE, mLen, nBytes) {
1932
var e, m, c,
1933
eLen = nBytes * 8 - mLen - 1,
1934
eMax = (1 << eLen) - 1,
1935
eBias = eMax >> 1,
1936
rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0),
1937
i = isLE ? 0 : (nBytes - 1),
1938
d = isLE ? 1 : -1,
1939
s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0;
1940
1941
value = Math.abs(value);
1942
1943
if (isNaN(value) || value === Infinity) {
1944
m = isNaN(value) ? 1 : 0;
1945
e = eMax;
1946
} else {
1947
e = Math.floor(Math.log(value) / Math.LN2);
1948
if (value * (c = Math.pow(2, -e)) < 1) {
1949
e--;
1950
c *= 2;
1951
}
1952
if (e + eBias >= 1) {
1953
value += rt / c;
1954
} else {
1955
value += rt * Math.pow(2, 1 - eBias);
1956
}
1957
if (value * c >= 2) {
1958
e++;
1959
c /= 2;
1960
}
1961
1962
if (e + eBias >= eMax) {
1963
m = 0;
1964
e = eMax;
1965
} else if (e + eBias >= 1) {
1966
m = (value * c - 1) * Math.pow(2, mLen);
1967
e = e + eBias;
1968
} else {
1969
m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen);
1970
e = 0;
1971
}
1972
}
1973
1974
for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8);
1975
1976
e = (e << mLen) | m;
1977
eLen += mLen;
1978
for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8);
1979
1980
buffer[offset + i - d] |= s * 128;
1981
};
1982
1983
},{}],6:[function(_dereq_,module,exports){
1984
1985
/**
1986
* isArray
1987
*/
1988
1989
var isArray = Array.isArray;
1990
1991
/**
1992
* toString
1993
*/
1994
1995
var str = Object.prototype.toString;
1996
1997
/**
1998
* Whether or not the given `val`
1999
* is an array.
2000
*
2001
* example:
2002
*
2003
* isArray([]);
2004
* // > true
2005
* isArray(arguments);
2006
* // > false
2007
* isArray('');
2008
* // > false
2009
*
2010
* @param {mixed} val
2011
* @return {bool}
2012
*/
2013
2014
module.exports = isArray || function (val) {
2015
return !! val && '[object Array]' == str.call(val);
2016
};
2017
2018
},{}],7:[function(_dereq_,module,exports){
2019
(function (process){
2020
// Copyright Joyent, Inc. and other Node contributors.
2021
//
2022
// Permission is hereby granted, free of charge, to any person obtaining a
2023
// copy of this software and associated documentation files (the
2024
// "Software"), to deal in the Software without restriction, including
2025
// without limitation the rights to use, copy, modify, merge, publish,
2026
// distribute, sublicense, and/or sell copies of the Software, and to permit
2027
// persons to whom the Software is furnished to do so, subject to the
2028
// following conditions:
2029
//
2030
// The above copyright notice and this permission notice shall be included
2031
// in all copies or substantial portions of the Software.
2032
//
2033
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
2034
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2035
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
2036
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
2037
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
2038
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
2039
// USE OR OTHER DEALINGS IN THE SOFTWARE.
2040
2041
// resolves . and .. elements in a path array with directory names there
2042
// must be no slashes, empty elements, or device names (c:\) in the array
2043
// (so also no leading and trailing slashes - it does not distinguish
2044
// relative and absolute paths)
2045
function normalizeArray(parts, allowAboveRoot) {
2046
// if the path tries to go above the root, `up` ends up > 0
2047
var up = 0;
2048
for (var i = parts.length - 1; i >= 0; i--) {
2049
var last = parts[i];
2050
if (last === '.') {
2051
parts.splice(i, 1);
2052
} else if (last === '..') {
2053
parts.splice(i, 1);
2054
up++;
2055
} else if (up) {
2056
parts.splice(i, 1);
2057
up--;
2058
}
2059
}
2060
2061
// if the path is allowed to go above the root, restore leading ..s
2062
if (allowAboveRoot) {
2063
for (; up--; up) {
2064
parts.unshift('..');
2065
}
2066
}
2067
2068
return parts;
2069
}
2070
2071
// Split a filename into [root, dir, basename, ext], unix version
2072
// 'root' is just a slash, or nothing.
2073
var splitPathRe =
2074
/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
2075
var splitPath = function(filename) {
2076
return splitPathRe.exec(filename).slice(1);
2077
};
2078
2079
// path.resolve([from ...], to)
2080
// posix version
2081
exports.resolve = function() {
2082
var resolvedPath = '',
2083
resolvedAbsolute = false;
2084
2085
for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
2086
var path = (i >= 0) ? arguments[i] : process.cwd();
2087
2088
// Skip empty and invalid entries
2089
if (typeof path !== 'string') {
2090
throw new TypeError('Arguments to path.resolve must be strings');
2091
} else if (!path) {
2092
continue;
2093
}
2094
2095
resolvedPath = path + '/' + resolvedPath;
2096
resolvedAbsolute = path.charAt(0) === '/';
2097
}
2098
2099
// At this point the path should be resolved to a full absolute path, but
2100
// handle relative paths to be safe (might happen when process.cwd() fails)
2101
2102
// Normalize the path
2103
resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {
2104
return !!p;
2105
}), !resolvedAbsolute).join('/');
2106
2107
return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
2108
};
2109
2110
// path.normalize(path)
2111
// posix version
2112
exports.normalize = function(path) {
2113
var isAbsolute = exports.isAbsolute(path),
2114
trailingSlash = substr(path, -1) === '/';
2115
2116
// Normalize the path
2117
path = normalizeArray(filter(path.split('/'), function(p) {
2118
return !!p;
2119
}), !isAbsolute).join('/');
2120
2121
if (!path && !isAbsolute) {
2122
path = '.';
2123
}
2124
if (path && trailingSlash) {
2125
path += '/';
2126
}
2127
2128
return (isAbsolute ? '/' : '') + path;
2129
};
2130
2131
// posix version
2132
exports.isAbsolute = function(path) {
2133
return path.charAt(0) === '/';
2134
};
2135
2136
// posix version
2137
exports.join = function() {
2138
var paths = Array.prototype.slice.call(arguments, 0);
2139
return exports.normalize(filter(paths, function(p, index) {
2140
if (typeof p !== 'string') {
2141
throw new TypeError('Arguments to path.join must be strings');
2142
}
2143
return p;
2144
}).join('/'));
2145
};
2146
2147
2148
// path.relative(from, to)
2149
// posix version
2150
exports.relative = function(from, to) {
2151
from = exports.resolve(from).substr(1);
2152
to = exports.resolve(to).substr(1);
2153
2154
function trim(arr) {
2155
var start = 0;
2156
for (; start < arr.length; start++) {
2157
if (arr[start] !== '') break;
2158
}
2159
2160
var end = arr.length - 1;
2161
for (; end >= 0; end--) {
2162
if (arr[end] !== '') break;
2163
}
2164
2165
if (start > end) return [];
2166
return arr.slice(start, end - start + 1);
2167
}
2168
2169
var fromParts = trim(from.split('/'));
2170
var toParts = trim(to.split('/'));
2171
2172
var length = Math.min(fromParts.length, toParts.length);
2173
var samePartsLength = length;
2174
for (var i = 0; i < length; i++) {
2175
if (fromParts[i] !== toParts[i]) {
2176
samePartsLength = i;
2177
break;
2178
}
2179
}
2180
2181
var outputParts = [];
2182
for (var i = samePartsLength; i < fromParts.length; i++) {
2183
outputParts.push('..');
2184
}
2185
2186
outputParts = outputParts.concat(toParts.slice(samePartsLength));
2187
2188
return outputParts.join('/');
2189
};
2190
2191
exports.sep = '/';
2192
exports.delimiter = ':';
2193
2194
exports.dirname = function(path) {
2195
var result = splitPath(path),
2196
root = result[0],
2197
dir = result[1];
2198
2199
if (!root && !dir) {
2200
// No dirname whatsoever
2201
return '.';
2202
}
2203
2204
if (dir) {
2205
// It has a dirname, strip trailing slash
2206
dir = dir.substr(0, dir.length - 1);
2207
}
2208
2209
return root + dir;
2210
};
2211
2212
2213
exports.basename = function(path, ext) {
2214
var f = splitPath(path)[2];
2215
// TODO: make this comparison case-insensitive on windows?
2216
if (ext && f.substr(-1 * ext.length) === ext) {
2217
f = f.substr(0, f.length - ext.length);
2218
}
2219
return f;
2220
};
2221
2222
2223
exports.extname = function(path) {
2224
return splitPath(path)[3];
2225
};
2226
2227
function filter (xs, f) {
2228
if (xs.filter) return xs.filter(f);
2229
var res = [];
2230
for (var i = 0; i < xs.length; i++) {
2231
if (f(xs[i], i, xs)) res.push(xs[i]);
2232
}
2233
return res;
2234
}
2235
2236
// String.prototype.substr - negative index don't work in IE8
2237
var substr = 'ab'.substr(-1) === 'b'
2238
? function (str, start, len) { return str.substr(start, len) }
2239
: function (str, start, len) {
2240
if (start < 0) start = str.length + start;
2241
return str.substr(start, len);
2242
}
2243
;
2244
2245
}).call(this,_dereq_('_process'))
2246
},{"_process":8}],8:[function(_dereq_,module,exports){
2247
// shim for using process in browser
2248
2249
var process = module.exports = {};
2250
var queue = [];
2251
var draining = false;
2252
2253
function drainQueue() {
2254
if (draining) {
2255
return;
2256
}
2257
draining = true;
2258
var currentQueue;
2259
var len = queue.length;
2260
while(len) {
2261
currentQueue = queue;
2262
queue = [];
2263
var i = -1;
2264
while (++i < len) {
2265
currentQueue[i]();
2266
}
2267
len = queue.length;
2268
}
2269
draining = false;
2270
}
2271
process.nextTick = function (fun) {
2272
queue.push(fun);
2273
if (!draining) {
2274
setTimeout(drainQueue, 0);
2275
}
2276
};
2277
2278
process.title = 'browser';
2279
process.browser = true;
2280
process.env = {};
2281
process.argv = [];
2282
process.version = ''; // empty string to avoid regexp issues
2283
process.versions = {};
2284
2285
function noop() {}
2286
2287
process.on = noop;
2288
process.addListener = noop;
2289
process.once = noop;
2290
process.off = noop;
2291
process.removeListener = noop;
2292
process.removeAllListeners = noop;
2293
process.emit = noop;
2294
2295
process.binding = function (name) {
2296
throw new Error('process.binding is not supported');
2297
};
2298
2299
// TODO(shtylman)
2300
process.cwd = function () { return '/' };
2301
process.chdir = function (dir) {
2302
throw new Error('process.chdir is not supported');
2303
};
2304
process.umask = function() { return 0; };
2305
2306
},{}],9:[function(_dereq_,module,exports){
2307
/*
2308
Copyright (C) 2013 Ariya Hidayat <[email protected]>
2309
Copyright (C) 2013 Thaddee Tyl <[email protected]>
2310
Copyright (C) 2012 Ariya Hidayat <[email protected]>
2311
Copyright (C) 2012 Mathias Bynens <[email protected]>
2312
Copyright (C) 2012 Joost-Wim Boekesteijn <[email protected]>
2313
Copyright (C) 2012 Kris Kowal <[email protected]>
2314
Copyright (C) 2012 Yusuke Suzuki <[email protected]>
2315
Copyright (C) 2012 Arpad Borsos <[email protected]>
2316
Copyright (C) 2011 Ariya Hidayat <[email protected]>
2317
2318
Redistribution and use in source and binary forms, with or without
2319
modification, are permitted provided that the following conditions are met:
2320
2321
* Redistributions of source code must retain the above copyright
2322
notice, this list of conditions and the following disclaimer.
2323
* Redistributions in binary form must reproduce the above copyright
2324
notice, this list of conditions and the following disclaimer in the
2325
documentation and/or other materials provided with the distribution.
2326
2327
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2328
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2329
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2330
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
2331
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2332
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2333
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
2334
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2335
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2336
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2337
*/
2338
2339
(function (root, factory) {
2340
'use strict';
2341
2342
// Universal Module Definition (UMD) to support AMD, CommonJS/Node.js,
2343
// Rhino, and plain browser loading.
2344
2345
/* istanbul ignore next */
2346
if (typeof define === 'function' && define.amd) {
2347
define(['exports'], factory);
2348
} else if (typeof exports !== 'undefined') {
2349
factory(exports);
2350
} else {
2351
factory((root.esprima = {}));
2352
}
2353
}(this, function (exports) {
2354
'use strict';
2355
2356
var Token,
2357
TokenName,
2358
FnExprTokens,
2359
Syntax,
2360
PropertyKind,
2361
Messages,
2362
Regex,
2363
SyntaxTreeDelegate,
2364
XHTMLEntities,
2365
ClassPropertyType,
2366
source,
2367
strict,
2368
index,
2369
lineNumber,
2370
lineStart,
2371
length,
2372
delegate,
2373
lookahead,
2374
state,
2375
extra;
2376
2377
Token = {
2378
BooleanLiteral: 1,
2379
EOF: 2,
2380
Identifier: 3,
2381
Keyword: 4,
2382
NullLiteral: 5,
2383
NumericLiteral: 6,
2384
Punctuator: 7,
2385
StringLiteral: 8,
2386
RegularExpression: 9,
2387
Template: 10,
2388
JSXIdentifier: 11,
2389
JSXText: 12
2390
};
2391
2392
TokenName = {};
2393
TokenName[Token.BooleanLiteral] = 'Boolean';
2394
TokenName[Token.EOF] = '<end>';
2395
TokenName[Token.Identifier] = 'Identifier';
2396
TokenName[Token.Keyword] = 'Keyword';
2397
TokenName[Token.NullLiteral] = 'Null';
2398
TokenName[Token.NumericLiteral] = 'Numeric';
2399
TokenName[Token.Punctuator] = 'Punctuator';
2400
TokenName[Token.StringLiteral] = 'String';
2401
TokenName[Token.JSXIdentifier] = 'JSXIdentifier';
2402
TokenName[Token.JSXText] = 'JSXText';
2403
TokenName[Token.RegularExpression] = 'RegularExpression';
2404
2405
// A function following one of those tokens is an expression.
2406
FnExprTokens = ['(', '{', '[', 'in', 'typeof', 'instanceof', 'new',
2407
'return', 'case', 'delete', 'throw', 'void',
2408
// assignment operators
2409
'=', '+=', '-=', '*=', '/=', '%=', '<<=', '>>=', '>>>=',
2410
'&=', '|=', '^=', ',',
2411
// binary/unary operators
2412
'+', '-', '*', '/', '%', '++', '--', '<<', '>>', '>>>', '&',
2413
'|', '^', '!', '~', '&&', '||', '?', ':', '===', '==', '>=',
2414
'<=', '<', '>', '!=', '!=='];
2415
2416
Syntax = {
2417
AnyTypeAnnotation: 'AnyTypeAnnotation',
2418
ArrayExpression: 'ArrayExpression',
2419
ArrayPattern: 'ArrayPattern',
2420
ArrayTypeAnnotation: 'ArrayTypeAnnotation',
2421
ArrowFunctionExpression: 'ArrowFunctionExpression',
2422
AssignmentExpression: 'AssignmentExpression',
2423
BinaryExpression: 'BinaryExpression',
2424
BlockStatement: 'BlockStatement',
2425
BooleanTypeAnnotation: 'BooleanTypeAnnotation',
2426
BreakStatement: 'BreakStatement',
2427
CallExpression: 'CallExpression',
2428
CatchClause: 'CatchClause',
2429
ClassBody: 'ClassBody',
2430
ClassDeclaration: 'ClassDeclaration',
2431
ClassExpression: 'ClassExpression',
2432
ClassImplements: 'ClassImplements',
2433
ClassProperty: 'ClassProperty',
2434
ComprehensionBlock: 'ComprehensionBlock',
2435
ComprehensionExpression: 'ComprehensionExpression',
2436
ConditionalExpression: 'ConditionalExpression',
2437
ContinueStatement: 'ContinueStatement',
2438
DebuggerStatement: 'DebuggerStatement',
2439
DeclareClass: 'DeclareClass',
2440
DeclareFunction: 'DeclareFunction',
2441
DeclareModule: 'DeclareModule',
2442
DeclareVariable: 'DeclareVariable',
2443
DoWhileStatement: 'DoWhileStatement',
2444
EmptyStatement: 'EmptyStatement',
2445
ExportDeclaration: 'ExportDeclaration',
2446
ExportBatchSpecifier: 'ExportBatchSpecifier',
2447
ExportSpecifier: 'ExportSpecifier',
2448
ExpressionStatement: 'ExpressionStatement',
2449
ForInStatement: 'ForInStatement',
2450
ForOfStatement: 'ForOfStatement',
2451
ForStatement: 'ForStatement',
2452
FunctionDeclaration: 'FunctionDeclaration',
2453
FunctionExpression: 'FunctionExpression',
2454
FunctionTypeAnnotation: 'FunctionTypeAnnotation',
2455
FunctionTypeParam: 'FunctionTypeParam',
2456
GenericTypeAnnotation: 'GenericTypeAnnotation',
2457
Identifier: 'Identifier',
2458
IfStatement: 'IfStatement',
2459
ImportDeclaration: 'ImportDeclaration',
2460
ImportDefaultSpecifier: 'ImportDefaultSpecifier',
2461
ImportNamespaceSpecifier: 'ImportNamespaceSpecifier',
2462
ImportSpecifier: 'ImportSpecifier',
2463
InterfaceDeclaration: 'InterfaceDeclaration',
2464
InterfaceExtends: 'InterfaceExtends',
2465
IntersectionTypeAnnotation: 'IntersectionTypeAnnotation',
2466
LabeledStatement: 'LabeledStatement',
2467
Literal: 'Literal',
2468
LogicalExpression: 'LogicalExpression',
2469
MemberExpression: 'MemberExpression',
2470
MethodDefinition: 'MethodDefinition',
2471
ModuleSpecifier: 'ModuleSpecifier',
2472
NewExpression: 'NewExpression',
2473
NullableTypeAnnotation: 'NullableTypeAnnotation',
2474
NumberTypeAnnotation: 'NumberTypeAnnotation',
2475
ObjectExpression: 'ObjectExpression',
2476
ObjectPattern: 'ObjectPattern',
2477
ObjectTypeAnnotation: 'ObjectTypeAnnotation',
2478
ObjectTypeCallProperty: 'ObjectTypeCallProperty',
2479
ObjectTypeIndexer: 'ObjectTypeIndexer',
2480
ObjectTypeProperty: 'ObjectTypeProperty',
2481
Program: 'Program',
2482
Property: 'Property',
2483
QualifiedTypeIdentifier: 'QualifiedTypeIdentifier',
2484
ReturnStatement: 'ReturnStatement',
2485
SequenceExpression: 'SequenceExpression',
2486
SpreadElement: 'SpreadElement',
2487
SpreadProperty: 'SpreadProperty',
2488
StringLiteralTypeAnnotation: 'StringLiteralTypeAnnotation',
2489
StringTypeAnnotation: 'StringTypeAnnotation',
2490
SwitchCase: 'SwitchCase',
2491
SwitchStatement: 'SwitchStatement',
2492
TaggedTemplateExpression: 'TaggedTemplateExpression',
2493
TemplateElement: 'TemplateElement',
2494
TemplateLiteral: 'TemplateLiteral',
2495
ThisExpression: 'ThisExpression',
2496
ThrowStatement: 'ThrowStatement',
2497
TupleTypeAnnotation: 'TupleTypeAnnotation',
2498
TryStatement: 'TryStatement',
2499
TypeAlias: 'TypeAlias',
2500
TypeAnnotation: 'TypeAnnotation',
2501
TypeCastExpression: 'TypeCastExpression',
2502
TypeofTypeAnnotation: 'TypeofTypeAnnotation',
2503
TypeParameterDeclaration: 'TypeParameterDeclaration',
2504
TypeParameterInstantiation: 'TypeParameterInstantiation',
2505
UnaryExpression: 'UnaryExpression',
2506
UnionTypeAnnotation: 'UnionTypeAnnotation',
2507
UpdateExpression: 'UpdateExpression',
2508
VariableDeclaration: 'VariableDeclaration',
2509
VariableDeclarator: 'VariableDeclarator',
2510
VoidTypeAnnotation: 'VoidTypeAnnotation',
2511
WhileStatement: 'WhileStatement',
2512
WithStatement: 'WithStatement',
2513
JSXIdentifier: 'JSXIdentifier',
2514
JSXNamespacedName: 'JSXNamespacedName',
2515
JSXMemberExpression: 'JSXMemberExpression',
2516
JSXEmptyExpression: 'JSXEmptyExpression',
2517
JSXExpressionContainer: 'JSXExpressionContainer',
2518
JSXElement: 'JSXElement',
2519
JSXClosingElement: 'JSXClosingElement',
2520
JSXOpeningElement: 'JSXOpeningElement',
2521
JSXAttribute: 'JSXAttribute',
2522
JSXSpreadAttribute: 'JSXSpreadAttribute',
2523
JSXText: 'JSXText',
2524
YieldExpression: 'YieldExpression',
2525
AwaitExpression: 'AwaitExpression'
2526
};
2527
2528
PropertyKind = {
2529
Data: 1,
2530
Get: 2,
2531
Set: 4
2532
};
2533
2534
ClassPropertyType = {
2535
'static': 'static',
2536
prototype: 'prototype'
2537
};
2538
2539
// Error messages should be identical to V8.
2540
Messages = {
2541
UnexpectedToken: 'Unexpected token %0',
2542
UnexpectedNumber: 'Unexpected number',
2543
UnexpectedString: 'Unexpected string',
2544
UnexpectedIdentifier: 'Unexpected identifier',
2545
UnexpectedReserved: 'Unexpected reserved word',
2546
UnexpectedTemplate: 'Unexpected quasi %0',
2547
UnexpectedEOS: 'Unexpected end of input',
2548
NewlineAfterThrow: 'Illegal newline after throw',
2549
InvalidRegExp: 'Invalid regular expression',
2550
UnterminatedRegExp: 'Invalid regular expression: missing /',
2551
InvalidLHSInAssignment: 'Invalid left-hand side in assignment',
2552
InvalidLHSInFormalsList: 'Invalid left-hand side in formals list',
2553
InvalidLHSInForIn: 'Invalid left-hand side in for-in',
2554
MultipleDefaultsInSwitch: 'More than one default clause in switch statement',
2555
NoCatchOrFinally: 'Missing catch or finally after try',
2556
UnknownLabel: 'Undefined label \'%0\'',
2557
Redeclaration: '%0 \'%1\' has already been declared',
2558
IllegalContinue: 'Illegal continue statement',
2559
IllegalBreak: 'Illegal break statement',
2560
IllegalDuplicateClassProperty: 'Illegal duplicate property in class definition',
2561
IllegalClassConstructorProperty: 'Illegal constructor property in class definition',
2562
IllegalReturn: 'Illegal return statement',
2563
IllegalSpread: 'Illegal spread element',
2564
StrictModeWith: 'Strict mode code may not include a with statement',
2565
StrictCatchVariable: 'Catch variable may not be eval or arguments in strict mode',
2566
StrictVarName: 'Variable name may not be eval or arguments in strict mode',
2567
StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode',
2568
StrictParamDupe: 'Strict mode function may not have duplicate parameter names',
2569
ParameterAfterRestParameter: 'Rest parameter must be final parameter of an argument list',
2570
DefaultRestParameter: 'Rest parameter can not have a default value',
2571
ElementAfterSpreadElement: 'Spread must be the final element of an element list',
2572
PropertyAfterSpreadProperty: 'A rest property must be the final property of an object literal',
2573
ObjectPatternAsRestParameter: 'Invalid rest parameter',
2574
ObjectPatternAsSpread: 'Invalid spread argument',
2575
StrictFunctionName: 'Function name may not be eval or arguments in strict mode',
2576
StrictOctalLiteral: 'Octal literals are not allowed in strict mode.',
2577
StrictDelete: 'Delete of an unqualified identifier in strict mode.',
2578
StrictDuplicateProperty: 'Duplicate data property in object literal not allowed in strict mode',
2579
AccessorDataProperty: 'Object literal may not have data and accessor property with the same name',
2580
AccessorGetSet: 'Object literal may not have multiple get/set accessors with the same name',
2581
StrictLHSAssignment: 'Assignment to eval or arguments is not allowed in strict mode',
2582
StrictLHSPostfix: 'Postfix increment/decrement may not have eval or arguments operand in strict mode',
2583
StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode',
2584
StrictReservedWord: 'Use of future reserved word in strict mode',
2585
MissingFromClause: 'Missing from clause',
2586
NoAsAfterImportNamespace: 'Missing as after import *',
2587
InvalidModuleSpecifier: 'Invalid module specifier',
2588
IllegalImportDeclaration: 'Illegal import declaration',
2589
IllegalExportDeclaration: 'Illegal export declaration',
2590
NoUninitializedConst: 'Const must be initialized',
2591
ComprehensionRequiresBlock: 'Comprehension must have at least one block',
2592
ComprehensionError: 'Comprehension Error',
2593
EachNotAllowed: 'Each is not supported',
2594
InvalidJSXAttributeValue: 'JSX value should be either an expression or a quoted JSX text',
2595
ExpectedJSXClosingTag: 'Expected corresponding JSX closing tag for %0',
2596
AdjacentJSXElements: 'Adjacent JSX elements must be wrapped in an enclosing tag',
2597
ConfusedAboutFunctionType: 'Unexpected token =>. It looks like ' +
2598
'you are trying to write a function type, but you ended up ' +
2599
'writing a grouped type followed by an =>, which is a syntax ' +
2600
'error. Remember, function type parameters are named so function ' +
2601
'types look like (name1: type1, name2: type2) => returnType. You ' +
2602
'probably wrote (type1) => returnType'
2603
};
2604
2605
// See also tools/generate-unicode-regex.py.
2606
Regex = {
2607
NonAsciiIdentifierStart: new RegExp('[\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc]'),
2608
NonAsciiIdentifierPart: new RegExp('[\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0300-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u0483-\u0487\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u05d0-\u05ea\u05f0-\u05f2\u0610-\u061a\u0620-\u0669\u066e-\u06d3\u06d5-\u06dc\u06df-\u06e8\u06ea-\u06fc\u06ff\u0710-\u074a\u074d-\u07b1\u07c0-\u07f5\u07fa\u0800-\u082d\u0840-\u085b\u08a0\u08a2-\u08ac\u08e4-\u08fe\u0900-\u0963\u0966-\u096f\u0971-\u0977\u0979-\u097f\u0981-\u0983\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bc-\u09c4\u09c7\u09c8\u09cb-\u09ce\u09d7\u09dc\u09dd\u09df-\u09e3\u09e6-\u09f1\u0a01-\u0a03\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a59-\u0a5c\u0a5e\u0a66-\u0a75\u0a81-\u0a83\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abc-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ad0\u0ae0-\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3c-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b5c\u0b5d\u0b5f-\u0b63\u0b66-\u0b6f\u0b71\u0b82\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd0\u0bd7\u0be6-\u0bef\u0c01-\u0c03\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c58\u0c59\u0c60-\u0c63\u0c66-\u0c6f\u0c82\u0c83\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbc-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0cde\u0ce0-\u0ce3\u0ce6-\u0cef\u0cf1\u0cf2\u0d02\u0d03\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d-\u0d44\u0d46-\u0d48\u0d4a-\u0d4e\u0d57\u0d60-\u0d63\u0d66-\u0d6f\u0d7a-\u0d7f\u0d82\u0d83\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2\u0df3\u0e01-\u0e3a\u0e40-\u0e4e\u0e50-\u0e59\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb9\u0ebb-\u0ebd\u0ec0-\u0ec4\u0ec6\u0ec8-\u0ecd\u0ed0-\u0ed9\u0edc-\u0edf\u0f00\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e-\u0f47\u0f49-\u0f6c\u0f71-\u0f84\u0f86-\u0f97\u0f99-\u0fbc\u0fc6\u1000-\u1049\u1050-\u109d\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u135d-\u135f\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176c\u176e-\u1770\u1772\u1773\u1780-\u17d3\u17d7\u17dc\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u1820-\u1877\u1880-\u18aa\u18b0-\u18f5\u1900-\u191c\u1920-\u192b\u1930-\u193b\u1946-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u19d0-\u19d9\u1a00-\u1a1b\u1a20-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1aa7\u1b00-\u1b4b\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1bf3\u1c00-\u1c37\u1c40-\u1c49\u1c4d-\u1c7d\u1cd0-\u1cd2\u1cd4-\u1cf6\u1d00-\u1de6\u1dfc-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u200c\u200d\u203f\u2040\u2054\u2071\u207f\u2090-\u209c\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d7f-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2de0-\u2dff\u2e2f\u3005-\u3007\u3021-\u302f\u3031-\u3035\u3038-\u303c\u3041-\u3096\u3099\u309a\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua62b\ua640-\ua66f\ua674-\ua67d\ua67f-\ua697\ua69f-\ua6f1\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua827\ua840-\ua873\ua880-\ua8c4\ua8d0-\ua8d9\ua8e0-\ua8f7\ua8fb\ua900-\ua92d\ua930-\ua953\ua960-\ua97c\ua980-\ua9c0\ua9cf-\ua9d9\uaa00-\uaa36\uaa40-\uaa4d\uaa50-\uaa59\uaa60-\uaa76\uaa7a\uaa7b\uaa80-\uaac2\uaadb-\uaadd\uaae0-\uaaef\uaaf2-\uaaf6\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabea\uabec\uabed\uabf0-\uabf9\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe00-\ufe0f\ufe20-\ufe26\ufe33\ufe34\ufe4d-\ufe4f\ufe70-\ufe74\ufe76-\ufefc\uff10-\uff19\uff21-\uff3a\uff3f\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc]'),
2609
LeadingZeros: new RegExp('^0+(?!$)')
2610
};
2611
2612
// Ensure the condition is true, otherwise throw an error.
2613
// This is only to have a better contract semantic, i.e. another safety net
2614
// to catch a logic error. The condition shall be fulfilled in normal case.
2615
// Do NOT use this to enforce a certain condition on any user input.
2616
2617
function assert(condition, message) {
2618
/* istanbul ignore if */
2619
if (!condition) {
2620
throw new Error('ASSERT: ' + message);
2621
}
2622
}
2623
2624
function StringMap() {
2625
this.$data = {};
2626
}
2627
2628
StringMap.prototype.get = function (key) {
2629
key = '$' + key;
2630
return this.$data[key];
2631
};
2632
2633
StringMap.prototype.set = function (key, value) {
2634
key = '$' + key;
2635
this.$data[key] = value;
2636
return this;
2637
};
2638
2639
StringMap.prototype.has = function (key) {
2640
key = '$' + key;
2641
return Object.prototype.hasOwnProperty.call(this.$data, key);
2642
};
2643
2644
StringMap.prototype["delete"] = function (key) {
2645
key = '$' + key;
2646
return delete this.$data[key];
2647
};
2648
2649
function isDecimalDigit(ch) {
2650
return (ch >= 48 && ch <= 57); // 0..9
2651
}
2652
2653
function isHexDigit(ch) {
2654
return '0123456789abcdefABCDEF'.indexOf(ch) >= 0;
2655
}
2656
2657
function isOctalDigit(ch) {
2658
return '01234567'.indexOf(ch) >= 0;
2659
}
2660
2661
2662
// 7.2 White Space
2663
2664
function isWhiteSpace(ch) {
2665
return (ch === 32) || // space
2666
(ch === 9) || // tab
2667
(ch === 0xB) ||
2668
(ch === 0xC) ||
2669
(ch === 0xA0) ||
2670
(ch >= 0x1680 && '\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\uFEFF'.indexOf(String.fromCharCode(ch)) > 0);
2671
}
2672
2673
// 7.3 Line Terminators
2674
2675
function isLineTerminator(ch) {
2676
return (ch === 10) || (ch === 13) || (ch === 0x2028) || (ch === 0x2029);
2677
}
2678
2679
// 7.6 Identifier Names and Identifiers
2680
2681
function isIdentifierStart(ch) {
2682
return (ch === 36) || (ch === 95) || // $ (dollar) and _ (underscore)
2683
(ch >= 65 && ch <= 90) || // A..Z
2684
(ch >= 97 && ch <= 122) || // a..z
2685
(ch === 92) || // \ (backslash)
2686
((ch >= 0x80) && Regex.NonAsciiIdentifierStart.test(String.fromCharCode(ch)));
2687
}
2688
2689
function isIdentifierPart(ch) {
2690
return (ch === 36) || (ch === 95) || // $ (dollar) and _ (underscore)
2691
(ch >= 65 && ch <= 90) || // A..Z
2692
(ch >= 97 && ch <= 122) || // a..z
2693
(ch >= 48 && ch <= 57) || // 0..9
2694
(ch === 92) || // \ (backslash)
2695
((ch >= 0x80) && Regex.NonAsciiIdentifierPart.test(String.fromCharCode(ch)));
2696
}
2697
2698
// 7.6.1.2 Future Reserved Words
2699
2700
function isFutureReservedWord(id) {
2701
switch (id) {
2702
case 'class':
2703
case 'enum':
2704
case 'export':
2705
case 'extends':
2706
case 'import':
2707
case 'super':
2708
return true;
2709
default:
2710
return false;
2711
}
2712
}
2713
2714
function isStrictModeReservedWord(id) {
2715
switch (id) {
2716
case 'implements':
2717
case 'interface':
2718
case 'package':
2719
case 'private':
2720
case 'protected':
2721
case 'public':
2722
case 'static':
2723
case 'yield':
2724
case 'let':
2725
return true;
2726
default:
2727
return false;
2728
}
2729
}
2730
2731
function isRestrictedWord(id) {
2732
return id === 'eval' || id === 'arguments';
2733
}
2734
2735
// 7.6.1.1 Keywords
2736
2737
function isKeyword(id) {
2738
if (strict && isStrictModeReservedWord(id)) {
2739
return true;
2740
}
2741
2742
// 'const' is specialized as Keyword in V8.
2743
// 'yield' is only treated as a keyword in strict mode.
2744
// 'let' is for compatiblity with SpiderMonkey and ES.next.
2745
// Some others are from future reserved words.
2746
2747
switch (id.length) {
2748
case 2:
2749
return (id === 'if') || (id === 'in') || (id === 'do');
2750
case 3:
2751
return (id === 'var') || (id === 'for') || (id === 'new') ||
2752
(id === 'try') || (id === 'let');
2753
case 4:
2754
return (id === 'this') || (id === 'else') || (id === 'case') ||
2755
(id === 'void') || (id === 'with') || (id === 'enum');
2756
case 5:
2757
return (id === 'while') || (id === 'break') || (id === 'catch') ||
2758
(id === 'throw') || (id === 'const') ||
2759
(id === 'class') || (id === 'super');
2760
case 6:
2761
return (id === 'return') || (id === 'typeof') || (id === 'delete') ||
2762
(id === 'switch') || (id === 'export') || (id === 'import');
2763
case 7:
2764
return (id === 'default') || (id === 'finally') || (id === 'extends');
2765
case 8:
2766
return (id === 'function') || (id === 'continue') || (id === 'debugger');
2767
case 10:
2768
return (id === 'instanceof');
2769
default:
2770
return false;
2771
}
2772
}
2773
2774
// 7.4 Comments
2775
2776
function addComment(type, value, start, end, loc) {
2777
var comment;
2778
assert(typeof start === 'number', 'Comment must have valid position');
2779
2780
// Because the way the actual token is scanned, often the comments
2781
// (if any) are skipped twice during the lexical analysis.
2782
// Thus, we need to skip adding a comment if the comment array already
2783
// handled it.
2784
if (state.lastCommentStart >= start) {
2785
return;
2786
}
2787
state.lastCommentStart = start;
2788
2789
comment = {
2790
type: type,
2791
value: value
2792
};
2793
if (extra.range) {
2794
comment.range = [start, end];
2795
}
2796
if (extra.loc) {
2797
comment.loc = loc;
2798
}
2799
extra.comments.push(comment);
2800
if (extra.attachComment) {
2801
extra.leadingComments.push(comment);
2802
extra.trailingComments.push(comment);
2803
}
2804
}
2805
2806
function skipSingleLineComment() {
2807
var start, loc, ch, comment;
2808
2809
start = index - 2;
2810
loc = {
2811
start: {
2812
line: lineNumber,
2813
column: index - lineStart - 2
2814
}
2815
};
2816
2817
while (index < length) {
2818
ch = source.charCodeAt(index);
2819
++index;
2820
if (isLineTerminator(ch)) {
2821
if (extra.comments) {
2822
comment = source.slice(start + 2, index - 1);
2823
loc.end = {
2824
line: lineNumber,
2825
column: index - lineStart - 1
2826
};
2827
addComment('Line', comment, start, index - 1, loc);
2828
}
2829
if (ch === 13 && source.charCodeAt(index) === 10) {
2830
++index;
2831
}
2832
++lineNumber;
2833
lineStart = index;
2834
return;
2835
}
2836
}
2837
2838
if (extra.comments) {
2839
comment = source.slice(start + 2, index);
2840
loc.end = {
2841
line: lineNumber,
2842
column: index - lineStart
2843
};
2844
addComment('Line', comment, start, index, loc);
2845
}
2846
}
2847
2848
function skipMultiLineComment() {
2849
var start, loc, ch, comment;
2850
2851
if (extra.comments) {
2852
start = index - 2;
2853
loc = {
2854
start: {
2855
line: lineNumber,
2856
column: index - lineStart - 2
2857
}
2858
};
2859
}
2860
2861
while (index < length) {
2862
ch = source.charCodeAt(index);
2863
if (isLineTerminator(ch)) {
2864
if (ch === 13 && source.charCodeAt(index + 1) === 10) {
2865
++index;
2866
}
2867
++lineNumber;
2868
++index;
2869
lineStart = index;
2870
if (index >= length) {
2871
throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
2872
}
2873
} else if (ch === 42) {
2874
// Block comment ends with '*/' (char #42, char #47).
2875
if (source.charCodeAt(index + 1) === 47) {
2876
++index;
2877
++index;
2878
if (extra.comments) {
2879
comment = source.slice(start + 2, index - 2);
2880
loc.end = {
2881
line: lineNumber,
2882
column: index - lineStart
2883
};
2884
addComment('Block', comment, start, index, loc);
2885
}
2886
return;
2887
}
2888
++index;
2889
} else {
2890
++index;
2891
}
2892
}
2893
2894
throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
2895
}
2896
2897
function skipComment() {
2898
var ch;
2899
2900
while (index < length) {
2901
ch = source.charCodeAt(index);
2902
2903
if (isWhiteSpace(ch)) {
2904
++index;
2905
} else if (isLineTerminator(ch)) {
2906
++index;
2907
if (ch === 13 && source.charCodeAt(index) === 10) {
2908
++index;
2909
}
2910
++lineNumber;
2911
lineStart = index;
2912
} else if (ch === 47) { // 47 is '/'
2913
ch = source.charCodeAt(index + 1);
2914
if (ch === 47) {
2915
++index;
2916
++index;
2917
skipSingleLineComment();
2918
} else if (ch === 42) { // 42 is '*'
2919
++index;
2920
++index;
2921
skipMultiLineComment();
2922
} else {
2923
break;
2924
}
2925
} else {
2926
break;
2927
}
2928
}
2929
}
2930
2931
function scanHexEscape(prefix) {
2932
var i, len, ch, code = 0;
2933
2934
len = (prefix === 'u') ? 4 : 2;
2935
for (i = 0; i < len; ++i) {
2936
if (index < length && isHexDigit(source[index])) {
2937
ch = source[index++];
2938
code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase());
2939
} else {
2940
return '';
2941
}
2942
}
2943
return String.fromCharCode(code);
2944
}
2945
2946
function scanUnicodeCodePointEscape() {
2947
var ch, code, cu1, cu2;
2948
2949
ch = source[index];
2950
code = 0;
2951
2952
// At least, one hex digit is required.
2953
if (ch === '}') {
2954
throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
2955
}
2956
2957
while (index < length) {
2958
ch = source[index++];
2959
if (!isHexDigit(ch)) {
2960
break;
2961
}
2962
code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase());
2963
}
2964
2965
if (code > 0x10FFFF || ch !== '}') {
2966
throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
2967
}
2968
2969
// UTF-16 Encoding
2970
if (code <= 0xFFFF) {
2971
return String.fromCharCode(code);
2972
}
2973
cu1 = ((code - 0x10000) >> 10) + 0xD800;
2974
cu2 = ((code - 0x10000) & 1023) + 0xDC00;
2975
return String.fromCharCode(cu1, cu2);
2976
}
2977
2978
function getEscapedIdentifier() {
2979
var ch, id;
2980
2981
ch = source.charCodeAt(index++);
2982
id = String.fromCharCode(ch);
2983
2984
// '\u' (char #92, char #117) denotes an escaped character.
2985
if (ch === 92) {
2986
if (source.charCodeAt(index) !== 117) {
2987
throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
2988
}
2989
++index;
2990
ch = scanHexEscape('u');
2991
if (!ch || ch === '\\' || !isIdentifierStart(ch.charCodeAt(0))) {
2992
throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
2993
}
2994
id = ch;
2995
}
2996
2997
while (index < length) {
2998
ch = source.charCodeAt(index);
2999
if (!isIdentifierPart(ch)) {
3000
break;
3001
}
3002
++index;
3003
id += String.fromCharCode(ch);
3004
3005
// '\u' (char #92, char #117) denotes an escaped character.
3006
if (ch === 92) {
3007
id = id.substr(0, id.length - 1);
3008
if (source.charCodeAt(index) !== 117) {
3009
throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
3010
}
3011
++index;
3012
ch = scanHexEscape('u');
3013
if (!ch || ch === '\\' || !isIdentifierPart(ch.charCodeAt(0))) {
3014
throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
3015
}
3016
id += ch;
3017
}
3018
}
3019
3020
return id;
3021
}
3022
3023
function getIdentifier() {
3024
var start, ch;
3025
3026
start = index++;
3027
while (index < length) {
3028
ch = source.charCodeAt(index);
3029
if (ch === 92) {
3030
// Blackslash (char #92) marks Unicode escape sequence.
3031
index = start;
3032
return getEscapedIdentifier();
3033
}
3034
if (isIdentifierPart(ch)) {
3035
++index;
3036
} else {
3037
break;
3038
}
3039
}
3040
3041
return source.slice(start, index);
3042
}
3043
3044
function scanIdentifier() {
3045
var start, id, type;
3046
3047
start = index;
3048
3049
// Backslash (char #92) starts an escaped character.
3050
id = (source.charCodeAt(index) === 92) ? getEscapedIdentifier() : getIdentifier();
3051
3052
// There is no keyword or literal with only one character.
3053
// Thus, it must be an identifier.
3054
if (id.length === 1) {
3055
type = Token.Identifier;
3056
} else if (isKeyword(id)) {
3057
type = Token.Keyword;
3058
} else if (id === 'null') {
3059
type = Token.NullLiteral;
3060
} else if (id === 'true' || id === 'false') {
3061
type = Token.BooleanLiteral;
3062
} else {
3063
type = Token.Identifier;
3064
}
3065
3066
return {
3067
type: type,
3068
value: id,
3069
lineNumber: lineNumber,
3070
lineStart: lineStart,
3071
range: [start, index]
3072
};
3073
}
3074
3075
3076
// 7.7 Punctuators
3077
3078
function scanPunctuator() {
3079
var start = index,
3080
code = source.charCodeAt(index),
3081
code2,
3082
ch1 = source[index],
3083
ch2,
3084
ch3,
3085
ch4;
3086
3087
if (state.inJSXTag || state.inJSXChild) {
3088
// Don't need to check for '{' and '}' as it's already handled
3089
// correctly by default.
3090
switch (code) {
3091
case 60: // <
3092
case 62: // >
3093
++index;
3094
return {
3095
type: Token.Punctuator,
3096
value: String.fromCharCode(code),
3097
lineNumber: lineNumber,
3098
lineStart: lineStart,
3099
range: [start, index]
3100
};
3101
}
3102
}
3103
3104
switch (code) {
3105
// Check for most common single-character punctuators.
3106
case 40: // ( open bracket
3107
case 41: // ) close bracket
3108
case 59: // ; semicolon
3109
case 44: // , comma
3110
case 123: // { open curly brace
3111
case 125: // } close curly brace
3112
case 91: // [
3113
case 93: // ]
3114
case 58: // :
3115
case 63: // ?
3116
case 126: // ~
3117
++index;
3118
if (extra.tokenize) {
3119
if (code === 40) {
3120
extra.openParenToken = extra.tokens.length;
3121
} else if (code === 123) {
3122
extra.openCurlyToken = extra.tokens.length;
3123
}
3124
}
3125
return {
3126
type: Token.Punctuator,
3127
value: String.fromCharCode(code),
3128
lineNumber: lineNumber,
3129
lineStart: lineStart,
3130
range: [start, index]
3131
};
3132
3133
default:
3134
code2 = source.charCodeAt(index + 1);
3135
3136
// '=' (char #61) marks an assignment or comparison operator.
3137
if (code2 === 61) {
3138
switch (code) {
3139
case 37: // %
3140
case 38: // &
3141
case 42: // *:
3142
case 43: // +
3143
case 45: // -
3144
case 47: // /
3145
case 60: // <
3146
case 62: // >
3147
case 94: // ^
3148
case 124: // |
3149
index += 2;
3150
return {
3151
type: Token.Punctuator,
3152
value: String.fromCharCode(code) + String.fromCharCode(code2),
3153
lineNumber: lineNumber,
3154
lineStart: lineStart,
3155
range: [start, index]
3156
};
3157
3158
case 33: // !
3159
case 61: // =
3160
index += 2;
3161
3162
// !== and ===
3163
if (source.charCodeAt(index) === 61) {
3164
++index;
3165
}
3166
return {
3167
type: Token.Punctuator,
3168
value: source.slice(start, index),
3169
lineNumber: lineNumber,
3170
lineStart: lineStart,
3171
range: [start, index]
3172
};
3173
default:
3174
break;
3175
}
3176
}
3177
break;
3178
}
3179
3180
// Peek more characters.
3181
3182
ch2 = source[index + 1];
3183
ch3 = source[index + 2];
3184
ch4 = source[index + 3];
3185
3186
// 4-character punctuator: >>>=
3187
3188
if (ch1 === '>' && ch2 === '>' && ch3 === '>') {
3189
if (ch4 === '=') {
3190
index += 4;
3191
return {
3192
type: Token.Punctuator,
3193
value: '>>>=',
3194
lineNumber: lineNumber,
3195
lineStart: lineStart,
3196
range: [start, index]
3197
};
3198
}
3199
}
3200
3201
// 3-character punctuators: === !== >>> <<= >>=
3202
3203
if (ch1 === '>' && ch2 === '>' && ch3 === '>' && !state.inType) {
3204
index += 3;
3205
return {
3206
type: Token.Punctuator,
3207
value: '>>>',
3208
lineNumber: lineNumber,
3209
lineStart: lineStart,
3210
range: [start, index]
3211
};
3212
}
3213
3214
if (ch1 === '<' && ch2 === '<' && ch3 === '=') {
3215
index += 3;
3216
return {
3217
type: Token.Punctuator,
3218
value: '<<=',
3219
lineNumber: lineNumber,
3220
lineStart: lineStart,
3221
range: [start, index]
3222
};
3223
}
3224
3225
if (ch1 === '>' && ch2 === '>' && ch3 === '=') {
3226
index += 3;
3227
return {
3228
type: Token.Punctuator,
3229
value: '>>=',
3230
lineNumber: lineNumber,
3231
lineStart: lineStart,
3232
range: [start, index]
3233
};
3234
}
3235
3236
if (ch1 === '.' && ch2 === '.' && ch3 === '.') {
3237
index += 3;
3238
return {
3239
type: Token.Punctuator,
3240
value: '...',
3241
lineNumber: lineNumber,
3242
lineStart: lineStart,
3243
range: [start, index]
3244
};
3245
}
3246
3247
// Other 2-character punctuators: ++ -- << >> && ||
3248
3249
// Don't match these tokens if we're in a type, since they never can
3250
// occur and can mess up types like Map<string, Array<string>>
3251
if (ch1 === ch2 && ('+-<>&|'.indexOf(ch1) >= 0) && !state.inType) {
3252
index += 2;
3253
return {
3254
type: Token.Punctuator,
3255
value: ch1 + ch2,
3256
lineNumber: lineNumber,
3257
lineStart: lineStart,
3258
range: [start, index]
3259
};
3260
}
3261
3262
if (ch1 === '=' && ch2 === '>') {
3263
index += 2;
3264
return {
3265
type: Token.Punctuator,
3266
value: '=>',
3267
lineNumber: lineNumber,
3268
lineStart: lineStart,
3269
range: [start, index]
3270
};
3271
}
3272
3273
if ('<>=!+-*%&|^/'.indexOf(ch1) >= 0) {
3274
++index;
3275
return {
3276
type: Token.Punctuator,
3277
value: ch1,
3278
lineNumber: lineNumber,
3279
lineStart: lineStart,
3280
range: [start, index]
3281
};
3282
}
3283
3284
if (ch1 === '.') {
3285
++index;
3286
return {
3287
type: Token.Punctuator,
3288
value: ch1,
3289
lineNumber: lineNumber,
3290
lineStart: lineStart,
3291
range: [start, index]
3292
};
3293
}
3294
3295
throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
3296
}
3297
3298
// 7.8.3 Numeric Literals
3299
3300
function scanHexLiteral(start) {
3301
var number = '';
3302
3303
while (index < length) {
3304
if (!isHexDigit(source[index])) {
3305
break;
3306
}
3307
number += source[index++];
3308
}
3309
3310
if (number.length === 0) {
3311
throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
3312
}
3313
3314
if (isIdentifierStart(source.charCodeAt(index))) {
3315
throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
3316
}
3317
3318
return {
3319
type: Token.NumericLiteral,
3320
value: parseInt('0x' + number, 16),
3321
lineNumber: lineNumber,
3322
lineStart: lineStart,
3323
range: [start, index]
3324
};
3325
}
3326
3327
function scanBinaryLiteral(start) {
3328
var ch, number;
3329
3330
number = '';
3331
3332
while (index < length) {
3333
ch = source[index];
3334
if (ch !== '0' && ch !== '1') {
3335
break;
3336
}
3337
number += source[index++];
3338
}
3339
3340
if (number.length === 0) {
3341
// only 0b or 0B
3342
throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
3343
}
3344
3345
if (index < length) {
3346
ch = source.charCodeAt(index);
3347
/* istanbul ignore else */
3348
if (isIdentifierStart(ch) || isDecimalDigit(ch)) {
3349
throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
3350
}
3351
}
3352
3353
return {
3354
type: Token.NumericLiteral,
3355
value: parseInt(number, 2),
3356
lineNumber: lineNumber,
3357
lineStart: lineStart,
3358
range: [start, index]
3359
};
3360
}
3361
3362
function scanOctalLiteral(prefix, start) {
3363
var number, octal;
3364
3365
if (isOctalDigit(prefix)) {
3366
octal = true;
3367
number = '0' + source[index++];
3368
} else {
3369
octal = false;
3370
++index;
3371
number = '';
3372
}
3373
3374
while (index < length) {
3375
if (!isOctalDigit(source[index])) {
3376
break;
3377
}
3378
number += source[index++];
3379
}
3380
3381
if (!octal && number.length === 0) {
3382
// only 0o or 0O
3383
throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
3384
}
3385
3386
if (isIdentifierStart(source.charCodeAt(index)) || isDecimalDigit(source.charCodeAt(index))) {
3387
throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
3388
}
3389
3390
return {
3391
type: Token.NumericLiteral,
3392
value: parseInt(number, 8),
3393
octal: octal,
3394
lineNumber: lineNumber,
3395
lineStart: lineStart,
3396
range: [start, index]
3397
};
3398
}
3399
3400
function scanNumericLiteral() {
3401
var number, start, ch;
3402
3403
ch = source[index];
3404
assert(isDecimalDigit(ch.charCodeAt(0)) || (ch === '.'),
3405
'Numeric literal must start with a decimal digit or a decimal point');
3406
3407
start = index;
3408
number = '';
3409
if (ch !== '.') {
3410
number = source[index++];
3411
ch = source[index];
3412
3413
// Hex number starts with '0x'.
3414
// Octal number starts with '0'.
3415
// Octal number in ES6 starts with '0o'.
3416
// Binary number in ES6 starts with '0b'.
3417
if (number === '0') {
3418
if (ch === 'x' || ch === 'X') {
3419
++index;
3420
return scanHexLiteral(start);
3421
}
3422
if (ch === 'b' || ch === 'B') {
3423
++index;
3424
return scanBinaryLiteral(start);
3425
}
3426
if (ch === 'o' || ch === 'O' || isOctalDigit(ch)) {
3427
return scanOctalLiteral(ch, start);
3428
}
3429
// decimal number starts with '0' such as '09' is illegal.
3430
if (ch && isDecimalDigit(ch.charCodeAt(0))) {
3431
throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
3432
}
3433
}
3434
3435
while (isDecimalDigit(source.charCodeAt(index))) {
3436
number += source[index++];
3437
}
3438
ch = source[index];
3439
}
3440
3441
if (ch === '.') {
3442
number += source[index++];
3443
while (isDecimalDigit(source.charCodeAt(index))) {
3444
number += source[index++];
3445
}
3446
ch = source[index];
3447
}
3448
3449
if (ch === 'e' || ch === 'E') {
3450
number += source[index++];
3451
3452
ch = source[index];
3453
if (ch === '+' || ch === '-') {
3454
number += source[index++];
3455
}
3456
if (isDecimalDigit(source.charCodeAt(index))) {
3457
while (isDecimalDigit(source.charCodeAt(index))) {
3458
number += source[index++];
3459
}
3460
} else {
3461
throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
3462
}
3463
}
3464
3465
if (isIdentifierStart(source.charCodeAt(index))) {
3466
throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
3467
}
3468
3469
return {
3470
type: Token.NumericLiteral,
3471
value: parseFloat(number),
3472
lineNumber: lineNumber,
3473
lineStart: lineStart,
3474
range: [start, index]
3475
};
3476
}
3477
3478
// 7.8.4 String Literals
3479
3480
function scanStringLiteral() {
3481
var str = '', quote, start, ch, code, unescaped, restore, octal = false;
3482
3483
quote = source[index];
3484
assert((quote === '\'' || quote === '"'),
3485
'String literal must starts with a quote');
3486
3487
start = index;
3488
++index;
3489
3490
while (index < length) {
3491
ch = source[index++];
3492
3493
if (ch === quote) {
3494
quote = '';
3495
break;
3496
} else if (ch === '\\') {
3497
ch = source[index++];
3498
if (!ch || !isLineTerminator(ch.charCodeAt(0))) {
3499
switch (ch) {
3500
case 'n':
3501
str += '\n';
3502
break;
3503
case 'r':
3504
str += '\r';
3505
break;
3506
case 't':
3507
str += '\t';
3508
break;
3509
case 'u':
3510
case 'x':
3511
if (source[index] === '{') {
3512
++index;
3513
str += scanUnicodeCodePointEscape();
3514
} else {
3515
restore = index;
3516
unescaped = scanHexEscape(ch);
3517
if (unescaped) {
3518
str += unescaped;
3519
} else {
3520
index = restore;
3521
str += ch;
3522
}
3523
}
3524
break;
3525
case 'b':
3526
str += '\b';
3527
break;
3528
case 'f':
3529
str += '\f';
3530
break;
3531
case 'v':
3532
str += '\x0B';
3533
break;
3534
3535
default:
3536
if (isOctalDigit(ch)) {
3537
code = '01234567'.indexOf(ch);
3538
3539
// \0 is not octal escape sequence
3540
if (code !== 0) {
3541
octal = true;
3542
}
3543
3544
/* istanbul ignore else */
3545
if (index < length && isOctalDigit(source[index])) {
3546
octal = true;
3547
code = code * 8 + '01234567'.indexOf(source[index++]);
3548
3549
// 3 digits are only allowed when string starts
3550
// with 0, 1, 2, 3
3551
if ('0123'.indexOf(ch) >= 0 &&
3552
index < length &&
3553
isOctalDigit(source[index])) {
3554
code = code * 8 + '01234567'.indexOf(source[index++]);
3555
}
3556
}
3557
str += String.fromCharCode(code);
3558
} else {
3559
str += ch;
3560
}
3561
break;
3562
}
3563
} else {
3564
++lineNumber;
3565
if (ch === '\r' && source[index] === '\n') {
3566
++index;
3567
}
3568
lineStart = index;
3569
}
3570
} else if (isLineTerminator(ch.charCodeAt(0))) {
3571
break;
3572
} else {
3573
str += ch;
3574
}
3575
}
3576
3577
if (quote !== '') {
3578
throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
3579
}
3580
3581
return {
3582
type: Token.StringLiteral,
3583
value: str,
3584
octal: octal,
3585
lineNumber: lineNumber,
3586
lineStart: lineStart,
3587
range: [start, index]
3588
};
3589
}
3590
3591
function scanTemplate() {
3592
var cooked = '', ch, start, terminated, tail, restore, unescaped, code, octal;
3593
3594
terminated = false;
3595
tail = false;
3596
start = index;
3597
3598
++index;
3599
3600
while (index < length) {
3601
ch = source[index++];
3602
if (ch === '`') {
3603
tail = true;
3604
terminated = true;
3605
break;
3606
} else if (ch === '$') {
3607
if (source[index] === '{') {
3608
++index;
3609
terminated = true;
3610
break;
3611
}
3612
cooked += ch;
3613
} else if (ch === '\\') {
3614
ch = source[index++];
3615
if (!isLineTerminator(ch.charCodeAt(0))) {
3616
switch (ch) {
3617
case 'n':
3618
cooked += '\n';
3619
break;
3620
case 'r':
3621
cooked += '\r';
3622
break;
3623
case 't':
3624
cooked += '\t';
3625
break;
3626
case 'u':
3627
case 'x':
3628
if (source[index] === '{') {
3629
++index;
3630
cooked += scanUnicodeCodePointEscape();
3631
} else {
3632
restore = index;
3633
unescaped = scanHexEscape(ch);
3634
if (unescaped) {
3635
cooked += unescaped;
3636
} else {
3637
index = restore;
3638
cooked += ch;
3639
}
3640
}
3641
break;
3642
case 'b':
3643
cooked += '\b';
3644
break;
3645
case 'f':
3646
cooked += '\f';
3647
break;
3648
case 'v':
3649
cooked += '\v';
3650
break;
3651
3652
default:
3653
if (isOctalDigit(ch)) {
3654
code = '01234567'.indexOf(ch);
3655
3656
// \0 is not octal escape sequence
3657
if (code !== 0) {
3658
octal = true;
3659
}
3660
3661
/* istanbul ignore else */
3662
if (index < length && isOctalDigit(source[index])) {
3663
octal = true;
3664
code = code * 8 + '01234567'.indexOf(source[index++]);
3665
3666
// 3 digits are only allowed when string starts
3667
// with 0, 1, 2, 3
3668
if ('0123'.indexOf(ch) >= 0 &&
3669
index < length &&
3670
isOctalDigit(source[index])) {
3671
code = code * 8 + '01234567'.indexOf(source[index++]);
3672
}
3673
}
3674
cooked += String.fromCharCode(code);
3675
} else {
3676
cooked += ch;
3677
}
3678
break;
3679
}
3680
} else {
3681
++lineNumber;
3682
if (ch === '\r' && source[index] === '\n') {
3683
++index;
3684
}
3685
lineStart = index;
3686
}
3687
} else if (isLineTerminator(ch.charCodeAt(0))) {
3688
++lineNumber;
3689
if (ch === '\r' && source[index] === '\n') {
3690
++index;
3691
}
3692
lineStart = index;
3693
cooked += '\n';
3694
} else {
3695
cooked += ch;
3696
}
3697
}
3698
3699
if (!terminated) {
3700
throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
3701
}
3702
3703
return {
3704
type: Token.Template,
3705
value: {
3706
cooked: cooked,
3707
raw: source.slice(start + 1, index - ((tail) ? 1 : 2))
3708
},
3709
tail: tail,
3710
octal: octal,
3711
lineNumber: lineNumber,
3712
lineStart: lineStart,
3713
range: [start, index]
3714
};
3715
}
3716
3717
function scanTemplateElement(option) {
3718
var startsWith, template;
3719
3720
lookahead = null;
3721
skipComment();
3722
3723
startsWith = (option.head) ? '`' : '}';
3724
3725
if (source[index] !== startsWith) {
3726
throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
3727
}
3728
3729
template = scanTemplate();
3730
3731
peek();
3732
3733
return template;
3734
}
3735
3736
function testRegExp(pattern, flags) {
3737
var tmp = pattern,
3738
value;
3739
3740
if (flags.indexOf('u') >= 0) {
3741
// Replace each astral symbol and every Unicode code point
3742
// escape sequence with a single ASCII symbol to avoid throwing on
3743
// regular expressions that are only valid in combination with the
3744
// `/u` flag.
3745
// Note: replacing with the ASCII symbol `x` might cause false
3746
// negatives in unlikely scenarios. For example, `[\u{61}-b]` is a
3747
// perfectly valid pattern that is equivalent to `[a-b]`, but it
3748
// would be replaced by `[x-b]` which throws an error.
3749
tmp = tmp
3750
.replace(/\\u\{([0-9a-fA-F]+)\}/g, function ($0, $1) {
3751
if (parseInt($1, 16) <= 0x10FFFF) {
3752
return 'x';
3753
}
3754
throwError({}, Messages.InvalidRegExp);
3755
})
3756
.replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, 'x');
3757
}
3758
3759
// First, detect invalid regular expressions.
3760
try {
3761
value = new RegExp(tmp);
3762
} catch (e) {
3763
throwError({}, Messages.InvalidRegExp);
3764
}
3765
3766
// Return a regular expression object for this pattern-flag pair, or
3767
// `null` in case the current environment doesn't support the flags it
3768
// uses.
3769
try {
3770
return new RegExp(pattern, flags);
3771
} catch (exception) {
3772
return null;
3773
}
3774
}
3775
3776
function scanRegExpBody() {
3777
var ch, str, classMarker, terminated, body;
3778
3779
ch = source[index];
3780
assert(ch === '/', 'Regular expression literal must start with a slash');
3781
str = source[index++];
3782
3783
classMarker = false;
3784
terminated = false;
3785
while (index < length) {
3786
ch = source[index++];
3787
str += ch;
3788
if (ch === '\\') {
3789
ch = source[index++];
3790
// ECMA-262 7.8.5
3791
if (isLineTerminator(ch.charCodeAt(0))) {
3792
throwError({}, Messages.UnterminatedRegExp);
3793
}
3794
str += ch;
3795
} else if (isLineTerminator(ch.charCodeAt(0))) {
3796
throwError({}, Messages.UnterminatedRegExp);
3797
} else if (classMarker) {
3798
if (ch === ']') {
3799
classMarker = false;
3800
}
3801
} else {
3802
if (ch === '/') {
3803
terminated = true;
3804
break;
3805
} else if (ch === '[') {
3806
classMarker = true;
3807
}
3808
}
3809
}
3810
3811
if (!terminated) {
3812
throwError({}, Messages.UnterminatedRegExp);
3813
}
3814
3815
// Exclude leading and trailing slash.
3816
body = str.substr(1, str.length - 2);
3817
return {
3818
value: body,
3819
literal: str
3820
};
3821
}
3822
3823
function scanRegExpFlags() {
3824
var ch, str, flags, restore;
3825
3826
str = '';
3827
flags = '';
3828
while (index < length) {
3829
ch = source[index];
3830
if (!isIdentifierPart(ch.charCodeAt(0))) {
3831
break;
3832
}
3833
3834
++index;
3835
if (ch === '\\' && index < length) {
3836
ch = source[index];
3837
if (ch === 'u') {
3838
++index;
3839
restore = index;
3840
ch = scanHexEscape('u');
3841
if (ch) {
3842
flags += ch;
3843
for (str += '\\u'; restore < index; ++restore) {
3844
str += source[restore];
3845
}
3846
} else {
3847
index = restore;
3848
flags += 'u';
3849
str += '\\u';
3850
}
3851
throwErrorTolerant({}, Messages.UnexpectedToken, 'ILLEGAL');
3852
} else {
3853
str += '\\';
3854
throwErrorTolerant({}, Messages.UnexpectedToken, 'ILLEGAL');
3855
}
3856
} else {
3857
flags += ch;
3858
str += ch;
3859
}
3860
}
3861
3862
return {
3863
value: flags,
3864
literal: str
3865
};
3866
}
3867
3868
function scanRegExp() {
3869
var start, body, flags, value;
3870
3871
lookahead = null;
3872
skipComment();
3873
start = index;
3874
3875
body = scanRegExpBody();
3876
flags = scanRegExpFlags();
3877
value = testRegExp(body.value, flags.value);
3878
3879
if (extra.tokenize) {
3880
return {
3881
type: Token.RegularExpression,
3882
value: value,
3883
regex: {
3884
pattern: body.value,
3885
flags: flags.value
3886
},
3887
lineNumber: lineNumber,
3888
lineStart: lineStart,
3889
range: [start, index]
3890
};
3891
}
3892
3893
return {
3894
literal: body.literal + flags.literal,
3895
value: value,
3896
regex: {
3897
pattern: body.value,
3898
flags: flags.value
3899
},
3900
range: [start, index]
3901
};
3902
}
3903
3904
function isIdentifierName(token) {
3905
return token.type === Token.Identifier ||
3906
token.type === Token.Keyword ||
3907
token.type === Token.BooleanLiteral ||
3908
token.type === Token.NullLiteral;
3909
}
3910
3911
function advanceSlash() {
3912
var prevToken,
3913
checkToken;
3914
// Using the following algorithm:
3915
// https://github.com/mozilla/sweet.js/wiki/design
3916
prevToken = extra.tokens[extra.tokens.length - 1];
3917
if (!prevToken) {
3918
// Nothing before that: it cannot be a division.
3919
return scanRegExp();
3920
}
3921
if (prevToken.type === 'Punctuator') {
3922
if (prevToken.value === ')') {
3923
checkToken = extra.tokens[extra.openParenToken - 1];
3924
if (checkToken &&
3925
checkToken.type === 'Keyword' &&
3926
(checkToken.value === 'if' ||
3927
checkToken.value === 'while' ||
3928
checkToken.value === 'for' ||
3929
checkToken.value === 'with')) {
3930
return scanRegExp();
3931
}
3932
return scanPunctuator();
3933
}
3934
if (prevToken.value === '}') {
3935
// Dividing a function by anything makes little sense,
3936
// but we have to check for that.
3937
if (extra.tokens[extra.openCurlyToken - 3] &&
3938
extra.tokens[extra.openCurlyToken - 3].type === 'Keyword') {
3939
// Anonymous function.
3940
checkToken = extra.tokens[extra.openCurlyToken - 4];
3941
if (!checkToken) {
3942
return scanPunctuator();
3943
}
3944
} else if (extra.tokens[extra.openCurlyToken - 4] &&
3945
extra.tokens[extra.openCurlyToken - 4].type === 'Keyword') {
3946
// Named function.
3947
checkToken = extra.tokens[extra.openCurlyToken - 5];
3948
if (!checkToken) {
3949
return scanRegExp();
3950
}
3951
} else {
3952
return scanPunctuator();
3953
}
3954
// checkToken determines whether the function is
3955
// a declaration or an expression.
3956
if (FnExprTokens.indexOf(checkToken.value) >= 0) {
3957
// It is an expression.
3958
return scanPunctuator();
3959
}
3960
// It is a declaration.
3961
return scanRegExp();
3962
}
3963
return scanRegExp();
3964
}
3965
if (prevToken.type === 'Keyword' && prevToken.value !== 'this') {
3966
return scanRegExp();
3967
}
3968
return scanPunctuator();
3969
}
3970
3971
function advance() {
3972
var ch;
3973
3974
if (!state.inJSXChild) {
3975
skipComment();
3976
}
3977
3978
if (index >= length) {
3979
return {
3980
type: Token.EOF,
3981
lineNumber: lineNumber,
3982
lineStart: lineStart,
3983
range: [index, index]
3984
};
3985
}
3986
3987
if (state.inJSXChild) {
3988
return advanceJSXChild();
3989
}
3990
3991
ch = source.charCodeAt(index);
3992
3993
// Very common: ( and ) and ;
3994
if (ch === 40 || ch === 41 || ch === 58) {
3995
return scanPunctuator();
3996
}
3997
3998
// String literal starts with single quote (#39) or double quote (#34).
3999
if (ch === 39 || ch === 34) {
4000
if (state.inJSXTag) {
4001
return scanJSXStringLiteral();
4002
}
4003
return scanStringLiteral();
4004
}
4005
4006
if (state.inJSXTag && isJSXIdentifierStart(ch)) {
4007
return scanJSXIdentifier();
4008
}
4009
4010
if (ch === 96) {
4011
return scanTemplate();
4012
}
4013
if (isIdentifierStart(ch)) {
4014
return scanIdentifier();
4015
}
4016
4017
// Dot (.) char #46 can also start a floating-point number, hence the need
4018
// to check the next character.
4019
if (ch === 46) {
4020
if (isDecimalDigit(source.charCodeAt(index + 1))) {
4021
return scanNumericLiteral();
4022
}
4023
return scanPunctuator();
4024
}
4025
4026
if (isDecimalDigit(ch)) {
4027
return scanNumericLiteral();
4028
}
4029
4030
// Slash (/) char #47 can also start a regex.
4031
if (extra.tokenize && ch === 47) {
4032
return advanceSlash();
4033
}
4034
4035
return scanPunctuator();
4036
}
4037
4038
function lex() {
4039
var token;
4040
4041
token = lookahead;
4042
index = token.range[1];
4043
lineNumber = token.lineNumber;
4044
lineStart = token.lineStart;
4045
4046
lookahead = advance();
4047
4048
index = token.range[1];
4049
lineNumber = token.lineNumber;
4050
lineStart = token.lineStart;
4051
4052
return token;
4053
}
4054
4055
function peek() {
4056
var pos, line, start;
4057
4058
pos = index;
4059
line = lineNumber;
4060
start = lineStart;
4061
lookahead = advance();
4062
index = pos;
4063
lineNumber = line;
4064
lineStart = start;
4065
}
4066
4067
function lookahead2() {
4068
var adv, pos, line, start, result;
4069
4070
// If we are collecting the tokens, don't grab the next one yet.
4071
/* istanbul ignore next */
4072
adv = (typeof extra.advance === 'function') ? extra.advance : advance;
4073
4074
pos = index;
4075
line = lineNumber;
4076
start = lineStart;
4077
4078
// Scan for the next immediate token.
4079
/* istanbul ignore if */
4080
if (lookahead === null) {
4081
lookahead = adv();
4082
}
4083
index = lookahead.range[1];
4084
lineNumber = lookahead.lineNumber;
4085
lineStart = lookahead.lineStart;
4086
4087
// Grab the token right after.
4088
result = adv();
4089
index = pos;
4090
lineNumber = line;
4091
lineStart = start;
4092
4093
return result;
4094
}
4095
4096
function rewind(token) {
4097
index = token.range[0];
4098
lineNumber = token.lineNumber;
4099
lineStart = token.lineStart;
4100
lookahead = token;
4101
}
4102
4103
function markerCreate() {
4104
if (!extra.loc && !extra.range) {
4105
return undefined;
4106
}
4107
skipComment();
4108
return {offset: index, line: lineNumber, col: index - lineStart};
4109
}
4110
4111
function markerCreatePreserveWhitespace() {
4112
if (!extra.loc && !extra.range) {
4113
return undefined;
4114
}
4115
return {offset: index, line: lineNumber, col: index - lineStart};
4116
}
4117
4118
function processComment(node) {
4119
var lastChild,
4120
trailingComments,
4121
bottomRight = extra.bottomRightStack,
4122
last = bottomRight[bottomRight.length - 1];
4123
4124
if (node.type === Syntax.Program) {
4125
/* istanbul ignore else */
4126
if (node.body.length > 0) {
4127
return;
4128
}
4129
}
4130
4131
if (extra.trailingComments.length > 0) {
4132
if (extra.trailingComments[0].range[0] >= node.range[1]) {
4133
trailingComments = extra.trailingComments;
4134
extra.trailingComments = [];
4135
} else {
4136
extra.trailingComments.length = 0;
4137
}
4138
} else {
4139
if (last && last.trailingComments && last.trailingComments[0].range[0] >= node.range[1]) {
4140
trailingComments = last.trailingComments;
4141
delete last.trailingComments;
4142
}
4143
}
4144
4145
// Eating the stack.
4146
if (last) {
4147
while (last && last.range[0] >= node.range[0]) {
4148
lastChild = last;
4149
last = bottomRight.pop();
4150
}
4151
}
4152
4153
if (lastChild) {
4154
if (lastChild.leadingComments && lastChild.leadingComments[lastChild.leadingComments.length - 1].range[1] <= node.range[0]) {
4155
node.leadingComments = lastChild.leadingComments;
4156
delete lastChild.leadingComments;
4157
}
4158
} else if (extra.leadingComments.length > 0 && extra.leadingComments[extra.leadingComments.length - 1].range[1] <= node.range[0]) {
4159
node.leadingComments = extra.leadingComments;
4160
extra.leadingComments = [];
4161
}
4162
4163
if (trailingComments) {
4164
node.trailingComments = trailingComments;
4165
}
4166
4167
bottomRight.push(node);
4168
}
4169
4170
function markerApply(marker, node) {
4171
if (extra.range) {
4172
node.range = [marker.offset, index];
4173
}
4174
if (extra.loc) {
4175
node.loc = {
4176
start: {
4177
line: marker.line,
4178
column: marker.col
4179
},
4180
end: {
4181
line: lineNumber,
4182
column: index - lineStart
4183
}
4184
};
4185
node = delegate.postProcess(node);
4186
}
4187
if (extra.attachComment) {
4188
processComment(node);
4189
}
4190
return node;
4191
}
4192
4193
SyntaxTreeDelegate = {
4194
4195
name: 'SyntaxTree',
4196
4197
postProcess: function (node) {
4198
return node;
4199
},
4200
4201
createArrayExpression: function (elements) {
4202
return {
4203
type: Syntax.ArrayExpression,
4204
elements: elements
4205
};
4206
},
4207
4208
createAssignmentExpression: function (operator, left, right) {
4209
return {
4210
type: Syntax.AssignmentExpression,
4211
operator: operator,
4212
left: left,
4213
right: right
4214
};
4215
},
4216
4217
createBinaryExpression: function (operator, left, right) {
4218
var type = (operator === '||' || operator === '&&') ? Syntax.LogicalExpression :
4219
Syntax.BinaryExpression;
4220
return {
4221
type: type,
4222
operator: operator,
4223
left: left,
4224
right: right
4225
};
4226
},
4227
4228
createBlockStatement: function (body) {
4229
return {
4230
type: Syntax.BlockStatement,
4231
body: body
4232
};
4233
},
4234
4235
createBreakStatement: function (label) {
4236
return {
4237
type: Syntax.BreakStatement,
4238
label: label
4239
};
4240
},
4241
4242
createCallExpression: function (callee, args) {
4243
return {
4244
type: Syntax.CallExpression,
4245
callee: callee,
4246
'arguments': args
4247
};
4248
},
4249
4250
createCatchClause: function (param, body) {
4251
return {
4252
type: Syntax.CatchClause,
4253
param: param,
4254
body: body
4255
};
4256
},
4257
4258
createConditionalExpression: function (test, consequent, alternate) {
4259
return {
4260
type: Syntax.ConditionalExpression,
4261
test: test,
4262
consequent: consequent,
4263
alternate: alternate
4264
};
4265
},
4266
4267
createContinueStatement: function (label) {
4268
return {
4269
type: Syntax.ContinueStatement,
4270
label: label
4271
};
4272
},
4273
4274
createDebuggerStatement: function () {
4275
return {
4276
type: Syntax.DebuggerStatement
4277
};
4278
},
4279
4280
createDoWhileStatement: function (body, test) {
4281
return {
4282
type: Syntax.DoWhileStatement,
4283
body: body,
4284
test: test
4285
};
4286
},
4287
4288
createEmptyStatement: function () {
4289
return {
4290
type: Syntax.EmptyStatement
4291
};
4292
},
4293
4294
createExpressionStatement: function (expression) {
4295
return {
4296
type: Syntax.ExpressionStatement,
4297
expression: expression
4298
};
4299
},
4300
4301
createForStatement: function (init, test, update, body) {
4302
return {
4303
type: Syntax.ForStatement,
4304
init: init,
4305
test: test,
4306
update: update,
4307
body: body
4308
};
4309
},
4310
4311
createForInStatement: function (left, right, body) {
4312
return {
4313
type: Syntax.ForInStatement,
4314
left: left,
4315
right: right,
4316
body: body,
4317
each: false
4318
};
4319
},
4320
4321
createForOfStatement: function (left, right, body) {
4322
return {
4323
type: Syntax.ForOfStatement,
4324
left: left,
4325
right: right,
4326
body: body
4327
};
4328
},
4329
4330
createFunctionDeclaration: function (id, params, defaults, body, rest, generator, expression,
4331
isAsync, returnType, typeParameters) {
4332
var funDecl = {
4333
type: Syntax.FunctionDeclaration,
4334
id: id,
4335
params: params,
4336
defaults: defaults,
4337
body: body,
4338
rest: rest,
4339
generator: generator,
4340
expression: expression,
4341
returnType: returnType,
4342
typeParameters: typeParameters
4343
};
4344
4345
if (isAsync) {
4346
funDecl.async = true;
4347
}
4348
4349
return funDecl;
4350
},
4351
4352
createFunctionExpression: function (id, params, defaults, body, rest, generator, expression,
4353
isAsync, returnType, typeParameters) {
4354
var funExpr = {
4355
type: Syntax.FunctionExpression,
4356
id: id,
4357
params: params,
4358
defaults: defaults,
4359
body: body,
4360
rest: rest,
4361
generator: generator,
4362
expression: expression,
4363
returnType: returnType,
4364
typeParameters: typeParameters
4365
};
4366
4367
if (isAsync) {
4368
funExpr.async = true;
4369
}
4370
4371
return funExpr;
4372
},
4373
4374
createIdentifier: function (name) {
4375
return {
4376
type: Syntax.Identifier,
4377
name: name,
4378
// Only here to initialize the shape of the object to ensure
4379
// that the 'typeAnnotation' key is ordered before others that
4380
// are added later (like 'loc' and 'range'). This just helps
4381
// keep the shape of Identifier nodes consistent with everything
4382
// else.
4383
typeAnnotation: undefined,
4384
optional: undefined
4385
};
4386
},
4387
4388
createTypeAnnotation: function (typeAnnotation) {
4389
return {
4390
type: Syntax.TypeAnnotation,
4391
typeAnnotation: typeAnnotation
4392
};
4393
},
4394
4395
createTypeCast: function (expression, typeAnnotation) {
4396
return {
4397
type: Syntax.TypeCastExpression,
4398
expression: expression,
4399
typeAnnotation: typeAnnotation
4400
};
4401
},
4402
4403
createFunctionTypeAnnotation: function (params, returnType, rest, typeParameters) {
4404
return {
4405
type: Syntax.FunctionTypeAnnotation,
4406
params: params,
4407
returnType: returnType,
4408
rest: rest,
4409
typeParameters: typeParameters
4410
};
4411
},
4412
4413
createFunctionTypeParam: function (name, typeAnnotation, optional) {
4414
return {
4415
type: Syntax.FunctionTypeParam,
4416
name: name,
4417
typeAnnotation: typeAnnotation,
4418
optional: optional
4419
};
4420
},
4421
4422
createNullableTypeAnnotation: function (typeAnnotation) {
4423
return {
4424
type: Syntax.NullableTypeAnnotation,
4425
typeAnnotation: typeAnnotation
4426
};
4427
},
4428
4429
createArrayTypeAnnotation: function (elementType) {
4430
return {
4431
type: Syntax.ArrayTypeAnnotation,
4432
elementType: elementType
4433
};
4434
},
4435
4436
createGenericTypeAnnotation: function (id, typeParameters) {
4437
return {
4438
type: Syntax.GenericTypeAnnotation,
4439
id: id,
4440
typeParameters: typeParameters
4441
};
4442
},
4443
4444
createQualifiedTypeIdentifier: function (qualification, id) {
4445
return {
4446
type: Syntax.QualifiedTypeIdentifier,
4447
qualification: qualification,
4448
id: id
4449
};
4450
},
4451
4452
createTypeParameterDeclaration: function (params) {
4453
return {
4454
type: Syntax.TypeParameterDeclaration,
4455
params: params
4456
};
4457
},
4458
4459
createTypeParameterInstantiation: function (params) {
4460
return {
4461
type: Syntax.TypeParameterInstantiation,
4462
params: params
4463
};
4464
},
4465
4466
createAnyTypeAnnotation: function () {
4467
return {
4468
type: Syntax.AnyTypeAnnotation
4469
};
4470
},
4471
4472
createBooleanTypeAnnotation: function () {
4473
return {
4474
type: Syntax.BooleanTypeAnnotation
4475
};
4476
},
4477
4478
createNumberTypeAnnotation: function () {
4479
return {
4480
type: Syntax.NumberTypeAnnotation
4481
};
4482
},
4483
4484
createStringTypeAnnotation: function () {
4485
return {
4486
type: Syntax.StringTypeAnnotation
4487
};
4488
},
4489
4490
createStringLiteralTypeAnnotation: function (token) {
4491
return {
4492
type: Syntax.StringLiteralTypeAnnotation,
4493
value: token.value,
4494
raw: source.slice(token.range[0], token.range[1])
4495
};
4496
},
4497
4498
createVoidTypeAnnotation: function () {
4499
return {
4500
type: Syntax.VoidTypeAnnotation
4501
};
4502
},
4503
4504
createTypeofTypeAnnotation: function (argument) {
4505
return {
4506
type: Syntax.TypeofTypeAnnotation,
4507
argument: argument
4508
};
4509
},
4510
4511
createTupleTypeAnnotation: function (types) {
4512
return {
4513
type: Syntax.TupleTypeAnnotation,
4514
types: types
4515
};
4516
},
4517
4518
createObjectTypeAnnotation: function (properties, indexers, callProperties) {
4519
return {
4520
type: Syntax.ObjectTypeAnnotation,
4521
properties: properties,
4522
indexers: indexers,
4523
callProperties: callProperties
4524
};
4525
},
4526
4527
createObjectTypeIndexer: function (id, key, value, isStatic) {
4528
return {
4529
type: Syntax.ObjectTypeIndexer,
4530
id: id,
4531
key: key,
4532
value: value,
4533
"static": isStatic
4534
};
4535
},
4536
4537
createObjectTypeCallProperty: function (value, isStatic) {
4538
return {
4539
type: Syntax.ObjectTypeCallProperty,
4540
value: value,
4541
"static": isStatic
4542
};
4543
},
4544
4545
createObjectTypeProperty: function (key, value, optional, isStatic) {
4546
return {
4547
type: Syntax.ObjectTypeProperty,
4548
key: key,
4549
value: value,
4550
optional: optional,
4551
"static": isStatic
4552
};
4553
},
4554
4555
createUnionTypeAnnotation: function (types) {
4556
return {
4557
type: Syntax.UnionTypeAnnotation,
4558
types: types
4559
};
4560
},
4561
4562
createIntersectionTypeAnnotation: function (types) {
4563
return {
4564
type: Syntax.IntersectionTypeAnnotation,
4565
types: types
4566
};
4567
},
4568
4569
createTypeAlias: function (id, typeParameters, right) {
4570
return {
4571
type: Syntax.TypeAlias,
4572
id: id,
4573
typeParameters: typeParameters,
4574
right: right
4575
};
4576
},
4577
4578
createInterface: function (id, typeParameters, body, extended) {
4579
return {
4580
type: Syntax.InterfaceDeclaration,
4581
id: id,
4582
typeParameters: typeParameters,
4583
body: body,
4584
"extends": extended
4585
};
4586
},
4587
4588
createInterfaceExtends: function (id, typeParameters) {
4589
return {
4590
type: Syntax.InterfaceExtends,
4591
id: id,
4592
typeParameters: typeParameters
4593
};
4594
},
4595
4596
createDeclareFunction: function (id) {
4597
return {
4598
type: Syntax.DeclareFunction,
4599
id: id
4600
};
4601
},
4602
4603
createDeclareVariable: function (id) {
4604
return {
4605
type: Syntax.DeclareVariable,
4606
id: id
4607
};
4608
},
4609
4610
createDeclareModule: function (id, body) {
4611
return {
4612
type: Syntax.DeclareModule,
4613
id: id,
4614
body: body
4615
};
4616
},
4617
4618
createJSXAttribute: function (name, value) {
4619
return {
4620
type: Syntax.JSXAttribute,
4621
name: name,
4622
value: value || null
4623
};
4624
},
4625
4626
createJSXSpreadAttribute: function (argument) {
4627
return {
4628
type: Syntax.JSXSpreadAttribute,
4629
argument: argument
4630
};
4631
},
4632
4633
createJSXIdentifier: function (name) {
4634
return {
4635
type: Syntax.JSXIdentifier,
4636
name: name
4637
};
4638
},
4639
4640
createJSXNamespacedName: function (namespace, name) {
4641
return {
4642
type: Syntax.JSXNamespacedName,
4643
namespace: namespace,
4644
name: name
4645
};
4646
},
4647
4648
createJSXMemberExpression: function (object, property) {
4649
return {
4650
type: Syntax.JSXMemberExpression,
4651
object: object,
4652
property: property
4653
};
4654
},
4655
4656
createJSXElement: function (openingElement, closingElement, children) {
4657
return {
4658
type: Syntax.JSXElement,
4659
openingElement: openingElement,
4660
closingElement: closingElement,
4661
children: children
4662
};
4663
},
4664
4665
createJSXEmptyExpression: function () {
4666
return {
4667
type: Syntax.JSXEmptyExpression
4668
};
4669
},
4670
4671
createJSXExpressionContainer: function (expression) {
4672
return {
4673
type: Syntax.JSXExpressionContainer,
4674
expression: expression
4675
};
4676
},
4677
4678
createJSXOpeningElement: function (name, attributes, selfClosing) {
4679
return {
4680
type: Syntax.JSXOpeningElement,
4681
name: name,
4682
selfClosing: selfClosing,
4683
attributes: attributes
4684
};
4685
},
4686
4687
createJSXClosingElement: function (name) {
4688
return {
4689
type: Syntax.JSXClosingElement,
4690
name: name
4691
};
4692
},
4693
4694
createIfStatement: function (test, consequent, alternate) {
4695
return {
4696
type: Syntax.IfStatement,
4697
test: test,
4698
consequent: consequent,
4699
alternate: alternate
4700
};
4701
},
4702
4703
createLabeledStatement: function (label, body) {
4704
return {
4705
type: Syntax.LabeledStatement,
4706
label: label,
4707
body: body
4708
};
4709
},
4710
4711
createLiteral: function (token) {
4712
var object = {
4713
type: Syntax.Literal,
4714
value: token.value,
4715
raw: source.slice(token.range[0], token.range[1])
4716
};
4717
if (token.regex) {
4718
object.regex = token.regex;
4719
}
4720
return object;
4721
},
4722
4723
createMemberExpression: function (accessor, object, property) {
4724
return {
4725
type: Syntax.MemberExpression,
4726
computed: accessor === '[',
4727
object: object,
4728
property: property
4729
};
4730
},
4731
4732
createNewExpression: function (callee, args) {
4733
return {
4734
type: Syntax.NewExpression,
4735
callee: callee,
4736
'arguments': args
4737
};
4738
},
4739
4740
createObjectExpression: function (properties) {
4741
return {
4742
type: Syntax.ObjectExpression,
4743
properties: properties
4744
};
4745
},
4746
4747
createPostfixExpression: function (operator, argument) {
4748
return {
4749
type: Syntax.UpdateExpression,
4750
operator: operator,
4751
argument: argument,
4752
prefix: false
4753
};
4754
},
4755
4756
createProgram: function (body) {
4757
return {
4758
type: Syntax.Program,
4759
body: body
4760
};
4761
},
4762
4763
createProperty: function (kind, key, value, method, shorthand, computed) {
4764
return {
4765
type: Syntax.Property,
4766
key: key,
4767
value: value,
4768
kind: kind,
4769
method: method,
4770
shorthand: shorthand,
4771
computed: computed
4772
};
4773
},
4774
4775
createReturnStatement: function (argument) {
4776
return {
4777
type: Syntax.ReturnStatement,
4778
argument: argument
4779
};
4780
},
4781
4782
createSequenceExpression: function (expressions) {
4783
return {
4784
type: Syntax.SequenceExpression,
4785
expressions: expressions
4786
};
4787
},
4788
4789
createSwitchCase: function (test, consequent) {
4790
return {
4791
type: Syntax.SwitchCase,
4792
test: test,
4793
consequent: consequent
4794
};
4795
},
4796
4797
createSwitchStatement: function (discriminant, cases) {
4798
return {
4799
type: Syntax.SwitchStatement,
4800
discriminant: discriminant,
4801
cases: cases
4802
};
4803
},
4804
4805
createThisExpression: function () {
4806
return {
4807
type: Syntax.ThisExpression
4808
};
4809
},
4810
4811
createThrowStatement: function (argument) {
4812
return {
4813
type: Syntax.ThrowStatement,
4814
argument: argument
4815
};
4816
},
4817
4818
createTryStatement: function (block, guardedHandlers, handlers, finalizer) {
4819
return {
4820
type: Syntax.TryStatement,
4821
block: block,
4822
guardedHandlers: guardedHandlers,
4823
handlers: handlers,
4824
finalizer: finalizer
4825
};
4826
},
4827
4828
createUnaryExpression: function (operator, argument) {
4829
if (operator === '++' || operator === '--') {
4830
return {
4831
type: Syntax.UpdateExpression,
4832
operator: operator,
4833
argument: argument,
4834
prefix: true
4835
};
4836
}
4837
return {
4838
type: Syntax.UnaryExpression,
4839
operator: operator,
4840
argument: argument,
4841
prefix: true
4842
};
4843
},
4844
4845
createVariableDeclaration: function (declarations, kind) {
4846
return {
4847
type: Syntax.VariableDeclaration,
4848
declarations: declarations,
4849
kind: kind
4850
};
4851
},
4852
4853
createVariableDeclarator: function (id, init) {
4854
return {
4855
type: Syntax.VariableDeclarator,
4856
id: id,
4857
init: init
4858
};
4859
},
4860
4861
createWhileStatement: function (test, body) {
4862
return {
4863
type: Syntax.WhileStatement,
4864
test: test,
4865
body: body
4866
};
4867
},
4868
4869
createWithStatement: function (object, body) {
4870
return {
4871
type: Syntax.WithStatement,
4872
object: object,
4873
body: body
4874
};
4875
},
4876
4877
createTemplateElement: function (value, tail) {
4878
return {
4879
type: Syntax.TemplateElement,
4880
value: value,
4881
tail: tail
4882
};
4883
},
4884
4885
createTemplateLiteral: function (quasis, expressions) {
4886
return {
4887
type: Syntax.TemplateLiteral,
4888
quasis: quasis,
4889
expressions: expressions
4890
};
4891
},
4892
4893
createSpreadElement: function (argument) {
4894
return {
4895
type: Syntax.SpreadElement,
4896
argument: argument
4897
};
4898
},
4899
4900
createSpreadProperty: function (argument) {
4901
return {
4902
type: Syntax.SpreadProperty,
4903
argument: argument
4904
};
4905
},
4906
4907
createTaggedTemplateExpression: function (tag, quasi) {
4908
return {
4909
type: Syntax.TaggedTemplateExpression,
4910
tag: tag,
4911
quasi: quasi
4912
};
4913
},
4914
4915
createArrowFunctionExpression: function (params, defaults, body, rest, expression, isAsync) {
4916
var arrowExpr = {
4917
type: Syntax.ArrowFunctionExpression,
4918
id: null,
4919
params: params,
4920
defaults: defaults,
4921
body: body,
4922
rest: rest,
4923
generator: false,
4924
expression: expression
4925
};
4926
4927
if (isAsync) {
4928
arrowExpr.async = true;
4929
}
4930
4931
return arrowExpr;
4932
},
4933
4934
createMethodDefinition: function (propertyType, kind, key, value, computed) {
4935
return {
4936
type: Syntax.MethodDefinition,
4937
key: key,
4938
value: value,
4939
kind: kind,
4940
'static': propertyType === ClassPropertyType["static"],
4941
computed: computed
4942
};
4943
},
4944
4945
createClassProperty: function (key, typeAnnotation, computed, isStatic) {
4946
return {
4947
type: Syntax.ClassProperty,
4948
key: key,
4949
typeAnnotation: typeAnnotation,
4950
computed: computed,
4951
"static": isStatic
4952
};
4953
},
4954
4955
createClassBody: function (body) {
4956
return {
4957
type: Syntax.ClassBody,
4958
body: body
4959
};
4960
},
4961
4962
createClassImplements: function (id, typeParameters) {
4963
return {
4964
type: Syntax.ClassImplements,
4965
id: id,
4966
typeParameters: typeParameters
4967
};
4968
},
4969
4970
createClassExpression: function (id, superClass, body, typeParameters, superTypeParameters, implemented) {
4971
return {
4972
type: Syntax.ClassExpression,
4973
id: id,
4974
superClass: superClass,
4975
body: body,
4976
typeParameters: typeParameters,
4977
superTypeParameters: superTypeParameters,
4978
"implements": implemented
4979
};
4980
},
4981
4982
createClassDeclaration: function (id, superClass, body, typeParameters, superTypeParameters, implemented) {
4983
return {
4984
type: Syntax.ClassDeclaration,
4985
id: id,
4986
superClass: superClass,
4987
body: body,
4988
typeParameters: typeParameters,
4989
superTypeParameters: superTypeParameters,
4990
"implements": implemented
4991
};
4992
},
4993
4994
createModuleSpecifier: function (token) {
4995
return {
4996
type: Syntax.ModuleSpecifier,
4997
value: token.value,
4998
raw: source.slice(token.range[0], token.range[1])
4999
};
5000
},
5001
5002
createExportSpecifier: function (id, name) {
5003
return {
5004
type: Syntax.ExportSpecifier,
5005
id: id,
5006
name: name
5007
};
5008
},
5009
5010
createExportBatchSpecifier: function () {
5011
return {
5012
type: Syntax.ExportBatchSpecifier
5013
};
5014
},
5015
5016
createImportDefaultSpecifier: function (id) {
5017
return {
5018
type: Syntax.ImportDefaultSpecifier,
5019
id: id
5020
};
5021
},
5022
5023
createImportNamespaceSpecifier: function (id) {
5024
return {
5025
type: Syntax.ImportNamespaceSpecifier,
5026
id: id
5027
};
5028
},
5029
5030
createExportDeclaration: function (isDefault, declaration, specifiers, src) {
5031
return {
5032
type: Syntax.ExportDeclaration,
5033
'default': !!isDefault,
5034
declaration: declaration,
5035
specifiers: specifiers,
5036
source: src
5037
};
5038
},
5039
5040
createImportSpecifier: function (id, name) {
5041
return {
5042
type: Syntax.ImportSpecifier,
5043
id: id,
5044
name: name
5045
};
5046
},
5047
5048
createImportDeclaration: function (specifiers, src, isType) {
5049
return {
5050
type: Syntax.ImportDeclaration,
5051
specifiers: specifiers,
5052
source: src,
5053
isType: isType
5054
};
5055
},
5056
5057
createYieldExpression: function (argument, dlg) {
5058
return {
5059
type: Syntax.YieldExpression,
5060
argument: argument,
5061
delegate: dlg
5062
};
5063
},
5064
5065
createAwaitExpression: function (argument) {
5066
return {
5067
type: Syntax.AwaitExpression,
5068
argument: argument
5069
};
5070
},
5071
5072
createComprehensionExpression: function (filter, blocks, body) {
5073
return {
5074
type: Syntax.ComprehensionExpression,
5075
filter: filter,
5076
blocks: blocks,
5077
body: body
5078
};
5079
}
5080
5081
};
5082
5083
// Return true if there is a line terminator before the next token.
5084
5085
function peekLineTerminator() {
5086
var pos, line, start, found;
5087
5088
pos = index;
5089
line = lineNumber;
5090
start = lineStart;
5091
skipComment();
5092
found = lineNumber !== line;
5093
index = pos;
5094
lineNumber = line;
5095
lineStart = start;
5096
5097
return found;
5098
}
5099
5100
// Throw an exception
5101
5102
function throwError(token, messageFormat) {
5103
var error,
5104
args = Array.prototype.slice.call(arguments, 2),
5105
msg = messageFormat.replace(
5106
/%(\d)/g,
5107
function (whole, idx) {
5108
assert(idx < args.length, 'Message reference must be in range');
5109
return args[idx];
5110
}
5111
);
5112
5113
if (typeof token.lineNumber === 'number') {
5114
error = new Error('Line ' + token.lineNumber + ': ' + msg);
5115
error.index = token.range[0];
5116
error.lineNumber = token.lineNumber;
5117
error.column = token.range[0] - lineStart + 1;
5118
} else {
5119
error = new Error('Line ' + lineNumber + ': ' + msg);
5120
error.index = index;
5121
error.lineNumber = lineNumber;
5122
error.column = index - lineStart + 1;
5123
}
5124
5125
error.description = msg;
5126
throw error;
5127
}
5128
5129
function throwErrorTolerant() {
5130
try {
5131
throwError.apply(null, arguments);
5132
} catch (e) {
5133
if (extra.errors) {
5134
extra.errors.push(e);
5135
} else {
5136
throw e;
5137
}
5138
}
5139
}
5140
5141
5142
// Throw an exception because of the token.
5143
5144
function throwUnexpected(token) {
5145
if (token.type === Token.EOF) {
5146
throwError(token, Messages.UnexpectedEOS);
5147
}
5148
5149
if (token.type === Token.NumericLiteral) {
5150
throwError(token, Messages.UnexpectedNumber);
5151
}
5152
5153
if (token.type === Token.StringLiteral || token.type === Token.JSXText) {
5154
throwError(token, Messages.UnexpectedString);
5155
}
5156
5157
if (token.type === Token.Identifier) {
5158
throwError(token, Messages.UnexpectedIdentifier);
5159
}
5160
5161
if (token.type === Token.Keyword) {
5162
if (isFutureReservedWord(token.value)) {
5163
throwError(token, Messages.UnexpectedReserved);
5164
} else if (strict && isStrictModeReservedWord(token.value)) {
5165
throwErrorTolerant(token, Messages.StrictReservedWord);
5166
return;
5167
}
5168
throwError(token, Messages.UnexpectedToken, token.value);
5169
}
5170
5171
if (token.type === Token.Template) {
5172
throwError(token, Messages.UnexpectedTemplate, token.value.raw);
5173
}
5174
5175
// BooleanLiteral, NullLiteral, or Punctuator.
5176
throwError(token, Messages.UnexpectedToken, token.value);
5177
}
5178
5179
// Expect the next token to match the specified punctuator.
5180
// If not, an exception will be thrown.
5181
5182
function expect(value) {
5183
var token = lex();
5184
if (token.type !== Token.Punctuator || token.value !== value) {
5185
throwUnexpected(token);
5186
}
5187
}
5188
5189
// Expect the next token to match the specified keyword.
5190
// If not, an exception will be thrown.
5191
5192
function expectKeyword(keyword, contextual) {
5193
var token = lex();
5194
if (token.type !== (contextual ? Token.Identifier : Token.Keyword) ||
5195
token.value !== keyword) {
5196
throwUnexpected(token);
5197
}
5198
}
5199
5200
// Expect the next token to match the specified contextual keyword.
5201
// If not, an exception will be thrown.
5202
5203
function expectContextualKeyword(keyword) {
5204
return expectKeyword(keyword, true);
5205
}
5206
5207
// Return true if the next token matches the specified punctuator.
5208
5209
function match(value) {
5210
return lookahead.type === Token.Punctuator && lookahead.value === value;
5211
}
5212
5213
// Return true if the next token matches the specified keyword
5214
5215
function matchKeyword(keyword, contextual) {
5216
var expectedType = contextual ? Token.Identifier : Token.Keyword;
5217
return lookahead.type === expectedType && lookahead.value === keyword;
5218
}
5219
5220
// Return true if the next token matches the specified contextual keyword
5221
5222
function matchContextualKeyword(keyword) {
5223
return matchKeyword(keyword, true);
5224
}
5225
5226
// Return true if the next token is an assignment operator
5227
5228
function matchAssign() {
5229
var op;
5230
5231
if (lookahead.type !== Token.Punctuator) {
5232
return false;
5233
}
5234
op = lookahead.value;
5235
return op === '=' ||
5236
op === '*=' ||
5237
op === '/=' ||
5238
op === '%=' ||
5239
op === '+=' ||
5240
op === '-=' ||
5241
op === '<<=' ||
5242
op === '>>=' ||
5243
op === '>>>=' ||
5244
op === '&=' ||
5245
op === '^=' ||
5246
op === '|=';
5247
}
5248
5249
// Note that 'yield' is treated as a keyword in strict mode, but a
5250
// contextual keyword (identifier) in non-strict mode, so we need to
5251
// use matchKeyword('yield', false) and matchKeyword('yield', true)
5252
// (i.e. matchContextualKeyword) appropriately.
5253
function matchYield() {
5254
return state.yieldAllowed && matchKeyword('yield', !strict);
5255
}
5256
5257
function matchAsync() {
5258
var backtrackToken = lookahead, matches = false;
5259
5260
if (matchContextualKeyword('async')) {
5261
lex(); // Make sure peekLineTerminator() starts after 'async'.
5262
matches = !peekLineTerminator();
5263
rewind(backtrackToken); // Revert the lex().
5264
}
5265
5266
return matches;
5267
}
5268
5269
function matchAwait() {
5270
return state.awaitAllowed && matchContextualKeyword('await');
5271
}
5272
5273
function consumeSemicolon() {
5274
var line, oldIndex = index, oldLineNumber = lineNumber,
5275
oldLineStart = lineStart, oldLookahead = lookahead;
5276
5277
// Catch the very common case first: immediately a semicolon (char #59).
5278
if (source.charCodeAt(index) === 59) {
5279
lex();
5280
return;
5281
}
5282
5283
line = lineNumber;
5284
skipComment();
5285
if (lineNumber !== line) {
5286
index = oldIndex;
5287
lineNumber = oldLineNumber;
5288
lineStart = oldLineStart;
5289
lookahead = oldLookahead;
5290
return;
5291
}
5292
5293
if (match(';')) {
5294
lex();
5295
return;
5296
}
5297
5298
if (lookahead.type !== Token.EOF && !match('}')) {
5299
throwUnexpected(lookahead);
5300
}
5301
}
5302
5303
// Return true if provided expression is LeftHandSideExpression
5304
5305
function isLeftHandSide(expr) {
5306
return expr.type === Syntax.Identifier || expr.type === Syntax.MemberExpression;
5307
}
5308
5309
function isAssignableLeftHandSide(expr) {
5310
return isLeftHandSide(expr) || expr.type === Syntax.ObjectPattern || expr.type === Syntax.ArrayPattern;
5311
}
5312
5313
// 11.1.4 Array Initialiser
5314
5315
function parseArrayInitialiser() {
5316
var elements = [], blocks = [], filter = null, tmp, possiblecomprehension = true,
5317
marker = markerCreate();
5318
5319
expect('[');
5320
while (!match(']')) {
5321
if (lookahead.value === 'for' &&
5322
lookahead.type === Token.Keyword) {
5323
if (!possiblecomprehension) {
5324
throwError({}, Messages.ComprehensionError);
5325
}
5326
matchKeyword('for');
5327
tmp = parseForStatement({ignoreBody: true});
5328
tmp.of = tmp.type === Syntax.ForOfStatement;
5329
tmp.type = Syntax.ComprehensionBlock;
5330
if (tmp.left.kind) { // can't be let or const
5331
throwError({}, Messages.ComprehensionError);
5332
}
5333
blocks.push(tmp);
5334
} else if (lookahead.value === 'if' &&
5335
lookahead.type === Token.Keyword) {
5336
if (!possiblecomprehension) {
5337
throwError({}, Messages.ComprehensionError);
5338
}
5339
expectKeyword('if');
5340
expect('(');
5341
filter = parseExpression();
5342
expect(')');
5343
} else if (lookahead.value === ',' &&
5344
lookahead.type === Token.Punctuator) {
5345
possiblecomprehension = false; // no longer allowed.
5346
lex();
5347
elements.push(null);
5348
} else {
5349
tmp = parseSpreadOrAssignmentExpression();
5350
elements.push(tmp);
5351
if (tmp && tmp.type === Syntax.SpreadElement) {
5352
if (!match(']')) {
5353
throwError({}, Messages.ElementAfterSpreadElement);
5354
}
5355
} else if (!(match(']') || matchKeyword('for') || matchKeyword('if'))) {
5356
expect(','); // this lexes.
5357
possiblecomprehension = false;
5358
}
5359
}
5360
}
5361
5362
expect(']');
5363
5364
if (filter && !blocks.length) {
5365
throwError({}, Messages.ComprehensionRequiresBlock);
5366
}
5367
5368
if (blocks.length) {
5369
if (elements.length !== 1) {
5370
throwError({}, Messages.ComprehensionError);
5371
}
5372
return markerApply(marker, delegate.createComprehensionExpression(filter, blocks, elements[0]));
5373
}
5374
return markerApply(marker, delegate.createArrayExpression(elements));
5375
}
5376
5377
// 11.1.5 Object Initialiser
5378
5379
function parsePropertyFunction(options) {
5380
var previousStrict, previousYieldAllowed, previousAwaitAllowed,
5381
params, defaults, body, marker = markerCreate();
5382
5383
previousStrict = strict;
5384
previousYieldAllowed = state.yieldAllowed;
5385
state.yieldAllowed = options.generator;
5386
previousAwaitAllowed = state.awaitAllowed;
5387
state.awaitAllowed = options.async;
5388
params = options.params || [];
5389
defaults = options.defaults || [];
5390
5391
body = parseConciseBody();
5392
if (options.name && strict && isRestrictedWord(params[0].name)) {
5393
throwErrorTolerant(options.name, Messages.StrictParamName);
5394
}
5395
strict = previousStrict;
5396
state.yieldAllowed = previousYieldAllowed;
5397
state.awaitAllowed = previousAwaitAllowed;
5398
5399
return markerApply(marker, delegate.createFunctionExpression(
5400
null,
5401
params,
5402
defaults,
5403
body,
5404
options.rest || null,
5405
options.generator,
5406
body.type !== Syntax.BlockStatement,
5407
options.async,
5408
options.returnType,
5409
options.typeParameters
5410
));
5411
}
5412
5413
5414
function parsePropertyMethodFunction(options) {
5415
var previousStrict, tmp, method;
5416
5417
previousStrict = strict;
5418
strict = true;
5419
5420
tmp = parseParams();
5421
5422
if (tmp.stricted) {
5423
throwErrorTolerant(tmp.stricted, tmp.message);
5424
}
5425
5426
method = parsePropertyFunction({
5427
params: tmp.params,
5428
defaults: tmp.defaults,
5429
rest: tmp.rest,
5430
generator: options.generator,
5431
async: options.async,
5432
returnType: tmp.returnType,
5433
typeParameters: options.typeParameters
5434
});
5435
5436
strict = previousStrict;
5437
5438
return method;
5439
}
5440
5441
5442
function parseObjectPropertyKey() {
5443
var marker = markerCreate(),
5444
token = lex(),
5445
propertyKey,
5446
result;
5447
5448
// Note: This function is called only from parseObjectProperty(), where
5449
// EOF and Punctuator tokens are already filtered out.
5450
5451
if (token.type === Token.StringLiteral || token.type === Token.NumericLiteral) {
5452
if (strict && token.octal) {
5453
throwErrorTolerant(token, Messages.StrictOctalLiteral);
5454
}
5455
return markerApply(marker, delegate.createLiteral(token));
5456
}
5457
5458
if (token.type === Token.Punctuator && token.value === '[') {
5459
// For computed properties we should skip the [ and ], and
5460
// capture in marker only the assignment expression itself.
5461
marker = markerCreate();
5462
propertyKey = parseAssignmentExpression();
5463
result = markerApply(marker, propertyKey);
5464
expect(']');
5465
return result;
5466
}
5467
5468
return markerApply(marker, delegate.createIdentifier(token.value));
5469
}
5470
5471
function parseObjectProperty() {
5472
var token, key, id, param, computed,
5473
marker = markerCreate(), returnType, typeParameters;
5474
5475
token = lookahead;
5476
computed = (token.value === '[' && token.type === Token.Punctuator);
5477
5478
if (token.type === Token.Identifier || computed || matchAsync()) {
5479
id = parseObjectPropertyKey();
5480
5481
if (match(':')) {
5482
lex();
5483
5484
return markerApply(
5485
marker,
5486
delegate.createProperty(
5487
'init',
5488
id,
5489
parseAssignmentExpression(),
5490
false,
5491
false,
5492
computed
5493
)
5494
);
5495
}
5496
5497
if (match('(') || match('<')) {
5498
if (match('<')) {
5499
typeParameters = parseTypeParameterDeclaration();
5500
}
5501
return markerApply(
5502
marker,
5503
delegate.createProperty(
5504
'init',
5505
id,
5506
parsePropertyMethodFunction({
5507
generator: false,
5508
async: false,
5509
typeParameters: typeParameters
5510
}),
5511
true,
5512
false,
5513
computed
5514
)
5515
);
5516
}
5517
5518
// Property Assignment: Getter and Setter.
5519
5520
if (token.value === 'get') {
5521
computed = (lookahead.value === '[');
5522
key = parseObjectPropertyKey();
5523
5524
expect('(');
5525
expect(')');
5526
if (match(':')) {
5527
returnType = parseTypeAnnotation();
5528
}
5529
5530
return markerApply(
5531
marker,
5532
delegate.createProperty(
5533
'get',
5534
key,
5535
parsePropertyFunction({
5536
generator: false,
5537
async: false,
5538
returnType: returnType
5539
}),
5540
false,
5541
false,
5542
computed
5543
)
5544
);
5545
}
5546
5547
if (token.value === 'set') {
5548
computed = (lookahead.value === '[');
5549
key = parseObjectPropertyKey();
5550
5551
expect('(');
5552
token = lookahead;
5553
param = [ parseTypeAnnotatableIdentifier() ];
5554
expect(')');
5555
if (match(':')) {
5556
returnType = parseTypeAnnotation();
5557
}
5558
5559
return markerApply(
5560
marker,
5561
delegate.createProperty(
5562
'set',
5563
key,
5564
parsePropertyFunction({
5565
params: param,
5566
generator: false,
5567
async: false,
5568
name: token,
5569
returnType: returnType
5570
}),
5571
false,
5572
false,
5573
computed
5574
)
5575
);
5576
}
5577
5578
if (token.value === 'async') {
5579
computed = (lookahead.value === '[');
5580
key = parseObjectPropertyKey();
5581
5582
if (match('<')) {
5583
typeParameters = parseTypeParameterDeclaration();
5584
}
5585
5586
return markerApply(
5587
marker,
5588
delegate.createProperty(
5589
'init',
5590
key,
5591
parsePropertyMethodFunction({
5592
generator: false,
5593
async: true,
5594
typeParameters: typeParameters
5595
}),
5596
true,
5597
false,
5598
computed
5599
)
5600
);
5601
}
5602
5603
if (computed) {
5604
// Computed properties can only be used with full notation.
5605
throwUnexpected(lookahead);
5606
}
5607
5608
return markerApply(
5609
marker,
5610
delegate.createProperty('init', id, id, false, true, false)
5611
);
5612
}
5613
5614
if (token.type === Token.EOF || token.type === Token.Punctuator) {
5615
if (!match('*')) {
5616
throwUnexpected(token);
5617
}
5618
lex();
5619
5620
computed = (lookahead.type === Token.Punctuator && lookahead.value === '[');
5621
5622
id = parseObjectPropertyKey();
5623
5624
if (match('<')) {
5625
typeParameters = parseTypeParameterDeclaration();
5626
}
5627
5628
if (!match('(')) {
5629
throwUnexpected(lex());
5630
}
5631
5632
return markerApply(marker, delegate.createProperty(
5633
'init',
5634
id,
5635
parsePropertyMethodFunction({
5636
generator: true,
5637
typeParameters: typeParameters
5638
}),
5639
true,
5640
false,
5641
computed
5642
));
5643
}
5644
key = parseObjectPropertyKey();
5645
if (match(':')) {
5646
lex();
5647
return markerApply(marker, delegate.createProperty('init', key, parseAssignmentExpression(), false, false, false));
5648
}
5649
if (match('(') || match('<')) {
5650
if (match('<')) {
5651
typeParameters = parseTypeParameterDeclaration();
5652
}
5653
return markerApply(marker, delegate.createProperty(
5654
'init',
5655
key,
5656
parsePropertyMethodFunction({
5657
generator: false,
5658
typeParameters: typeParameters
5659
}),
5660
true,
5661
false,
5662
false
5663
));
5664
}
5665
throwUnexpected(lex());
5666
}
5667
5668
function parseObjectSpreadProperty() {
5669
var marker = markerCreate();
5670
expect('...');
5671
return markerApply(marker, delegate.createSpreadProperty(parseAssignmentExpression()));
5672
}
5673
5674
function getFieldName(key) {
5675
var toString = String;
5676
if (key.type === Syntax.Identifier) {
5677
return key.name;
5678
}
5679
return toString(key.value);
5680
}
5681
5682
function parseObjectInitialiser() {
5683
var properties = [], property, name, kind, storedKind, map = new StringMap(),
5684
marker = markerCreate(), toString = String;
5685
5686
expect('{');
5687
5688
while (!match('}')) {
5689
if (match('...')) {
5690
property = parseObjectSpreadProperty();
5691
} else {
5692
property = parseObjectProperty();
5693
5694
if (property.key.type === Syntax.Identifier) {
5695
name = property.key.name;
5696
} else {
5697
name = toString(property.key.value);
5698
}
5699
kind = (property.kind === 'init') ? PropertyKind.Data : (property.kind === 'get') ? PropertyKind.Get : PropertyKind.Set;
5700
5701
if (map.has(name)) {
5702
storedKind = map.get(name);
5703
if (storedKind === PropertyKind.Data) {
5704
if (strict && kind === PropertyKind.Data) {
5705
throwErrorTolerant({}, Messages.StrictDuplicateProperty);
5706
} else if (kind !== PropertyKind.Data) {
5707
throwErrorTolerant({}, Messages.AccessorDataProperty);
5708
}
5709
} else {
5710
if (kind === PropertyKind.Data) {
5711
throwErrorTolerant({}, Messages.AccessorDataProperty);
5712
} else if (storedKind & kind) {
5713
throwErrorTolerant({}, Messages.AccessorGetSet);
5714
}
5715
}
5716
map.set(name, storedKind | kind);
5717
} else {
5718
map.set(name, kind);
5719
}
5720
}
5721
5722
properties.push(property);
5723
5724
if (!match('}')) {
5725
expect(',');
5726
}
5727
}
5728
5729
expect('}');
5730
5731
return markerApply(marker, delegate.createObjectExpression(properties));
5732
}
5733
5734
function parseTemplateElement(option) {
5735
var marker = markerCreate(),
5736
token = scanTemplateElement(option);
5737
if (strict && token.octal) {
5738
throwError(token, Messages.StrictOctalLiteral);
5739
}
5740
return markerApply(marker, delegate.createTemplateElement({ raw: token.value.raw, cooked: token.value.cooked }, token.tail));
5741
}
5742
5743
function parseTemplateLiteral() {
5744
var quasi, quasis, expressions, marker = markerCreate();
5745
5746
quasi = parseTemplateElement({ head: true });
5747
quasis = [ quasi ];
5748
expressions = [];
5749
5750
while (!quasi.tail) {
5751
expressions.push(parseExpression());
5752
quasi = parseTemplateElement({ head: false });
5753
quasis.push(quasi);
5754
}
5755
5756
return markerApply(marker, delegate.createTemplateLiteral(quasis, expressions));
5757
}
5758
5759
// 11.1.6 The Grouping Operator
5760
5761
function parseGroupExpression() {
5762
var expr, marker, typeAnnotation;
5763
5764
expect('(');
5765
5766
++state.parenthesizedCount;
5767
5768
marker = markerCreate();
5769
5770
expr = parseExpression();
5771
5772
if (match(':')) {
5773
typeAnnotation = parseTypeAnnotation();
5774
expr = markerApply(marker, delegate.createTypeCast(
5775
expr,
5776
typeAnnotation
5777
));
5778
}
5779
5780
expect(')');
5781
5782
return expr;
5783
}
5784
5785
function matchAsyncFuncExprOrDecl() {
5786
var token;
5787
5788
if (matchAsync()) {
5789
token = lookahead2();
5790
if (token.type === Token.Keyword && token.value === 'function') {
5791
return true;
5792
}
5793
}
5794
5795
return false;
5796
}
5797
5798
// 11.1 Primary Expressions
5799
5800
function parsePrimaryExpression() {
5801
var marker, type, token, expr;
5802
5803
type = lookahead.type;
5804
5805
if (type === Token.Identifier) {
5806
marker = markerCreate();
5807
return markerApply(marker, delegate.createIdentifier(lex().value));
5808
}
5809
5810
if (type === Token.StringLiteral || type === Token.NumericLiteral) {
5811
if (strict && lookahead.octal) {
5812
throwErrorTolerant(lookahead, Messages.StrictOctalLiteral);
5813
}
5814
marker = markerCreate();
5815
return markerApply(marker, delegate.createLiteral(lex()));
5816
}
5817
5818
if (type === Token.Keyword) {
5819
if (matchKeyword('this')) {
5820
marker = markerCreate();
5821
lex();
5822
return markerApply(marker, delegate.createThisExpression());
5823
}
5824
5825
if (matchKeyword('function')) {
5826
return parseFunctionExpression();
5827
}
5828
5829
if (matchKeyword('class')) {
5830
return parseClassExpression();
5831
}
5832
5833
if (matchKeyword('super')) {
5834
marker = markerCreate();
5835
lex();
5836
return markerApply(marker, delegate.createIdentifier('super'));
5837
}
5838
}
5839
5840
if (type === Token.BooleanLiteral) {
5841
marker = markerCreate();
5842
token = lex();
5843
token.value = (token.value === 'true');
5844
return markerApply(marker, delegate.createLiteral(token));
5845
}
5846
5847
if (type === Token.NullLiteral) {
5848
marker = markerCreate();
5849
token = lex();
5850
token.value = null;
5851
return markerApply(marker, delegate.createLiteral(token));
5852
}
5853
5854
if (match('[')) {
5855
return parseArrayInitialiser();
5856
}
5857
5858
if (match('{')) {
5859
return parseObjectInitialiser();
5860
}
5861
5862
if (match('(')) {
5863
return parseGroupExpression();
5864
}
5865
5866
if (match('/') || match('/=')) {
5867
marker = markerCreate();
5868
expr = delegate.createLiteral(scanRegExp());
5869
peek();
5870
return markerApply(marker, expr);
5871
}
5872
5873
if (type === Token.Template) {
5874
return parseTemplateLiteral();
5875
}
5876
5877
if (match('<')) {
5878
return parseJSXElement();
5879
}
5880
5881
throwUnexpected(lex());
5882
}
5883
5884
// 11.2 Left-Hand-Side Expressions
5885
5886
function parseArguments() {
5887
var args = [], arg;
5888
5889
expect('(');
5890
5891
if (!match(')')) {
5892
while (index < length) {
5893
arg = parseSpreadOrAssignmentExpression();
5894
args.push(arg);
5895
5896
if (match(')')) {
5897
break;
5898
} else if (arg.type === Syntax.SpreadElement) {
5899
throwError({}, Messages.ElementAfterSpreadElement);
5900
}
5901
5902
expect(',');
5903
}
5904
}
5905
5906
expect(')');
5907
5908
return args;
5909
}
5910
5911
function parseSpreadOrAssignmentExpression() {
5912
if (match('...')) {
5913
var marker = markerCreate();
5914
lex();
5915
return markerApply(marker, delegate.createSpreadElement(parseAssignmentExpression()));
5916
}
5917
return parseAssignmentExpression();
5918
}
5919
5920
function parseNonComputedProperty() {
5921
var marker = markerCreate(),
5922
token = lex();
5923
5924
if (!isIdentifierName(token)) {
5925
throwUnexpected(token);
5926
}
5927
5928
return markerApply(marker, delegate.createIdentifier(token.value));
5929
}
5930
5931
function parseNonComputedMember() {
5932
expect('.');
5933
5934
return parseNonComputedProperty();
5935
}
5936
5937
function parseComputedMember() {
5938
var expr;
5939
5940
expect('[');
5941
5942
expr = parseExpression();
5943
5944
expect(']');
5945
5946
return expr;
5947
}
5948
5949
function parseNewExpression() {
5950
var callee, args, marker = markerCreate();
5951
5952
expectKeyword('new');
5953
callee = parseLeftHandSideExpression();
5954
args = match('(') ? parseArguments() : [];
5955
5956
return markerApply(marker, delegate.createNewExpression(callee, args));
5957
}
5958
5959
function parseLeftHandSideExpressionAllowCall() {
5960
var expr, args, marker = markerCreate();
5961
5962
expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();
5963
5964
while (match('.') || match('[') || match('(') || lookahead.type === Token.Template) {
5965
if (match('(')) {
5966
args = parseArguments();
5967
expr = markerApply(marker, delegate.createCallExpression(expr, args));
5968
} else if (match('[')) {
5969
expr = markerApply(marker, delegate.createMemberExpression('[', expr, parseComputedMember()));
5970
} else if (match('.')) {
5971
expr = markerApply(marker, delegate.createMemberExpression('.', expr, parseNonComputedMember()));
5972
} else {
5973
expr = markerApply(marker, delegate.createTaggedTemplateExpression(expr, parseTemplateLiteral()));
5974
}
5975
}
5976
5977
return expr;
5978
}
5979
5980
function parseLeftHandSideExpression() {
5981
var expr, marker = markerCreate();
5982
5983
expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();
5984
5985
while (match('.') || match('[') || lookahead.type === Token.Template) {
5986
if (match('[')) {
5987
expr = markerApply(marker, delegate.createMemberExpression('[', expr, parseComputedMember()));
5988
} else if (match('.')) {
5989
expr = markerApply(marker, delegate.createMemberExpression('.', expr, parseNonComputedMember()));
5990
} else {
5991
expr = markerApply(marker, delegate.createTaggedTemplateExpression(expr, parseTemplateLiteral()));
5992
}
5993
}
5994
5995
return expr;
5996
}
5997
5998
// 11.3 Postfix Expressions
5999
6000
function parsePostfixExpression() {
6001
var marker = markerCreate(),
6002
expr = parseLeftHandSideExpressionAllowCall(),
6003
token;
6004
6005
if (lookahead.type !== Token.Punctuator) {
6006
return expr;
6007
}
6008
6009
if ((match('++') || match('--')) && !peekLineTerminator()) {
6010
// 11.3.1, 11.3.2
6011
if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {
6012
throwErrorTolerant({}, Messages.StrictLHSPostfix);
6013
}
6014
6015
if (!isLeftHandSide(expr)) {
6016
throwError({}, Messages.InvalidLHSInAssignment);
6017
}
6018
6019
token = lex();
6020
expr = markerApply(marker, delegate.createPostfixExpression(token.value, expr));
6021
}
6022
6023
return expr;
6024
}
6025
6026
// 11.4 Unary Operators
6027
6028
function parseUnaryExpression() {
6029
var marker, token, expr;
6030
6031
if (lookahead.type !== Token.Punctuator && lookahead.type !== Token.Keyword) {
6032
return parsePostfixExpression();
6033
}
6034
6035
if (match('++') || match('--')) {
6036
marker = markerCreate();
6037
token = lex();
6038
expr = parseUnaryExpression();
6039
// 11.4.4, 11.4.5
6040
if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {
6041
throwErrorTolerant({}, Messages.StrictLHSPrefix);
6042
}
6043
6044
if (!isLeftHandSide(expr)) {
6045
throwError({}, Messages.InvalidLHSInAssignment);
6046
}
6047
6048
return markerApply(marker, delegate.createUnaryExpression(token.value, expr));
6049
}
6050
6051
if (match('+') || match('-') || match('~') || match('!')) {
6052
marker = markerCreate();
6053
token = lex();
6054
expr = parseUnaryExpression();
6055
return markerApply(marker, delegate.createUnaryExpression(token.value, expr));
6056
}
6057
6058
if (matchKeyword('delete') || matchKeyword('void') || matchKeyword('typeof')) {
6059
marker = markerCreate();
6060
token = lex();
6061
expr = parseUnaryExpression();
6062
expr = markerApply(marker, delegate.createUnaryExpression(token.value, expr));
6063
if (strict && expr.operator === 'delete' && expr.argument.type === Syntax.Identifier) {
6064
throwErrorTolerant({}, Messages.StrictDelete);
6065
}
6066
return expr;
6067
}
6068
6069
return parsePostfixExpression();
6070
}
6071
6072
function binaryPrecedence(token, allowIn) {
6073
var prec = 0;
6074
6075
if (token.type !== Token.Punctuator && token.type !== Token.Keyword) {
6076
return 0;
6077
}
6078
6079
switch (token.value) {
6080
case '||':
6081
prec = 1;
6082
break;
6083
6084
case '&&':
6085
prec = 2;
6086
break;
6087
6088
case '|':
6089
prec = 3;
6090
break;
6091
6092
case '^':
6093
prec = 4;
6094
break;
6095
6096
case '&':
6097
prec = 5;
6098
break;
6099
6100
case '==':
6101
case '!=':
6102
case '===':
6103
case '!==':
6104
prec = 6;
6105
break;
6106
6107
case '<':
6108
case '>':
6109
case '<=':
6110
case '>=':
6111
case 'instanceof':
6112
prec = 7;
6113
break;
6114
6115
case 'in':
6116
prec = allowIn ? 7 : 0;
6117
break;
6118
6119
case '<<':
6120
case '>>':
6121
case '>>>':
6122
prec = 8;
6123
break;
6124
6125
case '+':
6126
case '-':
6127
prec = 9;
6128
break;
6129
6130
case '*':
6131
case '/':
6132
case '%':
6133
prec = 11;
6134
break;
6135
6136
default:
6137
break;
6138
}
6139
6140
return prec;
6141
}
6142
6143
// 11.5 Multiplicative Operators
6144
// 11.6 Additive Operators
6145
// 11.7 Bitwise Shift Operators
6146
// 11.8 Relational Operators
6147
// 11.9 Equality Operators
6148
// 11.10 Binary Bitwise Operators
6149
// 11.11 Binary Logical Operators
6150
6151
function parseBinaryExpression() {
6152
var expr, token, prec, previousAllowIn, stack, right, operator, left, i,
6153
marker, markers;
6154
6155
previousAllowIn = state.allowIn;
6156
state.allowIn = true;
6157
6158
marker = markerCreate();
6159
left = parseUnaryExpression();
6160
6161
token = lookahead;
6162
prec = binaryPrecedence(token, previousAllowIn);
6163
if (prec === 0) {
6164
return left;
6165
}
6166
token.prec = prec;
6167
lex();
6168
6169
markers = [marker, markerCreate()];
6170
right = parseUnaryExpression();
6171
6172
stack = [left, token, right];
6173
6174
while ((prec = binaryPrecedence(lookahead, previousAllowIn)) > 0) {
6175
6176
// Reduce: make a binary expression from the three topmost entries.
6177
while ((stack.length > 2) && (prec <= stack[stack.length - 2].prec)) {
6178
right = stack.pop();
6179
operator = stack.pop().value;
6180
left = stack.pop();
6181
expr = delegate.createBinaryExpression(operator, left, right);
6182
markers.pop();
6183
marker = markers.pop();
6184
markerApply(marker, expr);
6185
stack.push(expr);
6186
markers.push(marker);
6187
}
6188
6189
// Shift.
6190
token = lex();
6191
token.prec = prec;
6192
stack.push(token);
6193
markers.push(markerCreate());
6194
expr = parseUnaryExpression();
6195
stack.push(expr);
6196
}
6197
6198
state.allowIn = previousAllowIn;
6199
6200
// Final reduce to clean-up the stack.
6201
i = stack.length - 1;
6202
expr = stack[i];
6203
markers.pop();
6204
while (i > 1) {
6205
expr = delegate.createBinaryExpression(stack[i - 1].value, stack[i - 2], expr);
6206
i -= 2;
6207
marker = markers.pop();
6208
markerApply(marker, expr);
6209
}
6210
6211
return expr;
6212
}
6213
6214
6215
// 11.12 Conditional Operator
6216
6217
function parseConditionalExpression() {
6218
var expr, previousAllowIn, consequent, alternate, marker = markerCreate();
6219
expr = parseBinaryExpression();
6220
6221
if (match('?')) {
6222
lex();
6223
previousAllowIn = state.allowIn;
6224
state.allowIn = true;
6225
consequent = parseAssignmentExpression();
6226
state.allowIn = previousAllowIn;
6227
expect(':');
6228
alternate = parseAssignmentExpression();
6229
6230
expr = markerApply(marker, delegate.createConditionalExpression(expr, consequent, alternate));
6231
}
6232
6233
return expr;
6234
}
6235
6236
// 11.13 Assignment Operators
6237
6238
// 12.14.5 AssignmentPattern
6239
6240
function reinterpretAsAssignmentBindingPattern(expr) {
6241
var i, len, property, element;
6242
6243
if (expr.type === Syntax.ObjectExpression) {
6244
expr.type = Syntax.ObjectPattern;
6245
for (i = 0, len = expr.properties.length; i < len; i += 1) {
6246
property = expr.properties[i];
6247
if (property.type === Syntax.SpreadProperty) {
6248
if (i < len - 1) {
6249
throwError({}, Messages.PropertyAfterSpreadProperty);
6250
}
6251
reinterpretAsAssignmentBindingPattern(property.argument);
6252
} else {
6253
if (property.kind !== 'init') {
6254
throwError({}, Messages.InvalidLHSInAssignment);
6255
}
6256
reinterpretAsAssignmentBindingPattern(property.value);
6257
}
6258
}
6259
} else if (expr.type === Syntax.ArrayExpression) {
6260
expr.type = Syntax.ArrayPattern;
6261
for (i = 0, len = expr.elements.length; i < len; i += 1) {
6262
element = expr.elements[i];
6263
/* istanbul ignore else */
6264
if (element) {
6265
reinterpretAsAssignmentBindingPattern(element);
6266
}
6267
}
6268
} else if (expr.type === Syntax.Identifier) {
6269
if (isRestrictedWord(expr.name)) {
6270
throwError({}, Messages.InvalidLHSInAssignment);
6271
}
6272
} else if (expr.type === Syntax.SpreadElement) {
6273
reinterpretAsAssignmentBindingPattern(expr.argument);
6274
if (expr.argument.type === Syntax.ObjectPattern) {
6275
throwError({}, Messages.ObjectPatternAsSpread);
6276
}
6277
} else {
6278
/* istanbul ignore else */
6279
if (expr.type !== Syntax.MemberExpression && expr.type !== Syntax.CallExpression && expr.type !== Syntax.NewExpression) {
6280
throwError({}, Messages.InvalidLHSInAssignment);
6281
}
6282
}
6283
}
6284
6285
// 13.2.3 BindingPattern
6286
6287
function reinterpretAsDestructuredParameter(options, expr) {
6288
var i, len, property, element;
6289
6290
if (expr.type === Syntax.ObjectExpression) {
6291
expr.type = Syntax.ObjectPattern;
6292
for (i = 0, len = expr.properties.length; i < len; i += 1) {
6293
property = expr.properties[i];
6294
if (property.type === Syntax.SpreadProperty) {
6295
if (i < len - 1) {
6296
throwError({}, Messages.PropertyAfterSpreadProperty);
6297
}
6298
reinterpretAsDestructuredParameter(options, property.argument);
6299
} else {
6300
if (property.kind !== 'init') {
6301
throwError({}, Messages.InvalidLHSInFormalsList);
6302
}
6303
reinterpretAsDestructuredParameter(options, property.value);
6304
}
6305
}
6306
} else if (expr.type === Syntax.ArrayExpression) {
6307
expr.type = Syntax.ArrayPattern;
6308
for (i = 0, len = expr.elements.length; i < len; i += 1) {
6309
element = expr.elements[i];
6310
if (element) {
6311
reinterpretAsDestructuredParameter(options, element);
6312
}
6313
}
6314
} else if (expr.type === Syntax.Identifier) {
6315
validateParam(options, expr, expr.name);
6316
} else if (expr.type === Syntax.SpreadElement) {
6317
// BindingRestElement only allows BindingIdentifier
6318
if (expr.argument.type !== Syntax.Identifier) {
6319
throwError({}, Messages.InvalidLHSInFormalsList);
6320
}
6321
validateParam(options, expr.argument, expr.argument.name);
6322
} else {
6323
throwError({}, Messages.InvalidLHSInFormalsList);
6324
}
6325
}
6326
6327
function reinterpretAsCoverFormalsList(expressions) {
6328
var i, len, param, params, defaults, defaultCount, options, rest;
6329
6330
params = [];
6331
defaults = [];
6332
defaultCount = 0;
6333
rest = null;
6334
options = {
6335
paramSet: new StringMap()
6336
};
6337
6338
for (i = 0, len = expressions.length; i < len; i += 1) {
6339
param = expressions[i];
6340
if (param.type === Syntax.Identifier) {
6341
params.push(param);
6342
defaults.push(null);
6343
validateParam(options, param, param.name);
6344
} else if (param.type === Syntax.ObjectExpression || param.type === Syntax.ArrayExpression) {
6345
reinterpretAsDestructuredParameter(options, param);
6346
params.push(param);
6347
defaults.push(null);
6348
} else if (param.type === Syntax.SpreadElement) {
6349
assert(i === len - 1, 'It is guaranteed that SpreadElement is last element by parseExpression');
6350
if (param.argument.type !== Syntax.Identifier) {
6351
throwError({}, Messages.InvalidLHSInFormalsList);
6352
}
6353
reinterpretAsDestructuredParameter(options, param.argument);
6354
rest = param.argument;
6355
} else if (param.type === Syntax.AssignmentExpression) {
6356
params.push(param.left);
6357
defaults.push(param.right);
6358
++defaultCount;
6359
validateParam(options, param.left, param.left.name);
6360
} else {
6361
return null;
6362
}
6363
}
6364
6365
if (options.message === Messages.StrictParamDupe) {
6366
throwError(
6367
strict ? options.stricted : options.firstRestricted,
6368
options.message
6369
);
6370
}
6371
6372
if (defaultCount === 0) {
6373
defaults = [];
6374
}
6375
6376
return {
6377
params: params,
6378
defaults: defaults,
6379
rest: rest,
6380
stricted: options.stricted,
6381
firstRestricted: options.firstRestricted,
6382
message: options.message
6383
};
6384
}
6385
6386
function parseArrowFunctionExpression(options, marker) {
6387
var previousStrict, previousYieldAllowed, previousAwaitAllowed, body;
6388
6389
expect('=>');
6390
6391
previousStrict = strict;
6392
previousYieldAllowed = state.yieldAllowed;
6393
state.yieldAllowed = false;
6394
previousAwaitAllowed = state.awaitAllowed;
6395
state.awaitAllowed = !!options.async;
6396
body = parseConciseBody();
6397
6398
if (strict && options.firstRestricted) {
6399
throwError(options.firstRestricted, options.message);
6400
}
6401
if (strict && options.stricted) {
6402
throwErrorTolerant(options.stricted, options.message);
6403
}
6404
6405
strict = previousStrict;
6406
state.yieldAllowed = previousYieldAllowed;
6407
state.awaitAllowed = previousAwaitAllowed;
6408
6409
return markerApply(marker, delegate.createArrowFunctionExpression(
6410
options.params,
6411
options.defaults,
6412
body,
6413
options.rest,
6414
body.type !== Syntax.BlockStatement,
6415
!!options.async
6416
));
6417
}
6418
6419
function parseAssignmentExpression() {
6420
var marker, expr, token, params, oldParenthesizedCount,
6421
startsWithParen = false, backtrackToken = lookahead,
6422
possiblyAsync = false;
6423
6424
if (matchYield()) {
6425
return parseYieldExpression();
6426
}
6427
6428
if (matchAwait()) {
6429
return parseAwaitExpression();
6430
}
6431
6432
oldParenthesizedCount = state.parenthesizedCount;
6433
6434
marker = markerCreate();
6435
6436
if (matchAsyncFuncExprOrDecl()) {
6437
return parseFunctionExpression();
6438
}
6439
6440
if (matchAsync()) {
6441
// We can't be completely sure that this 'async' token is
6442
// actually a contextual keyword modifying a function
6443
// expression, so we might have to un-lex() it later by
6444
// calling rewind(backtrackToken).
6445
possiblyAsync = true;
6446
lex();
6447
}
6448
6449
if (match('(')) {
6450
token = lookahead2();
6451
if ((token.type === Token.Punctuator && token.value === ')') || token.value === '...') {
6452
params = parseParams();
6453
if (!match('=>')) {
6454
throwUnexpected(lex());
6455
}
6456
params.async = possiblyAsync;
6457
return parseArrowFunctionExpression(params, marker);
6458
}
6459
startsWithParen = true;
6460
}
6461
6462
token = lookahead;
6463
6464
// If the 'async' keyword is not followed by a '(' character or an
6465
// identifier, then it can't be an arrow function modifier, and we
6466
// should interpret it as a normal identifer.
6467
if (possiblyAsync && !match('(') && token.type !== Token.Identifier) {
6468
possiblyAsync = false;
6469
rewind(backtrackToken);
6470
}
6471
6472
expr = parseConditionalExpression();
6473
6474
if (match('=>') &&
6475
(state.parenthesizedCount === oldParenthesizedCount ||
6476
state.parenthesizedCount === (oldParenthesizedCount + 1))) {
6477
if (expr.type === Syntax.Identifier) {
6478
params = reinterpretAsCoverFormalsList([ expr ]);
6479
} else if (expr.type === Syntax.AssignmentExpression ||
6480
expr.type === Syntax.ArrayExpression ||
6481
expr.type === Syntax.ObjectExpression) {
6482
if (!startsWithParen) {
6483
throwUnexpected(lex());
6484
}
6485
params = reinterpretAsCoverFormalsList([ expr ]);
6486
} else if (expr.type === Syntax.SequenceExpression) {
6487
params = reinterpretAsCoverFormalsList(expr.expressions);
6488
}
6489
if (params) {
6490
params.async = possiblyAsync;
6491
return parseArrowFunctionExpression(params, marker);
6492
}
6493
}
6494
6495
// If we haven't returned by now, then the 'async' keyword was not
6496
// a function modifier, and we should rewind and interpret it as a
6497
// normal identifier.
6498
if (possiblyAsync) {
6499
possiblyAsync = false;
6500
rewind(backtrackToken);
6501
expr = parseConditionalExpression();
6502
}
6503
6504
if (matchAssign()) {
6505
// 11.13.1
6506
if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {
6507
throwErrorTolerant(token, Messages.StrictLHSAssignment);
6508
}
6509
6510
// ES.next draf 11.13 Runtime Semantics step 1
6511
if (match('=') && (expr.type === Syntax.ObjectExpression || expr.type === Syntax.ArrayExpression)) {
6512
reinterpretAsAssignmentBindingPattern(expr);
6513
} else if (!isLeftHandSide(expr)) {
6514
throwError({}, Messages.InvalidLHSInAssignment);
6515
}
6516
6517
expr = markerApply(marker, delegate.createAssignmentExpression(lex().value, expr, parseAssignmentExpression()));
6518
}
6519
6520
return expr;
6521
}
6522
6523
// 11.14 Comma Operator
6524
6525
function parseExpression() {
6526
var marker, expr, expressions, sequence, spreadFound;
6527
6528
marker = markerCreate();
6529
expr = parseAssignmentExpression();
6530
expressions = [ expr ];
6531
6532
if (match(',')) {
6533
while (index < length) {
6534
if (!match(',')) {
6535
break;
6536
}
6537
6538
lex();
6539
expr = parseSpreadOrAssignmentExpression();
6540
expressions.push(expr);
6541
6542
if (expr.type === Syntax.SpreadElement) {
6543
spreadFound = true;
6544
if (!match(')')) {
6545
throwError({}, Messages.ElementAfterSpreadElement);
6546
}
6547
break;
6548
}
6549
}
6550
6551
sequence = markerApply(marker, delegate.createSequenceExpression(expressions));
6552
}
6553
6554
if (spreadFound && lookahead2().value !== '=>') {
6555
throwError({}, Messages.IllegalSpread);
6556
}
6557
6558
return sequence || expr;
6559
}
6560
6561
// 12.1 Block
6562
6563
function parseStatementList() {
6564
var list = [],
6565
statement;
6566
6567
while (index < length) {
6568
if (match('}')) {
6569
break;
6570
}
6571
statement = parseSourceElement();
6572
if (typeof statement === 'undefined') {
6573
break;
6574
}
6575
list.push(statement);
6576
}
6577
6578
return list;
6579
}
6580
6581
function parseBlock() {
6582
var block, marker = markerCreate();
6583
6584
expect('{');
6585
6586
block = parseStatementList();
6587
6588
expect('}');
6589
6590
return markerApply(marker, delegate.createBlockStatement(block));
6591
}
6592
6593
// 12.2 Variable Statement
6594
6595
function parseTypeParameterDeclaration() {
6596
var marker = markerCreate(), paramTypes = [];
6597
6598
expect('<');
6599
while (!match('>')) {
6600
paramTypes.push(parseTypeAnnotatableIdentifier());
6601
if (!match('>')) {
6602
expect(',');
6603
}
6604
}
6605
expect('>');
6606
6607
return markerApply(marker, delegate.createTypeParameterDeclaration(
6608
paramTypes
6609
));
6610
}
6611
6612
function parseTypeParameterInstantiation() {
6613
var marker = markerCreate(), oldInType = state.inType, paramTypes = [];
6614
6615
state.inType = true;
6616
6617
expect('<');
6618
while (!match('>')) {
6619
paramTypes.push(parseType());
6620
if (!match('>')) {
6621
expect(',');
6622
}
6623
}
6624
expect('>');
6625
6626
state.inType = oldInType;
6627
6628
return markerApply(marker, delegate.createTypeParameterInstantiation(
6629
paramTypes
6630
));
6631
}
6632
6633
function parseObjectTypeIndexer(marker, isStatic) {
6634
var id, key, value;
6635
6636
expect('[');
6637
id = parseObjectPropertyKey();
6638
expect(':');
6639
key = parseType();
6640
expect(']');
6641
expect(':');
6642
value = parseType();
6643
6644
return markerApply(marker, delegate.createObjectTypeIndexer(
6645
id,
6646
key,
6647
value,
6648
isStatic
6649
));
6650
}
6651
6652
function parseObjectTypeMethodish(marker) {
6653
var params = [], rest = null, returnType, typeParameters = null;
6654
if (match('<')) {
6655
typeParameters = parseTypeParameterDeclaration();
6656
}
6657
6658
expect('(');
6659
while (lookahead.type === Token.Identifier) {
6660
params.push(parseFunctionTypeParam());
6661
if (!match(')')) {
6662
expect(',');
6663
}
6664
}
6665
6666
if (match('...')) {
6667
lex();
6668
rest = parseFunctionTypeParam();
6669
}
6670
expect(')');
6671
expect(':');
6672
returnType = parseType();
6673
6674
return markerApply(marker, delegate.createFunctionTypeAnnotation(
6675
params,
6676
returnType,
6677
rest,
6678
typeParameters
6679
));
6680
}
6681
6682
function parseObjectTypeMethod(marker, isStatic, key) {
6683
var optional = false, value;
6684
value = parseObjectTypeMethodish(marker);
6685
6686
return markerApply(marker, delegate.createObjectTypeProperty(
6687
key,
6688
value,
6689
optional,
6690
isStatic
6691
));
6692
}
6693
6694
function parseObjectTypeCallProperty(marker, isStatic) {
6695
var valueMarker = markerCreate();
6696
return markerApply(marker, delegate.createObjectTypeCallProperty(
6697
parseObjectTypeMethodish(valueMarker),
6698
isStatic
6699
));
6700
}
6701
6702
function parseObjectType(allowStatic) {
6703
var callProperties = [], indexers = [], marker, optional = false,
6704
properties = [], propertyKey, propertyTypeAnnotation,
6705
token, isStatic, matchStatic;
6706
6707
expect('{');
6708
6709
while (!match('}')) {
6710
marker = markerCreate();
6711
matchStatic =
6712
strict
6713
? matchKeyword('static')
6714
: matchContextualKeyword('static');
6715
6716
if (allowStatic && matchStatic) {
6717
token = lex();
6718
isStatic = true;
6719
}
6720
6721
if (match('[')) {
6722
indexers.push(parseObjectTypeIndexer(marker, isStatic));
6723
} else if (match('(') || match('<')) {
6724
callProperties.push(parseObjectTypeCallProperty(marker, allowStatic));
6725
} else {
6726
if (isStatic && match(':')) {
6727
propertyKey = markerApply(marker, delegate.createIdentifier(token));
6728
throwErrorTolerant(token, Messages.StrictReservedWord);
6729
} else {
6730
propertyKey = parseObjectPropertyKey();
6731
}
6732
if (match('<') || match('(')) {
6733
// This is a method property
6734
properties.push(parseObjectTypeMethod(marker, isStatic, propertyKey));
6735
} else {
6736
if (match('?')) {
6737
lex();
6738
optional = true;
6739
}
6740
expect(':');
6741
propertyTypeAnnotation = parseType();
6742
properties.push(markerApply(marker, delegate.createObjectTypeProperty(
6743
propertyKey,
6744
propertyTypeAnnotation,
6745
optional,
6746
isStatic
6747
)));
6748
}
6749
}
6750
6751
if (match(';')) {
6752
lex();
6753
} else if (!match('}')) {
6754
throwUnexpected(lookahead);
6755
}
6756
}
6757
6758
expect('}');
6759
6760
return delegate.createObjectTypeAnnotation(
6761
properties,
6762
indexers,
6763
callProperties
6764
);
6765
}
6766
6767
function parseGenericType() {
6768
var marker = markerCreate(),
6769
typeParameters = null, typeIdentifier;
6770
6771
typeIdentifier = parseVariableIdentifier();
6772
6773
while (match('.')) {
6774
expect('.');
6775
typeIdentifier = markerApply(marker, delegate.createQualifiedTypeIdentifier(
6776
typeIdentifier,
6777
parseVariableIdentifier()
6778
));
6779
}
6780
6781
if (match('<')) {
6782
typeParameters = parseTypeParameterInstantiation();
6783
}
6784
6785
return markerApply(marker, delegate.createGenericTypeAnnotation(
6786
typeIdentifier,
6787
typeParameters
6788
));
6789
}
6790
6791
function parseVoidType() {
6792
var marker = markerCreate();
6793
expectKeyword('void');
6794
return markerApply(marker, delegate.createVoidTypeAnnotation());
6795
}
6796
6797
function parseTypeofType() {
6798
var argument, marker = markerCreate();
6799
expectKeyword('typeof');
6800
argument = parsePrimaryType();
6801
return markerApply(marker, delegate.createTypeofTypeAnnotation(
6802
argument
6803
));
6804
}
6805
6806
function parseTupleType() {
6807
var marker = markerCreate(), types = [];
6808
expect('[');
6809
// We allow trailing commas
6810
while (index < length && !match(']')) {
6811
types.push(parseType());
6812
if (match(']')) {
6813
break;
6814
}
6815
expect(',');
6816
}
6817
expect(']');
6818
return markerApply(marker, delegate.createTupleTypeAnnotation(
6819
types
6820
));
6821
}
6822
6823
function parseFunctionTypeParam() {
6824
var marker = markerCreate(), name, optional = false, typeAnnotation;
6825
name = parseVariableIdentifier();
6826
if (match('?')) {
6827
lex();
6828
optional = true;
6829
}
6830
expect(':');
6831
typeAnnotation = parseType();
6832
return markerApply(marker, delegate.createFunctionTypeParam(
6833
name,
6834
typeAnnotation,
6835
optional
6836
));
6837
}
6838
6839
function parseFunctionTypeParams() {
6840
var ret = { params: [], rest: null };
6841
while (lookahead.type === Token.Identifier) {
6842
ret.params.push(parseFunctionTypeParam());
6843
if (!match(')')) {
6844
expect(',');
6845
}
6846
}
6847
6848
if (match('...')) {
6849
lex();
6850
ret.rest = parseFunctionTypeParam();
6851
}
6852
return ret;
6853
}
6854
6855
// The parsing of types roughly parallels the parsing of expressions, and
6856
// primary types are kind of like primary expressions...they're the
6857
// primitives with which other types are constructed.
6858
function parsePrimaryType() {
6859
var params = null, returnType = null,
6860
marker = markerCreate(), rest = null, tmp,
6861
typeParameters, token, type, isGroupedType = false;
6862
6863
switch (lookahead.type) {
6864
case Token.Identifier:
6865
switch (lookahead.value) {
6866
case 'any':
6867
lex();
6868
return markerApply(marker, delegate.createAnyTypeAnnotation());
6869
case 'bool': // fallthrough
6870
case 'boolean':
6871
lex();
6872
return markerApply(marker, delegate.createBooleanTypeAnnotation());
6873
case 'number':
6874
lex();
6875
return markerApply(marker, delegate.createNumberTypeAnnotation());
6876
case 'string':
6877
lex();
6878
return markerApply(marker, delegate.createStringTypeAnnotation());
6879
}
6880
return markerApply(marker, parseGenericType());
6881
case Token.Punctuator:
6882
switch (lookahead.value) {
6883
case '{':
6884
return markerApply(marker, parseObjectType());
6885
case '[':
6886
return parseTupleType();
6887
case '<':
6888
typeParameters = parseTypeParameterDeclaration();
6889
expect('(');
6890
tmp = parseFunctionTypeParams();
6891
params = tmp.params;
6892
rest = tmp.rest;
6893
expect(')');
6894
6895
expect('=>');
6896
6897
returnType = parseType();
6898
6899
return markerApply(marker, delegate.createFunctionTypeAnnotation(
6900
params,
6901
returnType,
6902
rest,
6903
typeParameters
6904
));
6905
case '(':
6906
lex();
6907
// Check to see if this is actually a grouped type
6908
if (!match(')') && !match('...')) {
6909
if (lookahead.type === Token.Identifier) {
6910
token = lookahead2();
6911
isGroupedType = token.value !== '?' && token.value !== ':';
6912
} else {
6913
isGroupedType = true;
6914
}
6915
}
6916
6917
if (isGroupedType) {
6918
type = parseType();
6919
expect(')');
6920
6921
// If we see a => next then someone was probably confused about
6922
// function types, so we can provide a better error message
6923
if (match('=>')) {
6924
throwError({}, Messages.ConfusedAboutFunctionType);
6925
}
6926
6927
return type;
6928
}
6929
6930
tmp = parseFunctionTypeParams();
6931
params = tmp.params;
6932
rest = tmp.rest;
6933
6934
expect(')');
6935
6936
expect('=>');
6937
6938
returnType = parseType();
6939
6940
return markerApply(marker, delegate.createFunctionTypeAnnotation(
6941
params,
6942
returnType,
6943
rest,
6944
null /* typeParameters */
6945
));
6946
}
6947
break;
6948
case Token.Keyword:
6949
switch (lookahead.value) {
6950
case 'void':
6951
return markerApply(marker, parseVoidType());
6952
case 'typeof':
6953
return markerApply(marker, parseTypeofType());
6954
}
6955
break;
6956
case Token.StringLiteral:
6957
token = lex();
6958
if (token.octal) {
6959
throwError(token, Messages.StrictOctalLiteral);
6960
}
6961
return markerApply(marker, delegate.createStringLiteralTypeAnnotation(
6962
token
6963
));
6964
}
6965
6966
throwUnexpected(lookahead);
6967
}
6968
6969
function parsePostfixType() {
6970
var marker = markerCreate(), t = parsePrimaryType();
6971
if (match('[')) {
6972
expect('[');
6973
expect(']');
6974
return markerApply(marker, delegate.createArrayTypeAnnotation(t));
6975
}
6976
return t;
6977
}
6978
6979
function parsePrefixType() {
6980
var marker = markerCreate();
6981
if (match('?')) {
6982
lex();
6983
return markerApply(marker, delegate.createNullableTypeAnnotation(
6984
parsePrefixType()
6985
));
6986
}
6987
return parsePostfixType();
6988
}
6989
6990
6991
function parseIntersectionType() {
6992
var marker = markerCreate(), type, types;
6993
type = parsePrefixType();
6994
types = [type];
6995
while (match('&')) {
6996
lex();
6997
types.push(parsePrefixType());
6998
}
6999
7000
return types.length === 1 ?
7001
type :
7002
markerApply(marker, delegate.createIntersectionTypeAnnotation(
7003
types
7004
));
7005
}
7006
7007
function parseUnionType() {
7008
var marker = markerCreate(), type, types;
7009
type = parseIntersectionType();
7010
types = [type];
7011
while (match('|')) {
7012
lex();
7013
types.push(parseIntersectionType());
7014
}
7015
return types.length === 1 ?
7016
type :
7017
markerApply(marker, delegate.createUnionTypeAnnotation(
7018
types
7019
));
7020
}
7021
7022
function parseType() {
7023
var oldInType = state.inType, type;
7024
state.inType = true;
7025
7026
type = parseUnionType();
7027
7028
state.inType = oldInType;
7029
return type;
7030
}
7031
7032
function parseTypeAnnotation() {
7033
var marker = markerCreate(), type;
7034
7035
expect(':');
7036
type = parseType();
7037
7038
return markerApply(marker, delegate.createTypeAnnotation(type));
7039
}
7040
7041
function parseVariableIdentifier() {
7042
var marker = markerCreate(),
7043
token = lex();
7044
7045
if (token.type !== Token.Identifier) {
7046
throwUnexpected(token);
7047
}
7048
7049
return markerApply(marker, delegate.createIdentifier(token.value));
7050
}
7051
7052
function parseTypeAnnotatableIdentifier(requireTypeAnnotation, canBeOptionalParam) {
7053
var marker = markerCreate(),
7054
ident = parseVariableIdentifier(),
7055
isOptionalParam = false;
7056
7057
if (canBeOptionalParam && match('?')) {
7058
expect('?');
7059
isOptionalParam = true;
7060
}
7061
7062
if (requireTypeAnnotation || match(':')) {
7063
ident.typeAnnotation = parseTypeAnnotation();
7064
ident = markerApply(marker, ident);
7065
}
7066
7067
if (isOptionalParam) {
7068
ident.optional = true;
7069
ident = markerApply(marker, ident);
7070
}
7071
7072
return ident;
7073
}
7074
7075
function parseVariableDeclaration(kind) {
7076
var id,
7077
marker = markerCreate(),
7078
init = null,
7079
typeAnnotationMarker = markerCreate();
7080
if (match('{')) {
7081
id = parseObjectInitialiser();
7082
reinterpretAsAssignmentBindingPattern(id);
7083
if (match(':')) {
7084
id.typeAnnotation = parseTypeAnnotation();
7085
markerApply(typeAnnotationMarker, id);
7086
}
7087
} else if (match('[')) {
7088
id = parseArrayInitialiser();
7089
reinterpretAsAssignmentBindingPattern(id);
7090
if (match(':')) {
7091
id.typeAnnotation = parseTypeAnnotation();
7092
markerApply(typeAnnotationMarker, id);
7093
}
7094
} else {
7095
/* istanbul ignore next */
7096
id = state.allowKeyword ? parseNonComputedProperty() : parseTypeAnnotatableIdentifier();
7097
// 12.2.1
7098
if (strict && isRestrictedWord(id.name)) {
7099
throwErrorTolerant({}, Messages.StrictVarName);
7100
}
7101
}
7102
7103
if (kind === 'const') {
7104
if (!match('=')) {
7105
throwError({}, Messages.NoUninitializedConst);
7106
}
7107
expect('=');
7108
init = parseAssignmentExpression();
7109
} else if (match('=')) {
7110
lex();
7111
init = parseAssignmentExpression();
7112
}
7113
7114
return markerApply(marker, delegate.createVariableDeclarator(id, init));
7115
}
7116
7117
function parseVariableDeclarationList(kind) {
7118
var list = [];
7119
7120
do {
7121
list.push(parseVariableDeclaration(kind));
7122
if (!match(',')) {
7123
break;
7124
}
7125
lex();
7126
} while (index < length);
7127
7128
return list;
7129
}
7130
7131
function parseVariableStatement() {
7132
var declarations, marker = markerCreate();
7133
7134
expectKeyword('var');
7135
7136
declarations = parseVariableDeclarationList();
7137
7138
consumeSemicolon();
7139
7140
return markerApply(marker, delegate.createVariableDeclaration(declarations, 'var'));
7141
}
7142
7143
// kind may be `const` or `let`
7144
// Both are experimental and not in the specification yet.
7145
// see http://wiki.ecmascript.org/doku.php?id=harmony:const
7146
// and http://wiki.ecmascript.org/doku.php?id=harmony:let
7147
function parseConstLetDeclaration(kind) {
7148
var declarations, marker = markerCreate();
7149
7150
expectKeyword(kind);
7151
7152
declarations = parseVariableDeclarationList(kind);
7153
7154
consumeSemicolon();
7155
7156
return markerApply(marker, delegate.createVariableDeclaration(declarations, kind));
7157
}
7158
7159
// people.mozilla.org/~jorendorff/es6-draft.html
7160
7161
function parseModuleSpecifier() {
7162
var marker = markerCreate(),
7163
specifier;
7164
7165
if (lookahead.type !== Token.StringLiteral) {
7166
throwError({}, Messages.InvalidModuleSpecifier);
7167
}
7168
specifier = delegate.createModuleSpecifier(lookahead);
7169
lex();
7170
return markerApply(marker, specifier);
7171
}
7172
7173
function parseExportBatchSpecifier() {
7174
var marker = markerCreate();
7175
expect('*');
7176
return markerApply(marker, delegate.createExportBatchSpecifier());
7177
}
7178
7179
function parseExportSpecifier() {
7180
var id, name = null, marker = markerCreate(), from;
7181
if (matchKeyword('default')) {
7182
lex();
7183
id = markerApply(marker, delegate.createIdentifier('default'));
7184
// export {default} from "something";
7185
} else {
7186
id = parseVariableIdentifier();
7187
}
7188
if (matchContextualKeyword('as')) {
7189
lex();
7190
name = parseNonComputedProperty();
7191
}
7192
7193
return markerApply(marker, delegate.createExportSpecifier(id, name));
7194
}
7195
7196
function parseExportDeclaration() {
7197
var declaration = null,
7198
possibleIdentifierToken, sourceElement,
7199
isExportFromIdentifier,
7200
src = null, specifiers = [],
7201
marker = markerCreate();
7202
7203
expectKeyword('export');
7204
7205
if (matchKeyword('default')) {
7206
// covers:
7207
// export default ...
7208
lex();
7209
if (matchKeyword('function') || matchKeyword('class')) {
7210
possibleIdentifierToken = lookahead2();
7211
if (isIdentifierName(possibleIdentifierToken)) {
7212
// covers:
7213
// export default function foo () {}
7214
// export default class foo {}
7215
sourceElement = parseSourceElement();
7216
return markerApply(marker, delegate.createExportDeclaration(true, sourceElement, [sourceElement.id], null));
7217
}
7218
// covers:
7219
// export default function () {}
7220
// export default class {}
7221
switch (lookahead.value) {
7222
case 'class':
7223
return markerApply(marker, delegate.createExportDeclaration(true, parseClassExpression(), [], null));
7224
case 'function':
7225
return markerApply(marker, delegate.createExportDeclaration(true, parseFunctionExpression(), [], null));
7226
}
7227
}
7228
7229
if (matchContextualKeyword('from')) {
7230
throwError({}, Messages.UnexpectedToken, lookahead.value);
7231
}
7232
7233
// covers:
7234
// export default {};
7235
// export default [];
7236
if (match('{')) {
7237
declaration = parseObjectInitialiser();
7238
} else if (match('[')) {
7239
declaration = parseArrayInitialiser();
7240
} else {
7241
declaration = parseAssignmentExpression();
7242
}
7243
consumeSemicolon();
7244
return markerApply(marker, delegate.createExportDeclaration(true, declaration, [], null));
7245
}
7246
7247
// non-default export
7248
if (lookahead.type === Token.Keyword || matchContextualKeyword('type')) {
7249
// covers:
7250
// export var f = 1;
7251
switch (lookahead.value) {
7252
case 'type':
7253
case 'let':
7254
case 'const':
7255
case 'var':
7256
case 'class':
7257
case 'function':
7258
return markerApply(marker, delegate.createExportDeclaration(false, parseSourceElement(), specifiers, null));
7259
}
7260
}
7261
7262
if (match('*')) {
7263
// covers:
7264
// export * from "foo";
7265
specifiers.push(parseExportBatchSpecifier());
7266
7267
if (!matchContextualKeyword('from')) {
7268
throwError({}, lookahead.value ?
7269
Messages.UnexpectedToken : Messages.MissingFromClause, lookahead.value);
7270
}
7271
lex();
7272
src = parseModuleSpecifier();
7273
consumeSemicolon();
7274
7275
return markerApply(marker, delegate.createExportDeclaration(false, null, specifiers, src));
7276
}
7277
7278
expect('{');
7279
if (!match('}')) {
7280
do {
7281
isExportFromIdentifier = isExportFromIdentifier || matchKeyword('default');
7282
specifiers.push(parseExportSpecifier());
7283
} while (match(',') && lex());
7284
}
7285
expect('}');
7286
7287
if (matchContextualKeyword('from')) {
7288
// covering:
7289
// export {default} from "foo";
7290
// export {foo} from "foo";
7291
lex();
7292
src = parseModuleSpecifier();
7293
consumeSemicolon();
7294
} else if (isExportFromIdentifier) {
7295
// covering:
7296
// export {default}; // missing fromClause
7297
throwError({}, lookahead.value ?
7298
Messages.UnexpectedToken : Messages.MissingFromClause, lookahead.value);
7299
} else {
7300
// cover
7301
// export {foo};
7302
consumeSemicolon();
7303
}
7304
return markerApply(marker, delegate.createExportDeclaration(false, declaration, specifiers, src));
7305
}
7306
7307
7308
function parseImportSpecifier() {
7309
// import {<foo as bar>} ...;
7310
var id, name = null, marker = markerCreate();
7311
7312
id = parseNonComputedProperty();
7313
if (matchContextualKeyword('as')) {
7314
lex();
7315
name = parseVariableIdentifier();
7316
}
7317
7318
return markerApply(marker, delegate.createImportSpecifier(id, name));
7319
}
7320
7321
function parseNamedImports() {
7322
var specifiers = [];
7323
// {foo, bar as bas}
7324
expect('{');
7325
if (!match('}')) {
7326
do {
7327
specifiers.push(parseImportSpecifier());
7328
} while (match(',') && lex());
7329
}
7330
expect('}');
7331
return specifiers;
7332
}
7333
7334
function parseImportDefaultSpecifier() {
7335
// import <foo> ...;
7336
var id, marker = markerCreate();
7337
7338
id = parseNonComputedProperty();
7339
7340
return markerApply(marker, delegate.createImportDefaultSpecifier(id));
7341
}
7342
7343
function parseImportNamespaceSpecifier() {
7344
// import <* as foo> ...;
7345
var id, marker = markerCreate();
7346
7347
expect('*');
7348
if (!matchContextualKeyword('as')) {
7349
throwError({}, Messages.NoAsAfterImportNamespace);
7350
}
7351
lex();
7352
id = parseNonComputedProperty();
7353
7354
return markerApply(marker, delegate.createImportNamespaceSpecifier(id));
7355
}
7356
7357
function parseImportDeclaration() {
7358
var specifiers, src, marker = markerCreate(), isType = false, token2;
7359
7360
expectKeyword('import');
7361
7362
if (matchContextualKeyword('type')) {
7363
token2 = lookahead2();
7364
if ((token2.type === Token.Identifier && token2.value !== 'from') ||
7365
(token2.type === Token.Punctuator &&
7366
(token2.value === '{' || token2.value === '*'))) {
7367
isType = true;
7368
lex();
7369
}
7370
}
7371
7372
specifiers = [];
7373
7374
if (lookahead.type === Token.StringLiteral) {
7375
// covers:
7376
// import "foo";
7377
src = parseModuleSpecifier();
7378
consumeSemicolon();
7379
return markerApply(marker, delegate.createImportDeclaration(specifiers, src, isType));
7380
}
7381
7382
if (!matchKeyword('default') && isIdentifierName(lookahead)) {
7383
// covers:
7384
// import foo
7385
// import foo, ...
7386
specifiers.push(parseImportDefaultSpecifier());
7387
if (match(',')) {
7388
lex();
7389
}
7390
}
7391
if (match('*')) {
7392
// covers:
7393
// import foo, * as foo
7394
// import * as foo
7395
specifiers.push(parseImportNamespaceSpecifier());
7396
} else if (match('{')) {
7397
// covers:
7398
// import foo, {bar}
7399
// import {bar}
7400
specifiers = specifiers.concat(parseNamedImports());
7401
}
7402
7403
if (!matchContextualKeyword('from')) {
7404
throwError({}, lookahead.value ?
7405
Messages.UnexpectedToken : Messages.MissingFromClause, lookahead.value);
7406
}
7407
lex();
7408
src = parseModuleSpecifier();
7409
consumeSemicolon();
7410
7411
return markerApply(marker, delegate.createImportDeclaration(specifiers, src, isType));
7412
}
7413
7414
// 12.3 Empty Statement
7415
7416
function parseEmptyStatement() {
7417
var marker = markerCreate();
7418
expect(';');
7419
return markerApply(marker, delegate.createEmptyStatement());
7420
}
7421
7422
// 12.4 Expression Statement
7423
7424
function parseExpressionStatement() {
7425
var marker = markerCreate(), expr = parseExpression();
7426
consumeSemicolon();
7427
return markerApply(marker, delegate.createExpressionStatement(expr));
7428
}
7429
7430
// 12.5 If statement
7431
7432
function parseIfStatement() {
7433
var test, consequent, alternate, marker = markerCreate();
7434
7435
expectKeyword('if');
7436
7437
expect('(');
7438
7439
test = parseExpression();
7440
7441
expect(')');
7442
7443
consequent = parseStatement();
7444
7445
if (matchKeyword('else')) {
7446
lex();
7447
alternate = parseStatement();
7448
} else {
7449
alternate = null;
7450
}
7451
7452
return markerApply(marker, delegate.createIfStatement(test, consequent, alternate));
7453
}
7454
7455
// 12.6 Iteration Statements
7456
7457
function parseDoWhileStatement() {
7458
var body, test, oldInIteration, marker = markerCreate();
7459
7460
expectKeyword('do');
7461
7462
oldInIteration = state.inIteration;
7463
state.inIteration = true;
7464
7465
body = parseStatement();
7466
7467
state.inIteration = oldInIteration;
7468
7469
expectKeyword('while');
7470
7471
expect('(');
7472
7473
test = parseExpression();
7474
7475
expect(')');
7476
7477
if (match(';')) {
7478
lex();
7479
}
7480
7481
return markerApply(marker, delegate.createDoWhileStatement(body, test));
7482
}
7483
7484
function parseWhileStatement() {
7485
var test, body, oldInIteration, marker = markerCreate();
7486
7487
expectKeyword('while');
7488
7489
expect('(');
7490
7491
test = parseExpression();
7492
7493
expect(')');
7494
7495
oldInIteration = state.inIteration;
7496
state.inIteration = true;
7497
7498
body = parseStatement();
7499
7500
state.inIteration = oldInIteration;
7501
7502
return markerApply(marker, delegate.createWhileStatement(test, body));
7503
}
7504
7505
function parseForVariableDeclaration() {
7506
var marker = markerCreate(),
7507
token = lex(),
7508
declarations = parseVariableDeclarationList();
7509
7510
return markerApply(marker, delegate.createVariableDeclaration(declarations, token.value));
7511
}
7512
7513
function parseForStatement(opts) {
7514
var init, test, update, left, right, body, operator, oldInIteration,
7515
marker = markerCreate();
7516
init = test = update = null;
7517
expectKeyword('for');
7518
7519
// http://wiki.ecmascript.org/doku.php?id=proposals:iterators_and_generators&s=each
7520
if (matchContextualKeyword('each')) {
7521
throwError({}, Messages.EachNotAllowed);
7522
}
7523
7524
expect('(');
7525
7526
if (match(';')) {
7527
lex();
7528
} else {
7529
if (matchKeyword('var') || matchKeyword('let') || matchKeyword('const')) {
7530
state.allowIn = false;
7531
init = parseForVariableDeclaration();
7532
state.allowIn = true;
7533
7534
if (init.declarations.length === 1) {
7535
if (matchKeyword('in') || matchContextualKeyword('of')) {
7536
operator = lookahead;
7537
if (!((operator.value === 'in' || init.kind !== 'var') && init.declarations[0].init)) {
7538
lex();
7539
left = init;
7540
right = parseExpression();
7541
init = null;
7542
}
7543
}
7544
}
7545
} else {
7546
state.allowIn = false;
7547
init = parseExpression();
7548
state.allowIn = true;
7549
7550
if (matchContextualKeyword('of')) {
7551
operator = lex();
7552
left = init;
7553
right = parseExpression();
7554
init = null;
7555
} else if (matchKeyword('in')) {
7556
// LeftHandSideExpression
7557
if (!isAssignableLeftHandSide(init)) {
7558
throwError({}, Messages.InvalidLHSInForIn);
7559
}
7560
operator = lex();
7561
left = init;
7562
right = parseExpression();
7563
init = null;
7564
}
7565
}
7566
7567
if (typeof left === 'undefined') {
7568
expect(';');
7569
}
7570
}
7571
7572
if (typeof left === 'undefined') {
7573
7574
if (!match(';')) {
7575
test = parseExpression();
7576
}
7577
expect(';');
7578
7579
if (!match(')')) {
7580
update = parseExpression();
7581
}
7582
}
7583
7584
expect(')');
7585
7586
oldInIteration = state.inIteration;
7587
state.inIteration = true;
7588
7589
if (!(opts !== undefined && opts.ignoreBody)) {
7590
body = parseStatement();
7591
}
7592
7593
state.inIteration = oldInIteration;
7594
7595
if (typeof left === 'undefined') {
7596
return markerApply(marker, delegate.createForStatement(init, test, update, body));
7597
}
7598
7599
if (operator.value === 'in') {
7600
return markerApply(marker, delegate.createForInStatement(left, right, body));
7601
}
7602
return markerApply(marker, delegate.createForOfStatement(left, right, body));
7603
}
7604
7605
// 12.7 The continue statement
7606
7607
function parseContinueStatement() {
7608
var label = null, marker = markerCreate();
7609
7610
expectKeyword('continue');
7611
7612
// Optimize the most common form: 'continue;'.
7613
if (source.charCodeAt(index) === 59) {
7614
lex();
7615
7616
if (!state.inIteration) {
7617
throwError({}, Messages.IllegalContinue);
7618
}
7619
7620
return markerApply(marker, delegate.createContinueStatement(null));
7621
}
7622
7623
if (peekLineTerminator()) {
7624
if (!state.inIteration) {
7625
throwError({}, Messages.IllegalContinue);
7626
}
7627
7628
return markerApply(marker, delegate.createContinueStatement(null));
7629
}
7630
7631
if (lookahead.type === Token.Identifier) {
7632
label = parseVariableIdentifier();
7633
7634
if (!state.labelSet.has(label.name)) {
7635
throwError({}, Messages.UnknownLabel, label.name);
7636
}
7637
}
7638
7639
consumeSemicolon();
7640
7641
if (label === null && !state.inIteration) {
7642
throwError({}, Messages.IllegalContinue);
7643
}
7644
7645
return markerApply(marker, delegate.createContinueStatement(label));
7646
}
7647
7648
// 12.8 The break statement
7649
7650
function parseBreakStatement() {
7651
var label = null, marker = markerCreate();
7652
7653
expectKeyword('break');
7654
7655
// Catch the very common case first: immediately a semicolon (char #59).
7656
if (source.charCodeAt(index) === 59) {
7657
lex();
7658
7659
if (!(state.inIteration || state.inSwitch)) {
7660
throwError({}, Messages.IllegalBreak);
7661
}
7662
7663
return markerApply(marker, delegate.createBreakStatement(null));
7664
}
7665
7666
if (peekLineTerminator()) {
7667
if (!(state.inIteration || state.inSwitch)) {
7668
throwError({}, Messages.IllegalBreak);
7669
}
7670
7671
return markerApply(marker, delegate.createBreakStatement(null));
7672
}
7673
7674
if (lookahead.type === Token.Identifier) {
7675
label = parseVariableIdentifier();
7676
7677
if (!state.labelSet.has(label.name)) {
7678
throwError({}, Messages.UnknownLabel, label.name);
7679
}
7680
}
7681
7682
consumeSemicolon();
7683
7684
if (label === null && !(state.inIteration || state.inSwitch)) {
7685
throwError({}, Messages.IllegalBreak);
7686
}
7687
7688
return markerApply(marker, delegate.createBreakStatement(label));
7689
}
7690
7691
// 12.9 The return statement
7692
7693
function parseReturnStatement() {
7694
var argument = null, marker = markerCreate();
7695
7696
expectKeyword('return');
7697
7698
if (!state.inFunctionBody) {
7699
throwErrorTolerant({}, Messages.IllegalReturn);
7700
}
7701
7702
// 'return' followed by a space and an identifier is very common.
7703
if (source.charCodeAt(index) === 32) {
7704
if (isIdentifierStart(source.charCodeAt(index + 1))) {
7705
argument = parseExpression();
7706
consumeSemicolon();
7707
return markerApply(marker, delegate.createReturnStatement(argument));
7708
}
7709
}
7710
7711
if (peekLineTerminator()) {
7712
return markerApply(marker, delegate.createReturnStatement(null));
7713
}
7714
7715
if (!match(';')) {
7716
if (!match('}') && lookahead.type !== Token.EOF) {
7717
argument = parseExpression();
7718
}
7719
}
7720
7721
consumeSemicolon();
7722
7723
return markerApply(marker, delegate.createReturnStatement(argument));
7724
}
7725
7726
// 12.10 The with statement
7727
7728
function parseWithStatement() {
7729
var object, body, marker = markerCreate();
7730
7731
if (strict) {
7732
throwErrorTolerant({}, Messages.StrictModeWith);
7733
}
7734
7735
expectKeyword('with');
7736
7737
expect('(');
7738
7739
object = parseExpression();
7740
7741
expect(')');
7742
7743
body = parseStatement();
7744
7745
return markerApply(marker, delegate.createWithStatement(object, body));
7746
}
7747
7748
// 12.10 The swith statement
7749
7750
function parseSwitchCase() {
7751
var test,
7752
consequent = [],
7753
sourceElement,
7754
marker = markerCreate();
7755
7756
if (matchKeyword('default')) {
7757
lex();
7758
test = null;
7759
} else {
7760
expectKeyword('case');
7761
test = parseExpression();
7762
}
7763
expect(':');
7764
7765
while (index < length) {
7766
if (match('}') || matchKeyword('default') || matchKeyword('case')) {
7767
break;
7768
}
7769
sourceElement = parseSourceElement();
7770
if (typeof sourceElement === 'undefined') {
7771
break;
7772
}
7773
consequent.push(sourceElement);
7774
}
7775
7776
return markerApply(marker, delegate.createSwitchCase(test, consequent));
7777
}
7778
7779
function parseSwitchStatement() {
7780
var discriminant, cases, clause, oldInSwitch, defaultFound, marker = markerCreate();
7781
7782
expectKeyword('switch');
7783
7784
expect('(');
7785
7786
discriminant = parseExpression();
7787
7788
expect(')');
7789
7790
expect('{');
7791
7792
cases = [];
7793
7794
if (match('}')) {
7795
lex();
7796
return markerApply(marker, delegate.createSwitchStatement(discriminant, cases));
7797
}
7798
7799
oldInSwitch = state.inSwitch;
7800
state.inSwitch = true;
7801
defaultFound = false;
7802
7803
while (index < length) {
7804
if (match('}')) {
7805
break;
7806
}
7807
clause = parseSwitchCase();
7808
if (clause.test === null) {
7809
if (defaultFound) {
7810
throwError({}, Messages.MultipleDefaultsInSwitch);
7811
}
7812
defaultFound = true;
7813
}
7814
cases.push(clause);
7815
}
7816
7817
state.inSwitch = oldInSwitch;
7818
7819
expect('}');
7820
7821
return markerApply(marker, delegate.createSwitchStatement(discriminant, cases));
7822
}
7823
7824
// 12.13 The throw statement
7825
7826
function parseThrowStatement() {
7827
var argument, marker = markerCreate();
7828
7829
expectKeyword('throw');
7830
7831
if (peekLineTerminator()) {
7832
throwError({}, Messages.NewlineAfterThrow);
7833
}
7834
7835
argument = parseExpression();
7836
7837
consumeSemicolon();
7838
7839
return markerApply(marker, delegate.createThrowStatement(argument));
7840
}
7841
7842
// 12.14 The try statement
7843
7844
function parseCatchClause() {
7845
var param, body, marker = markerCreate();
7846
7847
expectKeyword('catch');
7848
7849
expect('(');
7850
if (match(')')) {
7851
throwUnexpected(lookahead);
7852
}
7853
7854
param = parseExpression();
7855
// 12.14.1
7856
if (strict && param.type === Syntax.Identifier && isRestrictedWord(param.name)) {
7857
throwErrorTolerant({}, Messages.StrictCatchVariable);
7858
}
7859
7860
expect(')');
7861
body = parseBlock();
7862
return markerApply(marker, delegate.createCatchClause(param, body));
7863
}
7864
7865
function parseTryStatement() {
7866
var block, handlers = [], finalizer = null, marker = markerCreate();
7867
7868
expectKeyword('try');
7869
7870
block = parseBlock();
7871
7872
if (matchKeyword('catch')) {
7873
handlers.push(parseCatchClause());
7874
}
7875
7876
if (matchKeyword('finally')) {
7877
lex();
7878
finalizer = parseBlock();
7879
}
7880
7881
if (handlers.length === 0 && !finalizer) {
7882
throwError({}, Messages.NoCatchOrFinally);
7883
}
7884
7885
return markerApply(marker, delegate.createTryStatement(block, [], handlers, finalizer));
7886
}
7887
7888
// 12.15 The debugger statement
7889
7890
function parseDebuggerStatement() {
7891
var marker = markerCreate();
7892
expectKeyword('debugger');
7893
7894
consumeSemicolon();
7895
7896
return markerApply(marker, delegate.createDebuggerStatement());
7897
}
7898
7899
// 12 Statements
7900
7901
function parseStatement() {
7902
var type = lookahead.type,
7903
marker,
7904
expr,
7905
labeledBody;
7906
7907
if (type === Token.EOF) {
7908
throwUnexpected(lookahead);
7909
}
7910
7911
if (type === Token.Punctuator) {
7912
switch (lookahead.value) {
7913
case ';':
7914
return parseEmptyStatement();
7915
case '{':
7916
return parseBlock();
7917
case '(':
7918
return parseExpressionStatement();
7919
default:
7920
break;
7921
}
7922
}
7923
7924
if (type === Token.Keyword) {
7925
switch (lookahead.value) {
7926
case 'break':
7927
return parseBreakStatement();
7928
case 'continue':
7929
return parseContinueStatement();
7930
case 'debugger':
7931
return parseDebuggerStatement();
7932
case 'do':
7933
return parseDoWhileStatement();
7934
case 'for':
7935
return parseForStatement();
7936
case 'function':
7937
return parseFunctionDeclaration();
7938
case 'class':
7939
return parseClassDeclaration();
7940
case 'if':
7941
return parseIfStatement();
7942
case 'return':
7943
return parseReturnStatement();
7944
case 'switch':
7945
return parseSwitchStatement();
7946
case 'throw':
7947
return parseThrowStatement();
7948
case 'try':
7949
return parseTryStatement();
7950
case 'var':
7951
return parseVariableStatement();
7952
case 'while':
7953
return parseWhileStatement();
7954
case 'with':
7955
return parseWithStatement();
7956
default:
7957
break;
7958
}
7959
}
7960
7961
if (matchAsyncFuncExprOrDecl()) {
7962
return parseFunctionDeclaration();
7963
}
7964
7965
marker = markerCreate();
7966
expr = parseExpression();
7967
7968
// 12.12 Labelled Statements
7969
if ((expr.type === Syntax.Identifier) && match(':')) {
7970
lex();
7971
7972
if (state.labelSet.has(expr.name)) {
7973
throwError({}, Messages.Redeclaration, 'Label', expr.name);
7974
}
7975
7976
state.labelSet.set(expr.name, true);
7977
labeledBody = parseStatement();
7978
state.labelSet["delete"](expr.name);
7979
return markerApply(marker, delegate.createLabeledStatement(expr, labeledBody));
7980
}
7981
7982
consumeSemicolon();
7983
7984
return markerApply(marker, delegate.createExpressionStatement(expr));
7985
}
7986
7987
// 13 Function Definition
7988
7989
function parseConciseBody() {
7990
if (match('{')) {
7991
return parseFunctionSourceElements();
7992
}
7993
return parseAssignmentExpression();
7994
}
7995
7996
function parseFunctionSourceElements() {
7997
var sourceElement, sourceElements = [], token, directive, firstRestricted,
7998
oldLabelSet, oldInIteration, oldInSwitch, oldInFunctionBody, oldParenthesizedCount,
7999
marker = markerCreate();
8000
8001
expect('{');
8002
8003
while (index < length) {
8004
if (lookahead.type !== Token.StringLiteral) {
8005
break;
8006
}
8007
token = lookahead;
8008
8009
sourceElement = parseSourceElement();
8010
sourceElements.push(sourceElement);
8011
if (sourceElement.expression.type !== Syntax.Literal) {
8012
// this is not directive
8013
break;
8014
}
8015
directive = source.slice(token.range[0] + 1, token.range[1] - 1);
8016
if (directive === 'use strict') {
8017
strict = true;
8018
if (firstRestricted) {
8019
throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral);
8020
}
8021
} else {
8022
if (!firstRestricted && token.octal) {
8023
firstRestricted = token;
8024
}
8025
}
8026
}
8027
8028
oldLabelSet = state.labelSet;
8029
oldInIteration = state.inIteration;
8030
oldInSwitch = state.inSwitch;
8031
oldInFunctionBody = state.inFunctionBody;
8032
oldParenthesizedCount = state.parenthesizedCount;
8033
8034
state.labelSet = new StringMap();
8035
state.inIteration = false;
8036
state.inSwitch = false;
8037
state.inFunctionBody = true;
8038
state.parenthesizedCount = 0;
8039
8040
while (index < length) {
8041
if (match('}')) {
8042
break;
8043
}
8044
sourceElement = parseSourceElement();
8045
if (typeof sourceElement === 'undefined') {
8046
break;
8047
}
8048
sourceElements.push(sourceElement);
8049
}
8050
8051
expect('}');
8052
8053
state.labelSet = oldLabelSet;
8054
state.inIteration = oldInIteration;
8055
state.inSwitch = oldInSwitch;
8056
state.inFunctionBody = oldInFunctionBody;
8057
state.parenthesizedCount = oldParenthesizedCount;
8058
8059
return markerApply(marker, delegate.createBlockStatement(sourceElements));
8060
}
8061
8062
function validateParam(options, param, name) {
8063
if (strict) {
8064
if (isRestrictedWord(name)) {
8065
options.stricted = param;
8066
options.message = Messages.StrictParamName;
8067
}
8068
if (options.paramSet.has(name)) {
8069
options.stricted = param;
8070
options.message = Messages.StrictParamDupe;
8071
}
8072
} else if (!options.firstRestricted) {
8073
if (isRestrictedWord(name)) {
8074
options.firstRestricted = param;
8075
options.message = Messages.StrictParamName;
8076
} else if (isStrictModeReservedWord(name)) {
8077
options.firstRestricted = param;
8078
options.message = Messages.StrictReservedWord;
8079
} else if (options.paramSet.has(name)) {
8080
options.firstRestricted = param;
8081
options.message = Messages.StrictParamDupe;
8082
}
8083
}
8084
options.paramSet.set(name, true);
8085
}
8086
8087
function parseParam(options) {
8088
var marker, token, rest, param, def;
8089
8090
token = lookahead;
8091
if (token.value === '...') {
8092
token = lex();
8093
rest = true;
8094
}
8095
8096
if (match('[')) {
8097
marker = markerCreate();
8098
param = parseArrayInitialiser();
8099
reinterpretAsDestructuredParameter(options, param);
8100
if (match(':')) {
8101
param.typeAnnotation = parseTypeAnnotation();
8102
markerApply(marker, param);
8103
}
8104
} else if (match('{')) {
8105
marker = markerCreate();
8106
if (rest) {
8107
throwError({}, Messages.ObjectPatternAsRestParameter);
8108
}
8109
param = parseObjectInitialiser();
8110
reinterpretAsDestructuredParameter(options, param);
8111
if (match(':')) {
8112
param.typeAnnotation = parseTypeAnnotation();
8113
markerApply(marker, param);
8114
}
8115
} else {
8116
param =
8117
rest
8118
? parseTypeAnnotatableIdentifier(
8119
false, /* requireTypeAnnotation */
8120
false /* canBeOptionalParam */
8121
)
8122
: parseTypeAnnotatableIdentifier(
8123
false, /* requireTypeAnnotation */
8124
true /* canBeOptionalParam */
8125
);
8126
8127
validateParam(options, token, token.value);
8128
}
8129
8130
if (match('=')) {
8131
if (rest) {
8132
throwErrorTolerant(lookahead, Messages.DefaultRestParameter);
8133
}
8134
lex();
8135
def = parseAssignmentExpression();
8136
++options.defaultCount;
8137
}
8138
8139
if (rest) {
8140
if (!match(')')) {
8141
throwError({}, Messages.ParameterAfterRestParameter);
8142
}
8143
options.rest = param;
8144
return false;
8145
}
8146
8147
options.params.push(param);
8148
options.defaults.push(def);
8149
return !match(')');
8150
}
8151
8152
function parseParams(firstRestricted) {
8153
var options, marker = markerCreate();
8154
8155
options = {
8156
params: [],
8157
defaultCount: 0,
8158
defaults: [],
8159
rest: null,
8160
firstRestricted: firstRestricted
8161
};
8162
8163
expect('(');
8164
8165
if (!match(')')) {
8166
options.paramSet = new StringMap();
8167
while (index < length) {
8168
if (!parseParam(options)) {
8169
break;
8170
}
8171
expect(',');
8172
}
8173
}
8174
8175
expect(')');
8176
8177
if (options.defaultCount === 0) {
8178
options.defaults = [];
8179
}
8180
8181
if (match(':')) {
8182
options.returnType = parseTypeAnnotation();
8183
}
8184
8185
return markerApply(marker, options);
8186
}
8187
8188
function parseFunctionDeclaration() {
8189
var id, body, token, tmp, firstRestricted, message, generator, isAsync,
8190
previousStrict, previousYieldAllowed, previousAwaitAllowed,
8191
marker = markerCreate(), typeParameters;
8192
8193
isAsync = false;
8194
if (matchAsync()) {
8195
lex();
8196
isAsync = true;
8197
}
8198
8199
expectKeyword('function');
8200
8201
generator = false;
8202
if (match('*')) {
8203
lex();
8204
generator = true;
8205
}
8206
8207
token = lookahead;
8208
8209
id = parseVariableIdentifier();
8210
8211
if (match('<')) {
8212
typeParameters = parseTypeParameterDeclaration();
8213
}
8214
8215
if (strict) {
8216
if (isRestrictedWord(token.value)) {
8217
throwErrorTolerant(token, Messages.StrictFunctionName);
8218
}
8219
} else {
8220
if (isRestrictedWord(token.value)) {
8221
firstRestricted = token;
8222
message = Messages.StrictFunctionName;
8223
} else if (isStrictModeReservedWord(token.value)) {
8224
firstRestricted = token;
8225
message = Messages.StrictReservedWord;
8226
}
8227
}
8228
8229
tmp = parseParams(firstRestricted);
8230
firstRestricted = tmp.firstRestricted;
8231
if (tmp.message) {
8232
message = tmp.message;
8233
}
8234
8235
previousStrict = strict;
8236
previousYieldAllowed = state.yieldAllowed;
8237
state.yieldAllowed = generator;
8238
previousAwaitAllowed = state.awaitAllowed;
8239
state.awaitAllowed = isAsync;
8240
8241
body = parseFunctionSourceElements();
8242
8243
if (strict && firstRestricted) {
8244
throwError(firstRestricted, message);
8245
}
8246
if (strict && tmp.stricted) {
8247
throwErrorTolerant(tmp.stricted, message);
8248
}
8249
strict = previousStrict;
8250
state.yieldAllowed = previousYieldAllowed;
8251
state.awaitAllowed = previousAwaitAllowed;
8252
8253
return markerApply(
8254
marker,
8255
delegate.createFunctionDeclaration(
8256
id,
8257
tmp.params,
8258
tmp.defaults,
8259
body,
8260
tmp.rest,
8261
generator,
8262
false,
8263
isAsync,
8264
tmp.returnType,
8265
typeParameters
8266
)
8267
);
8268
}
8269
8270
function parseFunctionExpression() {
8271
var token, id = null, firstRestricted, message, tmp, body, generator, isAsync,
8272
previousStrict, previousYieldAllowed, previousAwaitAllowed,
8273
marker = markerCreate(), typeParameters;
8274
8275
isAsync = false;
8276
if (matchAsync()) {
8277
lex();
8278
isAsync = true;
8279
}
8280
8281
expectKeyword('function');
8282
8283
generator = false;
8284
8285
if (match('*')) {
8286
lex();
8287
generator = true;
8288
}
8289
8290
if (!match('(')) {
8291
if (!match('<')) {
8292
token = lookahead;
8293
id = parseVariableIdentifier();
8294
8295
if (strict) {
8296
if (isRestrictedWord(token.value)) {
8297
throwErrorTolerant(token, Messages.StrictFunctionName);
8298
}
8299
} else {
8300
if (isRestrictedWord(token.value)) {
8301
firstRestricted = token;
8302
message = Messages.StrictFunctionName;
8303
} else if (isStrictModeReservedWord(token.value)) {
8304
firstRestricted = token;
8305
message = Messages.StrictReservedWord;
8306
}
8307
}
8308
}
8309
8310
if (match('<')) {
8311
typeParameters = parseTypeParameterDeclaration();
8312
}
8313
}
8314
8315
tmp = parseParams(firstRestricted);
8316
firstRestricted = tmp.firstRestricted;
8317
if (tmp.message) {
8318
message = tmp.message;
8319
}
8320
8321
previousStrict = strict;
8322
previousYieldAllowed = state.yieldAllowed;
8323
state.yieldAllowed = generator;
8324
previousAwaitAllowed = state.awaitAllowed;
8325
state.awaitAllowed = isAsync;
8326
8327
body = parseFunctionSourceElements();
8328
8329
if (strict && firstRestricted) {
8330
throwError(firstRestricted, message);
8331
}
8332
if (strict && tmp.stricted) {
8333
throwErrorTolerant(tmp.stricted, message);
8334
}
8335
strict = previousStrict;
8336
state.yieldAllowed = previousYieldAllowed;
8337
state.awaitAllowed = previousAwaitAllowed;
8338
8339
return markerApply(
8340
marker,
8341
delegate.createFunctionExpression(
8342
id,
8343
tmp.params,
8344
tmp.defaults,
8345
body,
8346
tmp.rest,
8347
generator,
8348
false,
8349
isAsync,
8350
tmp.returnType,
8351
typeParameters
8352
)
8353
);
8354
}
8355
8356
function parseYieldExpression() {
8357
var delegateFlag, expr, marker = markerCreate();
8358
8359
expectKeyword('yield', !strict);
8360
8361
delegateFlag = false;
8362
if (match('*')) {
8363
lex();
8364
delegateFlag = true;
8365
}
8366
8367
expr = parseAssignmentExpression();
8368
8369
return markerApply(marker, delegate.createYieldExpression(expr, delegateFlag));
8370
}
8371
8372
function parseAwaitExpression() {
8373
var expr, marker = markerCreate();
8374
expectContextualKeyword('await');
8375
expr = parseAssignmentExpression();
8376
return markerApply(marker, delegate.createAwaitExpression(expr));
8377
}
8378
8379
// 14 Functions and classes
8380
8381
// 14.1 Functions is defined above (13 in ES5)
8382
// 14.2 Arrow Functions Definitions is defined in (7.3 assignments)
8383
8384
// 14.3 Method Definitions
8385
// 14.3.7
8386
function specialMethod(methodDefinition) {
8387
return methodDefinition.kind === 'get' ||
8388
methodDefinition.kind === 'set' ||
8389
methodDefinition.value.generator;
8390
}
8391
8392
function parseMethodDefinition(key, isStatic, generator, computed) {
8393
var token, param, propType,
8394
isAsync, typeParameters, tokenValue, returnType;
8395
8396
propType = isStatic ? ClassPropertyType["static"] : ClassPropertyType.prototype;
8397
8398
if (generator) {
8399
return delegate.createMethodDefinition(
8400
propType,
8401
'',
8402
key,
8403
parsePropertyMethodFunction({ generator: true }),
8404
computed
8405
);
8406
}
8407
8408
tokenValue = key.type === 'Identifier' && key.name;
8409
8410
if (tokenValue === 'get' && !match('(')) {
8411
key = parseObjectPropertyKey();
8412
8413
expect('(');
8414
expect(')');
8415
if (match(':')) {
8416
returnType = parseTypeAnnotation();
8417
}
8418
return delegate.createMethodDefinition(
8419
propType,
8420
'get',
8421
key,
8422
parsePropertyFunction({ generator: false, returnType: returnType }),
8423
computed
8424
);
8425
}
8426
if (tokenValue === 'set' && !match('(')) {
8427
key = parseObjectPropertyKey();
8428
8429
expect('(');
8430
token = lookahead;
8431
param = [ parseTypeAnnotatableIdentifier() ];
8432
expect(')');
8433
if (match(':')) {
8434
returnType = parseTypeAnnotation();
8435
}
8436
return delegate.createMethodDefinition(
8437
propType,
8438
'set',
8439
key,
8440
parsePropertyFunction({
8441
params: param,
8442
generator: false,
8443
name: token,
8444
returnType: returnType
8445
}),
8446
computed
8447
);
8448
}
8449
8450
if (match('<')) {
8451
typeParameters = parseTypeParameterDeclaration();
8452
}
8453
8454
isAsync = tokenValue === 'async' && !match('(');
8455
if (isAsync) {
8456
key = parseObjectPropertyKey();
8457
}
8458
8459
return delegate.createMethodDefinition(
8460
propType,
8461
'',
8462
key,
8463
parsePropertyMethodFunction({
8464
generator: false,
8465
async: isAsync,
8466
typeParameters: typeParameters
8467
}),
8468
computed
8469
);
8470
}
8471
8472
function parseClassProperty(key, computed, isStatic) {
8473
var typeAnnotation;
8474
8475
typeAnnotation = parseTypeAnnotation();
8476
expect(';');
8477
8478
return delegate.createClassProperty(
8479
key,
8480
typeAnnotation,
8481
computed,
8482
isStatic
8483
);
8484
}
8485
8486
function parseClassElement() {
8487
var computed = false, generator = false, key, marker = markerCreate(),
8488
isStatic = false, possiblyOpenBracketToken;
8489
if (match(';')) {
8490
lex();
8491
return undefined;
8492
}
8493
8494
if (lookahead.value === 'static') {
8495
lex();
8496
isStatic = true;
8497
}
8498
8499
if (match('*')) {
8500
lex();
8501
generator = true;
8502
}
8503
8504
possiblyOpenBracketToken = lookahead;
8505
if (matchContextualKeyword('get') || matchContextualKeyword('set')) {
8506
possiblyOpenBracketToken = lookahead2();
8507
}
8508
8509
if (possiblyOpenBracketToken.type === Token.Punctuator
8510
&& possiblyOpenBracketToken.value === '[') {
8511
computed = true;
8512
}
8513
8514
key = parseObjectPropertyKey();
8515
8516
if (!generator && lookahead.value === ':') {
8517
return markerApply(marker, parseClassProperty(key, computed, isStatic));
8518
}
8519
8520
return markerApply(marker, parseMethodDefinition(
8521
key,
8522
isStatic,
8523
generator,
8524
computed
8525
));
8526
}
8527
8528
function parseClassBody() {
8529
var classElement, classElements = [], existingProps = {},
8530
marker = markerCreate(), propName, propType;
8531
8532
existingProps[ClassPropertyType["static"]] = new StringMap();
8533
existingProps[ClassPropertyType.prototype] = new StringMap();
8534
8535
expect('{');
8536
8537
while (index < length) {
8538
if (match('}')) {
8539
break;
8540
}
8541
classElement = parseClassElement(existingProps);
8542
8543
if (typeof classElement !== 'undefined') {
8544
classElements.push(classElement);
8545
8546
propName = !classElement.computed && getFieldName(classElement.key);
8547
if (propName !== false) {
8548
propType = classElement["static"] ?
8549
ClassPropertyType["static"] :
8550
ClassPropertyType.prototype;
8551
8552
if (classElement.type === Syntax.MethodDefinition) {
8553
if (propName === 'constructor' && !classElement["static"]) {
8554
if (specialMethod(classElement)) {
8555
throwError(classElement, Messages.IllegalClassConstructorProperty);
8556
}
8557
if (existingProps[ClassPropertyType.prototype].has('constructor')) {
8558
throwError(classElement.key, Messages.IllegalDuplicateClassProperty);
8559
}
8560
}
8561
existingProps[propType].set(propName, true);
8562
}
8563
}
8564
}
8565
}
8566
8567
expect('}');
8568
8569
return markerApply(marker, delegate.createClassBody(classElements));
8570
}
8571
8572
function parseClassImplements() {
8573
var id, implemented = [], marker, typeParameters;
8574
if (strict) {
8575
expectKeyword('implements');
8576
} else {
8577
expectContextualKeyword('implements');
8578
}
8579
while (index < length) {
8580
marker = markerCreate();
8581
id = parseVariableIdentifier();
8582
if (match('<')) {
8583
typeParameters = parseTypeParameterInstantiation();
8584
} else {
8585
typeParameters = null;
8586
}
8587
implemented.push(markerApply(marker, delegate.createClassImplements(
8588
id,
8589
typeParameters
8590
)));
8591
if (!match(',')) {
8592
break;
8593
}
8594
expect(',');
8595
}
8596
return implemented;
8597
}
8598
8599
function parseClassExpression() {
8600
var id, implemented, previousYieldAllowed, superClass = null,
8601
superTypeParameters, marker = markerCreate(), typeParameters,
8602
matchImplements;
8603
8604
expectKeyword('class');
8605
8606
matchImplements =
8607
strict
8608
? matchKeyword('implements')
8609
: matchContextualKeyword('implements');
8610
8611
if (!matchKeyword('extends') && !matchImplements && !match('{')) {
8612
id = parseVariableIdentifier();
8613
}
8614
8615
if (match('<')) {
8616
typeParameters = parseTypeParameterDeclaration();
8617
}
8618
8619
if (matchKeyword('extends')) {
8620
expectKeyword('extends');
8621
previousYieldAllowed = state.yieldAllowed;
8622
state.yieldAllowed = false;
8623
superClass = parseLeftHandSideExpressionAllowCall();
8624
if (match('<')) {
8625
superTypeParameters = parseTypeParameterInstantiation();
8626
}
8627
state.yieldAllowed = previousYieldAllowed;
8628
}
8629
8630
if (strict ? matchKeyword('implements') : matchContextualKeyword('implements')) {
8631
implemented = parseClassImplements();
8632
}
8633
8634
return markerApply(marker, delegate.createClassExpression(
8635
id,
8636
superClass,
8637
parseClassBody(),
8638
typeParameters,
8639
superTypeParameters,
8640
implemented
8641
));
8642
}
8643
8644
function parseClassDeclaration() {
8645
var id, implemented, previousYieldAllowed, superClass = null,
8646
superTypeParameters, marker = markerCreate(), typeParameters;
8647
8648
expectKeyword('class');
8649
8650
id = parseVariableIdentifier();
8651
8652
if (match('<')) {
8653
typeParameters = parseTypeParameterDeclaration();
8654
}
8655
8656
if (matchKeyword('extends')) {
8657
expectKeyword('extends');
8658
previousYieldAllowed = state.yieldAllowed;
8659
state.yieldAllowed = false;
8660
superClass = parseLeftHandSideExpressionAllowCall();
8661
if (match('<')) {
8662
superTypeParameters = parseTypeParameterInstantiation();
8663
}
8664
state.yieldAllowed = previousYieldAllowed;
8665
}
8666
8667
if (strict ? matchKeyword('implements') : matchContextualKeyword('implements')) {
8668
implemented = parseClassImplements();
8669
}
8670
8671
return markerApply(marker, delegate.createClassDeclaration(
8672
id,
8673
superClass,
8674
parseClassBody(),
8675
typeParameters,
8676
superTypeParameters,
8677
implemented
8678
));
8679
}
8680
8681
// 15 Program
8682
8683
function parseSourceElement() {
8684
var token;
8685
if (lookahead.type === Token.Keyword) {
8686
switch (lookahead.value) {
8687
case 'const':
8688
case 'let':
8689
return parseConstLetDeclaration(lookahead.value);
8690
case 'function':
8691
return parseFunctionDeclaration();
8692
case 'export':
8693
throwErrorTolerant({}, Messages.IllegalExportDeclaration);
8694
return parseExportDeclaration();
8695
case 'import':
8696
throwErrorTolerant({}, Messages.IllegalImportDeclaration);
8697
return parseImportDeclaration();
8698
case 'interface':
8699
if (lookahead2().type === Token.Identifier) {
8700
return parseInterface();
8701
}
8702
return parseStatement();
8703
default:
8704
return parseStatement();
8705
}
8706
}
8707
8708
if (matchContextualKeyword('type')
8709
&& lookahead2().type === Token.Identifier) {
8710
return parseTypeAlias();
8711
}
8712
8713
if (matchContextualKeyword('interface')
8714
&& lookahead2().type === Token.Identifier) {
8715
return parseInterface();
8716
}
8717
8718
if (matchContextualKeyword('declare')) {
8719
token = lookahead2();
8720
if (token.type === Token.Keyword) {
8721
switch (token.value) {
8722
case 'class':
8723
return parseDeclareClass();
8724
case 'function':
8725
return parseDeclareFunction();
8726
case 'var':
8727
return parseDeclareVariable();
8728
}
8729
} else if (token.type === Token.Identifier
8730
&& token.value === 'module') {
8731
return parseDeclareModule();
8732
}
8733
}
8734
8735
if (lookahead.type !== Token.EOF) {
8736
return parseStatement();
8737
}
8738
}
8739
8740
function parseProgramElement() {
8741
var isModule = extra.sourceType === 'module' || extra.sourceType === 'nonStrictModule';
8742
8743
if (isModule && lookahead.type === Token.Keyword) {
8744
switch (lookahead.value) {
8745
case 'export':
8746
return parseExportDeclaration();
8747
case 'import':
8748
return parseImportDeclaration();
8749
}
8750
}
8751
8752
return parseSourceElement();
8753
}
8754
8755
function parseProgramElements() {
8756
var sourceElement, sourceElements = [], token, directive, firstRestricted;
8757
8758
while (index < length) {
8759
token = lookahead;
8760
if (token.type !== Token.StringLiteral) {
8761
break;
8762
}
8763
8764
sourceElement = parseProgramElement();
8765
sourceElements.push(sourceElement);
8766
if (sourceElement.expression.type !== Syntax.Literal) {
8767
// this is not directive
8768
break;
8769
}
8770
directive = source.slice(token.range[0] + 1, token.range[1] - 1);
8771
if (directive === 'use strict') {
8772
strict = true;
8773
if (firstRestricted) {
8774
throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral);
8775
}
8776
} else {
8777
if (!firstRestricted && token.octal) {
8778
firstRestricted = token;
8779
}
8780
}
8781
}
8782
8783
while (index < length) {
8784
sourceElement = parseProgramElement();
8785
if (typeof sourceElement === 'undefined') {
8786
break;
8787
}
8788
sourceElements.push(sourceElement);
8789
}
8790
return sourceElements;
8791
}
8792
8793
function parseProgram() {
8794
var body, marker = markerCreate();
8795
strict = extra.sourceType === 'module';
8796
peek();
8797
body = parseProgramElements();
8798
return markerApply(marker, delegate.createProgram(body));
8799
}
8800
8801
// 16 JSX
8802
8803
XHTMLEntities = {
8804
quot: '\u0022',
8805
amp: '&',
8806
apos: '\u0027',
8807
lt: '<',
8808
gt: '>',
8809
nbsp: '\u00A0',
8810
iexcl: '\u00A1',
8811
cent: '\u00A2',
8812
pound: '\u00A3',
8813
curren: '\u00A4',
8814
yen: '\u00A5',
8815
brvbar: '\u00A6',
8816
sect: '\u00A7',
8817
uml: '\u00A8',
8818
copy: '\u00A9',
8819
ordf: '\u00AA',
8820
laquo: '\u00AB',
8821
not: '\u00AC',
8822
shy: '\u00AD',
8823
reg: '\u00AE',
8824
macr: '\u00AF',
8825
deg: '\u00B0',
8826
plusmn: '\u00B1',
8827
sup2: '\u00B2',
8828
sup3: '\u00B3',
8829
acute: '\u00B4',
8830
micro: '\u00B5',
8831
para: '\u00B6',
8832
middot: '\u00B7',
8833
cedil: '\u00B8',
8834
sup1: '\u00B9',
8835
ordm: '\u00BA',
8836
raquo: '\u00BB',
8837
frac14: '\u00BC',
8838
frac12: '\u00BD',
8839
frac34: '\u00BE',
8840
iquest: '\u00BF',
8841
Agrave: '\u00C0',
8842
Aacute: '\u00C1',
8843
Acirc: '\u00C2',
8844
Atilde: '\u00C3',
8845
Auml: '\u00C4',
8846
Aring: '\u00C5',
8847
AElig: '\u00C6',
8848
Ccedil: '\u00C7',
8849
Egrave: '\u00C8',
8850
Eacute: '\u00C9',
8851
Ecirc: '\u00CA',
8852
Euml: '\u00CB',
8853
Igrave: '\u00CC',
8854
Iacute: '\u00CD',
8855
Icirc: '\u00CE',
8856
Iuml: '\u00CF',
8857
ETH: '\u00D0',
8858
Ntilde: '\u00D1',
8859
Ograve: '\u00D2',
8860
Oacute: '\u00D3',
8861
Ocirc: '\u00D4',
8862
Otilde: '\u00D5',
8863
Ouml: '\u00D6',
8864
times: '\u00D7',
8865
Oslash: '\u00D8',
8866
Ugrave: '\u00D9',
8867
Uacute: '\u00DA',
8868
Ucirc: '\u00DB',
8869
Uuml: '\u00DC',
8870
Yacute: '\u00DD',
8871
THORN: '\u00DE',
8872
szlig: '\u00DF',
8873
agrave: '\u00E0',
8874
aacute: '\u00E1',
8875
acirc: '\u00E2',
8876
atilde: '\u00E3',
8877
auml: '\u00E4',
8878
aring: '\u00E5',
8879
aelig: '\u00E6',
8880
ccedil: '\u00E7',
8881
egrave: '\u00E8',
8882
eacute: '\u00E9',
8883
ecirc: '\u00EA',
8884
euml: '\u00EB',
8885
igrave: '\u00EC',
8886
iacute: '\u00ED',
8887
icirc: '\u00EE',
8888
iuml: '\u00EF',
8889
eth: '\u00F0',
8890
ntilde: '\u00F1',
8891
ograve: '\u00F2',
8892
oacute: '\u00F3',
8893
ocirc: '\u00F4',
8894
otilde: '\u00F5',
8895
ouml: '\u00F6',
8896
divide: '\u00F7',
8897
oslash: '\u00F8',
8898
ugrave: '\u00F9',
8899
uacute: '\u00FA',
8900
ucirc: '\u00FB',
8901
uuml: '\u00FC',
8902
yacute: '\u00FD',
8903
thorn: '\u00FE',
8904
yuml: '\u00FF',
8905
OElig: '\u0152',
8906
oelig: '\u0153',
8907
Scaron: '\u0160',
8908
scaron: '\u0161',
8909
Yuml: '\u0178',
8910
fnof: '\u0192',
8911
circ: '\u02C6',
8912
tilde: '\u02DC',
8913
Alpha: '\u0391',
8914
Beta: '\u0392',
8915
Gamma: '\u0393',
8916
Delta: '\u0394',
8917
Epsilon: '\u0395',
8918
Zeta: '\u0396',
8919
Eta: '\u0397',
8920
Theta: '\u0398',
8921
Iota: '\u0399',
8922
Kappa: '\u039A',
8923
Lambda: '\u039B',
8924
Mu: '\u039C',
8925
Nu: '\u039D',
8926
Xi: '\u039E',
8927
Omicron: '\u039F',
8928
Pi: '\u03A0',
8929
Rho: '\u03A1',
8930
Sigma: '\u03A3',
8931
Tau: '\u03A4',
8932
Upsilon: '\u03A5',
8933
Phi: '\u03A6',
8934
Chi: '\u03A7',
8935
Psi: '\u03A8',
8936
Omega: '\u03A9',
8937
alpha: '\u03B1',
8938
beta: '\u03B2',
8939
gamma: '\u03B3',
8940
delta: '\u03B4',
8941
epsilon: '\u03B5',
8942
zeta: '\u03B6',
8943
eta: '\u03B7',
8944
theta: '\u03B8',
8945
iota: '\u03B9',
8946
kappa: '\u03BA',
8947
lambda: '\u03BB',
8948
mu: '\u03BC',
8949
nu: '\u03BD',
8950
xi: '\u03BE',
8951
omicron: '\u03BF',
8952
pi: '\u03C0',
8953
rho: '\u03C1',
8954
sigmaf: '\u03C2',
8955
sigma: '\u03C3',
8956
tau: '\u03C4',
8957
upsilon: '\u03C5',
8958
phi: '\u03C6',
8959
chi: '\u03C7',
8960
psi: '\u03C8',
8961
omega: '\u03C9',
8962
thetasym: '\u03D1',
8963
upsih: '\u03D2',
8964
piv: '\u03D6',
8965
ensp: '\u2002',
8966
emsp: '\u2003',
8967
thinsp: '\u2009',
8968
zwnj: '\u200C',
8969
zwj: '\u200D',
8970
lrm: '\u200E',
8971
rlm: '\u200F',
8972
ndash: '\u2013',
8973
mdash: '\u2014',
8974
lsquo: '\u2018',
8975
rsquo: '\u2019',
8976
sbquo: '\u201A',
8977
ldquo: '\u201C',
8978
rdquo: '\u201D',
8979
bdquo: '\u201E',
8980
dagger: '\u2020',
8981
Dagger: '\u2021',
8982
bull: '\u2022',
8983
hellip: '\u2026',
8984
permil: '\u2030',
8985
prime: '\u2032',
8986
Prime: '\u2033',
8987
lsaquo: '\u2039',
8988
rsaquo: '\u203A',
8989
oline: '\u203E',
8990
frasl: '\u2044',
8991
euro: '\u20AC',
8992
image: '\u2111',
8993
weierp: '\u2118',
8994
real: '\u211C',
8995
trade: '\u2122',
8996
alefsym: '\u2135',
8997
larr: '\u2190',
8998
uarr: '\u2191',
8999
rarr: '\u2192',
9000
darr: '\u2193',
9001
harr: '\u2194',
9002
crarr: '\u21B5',
9003
lArr: '\u21D0',
9004
uArr: '\u21D1',
9005
rArr: '\u21D2',
9006
dArr: '\u21D3',
9007
hArr: '\u21D4',
9008
forall: '\u2200',
9009
part: '\u2202',
9010
exist: '\u2203',
9011
empty: '\u2205',
9012
nabla: '\u2207',
9013
isin: '\u2208',
9014
notin: '\u2209',
9015
ni: '\u220B',
9016
prod: '\u220F',
9017
sum: '\u2211',
9018
minus: '\u2212',
9019
lowast: '\u2217',
9020
radic: '\u221A',
9021
prop: '\u221D',
9022
infin: '\u221E',
9023
ang: '\u2220',
9024
and: '\u2227',
9025
or: '\u2228',
9026
cap: '\u2229',
9027
cup: '\u222A',
9028
'int': '\u222B',
9029
there4: '\u2234',
9030
sim: '\u223C',
9031
cong: '\u2245',
9032
asymp: '\u2248',
9033
ne: '\u2260',
9034
equiv: '\u2261',
9035
le: '\u2264',
9036
ge: '\u2265',
9037
sub: '\u2282',
9038
sup: '\u2283',
9039
nsub: '\u2284',
9040
sube: '\u2286',
9041
supe: '\u2287',
9042
oplus: '\u2295',
9043
otimes: '\u2297',
9044
perp: '\u22A5',
9045
sdot: '\u22C5',
9046
lceil: '\u2308',
9047
rceil: '\u2309',
9048
lfloor: '\u230A',
9049
rfloor: '\u230B',
9050
lang: '\u2329',
9051
rang: '\u232A',
9052
loz: '\u25CA',
9053
spades: '\u2660',
9054
clubs: '\u2663',
9055
hearts: '\u2665',
9056
diams: '\u2666'
9057
};
9058
9059
function getQualifiedJSXName(object) {
9060
if (object.type === Syntax.JSXIdentifier) {
9061
return object.name;
9062
}
9063
if (object.type === Syntax.JSXNamespacedName) {
9064
return object.namespace.name + ':' + object.name.name;
9065
}
9066
/* istanbul ignore else */
9067
if (object.type === Syntax.JSXMemberExpression) {
9068
return (
9069
getQualifiedJSXName(object.object) + '.' +
9070
getQualifiedJSXName(object.property)
9071
);
9072
}
9073
/* istanbul ignore next */
9074
throwUnexpected(object);
9075
}
9076
9077
function isJSXIdentifierStart(ch) {
9078
// exclude backslash (\)
9079
return (ch !== 92) && isIdentifierStart(ch);
9080
}
9081
9082
function isJSXIdentifierPart(ch) {
9083
// exclude backslash (\) and add hyphen (-)
9084
return (ch !== 92) && (ch === 45 || isIdentifierPart(ch));
9085
}
9086
9087
function scanJSXIdentifier() {
9088
var ch, start, value = '';
9089
9090
start = index;
9091
while (index < length) {
9092
ch = source.charCodeAt(index);
9093
if (!isJSXIdentifierPart(ch)) {
9094
break;
9095
}
9096
value += source[index++];
9097
}
9098
9099
return {
9100
type: Token.JSXIdentifier,
9101
value: value,
9102
lineNumber: lineNumber,
9103
lineStart: lineStart,
9104
range: [start, index]
9105
};
9106
}
9107
9108
function scanJSXEntity() {
9109
var ch, str = '', start = index, count = 0, code;
9110
ch = source[index];
9111
assert(ch === '&', 'Entity must start with an ampersand');
9112
index++;
9113
while (index < length && count++ < 10) {
9114
ch = source[index++];
9115
if (ch === ';') {
9116
break;
9117
}
9118
str += ch;
9119
}
9120
9121
// Well-formed entity (ending was found).
9122
if (ch === ';') {
9123
// Numeric entity.
9124
if (str[0] === '#') {
9125
if (str[1] === 'x') {
9126
code = +('0' + str.substr(1));
9127
} else {
9128
// Removing leading zeros in order to avoid treating as octal in old browsers.
9129
code = +str.substr(1).replace(Regex.LeadingZeros, '');
9130
}
9131
9132
if (!isNaN(code)) {
9133
return String.fromCharCode(code);
9134
}
9135
/* istanbul ignore else */
9136
} else if (XHTMLEntities[str]) {
9137
return XHTMLEntities[str];
9138
}
9139
}
9140
9141
// Treat non-entity sequences as regular text.
9142
index = start + 1;
9143
return '&';
9144
}
9145
9146
function scanJSXText(stopChars) {
9147
var ch, str = '', start;
9148
start = index;
9149
while (index < length) {
9150
ch = source[index];
9151
if (stopChars.indexOf(ch) !== -1) {
9152
break;
9153
}
9154
if (ch === '&') {
9155
str += scanJSXEntity();
9156
} else {
9157
index++;
9158
if (ch === '\r' && source[index] === '\n') {
9159
str += ch;
9160
ch = source[index];
9161
index++;
9162
}
9163
if (isLineTerminator(ch.charCodeAt(0))) {
9164
++lineNumber;
9165
lineStart = index;
9166
}
9167
str += ch;
9168
}
9169
}
9170
return {
9171
type: Token.JSXText,
9172
value: str,
9173
lineNumber: lineNumber,
9174
lineStart: lineStart,
9175
range: [start, index]
9176
};
9177
}
9178
9179
function scanJSXStringLiteral() {
9180
var innerToken, quote, start;
9181
9182
quote = source[index];
9183
assert((quote === '\'' || quote === '"'),
9184
'String literal must starts with a quote');
9185
9186
start = index;
9187
++index;
9188
9189
innerToken = scanJSXText([quote]);
9190
9191
if (quote !== source[index]) {
9192
throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
9193
}
9194
9195
++index;
9196
9197
innerToken.range = [start, index];
9198
9199
return innerToken;
9200
}
9201
9202
/**
9203
* Between JSX opening and closing tags (e.g. <foo>HERE</foo>), anything that
9204
* is not another JSX tag and is not an expression wrapped by {} is text.
9205
*/
9206
function advanceJSXChild() {
9207
var ch = source.charCodeAt(index);
9208
9209
// '<' 60, '>' 62, '{' 123, '}' 125
9210
if (ch !== 60 && ch !== 62 && ch !== 123 && ch !== 125) {
9211
return scanJSXText(['<', '>', '{', '}']);
9212
}
9213
9214
return scanPunctuator();
9215
}
9216
9217
function parseJSXIdentifier() {
9218
var token, marker = markerCreate();
9219
9220
if (lookahead.type !== Token.JSXIdentifier) {
9221
throwUnexpected(lookahead);
9222
}
9223
9224
token = lex();
9225
return markerApply(marker, delegate.createJSXIdentifier(token.value));
9226
}
9227
9228
function parseJSXNamespacedName() {
9229
var namespace, name, marker = markerCreate();
9230
9231
namespace = parseJSXIdentifier();
9232
expect(':');
9233
name = parseJSXIdentifier();
9234
9235
return markerApply(marker, delegate.createJSXNamespacedName(namespace, name));
9236
}
9237
9238
function parseJSXMemberExpression() {
9239
var marker = markerCreate(),
9240
expr = parseJSXIdentifier();
9241
9242
while (match('.')) {
9243
lex();
9244
expr = markerApply(marker, delegate.createJSXMemberExpression(expr, parseJSXIdentifier()));
9245
}
9246
9247
return expr;
9248
}
9249
9250
function parseJSXElementName() {
9251
if (lookahead2().value === ':') {
9252
return parseJSXNamespacedName();
9253
}
9254
if (lookahead2().value === '.') {
9255
return parseJSXMemberExpression();
9256
}
9257
9258
return parseJSXIdentifier();
9259
}
9260
9261
function parseJSXAttributeName() {
9262
if (lookahead2().value === ':') {
9263
return parseJSXNamespacedName();
9264
}
9265
9266
return parseJSXIdentifier();
9267
}
9268
9269
function parseJSXAttributeValue() {
9270
var value, marker;
9271
if (match('{')) {
9272
value = parseJSXExpressionContainer();
9273
if (value.expression.type === Syntax.JSXEmptyExpression) {
9274
throwError(
9275
value,
9276
'JSX attributes must only be assigned a non-empty ' +
9277
'expression'
9278
);
9279
}
9280
} else if (match('<')) {
9281
value = parseJSXElement();
9282
} else if (lookahead.type === Token.JSXText) {
9283
marker = markerCreate();
9284
value = markerApply(marker, delegate.createLiteral(lex()));
9285
} else {
9286
throwError({}, Messages.InvalidJSXAttributeValue);
9287
}
9288
return value;
9289
}
9290
9291
function parseJSXEmptyExpression() {
9292
var marker = markerCreatePreserveWhitespace();
9293
while (source.charAt(index) !== '}') {
9294
index++;
9295
}
9296
return markerApply(marker, delegate.createJSXEmptyExpression());
9297
}
9298
9299
function parseJSXExpressionContainer() {
9300
var expression, origInJSXChild, origInJSXTag, marker = markerCreate();
9301
9302
origInJSXChild = state.inJSXChild;
9303
origInJSXTag = state.inJSXTag;
9304
state.inJSXChild = false;
9305
state.inJSXTag = false;
9306
9307
expect('{');
9308
9309
if (match('}')) {
9310
expression = parseJSXEmptyExpression();
9311
} else {
9312
expression = parseExpression();
9313
}
9314
9315
state.inJSXChild = origInJSXChild;
9316
state.inJSXTag = origInJSXTag;
9317
9318
expect('}');
9319
9320
return markerApply(marker, delegate.createJSXExpressionContainer(expression));
9321
}
9322
9323
function parseJSXSpreadAttribute() {
9324
var expression, origInJSXChild, origInJSXTag, marker = markerCreate();
9325
9326
origInJSXChild = state.inJSXChild;
9327
origInJSXTag = state.inJSXTag;
9328
state.inJSXChild = false;
9329
state.inJSXTag = false;
9330
9331
expect('{');
9332
expect('...');
9333
9334
expression = parseAssignmentExpression();
9335
9336
state.inJSXChild = origInJSXChild;
9337
state.inJSXTag = origInJSXTag;
9338
9339
expect('}');
9340
9341
return markerApply(marker, delegate.createJSXSpreadAttribute(expression));
9342
}
9343
9344
function parseJSXAttribute() {
9345
var name, marker;
9346
9347
if (match('{')) {
9348
return parseJSXSpreadAttribute();
9349
}
9350
9351
marker = markerCreate();
9352
9353
name = parseJSXAttributeName();
9354
9355
// HTML empty attribute
9356
if (match('=')) {
9357
lex();
9358
return markerApply(marker, delegate.createJSXAttribute(name, parseJSXAttributeValue()));
9359
}
9360
9361
return markerApply(marker, delegate.createJSXAttribute(name));
9362
}
9363
9364
function parseJSXChild() {
9365
var token, marker;
9366
if (match('{')) {
9367
token = parseJSXExpressionContainer();
9368
} else if (lookahead.type === Token.JSXText) {
9369
marker = markerCreatePreserveWhitespace();
9370
token = markerApply(marker, delegate.createLiteral(lex()));
9371
} else if (match('<')) {
9372
token = parseJSXElement();
9373
} else {
9374
throwUnexpected(lookahead);
9375
}
9376
return token;
9377
}
9378
9379
function parseJSXClosingElement() {
9380
var name, origInJSXChild, origInJSXTag, marker = markerCreate();
9381
origInJSXChild = state.inJSXChild;
9382
origInJSXTag = state.inJSXTag;
9383
state.inJSXChild = false;
9384
state.inJSXTag = true;
9385
expect('<');
9386
expect('/');
9387
name = parseJSXElementName();
9388
// Because advance() (called by lex() called by expect()) expects there
9389
// to be a valid token after >, it needs to know whether to look for a
9390
// standard JS token or an JSX text node
9391
state.inJSXChild = origInJSXChild;
9392
state.inJSXTag = origInJSXTag;
9393
expect('>');
9394
return markerApply(marker, delegate.createJSXClosingElement(name));
9395
}
9396
9397
function parseJSXOpeningElement() {
9398
var name, attributes = [], selfClosing = false, origInJSXChild, origInJSXTag, marker = markerCreate();
9399
9400
origInJSXChild = state.inJSXChild;
9401
origInJSXTag = state.inJSXTag;
9402
state.inJSXChild = false;
9403
state.inJSXTag = true;
9404
9405
expect('<');
9406
9407
name = parseJSXElementName();
9408
9409
while (index < length &&
9410
lookahead.value !== '/' &&
9411
lookahead.value !== '>') {
9412
attributes.push(parseJSXAttribute());
9413
}
9414
9415
state.inJSXTag = origInJSXTag;
9416
9417
if (lookahead.value === '/') {
9418
expect('/');
9419
// Because advance() (called by lex() called by expect()) expects
9420
// there to be a valid token after >, it needs to know whether to
9421
// look for a standard JS token or an JSX text node
9422
state.inJSXChild = origInJSXChild;
9423
expect('>');
9424
selfClosing = true;
9425
} else {
9426
state.inJSXChild = true;
9427
expect('>');
9428
}
9429
return markerApply(marker, delegate.createJSXOpeningElement(name, attributes, selfClosing));
9430
}
9431
9432
function parseJSXElement() {
9433
var openingElement, closingElement = null, children = [], origInJSXChild, origInJSXTag, marker = markerCreate();
9434
9435
origInJSXChild = state.inJSXChild;
9436
origInJSXTag = state.inJSXTag;
9437
openingElement = parseJSXOpeningElement();
9438
9439
if (!openingElement.selfClosing) {
9440
while (index < length) {
9441
state.inJSXChild = false; // Call lookahead2() with inJSXChild = false because </ should not be considered in the child
9442
if (lookahead.value === '<' && lookahead2().value === '/') {
9443
break;
9444
}
9445
state.inJSXChild = true;
9446
children.push(parseJSXChild());
9447
}
9448
state.inJSXChild = origInJSXChild;
9449
state.inJSXTag = origInJSXTag;
9450
closingElement = parseJSXClosingElement();
9451
if (getQualifiedJSXName(closingElement.name) !== getQualifiedJSXName(openingElement.name)) {
9452
throwError({}, Messages.ExpectedJSXClosingTag, getQualifiedJSXName(openingElement.name));
9453
}
9454
}
9455
9456
// When (erroneously) writing two adjacent tags like
9457
//
9458
// var x = <div>one</div><div>two</div>;
9459
//
9460
// the default error message is a bit incomprehensible. Since it's
9461
// rarely (never?) useful to write a less-than sign after an JSX
9462
// element, we disallow it here in the parser in order to provide a
9463
// better error message. (In the rare case that the less-than operator
9464
// was intended, the left tag can be wrapped in parentheses.)
9465
if (!origInJSXChild && match('<')) {
9466
throwError(lookahead, Messages.AdjacentJSXElements);
9467
}
9468
9469
return markerApply(marker, delegate.createJSXElement(openingElement, closingElement, children));
9470
}
9471
9472
function parseTypeAlias() {
9473
var id, marker = markerCreate(), typeParameters = null, right;
9474
expectContextualKeyword('type');
9475
id = parseVariableIdentifier();
9476
if (match('<')) {
9477
typeParameters = parseTypeParameterDeclaration();
9478
}
9479
expect('=');
9480
right = parseType();
9481
consumeSemicolon();
9482
return markerApply(marker, delegate.createTypeAlias(id, typeParameters, right));
9483
}
9484
9485
function parseInterfaceExtends() {
9486
var marker = markerCreate(), id, typeParameters = null;
9487
9488
id = parseVariableIdentifier();
9489
if (match('<')) {
9490
typeParameters = parseTypeParameterInstantiation();
9491
}
9492
9493
return markerApply(marker, delegate.createInterfaceExtends(
9494
id,
9495
typeParameters
9496
));
9497
}
9498
9499
function parseInterfaceish(marker, allowStatic) {
9500
var body, bodyMarker, extended = [], id,
9501
typeParameters = null;
9502
9503
id = parseVariableIdentifier();
9504
if (match('<')) {
9505
typeParameters = parseTypeParameterDeclaration();
9506
}
9507
9508
if (matchKeyword('extends')) {
9509
expectKeyword('extends');
9510
9511
while (index < length) {
9512
extended.push(parseInterfaceExtends());
9513
if (!match(',')) {
9514
break;
9515
}
9516
expect(',');
9517
}
9518
}
9519
9520
bodyMarker = markerCreate();
9521
body = markerApply(bodyMarker, parseObjectType(allowStatic));
9522
9523
return markerApply(marker, delegate.createInterface(
9524
id,
9525
typeParameters,
9526
body,
9527
extended
9528
));
9529
}
9530
9531
function parseInterface() {
9532
var marker = markerCreate();
9533
9534
if (strict) {
9535
expectKeyword('interface');
9536
} else {
9537
expectContextualKeyword('interface');
9538
}
9539
9540
return parseInterfaceish(marker, /* allowStatic */false);
9541
}
9542
9543
function parseDeclareClass() {
9544
var marker = markerCreate(), ret;
9545
expectContextualKeyword('declare');
9546
expectKeyword('class');
9547
9548
ret = parseInterfaceish(marker, /* allowStatic */true);
9549
ret.type = Syntax.DeclareClass;
9550
return ret;
9551
}
9552
9553
function parseDeclareFunction() {
9554
var id, idMarker,
9555
marker = markerCreate(), params, returnType, rest, tmp,
9556
typeParameters = null, value, valueMarker;
9557
9558
expectContextualKeyword('declare');
9559
expectKeyword('function');
9560
idMarker = markerCreate();
9561
id = parseVariableIdentifier();
9562
9563
valueMarker = markerCreate();
9564
if (match('<')) {
9565
typeParameters = parseTypeParameterDeclaration();
9566
}
9567
expect('(');
9568
tmp = parseFunctionTypeParams();
9569
params = tmp.params;
9570
rest = tmp.rest;
9571
expect(')');
9572
9573
expect(':');
9574
returnType = parseType();
9575
9576
value = markerApply(valueMarker, delegate.createFunctionTypeAnnotation(
9577
params,
9578
returnType,
9579
rest,
9580
typeParameters
9581
));
9582
9583
id.typeAnnotation = markerApply(valueMarker, delegate.createTypeAnnotation(
9584
value
9585
));
9586
markerApply(idMarker, id);
9587
9588
consumeSemicolon();
9589
9590
return markerApply(marker, delegate.createDeclareFunction(
9591
id
9592
));
9593
}
9594
9595
function parseDeclareVariable() {
9596
var id, marker = markerCreate();
9597
expectContextualKeyword('declare');
9598
expectKeyword('var');
9599
id = parseTypeAnnotatableIdentifier();
9600
9601
consumeSemicolon();
9602
9603
return markerApply(marker, delegate.createDeclareVariable(
9604
id
9605
));
9606
}
9607
9608
function parseDeclareModule() {
9609
var body = [], bodyMarker, id, idMarker, marker = markerCreate(), token;
9610
expectContextualKeyword('declare');
9611
expectContextualKeyword('module');
9612
9613
if (lookahead.type === Token.StringLiteral) {
9614
if (strict && lookahead.octal) {
9615
throwErrorTolerant(lookahead, Messages.StrictOctalLiteral);
9616
}
9617
idMarker = markerCreate();
9618
id = markerApply(idMarker, delegate.createLiteral(lex()));
9619
} else {
9620
id = parseVariableIdentifier();
9621
}
9622
9623
bodyMarker = markerCreate();
9624
expect('{');
9625
while (index < length && !match('}')) {
9626
token = lookahead2();
9627
switch (token.value) {
9628
case 'class':
9629
body.push(parseDeclareClass());
9630
break;
9631
case 'function':
9632
body.push(parseDeclareFunction());
9633
break;
9634
case 'var':
9635
body.push(parseDeclareVariable());
9636
break;
9637
default:
9638
throwUnexpected(lookahead);
9639
}
9640
}
9641
expect('}');
9642
9643
return markerApply(marker, delegate.createDeclareModule(
9644
id,
9645
markerApply(bodyMarker, delegate.createBlockStatement(body))
9646
));
9647
}
9648
9649
function collectToken() {
9650
var loc, token, range, value, entry;
9651
9652
/* istanbul ignore else */
9653
if (!state.inJSXChild) {
9654
skipComment();
9655
}
9656
9657
loc = {
9658
start: {
9659
line: lineNumber,
9660
column: index - lineStart
9661
}
9662
};
9663
9664
token = extra.advance();
9665
loc.end = {
9666
line: lineNumber,
9667
column: index - lineStart
9668
};
9669
9670
if (token.type !== Token.EOF) {
9671
range = [token.range[0], token.range[1]];
9672
value = source.slice(token.range[0], token.range[1]);
9673
entry = {
9674
type: TokenName[token.type],
9675
value: value,
9676
range: range,
9677
loc: loc
9678
};
9679
if (token.regex) {
9680
entry.regex = {
9681
pattern: token.regex.pattern,
9682
flags: token.regex.flags
9683
};
9684
}
9685
extra.tokens.push(entry);
9686
}
9687
9688
return token;
9689
}
9690
9691
function collectRegex() {
9692
var pos, loc, regex, token;
9693
9694
skipComment();
9695
9696
pos = index;
9697
loc = {
9698
start: {
9699
line: lineNumber,
9700
column: index - lineStart
9701
}
9702
};
9703
9704
regex = extra.scanRegExp();
9705
loc.end = {
9706
line: lineNumber,
9707
column: index - lineStart
9708
};
9709
9710
if (!extra.tokenize) {
9711
/* istanbul ignore next */
9712
// Pop the previous token, which is likely '/' or '/='
9713
if (extra.tokens.length > 0) {
9714
token = extra.tokens[extra.tokens.length - 1];
9715
if (token.range[0] === pos && token.type === 'Punctuator') {
9716
if (token.value === '/' || token.value === '/=') {
9717
extra.tokens.pop();
9718
}
9719
}
9720
}
9721
9722
extra.tokens.push({
9723
type: 'RegularExpression',
9724
value: regex.literal,
9725
regex: regex.regex,
9726
range: [pos, index],
9727
loc: loc
9728
});
9729
}
9730
9731
return regex;
9732
}
9733
9734
function filterTokenLocation() {
9735
var i, entry, token, tokens = [];
9736
9737
for (i = 0; i < extra.tokens.length; ++i) {
9738
entry = extra.tokens[i];
9739
token = {
9740
type: entry.type,
9741
value: entry.value
9742
};
9743
if (entry.regex) {
9744
token.regex = {
9745
pattern: entry.regex.pattern,
9746
flags: entry.regex.flags
9747
};
9748
}
9749
if (extra.range) {
9750
token.range = entry.range;
9751
}
9752
if (extra.loc) {
9753
token.loc = entry.loc;
9754
}
9755
tokens.push(token);
9756
}
9757
9758
extra.tokens = tokens;
9759
}
9760
9761
function patch() {
9762
if (typeof extra.tokens !== 'undefined') {
9763
extra.advance = advance;
9764
extra.scanRegExp = scanRegExp;
9765
9766
advance = collectToken;
9767
scanRegExp = collectRegex;
9768
}
9769
}
9770
9771
function unpatch() {
9772
if (typeof extra.scanRegExp === 'function') {
9773
advance = extra.advance;
9774
scanRegExp = extra.scanRegExp;
9775
}
9776
}
9777
9778
// This is used to modify the delegate.
9779
9780
function extend(object, properties) {
9781
var entry, result = {};
9782
9783
for (entry in object) {
9784
/* istanbul ignore else */
9785
if (object.hasOwnProperty(entry)) {
9786
result[entry] = object[entry];
9787
}
9788
}
9789
9790
for (entry in properties) {
9791
/* istanbul ignore else */
9792
if (properties.hasOwnProperty(entry)) {
9793
result[entry] = properties[entry];
9794
}
9795
}
9796
9797
return result;
9798
}
9799
9800
function tokenize(code, options) {
9801
var toString,
9802
token,
9803
tokens;
9804
9805
toString = String;
9806
if (typeof code !== 'string' && !(code instanceof String)) {
9807
code = toString(code);
9808
}
9809
9810
delegate = SyntaxTreeDelegate;
9811
source = code;
9812
index = 0;
9813
lineNumber = (source.length > 0) ? 1 : 0;
9814
lineStart = 0;
9815
length = source.length;
9816
lookahead = null;
9817
state = {
9818
allowKeyword: true,
9819
allowIn: true,
9820
labelSet: new StringMap(),
9821
inFunctionBody: false,
9822
inIteration: false,
9823
inSwitch: false,
9824
lastCommentStart: -1
9825
};
9826
9827
extra = {};
9828
9829
// Options matching.
9830
options = options || {};
9831
9832
// Of course we collect tokens here.
9833
options.tokens = true;
9834
extra.tokens = [];
9835
extra.tokenize = true;
9836
// The following two fields are necessary to compute the Regex tokens.
9837
extra.openParenToken = -1;
9838
extra.openCurlyToken = -1;
9839
9840
extra.range = (typeof options.range === 'boolean') && options.range;
9841
extra.loc = (typeof options.loc === 'boolean') && options.loc;
9842
9843
if (typeof options.comment === 'boolean' && options.comment) {
9844
extra.comments = [];
9845
}
9846
if (typeof options.tolerant === 'boolean' && options.tolerant) {
9847
extra.errors = [];
9848
}
9849
9850
patch();
9851
9852
try {
9853
peek();
9854
if (lookahead.type === Token.EOF) {
9855
return extra.tokens;
9856
}
9857
9858
token = lex();
9859
while (lookahead.type !== Token.EOF) {
9860
try {
9861
token = lex();
9862
} catch (lexError) {
9863
token = lookahead;
9864
if (extra.errors) {
9865
extra.errors.push(lexError);
9866
// We have to break on the first error
9867
// to avoid infinite loops.
9868
break;
9869
} else {
9870
throw lexError;
9871
}
9872
}
9873
}
9874
9875
filterTokenLocation();
9876
tokens = extra.tokens;
9877
if (typeof extra.comments !== 'undefined') {
9878
tokens.comments = extra.comments;
9879
}
9880
if (typeof extra.errors !== 'undefined') {
9881
tokens.errors = extra.errors;
9882
}
9883
} catch (e) {
9884
throw e;
9885
} finally {
9886
unpatch();
9887
extra = {};
9888
}
9889
return tokens;
9890
}
9891
9892
function parse(code, options) {
9893
var program, toString;
9894
9895
toString = String;
9896
if (typeof code !== 'string' && !(code instanceof String)) {
9897
code = toString(code);
9898
}
9899
9900
delegate = SyntaxTreeDelegate;
9901
source = code;
9902
index = 0;
9903
lineNumber = (source.length > 0) ? 1 : 0;
9904
lineStart = 0;
9905
length = source.length;
9906
lookahead = null;
9907
state = {
9908
allowKeyword: false,
9909
allowIn: true,
9910
labelSet: new StringMap(),
9911
parenthesizedCount: 0,
9912
inFunctionBody: false,
9913
inIteration: false,
9914
inSwitch: false,
9915
inJSXChild: false,
9916
inJSXTag: false,
9917
inType: false,
9918
lastCommentStart: -1,
9919
yieldAllowed: false,
9920
awaitAllowed: false
9921
};
9922
9923
extra = {};
9924
if (typeof options !== 'undefined') {
9925
extra.range = (typeof options.range === 'boolean') && options.range;
9926
extra.loc = (typeof options.loc === 'boolean') && options.loc;
9927
extra.attachComment = (typeof options.attachComment === 'boolean') && options.attachComment;
9928
9929
if (extra.loc && options.source !== null && options.source !== undefined) {
9930
delegate = extend(delegate, {
9931
'postProcess': function (node) {
9932
node.loc.source = toString(options.source);
9933
return node;
9934
}
9935
});
9936
}
9937
9938
extra.sourceType = options.sourceType;
9939
if (typeof options.tokens === 'boolean' && options.tokens) {
9940
extra.tokens = [];
9941
}
9942
if (typeof options.comment === 'boolean' && options.comment) {
9943
extra.comments = [];
9944
}
9945
if (typeof options.tolerant === 'boolean' && options.tolerant) {
9946
extra.errors = [];
9947
}
9948
if (extra.attachComment) {
9949
extra.range = true;
9950
extra.comments = [];
9951
extra.bottomRightStack = [];
9952
extra.trailingComments = [];
9953
extra.leadingComments = [];
9954
}
9955
}
9956
9957
patch();
9958
try {
9959
program = parseProgram();
9960
if (typeof extra.comments !== 'undefined') {
9961
program.comments = extra.comments;
9962
}
9963
if (typeof extra.tokens !== 'undefined') {
9964
filterTokenLocation();
9965
program.tokens = extra.tokens;
9966
}
9967
if (typeof extra.errors !== 'undefined') {
9968
program.errors = extra.errors;
9969
}
9970
} catch (e) {
9971
throw e;
9972
} finally {
9973
unpatch();
9974
extra = {};
9975
}
9976
9977
return program;
9978
}
9979
9980
// Sync with *.json manifests.
9981
exports.version = '13001.1001.0-dev-harmony-fb';
9982
9983
exports.tokenize = tokenize;
9984
9985
exports.parse = parse;
9986
9987
// Deep copy.
9988
/* istanbul ignore next */
9989
exports.Syntax = (function () {
9990
var name, types = {};
9991
9992
if (typeof Object.create === 'function') {
9993
types = Object.create(null);
9994
}
9995
9996
for (name in Syntax) {
9997
if (Syntax.hasOwnProperty(name)) {
9998
types[name] = Syntax[name];
9999
}
10000
}
10001
10002
if (typeof Object.freeze === 'function') {
10003
Object.freeze(types);
10004
}
10005
10006
return types;
10007
}());
10008
10009
}));
10010
/* vim: set sw=4 ts=4 et tw=80 : */
10011
10012
},{}],10:[function(_dereq_,module,exports){
10013
var Base62 = (function (my) {
10014
my.chars = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
10015
10016
my.encode = function(i){
10017
if (i === 0) {return '0'}
10018
var s = ''
10019
while (i > 0) {
10020
s = this.chars[i % 62] + s
10021
i = Math.floor(i/62)
10022
}
10023
return s
10024
};
10025
my.decode = function(a,b,c,d){
10026
for (
10027
b = c = (
10028
a === (/\W|_|^$/.test(a += "") || a)
10029
) - 1;
10030
d = a.charCodeAt(c++);
10031
)
10032
b = b * 62 + d - [, 48, 29, 87][d >> 5];
10033
return b
10034
};
10035
10036
return my;
10037
}({}));
10038
10039
module.exports = Base62
10040
},{}],11:[function(_dereq_,module,exports){
10041
/*
10042
* Copyright 2009-2011 Mozilla Foundation and contributors
10043
* Licensed under the New BSD license. See LICENSE.txt or:
10044
* http://opensource.org/licenses/BSD-3-Clause
10045
*/
10046
exports.SourceMapGenerator = _dereq_('./source-map/source-map-generator').SourceMapGenerator;
10047
exports.SourceMapConsumer = _dereq_('./source-map/source-map-consumer').SourceMapConsumer;
10048
exports.SourceNode = _dereq_('./source-map/source-node').SourceNode;
10049
10050
},{"./source-map/source-map-consumer":16,"./source-map/source-map-generator":17,"./source-map/source-node":18}],12:[function(_dereq_,module,exports){
10051
/* -*- Mode: js; js-indent-level: 2; -*- */
10052
/*
10053
* Copyright 2011 Mozilla Foundation and contributors
10054
* Licensed under the New BSD license. See LICENSE or:
10055
* http://opensource.org/licenses/BSD-3-Clause
10056
*/
10057
if (typeof define !== 'function') {
10058
var define = _dereq_('amdefine')(module, _dereq_);
10059
}
10060
define(function (_dereq_, exports, module) {
10061
10062
var util = _dereq_('./util');
10063
10064
/**
10065
* A data structure which is a combination of an array and a set. Adding a new
10066
* member is O(1), testing for membership is O(1), and finding the index of an
10067
* element is O(1). Removing elements from the set is not supported. Only
10068
* strings are supported for membership.
10069
*/
10070
function ArraySet() {
10071
this._array = [];
10072
this._set = {};
10073
}
10074
10075
/**
10076
* Static method for creating ArraySet instances from an existing array.
10077
*/
10078
ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) {
10079
var set = new ArraySet();
10080
for (var i = 0, len = aArray.length; i < len; i++) {
10081
set.add(aArray[i], aAllowDuplicates);
10082
}
10083
return set;
10084
};
10085
10086
/**
10087
* Add the given string to this set.
10088
*
10089
* @param String aStr
10090
*/
10091
ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {
10092
var isDuplicate = this.has(aStr);
10093
var idx = this._array.length;
10094
if (!isDuplicate || aAllowDuplicates) {
10095
this._array.push(aStr);
10096
}
10097
if (!isDuplicate) {
10098
this._set[util.toSetString(aStr)] = idx;
10099
}
10100
};
10101
10102
/**
10103
* Is the given string a member of this set?
10104
*
10105
* @param String aStr
10106
*/
10107
ArraySet.prototype.has = function ArraySet_has(aStr) {
10108
return Object.prototype.hasOwnProperty.call(this._set,
10109
util.toSetString(aStr));
10110
};
10111
10112
/**
10113
* What is the index of the given string in the array?
10114
*
10115
* @param String aStr
10116
*/
10117
ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {
10118
if (this.has(aStr)) {
10119
return this._set[util.toSetString(aStr)];
10120
}
10121
throw new Error('"' + aStr + '" is not in the set.');
10122
};
10123
10124
/**
10125
* What is the element at the given index?
10126
*
10127
* @param Number aIdx
10128
*/
10129
ArraySet.prototype.at = function ArraySet_at(aIdx) {
10130
if (aIdx >= 0 && aIdx < this._array.length) {
10131
return this._array[aIdx];
10132
}
10133
throw new Error('No element indexed by ' + aIdx);
10134
};
10135
10136
/**
10137
* Returns the array representation of this set (which has the proper indices
10138
* indicated by indexOf). Note that this is a copy of the internal array used
10139
* for storing the members so that no one can mess with internal state.
10140
*/
10141
ArraySet.prototype.toArray = function ArraySet_toArray() {
10142
return this._array.slice();
10143
};
10144
10145
exports.ArraySet = ArraySet;
10146
10147
});
10148
10149
},{"./util":19,"amdefine":20}],13:[function(_dereq_,module,exports){
10150
/* -*- Mode: js; js-indent-level: 2; -*- */
10151
/*
10152
* Copyright 2011 Mozilla Foundation and contributors
10153
* Licensed under the New BSD license. See LICENSE or:
10154
* http://opensource.org/licenses/BSD-3-Clause
10155
*
10156
* Based on the Base 64 VLQ implementation in Closure Compiler:
10157
* https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java
10158
*
10159
* Copyright 2011 The Closure Compiler Authors. All rights reserved.
10160
* Redistribution and use in source and binary forms, with or without
10161
* modification, are permitted provided that the following conditions are
10162
* met:
10163
*
10164
* * Redistributions of source code must retain the above copyright
10165
* notice, this list of conditions and the following disclaimer.
10166
* * Redistributions in binary form must reproduce the above
10167
* copyright notice, this list of conditions and the following
10168
* disclaimer in the documentation and/or other materials provided
10169
* with the distribution.
10170
* * Neither the name of Google Inc. nor the names of its
10171
* contributors may be used to endorse or promote products derived
10172
* from this software without specific prior written permission.
10173
*
10174
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
10175
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
10176
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
10177
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
10178
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
10179
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
10180
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10181
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
10182
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
10183
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
10184
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
10185
*/
10186
if (typeof define !== 'function') {
10187
var define = _dereq_('amdefine')(module, _dereq_);
10188
}
10189
define(function (_dereq_, exports, module) {
10190
10191
var base64 = _dereq_('./base64');
10192
10193
// A single base 64 digit can contain 6 bits of data. For the base 64 variable
10194
// length quantities we use in the source map spec, the first bit is the sign,
10195
// the next four bits are the actual value, and the 6th bit is the
10196
// continuation bit. The continuation bit tells us whether there are more
10197
// digits in this value following this digit.
10198
//
10199
// Continuation
10200
// | Sign
10201
// | |
10202
// V V
10203
// 101011
10204
10205
var VLQ_BASE_SHIFT = 5;
10206
10207
// binary: 100000
10208
var VLQ_BASE = 1 << VLQ_BASE_SHIFT;
10209
10210
// binary: 011111
10211
var VLQ_BASE_MASK = VLQ_BASE - 1;
10212
10213
// binary: 100000
10214
var VLQ_CONTINUATION_BIT = VLQ_BASE;
10215
10216
/**
10217
* Converts from a two-complement value to a value where the sign bit is
10218
* is placed in the least significant bit. For example, as decimals:
10219
* 1 becomes 2 (10 binary), -1 becomes 3 (11 binary)
10220
* 2 becomes 4 (100 binary), -2 becomes 5 (101 binary)
10221
*/
10222
function toVLQSigned(aValue) {
10223
return aValue < 0
10224
? ((-aValue) << 1) + 1
10225
: (aValue << 1) + 0;
10226
}
10227
10228
/**
10229
* Converts to a two-complement value from a value where the sign bit is
10230
* is placed in the least significant bit. For example, as decimals:
10231
* 2 (10 binary) becomes 1, 3 (11 binary) becomes -1
10232
* 4 (100 binary) becomes 2, 5 (101 binary) becomes -2
10233
*/
10234
function fromVLQSigned(aValue) {
10235
var isNegative = (aValue & 1) === 1;
10236
var shifted = aValue >> 1;
10237
return isNegative
10238
? -shifted
10239
: shifted;
10240
}
10241
10242
/**
10243
* Returns the base 64 VLQ encoded value.
10244
*/
10245
exports.encode = function base64VLQ_encode(aValue) {
10246
var encoded = "";
10247
var digit;
10248
10249
var vlq = toVLQSigned(aValue);
10250
10251
do {
10252
digit = vlq & VLQ_BASE_MASK;
10253
vlq >>>= VLQ_BASE_SHIFT;
10254
if (vlq > 0) {
10255
// There are still more digits in this value, so we must make sure the
10256
// continuation bit is marked.
10257
digit |= VLQ_CONTINUATION_BIT;
10258
}
10259
encoded += base64.encode(digit);
10260
} while (vlq > 0);
10261
10262
return encoded;
10263
};
10264
10265
/**
10266
* Decodes the next base 64 VLQ value from the given string and returns the
10267
* value and the rest of the string.
10268
*/
10269
exports.decode = function base64VLQ_decode(aStr) {
10270
var i = 0;
10271
var strLen = aStr.length;
10272
var result = 0;
10273
var shift = 0;
10274
var continuation, digit;
10275
10276
do {
10277
if (i >= strLen) {
10278
throw new Error("Expected more digits in base 64 VLQ value.");
10279
}
10280
digit = base64.decode(aStr.charAt(i++));
10281
continuation = !!(digit & VLQ_CONTINUATION_BIT);
10282
digit &= VLQ_BASE_MASK;
10283
result = result + (digit << shift);
10284
shift += VLQ_BASE_SHIFT;
10285
} while (continuation);
10286
10287
return {
10288
value: fromVLQSigned(result),
10289
rest: aStr.slice(i)
10290
};
10291
};
10292
10293
});
10294
10295
},{"./base64":14,"amdefine":20}],14:[function(_dereq_,module,exports){
10296
/* -*- Mode: js; js-indent-level: 2; -*- */
10297
/*
10298
* Copyright 2011 Mozilla Foundation and contributors
10299
* Licensed under the New BSD license. See LICENSE or:
10300
* http://opensource.org/licenses/BSD-3-Clause
10301
*/
10302
if (typeof define !== 'function') {
10303
var define = _dereq_('amdefine')(module, _dereq_);
10304
}
10305
define(function (_dereq_, exports, module) {
10306
10307
var charToIntMap = {};
10308
var intToCharMap = {};
10309
10310
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
10311
.split('')
10312
.forEach(function (ch, index) {
10313
charToIntMap[ch] = index;
10314
intToCharMap[index] = ch;
10315
});
10316
10317
/**
10318
* Encode an integer in the range of 0 to 63 to a single base 64 digit.
10319
*/
10320
exports.encode = function base64_encode(aNumber) {
10321
if (aNumber in intToCharMap) {
10322
return intToCharMap[aNumber];
10323
}
10324
throw new TypeError("Must be between 0 and 63: " + aNumber);
10325
};
10326
10327
/**
10328
* Decode a single base 64 digit to an integer.
10329
*/
10330
exports.decode = function base64_decode(aChar) {
10331
if (aChar in charToIntMap) {
10332
return charToIntMap[aChar];
10333
}
10334
throw new TypeError("Not a valid base 64 digit: " + aChar);
10335
};
10336
10337
});
10338
10339
},{"amdefine":20}],15:[function(_dereq_,module,exports){
10340
/* -*- Mode: js; js-indent-level: 2; -*- */
10341
/*
10342
* Copyright 2011 Mozilla Foundation and contributors
10343
* Licensed under the New BSD license. See LICENSE or:
10344
* http://opensource.org/licenses/BSD-3-Clause
10345
*/
10346
if (typeof define !== 'function') {
10347
var define = _dereq_('amdefine')(module, _dereq_);
10348
}
10349
define(function (_dereq_, exports, module) {
10350
10351
/**
10352
* Recursive implementation of binary search.
10353
*
10354
* @param aLow Indices here and lower do not contain the needle.
10355
* @param aHigh Indices here and higher do not contain the needle.
10356
* @param aNeedle The element being searched for.
10357
* @param aHaystack The non-empty array being searched.
10358
* @param aCompare Function which takes two elements and returns -1, 0, or 1.
10359
*/
10360
function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare) {
10361
// This function terminates when one of the following is true:
10362
//
10363
// 1. We find the exact element we are looking for.
10364
//
10365
// 2. We did not find the exact element, but we can return the next
10366
// closest element that is less than that element.
10367
//
10368
// 3. We did not find the exact element, and there is no next-closest
10369
// element which is less than the one we are searching for, so we
10370
// return null.
10371
var mid = Math.floor((aHigh - aLow) / 2) + aLow;
10372
var cmp = aCompare(aNeedle, aHaystack[mid], true);
10373
if (cmp === 0) {
10374
// Found the element we are looking for.
10375
return aHaystack[mid];
10376
}
10377
else if (cmp > 0) {
10378
// aHaystack[mid] is greater than our needle.
10379
if (aHigh - mid > 1) {
10380
// The element is in the upper half.
10381
return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare);
10382
}
10383
// We did not find an exact match, return the next closest one
10384
// (termination case 2).
10385
return aHaystack[mid];
10386
}
10387
else {
10388
// aHaystack[mid] is less than our needle.
10389
if (mid - aLow > 1) {
10390
// The element is in the lower half.
10391
return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare);
10392
}
10393
// The exact needle element was not found in this haystack. Determine if
10394
// we are in termination case (2) or (3) and return the appropriate thing.
10395
return aLow < 0
10396
? null
10397
: aHaystack[aLow];
10398
}
10399
}
10400
10401
/**
10402
* This is an implementation of binary search which will always try and return
10403
* the next lowest value checked if there is no exact hit. This is because
10404
* mappings between original and generated line/col pairs are single points,
10405
* and there is an implicit region between each of them, so a miss just means
10406
* that you aren't on the very start of a region.
10407
*
10408
* @param aNeedle The element you are looking for.
10409
* @param aHaystack The array that is being searched.
10410
* @param aCompare A function which takes the needle and an element in the
10411
* array and returns -1, 0, or 1 depending on whether the needle is less
10412
* than, equal to, or greater than the element, respectively.
10413
*/
10414
exports.search = function search(aNeedle, aHaystack, aCompare) {
10415
return aHaystack.length > 0
10416
? recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack, aCompare)
10417
: null;
10418
};
10419
10420
});
10421
10422
},{"amdefine":20}],16:[function(_dereq_,module,exports){
10423
/* -*- Mode: js; js-indent-level: 2; -*- */
10424
/*
10425
* Copyright 2011 Mozilla Foundation and contributors
10426
* Licensed under the New BSD license. See LICENSE or:
10427
* http://opensource.org/licenses/BSD-3-Clause
10428
*/
10429
if (typeof define !== 'function') {
10430
var define = _dereq_('amdefine')(module, _dereq_);
10431
}
10432
define(function (_dereq_, exports, module) {
10433
10434
var util = _dereq_('./util');
10435
var binarySearch = _dereq_('./binary-search');
10436
var ArraySet = _dereq_('./array-set').ArraySet;
10437
var base64VLQ = _dereq_('./base64-vlq');
10438
10439
/**
10440
* A SourceMapConsumer instance represents a parsed source map which we can
10441
* query for information about the original file positions by giving it a file
10442
* position in the generated source.
10443
*
10444
* The only parameter is the raw source map (either as a JSON string, or
10445
* already parsed to an object). According to the spec, source maps have the
10446
* following attributes:
10447
*
10448
* - version: Which version of the source map spec this map is following.
10449
* - sources: An array of URLs to the original source files.
10450
* - names: An array of identifiers which can be referrenced by individual mappings.
10451
* - sourceRoot: Optional. The URL root from which all sources are relative.
10452
* - sourcesContent: Optional. An array of contents of the original source files.
10453
* - mappings: A string of base64 VLQs which contain the actual mappings.
10454
* - file: The generated file this source map is associated with.
10455
*
10456
* Here is an example source map, taken from the source map spec[0]:
10457
*
10458
* {
10459
* version : 3,
10460
* file: "out.js",
10461
* sourceRoot : "",
10462
* sources: ["foo.js", "bar.js"],
10463
* names: ["src", "maps", "are", "fun"],
10464
* mappings: "AA,AB;;ABCDE;"
10465
* }
10466
*
10467
* [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1#
10468
*/
10469
function SourceMapConsumer(aSourceMap) {
10470
var sourceMap = aSourceMap;
10471
if (typeof aSourceMap === 'string') {
10472
sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
10473
}
10474
10475
var version = util.getArg(sourceMap, 'version');
10476
var sources = util.getArg(sourceMap, 'sources');
10477
// Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which
10478
// requires the array) to play nice here.
10479
var names = util.getArg(sourceMap, 'names', []);
10480
var sourceRoot = util.getArg(sourceMap, 'sourceRoot', null);
10481
var sourcesContent = util.getArg(sourceMap, 'sourcesContent', null);
10482
var mappings = util.getArg(sourceMap, 'mappings');
10483
var file = util.getArg(sourceMap, 'file', null);
10484
10485
// Once again, Sass deviates from the spec and supplies the version as a
10486
// string rather than a number, so we use loose equality checking here.
10487
if (version != this._version) {
10488
throw new Error('Unsupported version: ' + version);
10489
}
10490
10491
// Pass `true` below to allow duplicate names and sources. While source maps
10492
// are intended to be compressed and deduplicated, the TypeScript compiler
10493
// sometimes generates source maps with duplicates in them. See Github issue
10494
// #72 and bugzil.la/889492.
10495
this._names = ArraySet.fromArray(names, true);
10496
this._sources = ArraySet.fromArray(sources, true);
10497
10498
this.sourceRoot = sourceRoot;
10499
this.sourcesContent = sourcesContent;
10500
this._mappings = mappings;
10501
this.file = file;
10502
}
10503
10504
/**
10505
* Create a SourceMapConsumer from a SourceMapGenerator.
10506
*
10507
* @param SourceMapGenerator aSourceMap
10508
* The source map that will be consumed.
10509
* @returns SourceMapConsumer
10510
*/
10511
SourceMapConsumer.fromSourceMap =
10512
function SourceMapConsumer_fromSourceMap(aSourceMap) {
10513
var smc = Object.create(SourceMapConsumer.prototype);
10514
10515
smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true);
10516
smc._sources = ArraySet.fromArray(aSourceMap._sources.toArray(), true);
10517
smc.sourceRoot = aSourceMap._sourceRoot;
10518
smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(),
10519
smc.sourceRoot);
10520
smc.file = aSourceMap._file;
10521
10522
smc.__generatedMappings = aSourceMap._mappings.slice()
10523
.sort(util.compareByGeneratedPositions);
10524
smc.__originalMappings = aSourceMap._mappings.slice()
10525
.sort(util.compareByOriginalPositions);
10526
10527
return smc;
10528
};
10529
10530
/**
10531
* The version of the source mapping spec that we are consuming.
10532
*/
10533
SourceMapConsumer.prototype._version = 3;
10534
10535
/**
10536
* The list of original sources.
10537
*/
10538
Object.defineProperty(SourceMapConsumer.prototype, 'sources', {
10539
get: function () {
10540
return this._sources.toArray().map(function (s) {
10541
return this.sourceRoot ? util.join(this.sourceRoot, s) : s;
10542
}, this);
10543
}
10544
});
10545
10546
// `__generatedMappings` and `__originalMappings` are arrays that hold the
10547
// parsed mapping coordinates from the source map's "mappings" attribute. They
10548
// are lazily instantiated, accessed via the `_generatedMappings` and
10549
// `_originalMappings` getters respectively, and we only parse the mappings
10550
// and create these arrays once queried for a source location. We jump through
10551
// these hoops because there can be many thousands of mappings, and parsing
10552
// them is expensive, so we only want to do it if we must.
10553
//
10554
// Each object in the arrays is of the form:
10555
//
10556
// {
10557
// generatedLine: The line number in the generated code,
10558
// generatedColumn: The column number in the generated code,
10559
// source: The path to the original source file that generated this
10560
// chunk of code,
10561
// originalLine: The line number in the original source that
10562
// corresponds to this chunk of generated code,
10563
// originalColumn: The column number in the original source that
10564
// corresponds to this chunk of generated code,
10565
// name: The name of the original symbol which generated this chunk of
10566
// code.
10567
// }
10568
//
10569
// All properties except for `generatedLine` and `generatedColumn` can be
10570
// `null`.
10571
//
10572
// `_generatedMappings` is ordered by the generated positions.
10573
//
10574
// `_originalMappings` is ordered by the original positions.
10575
10576
SourceMapConsumer.prototype.__generatedMappings = null;
10577
Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', {
10578
get: function () {
10579
if (!this.__generatedMappings) {
10580
this.__generatedMappings = [];
10581
this.__originalMappings = [];
10582
this._parseMappings(this._mappings, this.sourceRoot);
10583
}
10584
10585
return this.__generatedMappings;
10586
}
10587
});
10588
10589
SourceMapConsumer.prototype.__originalMappings = null;
10590
Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', {
10591
get: function () {
10592
if (!this.__originalMappings) {
10593
this.__generatedMappings = [];
10594
this.__originalMappings = [];
10595
this._parseMappings(this._mappings, this.sourceRoot);
10596
}
10597
10598
return this.__originalMappings;
10599
}
10600
});
10601
10602
/**
10603
* Parse the mappings in a string in to a data structure which we can easily
10604
* query (the ordered arrays in the `this.__generatedMappings` and
10605
* `this.__originalMappings` properties).
10606
*/
10607
SourceMapConsumer.prototype._parseMappings =
10608
function SourceMapConsumer_parseMappings(aStr, aSourceRoot) {
10609
var generatedLine = 1;
10610
var previousGeneratedColumn = 0;
10611
var previousOriginalLine = 0;
10612
var previousOriginalColumn = 0;
10613
var previousSource = 0;
10614
var previousName = 0;
10615
var mappingSeparator = /^[,;]/;
10616
var str = aStr;
10617
var mapping;
10618
var temp;
10619
10620
while (str.length > 0) {
10621
if (str.charAt(0) === ';') {
10622
generatedLine++;
10623
str = str.slice(1);
10624
previousGeneratedColumn = 0;
10625
}
10626
else if (str.charAt(0) === ',') {
10627
str = str.slice(1);
10628
}
10629
else {
10630
mapping = {};
10631
mapping.generatedLine = generatedLine;
10632
10633
// Generated column.
10634
temp = base64VLQ.decode(str);
10635
mapping.generatedColumn = previousGeneratedColumn + temp.value;
10636
previousGeneratedColumn = mapping.generatedColumn;
10637
str = temp.rest;
10638
10639
if (str.length > 0 && !mappingSeparator.test(str.charAt(0))) {
10640
// Original source.
10641
temp = base64VLQ.decode(str);
10642
mapping.source = this._sources.at(previousSource + temp.value);
10643
previousSource += temp.value;
10644
str = temp.rest;
10645
if (str.length === 0 || mappingSeparator.test(str.charAt(0))) {
10646
throw new Error('Found a source, but no line and column');
10647
}
10648
10649
// Original line.
10650
temp = base64VLQ.decode(str);
10651
mapping.originalLine = previousOriginalLine + temp.value;
10652
previousOriginalLine = mapping.originalLine;
10653
// Lines are stored 0-based
10654
mapping.originalLine += 1;
10655
str = temp.rest;
10656
if (str.length === 0 || mappingSeparator.test(str.charAt(0))) {
10657
throw new Error('Found a source and line, but no column');
10658
}
10659
10660
// Original column.
10661
temp = base64VLQ.decode(str);
10662
mapping.originalColumn = previousOriginalColumn + temp.value;
10663
previousOriginalColumn = mapping.originalColumn;
10664
str = temp.rest;
10665
10666
if (str.length > 0 && !mappingSeparator.test(str.charAt(0))) {
10667
// Original name.
10668
temp = base64VLQ.decode(str);
10669
mapping.name = this._names.at(previousName + temp.value);
10670
previousName += temp.value;
10671
str = temp.rest;
10672
}
10673
}
10674
10675
this.__generatedMappings.push(mapping);
10676
if (typeof mapping.originalLine === 'number') {
10677
this.__originalMappings.push(mapping);
10678
}
10679
}
10680
}
10681
10682
this.__originalMappings.sort(util.compareByOriginalPositions);
10683
};
10684
10685
/**
10686
* Find the mapping that best matches the hypothetical "needle" mapping that
10687
* we are searching for in the given "haystack" of mappings.
10688
*/
10689
SourceMapConsumer.prototype._findMapping =
10690
function SourceMapConsumer_findMapping(aNeedle, aMappings, aLineName,
10691
aColumnName, aComparator) {
10692
// To return the position we are searching for, we must first find the
10693
// mapping for the given position and then return the opposite position it
10694
// points to. Because the mappings are sorted, we can use binary search to
10695
// find the best mapping.
10696
10697
if (aNeedle[aLineName] <= 0) {
10698
throw new TypeError('Line must be greater than or equal to 1, got '
10699
+ aNeedle[aLineName]);
10700
}
10701
if (aNeedle[aColumnName] < 0) {
10702
throw new TypeError('Column must be greater than or equal to 0, got '
10703
+ aNeedle[aColumnName]);
10704
}
10705
10706
return binarySearch.search(aNeedle, aMappings, aComparator);
10707
};
10708
10709
/**
10710
* Returns the original source, line, and column information for the generated
10711
* source's line and column positions provided. The only argument is an object
10712
* with the following properties:
10713
*
10714
* - line: The line number in the generated source.
10715
* - column: The column number in the generated source.
10716
*
10717
* and an object is returned with the following properties:
10718
*
10719
* - source: The original source file, or null.
10720
* - line: The line number in the original source, or null.
10721
* - column: The column number in the original source, or null.
10722
* - name: The original identifier, or null.
10723
*/
10724
SourceMapConsumer.prototype.originalPositionFor =
10725
function SourceMapConsumer_originalPositionFor(aArgs) {
10726
var needle = {
10727
generatedLine: util.getArg(aArgs, 'line'),
10728
generatedColumn: util.getArg(aArgs, 'column')
10729
};
10730
10731
var mapping = this._findMapping(needle,
10732
this._generatedMappings,
10733
"generatedLine",
10734
"generatedColumn",
10735
util.compareByGeneratedPositions);
10736
10737
if (mapping) {
10738
var source = util.getArg(mapping, 'source', null);
10739
if (source && this.sourceRoot) {
10740
source = util.join(this.sourceRoot, source);
10741
}
10742
return {
10743
source: source,
10744
line: util.getArg(mapping, 'originalLine', null),
10745
column: util.getArg(mapping, 'originalColumn', null),
10746
name: util.getArg(mapping, 'name', null)
10747
};
10748
}
10749
10750
return {
10751
source: null,
10752
line: null,
10753
column: null,
10754
name: null
10755
};
10756
};
10757
10758
/**
10759
* Returns the original source content. The only argument is the url of the
10760
* original source file. Returns null if no original source content is
10761
* availible.
10762
*/
10763
SourceMapConsumer.prototype.sourceContentFor =
10764
function SourceMapConsumer_sourceContentFor(aSource) {
10765
if (!this.sourcesContent) {
10766
return null;
10767
}
10768
10769
if (this.sourceRoot) {
10770
aSource = util.relative(this.sourceRoot, aSource);
10771
}
10772
10773
if (this._sources.has(aSource)) {
10774
return this.sourcesContent[this._sources.indexOf(aSource)];
10775
}
10776
10777
var url;
10778
if (this.sourceRoot
10779
&& (url = util.urlParse(this.sourceRoot))) {
10780
// XXX: file:// URIs and absolute paths lead to unexpected behavior for
10781
// many users. We can help them out when they expect file:// URIs to
10782
// behave like it would if they were running a local HTTP server. See
10783
// https://bugzilla.mozilla.org/show_bug.cgi?id=885597.
10784
var fileUriAbsPath = aSource.replace(/^file:\/\//, "");
10785
if (url.scheme == "file"
10786
&& this._sources.has(fileUriAbsPath)) {
10787
return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)]
10788
}
10789
10790
if ((!url.path || url.path == "/")
10791
&& this._sources.has("/" + aSource)) {
10792
return this.sourcesContent[this._sources.indexOf("/" + aSource)];
10793
}
10794
}
10795
10796
throw new Error('"' + aSource + '" is not in the SourceMap.');
10797
};
10798
10799
/**
10800
* Returns the generated line and column information for the original source,
10801
* line, and column positions provided. The only argument is an object with
10802
* the following properties:
10803
*
10804
* - source: The filename of the original source.
10805
* - line: The line number in the original source.
10806
* - column: The column number in the original source.
10807
*
10808
* and an object is returned with the following properties:
10809
*
10810
* - line: The line number in the generated source, or null.
10811
* - column: The column number in the generated source, or null.
10812
*/
10813
SourceMapConsumer.prototype.generatedPositionFor =
10814
function SourceMapConsumer_generatedPositionFor(aArgs) {
10815
var needle = {
10816
source: util.getArg(aArgs, 'source'),
10817
originalLine: util.getArg(aArgs, 'line'),
10818
originalColumn: util.getArg(aArgs, 'column')
10819
};
10820
10821
if (this.sourceRoot) {
10822
needle.source = util.relative(this.sourceRoot, needle.source);
10823
}
10824
10825
var mapping = this._findMapping(needle,
10826
this._originalMappings,
10827
"originalLine",
10828
"originalColumn",
10829
util.compareByOriginalPositions);
10830
10831
if (mapping) {
10832
return {
10833
line: util.getArg(mapping, 'generatedLine', null),
10834
column: util.getArg(mapping, 'generatedColumn', null)
10835
};
10836
}
10837
10838
return {
10839
line: null,
10840
column: null
10841
};
10842
};
10843
10844
SourceMapConsumer.GENERATED_ORDER = 1;
10845
SourceMapConsumer.ORIGINAL_ORDER = 2;
10846
10847
/**
10848
* Iterate over each mapping between an original source/line/column and a
10849
* generated line/column in this source map.
10850
*
10851
* @param Function aCallback
10852
* The function that is called with each mapping.
10853
* @param Object aContext
10854
* Optional. If specified, this object will be the value of `this` every
10855
* time that `aCallback` is called.
10856
* @param aOrder
10857
* Either `SourceMapConsumer.GENERATED_ORDER` or
10858
* `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to
10859
* iterate over the mappings sorted by the generated file's line/column
10860
* order or the original's source/line/column order, respectively. Defaults to
10861
* `SourceMapConsumer.GENERATED_ORDER`.
10862
*/
10863
SourceMapConsumer.prototype.eachMapping =
10864
function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) {
10865
var context = aContext || null;
10866
var order = aOrder || SourceMapConsumer.GENERATED_ORDER;
10867
10868
var mappings;
10869
switch (order) {
10870
case SourceMapConsumer.GENERATED_ORDER:
10871
mappings = this._generatedMappings;
10872
break;
10873
case SourceMapConsumer.ORIGINAL_ORDER:
10874
mappings = this._originalMappings;
10875
break;
10876
default:
10877
throw new Error("Unknown order of iteration.");
10878
}
10879
10880
var sourceRoot = this.sourceRoot;
10881
mappings.map(function (mapping) {
10882
var source = mapping.source;
10883
if (source && sourceRoot) {
10884
source = util.join(sourceRoot, source);
10885
}
10886
return {
10887
source: source,
10888
generatedLine: mapping.generatedLine,
10889
generatedColumn: mapping.generatedColumn,
10890
originalLine: mapping.originalLine,
10891
originalColumn: mapping.originalColumn,
10892
name: mapping.name
10893
};
10894
}).forEach(aCallback, context);
10895
};
10896
10897
exports.SourceMapConsumer = SourceMapConsumer;
10898
10899
});
10900
10901
},{"./array-set":12,"./base64-vlq":13,"./binary-search":15,"./util":19,"amdefine":20}],17:[function(_dereq_,module,exports){
10902
/* -*- Mode: js; js-indent-level: 2; -*- */
10903
/*
10904
* Copyright 2011 Mozilla Foundation and contributors
10905
* Licensed under the New BSD license. See LICENSE or:
10906
* http://opensource.org/licenses/BSD-3-Clause
10907
*/
10908
if (typeof define !== 'function') {
10909
var define = _dereq_('amdefine')(module, _dereq_);
10910
}
10911
define(function (_dereq_, exports, module) {
10912
10913
var base64VLQ = _dereq_('./base64-vlq');
10914
var util = _dereq_('./util');
10915
var ArraySet = _dereq_('./array-set').ArraySet;
10916
10917
/**
10918
* An instance of the SourceMapGenerator represents a source map which is
10919
* being built incrementally. To create a new one, you must pass an object
10920
* with the following properties:
10921
*
10922
* - file: The filename of the generated source.
10923
* - sourceRoot: An optional root for all URLs in this source map.
10924
*/
10925
function SourceMapGenerator(aArgs) {
10926
this._file = util.getArg(aArgs, 'file');
10927
this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null);
10928
this._sources = new ArraySet();
10929
this._names = new ArraySet();
10930
this._mappings = [];
10931
this._sourcesContents = null;
10932
}
10933
10934
SourceMapGenerator.prototype._version = 3;
10935
10936
/**
10937
* Creates a new SourceMapGenerator based on a SourceMapConsumer
10938
*
10939
* @param aSourceMapConsumer The SourceMap.
10940
*/
10941
SourceMapGenerator.fromSourceMap =
10942
function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) {
10943
var sourceRoot = aSourceMapConsumer.sourceRoot;
10944
var generator = new SourceMapGenerator({
10945
file: aSourceMapConsumer.file,
10946
sourceRoot: sourceRoot
10947
});
10948
aSourceMapConsumer.eachMapping(function (mapping) {
10949
var newMapping = {
10950
generated: {
10951
line: mapping.generatedLine,
10952
column: mapping.generatedColumn
10953
}
10954
};
10955
10956
if (mapping.source) {
10957
newMapping.source = mapping.source;
10958
if (sourceRoot) {
10959
newMapping.source = util.relative(sourceRoot, newMapping.source);
10960
}
10961
10962
newMapping.original = {
10963
line: mapping.originalLine,
10964
column: mapping.originalColumn
10965
};
10966
10967
if (mapping.name) {
10968
newMapping.name = mapping.name;
10969
}
10970
}
10971
10972
generator.addMapping(newMapping);
10973
});
10974
aSourceMapConsumer.sources.forEach(function (sourceFile) {
10975
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
10976
if (content) {
10977
generator.setSourceContent(sourceFile, content);
10978
}
10979
});
10980
return generator;
10981
};
10982
10983
/**
10984
* Add a single mapping from original source line and column to the generated
10985
* source's line and column for this source map being created. The mapping
10986
* object should have the following properties:
10987
*
10988
* - generated: An object with the generated line and column positions.
10989
* - original: An object with the original line and column positions.
10990
* - source: The original source file (relative to the sourceRoot).
10991
* - name: An optional original token name for this mapping.
10992
*/
10993
SourceMapGenerator.prototype.addMapping =
10994
function SourceMapGenerator_addMapping(aArgs) {
10995
var generated = util.getArg(aArgs, 'generated');
10996
var original = util.getArg(aArgs, 'original', null);
10997
var source = util.getArg(aArgs, 'source', null);
10998
var name = util.getArg(aArgs, 'name', null);
10999
11000
this._validateMapping(generated, original, source, name);
11001
11002
if (source && !this._sources.has(source)) {
11003
this._sources.add(source);
11004
}
11005
11006
if (name && !this._names.has(name)) {
11007
this._names.add(name);
11008
}
11009
11010
this._mappings.push({
11011
generatedLine: generated.line,
11012
generatedColumn: generated.column,
11013
originalLine: original != null && original.line,
11014
originalColumn: original != null && original.column,
11015
source: source,
11016
name: name
11017
});
11018
};
11019
11020
/**
11021
* Set the source content for a source file.
11022
*/
11023
SourceMapGenerator.prototype.setSourceContent =
11024
function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) {
11025
var source = aSourceFile;
11026
if (this._sourceRoot) {
11027
source = util.relative(this._sourceRoot, source);
11028
}
11029
11030
if (aSourceContent !== null) {
11031
// Add the source content to the _sourcesContents map.
11032
// Create a new _sourcesContents map if the property is null.
11033
if (!this._sourcesContents) {
11034
this._sourcesContents = {};
11035
}
11036
this._sourcesContents[util.toSetString(source)] = aSourceContent;
11037
} else {
11038
// Remove the source file from the _sourcesContents map.
11039
// If the _sourcesContents map is empty, set the property to null.
11040
delete this._sourcesContents[util.toSetString(source)];
11041
if (Object.keys(this._sourcesContents).length === 0) {
11042
this._sourcesContents = null;
11043
}
11044
}
11045
};
11046
11047
/**
11048
* Applies the mappings of a sub-source-map for a specific source file to the
11049
* source map being generated. Each mapping to the supplied source file is
11050
* rewritten using the supplied source map. Note: The resolution for the
11051
* resulting mappings is the minimium of this map and the supplied map.
11052
*
11053
* @param aSourceMapConsumer The source map to be applied.
11054
* @param aSourceFile Optional. The filename of the source file.
11055
* If omitted, SourceMapConsumer's file property will be used.
11056
*/
11057
SourceMapGenerator.prototype.applySourceMap =
11058
function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile) {
11059
// If aSourceFile is omitted, we will use the file property of the SourceMap
11060
if (!aSourceFile) {
11061
aSourceFile = aSourceMapConsumer.file;
11062
}
11063
var sourceRoot = this._sourceRoot;
11064
// Make "aSourceFile" relative if an absolute Url is passed.
11065
if (sourceRoot) {
11066
aSourceFile = util.relative(sourceRoot, aSourceFile);
11067
}
11068
// Applying the SourceMap can add and remove items from the sources and
11069
// the names array.
11070
var newSources = new ArraySet();
11071
var newNames = new ArraySet();
11072
11073
// Find mappings for the "aSourceFile"
11074
this._mappings.forEach(function (mapping) {
11075
if (mapping.source === aSourceFile && mapping.originalLine) {
11076
// Check if it can be mapped by the source map, then update the mapping.
11077
var original = aSourceMapConsumer.originalPositionFor({
11078
line: mapping.originalLine,
11079
column: mapping.originalColumn
11080
});
11081
if (original.source !== null) {
11082
// Copy mapping
11083
if (sourceRoot) {
11084
mapping.source = util.relative(sourceRoot, original.source);
11085
} else {
11086
mapping.source = original.source;
11087
}
11088
mapping.originalLine = original.line;
11089
mapping.originalColumn = original.column;
11090
if (original.name !== null && mapping.name !== null) {
11091
// Only use the identifier name if it's an identifier
11092
// in both SourceMaps
11093
mapping.name = original.name;
11094
}
11095
}
11096
}
11097
11098
var source = mapping.source;
11099
if (source && !newSources.has(source)) {
11100
newSources.add(source);
11101
}
11102
11103
var name = mapping.name;
11104
if (name && !newNames.has(name)) {
11105
newNames.add(name);
11106
}
11107
11108
}, this);
11109
this._sources = newSources;
11110
this._names = newNames;
11111
11112
// Copy sourcesContents of applied map.
11113
aSourceMapConsumer.sources.forEach(function (sourceFile) {
11114
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
11115
if (content) {
11116
if (sourceRoot) {
11117
sourceFile = util.relative(sourceRoot, sourceFile);
11118
}
11119
this.setSourceContent(sourceFile, content);
11120
}
11121
}, this);
11122
};
11123
11124
/**
11125
* A mapping can have one of the three levels of data:
11126
*
11127
* 1. Just the generated position.
11128
* 2. The Generated position, original position, and original source.
11129
* 3. Generated and original position, original source, as well as a name
11130
* token.
11131
*
11132
* To maintain consistency, we validate that any new mapping being added falls
11133
* in to one of these categories.
11134
*/
11135
SourceMapGenerator.prototype._validateMapping =
11136
function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,
11137
aName) {
11138
if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
11139
&& aGenerated.line > 0 && aGenerated.column >= 0
11140
&& !aOriginal && !aSource && !aName) {
11141
// Case 1.
11142
return;
11143
}
11144
else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
11145
&& aOriginal && 'line' in aOriginal && 'column' in aOriginal
11146
&& aGenerated.line > 0 && aGenerated.column >= 0
11147
&& aOriginal.line > 0 && aOriginal.column >= 0
11148
&& aSource) {
11149
// Cases 2 and 3.
11150
return;
11151
}
11152
else {
11153
throw new Error('Invalid mapping: ' + JSON.stringify({
11154
generated: aGenerated,
11155
source: aSource,
11156
orginal: aOriginal,
11157
name: aName
11158
}));
11159
}
11160
};
11161
11162
/**
11163
* Serialize the accumulated mappings in to the stream of base 64 VLQs
11164
* specified by the source map format.
11165
*/
11166
SourceMapGenerator.prototype._serializeMappings =
11167
function SourceMapGenerator_serializeMappings() {
11168
var previousGeneratedColumn = 0;
11169
var previousGeneratedLine = 1;
11170
var previousOriginalColumn = 0;
11171
var previousOriginalLine = 0;
11172
var previousName = 0;
11173
var previousSource = 0;
11174
var result = '';
11175
var mapping;
11176
11177
// The mappings must be guaranteed to be in sorted order before we start
11178
// serializing them or else the generated line numbers (which are defined
11179
// via the ';' separators) will be all messed up. Note: it might be more
11180
// performant to maintain the sorting as we insert them, rather than as we
11181
// serialize them, but the big O is the same either way.
11182
this._mappings.sort(util.compareByGeneratedPositions);
11183
11184
for (var i = 0, len = this._mappings.length; i < len; i++) {
11185
mapping = this._mappings[i];
11186
11187
if (mapping.generatedLine !== previousGeneratedLine) {
11188
previousGeneratedColumn = 0;
11189
while (mapping.generatedLine !== previousGeneratedLine) {
11190
result += ';';
11191
previousGeneratedLine++;
11192
}
11193
}
11194
else {
11195
if (i > 0) {
11196
if (!util.compareByGeneratedPositions(mapping, this._mappings[i - 1])) {
11197
continue;
11198
}
11199
result += ',';
11200
}
11201
}
11202
11203
result += base64VLQ.encode(mapping.generatedColumn
11204
- previousGeneratedColumn);
11205
previousGeneratedColumn = mapping.generatedColumn;
11206
11207
if (mapping.source) {
11208
result += base64VLQ.encode(this._sources.indexOf(mapping.source)
11209
- previousSource);
11210
previousSource = this._sources.indexOf(mapping.source);
11211
11212
// lines are stored 0-based in SourceMap spec version 3
11213
result += base64VLQ.encode(mapping.originalLine - 1
11214
- previousOriginalLine);
11215
previousOriginalLine = mapping.originalLine - 1;
11216
11217
result += base64VLQ.encode(mapping.originalColumn
11218
- previousOriginalColumn);
11219
previousOriginalColumn = mapping.originalColumn;
11220
11221
if (mapping.name) {
11222
result += base64VLQ.encode(this._names.indexOf(mapping.name)
11223
- previousName);
11224
previousName = this._names.indexOf(mapping.name);
11225
}
11226
}
11227
}
11228
11229
return result;
11230
};
11231
11232
SourceMapGenerator.prototype._generateSourcesContent =
11233
function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) {
11234
return aSources.map(function (source) {
11235
if (!this._sourcesContents) {
11236
return null;
11237
}
11238
if (aSourceRoot) {
11239
source = util.relative(aSourceRoot, source);
11240
}
11241
var key = util.toSetString(source);
11242
return Object.prototype.hasOwnProperty.call(this._sourcesContents,
11243
key)
11244
? this._sourcesContents[key]
11245
: null;
11246
}, this);
11247
};
11248
11249
/**
11250
* Externalize the source map.
11251
*/
11252
SourceMapGenerator.prototype.toJSON =
11253
function SourceMapGenerator_toJSON() {
11254
var map = {
11255
version: this._version,
11256
file: this._file,
11257
sources: this._sources.toArray(),
11258
names: this._names.toArray(),
11259
mappings: this._serializeMappings()
11260
};
11261
if (this._sourceRoot) {
11262
map.sourceRoot = this._sourceRoot;
11263
}
11264
if (this._sourcesContents) {
11265
map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot);
11266
}
11267
11268
return map;
11269
};
11270
11271
/**
11272
* Render the source map being generated to a string.
11273
*/
11274
SourceMapGenerator.prototype.toString =
11275
function SourceMapGenerator_toString() {
11276
return JSON.stringify(this);
11277
};
11278
11279
exports.SourceMapGenerator = SourceMapGenerator;
11280
11281
});
11282
11283
},{"./array-set":12,"./base64-vlq":13,"./util":19,"amdefine":20}],18:[function(_dereq_,module,exports){
11284
/* -*- Mode: js; js-indent-level: 2; -*- */
11285
/*
11286
* Copyright 2011 Mozilla Foundation and contributors
11287
* Licensed under the New BSD license. See LICENSE or:
11288
* http://opensource.org/licenses/BSD-3-Clause
11289
*/
11290
if (typeof define !== 'function') {
11291
var define = _dereq_('amdefine')(module, _dereq_);
11292
}
11293
define(function (_dereq_, exports, module) {
11294
11295
var SourceMapGenerator = _dereq_('./source-map-generator').SourceMapGenerator;
11296
var util = _dereq_('./util');
11297
11298
/**
11299
* SourceNodes provide a way to abstract over interpolating/concatenating
11300
* snippets of generated JavaScript source code while maintaining the line and
11301
* column information associated with the original source code.
11302
*
11303
* @param aLine The original line number.
11304
* @param aColumn The original column number.
11305
* @param aSource The original source's filename.
11306
* @param aChunks Optional. An array of strings which are snippets of
11307
* generated JS, or other SourceNodes.
11308
* @param aName The original identifier.
11309
*/
11310
function SourceNode(aLine, aColumn, aSource, aChunks, aName) {
11311
this.children = [];
11312
this.sourceContents = {};
11313
this.line = aLine === undefined ? null : aLine;
11314
this.column = aColumn === undefined ? null : aColumn;
11315
this.source = aSource === undefined ? null : aSource;
11316
this.name = aName === undefined ? null : aName;
11317
if (aChunks != null) this.add(aChunks);
11318
}
11319
11320
/**
11321
* Creates a SourceNode from generated code and a SourceMapConsumer.
11322
*
11323
* @param aGeneratedCode The generated code
11324
* @param aSourceMapConsumer The SourceMap for the generated code
11325
*/
11326
SourceNode.fromStringWithSourceMap =
11327
function SourceNode_fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer) {
11328
// The SourceNode we want to fill with the generated code
11329
// and the SourceMap
11330
var node = new SourceNode();
11331
11332
// The generated code
11333
// Processed fragments are removed from this array.
11334
var remainingLines = aGeneratedCode.split('\n');
11335
11336
// We need to remember the position of "remainingLines"
11337
var lastGeneratedLine = 1, lastGeneratedColumn = 0;
11338
11339
// The generate SourceNodes we need a code range.
11340
// To extract it current and last mapping is used.
11341
// Here we store the last mapping.
11342
var lastMapping = null;
11343
11344
aSourceMapConsumer.eachMapping(function (mapping) {
11345
if (lastMapping === null) {
11346
// We add the generated code until the first mapping
11347
// to the SourceNode without any mapping.
11348
// Each line is added as separate string.
11349
while (lastGeneratedLine < mapping.generatedLine) {
11350
node.add(remainingLines.shift() + "\n");
11351
lastGeneratedLine++;
11352
}
11353
if (lastGeneratedColumn < mapping.generatedColumn) {
11354
var nextLine = remainingLines[0];
11355
node.add(nextLine.substr(0, mapping.generatedColumn));
11356
remainingLines[0] = nextLine.substr(mapping.generatedColumn);
11357
lastGeneratedColumn = mapping.generatedColumn;
11358
}
11359
} else {
11360
// We add the code from "lastMapping" to "mapping":
11361
// First check if there is a new line in between.
11362
if (lastGeneratedLine < mapping.generatedLine) {
11363
var code = "";
11364
// Associate full lines with "lastMapping"
11365
do {
11366
code += remainingLines.shift() + "\n";
11367
lastGeneratedLine++;
11368
lastGeneratedColumn = 0;
11369
} while (lastGeneratedLine < mapping.generatedLine);
11370
// When we reached the correct line, we add code until we
11371
// reach the correct column too.
11372
if (lastGeneratedColumn < mapping.generatedColumn) {
11373
var nextLine = remainingLines[0];
11374
code += nextLine.substr(0, mapping.generatedColumn);
11375
remainingLines[0] = nextLine.substr(mapping.generatedColumn);
11376
lastGeneratedColumn = mapping.generatedColumn;
11377
}
11378
// Create the SourceNode.
11379
addMappingWithCode(lastMapping, code);
11380
} else {
11381
// There is no new line in between.
11382
// Associate the code between "lastGeneratedColumn" and
11383
// "mapping.generatedColumn" with "lastMapping"
11384
var nextLine = remainingLines[0];
11385
var code = nextLine.substr(0, mapping.generatedColumn -
11386
lastGeneratedColumn);
11387
remainingLines[0] = nextLine.substr(mapping.generatedColumn -
11388
lastGeneratedColumn);
11389
lastGeneratedColumn = mapping.generatedColumn;
11390
addMappingWithCode(lastMapping, code);
11391
}
11392
}
11393
lastMapping = mapping;
11394
}, this);
11395
// We have processed all mappings.
11396
// Associate the remaining code in the current line with "lastMapping"
11397
// and add the remaining lines without any mapping
11398
addMappingWithCode(lastMapping, remainingLines.join("\n"));
11399
11400
// Copy sourcesContent into SourceNode
11401
aSourceMapConsumer.sources.forEach(function (sourceFile) {
11402
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
11403
if (content) {
11404
node.setSourceContent(sourceFile, content);
11405
}
11406
});
11407
11408
return node;
11409
11410
function addMappingWithCode(mapping, code) {
11411
if (mapping === null || mapping.source === undefined) {
11412
node.add(code);
11413
} else {
11414
node.add(new SourceNode(mapping.originalLine,
11415
mapping.originalColumn,
11416
mapping.source,
11417
code,
11418
mapping.name));
11419
}
11420
}
11421
};
11422
11423
/**
11424
* Add a chunk of generated JS to this source node.
11425
*
11426
* @param aChunk A string snippet of generated JS code, another instance of
11427
* SourceNode, or an array where each member is one of those things.
11428
*/
11429
SourceNode.prototype.add = function SourceNode_add(aChunk) {
11430
if (Array.isArray(aChunk)) {
11431
aChunk.forEach(function (chunk) {
11432
this.add(chunk);
11433
}, this);
11434
}
11435
else if (aChunk instanceof SourceNode || typeof aChunk === "string") {
11436
if (aChunk) {
11437
this.children.push(aChunk);
11438
}
11439
}
11440
else {
11441
throw new TypeError(
11442
"Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk
11443
);
11444
}
11445
return this;
11446
};
11447
11448
/**
11449
* Add a chunk of generated JS to the beginning of this source node.
11450
*
11451
* @param aChunk A string snippet of generated JS code, another instance of
11452
* SourceNode, or an array where each member is one of those things.
11453
*/
11454
SourceNode.prototype.prepend = function SourceNode_prepend(aChunk) {
11455
if (Array.isArray(aChunk)) {
11456
for (var i = aChunk.length-1; i >= 0; i--) {
11457
this.prepend(aChunk[i]);
11458
}
11459
}
11460
else if (aChunk instanceof SourceNode || typeof aChunk === "string") {
11461
this.children.unshift(aChunk);
11462
}
11463
else {
11464
throw new TypeError(
11465
"Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk
11466
);
11467
}
11468
return this;
11469
};
11470
11471
/**
11472
* Walk over the tree of JS snippets in this node and its children. The
11473
* walking function is called once for each snippet of JS and is passed that
11474
* snippet and the its original associated source's line/column location.
11475
*
11476
* @param aFn The traversal function.
11477
*/
11478
SourceNode.prototype.walk = function SourceNode_walk(aFn) {
11479
var chunk;
11480
for (var i = 0, len = this.children.length; i < len; i++) {
11481
chunk = this.children[i];
11482
if (chunk instanceof SourceNode) {
11483
chunk.walk(aFn);
11484
}
11485
else {
11486
if (chunk !== '') {
11487
aFn(chunk, { source: this.source,
11488
line: this.line,
11489
column: this.column,
11490
name: this.name });
11491
}
11492
}
11493
}
11494
};
11495
11496
/**
11497
* Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between
11498
* each of `this.children`.
11499
*
11500
* @param aSep The separator.
11501
*/
11502
SourceNode.prototype.join = function SourceNode_join(aSep) {
11503
var newChildren;
11504
var i;
11505
var len = this.children.length;
11506
if (len > 0) {
11507
newChildren = [];
11508
for (i = 0; i < len-1; i++) {
11509
newChildren.push(this.children[i]);
11510
newChildren.push(aSep);
11511
}
11512
newChildren.push(this.children[i]);
11513
this.children = newChildren;
11514
}
11515
return this;
11516
};
11517
11518
/**
11519
* Call String.prototype.replace on the very right-most source snippet. Useful
11520
* for trimming whitespace from the end of a source node, etc.
11521
*
11522
* @param aPattern The pattern to replace.
11523
* @param aReplacement The thing to replace the pattern with.
11524
*/
11525
SourceNode.prototype.replaceRight = function SourceNode_replaceRight(aPattern, aReplacement) {
11526
var lastChild = this.children[this.children.length - 1];
11527
if (lastChild instanceof SourceNode) {
11528
lastChild.replaceRight(aPattern, aReplacement);
11529
}
11530
else if (typeof lastChild === 'string') {
11531
this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement);
11532
}
11533
else {
11534
this.children.push(''.replace(aPattern, aReplacement));
11535
}
11536
return this;
11537
};
11538
11539
/**
11540
* Set the source content for a source file. This will be added to the SourceMapGenerator
11541
* in the sourcesContent field.
11542
*
11543
* @param aSourceFile The filename of the source file
11544
* @param aSourceContent The content of the source file
11545
*/
11546
SourceNode.prototype.setSourceContent =
11547
function SourceNode_setSourceContent(aSourceFile, aSourceContent) {
11548
this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent;
11549
};
11550
11551
/**
11552
* Walk over the tree of SourceNodes. The walking function is called for each
11553
* source file content and is passed the filename and source content.
11554
*
11555
* @param aFn The traversal function.
11556
*/
11557
SourceNode.prototype.walkSourceContents =
11558
function SourceNode_walkSourceContents(aFn) {
11559
for (var i = 0, len = this.children.length; i < len; i++) {
11560
if (this.children[i] instanceof SourceNode) {
11561
this.children[i].walkSourceContents(aFn);
11562
}
11563
}
11564
11565
var sources = Object.keys(this.sourceContents);
11566
for (var i = 0, len = sources.length; i < len; i++) {
11567
aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]);
11568
}
11569
};
11570
11571
/**
11572
* Return the string representation of this source node. Walks over the tree
11573
* and concatenates all the various snippets together to one string.
11574
*/
11575
SourceNode.prototype.toString = function SourceNode_toString() {
11576
var str = "";
11577
this.walk(function (chunk) {
11578
str += chunk;
11579
});
11580
return str;
11581
};
11582
11583
/**
11584
* Returns the string representation of this source node along with a source
11585
* map.
11586
*/
11587
SourceNode.prototype.toStringWithSourceMap = function SourceNode_toStringWithSourceMap(aArgs) {
11588
var generated = {
11589
code: "",
11590
line: 1,
11591
column: 0
11592
};
11593
var map = new SourceMapGenerator(aArgs);
11594
var sourceMappingActive = false;
11595
var lastOriginalSource = null;
11596
var lastOriginalLine = null;
11597
var lastOriginalColumn = null;
11598
var lastOriginalName = null;
11599
this.walk(function (chunk, original) {
11600
generated.code += chunk;
11601
if (original.source !== null
11602
&& original.line !== null
11603
&& original.column !== null) {
11604
if(lastOriginalSource !== original.source
11605
|| lastOriginalLine !== original.line
11606
|| lastOriginalColumn !== original.column
11607
|| lastOriginalName !== original.name) {
11608
map.addMapping({
11609
source: original.source,
11610
original: {
11611
line: original.line,
11612
column: original.column
11613
},
11614
generated: {
11615
line: generated.line,
11616
column: generated.column
11617
},
11618
name: original.name
11619
});
11620
}
11621
lastOriginalSource = original.source;
11622
lastOriginalLine = original.line;
11623
lastOriginalColumn = original.column;
11624
lastOriginalName = original.name;
11625
sourceMappingActive = true;
11626
} else if (sourceMappingActive) {
11627
map.addMapping({
11628
generated: {
11629
line: generated.line,
11630
column: generated.column
11631
}
11632
});
11633
lastOriginalSource = null;
11634
sourceMappingActive = false;
11635
}
11636
chunk.split('').forEach(function (ch) {
11637
if (ch === '\n') {
11638
generated.line++;
11639
generated.column = 0;
11640
} else {
11641
generated.column++;
11642
}
11643
});
11644
});
11645
this.walkSourceContents(function (sourceFile, sourceContent) {
11646
map.setSourceContent(sourceFile, sourceContent);
11647
});
11648
11649
return { code: generated.code, map: map };
11650
};
11651
11652
exports.SourceNode = SourceNode;
11653
11654
});
11655
11656
},{"./source-map-generator":17,"./util":19,"amdefine":20}],19:[function(_dereq_,module,exports){
11657
/* -*- Mode: js; js-indent-level: 2; -*- */
11658
/*
11659
* Copyright 2011 Mozilla Foundation and contributors
11660
* Licensed under the New BSD license. See LICENSE or:
11661
* http://opensource.org/licenses/BSD-3-Clause
11662
*/
11663
if (typeof define !== 'function') {
11664
var define = _dereq_('amdefine')(module, _dereq_);
11665
}
11666
define(function (_dereq_, exports, module) {
11667
11668
/**
11669
* This is a helper function for getting values from parameter/options
11670
* objects.
11671
*
11672
* @param args The object we are extracting values from
11673
* @param name The name of the property we are getting.
11674
* @param defaultValue An optional value to return if the property is missing
11675
* from the object. If this is not specified and the property is missing, an
11676
* error will be thrown.
11677
*/
11678
function getArg(aArgs, aName, aDefaultValue) {
11679
if (aName in aArgs) {
11680
return aArgs[aName];
11681
} else if (arguments.length === 3) {
11682
return aDefaultValue;
11683
} else {
11684
throw new Error('"' + aName + '" is a required argument.');
11685
}
11686
}
11687
exports.getArg = getArg;
11688
11689
var urlRegexp = /([\w+\-.]+):\/\/((\w+:\w+)@)?([\w.]+)?(:(\d+))?(\S+)?/;
11690
var dataUrlRegexp = /^data:.+\,.+/;
11691
11692
function urlParse(aUrl) {
11693
var match = aUrl.match(urlRegexp);
11694
if (!match) {
11695
return null;
11696
}
11697
return {
11698
scheme: match[1],
11699
auth: match[3],
11700
host: match[4],
11701
port: match[6],
11702
path: match[7]
11703
};
11704
}
11705
exports.urlParse = urlParse;
11706
11707
function urlGenerate(aParsedUrl) {
11708
var url = aParsedUrl.scheme + "://";
11709
if (aParsedUrl.auth) {
11710
url += aParsedUrl.auth + "@"
11711
}
11712
if (aParsedUrl.host) {
11713
url += aParsedUrl.host;
11714
}
11715
if (aParsedUrl.port) {
11716
url += ":" + aParsedUrl.port
11717
}
11718
if (aParsedUrl.path) {
11719
url += aParsedUrl.path;
11720
}
11721
return url;
11722
}
11723
exports.urlGenerate = urlGenerate;
11724
11725
function join(aRoot, aPath) {
11726
var url;
11727
11728
if (aPath.match(urlRegexp) || aPath.match(dataUrlRegexp)) {
11729
return aPath;
11730
}
11731
11732
if (aPath.charAt(0) === '/' && (url = urlParse(aRoot))) {
11733
url.path = aPath;
11734
return urlGenerate(url);
11735
}
11736
11737
return aRoot.replace(/\/$/, '') + '/' + aPath;
11738
}
11739
exports.join = join;
11740
11741
/**
11742
* Because behavior goes wacky when you set `__proto__` on objects, we
11743
* have to prefix all the strings in our set with an arbitrary character.
11744
*
11745
* See https://github.com/mozilla/source-map/pull/31 and
11746
* https://github.com/mozilla/source-map/issues/30
11747
*
11748
* @param String aStr
11749
*/
11750
function toSetString(aStr) {
11751
return '$' + aStr;
11752
}
11753
exports.toSetString = toSetString;
11754
11755
function fromSetString(aStr) {
11756
return aStr.substr(1);
11757
}
11758
exports.fromSetString = fromSetString;
11759
11760
function relative(aRoot, aPath) {
11761
aRoot = aRoot.replace(/\/$/, '');
11762
11763
var url = urlParse(aRoot);
11764
if (aPath.charAt(0) == "/" && url && url.path == "/") {
11765
return aPath.slice(1);
11766
}
11767
11768
return aPath.indexOf(aRoot + '/') === 0
11769
? aPath.substr(aRoot.length + 1)
11770
: aPath;
11771
}
11772
exports.relative = relative;
11773
11774
function strcmp(aStr1, aStr2) {
11775
var s1 = aStr1 || "";
11776
var s2 = aStr2 || "";
11777
return (s1 > s2) - (s1 < s2);
11778
}
11779
11780
/**
11781
* Comparator between two mappings where the original positions are compared.
11782
*
11783
* Optionally pass in `true` as `onlyCompareGenerated` to consider two
11784
* mappings with the same original source/line/column, but different generated
11785
* line and column the same. Useful when searching for a mapping with a
11786
* stubbed out mapping.
11787
*/
11788
function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {
11789
var cmp;
11790
11791
cmp = strcmp(mappingA.source, mappingB.source);
11792
if (cmp) {
11793
return cmp;
11794
}
11795
11796
cmp = mappingA.originalLine - mappingB.originalLine;
11797
if (cmp) {
11798
return cmp;
11799
}
11800
11801
cmp = mappingA.originalColumn - mappingB.originalColumn;
11802
if (cmp || onlyCompareOriginal) {
11803
return cmp;
11804
}
11805
11806
cmp = strcmp(mappingA.name, mappingB.name);
11807
if (cmp) {
11808
return cmp;
11809
}
11810
11811
cmp = mappingA.generatedLine - mappingB.generatedLine;
11812
if (cmp) {
11813
return cmp;
11814
}
11815
11816
return mappingA.generatedColumn - mappingB.generatedColumn;
11817
};
11818
exports.compareByOriginalPositions = compareByOriginalPositions;
11819
11820
/**
11821
* Comparator between two mappings where the generated positions are
11822
* compared.
11823
*
11824
* Optionally pass in `true` as `onlyCompareGenerated` to consider two
11825
* mappings with the same generated line and column, but different
11826
* source/name/original line and column the same. Useful when searching for a
11827
* mapping with a stubbed out mapping.
11828
*/
11829
function compareByGeneratedPositions(mappingA, mappingB, onlyCompareGenerated) {
11830
var cmp;
11831
11832
cmp = mappingA.generatedLine - mappingB.generatedLine;
11833
if (cmp) {
11834
return cmp;
11835
}
11836
11837
cmp = mappingA.generatedColumn - mappingB.generatedColumn;
11838
if (cmp || onlyCompareGenerated) {
11839
return cmp;
11840
}
11841
11842
cmp = strcmp(mappingA.source, mappingB.source);
11843
if (cmp) {
11844
return cmp;
11845
}
11846
11847
cmp = mappingA.originalLine - mappingB.originalLine;
11848
if (cmp) {
11849
return cmp;
11850
}
11851
11852
cmp = mappingA.originalColumn - mappingB.originalColumn;
11853
if (cmp) {
11854
return cmp;
11855
}
11856
11857
return strcmp(mappingA.name, mappingB.name);
11858
};
11859
exports.compareByGeneratedPositions = compareByGeneratedPositions;
11860
11861
});
11862
11863
},{"amdefine":20}],20:[function(_dereq_,module,exports){
11864
(function (process,__filename){
11865
/** vim: et:ts=4:sw=4:sts=4
11866
* @license amdefine 0.1.0 Copyright (c) 2011, The Dojo Foundation All Rights Reserved.
11867
* Available via the MIT or new BSD license.
11868
* see: http://github.com/jrburke/amdefine for details
11869
*/
11870
11871
/*jslint node: true */
11872
/*global module, process */
11873
'use strict';
11874
11875
/**
11876
* Creates a define for node.
11877
* @param {Object} module the "module" object that is defined by Node for the
11878
* current module.
11879
* @param {Function} [requireFn]. Node's require function for the current module.
11880
* It only needs to be passed in Node versions before 0.5, when module.require
11881
* did not exist.
11882
* @returns {Function} a define function that is usable for the current node
11883
* module.
11884
*/
11885
function amdefine(module, requireFn) {
11886
'use strict';
11887
var defineCache = {},
11888
loaderCache = {},
11889
alreadyCalled = false,
11890
path = _dereq_('path'),
11891
makeRequire, stringRequire;
11892
11893
/**
11894
* Trims the . and .. from an array of path segments.
11895
* It will keep a leading path segment if a .. will become
11896
* the first path segment, to help with module name lookups,
11897
* which act like paths, but can be remapped. But the end result,
11898
* all paths that use this function should look normalized.
11899
* NOTE: this method MODIFIES the input array.
11900
* @param {Array} ary the array of path segments.
11901
*/
11902
function trimDots(ary) {
11903
var i, part;
11904
for (i = 0; ary[i]; i+= 1) {
11905
part = ary[i];
11906
if (part === '.') {
11907
ary.splice(i, 1);
11908
i -= 1;
11909
} else if (part === '..') {
11910
if (i === 1 && (ary[2] === '..' || ary[0] === '..')) {
11911
//End of the line. Keep at least one non-dot
11912
//path segment at the front so it can be mapped
11913
//correctly to disk. Otherwise, there is likely
11914
//no path mapping for a path starting with '..'.
11915
//This can still fail, but catches the most reasonable
11916
//uses of ..
11917
break;
11918
} else if (i > 0) {
11919
ary.splice(i - 1, 2);
11920
i -= 2;
11921
}
11922
}
11923
}
11924
}
11925
11926
function normalize(name, baseName) {
11927
var baseParts;
11928
11929
//Adjust any relative paths.
11930
if (name && name.charAt(0) === '.') {
11931
//If have a base name, try to normalize against it,
11932
//otherwise, assume it is a top-level require that will
11933
//be relative to baseUrl in the end.
11934
if (baseName) {
11935
baseParts = baseName.split('/');
11936
baseParts = baseParts.slice(0, baseParts.length - 1);
11937
baseParts = baseParts.concat(name.split('/'));
11938
trimDots(baseParts);
11939
name = baseParts.join('/');
11940
}
11941
}
11942
11943
return name;
11944
}
11945
11946
/**
11947
* Create the normalize() function passed to a loader plugin's
11948
* normalize method.
11949
*/
11950
function makeNormalize(relName) {
11951
return function (name) {
11952
return normalize(name, relName);
11953
};
11954
}
11955
11956
function makeLoad(id) {
11957
function load(value) {
11958
loaderCache[id] = value;
11959
}
11960
11961
load.fromText = function (id, text) {
11962
//This one is difficult because the text can/probably uses
11963
//define, and any relative paths and requires should be relative
11964
//to that id was it would be found on disk. But this would require
11965
//bootstrapping a module/require fairly deeply from node core.
11966
//Not sure how best to go about that yet.
11967
throw new Error('amdefine does not implement load.fromText');
11968
};
11969
11970
return load;
11971
}
11972
11973
makeRequire = function (systemRequire, exports, module, relId) {
11974
function amdRequire(deps, callback) {
11975
if (typeof deps === 'string') {
11976
//Synchronous, single module require('')
11977
return stringRequire(systemRequire, exports, module, deps, relId);
11978
} else {
11979
//Array of dependencies with a callback.
11980
11981
//Convert the dependencies to modules.
11982
deps = deps.map(function (depName) {
11983
return stringRequire(systemRequire, exports, module, depName, relId);
11984
});
11985
11986
//Wait for next tick to call back the require call.
11987
process.nextTick(function () {
11988
callback.apply(null, deps);
11989
});
11990
}
11991
}
11992
11993
amdRequire.toUrl = function (filePath) {
11994
if (filePath.indexOf('.') === 0) {
11995
return normalize(filePath, path.dirname(module.filename));
11996
} else {
11997
return filePath;
11998
}
11999
};
12000
12001
return amdRequire;
12002
};
12003
12004
//Favor explicit value, passed in if the module wants to support Node 0.4.
12005
requireFn = requireFn || function req() {
12006
return module.require.apply(module, arguments);
12007
};
12008
12009
function runFactory(id, deps, factory) {
12010
var r, e, m, result;
12011
12012
if (id) {
12013
e = loaderCache[id] = {};
12014
m = {
12015
id: id,
12016
uri: __filename,
12017
exports: e
12018
};
12019
r = makeRequire(requireFn, e, m, id);
12020
} else {
12021
//Only support one define call per file
12022
if (alreadyCalled) {
12023
throw new Error('amdefine with no module ID cannot be called more than once per file.');
12024
}
12025
alreadyCalled = true;
12026
12027
//Use the real variables from node
12028
//Use module.exports for exports, since
12029
//the exports in here is amdefine exports.
12030
e = module.exports;
12031
m = module;
12032
r = makeRequire(requireFn, e, m, module.id);
12033
}
12034
12035
//If there are dependencies, they are strings, so need
12036
//to convert them to dependency values.
12037
if (deps) {
12038
deps = deps.map(function (depName) {
12039
return r(depName);
12040
});
12041
}
12042
12043
//Call the factory with the right dependencies.
12044
if (typeof factory === 'function') {
12045
result = factory.apply(m.exports, deps);
12046
} else {
12047
result = factory;
12048
}
12049
12050
if (result !== undefined) {
12051
m.exports = result;
12052
if (id) {
12053
loaderCache[id] = m.exports;
12054
}
12055
}
12056
}
12057
12058
stringRequire = function (systemRequire, exports, module, id, relId) {
12059
//Split the ID by a ! so that
12060
var index = id.indexOf('!'),
12061
originalId = id,
12062
prefix, plugin;
12063
12064
if (index === -1) {
12065
id = normalize(id, relId);
12066
12067
//Straight module lookup. If it is one of the special dependencies,
12068
//deal with it, otherwise, delegate to node.
12069
if (id === 'require') {
12070
return makeRequire(systemRequire, exports, module, relId);
12071
} else if (id === 'exports') {
12072
return exports;
12073
} else if (id === 'module') {
12074
return module;
12075
} else if (loaderCache.hasOwnProperty(id)) {
12076
return loaderCache[id];
12077
} else if (defineCache[id]) {
12078
runFactory.apply(null, defineCache[id]);
12079
return loaderCache[id];
12080
} else {
12081
if(systemRequire) {
12082
return systemRequire(originalId);
12083
} else {
12084
throw new Error('No module with ID: ' + id);
12085
}
12086
}
12087
} else {
12088
//There is a plugin in play.
12089
prefix = id.substring(0, index);
12090
id = id.substring(index + 1, id.length);
12091
12092
plugin = stringRequire(systemRequire, exports, module, prefix, relId);
12093
12094
if (plugin.normalize) {
12095
id = plugin.normalize(id, makeNormalize(relId));
12096
} else {
12097
//Normalize the ID normally.
12098
id = normalize(id, relId);
12099
}
12100
12101
if (loaderCache[id]) {
12102
return loaderCache[id];
12103
} else {
12104
plugin.load(id, makeRequire(systemRequire, exports, module, relId), makeLoad(id), {});
12105
12106
return loaderCache[id];
12107
}
12108
}
12109
};
12110
12111
//Create a define function specific to the module asking for amdefine.
12112
function define(id, deps, factory) {
12113
if (Array.isArray(id)) {
12114
factory = deps;
12115
deps = id;
12116
id = undefined;
12117
} else if (typeof id !== 'string') {
12118
factory = id;
12119
id = deps = undefined;
12120
}
12121
12122
if (deps && !Array.isArray(deps)) {
12123
factory = deps;
12124
deps = undefined;
12125
}
12126
12127
if (!deps) {
12128
deps = ['require', 'exports', 'module'];
12129
}
12130
12131
//Set up properties for this module. If an ID, then use
12132
//internal cache. If no ID, then use the external variables
12133
//for this node module.
12134
if (id) {
12135
//Put the module in deep freeze until there is a
12136
//require call for it.
12137
defineCache[id] = [id, deps, factory];
12138
} else {
12139
runFactory(id, deps, factory);
12140
}
12141
}
12142
12143
//define.require, which has access to all the values in the
12144
//cache. Useful for AMD modules that all have IDs in the file,
12145
//but need to finally export a value to node based on one of those
12146
//IDs.
12147
define.require = function (id) {
12148
if (loaderCache[id]) {
12149
return loaderCache[id];
12150
}
12151
12152
if (defineCache[id]) {
12153
runFactory.apply(null, defineCache[id]);
12154
return loaderCache[id];
12155
}
12156
};
12157
12158
define.amd = {};
12159
12160
return define;
12161
}
12162
12163
module.exports = amdefine;
12164
12165
}).call(this,_dereq_('_process'),"/node_modules/jstransform/node_modules/source-map/node_modules/amdefine/amdefine.js")
12166
},{"_process":8,"path":7}],21:[function(_dereq_,module,exports){
12167
/**
12168
* Copyright 2013 Facebook, Inc.
12169
*
12170
* Licensed under the Apache License, Version 2.0 (the "License");
12171
* you may not use this file except in compliance with the License.
12172
* You may obtain a copy of the License at
12173
*
12174
* http://www.apache.org/licenses/LICENSE-2.0
12175
*
12176
* Unless required by applicable law or agreed to in writing, software
12177
* distributed under the License is distributed on an "AS IS" BASIS,
12178
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12179
* See the License for the specific language governing permissions and
12180
* limitations under the License.
12181
*/
12182
12183
var docblockRe = /^\s*(\/\*\*(.|\r?\n)*?\*\/)/;
12184
var ltrimRe = /^\s*/;
12185
/**
12186
* @param {String} contents
12187
* @return {String}
12188
*/
12189
function extract(contents) {
12190
var match = contents.match(docblockRe);
12191
if (match) {
12192
return match[0].replace(ltrimRe, '') || '';
12193
}
12194
return '';
12195
}
12196
12197
12198
var commentStartRe = /^\/\*\*?/;
12199
var commentEndRe = /\*+\/$/;
12200
var wsRe = /[\t ]+/g;
12201
var stringStartRe = /(\r?\n|^) *\*/g;
12202
var multilineRe = /(?:^|\r?\n) *(@[^\r\n]*?) *\r?\n *([^@\r\n\s][^@\r\n]+?) *\r?\n/g;
12203
var propertyRe = /(?:^|\r?\n) *@(\S+) *([^\r\n]*)/g;
12204
12205
/**
12206
* @param {String} contents
12207
* @return {Array}
12208
*/
12209
function parse(docblock) {
12210
docblock = docblock
12211
.replace(commentStartRe, '')
12212
.replace(commentEndRe, '')
12213
.replace(wsRe, ' ')
12214
.replace(stringStartRe, '$1');
12215
12216
// Normalize multi-line directives
12217
var prev = '';
12218
while (prev != docblock) {
12219
prev = docblock;
12220
docblock = docblock.replace(multilineRe, "\n$1 $2\n");
12221
}
12222
docblock = docblock.trim();
12223
12224
var result = [];
12225
var match;
12226
while (match = propertyRe.exec(docblock)) {
12227
result.push([match[1], match[2]]);
12228
}
12229
12230
return result;
12231
}
12232
12233
/**
12234
* Same as parse but returns an object of prop: value instead of array of paris
12235
* If a property appers more than once the last one will be returned
12236
*
12237
* @param {String} contents
12238
* @return {Object}
12239
*/
12240
function parseAsObject(docblock) {
12241
var pairs = parse(docblock);
12242
var result = {};
12243
for (var i = 0; i < pairs.length; i++) {
12244
result[pairs[i][0]] = pairs[i][1];
12245
}
12246
return result;
12247
}
12248
12249
12250
exports.extract = extract;
12251
exports.parse = parse;
12252
exports.parseAsObject = parseAsObject;
12253
12254
},{}],22:[function(_dereq_,module,exports){
12255
/**
12256
* Copyright 2013 Facebook, Inc.
12257
*
12258
* Licensed under the Apache License, Version 2.0 (the "License");
12259
* you may not use this file except in compliance with the License.
12260
* You may obtain a copy of the License at
12261
*
12262
* http://www.apache.org/licenses/LICENSE-2.0
12263
*
12264
* Unless required by applicable law or agreed to in writing, software
12265
* distributed under the License is distributed on an "AS IS" BASIS,
12266
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12267
* See the License for the specific language governing permissions and
12268
* limitations under the License.
12269
*/
12270
12271
12272
/*jslint node: true*/
12273
"use strict";
12274
12275
var esprima = _dereq_('esprima-fb');
12276
var utils = _dereq_('./utils');
12277
12278
var getBoundaryNode = utils.getBoundaryNode;
12279
var declareIdentInScope = utils.declareIdentInLocalScope;
12280
var initScopeMetadata = utils.initScopeMetadata;
12281
var Syntax = esprima.Syntax;
12282
12283
/**
12284
* @param {object} node
12285
* @param {object} parentNode
12286
* @return {boolean}
12287
*/
12288
function _nodeIsClosureScopeBoundary(node, parentNode) {
12289
if (node.type === Syntax.Program) {
12290
return true;
12291
}
12292
12293
var parentIsFunction =
12294
parentNode.type === Syntax.FunctionDeclaration
12295
|| parentNode.type === Syntax.FunctionExpression
12296
|| parentNode.type === Syntax.ArrowFunctionExpression;
12297
12298
var parentIsCurlylessArrowFunc =
12299
parentNode.type === Syntax.ArrowFunctionExpression
12300
&& node === parentNode.body;
12301
12302
return parentIsFunction
12303
&& (node.type === Syntax.BlockStatement || parentIsCurlylessArrowFunc);
12304
}
12305
12306
function _nodeIsBlockScopeBoundary(node, parentNode) {
12307
if (node.type === Syntax.Program) {
12308
return false;
12309
}
12310
12311
return node.type === Syntax.BlockStatement
12312
&& parentNode.type === Syntax.CatchClause;
12313
}
12314
12315
/**
12316
* @param {object} node
12317
* @param {array} path
12318
* @param {object} state
12319
*/
12320
function traverse(node, path, state) {
12321
/*jshint -W004*/
12322
// Create a scope stack entry if this is the first node we've encountered in
12323
// its local scope
12324
var startIndex = null;
12325
var parentNode = path[0];
12326
if (!Array.isArray(node) && state.localScope.parentNode !== parentNode) {
12327
if (_nodeIsClosureScopeBoundary(node, parentNode)) {
12328
var scopeIsStrict = state.scopeIsStrict;
12329
if (!scopeIsStrict
12330
&& (node.type === Syntax.BlockStatement
12331
|| node.type === Syntax.Program)) {
12332
scopeIsStrict =
12333
node.body.length > 0
12334
&& node.body[0].type === Syntax.ExpressionStatement
12335
&& node.body[0].expression.type === Syntax.Literal
12336
&& node.body[0].expression.value === 'use strict';
12337
}
12338
12339
if (node.type === Syntax.Program) {
12340
startIndex = state.g.buffer.length;
12341
state = utils.updateState(state, {
12342
scopeIsStrict: scopeIsStrict
12343
});
12344
} else {
12345
startIndex = state.g.buffer.length + 1;
12346
state = utils.updateState(state, {
12347
localScope: {
12348
parentNode: parentNode,
12349
parentScope: state.localScope,
12350
identifiers: {},
12351
tempVarIndex: 0,
12352
tempVars: []
12353
},
12354
scopeIsStrict: scopeIsStrict
12355
});
12356
12357
// All functions have an implicit 'arguments' object in scope
12358
declareIdentInScope('arguments', initScopeMetadata(node), state);
12359
12360
// Include function arg identifiers in the scope boundaries of the
12361
// function
12362
if (parentNode.params.length > 0) {
12363
var param;
12364
var metadata = initScopeMetadata(parentNode, path.slice(1), path[0]);
12365
for (var i = 0; i < parentNode.params.length; i++) {
12366
param = parentNode.params[i];
12367
if (param.type === Syntax.Identifier) {
12368
declareIdentInScope(param.name, metadata, state);
12369
}
12370
}
12371
}
12372
12373
// Include rest arg identifiers in the scope boundaries of their
12374
// functions
12375
if (parentNode.rest) {
12376
var metadata = initScopeMetadata(
12377
parentNode,
12378
path.slice(1),
12379
path[0]
12380
);
12381
declareIdentInScope(parentNode.rest.name, metadata, state);
12382
}
12383
12384
// Named FunctionExpressions scope their name within the body block of
12385
// themselves only
12386
if (parentNode.type === Syntax.FunctionExpression && parentNode.id) {
12387
var metaData =
12388
initScopeMetadata(parentNode, path.parentNodeslice, parentNode);
12389
declareIdentInScope(parentNode.id.name, metaData, state);
12390
}
12391
}
12392
12393
// Traverse and find all local identifiers in this closure first to
12394
// account for function/variable declaration hoisting
12395
collectClosureIdentsAndTraverse(node, path, state);
12396
}
12397
12398
if (_nodeIsBlockScopeBoundary(node, parentNode)) {
12399
startIndex = state.g.buffer.length;
12400
state = utils.updateState(state, {
12401
localScope: {
12402
parentNode: parentNode,
12403
parentScope: state.localScope,
12404
identifiers: {},
12405
tempVarIndex: 0,
12406
tempVars: []
12407
}
12408
});
12409
12410
if (parentNode.type === Syntax.CatchClause) {
12411
var metadata = initScopeMetadata(
12412
parentNode,
12413
path.slice(1),
12414
parentNode
12415
);
12416
declareIdentInScope(parentNode.param.name, metadata, state);
12417
}
12418
collectBlockIdentsAndTraverse(node, path, state);
12419
}
12420
}
12421
12422
// Only catchup() before and after traversing a child node
12423
function traverser(node, path, state) {
12424
node.range && utils.catchup(node.range[0], state);
12425
traverse(node, path, state);
12426
node.range && utils.catchup(node.range[1], state);
12427
}
12428
12429
utils.analyzeAndTraverse(walker, traverser, node, path, state);
12430
12431
// Inject temp variables into the scope.
12432
if (startIndex !== null) {
12433
utils.injectTempVarDeclarations(state, startIndex);
12434
}
12435
}
12436
12437
function collectClosureIdentsAndTraverse(node, path, state) {
12438
utils.analyzeAndTraverse(
12439
visitLocalClosureIdentifiers,
12440
collectClosureIdentsAndTraverse,
12441
node,
12442
path,
12443
state
12444
);
12445
}
12446
12447
function collectBlockIdentsAndTraverse(node, path, state) {
12448
utils.analyzeAndTraverse(
12449
visitLocalBlockIdentifiers,
12450
collectBlockIdentsAndTraverse,
12451
node,
12452
path,
12453
state
12454
);
12455
}
12456
12457
function visitLocalClosureIdentifiers(node, path, state) {
12458
var metaData;
12459
switch (node.type) {
12460
case Syntax.ArrowFunctionExpression:
12461
case Syntax.FunctionExpression:
12462
// Function expressions don't get their names (if there is one) added to
12463
// the closure scope they're defined in
12464
return false;
12465
case Syntax.ClassDeclaration:
12466
case Syntax.ClassExpression:
12467
case Syntax.FunctionDeclaration:
12468
if (node.id) {
12469
metaData = initScopeMetadata(getBoundaryNode(path), path.slice(), node);
12470
declareIdentInScope(node.id.name, metaData, state);
12471
}
12472
return false;
12473
case Syntax.VariableDeclarator:
12474
// Variables have function-local scope
12475
if (path[0].kind === 'var') {
12476
metaData = initScopeMetadata(getBoundaryNode(path), path.slice(), node);
12477
declareIdentInScope(node.id.name, metaData, state);
12478
}
12479
break;
12480
}
12481
}
12482
12483
function visitLocalBlockIdentifiers(node, path, state) {
12484
// TODO: Support 'let' here...maybe...one day...or something...
12485
if (node.type === Syntax.CatchClause) {
12486
return false;
12487
}
12488
}
12489
12490
function walker(node, path, state) {
12491
var visitors = state.g.visitors;
12492
for (var i = 0; i < visitors.length; i++) {
12493
if (visitors[i].test(node, path, state)) {
12494
return visitors[i](traverse, node, path, state);
12495
}
12496
}
12497
}
12498
12499
var _astCache = {};
12500
12501
function getAstForSource(source, options) {
12502
if (_astCache[source] && !options.disableAstCache) {
12503
return _astCache[source];
12504
}
12505
var ast = esprima.parse(source, {
12506
comment: true,
12507
loc: true,
12508
range: true,
12509
sourceType: options.sourceType
12510
});
12511
if (!options.disableAstCache) {
12512
_astCache[source] = ast;
12513
}
12514
return ast;
12515
}
12516
12517
/**
12518
* Applies all available transformations to the source
12519
* @param {array} visitors
12520
* @param {string} source
12521
* @param {?object} options
12522
* @return {object}
12523
*/
12524
function transform(visitors, source, options) {
12525
options = options || {};
12526
var ast;
12527
try {
12528
ast = getAstForSource(source, options);
12529
} catch (e) {
12530
e.message = 'Parse Error: ' + e.message;
12531
throw e;
12532
}
12533
var state = utils.createState(source, ast, options);
12534
state.g.visitors = visitors;
12535
12536
if (options.sourceMap) {
12537
var SourceMapGenerator = _dereq_('source-map').SourceMapGenerator;
12538
state.g.sourceMap = new SourceMapGenerator({file: options.filename || 'transformed.js'});
12539
}
12540
12541
traverse(ast, [], state);
12542
utils.catchup(source.length, state);
12543
12544
var ret = {code: state.g.buffer, extra: state.g.extra};
12545
if (options.sourceMap) {
12546
ret.sourceMap = state.g.sourceMap;
12547
ret.sourceMapFilename = options.filename || 'source.js';
12548
}
12549
return ret;
12550
}
12551
12552
exports.transform = transform;
12553
exports.Syntax = Syntax;
12554
12555
},{"./utils":23,"esprima-fb":9,"source-map":11}],23:[function(_dereq_,module,exports){
12556
/**
12557
* Copyright 2013 Facebook, Inc.
12558
*
12559
* Licensed under the Apache License, Version 2.0 (the "License");
12560
* you may not use this file except in compliance with the License.
12561
* You may obtain a copy of the License at
12562
*
12563
* http://www.apache.org/licenses/LICENSE-2.0
12564
*
12565
* Unless required by applicable law or agreed to in writing, software
12566
* distributed under the License is distributed on an "AS IS" BASIS,
12567
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12568
* See the License for the specific language governing permissions and
12569
* limitations under the License.
12570
*/
12571
12572
12573
/*jslint node: true*/
12574
var Syntax = _dereq_('esprima-fb').Syntax;
12575
var leadingIndentRegexp = /(^|\n)( {2}|\t)/g;
12576
var nonWhiteRegexp = /(\S)/g;
12577
12578
/**
12579
* A `state` object represents the state of the parser. It has "local" and
12580
* "global" parts. Global contains parser position, source, etc. Local contains
12581
* scope based properties like current class name. State should contain all the
12582
* info required for transformation. It's the only mandatory object that is
12583
* being passed to every function in transform chain.
12584
*
12585
* @param {string} source
12586
* @param {object} transformOptions
12587
* @return {object}
12588
*/
12589
function createState(source, rootNode, transformOptions) {
12590
return {
12591
/**
12592
* A tree representing the current local scope (and its lexical scope chain)
12593
* Useful for tracking identifiers from parent scopes, etc.
12594
* @type {Object}
12595
*/
12596
localScope: {
12597
parentNode: rootNode,
12598
parentScope: null,
12599
identifiers: {},
12600
tempVarIndex: 0,
12601
tempVars: []
12602
},
12603
/**
12604
* The name (and, if applicable, expression) of the super class
12605
* @type {Object}
12606
*/
12607
superClass: null,
12608
/**
12609
* The namespace to use when munging identifiers
12610
* @type {String}
12611
*/
12612
mungeNamespace: '',
12613
/**
12614
* Ref to the node for the current MethodDefinition
12615
* @type {Object}
12616
*/
12617
methodNode: null,
12618
/**
12619
* Ref to the node for the FunctionExpression of the enclosing
12620
* MethodDefinition
12621
* @type {Object}
12622
*/
12623
methodFuncNode: null,
12624
/**
12625
* Name of the enclosing class
12626
* @type {String}
12627
*/
12628
className: null,
12629
/**
12630
* Whether we're currently within a `strict` scope
12631
* @type {Bool}
12632
*/
12633
scopeIsStrict: null,
12634
/**
12635
* Indentation offset
12636
* @type {Number}
12637
*/
12638
indentBy: 0,
12639
/**
12640
* Global state (not affected by updateState)
12641
* @type {Object}
12642
*/
12643
g: {
12644
/**
12645
* A set of general options that transformations can consider while doing
12646
* a transformation:
12647
*
12648
* - minify
12649
* Specifies that transformation steps should do their best to minify
12650
* the output source when possible. This is useful for places where
12651
* minification optimizations are possible with higher-level context
12652
* info than what jsxmin can provide.
12653
*
12654
* For example, the ES6 class transform will minify munged private
12655
* variables if this flag is set.
12656
*/
12657
opts: transformOptions,
12658
/**
12659
* Current position in the source code
12660
* @type {Number}
12661
*/
12662
position: 0,
12663
/**
12664
* Auxiliary data to be returned by transforms
12665
* @type {Object}
12666
*/
12667
extra: {},
12668
/**
12669
* Buffer containing the result
12670
* @type {String}
12671
*/
12672
buffer: '',
12673
/**
12674
* Source that is being transformed
12675
* @type {String}
12676
*/
12677
source: source,
12678
12679
/**
12680
* Cached parsed docblock (see getDocblock)
12681
* @type {object}
12682
*/
12683
docblock: null,
12684
12685
/**
12686
* Whether the thing was used
12687
* @type {Boolean}
12688
*/
12689
tagNamespaceUsed: false,
12690
12691
/**
12692
* If using bolt xjs transformation
12693
* @type {Boolean}
12694
*/
12695
isBolt: undefined,
12696
12697
/**
12698
* Whether to record source map (expensive) or not
12699
* @type {SourceMapGenerator|null}
12700
*/
12701
sourceMap: null,
12702
12703
/**
12704
* Filename of the file being processed. Will be returned as a source
12705
* attribute in the source map
12706
*/
12707
sourceMapFilename: 'source.js',
12708
12709
/**
12710
* Only when source map is used: last line in the source for which
12711
* source map was generated
12712
* @type {Number}
12713
*/
12714
sourceLine: 1,
12715
12716
/**
12717
* Only when source map is used: last line in the buffer for which
12718
* source map was generated
12719
* @type {Number}
12720
*/
12721
bufferLine: 1,
12722
12723
/**
12724
* The top-level Program AST for the original file.
12725
*/
12726
originalProgramAST: null,
12727
12728
sourceColumn: 0,
12729
bufferColumn: 0
12730
}
12731
};
12732
}
12733
12734
/**
12735
* Updates a copy of a given state with "update" and returns an updated state.
12736
*
12737
* @param {object} state
12738
* @param {object} update
12739
* @return {object}
12740
*/
12741
function updateState(state, update) {
12742
var ret = Object.create(state);
12743
Object.keys(update).forEach(function(updatedKey) {
12744
ret[updatedKey] = update[updatedKey];
12745
});
12746
return ret;
12747
}
12748
12749
/**
12750
* Given a state fill the resulting buffer from the original source up to
12751
* the end
12752
*
12753
* @param {number} end
12754
* @param {object} state
12755
* @param {?function} contentTransformer Optional callback to transform newly
12756
* added content.
12757
*/
12758
function catchup(end, state, contentTransformer) {
12759
if (end < state.g.position) {
12760
// cannot move backwards
12761
return;
12762
}
12763
var source = state.g.source.substring(state.g.position, end);
12764
var transformed = updateIndent(source, state);
12765
if (state.g.sourceMap && transformed) {
12766
// record where we are
12767
state.g.sourceMap.addMapping({
12768
generated: { line: state.g.bufferLine, column: state.g.bufferColumn },
12769
original: { line: state.g.sourceLine, column: state.g.sourceColumn },
12770
source: state.g.sourceMapFilename
12771
});
12772
12773
// record line breaks in transformed source
12774
var sourceLines = source.split('\n');
12775
var transformedLines = transformed.split('\n');
12776
// Add line break mappings between last known mapping and the end of the
12777
// added piece. So for the code piece
12778
// (foo, bar);
12779
// > var x = 2;
12780
// > var b = 3;
12781
// var c =
12782
// only add lines marked with ">": 2, 3.
12783
for (var i = 1; i < sourceLines.length - 1; i++) {
12784
state.g.sourceMap.addMapping({
12785
generated: { line: state.g.bufferLine, column: 0 },
12786
original: { line: state.g.sourceLine, column: 0 },
12787
source: state.g.sourceMapFilename
12788
});
12789
state.g.sourceLine++;
12790
state.g.bufferLine++;
12791
}
12792
// offset for the last piece
12793
if (sourceLines.length > 1) {
12794
state.g.sourceLine++;
12795
state.g.bufferLine++;
12796
state.g.sourceColumn = 0;
12797
state.g.bufferColumn = 0;
12798
}
12799
state.g.sourceColumn += sourceLines[sourceLines.length - 1].length;
12800
state.g.bufferColumn +=
12801
transformedLines[transformedLines.length - 1].length;
12802
}
12803
state.g.buffer +=
12804
contentTransformer ? contentTransformer(transformed) : transformed;
12805
state.g.position = end;
12806
}
12807
12808
/**
12809
* Returns original source for an AST node.
12810
* @param {object} node
12811
* @param {object} state
12812
* @return {string}
12813
*/
12814
function getNodeSourceText(node, state) {
12815
return state.g.source.substring(node.range[0], node.range[1]);
12816
}
12817
12818
function _replaceNonWhite(value) {
12819
return value.replace(nonWhiteRegexp, ' ');
12820
}
12821
12822
/**
12823
* Removes all non-whitespace characters
12824
*/
12825
function _stripNonWhite(value) {
12826
return value.replace(nonWhiteRegexp, '');
12827
}
12828
12829
/**
12830
* Finds the position of the next instance of the specified syntactic char in
12831
* the pending source.
12832
*
12833
* NOTE: This will skip instances of the specified char if they sit inside a
12834
* comment body.
12835
*
12836
* NOTE: This function also assumes that the buffer's current position is not
12837
* already within a comment or a string. This is rarely the case since all
12838
* of the buffer-advancement utility methods tend to be used on syntactic
12839
* nodes' range values -- but it's a small gotcha that's worth mentioning.
12840
*/
12841
function getNextSyntacticCharOffset(char, state) {
12842
var pendingSource = state.g.source.substring(state.g.position);
12843
var pendingSourceLines = pendingSource.split('\n');
12844
12845
var charOffset = 0;
12846
var line;
12847
var withinBlockComment = false;
12848
var withinString = false;
12849
lineLoop: while ((line = pendingSourceLines.shift()) !== undefined) {
12850
var lineEndPos = charOffset + line.length;
12851
charLoop: for (; charOffset < lineEndPos; charOffset++) {
12852
var currChar = pendingSource[charOffset];
12853
if (currChar === '"' || currChar === '\'') {
12854
withinString = !withinString;
12855
continue charLoop;
12856
} else if (withinString) {
12857
continue charLoop;
12858
} else if (charOffset + 1 < lineEndPos) {
12859
var nextTwoChars = currChar + line[charOffset + 1];
12860
if (nextTwoChars === '//') {
12861
charOffset = lineEndPos + 1;
12862
continue lineLoop;
12863
} else if (nextTwoChars === '/*') {
12864
withinBlockComment = true;
12865
charOffset += 1;
12866
continue charLoop;
12867
} else if (nextTwoChars === '*/') {
12868
withinBlockComment = false;
12869
charOffset += 1;
12870
continue charLoop;
12871
}
12872
}
12873
12874
if (!withinBlockComment && currChar === char) {
12875
return charOffset + state.g.position;
12876
}
12877
}
12878
12879
// Account for '\n'
12880
charOffset++;
12881
withinString = false;
12882
}
12883
12884
throw new Error('`' + char + '` not found!');
12885
}
12886
12887
/**
12888
* Catches up as `catchup` but replaces non-whitespace chars with spaces.
12889
*/
12890
function catchupWhiteOut(end, state) {
12891
catchup(end, state, _replaceNonWhite);
12892
}
12893
12894
/**
12895
* Catches up as `catchup` but removes all non-whitespace characters.
12896
*/
12897
function catchupWhiteSpace(end, state) {
12898
catchup(end, state, _stripNonWhite);
12899
}
12900
12901
/**
12902
* Removes all non-newline characters
12903
*/
12904
var reNonNewline = /[^\n]/g;
12905
function stripNonNewline(value) {
12906
return value.replace(reNonNewline, function() {
12907
return '';
12908
});
12909
}
12910
12911
/**
12912
* Catches up as `catchup` but removes all non-newline characters.
12913
*
12914
* Equivalent to appending as many newlines as there are in the original source
12915
* between the current position and `end`.
12916
*/
12917
function catchupNewlines(end, state) {
12918
catchup(end, state, stripNonNewline);
12919
}
12920
12921
12922
/**
12923
* Same as catchup but does not touch the buffer
12924
*
12925
* @param {number} end
12926
* @param {object} state
12927
*/
12928
function move(end, state) {
12929
// move the internal cursors
12930
if (state.g.sourceMap) {
12931
if (end < state.g.position) {
12932
state.g.position = 0;
12933
state.g.sourceLine = 1;
12934
state.g.sourceColumn = 0;
12935
}
12936
12937
var source = state.g.source.substring(state.g.position, end);
12938
var sourceLines = source.split('\n');
12939
if (sourceLines.length > 1) {
12940
state.g.sourceLine += sourceLines.length - 1;
12941
state.g.sourceColumn = 0;
12942
}
12943
state.g.sourceColumn += sourceLines[sourceLines.length - 1].length;
12944
}
12945
state.g.position = end;
12946
}
12947
12948
/**
12949
* Appends a string of text to the buffer
12950
*
12951
* @param {string} str
12952
* @param {object} state
12953
*/
12954
function append(str, state) {
12955
if (state.g.sourceMap && str) {
12956
state.g.sourceMap.addMapping({
12957
generated: { line: state.g.bufferLine, column: state.g.bufferColumn },
12958
original: { line: state.g.sourceLine, column: state.g.sourceColumn },
12959
source: state.g.sourceMapFilename
12960
});
12961
var transformedLines = str.split('\n');
12962
if (transformedLines.length > 1) {
12963
state.g.bufferLine += transformedLines.length - 1;
12964
state.g.bufferColumn = 0;
12965
}
12966
state.g.bufferColumn +=
12967
transformedLines[transformedLines.length - 1].length;
12968
}
12969
state.g.buffer += str;
12970
}
12971
12972
/**
12973
* Update indent using state.indentBy property. Indent is measured in
12974
* double spaces. Updates a single line only.
12975
*
12976
* @param {string} str
12977
* @param {object} state
12978
* @return {string}
12979
*/
12980
function updateIndent(str, state) {
12981
/*jshint -W004*/
12982
var indentBy = state.indentBy;
12983
if (indentBy < 0) {
12984
for (var i = 0; i < -indentBy; i++) {
12985
str = str.replace(leadingIndentRegexp, '$1');
12986
}
12987
} else {
12988
for (var i = 0; i < indentBy; i++) {
12989
str = str.replace(leadingIndentRegexp, '$1$2$2');
12990
}
12991
}
12992
return str;
12993
}
12994
12995
/**
12996
* Calculates indent from the beginning of the line until "start" or the first
12997
* character before start.
12998
* @example
12999
* " foo.bar()"
13000
* ^
13001
* start
13002
* indent will be " "
13003
*
13004
* @param {number} start
13005
* @param {object} state
13006
* @return {string}
13007
*/
13008
function indentBefore(start, state) {
13009
var end = start;
13010
start = start - 1;
13011
13012
while (start > 0 && state.g.source[start] != '\n') {
13013
if (!state.g.source[start].match(/[ \t]/)) {
13014
end = start;
13015
}
13016
start--;
13017
}
13018
return state.g.source.substring(start + 1, end);
13019
}
13020
13021
function getDocblock(state) {
13022
if (!state.g.docblock) {
13023
var docblock = _dereq_('./docblock');
13024
state.g.docblock =
13025
docblock.parseAsObject(docblock.extract(state.g.source));
13026
}
13027
return state.g.docblock;
13028
}
13029
13030
function identWithinLexicalScope(identName, state, stopBeforeNode) {
13031
var currScope = state.localScope;
13032
while (currScope) {
13033
if (currScope.identifiers[identName] !== undefined) {
13034
return true;
13035
}
13036
13037
if (stopBeforeNode && currScope.parentNode === stopBeforeNode) {
13038
break;
13039
}
13040
13041
currScope = currScope.parentScope;
13042
}
13043
return false;
13044
}
13045
13046
function identInLocalScope(identName, state) {
13047
return state.localScope.identifiers[identName] !== undefined;
13048
}
13049
13050
/**
13051
* @param {object} boundaryNode
13052
* @param {?array} path
13053
* @return {?object} node
13054
*/
13055
function initScopeMetadata(boundaryNode, path, node) {
13056
return {
13057
boundaryNode: boundaryNode,
13058
bindingPath: path,
13059
bindingNode: node
13060
};
13061
}
13062
13063
function declareIdentInLocalScope(identName, metaData, state) {
13064
state.localScope.identifiers[identName] = {
13065
boundaryNode: metaData.boundaryNode,
13066
path: metaData.bindingPath,
13067
node: metaData.bindingNode,
13068
state: Object.create(state)
13069
};
13070
}
13071
13072
function getLexicalBindingMetadata(identName, state) {
13073
var currScope = state.localScope;
13074
while (currScope) {
13075
if (currScope.identifiers[identName] !== undefined) {
13076
return currScope.identifiers[identName];
13077
}
13078
13079
currScope = currScope.parentScope;
13080
}
13081
}
13082
13083
function getLocalBindingMetadata(identName, state) {
13084
return state.localScope.identifiers[identName];
13085
}
13086
13087
/**
13088
* Apply the given analyzer function to the current node. If the analyzer
13089
* doesn't return false, traverse each child of the current node using the given
13090
* traverser function.
13091
*
13092
* @param {function} analyzer
13093
* @param {function} traverser
13094
* @param {object} node
13095
* @param {array} path
13096
* @param {object} state
13097
*/
13098
function analyzeAndTraverse(analyzer, traverser, node, path, state) {
13099
if (node.type) {
13100
if (analyzer(node, path, state) === false) {
13101
return;
13102
}
13103
path.unshift(node);
13104
}
13105
13106
getOrderedChildren(node).forEach(function(child) {
13107
traverser(child, path, state);
13108
});
13109
13110
node.type && path.shift();
13111
}
13112
13113
/**
13114
* It is crucial that we traverse in order, or else catchup() on a later
13115
* node that is processed out of order can move the buffer past a node
13116
* that we haven't handled yet, preventing us from modifying that node.
13117
*
13118
* This can happen when a node has multiple properties containing children.
13119
* For example, XJSElement nodes have `openingElement`, `closingElement` and
13120
* `children`. If we traverse `openingElement`, then `closingElement`, then
13121
* when we get to `children`, the buffer has already caught up to the end of
13122
* the closing element, after the children.
13123
*
13124
* This is basically a Schwartzian transform. Collects an array of children,
13125
* each one represented as [child, startIndex]; sorts the array by start
13126
* index; then traverses the children in that order.
13127
*/
13128
function getOrderedChildren(node) {
13129
var queue = [];
13130
for (var key in node) {
13131
if (node.hasOwnProperty(key)) {
13132
enqueueNodeWithStartIndex(queue, node[key]);
13133
}
13134
}
13135
queue.sort(function(a, b) { return a[1] - b[1]; });
13136
return queue.map(function(pair) { return pair[0]; });
13137
}
13138
13139
/**
13140
* Helper function for analyzeAndTraverse which queues up all of the children
13141
* of the given node.
13142
*
13143
* Children can also be found in arrays, so we basically want to merge all of
13144
* those arrays together so we can sort them and then traverse the children
13145
* in order.
13146
*
13147
* One example is the Program node. It contains `body` and `comments`, both
13148
* arrays. Lexographically, comments are interspersed throughout the body
13149
* nodes, but esprima's AST groups them together.
13150
*/
13151
function enqueueNodeWithStartIndex(queue, node) {
13152
if (typeof node !== 'object' || node === null) {
13153
return;
13154
}
13155
if (node.range) {
13156
queue.push([node, node.range[0]]);
13157
} else if (Array.isArray(node)) {
13158
for (var ii = 0; ii < node.length; ii++) {
13159
enqueueNodeWithStartIndex(queue, node[ii]);
13160
}
13161
}
13162
}
13163
13164
/**
13165
* Checks whether a node or any of its sub-nodes contains
13166
* a syntactic construct of the passed type.
13167
* @param {object} node - AST node to test.
13168
* @param {string} type - node type to lookup.
13169
*/
13170
function containsChildOfType(node, type) {
13171
return containsChildMatching(node, function(node) {
13172
return node.type === type;
13173
});
13174
}
13175
13176
function containsChildMatching(node, matcher) {
13177
var foundMatchingChild = false;
13178
function nodeTypeAnalyzer(node) {
13179
if (matcher(node) === true) {
13180
foundMatchingChild = true;
13181
return false;
13182
}
13183
}
13184
function nodeTypeTraverser(child, path, state) {
13185
if (!foundMatchingChild) {
13186
foundMatchingChild = containsChildMatching(child, matcher);
13187
}
13188
}
13189
analyzeAndTraverse(
13190
nodeTypeAnalyzer,
13191
nodeTypeTraverser,
13192
node,
13193
[]
13194
);
13195
return foundMatchingChild;
13196
}
13197
13198
var scopeTypes = {};
13199
scopeTypes[Syntax.ArrowFunctionExpression] = true;
13200
scopeTypes[Syntax.FunctionExpression] = true;
13201
scopeTypes[Syntax.FunctionDeclaration] = true;
13202
scopeTypes[Syntax.Program] = true;
13203
13204
function getBoundaryNode(path) {
13205
for (var ii = 0; ii < path.length; ++ii) {
13206
if (scopeTypes[path[ii].type]) {
13207
return path[ii];
13208
}
13209
}
13210
throw new Error(
13211
'Expected to find a node with one of the following types in path:\n' +
13212
JSON.stringify(Object.keys(scopeTypes))
13213
);
13214
}
13215
13216
function getTempVar(tempVarIndex) {
13217
return '$__' + tempVarIndex;
13218
}
13219
13220
function injectTempVar(state) {
13221
var tempVar = '$__' + (state.localScope.tempVarIndex++);
13222
state.localScope.tempVars.push(tempVar);
13223
return tempVar;
13224
}
13225
13226
function injectTempVarDeclarations(state, index) {
13227
if (state.localScope.tempVars.length) {
13228
state.g.buffer =
13229
state.g.buffer.slice(0, index) +
13230
'var ' + state.localScope.tempVars.join(', ') + ';' +
13231
state.g.buffer.slice(index);
13232
state.localScope.tempVars = [];
13233
}
13234
}
13235
13236
exports.analyzeAndTraverse = analyzeAndTraverse;
13237
exports.append = append;
13238
exports.catchup = catchup;
13239
exports.catchupNewlines = catchupNewlines;
13240
exports.catchupWhiteOut = catchupWhiteOut;
13241
exports.catchupWhiteSpace = catchupWhiteSpace;
13242
exports.containsChildMatching = containsChildMatching;
13243
exports.containsChildOfType = containsChildOfType;
13244
exports.createState = createState;
13245
exports.declareIdentInLocalScope = declareIdentInLocalScope;
13246
exports.getBoundaryNode = getBoundaryNode;
13247
exports.getDocblock = getDocblock;
13248
exports.getLexicalBindingMetadata = getLexicalBindingMetadata;
13249
exports.getLocalBindingMetadata = getLocalBindingMetadata;
13250
exports.getNextSyntacticCharOffset = getNextSyntacticCharOffset;
13251
exports.getNodeSourceText = getNodeSourceText;
13252
exports.getOrderedChildren = getOrderedChildren;
13253
exports.getTempVar = getTempVar;
13254
exports.identInLocalScope = identInLocalScope;
13255
exports.identWithinLexicalScope = identWithinLexicalScope;
13256
exports.indentBefore = indentBefore;
13257
exports.initScopeMetadata = initScopeMetadata;
13258
exports.injectTempVar = injectTempVar;
13259
exports.injectTempVarDeclarations = injectTempVarDeclarations;
13260
exports.move = move;
13261
exports.scopeTypes = scopeTypes;
13262
exports.updateIndent = updateIndent;
13263
exports.updateState = updateState;
13264
13265
},{"./docblock":21,"esprima-fb":9}],24:[function(_dereq_,module,exports){
13266
/**
13267
* Copyright 2013 Facebook, Inc.
13268
*
13269
* Licensed under the Apache License, Version 2.0 (the "License");
13270
* you may not use this file except in compliance with the License.
13271
* You may obtain a copy of the License at
13272
*
13273
* http://www.apache.org/licenses/LICENSE-2.0
13274
*
13275
* Unless required by applicable law or agreed to in writing, software
13276
* distributed under the License is distributed on an "AS IS" BASIS,
13277
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13278
* See the License for the specific language governing permissions and
13279
* limitations under the License.
13280
*/
13281
13282
/*global exports:true*/
13283
13284
/**
13285
* Desugars ES6 Arrow functions to ES3 function expressions.
13286
* If the function contains `this` expression -- automatically
13287
* binds the function to current value of `this`.
13288
*
13289
* Single parameter, simple expression:
13290
*
13291
* [1, 2, 3].map(x => x * x);
13292
*
13293
* [1, 2, 3].map(function(x) { return x * x; });
13294
*
13295
* Several parameters, complex block:
13296
*
13297
* this.users.forEach((user, idx) => {
13298
* return this.isActive(idx) && this.send(user);
13299
* });
13300
*
13301
* this.users.forEach(function(user, idx) {
13302
* return this.isActive(idx) && this.send(user);
13303
* }.bind(this));
13304
*
13305
*/
13306
var restParamVisitors = _dereq_('./es6-rest-param-visitors');
13307
var destructuringVisitors = _dereq_('./es6-destructuring-visitors');
13308
13309
var Syntax = _dereq_('esprima-fb').Syntax;
13310
var utils = _dereq_('../src/utils');
13311
13312
/**
13313
* @public
13314
*/
13315
function visitArrowFunction(traverse, node, path, state) {
13316
var notInExpression = (path[0].type === Syntax.ExpressionStatement);
13317
13318
// Wrap a function into a grouping operator, if it's not
13319
// in the expression position.
13320
if (notInExpression) {
13321
utils.append('(', state);
13322
}
13323
13324
utils.append('function', state);
13325
renderParams(traverse, node, path, state);
13326
13327
// Skip arrow.
13328
utils.catchupWhiteSpace(node.body.range[0], state);
13329
13330
var renderBody = node.body.type == Syntax.BlockStatement
13331
? renderStatementBody
13332
: renderExpressionBody;
13333
13334
path.unshift(node);
13335
renderBody(traverse, node, path, state);
13336
path.shift();
13337
13338
// Bind the function only if `this` value is used
13339
// inside it or inside any sub-expression.
13340
var containsBindingSyntax =
13341
utils.containsChildMatching(node.body, function(node) {
13342
return node.type === Syntax.ThisExpression
13343
|| (node.type === Syntax.Identifier
13344
&& node.name === "super");
13345
});
13346
13347
if (containsBindingSyntax) {
13348
utils.append('.bind(this)', state);
13349
}
13350
13351
utils.catchupWhiteSpace(node.range[1], state);
13352
13353
// Close wrapper if not in the expression.
13354
if (notInExpression) {
13355
utils.append(')', state);
13356
}
13357
13358
return false;
13359
}
13360
13361
function renderParams(traverse, node, path, state) {
13362
// To preserve inline typechecking directives, we
13363
// distinguish between parens-free and paranthesized single param.
13364
if (isParensFreeSingleParam(node, state) || !node.params.length) {
13365
utils.append('(', state);
13366
}
13367
if (node.params.length !== 0) {
13368
path.unshift(node);
13369
traverse(node.params, path, state);
13370
path.unshift();
13371
}
13372
utils.append(')', state);
13373
}
13374
13375
function isParensFreeSingleParam(node, state) {
13376
return node.params.length === 1 &&
13377
state.g.source[state.g.position] !== '(';
13378
}
13379
13380
function renderExpressionBody(traverse, node, path, state) {
13381
// Wrap simple expression bodies into a block
13382
// with explicit return statement.
13383
utils.append('{', state);
13384
13385
// Special handling of rest param.
13386
if (node.rest) {
13387
utils.append(
13388
restParamVisitors.renderRestParamSetup(node, state),
13389
state
13390
);
13391
}
13392
13393
// Special handling of destructured params.
13394
destructuringVisitors.renderDestructuredComponents(
13395
node,
13396
utils.updateState(state, {
13397
localScope: {
13398
parentNode: state.parentNode,
13399
parentScope: state.parentScope,
13400
identifiers: state.identifiers,
13401
tempVarIndex: 0
13402
}
13403
})
13404
);
13405
13406
utils.append('return ', state);
13407
renderStatementBody(traverse, node, path, state);
13408
utils.append(';}', state);
13409
}
13410
13411
function renderStatementBody(traverse, node, path, state) {
13412
traverse(node.body, path, state);
13413
utils.catchup(node.body.range[1], state);
13414
}
13415
13416
visitArrowFunction.test = function(node, path, state) {
13417
return node.type === Syntax.ArrowFunctionExpression;
13418
};
13419
13420
exports.visitorList = [
13421
visitArrowFunction
13422
];
13423
13424
13425
},{"../src/utils":23,"./es6-destructuring-visitors":27,"./es6-rest-param-visitors":30,"esprima-fb":9}],25:[function(_dereq_,module,exports){
13426
/**
13427
* Copyright 2004-present Facebook. All Rights Reserved.
13428
*/
13429
/*global exports:true*/
13430
13431
/**
13432
* Implements ES6 call spread.
13433
*
13434
* instance.method(a, b, c, ...d)
13435
*
13436
* instance.method.apply(instance, [a, b, c].concat(d))
13437
*
13438
*/
13439
13440
var Syntax = _dereq_('esprima-fb').Syntax;
13441
var utils = _dereq_('../src/utils');
13442
13443
function process(traverse, node, path, state) {
13444
utils.move(node.range[0], state);
13445
traverse(node, path, state);
13446
utils.catchup(node.range[1], state);
13447
}
13448
13449
function visitCallSpread(traverse, node, path, state) {
13450
utils.catchup(node.range[0], state);
13451
13452
if (node.type === Syntax.NewExpression) {
13453
// Input = new Set(1, 2, ...list)
13454
// Output = new (Function.prototype.bind.apply(Set, [null, 1, 2].concat(list)))
13455
utils.append('new (Function.prototype.bind.apply(', state);
13456
process(traverse, node.callee, path, state);
13457
} else if (node.callee.type === Syntax.MemberExpression) {
13458
// Input = get().fn(1, 2, ...more)
13459
// Output = (_ = get()).fn.apply(_, [1, 2].apply(more))
13460
var tempVar = utils.injectTempVar(state);
13461
utils.append('(' + tempVar + ' = ', state);
13462
process(traverse, node.callee.object, path, state);
13463
utils.append(')', state);
13464
if (node.callee.property.type === Syntax.Identifier) {
13465
utils.append('.', state);
13466
process(traverse, node.callee.property, path, state);
13467
} else {
13468
utils.append('[', state);
13469
process(traverse, node.callee.property, path, state);
13470
utils.append(']', state);
13471
}
13472
utils.append('.apply(' + tempVar, state);
13473
} else {
13474
// Input = max(1, 2, ...list)
13475
// Output = max.apply(null, [1, 2].concat(list))
13476
var needsToBeWrappedInParenthesis =
13477
node.callee.type === Syntax.FunctionDeclaration ||
13478
node.callee.type === Syntax.FunctionExpression;
13479
if (needsToBeWrappedInParenthesis) {
13480
utils.append('(', state);
13481
}
13482
process(traverse, node.callee, path, state);
13483
if (needsToBeWrappedInParenthesis) {
13484
utils.append(')', state);
13485
}
13486
utils.append('.apply(null', state);
13487
}
13488
utils.append(', ', state);
13489
13490
var args = node.arguments.slice();
13491
var spread = args.pop();
13492
if (args.length || node.type === Syntax.NewExpression) {
13493
utils.append('[', state);
13494
if (node.type === Syntax.NewExpression) {
13495
utils.append('null' + (args.length ? ', ' : ''), state);
13496
}
13497
while (args.length) {
13498
var arg = args.shift();
13499
utils.move(arg.range[0], state);
13500
traverse(arg, path, state);
13501
if (args.length) {
13502
utils.catchup(args[0].range[0], state);
13503
} else {
13504
utils.catchup(arg.range[1], state);
13505
}
13506
}
13507
utils.append('].concat(', state);
13508
process(traverse, spread.argument, path, state);
13509
utils.append(')', state);
13510
} else {
13511
process(traverse, spread.argument, path, state);
13512
}
13513
utils.append(node.type === Syntax.NewExpression ? '))' : ')', state);
13514
13515
utils.move(node.range[1], state);
13516
return false;
13517
}
13518
13519
visitCallSpread.test = function(node, path, state) {
13520
return (
13521
(
13522
node.type === Syntax.CallExpression ||
13523
node.type === Syntax.NewExpression
13524
) &&
13525
node.arguments.length > 0 &&
13526
node.arguments[node.arguments.length - 1].type === Syntax.SpreadElement
13527
);
13528
};
13529
13530
exports.visitorList = [
13531
visitCallSpread
13532
];
13533
13534
},{"../src/utils":23,"esprima-fb":9}],26:[function(_dereq_,module,exports){
13535
/**
13536
* Copyright 2013 Facebook, Inc.
13537
*
13538
* Licensed under the Apache License, Version 2.0 (the "License");
13539
* you may not use this file except in compliance with the License.
13540
* You may obtain a copy of the License at
13541
*
13542
* http://www.apache.org/licenses/LICENSE-2.0
13543
*
13544
* Unless required by applicable law or agreed to in writing, software
13545
* distributed under the License is distributed on an "AS IS" BASIS,
13546
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13547
* See the License for the specific language governing permissions and
13548
* limitations under the License.
13549
*/
13550
13551
/*jslint node:true*/
13552
13553
/**
13554
* @typechecks
13555
*/
13556
'use strict';
13557
13558
var base62 = _dereq_('base62');
13559
var Syntax = _dereq_('esprima-fb').Syntax;
13560
var utils = _dereq_('../src/utils');
13561
var reservedWordsHelper = _dereq_('./reserved-words-helper');
13562
13563
var declareIdentInLocalScope = utils.declareIdentInLocalScope;
13564
var initScopeMetadata = utils.initScopeMetadata;
13565
13566
var SUPER_PROTO_IDENT_PREFIX = '____SuperProtoOf';
13567
13568
var _anonClassUUIDCounter = 0;
13569
var _mungedSymbolMaps = {};
13570
13571
function resetSymbols() {
13572
_anonClassUUIDCounter = 0;
13573
_mungedSymbolMaps = {};
13574
}
13575
13576
/**
13577
* Used to generate a unique class for use with code-gens for anonymous class
13578
* expressions.
13579
*
13580
* @param {object} state
13581
* @return {string}
13582
*/
13583
function _generateAnonymousClassName(state) {
13584
var mungeNamespace = state.mungeNamespace || '';
13585
return '____Class' + mungeNamespace + base62.encode(_anonClassUUIDCounter++);
13586
}
13587
13588
/**
13589
* Given an identifier name, munge it using the current state's mungeNamespace.
13590
*
13591
* @param {string} identName
13592
* @param {object} state
13593
* @return {string}
13594
*/
13595
function _getMungedName(identName, state) {
13596
var mungeNamespace = state.mungeNamespace;
13597
var shouldMinify = state.g.opts.minify;
13598
13599
if (shouldMinify) {
13600
if (!_mungedSymbolMaps[mungeNamespace]) {
13601
_mungedSymbolMaps[mungeNamespace] = {
13602
symbolMap: {},
13603
identUUIDCounter: 0
13604
};
13605
}
13606
13607
var symbolMap = _mungedSymbolMaps[mungeNamespace].symbolMap;
13608
if (!symbolMap[identName]) {
13609
symbolMap[identName] =
13610
base62.encode(_mungedSymbolMaps[mungeNamespace].identUUIDCounter++);
13611
}
13612
identName = symbolMap[identName];
13613
}
13614
return '$' + mungeNamespace + identName;
13615
}
13616
13617
/**
13618
* Extracts super class information from a class node.
13619
*
13620
* Information includes name of the super class and/or the expression string
13621
* (if extending from an expression)
13622
*
13623
* @param {object} node
13624
* @param {object} state
13625
* @return {object}
13626
*/
13627
function _getSuperClassInfo(node, state) {
13628
var ret = {
13629
name: null,
13630
expression: null
13631
};
13632
if (node.superClass) {
13633
if (node.superClass.type === Syntax.Identifier) {
13634
ret.name = node.superClass.name;
13635
} else {
13636
// Extension from an expression
13637
ret.name = _generateAnonymousClassName(state);
13638
ret.expression = state.g.source.substring(
13639
node.superClass.range[0],
13640
node.superClass.range[1]
13641
);
13642
}
13643
}
13644
return ret;
13645
}
13646
13647
/**
13648
* Used with .filter() to find the constructor method in a list of
13649
* MethodDefinition nodes.
13650
*
13651
* @param {object} classElement
13652
* @return {boolean}
13653
*/
13654
function _isConstructorMethod(classElement) {
13655
return classElement.type === Syntax.MethodDefinition &&
13656
classElement.key.type === Syntax.Identifier &&
13657
classElement.key.name === 'constructor';
13658
}
13659
13660
/**
13661
* @param {object} node
13662
* @param {object} state
13663
* @return {boolean}
13664
*/
13665
function _shouldMungeIdentifier(node, state) {
13666
return (
13667
!!state.methodFuncNode &&
13668
!utils.getDocblock(state).hasOwnProperty('preventMunge') &&
13669
/^_(?!_)/.test(node.name)
13670
);
13671
}
13672
13673
/**
13674
* @param {function} traverse
13675
* @param {object} node
13676
* @param {array} path
13677
* @param {object} state
13678
*/
13679
function visitClassMethod(traverse, node, path, state) {
13680
if (!state.g.opts.es5 && (node.kind === 'get' || node.kind === 'set')) {
13681
throw new Error(
13682
'This transform does not support ' + node.kind + 'ter methods for ES6 ' +
13683
'classes. (line: ' + node.loc.start.line + ', col: ' +
13684
node.loc.start.column + ')'
13685
);
13686
}
13687
state = utils.updateState(state, {
13688
methodNode: node
13689
});
13690
utils.catchup(node.range[0], state);
13691
path.unshift(node);
13692
traverse(node.value, path, state);
13693
path.shift();
13694
return false;
13695
}
13696
visitClassMethod.test = function(node, path, state) {
13697
return node.type === Syntax.MethodDefinition;
13698
};
13699
13700
/**
13701
* @param {function} traverse
13702
* @param {object} node
13703
* @param {array} path
13704
* @param {object} state
13705
*/
13706
function visitClassFunctionExpression(traverse, node, path, state) {
13707
var methodNode = path[0];
13708
var isGetter = methodNode.kind === 'get';
13709
var isSetter = methodNode.kind === 'set';
13710
13711
state = utils.updateState(state, {
13712
methodFuncNode: node
13713
});
13714
13715
if (methodNode.key.name === 'constructor') {
13716
utils.append('function ' + state.className, state);
13717
} else {
13718
var methodAccessorComputed = false;
13719
var methodAccessor;
13720
var prototypeOrStatic = methodNode["static"] ? '' : '.prototype';
13721
var objectAccessor = state.className + prototypeOrStatic;
13722
13723
if (methodNode.key.type === Syntax.Identifier) {
13724
// foo() {}
13725
methodAccessor = methodNode.key.name;
13726
if (_shouldMungeIdentifier(methodNode.key, state)) {
13727
methodAccessor = _getMungedName(methodAccessor, state);
13728
}
13729
if (isGetter || isSetter) {
13730
methodAccessor = JSON.stringify(methodAccessor);
13731
} else if (reservedWordsHelper.isReservedWord(methodAccessor)) {
13732
methodAccessorComputed = true;
13733
methodAccessor = JSON.stringify(methodAccessor);
13734
}
13735
} else if (methodNode.key.type === Syntax.Literal) {
13736
// 'foo bar'() {} | get 'foo bar'() {} | set 'foo bar'() {}
13737
methodAccessor = JSON.stringify(methodNode.key.value);
13738
methodAccessorComputed = true;
13739
}
13740
13741
if (isSetter || isGetter) {
13742
utils.append(
13743
'Object.defineProperty(' +
13744
objectAccessor + ',' +
13745
methodAccessor + ',' +
13746
'{configurable:true,' +
13747
methodNode.kind + ':function',
13748
state
13749
);
13750
} else {
13751
if (state.g.opts.es3) {
13752
if (methodAccessorComputed) {
13753
methodAccessor = '[' + methodAccessor + ']';
13754
} else {
13755
methodAccessor = '.' + methodAccessor;
13756
}
13757
utils.append(
13758
objectAccessor +
13759
methodAccessor + '=function' + (node.generator ? '*' : ''),
13760
state
13761
);
13762
} else {
13763
if (!methodAccessorComputed) {
13764
methodAccessor = JSON.stringify(methodAccessor);
13765
}
13766
utils.append(
13767
'Object.defineProperty(' +
13768
objectAccessor + ',' +
13769
methodAccessor + ',' +
13770
'{writable:true,configurable:true,' +
13771
'value:function' + (node.generator ? '*' : ''),
13772
state
13773
);
13774
}
13775
}
13776
}
13777
utils.move(methodNode.key.range[1], state);
13778
utils.append('(', state);
13779
13780
var params = node.params;
13781
if (params.length > 0) {
13782
utils.catchupNewlines(params[0].range[0], state);
13783
for (var i = 0; i < params.length; i++) {
13784
utils.catchup(node.params[i].range[0], state);
13785
path.unshift(node);
13786
traverse(params[i], path, state);
13787
path.shift();
13788
}
13789
}
13790
13791
var closingParenPosition = utils.getNextSyntacticCharOffset(')', state);
13792
utils.catchupWhiteSpace(closingParenPosition, state);
13793
13794
var openingBracketPosition = utils.getNextSyntacticCharOffset('{', state);
13795
utils.catchup(openingBracketPosition + 1, state);
13796
13797
if (!state.scopeIsStrict) {
13798
utils.append('"use strict";', state);
13799
state = utils.updateState(state, {
13800
scopeIsStrict: true
13801
});
13802
}
13803
utils.move(node.body.range[0] + '{'.length, state);
13804
13805
path.unshift(node);
13806
traverse(node.body, path, state);
13807
path.shift();
13808
utils.catchup(node.body.range[1], state);
13809
13810
if (methodNode.key.name !== 'constructor') {
13811
if (isGetter || isSetter || !state.g.opts.es3) {
13812
utils.append('})', state);
13813
}
13814
utils.append(';', state);
13815
}
13816
return false;
13817
}
13818
visitClassFunctionExpression.test = function(node, path, state) {
13819
return node.type === Syntax.FunctionExpression
13820
&& path[0].type === Syntax.MethodDefinition;
13821
};
13822
13823
function visitClassMethodParam(traverse, node, path, state) {
13824
var paramName = node.name;
13825
if (_shouldMungeIdentifier(node, state)) {
13826
paramName = _getMungedName(node.name, state);
13827
}
13828
utils.append(paramName, state);
13829
utils.move(node.range[1], state);
13830
}
13831
visitClassMethodParam.test = function(node, path, state) {
13832
if (!path[0] || !path[1]) {
13833
return;
13834
}
13835
13836
var parentFuncExpr = path[0];
13837
var parentClassMethod = path[1];
13838
13839
return parentFuncExpr.type === Syntax.FunctionExpression
13840
&& parentClassMethod.type === Syntax.MethodDefinition
13841
&& node.type === Syntax.Identifier;
13842
};
13843
13844
/**
13845
* @param {function} traverse
13846
* @param {object} node
13847
* @param {array} path
13848
* @param {object} state
13849
*/
13850
function _renderClassBody(traverse, node, path, state) {
13851
var className = state.className;
13852
var superClass = state.superClass;
13853
13854
// Set up prototype of constructor on same line as `extends` for line-number
13855
// preservation. This relies on function-hoisting if a constructor function is
13856
// defined in the class body.
13857
if (superClass.name) {
13858
// If the super class is an expression, we need to memoize the output of the
13859
// expression into the generated class name variable and use that to refer
13860
// to the super class going forward. Example:
13861
//
13862
// class Foo extends mixin(Bar, Baz) {}
13863
// --transforms to--
13864
// function Foo() {} var ____Class0Blah = mixin(Bar, Baz);
13865
if (superClass.expression !== null) {
13866
utils.append(
13867
'var ' + superClass.name + '=' + superClass.expression + ';',
13868
state
13869
);
13870
}
13871
13872
var keyName = superClass.name + '____Key';
13873
var keyNameDeclarator = '';
13874
if (!utils.identWithinLexicalScope(keyName, state)) {
13875
keyNameDeclarator = 'var ';
13876
declareIdentInLocalScope(keyName, initScopeMetadata(node), state);
13877
}
13878
utils.append(
13879
'for(' + keyNameDeclarator + keyName + ' in ' + superClass.name + '){' +
13880
'if(' + superClass.name + '.hasOwnProperty(' + keyName + ')){' +
13881
className + '[' + keyName + ']=' +
13882
superClass.name + '[' + keyName + '];' +
13883
'}' +
13884
'}',
13885
state
13886
);
13887
13888
var superProtoIdentStr = SUPER_PROTO_IDENT_PREFIX + superClass.name;
13889
if (!utils.identWithinLexicalScope(superProtoIdentStr, state)) {
13890
utils.append(
13891
'var ' + superProtoIdentStr + '=' + superClass.name + '===null?' +
13892
'null:' + superClass.name + '.prototype;',
13893
state
13894
);
13895
declareIdentInLocalScope(superProtoIdentStr, initScopeMetadata(node), state);
13896
}
13897
13898
utils.append(
13899
className + '.prototype=Object.create(' + superProtoIdentStr + ');',
13900
state
13901
);
13902
utils.append(
13903
className + '.prototype.constructor=' + className + ';',
13904
state
13905
);
13906
utils.append(
13907
className + '.__superConstructor__=' + superClass.name + ';',
13908
state
13909
);
13910
}
13911
13912
// If there's no constructor method specified in the class body, create an
13913
// empty constructor function at the top (same line as the class keyword)
13914
if (!node.body.body.filter(_isConstructorMethod).pop()) {
13915
utils.append('function ' + className + '(){', state);
13916
if (!state.scopeIsStrict) {
13917
utils.append('"use strict";', state);
13918
}
13919
if (superClass.name) {
13920
utils.append(
13921
'if(' + superClass.name + '!==null){' +
13922
superClass.name + '.apply(this,arguments);}',
13923
state
13924
);
13925
}
13926
utils.append('}', state);
13927
}
13928
13929
utils.move(node.body.range[0] + '{'.length, state);
13930
traverse(node.body, path, state);
13931
utils.catchupWhiteSpace(node.range[1], state);
13932
}
13933
13934
/**
13935
* @param {function} traverse
13936
* @param {object} node
13937
* @param {array} path
13938
* @param {object} state
13939
*/
13940
function visitClassDeclaration(traverse, node, path, state) {
13941
var className = node.id.name;
13942
var superClass = _getSuperClassInfo(node, state);
13943
13944
state = utils.updateState(state, {
13945
mungeNamespace: className,
13946
className: className,
13947
superClass: superClass
13948
});
13949
13950
_renderClassBody(traverse, node, path, state);
13951
13952
return false;
13953
}
13954
visitClassDeclaration.test = function(node, path, state) {
13955
return node.type === Syntax.ClassDeclaration;
13956
};
13957
13958
/**
13959
* @param {function} traverse
13960
* @param {object} node
13961
* @param {array} path
13962
* @param {object} state
13963
*/
13964
function visitClassExpression(traverse, node, path, state) {
13965
var className = node.id && node.id.name || _generateAnonymousClassName(state);
13966
var superClass = _getSuperClassInfo(node, state);
13967
13968
utils.append('(function(){', state);
13969
13970
state = utils.updateState(state, {
13971
mungeNamespace: className,
13972
className: className,
13973
superClass: superClass
13974
});
13975
13976
_renderClassBody(traverse, node, path, state);
13977
13978
utils.append('return ' + className + ';})()', state);
13979
return false;
13980
}
13981
visitClassExpression.test = function(node, path, state) {
13982
return node.type === Syntax.ClassExpression;
13983
};
13984
13985
/**
13986
* @param {function} traverse
13987
* @param {object} node
13988
* @param {array} path
13989
* @param {object} state
13990
*/
13991
function visitPrivateIdentifier(traverse, node, path, state) {
13992
utils.append(_getMungedName(node.name, state), state);
13993
utils.move(node.range[1], state);
13994
}
13995
visitPrivateIdentifier.test = function(node, path, state) {
13996
if (node.type === Syntax.Identifier && _shouldMungeIdentifier(node, state)) {
13997
// Always munge non-computed properties of MemberExpressions
13998
// (a la preventing access of properties of unowned objects)
13999
if (path[0].type === Syntax.MemberExpression && path[0].object !== node
14000
&& path[0].computed === false) {
14001
return true;
14002
}
14003
14004
// Always munge identifiers that were declared within the method function
14005
// scope
14006
if (utils.identWithinLexicalScope(node.name, state, state.methodFuncNode)) {
14007
return true;
14008
}
14009
14010
// Always munge private keys on object literals defined within a method's
14011
// scope.
14012
if (path[0].type === Syntax.Property
14013
&& path[1].type === Syntax.ObjectExpression) {
14014
return true;
14015
}
14016
14017
// Always munge function parameters
14018
if (path[0].type === Syntax.FunctionExpression
14019
|| path[0].type === Syntax.FunctionDeclaration
14020
|| path[0].type === Syntax.ArrowFunctionExpression) {
14021
for (var i = 0; i < path[0].params.length; i++) {
14022
if (path[0].params[i] === node) {
14023
return true;
14024
}
14025
}
14026
}
14027
}
14028
return false;
14029
};
14030
14031
/**
14032
* @param {function} traverse
14033
* @param {object} node
14034
* @param {array} path
14035
* @param {object} state
14036
*/
14037
function visitSuperCallExpression(traverse, node, path, state) {
14038
var superClassName = state.superClass.name;
14039
14040
if (node.callee.type === Syntax.Identifier) {
14041
if (_isConstructorMethod(state.methodNode)) {
14042
utils.append(superClassName + '.call(', state);
14043
} else {
14044
var protoProp = SUPER_PROTO_IDENT_PREFIX + superClassName;
14045
if (state.methodNode.key.type === Syntax.Identifier) {
14046
protoProp += '.' + state.methodNode.key.name;
14047
} else if (state.methodNode.key.type === Syntax.Literal) {
14048
protoProp += '[' + JSON.stringify(state.methodNode.key.value) + ']';
14049
}
14050
utils.append(protoProp + ".call(", state);
14051
}
14052
utils.move(node.callee.range[1], state);
14053
} else if (node.callee.type === Syntax.MemberExpression) {
14054
utils.append(SUPER_PROTO_IDENT_PREFIX + superClassName, state);
14055
utils.move(node.callee.object.range[1], state);
14056
14057
if (node.callee.computed) {
14058
// ["a" + "b"]
14059
utils.catchup(node.callee.property.range[1] + ']'.length, state);
14060
} else {
14061
// .ab
14062
utils.append('.' + node.callee.property.name, state);
14063
}
14064
14065
utils.append('.call(', state);
14066
utils.move(node.callee.range[1], state);
14067
}
14068
14069
utils.append('this', state);
14070
if (node.arguments.length > 0) {
14071
utils.append(',', state);
14072
utils.catchupWhiteSpace(node.arguments[0].range[0], state);
14073
traverse(node.arguments, path, state);
14074
}
14075
14076
utils.catchupWhiteSpace(node.range[1], state);
14077
utils.append(')', state);
14078
return false;
14079
}
14080
visitSuperCallExpression.test = function(node, path, state) {
14081
if (state.superClass && node.type === Syntax.CallExpression) {
14082
var callee = node.callee;
14083
if (callee.type === Syntax.Identifier && callee.name === 'super'
14084
|| callee.type == Syntax.MemberExpression
14085
&& callee.object.name === 'super') {
14086
return true;
14087
}
14088
}
14089
return false;
14090
};
14091
14092
/**
14093
* @param {function} traverse
14094
* @param {object} node
14095
* @param {array} path
14096
* @param {object} state
14097
*/
14098
function visitSuperMemberExpression(traverse, node, path, state) {
14099
var superClassName = state.superClass.name;
14100
14101
utils.append(SUPER_PROTO_IDENT_PREFIX + superClassName, state);
14102
utils.move(node.object.range[1], state);
14103
}
14104
visitSuperMemberExpression.test = function(node, path, state) {
14105
return state.superClass
14106
&& node.type === Syntax.MemberExpression
14107
&& node.object.type === Syntax.Identifier
14108
&& node.object.name === 'super';
14109
};
14110
14111
exports.resetSymbols = resetSymbols;
14112
14113
exports.visitorList = [
14114
visitClassDeclaration,
14115
visitClassExpression,
14116
visitClassFunctionExpression,
14117
visitClassMethod,
14118
visitClassMethodParam,
14119
visitPrivateIdentifier,
14120
visitSuperCallExpression,
14121
visitSuperMemberExpression
14122
];
14123
14124
},{"../src/utils":23,"./reserved-words-helper":34,"base62":10,"esprima-fb":9}],27:[function(_dereq_,module,exports){
14125
/**
14126
* Copyright 2014 Facebook, Inc.
14127
*
14128
* Licensed under the Apache License, Version 2.0 (the "License");
14129
* you may not use this file except in compliance with the License.
14130
* You may obtain a copy of the License at
14131
*
14132
* http://www.apache.org/licenses/LICENSE-2.0
14133
*
14134
* Unless required by applicable law or agreed to in writing, software
14135
* distributed under the License is distributed on an "AS IS" BASIS,
14136
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14137
* See the License for the specific language governing permissions and
14138
* limitations under the License.
14139
*/
14140
/*global exports:true*/
14141
14142
/**
14143
* Implements ES6 destructuring assignment and pattern matchng.
14144
*
14145
* function init({port, ip, coords: [x, y]}) {
14146
* return (x && y) ? {id, port} : {ip};
14147
* };
14148
*
14149
* function init($__0) {
14150
* var
14151
* port = $__0.port,
14152
* ip = $__0.ip,
14153
* $__1 = $__0.coords,
14154
* x = $__1[0],
14155
* y = $__1[1];
14156
* return (x && y) ? {id, port} : {ip};
14157
* }
14158
*
14159
* var x, {ip, port} = init({ip, port});
14160
*
14161
* var x, $__0 = init({ip, port}), ip = $__0.ip, port = $__0.port;
14162
*
14163
*/
14164
var Syntax = _dereq_('esprima-fb').Syntax;
14165
var utils = _dereq_('../src/utils');
14166
14167
var reservedWordsHelper = _dereq_('./reserved-words-helper');
14168
var restParamVisitors = _dereq_('./es6-rest-param-visitors');
14169
var restPropertyHelpers = _dereq_('./es7-rest-property-helpers');
14170
14171
// -------------------------------------------------------
14172
// 1. Structured variable declarations.
14173
//
14174
// var [a, b] = [b, a];
14175
// var {x, y} = {y, x};
14176
// -------------------------------------------------------
14177
14178
function visitStructuredVariable(traverse, node, path, state) {
14179
// Allocate new temp for the pattern.
14180
utils.append(utils.getTempVar(state.localScope.tempVarIndex) + '=', state);
14181
// Skip the pattern and assign the init to the temp.
14182
utils.catchupWhiteSpace(node.init.range[0], state);
14183
traverse(node.init, path, state);
14184
utils.catchup(node.init.range[1], state);
14185
// Render the destructured data.
14186
utils.append(',' + getDestructuredComponents(node.id, state), state);
14187
state.localScope.tempVarIndex++;
14188
return false;
14189
}
14190
14191
visitStructuredVariable.test = function(node, path, state) {
14192
return node.type === Syntax.VariableDeclarator &&
14193
isStructuredPattern(node.id);
14194
};
14195
14196
function isStructuredPattern(node) {
14197
return node.type === Syntax.ObjectPattern ||
14198
node.type === Syntax.ArrayPattern;
14199
}
14200
14201
// Main function which does actual recursive destructuring
14202
// of nested complex structures.
14203
function getDestructuredComponents(node, state) {
14204
var tmpIndex = state.localScope.tempVarIndex;
14205
var components = [];
14206
var patternItems = getPatternItems(node);
14207
14208
for (var idx = 0; idx < patternItems.length; idx++) {
14209
var item = patternItems[idx];
14210
if (!item) {
14211
continue;
14212
}
14213
14214
if (item.type === Syntax.SpreadElement) {
14215
// Spread/rest of an array.
14216
// TODO(dmitrys): support spread in the middle of a pattern
14217
// and also for function param patterns: [x, ...xs, y]
14218
components.push(item.argument.name +
14219
'=Array.prototype.slice.call(' +
14220
utils.getTempVar(tmpIndex) + ',' + idx + ')'
14221
);
14222
continue;
14223
}
14224
14225
if (item.type === Syntax.SpreadProperty) {
14226
var restExpression = restPropertyHelpers.renderRestExpression(
14227
utils.getTempVar(tmpIndex),
14228
patternItems
14229
);
14230
components.push(item.argument.name + '=' + restExpression);
14231
continue;
14232
}
14233
14234
// Depending on pattern type (Array or Object), we get
14235
// corresponding pattern item parts.
14236
var accessor = getPatternItemAccessor(node, item, tmpIndex, idx);
14237
var value = getPatternItemValue(node, item);
14238
14239
// TODO(dmitrys): implement default values: {x, y=5}
14240
if (value.type === Syntax.Identifier) {
14241
// Simple pattern item.
14242
components.push(value.name + '=' + accessor);
14243
} else {
14244
// Complex sub-structure.
14245
components.push(
14246
utils.getTempVar(++state.localScope.tempVarIndex) + '=' + accessor +
14247
',' + getDestructuredComponents(value, state)
14248
);
14249
}
14250
}
14251
14252
return components.join(',');
14253
}
14254
14255
function getPatternItems(node) {
14256
return node.properties || node.elements;
14257
}
14258
14259
function getPatternItemAccessor(node, patternItem, tmpIndex, idx) {
14260
var tmpName = utils.getTempVar(tmpIndex);
14261
if (node.type === Syntax.ObjectPattern) {
14262
if (reservedWordsHelper.isReservedWord(patternItem.key.name)) {
14263
return tmpName + '["' + patternItem.key.name + '"]';
14264
} else if (patternItem.key.type === Syntax.Literal) {
14265
return tmpName + '[' + JSON.stringify(patternItem.key.value) + ']';
14266
} else if (patternItem.key.type === Syntax.Identifier) {
14267
return tmpName + '.' + patternItem.key.name;
14268
}
14269
} else if (node.type === Syntax.ArrayPattern) {
14270
return tmpName + '[' + idx + ']';
14271
}
14272
}
14273
14274
function getPatternItemValue(node, patternItem) {
14275
return node.type === Syntax.ObjectPattern
14276
? patternItem.value
14277
: patternItem;
14278
}
14279
14280
// -------------------------------------------------------
14281
// 2. Assignment expression.
14282
//
14283
// [a, b] = [b, a];
14284
// ({x, y} = {y, x});
14285
// -------------------------------------------------------
14286
14287
function visitStructuredAssignment(traverse, node, path, state) {
14288
var exprNode = node.expression;
14289
utils.append('var ' + utils.getTempVar(state.localScope.tempVarIndex) + '=', state);
14290
14291
utils.catchupWhiteSpace(exprNode.right.range[0], state);
14292
traverse(exprNode.right, path, state);
14293
utils.catchup(exprNode.right.range[1], state);
14294
14295
utils.append(
14296
';' + getDestructuredComponents(exprNode.left, state) + ';',
14297
state
14298
);
14299
14300
utils.catchupWhiteSpace(node.range[1], state);
14301
state.localScope.tempVarIndex++;
14302
return false;
14303
}
14304
14305
visitStructuredAssignment.test = function(node, path, state) {
14306
// We consider the expression statement rather than just assignment
14307
// expression to cover case with object patters which should be
14308
// wrapped in grouping operator: ({x, y} = {y, x});
14309
return node.type === Syntax.ExpressionStatement &&
14310
node.expression.type === Syntax.AssignmentExpression &&
14311
isStructuredPattern(node.expression.left);
14312
};
14313
14314
// -------------------------------------------------------
14315
// 3. Structured parameter.
14316
//
14317
// function foo({x, y}) { ... }
14318
// -------------------------------------------------------
14319
14320
function visitStructuredParameter(traverse, node, path, state) {
14321
utils.append(utils.getTempVar(getParamIndex(node, path)), state);
14322
utils.catchupWhiteSpace(node.range[1], state);
14323
return true;
14324
}
14325
14326
function getParamIndex(paramNode, path) {
14327
var funcNode = path[0];
14328
var tmpIndex = 0;
14329
for (var k = 0; k < funcNode.params.length; k++) {
14330
var param = funcNode.params[k];
14331
if (param === paramNode) {
14332
break;
14333
}
14334
if (isStructuredPattern(param)) {
14335
tmpIndex++;
14336
}
14337
}
14338
return tmpIndex;
14339
}
14340
14341
visitStructuredParameter.test = function(node, path, state) {
14342
return isStructuredPattern(node) && isFunctionNode(path[0]);
14343
};
14344
14345
function isFunctionNode(node) {
14346
return (node.type == Syntax.FunctionDeclaration ||
14347
node.type == Syntax.FunctionExpression ||
14348
node.type == Syntax.MethodDefinition ||
14349
node.type == Syntax.ArrowFunctionExpression);
14350
}
14351
14352
// -------------------------------------------------------
14353
// 4. Function body for structured parameters.
14354
//
14355
// function foo({x, y}) { x; y; }
14356
// -------------------------------------------------------
14357
14358
function visitFunctionBodyForStructuredParameter(traverse, node, path, state) {
14359
var funcNode = path[0];
14360
14361
utils.catchup(funcNode.body.range[0] + 1, state);
14362
renderDestructuredComponents(funcNode, state);
14363
14364
if (funcNode.rest) {
14365
utils.append(
14366
restParamVisitors.renderRestParamSetup(funcNode, state),
14367
state
14368
);
14369
}
14370
14371
return true;
14372
}
14373
14374
function renderDestructuredComponents(funcNode, state) {
14375
var destructuredComponents = [];
14376
14377
for (var k = 0; k < funcNode.params.length; k++) {
14378
var param = funcNode.params[k];
14379
if (isStructuredPattern(param)) {
14380
destructuredComponents.push(
14381
getDestructuredComponents(param, state)
14382
);
14383
state.localScope.tempVarIndex++;
14384
}
14385
}
14386
14387
if (destructuredComponents.length) {
14388
utils.append('var ' + destructuredComponents.join(',') + ';', state);
14389
}
14390
}
14391
14392
visitFunctionBodyForStructuredParameter.test = function(node, path, state) {
14393
return node.type === Syntax.BlockStatement && isFunctionNode(path[0]);
14394
};
14395
14396
exports.visitorList = [
14397
visitStructuredVariable,
14398
visitStructuredAssignment,
14399
visitStructuredParameter,
14400
visitFunctionBodyForStructuredParameter
14401
];
14402
14403
exports.renderDestructuredComponents = renderDestructuredComponents;
14404
14405
14406
},{"../src/utils":23,"./es6-rest-param-visitors":30,"./es7-rest-property-helpers":32,"./reserved-words-helper":34,"esprima-fb":9}],28:[function(_dereq_,module,exports){
14407
/**
14408
* Copyright 2013 Facebook, Inc.
14409
*
14410
* Licensed under the Apache License, Version 2.0 (the "License");
14411
* you may not use this file except in compliance with the License.
14412
* You may obtain a copy of the License at
14413
*
14414
* http://www.apache.org/licenses/LICENSE-2.0
14415
*
14416
* Unless required by applicable law or agreed to in writing, software
14417
* distributed under the License is distributed on an "AS IS" BASIS,
14418
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14419
* See the License for the specific language governing permissions and
14420
* limitations under the License.
14421
*/
14422
14423
/*jslint node:true*/
14424
14425
/**
14426
* Desugars concise methods of objects to function expressions.
14427
*
14428
* var foo = {
14429
* method(x, y) { ... }
14430
* };
14431
*
14432
* var foo = {
14433
* method: function(x, y) { ... }
14434
* };
14435
*
14436
*/
14437
14438
var Syntax = _dereq_('esprima-fb').Syntax;
14439
var utils = _dereq_('../src/utils');
14440
var reservedWordsHelper = _dereq_('./reserved-words-helper');
14441
14442
function visitObjectConciseMethod(traverse, node, path, state) {
14443
var isGenerator = node.value.generator;
14444
if (isGenerator) {
14445
utils.catchupWhiteSpace(node.range[0] + 1, state);
14446
}
14447
if (node.computed) { // [<expr>]() { ...}
14448
utils.catchup(node.key.range[1] + 1, state);
14449
} else if (reservedWordsHelper.isReservedWord(node.key.name)) {
14450
utils.catchup(node.key.range[0], state);
14451
utils.append('"', state);
14452
utils.catchup(node.key.range[1], state);
14453
utils.append('"', state);
14454
}
14455
14456
utils.catchup(node.key.range[1], state);
14457
utils.append(
14458
':function' + (isGenerator ? '*' : ''),
14459
state
14460
);
14461
path.unshift(node);
14462
traverse(node.value, path, state);
14463
path.shift();
14464
return false;
14465
}
14466
14467
visitObjectConciseMethod.test = function(node, path, state) {
14468
return node.type === Syntax.Property &&
14469
node.value.type === Syntax.FunctionExpression &&
14470
node.method === true;
14471
};
14472
14473
exports.visitorList = [
14474
visitObjectConciseMethod
14475
];
14476
14477
},{"../src/utils":23,"./reserved-words-helper":34,"esprima-fb":9}],29:[function(_dereq_,module,exports){
14478
/**
14479
* Copyright 2013 Facebook, Inc.
14480
*
14481
* Licensed under the Apache License, Version 2.0 (the "License");
14482
* you may not use this file except in compliance with the License.
14483
* You may obtain a copy of the License at
14484
*
14485
* http://www.apache.org/licenses/LICENSE-2.0
14486
*
14487
* Unless required by applicable law or agreed to in writing, software
14488
* distributed under the License is distributed on an "AS IS" BASIS,
14489
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14490
* See the License for the specific language governing permissions and
14491
* limitations under the License.
14492
*/
14493
14494
/*jslint node: true*/
14495
14496
/**
14497
* Desugars ES6 Object Literal short notations into ES3 full notation.
14498
*
14499
* // Easier return values.
14500
* function foo(x, y) {
14501
* return {x, y}; // {x: x, y: y}
14502
* };
14503
*
14504
* // Destructuring.
14505
* function init({port, ip, coords: {x, y}}) { ... }
14506
*
14507
*/
14508
var Syntax = _dereq_('esprima-fb').Syntax;
14509
var utils = _dereq_('../src/utils');
14510
14511
/**
14512
* @public
14513
*/
14514
function visitObjectLiteralShortNotation(traverse, node, path, state) {
14515
utils.catchup(node.key.range[1], state);
14516
utils.append(':' + node.key.name, state);
14517
return false;
14518
}
14519
14520
visitObjectLiteralShortNotation.test = function(node, path, state) {
14521
return node.type === Syntax.Property &&
14522
node.kind === 'init' &&
14523
node.shorthand === true &&
14524
path[0].type !== Syntax.ObjectPattern;
14525
};
14526
14527
exports.visitorList = [
14528
visitObjectLiteralShortNotation
14529
];
14530
14531
14532
},{"../src/utils":23,"esprima-fb":9}],30:[function(_dereq_,module,exports){
14533
/**
14534
* Copyright 2013 Facebook, Inc.
14535
*
14536
* Licensed under the Apache License, Version 2.0 (the "License");
14537
* you may not use this file except in compliance with the License.
14538
* You may obtain a copy of the License at
14539
*
14540
* http://www.apache.org/licenses/LICENSE-2.0
14541
*
14542
* Unless required by applicable law or agreed to in writing, software
14543
* distributed under the License is distributed on an "AS IS" BASIS,
14544
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14545
* See the License for the specific language governing permissions and
14546
* limitations under the License.
14547
*/
14548
14549
/*jslint node:true*/
14550
14551
/**
14552
* Desugars ES6 rest parameters into an ES3 arguments array.
14553
*
14554
* function printf(template, ...args) {
14555
* args.forEach(...);
14556
* }
14557
*
14558
* We could use `Array.prototype.slice.call`, but that usage of arguments causes
14559
* functions to be deoptimized in V8, so instead we use a for-loop.
14560
*
14561
* function printf(template) {
14562
* for (var args = [], $__0 = 1, $__1 = arguments.length; $__0 < $__1; $__0++)
14563
* args.push(arguments[$__0]);
14564
* args.forEach(...);
14565
* }
14566
*
14567
*/
14568
var Syntax = _dereq_('esprima-fb').Syntax;
14569
var utils = _dereq_('../src/utils');
14570
14571
14572
14573
function _nodeIsFunctionWithRestParam(node) {
14574
return (node.type === Syntax.FunctionDeclaration
14575
|| node.type === Syntax.FunctionExpression
14576
|| node.type === Syntax.ArrowFunctionExpression)
14577
&& node.rest;
14578
}
14579
14580
function visitFunctionParamsWithRestParam(traverse, node, path, state) {
14581
if (node.parametricType) {
14582
utils.catchup(node.parametricType.range[0], state);
14583
path.unshift(node);
14584
traverse(node.parametricType, path, state);
14585
path.shift();
14586
}
14587
14588
// Render params.
14589
if (node.params.length) {
14590
path.unshift(node);
14591
traverse(node.params, path, state);
14592
path.shift();
14593
} else {
14594
// -3 is for ... of the rest.
14595
utils.catchup(node.rest.range[0] - 3, state);
14596
}
14597
utils.catchupWhiteSpace(node.rest.range[1], state);
14598
14599
path.unshift(node);
14600
traverse(node.body, path, state);
14601
path.shift();
14602
14603
return false;
14604
}
14605
14606
visitFunctionParamsWithRestParam.test = function(node, path, state) {
14607
return _nodeIsFunctionWithRestParam(node);
14608
};
14609
14610
function renderRestParamSetup(functionNode, state) {
14611
var idx = state.localScope.tempVarIndex++;
14612
var len = state.localScope.tempVarIndex++;
14613
14614
return 'for (var ' + functionNode.rest.name + '=[],' +
14615
utils.getTempVar(idx) + '=' + functionNode.params.length + ',' +
14616
utils.getTempVar(len) + '=arguments.length;' +
14617
utils.getTempVar(idx) + '<' + utils.getTempVar(len) + ';' +
14618
utils.getTempVar(idx) + '++) ' +
14619
functionNode.rest.name + '.push(arguments[' + utils.getTempVar(idx) + ']);';
14620
}
14621
14622
function visitFunctionBodyWithRestParam(traverse, node, path, state) {
14623
utils.catchup(node.range[0] + 1, state);
14624
var parentNode = path[0];
14625
utils.append(renderRestParamSetup(parentNode, state), state);
14626
return true;
14627
}
14628
14629
visitFunctionBodyWithRestParam.test = function(node, path, state) {
14630
return node.type === Syntax.BlockStatement
14631
&& _nodeIsFunctionWithRestParam(path[0]);
14632
};
14633
14634
exports.renderRestParamSetup = renderRestParamSetup;
14635
exports.visitorList = [
14636
visitFunctionParamsWithRestParam,
14637
visitFunctionBodyWithRestParam
14638
];
14639
14640
},{"../src/utils":23,"esprima-fb":9}],31:[function(_dereq_,module,exports){
14641
/**
14642
* Copyright 2013 Facebook, Inc.
14643
*
14644
* Licensed under the Apache License, Version 2.0 (the "License");
14645
* you may not use this file except in compliance with the License.
14646
* You may obtain a copy of the License at
14647
*
14648
* http://www.apache.org/licenses/LICENSE-2.0
14649
*
14650
* Unless required by applicable law or agreed to in writing, software
14651
* distributed under the License is distributed on an "AS IS" BASIS,
14652
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14653
* See the License for the specific language governing permissions and
14654
* limitations under the License.
14655
*/
14656
14657
/*jslint node:true*/
14658
14659
/**
14660
* @typechecks
14661
*/
14662
'use strict';
14663
14664
var Syntax = _dereq_('esprima-fb').Syntax;
14665
var utils = _dereq_('../src/utils');
14666
14667
/**
14668
* http://people.mozilla.org/~jorendorff/es6-draft.html#sec-12.1.9
14669
*/
14670
function visitTemplateLiteral(traverse, node, path, state) {
14671
var templateElements = node.quasis;
14672
14673
utils.append('(', state);
14674
for (var ii = 0; ii < templateElements.length; ii++) {
14675
var templateElement = templateElements[ii];
14676
if (templateElement.value.raw !== '') {
14677
utils.append(getCookedValue(templateElement), state);
14678
if (!templateElement.tail) {
14679
// + between element and substitution
14680
utils.append(' + ', state);
14681
}
14682
// maintain line numbers
14683
utils.move(templateElement.range[0], state);
14684
utils.catchupNewlines(templateElement.range[1], state);
14685
} else { // templateElement.value.raw === ''
14686
// Concatenat adjacent substitutions, e.g. `${x}${y}`. Empty templates
14687
// appear before the first and after the last element - nothing to add in
14688
// those cases.
14689
if (ii > 0 && !templateElement.tail) {
14690
// + between substitution and substitution
14691
utils.append(' + ', state);
14692
}
14693
}
14694
14695
utils.move(templateElement.range[1], state);
14696
if (!templateElement.tail) {
14697
var substitution = node.expressions[ii];
14698
if (substitution.type === Syntax.Identifier ||
14699
substitution.type === Syntax.MemberExpression ||
14700
substitution.type === Syntax.CallExpression) {
14701
utils.catchup(substitution.range[1], state);
14702
} else {
14703
utils.append('(', state);
14704
traverse(substitution, path, state);
14705
utils.catchup(substitution.range[1], state);
14706
utils.append(')', state);
14707
}
14708
// if next templateElement isn't empty...
14709
if (templateElements[ii + 1].value.cooked !== '') {
14710
utils.append(' + ', state);
14711
}
14712
}
14713
}
14714
utils.move(node.range[1], state);
14715
utils.append(')', state);
14716
return false;
14717
}
14718
14719
visitTemplateLiteral.test = function(node, path, state) {
14720
return node.type === Syntax.TemplateLiteral;
14721
};
14722
14723
/**
14724
* http://people.mozilla.org/~jorendorff/es6-draft.html#sec-12.2.6
14725
*/
14726
function visitTaggedTemplateExpression(traverse, node, path, state) {
14727
var template = node.quasi;
14728
var numQuasis = template.quasis.length;
14729
14730
// print the tag
14731
utils.move(node.tag.range[0], state);
14732
traverse(node.tag, path, state);
14733
utils.catchup(node.tag.range[1], state);
14734
14735
// print array of template elements
14736
utils.append('(function() { var siteObj = [', state);
14737
for (var ii = 0; ii < numQuasis; ii++) {
14738
utils.append(getCookedValue(template.quasis[ii]), state);
14739
if (ii !== numQuasis - 1) {
14740
utils.append(', ', state);
14741
}
14742
}
14743
utils.append(']; siteObj.raw = [', state);
14744
for (ii = 0; ii < numQuasis; ii++) {
14745
utils.append(getRawValue(template.quasis[ii]), state);
14746
if (ii !== numQuasis - 1) {
14747
utils.append(', ', state);
14748
}
14749
}
14750
utils.append(
14751
']; Object.freeze(siteObj.raw); Object.freeze(siteObj); return siteObj; }()',
14752
state
14753
);
14754
14755
// print substitutions
14756
if (numQuasis > 1) {
14757
for (ii = 0; ii < template.expressions.length; ii++) {
14758
var expression = template.expressions[ii];
14759
utils.append(', ', state);
14760
14761
// maintain line numbers by calling catchupWhiteSpace over the whole
14762
// previous TemplateElement
14763
utils.move(template.quasis[ii].range[0], state);
14764
utils.catchupNewlines(template.quasis[ii].range[1], state);
14765
14766
utils.move(expression.range[0], state);
14767
traverse(expression, path, state);
14768
utils.catchup(expression.range[1], state);
14769
}
14770
}
14771
14772
// print blank lines to push the closing ) down to account for the final
14773
// TemplateElement.
14774
utils.catchupNewlines(node.range[1], state);
14775
14776
utils.append(')', state);
14777
14778
return false;
14779
}
14780
14781
visitTaggedTemplateExpression.test = function(node, path, state) {
14782
return node.type === Syntax.TaggedTemplateExpression;
14783
};
14784
14785
function getCookedValue(templateElement) {
14786
return JSON.stringify(templateElement.value.cooked);
14787
}
14788
14789
function getRawValue(templateElement) {
14790
return JSON.stringify(templateElement.value.raw);
14791
}
14792
14793
exports.visitorList = [
14794
visitTemplateLiteral,
14795
visitTaggedTemplateExpression
14796
];
14797
14798
},{"../src/utils":23,"esprima-fb":9}],32:[function(_dereq_,module,exports){
14799
/**
14800
* Copyright 2013 Facebook, Inc.
14801
*
14802
* Licensed under the Apache License, Version 2.0 (the "License");
14803
* you may not use this file except in compliance with the License.
14804
* You may obtain a copy of the License at
14805
*
14806
* http://www.apache.org/licenses/LICENSE-2.0
14807
*
14808
* Unless required by applicable law or agreed to in writing, software
14809
* distributed under the License is distributed on an "AS IS" BASIS,
14810
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14811
* See the License for the specific language governing permissions and
14812
* limitations under the License.
14813
*/
14814
14815
/*jslint node:true*/
14816
14817
/**
14818
* Desugars ES7 rest properties into ES5 object iteration.
14819
*/
14820
14821
var Syntax = _dereq_('esprima-fb').Syntax;
14822
14823
// TODO: This is a pretty massive helper, it should only be defined once, in the
14824
// transform's runtime environment. We don't currently have a runtime though.
14825
var restFunction =
14826
'(function(source, exclusion) {' +
14827
'var rest = {};' +
14828
'var hasOwn = Object.prototype.hasOwnProperty;' +
14829
'if (source == null) {' +
14830
'throw new TypeError();' +
14831
'}' +
14832
'for (var key in source) {' +
14833
'if (hasOwn.call(source, key) && !hasOwn.call(exclusion, key)) {' +
14834
'rest[key] = source[key];' +
14835
'}' +
14836
'}' +
14837
'return rest;' +
14838
'})';
14839
14840
function getPropertyNames(properties) {
14841
var names = [];
14842
for (var i = 0; i < properties.length; i++) {
14843
var property = properties[i];
14844
if (property.type === Syntax.SpreadProperty) {
14845
continue;
14846
}
14847
if (property.type === Syntax.Identifier) {
14848
names.push(property.name);
14849
} else {
14850
names.push(property.key.name);
14851
}
14852
}
14853
return names;
14854
}
14855
14856
function getRestFunctionCall(source, exclusion) {
14857
return restFunction + '(' + source + ',' + exclusion + ')';
14858
}
14859
14860
function getSimpleShallowCopy(accessorExpression) {
14861
// This could be faster with 'Object.assign({}, ' + accessorExpression + ')'
14862
// but to unify code paths and avoid a ES6 dependency we use the same
14863
// helper as for the exclusion case.
14864
return getRestFunctionCall(accessorExpression, '{}');
14865
}
14866
14867
function renderRestExpression(accessorExpression, excludedProperties) {
14868
var excludedNames = getPropertyNames(excludedProperties);
14869
if (!excludedNames.length) {
14870
return getSimpleShallowCopy(accessorExpression);
14871
}
14872
return getRestFunctionCall(
14873
accessorExpression,
14874
'{' + excludedNames.join(':1,') + ':1}'
14875
);
14876
}
14877
14878
exports.renderRestExpression = renderRestExpression;
14879
14880
},{"esprima-fb":9}],33:[function(_dereq_,module,exports){
14881
/**
14882
* Copyright 2004-present Facebook. All Rights Reserved.
14883
*/
14884
/*global exports:true*/
14885
14886
/**
14887
* Implements ES7 object spread property.
14888
* https://gist.github.com/sebmarkbage/aa849c7973cb4452c547
14889
*
14890
* { ...a, x: 1 }
14891
*
14892
* Object.assign({}, a, {x: 1 })
14893
*
14894
*/
14895
14896
var Syntax = _dereq_('esprima-fb').Syntax;
14897
var utils = _dereq_('../src/utils');
14898
14899
function visitObjectLiteralSpread(traverse, node, path, state) {
14900
utils.catchup(node.range[0], state);
14901
14902
utils.append('Object.assign({', state);
14903
14904
// Skip the original {
14905
utils.move(node.range[0] + 1, state);
14906
14907
var previousWasSpread = false;
14908
14909
for (var i = 0; i < node.properties.length; i++) {
14910
var property = node.properties[i];
14911
if (property.type === Syntax.SpreadProperty) {
14912
14913
// Close the previous object or initial object
14914
if (!previousWasSpread) {
14915
utils.append('}', state);
14916
}
14917
14918
if (i === 0) {
14919
// Normally there will be a comma when we catch up, but not before
14920
// the first property.
14921
utils.append(',', state);
14922
}
14923
14924
utils.catchup(property.range[0], state);
14925
14926
// skip ...
14927
utils.move(property.range[0] + 3, state);
14928
14929
traverse(property.argument, path, state);
14930
14931
utils.catchup(property.range[1], state);
14932
14933
previousWasSpread = true;
14934
14935
} else {
14936
14937
utils.catchup(property.range[0], state);
14938
14939
if (previousWasSpread) {
14940
utils.append('{', state);
14941
}
14942
14943
traverse(property, path, state);
14944
14945
utils.catchup(property.range[1], state);
14946
14947
previousWasSpread = false;
14948
14949
}
14950
}
14951
14952
// Strip any non-whitespace between the last item and the end.
14953
// We only catch up on whitespace so that we ignore any trailing commas which
14954
// are stripped out for IE8 support. Unfortunately, this also strips out any
14955
// trailing comments.
14956
utils.catchupWhiteSpace(node.range[1] - 1, state);
14957
14958
// Skip the trailing }
14959
utils.move(node.range[1], state);
14960
14961
if (!previousWasSpread) {
14962
utils.append('}', state);
14963
}
14964
14965
utils.append(')', state);
14966
return false;
14967
}
14968
14969
visitObjectLiteralSpread.test = function(node, path, state) {
14970
if (node.type !== Syntax.ObjectExpression) {
14971
return false;
14972
}
14973
// Tight loop optimization
14974
var hasAtLeastOneSpreadProperty = false;
14975
for (var i = 0; i < node.properties.length; i++) {
14976
var property = node.properties[i];
14977
if (property.type === Syntax.SpreadProperty) {
14978
hasAtLeastOneSpreadProperty = true;
14979
} else if (property.kind !== 'init') {
14980
return false;
14981
}
14982
}
14983
return hasAtLeastOneSpreadProperty;
14984
};
14985
14986
exports.visitorList = [
14987
visitObjectLiteralSpread
14988
];
14989
14990
},{"../src/utils":23,"esprima-fb":9}],34:[function(_dereq_,module,exports){
14991
/**
14992
* Copyright 2014 Facebook, Inc.
14993
*
14994
* Licensed under the Apache License, Version 2.0 (the "License");
14995
* you may not use this file except in compliance with the License.
14996
* You may obtain a copy of the License at
14997
*
14998
* http://www.apache.org/licenses/LICENSE-2.0
14999
*
15000
* Unless required by applicable law or agreed to in writing, software
15001
* distributed under the License is distributed on an "AS IS" BASIS,
15002
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15003
* See the License for the specific language governing permissions and
15004
* limitations under the License.
15005
*/
15006
15007
var KEYWORDS = [
15008
'break', 'do', 'in', 'typeof', 'case', 'else', 'instanceof', 'var', 'catch',
15009
'export', 'new', 'void', 'class', 'extends', 'return', 'while', 'const',
15010
'finally', 'super', 'with', 'continue', 'for', 'switch', 'yield', 'debugger',
15011
'function', 'this', 'default', 'if', 'throw', 'delete', 'import', 'try'
15012
];
15013
15014
var FUTURE_RESERVED_WORDS = [
15015
'enum', 'await', 'implements', 'package', 'protected', 'static', 'interface',
15016
'private', 'public'
15017
];
15018
15019
var LITERALS = [
15020
'null',
15021
'true',
15022
'false'
15023
];
15024
15025
// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-reserved-words
15026
var RESERVED_WORDS = [].concat(
15027
KEYWORDS,
15028
FUTURE_RESERVED_WORDS,
15029
LITERALS
15030
);
15031
15032
var reservedWordsMap = Object.create(null);
15033
RESERVED_WORDS.forEach(function(k) {
15034
reservedWordsMap[k] = true;
15035
});
15036
15037
/**
15038
* This list should not grow as new reserved words are introdued. This list is
15039
* of words that need to be quoted because ES3-ish browsers do not allow their
15040
* use as identifier names.
15041
*/
15042
var ES3_FUTURE_RESERVED_WORDS = [
15043
'enum', 'implements', 'package', 'protected', 'static', 'interface',
15044
'private', 'public'
15045
];
15046
15047
var ES3_RESERVED_WORDS = [].concat(
15048
KEYWORDS,
15049
ES3_FUTURE_RESERVED_WORDS,
15050
LITERALS
15051
);
15052
15053
var es3ReservedWordsMap = Object.create(null);
15054
ES3_RESERVED_WORDS.forEach(function(k) {
15055
es3ReservedWordsMap[k] = true;
15056
});
15057
15058
exports.isReservedWord = function(word) {
15059
return !!reservedWordsMap[word];
15060
};
15061
15062
exports.isES3ReservedWord = function(word) {
15063
return !!es3ReservedWordsMap[word];
15064
};
15065
15066
},{}],35:[function(_dereq_,module,exports){
15067
/**
15068
* Copyright 2014 Facebook, Inc.
15069
*
15070
* Licensed under the Apache License, Version 2.0 (the "License");
15071
* you may not use this file except in compliance with the License.
15072
* You may obtain a copy of the License at
15073
*
15074
* http://www.apache.org/licenses/LICENSE-2.0
15075
*
15076
* Unless required by applicable law or agreed to in writing, software
15077
* distributed under the License is distributed on an "AS IS" BASIS,
15078
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15079
* See the License for the specific language governing permissions and
15080
* limitations under the License.
15081
*
15082
*/
15083
/*global exports:true*/
15084
15085
var Syntax = _dereq_('esprima-fb').Syntax;
15086
var utils = _dereq_('../src/utils');
15087
var reserverdWordsHelper = _dereq_('./reserved-words-helper');
15088
15089
/**
15090
* Code adapted from https://github.com/spicyj/es3ify
15091
* The MIT License (MIT)
15092
* Copyright (c) 2014 Ben Alpert
15093
*/
15094
15095
function visitProperty(traverse, node, path, state) {
15096
utils.catchup(node.key.range[0], state);
15097
utils.append('"', state);
15098
utils.catchup(node.key.range[1], state);
15099
utils.append('"', state);
15100
utils.catchup(node.value.range[0], state);
15101
traverse(node.value, path, state);
15102
return false;
15103
}
15104
15105
visitProperty.test = function(node) {
15106
return node.type === Syntax.Property &&
15107
node.key.type === Syntax.Identifier &&
15108
!node.method &&
15109
!node.shorthand &&
15110
!node.computed &&
15111
reserverdWordsHelper.isES3ReservedWord(node.key.name);
15112
};
15113
15114
function visitMemberExpression(traverse, node, path, state) {
15115
traverse(node.object, path, state);
15116
utils.catchup(node.property.range[0] - 1, state);
15117
utils.append('[', state);
15118
utils.catchupWhiteSpace(node.property.range[0], state);
15119
utils.append('"', state);
15120
utils.catchup(node.property.range[1], state);
15121
utils.append('"]', state);
15122
return false;
15123
}
15124
15125
visitMemberExpression.test = function(node) {
15126
return node.type === Syntax.MemberExpression &&
15127
node.property.type === Syntax.Identifier &&
15128
reserverdWordsHelper.isES3ReservedWord(node.property.name);
15129
};
15130
15131
exports.visitorList = [
15132
visitProperty,
15133
visitMemberExpression
15134
];
15135
15136
},{"../src/utils":23,"./reserved-words-helper":34,"esprima-fb":9}],36:[function(_dereq_,module,exports){
15137
var esprima = _dereq_('esprima-fb');
15138
var utils = _dereq_('../src/utils');
15139
15140
var Syntax = esprima.Syntax;
15141
15142
function _isFunctionNode(node) {
15143
return node.type === Syntax.FunctionDeclaration
15144
|| node.type === Syntax.FunctionExpression
15145
|| node.type === Syntax.ArrowFunctionExpression;
15146
}
15147
15148
function visitClassProperty(traverse, node, path, state) {
15149
utils.catchup(node.range[0], state);
15150
utils.catchupWhiteOut(node.range[1], state);
15151
return false;
15152
}
15153
visitClassProperty.test = function(node, path, state) {
15154
return node.type === Syntax.ClassProperty;
15155
};
15156
15157
function visitTypeAlias(traverse, node, path, state) {
15158
utils.catchupWhiteOut(node.range[1], state);
15159
return false;
15160
}
15161
visitTypeAlias.test = function(node, path, state) {
15162
return node.type === Syntax.TypeAlias;
15163
};
15164
15165
function visitTypeCast(traverse, node, path, state) {
15166
path.unshift(node);
15167
traverse(node.expression, path, state);
15168
path.shift();
15169
15170
utils.catchup(node.typeAnnotation.range[0], state);
15171
utils.catchupWhiteOut(node.typeAnnotation.range[1], state);
15172
return false;
15173
}
15174
visitTypeCast.test = function(node, path, state) {
15175
return node.type === Syntax.TypeCastExpression;
15176
};
15177
15178
function visitInterfaceDeclaration(traverse, node, path, state) {
15179
utils.catchupWhiteOut(node.range[1], state);
15180
return false;
15181
}
15182
visitInterfaceDeclaration.test = function(node, path, state) {
15183
return node.type === Syntax.InterfaceDeclaration;
15184
};
15185
15186
function visitDeclare(traverse, node, path, state) {
15187
utils.catchupWhiteOut(node.range[1], state);
15188
return false;
15189
}
15190
visitDeclare.test = function(node, path, state) {
15191
switch (node.type) {
15192
case Syntax.DeclareVariable:
15193
case Syntax.DeclareFunction:
15194
case Syntax.DeclareClass:
15195
case Syntax.DeclareModule:
15196
return true;
15197
}
15198
return false;
15199
};
15200
15201
function visitFunctionParametricAnnotation(traverse, node, path, state) {
15202
utils.catchup(node.range[0], state);
15203
utils.catchupWhiteOut(node.range[1], state);
15204
return false;
15205
}
15206
visitFunctionParametricAnnotation.test = function(node, path, state) {
15207
return node.type === Syntax.TypeParameterDeclaration
15208
&& path[0]
15209
&& _isFunctionNode(path[0])
15210
&& node === path[0].typeParameters;
15211
};
15212
15213
function visitFunctionReturnAnnotation(traverse, node, path, state) {
15214
utils.catchup(node.range[0], state);
15215
utils.catchupWhiteOut(node.range[1], state);
15216
return false;
15217
}
15218
visitFunctionReturnAnnotation.test = function(node, path, state) {
15219
return path[0] && _isFunctionNode(path[0]) && node === path[0].returnType;
15220
};
15221
15222
function visitOptionalFunctionParameterAnnotation(traverse, node, path, state) {
15223
utils.catchup(node.range[0] + node.name.length, state);
15224
utils.catchupWhiteOut(node.range[1], state);
15225
return false;
15226
}
15227
visitOptionalFunctionParameterAnnotation.test = function(node, path, state) {
15228
return node.type === Syntax.Identifier
15229
&& node.optional
15230
&& path[0]
15231
&& _isFunctionNode(path[0]);
15232
};
15233
15234
function visitTypeAnnotatedIdentifier(traverse, node, path, state) {
15235
utils.catchup(node.typeAnnotation.range[0], state);
15236
utils.catchupWhiteOut(node.typeAnnotation.range[1], state);
15237
return false;
15238
}
15239
visitTypeAnnotatedIdentifier.test = function(node, path, state) {
15240
return node.type === Syntax.Identifier && node.typeAnnotation;
15241
};
15242
15243
function visitTypeAnnotatedObjectOrArrayPattern(traverse, node, path, state) {
15244
utils.catchup(node.typeAnnotation.range[0], state);
15245
utils.catchupWhiteOut(node.typeAnnotation.range[1], state);
15246
return false;
15247
}
15248
visitTypeAnnotatedObjectOrArrayPattern.test = function(node, path, state) {
15249
var rightType = node.type === Syntax.ObjectPattern
15250
|| node.type === Syntax.ArrayPattern;
15251
return rightType && node.typeAnnotation;
15252
};
15253
15254
/**
15255
* Methods cause trouble, since esprima parses them as a key/value pair, where
15256
* the location of the value starts at the method body. For example
15257
* { bar(x:number,...y:Array<number>):number {} }
15258
* is parsed as
15259
* { bar: function(x: number, ...y:Array<number>): number {} }
15260
* except that the location of the FunctionExpression value is 40-something,
15261
* which is the location of the function body. This means that by the time we
15262
* visit the params, rest param, and return type organically, we've already
15263
* catchup()'d passed them.
15264
*/
15265
function visitMethod(traverse, node, path, state) {
15266
path.unshift(node);
15267
traverse(node.key, path, state);
15268
15269
path.unshift(node.value);
15270
traverse(node.value.params, path, state);
15271
node.value.rest && traverse(node.value.rest, path, state);
15272
node.value.returnType && traverse(node.value.returnType, path, state);
15273
traverse(node.value.body, path, state);
15274
15275
path.shift();
15276
15277
path.shift();
15278
return false;
15279
}
15280
15281
visitMethod.test = function(node, path, state) {
15282
return (node.type === "Property" && (node.method || node.kind === "set" || node.kind === "get"))
15283
|| (node.type === "MethodDefinition");
15284
};
15285
15286
function visitImportType(traverse, node, path, state) {
15287
utils.catchupWhiteOut(node.range[1], state);
15288
return false;
15289
}
15290
visitImportType.test = function(node, path, state) {
15291
return node.type === 'ImportDeclaration'
15292
&& node.isType;
15293
};
15294
15295
exports.visitorList = [
15296
visitClassProperty,
15297
visitDeclare,
15298
visitImportType,
15299
visitInterfaceDeclaration,
15300
visitFunctionParametricAnnotation,
15301
visitFunctionReturnAnnotation,
15302
visitMethod,
15303
visitOptionalFunctionParameterAnnotation,
15304
visitTypeAlias,
15305
visitTypeCast,
15306
visitTypeAnnotatedIdentifier,
15307
visitTypeAnnotatedObjectOrArrayPattern
15308
];
15309
15310
},{"../src/utils":23,"esprima-fb":9}],37:[function(_dereq_,module,exports){
15311
/**
15312
* Copyright 2013-2015, Facebook, Inc.
15313
* All rights reserved.
15314
*
15315
* This source code is licensed under the BSD-style license found in the
15316
* LICENSE file in the root directory of this source tree. An additional grant
15317
* of patent rights can be found in the PATENTS file in the same directory.
15318
*/
15319
/*global exports:true*/
15320
'use strict';
15321
var Syntax = _dereq_('jstransform').Syntax;
15322
var utils = _dereq_('jstransform/src/utils');
15323
15324
function renderJSXLiteral(object, isLast, state, start, end) {
15325
var lines = object.value.split(/\r\n|\n|\r/);
15326
15327
if (start) {
15328
utils.append(start, state);
15329
}
15330
15331
var lastNonEmptyLine = 0;
15332
15333
lines.forEach(function(line, index) {
15334
if (line.match(/[^ \t]/)) {
15335
lastNonEmptyLine = index;
15336
}
15337
});
15338
15339
lines.forEach(function(line, index) {
15340
var isFirstLine = index === 0;
15341
var isLastLine = index === lines.length - 1;
15342
var isLastNonEmptyLine = index === lastNonEmptyLine;
15343
15344
// replace rendered whitespace tabs with spaces
15345
var trimmedLine = line.replace(/\t/g, ' ');
15346
15347
// trim whitespace touching a newline
15348
if (!isFirstLine) {
15349
trimmedLine = trimmedLine.replace(/^[ ]+/, '');
15350
}
15351
if (!isLastLine) {
15352
trimmedLine = trimmedLine.replace(/[ ]+$/, '');
15353
}
15354
15355
if (!isFirstLine) {
15356
utils.append(line.match(/^[ \t]*/)[0], state);
15357
}
15358
15359
if (trimmedLine || isLastNonEmptyLine) {
15360
utils.append(
15361
JSON.stringify(trimmedLine) +
15362
(!isLastNonEmptyLine ? ' + \' \' +' : ''),
15363
state);
15364
15365
if (isLastNonEmptyLine) {
15366
if (end) {
15367
utils.append(end, state);
15368
}
15369
if (!isLast) {
15370
utils.append(', ', state);
15371
}
15372
}
15373
15374
// only restore tail whitespace if line had literals
15375
if (trimmedLine && !isLastLine) {
15376
utils.append(line.match(/[ \t]*$/)[0], state);
15377
}
15378
}
15379
15380
if (!isLastLine) {
15381
utils.append('\n', state);
15382
}
15383
});
15384
15385
utils.move(object.range[1], state);
15386
}
15387
15388
function renderJSXExpressionContainer(traverse, object, isLast, path, state) {
15389
// Plus 1 to skip `{`.
15390
utils.move(object.range[0] + 1, state);
15391
utils.catchup(object.expression.range[0], state);
15392
traverse(object.expression, path, state);
15393
15394
if (!isLast && object.expression.type !== Syntax.JSXEmptyExpression) {
15395
// If we need to append a comma, make sure to do so after the expression.
15396
utils.catchup(object.expression.range[1], state, trimLeft);
15397
utils.append(', ', state);
15398
}
15399
15400
// Minus 1 to skip `}`.
15401
utils.catchup(object.range[1] - 1, state, trimLeft);
15402
utils.move(object.range[1], state);
15403
return false;
15404
}
15405
15406
function quoteAttrName(attr) {
15407
// Quote invalid JS identifiers.
15408
if (!/^[a-z_$][a-z\d_$]*$/i.test(attr)) {
15409
return '"' + attr + '"';
15410
}
15411
return attr;
15412
}
15413
15414
function trimLeft(value) {
15415
return value.replace(/^[ ]+/, '');
15416
}
15417
15418
exports.renderJSXExpressionContainer = renderJSXExpressionContainer;
15419
exports.renderJSXLiteral = renderJSXLiteral;
15420
exports.quoteAttrName = quoteAttrName;
15421
exports.trimLeft = trimLeft;
15422
15423
},{"jstransform":22,"jstransform/src/utils":23}],38:[function(_dereq_,module,exports){
15424
/**
15425
* Copyright 2013-2015, Facebook, Inc.
15426
* All rights reserved.
15427
*
15428
* This source code is licensed under the BSD-style license found in the
15429
* LICENSE file in the root directory of this source tree. An additional grant
15430
* of patent rights can be found in the PATENTS file in the same directory.
15431
*/
15432
/*global exports:true*/
15433
'use strict';
15434
15435
var Syntax = _dereq_('jstransform').Syntax;
15436
var utils = _dereq_('jstransform/src/utils');
15437
15438
var renderJSXExpressionContainer =
15439
_dereq_('./jsx').renderJSXExpressionContainer;
15440
var renderJSXLiteral = _dereq_('./jsx').renderJSXLiteral;
15441
var quoteAttrName = _dereq_('./jsx').quoteAttrName;
15442
15443
var trimLeft = _dereq_('./jsx').trimLeft;
15444
15445
/**
15446
* Customized desugar processor for React JSX. Currently:
15447
*
15448
* <X> </X> => React.createElement(X, null)
15449
* <X prop="1" /> => React.createElement(X, {prop: '1'}, null)
15450
* <X prop="2"><Y /></X> => React.createElement(X, {prop:'2'},
15451
* React.createElement(Y, null)
15452
* )
15453
* <div /> => React.createElement("div", null)
15454
*/
15455
15456
/**
15457
* Removes all non-whitespace/parenthesis characters
15458
*/
15459
var reNonWhiteParen = /([^\s\(\)])/g;
15460
function stripNonWhiteParen(value) {
15461
return value.replace(reNonWhiteParen, '');
15462
}
15463
15464
var tagConvention = /^[a-z]|\-/;
15465
function isTagName(name) {
15466
return tagConvention.test(name);
15467
}
15468
15469
function visitReactTag(traverse, object, path, state) {
15470
var openingElement = object.openingElement;
15471
var nameObject = openingElement.name;
15472
var attributesObject = openingElement.attributes;
15473
15474
utils.catchup(openingElement.range[0], state, trimLeft);
15475
15476
if (nameObject.type === Syntax.JSXNamespacedName && nameObject.namespace) {
15477
throw new Error('Namespace tags are not supported. ReactJSX is not XML.');
15478
}
15479
15480
// We assume that the React runtime is already in scope
15481
utils.append('React.createElement(', state);
15482
15483
if (nameObject.type === Syntax.JSXIdentifier && isTagName(nameObject.name)) {
15484
utils.append('"' + nameObject.name + '"', state);
15485
utils.move(nameObject.range[1], state);
15486
} else {
15487
// Use utils.catchup in this case so we can easily handle
15488
// JSXMemberExpressions which look like Foo.Bar.Baz. This also handles
15489
// JSXIdentifiers that aren't fallback tags.
15490
utils.move(nameObject.range[0], state);
15491
utils.catchup(nameObject.range[1], state);
15492
}
15493
15494
utils.append(', ', state);
15495
15496
var hasAttributes = attributesObject.length;
15497
15498
var hasAtLeastOneSpreadProperty = attributesObject.some(function(attr) {
15499
return attr.type === Syntax.JSXSpreadAttribute;
15500
});
15501
15502
// if we don't have any attributes, pass in null
15503
if (hasAtLeastOneSpreadProperty) {
15504
utils.append('React.__spread({', state);
15505
} else if (hasAttributes) {
15506
utils.append('{', state);
15507
} else {
15508
utils.append('null', state);
15509
}
15510
15511
// keep track of if the previous attribute was a spread attribute
15512
var previousWasSpread = false;
15513
15514
// write attributes
15515
attributesObject.forEach(function(attr, index) {
15516
var isLast = index === attributesObject.length - 1;
15517
15518
if (attr.type === Syntax.JSXSpreadAttribute) {
15519
// Close the previous object or initial object
15520
if (!previousWasSpread) {
15521
utils.append('}, ', state);
15522
}
15523
15524
// Move to the expression start, ignoring everything except parenthesis
15525
// and whitespace.
15526
utils.catchup(attr.range[0], state, stripNonWhiteParen);
15527
// Plus 1 to skip `{`.
15528
utils.move(attr.range[0] + 1, state);
15529
utils.catchup(attr.argument.range[0], state, stripNonWhiteParen);
15530
15531
traverse(attr.argument, path, state);
15532
15533
utils.catchup(attr.argument.range[1], state);
15534
15535
// Move to the end, ignoring parenthesis and the closing `}`
15536
utils.catchup(attr.range[1] - 1, state, stripNonWhiteParen);
15537
15538
if (!isLast) {
15539
utils.append(', ', state);
15540
}
15541
15542
utils.move(attr.range[1], state);
15543
15544
previousWasSpread = true;
15545
15546
return;
15547
}
15548
15549
// If the next attribute is a spread, we're effective last in this object
15550
if (!isLast) {
15551
isLast = attributesObject[index + 1].type === Syntax.JSXSpreadAttribute;
15552
}
15553
15554
if (attr.name.namespace) {
15555
throw new Error(
15556
'Namespace attributes are not supported. ReactJSX is not XML.');
15557
}
15558
var name = attr.name.name;
15559
15560
utils.catchup(attr.range[0], state, trimLeft);
15561
15562
if (previousWasSpread) {
15563
utils.append('{', state);
15564
}
15565
15566
utils.append(quoteAttrName(name), state);
15567
utils.append(': ', state);
15568
15569
if (!attr.value) {
15570
state.g.buffer += 'true';
15571
state.g.position = attr.name.range[1];
15572
if (!isLast) {
15573
utils.append(', ', state);
15574
}
15575
} else {
15576
utils.move(attr.name.range[1], state);
15577
// Use catchupNewlines to skip over the '=' in the attribute
15578
utils.catchupNewlines(attr.value.range[0], state);
15579
if (attr.value.type === Syntax.Literal) {
15580
renderJSXLiteral(attr.value, isLast, state);
15581
} else {
15582
renderJSXExpressionContainer(traverse, attr.value, isLast, path, state);
15583
}
15584
}
15585
15586
utils.catchup(attr.range[1], state, trimLeft);
15587
15588
previousWasSpread = false;
15589
15590
});
15591
15592
if (!openingElement.selfClosing) {
15593
utils.catchup(openingElement.range[1] - 1, state, trimLeft);
15594
utils.move(openingElement.range[1], state);
15595
}
15596
15597
if (hasAttributes && !previousWasSpread) {
15598
utils.append('}', state);
15599
}
15600
15601
if (hasAtLeastOneSpreadProperty) {
15602
utils.append(')', state);
15603
}
15604
15605
// filter out whitespace
15606
var childrenToRender = object.children.filter(function(child) {
15607
return !(child.type === Syntax.Literal
15608
&& typeof child.value === 'string'
15609
&& child.value.match(/^[ \t]*[\r\n][ \t\r\n]*$/));
15610
});
15611
if (childrenToRender.length > 0) {
15612
var lastRenderableIndex;
15613
15614
childrenToRender.forEach(function(child, index) {
15615
if (child.type !== Syntax.JSXExpressionContainer ||
15616
child.expression.type !== Syntax.JSXEmptyExpression) {
15617
lastRenderableIndex = index;
15618
}
15619
});
15620
15621
if (lastRenderableIndex !== undefined) {
15622
utils.append(', ', state);
15623
}
15624
15625
childrenToRender.forEach(function(child, index) {
15626
utils.catchup(child.range[0], state, trimLeft);
15627
15628
var isLast = index >= lastRenderableIndex;
15629
15630
if (child.type === Syntax.Literal) {
15631
renderJSXLiteral(child, isLast, state);
15632
} else if (child.type === Syntax.JSXExpressionContainer) {
15633
renderJSXExpressionContainer(traverse, child, isLast, path, state);
15634
} else {
15635
traverse(child, path, state);
15636
if (!isLast) {
15637
utils.append(', ', state);
15638
}
15639
}
15640
15641
utils.catchup(child.range[1], state, trimLeft);
15642
});
15643
}
15644
15645
if (openingElement.selfClosing) {
15646
// everything up to />
15647
utils.catchup(openingElement.range[1] - 2, state, trimLeft);
15648
utils.move(openingElement.range[1], state);
15649
} else {
15650
// everything up to </ sdflksjfd>
15651
utils.catchup(object.closingElement.range[0], state, trimLeft);
15652
utils.move(object.closingElement.range[1], state);
15653
}
15654
15655
utils.append(')', state);
15656
return false;
15657
}
15658
15659
visitReactTag.test = function(object, path, state) {
15660
return object.type === Syntax.JSXElement;
15661
};
15662
15663
exports.visitorList = [
15664
visitReactTag
15665
];
15666
15667
},{"./jsx":37,"jstransform":22,"jstransform/src/utils":23}],39:[function(_dereq_,module,exports){
15668
/**
15669
* Copyright 2013-2015, Facebook, Inc.
15670
* All rights reserved.
15671
*
15672
* This source code is licensed under the BSD-style license found in the
15673
* LICENSE file in the root directory of this source tree. An additional grant
15674
* of patent rights can be found in the PATENTS file in the same directory.
15675
*/
15676
/*global exports:true*/
15677
'use strict';
15678
15679
var Syntax = _dereq_('jstransform').Syntax;
15680
var utils = _dereq_('jstransform/src/utils');
15681
15682
function addDisplayName(displayName, object, state) {
15683
if (object &&
15684
object.type === Syntax.CallExpression &&
15685
object.callee.type === Syntax.MemberExpression &&
15686
object.callee.object.type === Syntax.Identifier &&
15687
object.callee.object.name === 'React' &&
15688
object.callee.property.type === Syntax.Identifier &&
15689
object.callee.property.name === 'createClass' &&
15690
object.arguments.length === 1 &&
15691
object.arguments[0].type === Syntax.ObjectExpression) {
15692
// Verify that the displayName property isn't already set
15693
var properties = object.arguments[0].properties;
15694
var safe = properties.every(function(property) {
15695
var value = property.key.type === Syntax.Identifier ?
15696
property.key.name :
15697
property.key.value;
15698
return value !== 'displayName';
15699
});
15700
15701
if (safe) {
15702
utils.catchup(object.arguments[0].range[0] + 1, state);
15703
utils.append('displayName: "' + displayName + '",', state);
15704
}
15705
}
15706
}
15707
15708
/**
15709
* Transforms the following:
15710
*
15711
* var MyComponent = React.createClass({
15712
* render: ...
15713
* });
15714
*
15715
* into:
15716
*
15717
* var MyComponent = React.createClass({
15718
* displayName: 'MyComponent',
15719
* render: ...
15720
* });
15721
*
15722
* Also catches:
15723
*
15724
* MyComponent = React.createClass(...);
15725
* exports.MyComponent = React.createClass(...);
15726
* module.exports = {MyComponent: React.createClass(...)};
15727
*/
15728
function visitReactDisplayName(traverse, object, path, state) {
15729
var left, right;
15730
15731
if (object.type === Syntax.AssignmentExpression) {
15732
left = object.left;
15733
right = object.right;
15734
} else if (object.type === Syntax.Property) {
15735
left = object.key;
15736
right = object.value;
15737
} else if (object.type === Syntax.VariableDeclarator) {
15738
left = object.id;
15739
right = object.init;
15740
}
15741
15742
if (left && left.type === Syntax.MemberExpression) {
15743
left = left.property;
15744
}
15745
if (left && left.type === Syntax.Identifier) {
15746
addDisplayName(left.name, right, state);
15747
}
15748
}
15749
15750
visitReactDisplayName.test = function(object, path, state) {
15751
return (
15752
object.type === Syntax.AssignmentExpression ||
15753
object.type === Syntax.Property ||
15754
object.type === Syntax.VariableDeclarator
15755
);
15756
};
15757
15758
exports.visitorList = [
15759
visitReactDisplayName
15760
];
15761
15762
},{"jstransform":22,"jstransform/src/utils":23}],40:[function(_dereq_,module,exports){
15763
/*global exports:true*/
15764
15765
'use strict';
15766
15767
var es6ArrowFunctions =
15768
_dereq_('jstransform/visitors/es6-arrow-function-visitors');
15769
var es6Classes = _dereq_('jstransform/visitors/es6-class-visitors');
15770
var es6Destructuring =
15771
_dereq_('jstransform/visitors/es6-destructuring-visitors');
15772
var es6ObjectConciseMethod =
15773
_dereq_('jstransform/visitors/es6-object-concise-method-visitors');
15774
var es6ObjectShortNotation =
15775
_dereq_('jstransform/visitors/es6-object-short-notation-visitors');
15776
var es6RestParameters = _dereq_('jstransform/visitors/es6-rest-param-visitors');
15777
var es6Templates = _dereq_('jstransform/visitors/es6-template-visitors');
15778
var es6CallSpread =
15779
_dereq_('jstransform/visitors/es6-call-spread-visitors');
15780
var es7SpreadProperty =
15781
_dereq_('jstransform/visitors/es7-spread-property-visitors');
15782
var react = _dereq_('./transforms/react');
15783
var reactDisplayName = _dereq_('./transforms/reactDisplayName');
15784
var reservedWords = _dereq_('jstransform/visitors/reserved-words-visitors');
15785
15786
/**
15787
* Map from transformName => orderedListOfVisitors.
15788
*/
15789
var transformVisitors = {
15790
'es6-arrow-functions': es6ArrowFunctions.visitorList,
15791
'es6-classes': es6Classes.visitorList,
15792
'es6-destructuring': es6Destructuring.visitorList,
15793
'es6-object-concise-method': es6ObjectConciseMethod.visitorList,
15794
'es6-object-short-notation': es6ObjectShortNotation.visitorList,
15795
'es6-rest-params': es6RestParameters.visitorList,
15796
'es6-templates': es6Templates.visitorList,
15797
'es6-call-spread': es6CallSpread.visitorList,
15798
'es7-spread-property': es7SpreadProperty.visitorList,
15799
'react': react.visitorList.concat(reactDisplayName.visitorList),
15800
'reserved-words': reservedWords.visitorList
15801
};
15802
15803
var transformSets = {
15804
'harmony': [
15805
'es6-arrow-functions',
15806
'es6-object-concise-method',
15807
'es6-object-short-notation',
15808
'es6-classes',
15809
'es6-rest-params',
15810
'es6-templates',
15811
'es6-destructuring',
15812
'es6-call-spread',
15813
'es7-spread-property'
15814
],
15815
'es3': [
15816
'reserved-words'
15817
],
15818
'react': [
15819
'react'
15820
]
15821
};
15822
15823
/**
15824
* Specifies the order in which each transform should run.
15825
*/
15826
var transformRunOrder = [
15827
'reserved-words',
15828
'es6-arrow-functions',
15829
'es6-object-concise-method',
15830
'es6-object-short-notation',
15831
'es6-classes',
15832
'es6-rest-params',
15833
'es6-templates',
15834
'es6-destructuring',
15835
'es6-call-spread',
15836
'es7-spread-property',
15837
'react'
15838
];
15839
15840
/**
15841
* Given a list of transform names, return the ordered list of visitors to be
15842
* passed to the transform() function.
15843
*
15844
* @param {array?} excludes
15845
* @return {array}
15846
*/
15847
function getAllVisitors(excludes) {
15848
var ret = [];
15849
for (var i = 0, il = transformRunOrder.length; i < il; i++) {
15850
if (!excludes || excludes.indexOf(transformRunOrder[i]) === -1) {
15851
ret = ret.concat(transformVisitors[transformRunOrder[i]]);
15852
}
15853
}
15854
return ret;
15855
}
15856
15857
/**
15858
* Given a list of visitor set names, return the ordered list of visitors to be
15859
* passed to jstransform.
15860
*
15861
* @param {array}
15862
* @return {array}
15863
*/
15864
function getVisitorsBySet(sets) {
15865
var visitorsToInclude = sets.reduce(function(visitors, set) {
15866
if (!transformSets.hasOwnProperty(set)) {
15867
throw new Error('Unknown visitor set: ' + set);
15868
}
15869
transformSets[set].forEach(function(visitor) {
15870
visitors[visitor] = true;
15871
});
15872
return visitors;
15873
}, {});
15874
15875
var visitorList = [];
15876
for (var i = 0; i < transformRunOrder.length; i++) {
15877
if (visitorsToInclude.hasOwnProperty(transformRunOrder[i])) {
15878
visitorList = visitorList.concat(transformVisitors[transformRunOrder[i]]);
15879
}
15880
}
15881
15882
return visitorList;
15883
}
15884
15885
exports.getVisitorsBySet = getVisitorsBySet;
15886
exports.getAllVisitors = getAllVisitors;
15887
exports.transformVisitors = transformVisitors;
15888
15889
},{"./transforms/react":38,"./transforms/reactDisplayName":39,"jstransform/visitors/es6-arrow-function-visitors":24,"jstransform/visitors/es6-call-spread-visitors":25,"jstransform/visitors/es6-class-visitors":26,"jstransform/visitors/es6-destructuring-visitors":27,"jstransform/visitors/es6-object-concise-method-visitors":28,"jstransform/visitors/es6-object-short-notation-visitors":29,"jstransform/visitors/es6-rest-param-visitors":30,"jstransform/visitors/es6-template-visitors":31,"jstransform/visitors/es7-spread-property-visitors":33,"jstransform/visitors/reserved-words-visitors":35}],41:[function(_dereq_,module,exports){
15890
/**
15891
* Copyright 2013-2015, Facebook, Inc.
15892
* All rights reserved.
15893
*
15894
* This source code is licensed under the BSD-style license found in the
15895
* LICENSE file in the root directory of this source tree. An additional grant
15896
* of patent rights can be found in the PATENTS file in the same directory.
15897
*/
15898
15899
'use strict';
15900
/*eslint-disable no-undef*/
15901
var Buffer = _dereq_('buffer').Buffer;
15902
15903
function inlineSourceMap(sourceMap, sourceCode, sourceFilename) {
15904
// This can be used with a sourcemap that has already has toJSON called on it.
15905
// Check first.
15906
var json = sourceMap;
15907
if (typeof sourceMap.toJSON === 'function') {
15908
json = sourceMap.toJSON();
15909
}
15910
json.sources = [sourceFilename];
15911
json.sourcesContent = [sourceCode];
15912
var base64 = Buffer(JSON.stringify(json)).toString('base64');
15913
return '//# sourceMappingURL=data:application/json;base64,' + base64;
15914
}
15915
15916
module.exports = inlineSourceMap;
15917
15918
},{"buffer":3}]},{},[1])(1)
15919
});
15920