<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[209491] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/209491">209491</a></dd>
<dt>Author</dt> <dd>joepeck@webkit.org</dd>
<dt>Date</dt> <dd>2016-12-07 16:04:07 -0800 (Wed, 07 Dec 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Web Inspector: Update Esprima to support new features / syntax (**, async/await, trailing comma)
https://bugs.webkit.org/show_bug.cgi?id=164830
&lt;rdar://problem/29293814&gt;

Reviewed by Timothy Hatcher.

Source/WebInspectorUI:

* UserInterface/External/Esprima/LICENSE:
* UserInterface/External/Esprima/esprima.js:
Updated to Esprima@7219731 (4.0.0-dev).

* UserInterface/Models/ScriptSyntaxTree.js:
(WebInspector.ScriptSyntaxTree.prototype._recurse):
(WebInspector.ScriptSyntaxTree.prototype._createInternalSyntaxTree):
* UserInterface/Workers/Formatter/ESTreeWalker.js:
(ESTreeWalker.prototype._walkChildren):
Add new nodes (AwaitExpression).
Add new states (async boolean property on Functions).
Remove stale properties (defaults is no longer needed, as parameters
with default values are now AssignmentPatterns).
Update MetaProperty where meta/property are now Identifiers not strings.

* UserInterface/Workers/Formatter/EsprimaFormatter.js:
(EsprimaFormatter.prototype._handleTokenAtNode):
Handle pretty printing of new nodes and identifiers.

* Controllers/FrameResourceManager.js
Address a console.assert warning for stripping assertions in Production.

LayoutTests:

* inspector/formatting/resources/javascript-tests/arrow-functions-expected.js:
* inspector/formatting/resources/javascript-tests/arrow-functions.js:
* inspector/formatting/resources/javascript-tests/classes-expected.js:
* inspector/formatting/resources/javascript-tests/classes.js:
* inspector/formatting/resources/javascript-tests/functions-expected.js:
* inspector/formatting/resources/javascript-tests/functions.js:
* inspector/formatting/resources/javascript-tests/other-statements-expected.js:
* inspector/formatting/resources/javascript-tests/other-statements.js:
* inspector/formatting/resources/javascript-tests/unary-binary-expressions-expected.js:
* inspector/formatting/resources/javascript-tests/unary-binary-expressions.js:
* inspector/model/parse-script-syntax-tree-expected.txt:
* inspector/model/parse-script-syntax-tree.html:
Coverage for new supported syntax.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsinspectorformattingresourcesjavascripttestsarrowfunctionsexpectedjs">trunk/LayoutTests/inspector/formatting/resources/javascript-tests/arrow-functions-expected.js</a></li>
<li><a href="#trunkLayoutTestsinspectorformattingresourcesjavascripttestsarrowfunctionsjs">trunk/LayoutTests/inspector/formatting/resources/javascript-tests/arrow-functions.js</a></li>
<li><a href="#trunkLayoutTestsinspectorformattingresourcesjavascripttestsclassesexpectedjs">trunk/LayoutTests/inspector/formatting/resources/javascript-tests/classes-expected.js</a></li>
<li><a href="#trunkLayoutTestsinspectorformattingresourcesjavascripttestsclassesjs">trunk/LayoutTests/inspector/formatting/resources/javascript-tests/classes.js</a></li>
<li><a href="#trunkLayoutTestsinspectorformattingresourcesjavascripttestsfunctionsexpectedjs">trunk/LayoutTests/inspector/formatting/resources/javascript-tests/functions-expected.js</a></li>
<li><a href="#trunkLayoutTestsinspectorformattingresourcesjavascripttestsfunctionsjs">trunk/LayoutTests/inspector/formatting/resources/javascript-tests/functions.js</a></li>
<li><a href="#trunkLayoutTestsinspectorformattingresourcesjavascripttestsotherstatementsexpectedjs">trunk/LayoutTests/inspector/formatting/resources/javascript-tests/other-statements-expected.js</a></li>
<li><a href="#trunkLayoutTestsinspectorformattingresourcesjavascripttestsotherstatementsjs">trunk/LayoutTests/inspector/formatting/resources/javascript-tests/other-statements.js</a></li>
<li><a href="#trunkLayoutTestsinspectorformattingresourcesjavascripttestsunarybinaryexpressionsexpectedjs">trunk/LayoutTests/inspector/formatting/resources/javascript-tests/unary-binary-expressions-expected.js</a></li>
<li><a href="#trunkLayoutTestsinspectorformattingresourcesjavascripttestsunarybinaryexpressionsjs">trunk/LayoutTests/inspector/formatting/resources/javascript-tests/unary-binary-expressions.js</a></li>
<li><a href="#trunkLayoutTestsinspectormodelparsescriptsyntaxtreeexpectedtxt">trunk/LayoutTests/inspector/model/parse-script-syntax-tree-expected.txt</a></li>
<li><a href="#trunkLayoutTestsinspectormodelparsescriptsyntaxtreehtml">trunk/LayoutTests/inspector/model/parse-script-syntax-tree.html</a></li>
<li><a href="#trunkSourceWebInspectorUIChangeLog">trunk/Source/WebInspectorUI/ChangeLog</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceControllersFrameResourceManagerjs">trunk/Source/WebInspectorUI/UserInterface/Controllers/FrameResourceManager.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceExternalEsprimaLICENSE">trunk/Source/WebInspectorUI/UserInterface/External/Esprima/LICENSE</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceExternalEsprimaesprimajs">trunk/Source/WebInspectorUI/UserInterface/External/Esprima/esprima.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceModelsScriptSyntaxTreejs">trunk/Source/WebInspectorUI/UserInterface/Models/ScriptSyntaxTree.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceWorkersFormatterESTreeWalkerjs">trunk/Source/WebInspectorUI/UserInterface/Workers/Formatter/ESTreeWalker.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceWorkersFormatterEsprimaFormatterjs">trunk/Source/WebInspectorUI/UserInterface/Workers/Formatter/EsprimaFormatter.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (209490 => 209491)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-12-07 23:53:10 UTC (rev 209490)
+++ trunk/LayoutTests/ChangeLog        2016-12-08 00:04:07 UTC (rev 209491)
</span><span class="lines">@@ -1,3 +1,25 @@
</span><ins>+2016-12-07  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
+
+        Web Inspector: Update Esprima to support new features / syntax (**, async/await, trailing comma)
+        https://bugs.webkit.org/show_bug.cgi?id=164830
+        &lt;rdar://problem/29293814&gt;
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/formatting/resources/javascript-tests/arrow-functions-expected.js:
+        * inspector/formatting/resources/javascript-tests/arrow-functions.js:
+        * inspector/formatting/resources/javascript-tests/classes-expected.js:
+        * inspector/formatting/resources/javascript-tests/classes.js:
+        * inspector/formatting/resources/javascript-tests/functions-expected.js:
+        * inspector/formatting/resources/javascript-tests/functions.js:
+        * inspector/formatting/resources/javascript-tests/other-statements-expected.js:
+        * inspector/formatting/resources/javascript-tests/other-statements.js:
+        * inspector/formatting/resources/javascript-tests/unary-binary-expressions-expected.js:
+        * inspector/formatting/resources/javascript-tests/unary-binary-expressions.js:
+        * inspector/model/parse-script-syntax-tree-expected.txt:
+        * inspector/model/parse-script-syntax-tree.html:
+        Coverage for new supported syntax.
+
</ins><span class="cx"> 2016-12-07  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Rebaseline tests after r209486. Also updated media-shadow-manipulation.html now that range is null.
</span></span></pre></div>
<a id="trunkLayoutTestsinspectorformattingresourcesjavascripttestsarrowfunctionsexpectedjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/formatting/resources/javascript-tests/arrow-functions-expected.js (209490 => 209491)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/formatting/resources/javascript-tests/arrow-functions-expected.js        2016-12-07 23:53:10 UTC (rev 209490)
+++ trunk/LayoutTests/inspector/formatting/resources/javascript-tests/arrow-functions-expected.js        2016-12-08 00:04:07 UTC (rev 209491)
</span><span class="lines">@@ -29,3 +29,11 @@
</span><span class="cx"> });
</span><span class="cx"> 
</span><span class="cx"> foo((a=1, ...rest) =&gt; rest[a]);
</span><ins>+
+foo((a=1, b) =&gt; b);
+
+foo((a=1, b, ) =&gt; b);
+
+async x =&gt; x
+async (x) =&gt; x
+async (x) =&gt; {x}
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectorformattingresourcesjavascripttestsarrowfunctionsjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/formatting/resources/javascript-tests/arrow-functions.js (209490 => 209491)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/formatting/resources/javascript-tests/arrow-functions.js        2016-12-07 23:53:10 UTC (rev 209490)
+++ trunk/LayoutTests/inspector/formatting/resources/javascript-tests/arrow-functions.js        2016-12-08 00:04:07 UTC (rev 209491)
</span><span class="lines">@@ -19,3 +19,11 @@
</span><span class="cx"> setTimeout(()=&gt;{1;2;3});
</span><span class="cx"> 
</span><span class="cx"> foo((a=1,...rest)=&gt;rest[a]);
</span><ins>+
+foo((a=1,b)=&gt;b);
+
+foo((a=1,b,)=&gt;b);
+
+async x=&gt;x
+async(x)=&gt;x
+async(x)=&gt;{x}
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectorformattingresourcesjavascripttestsclassesexpectedjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/formatting/resources/javascript-tests/classes-expected.js (209490 => 209491)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/formatting/resources/javascript-tests/classes-expected.js        2016-12-07 23:53:10 UTC (rev 209490)
+++ trunk/LayoutTests/inspector/formatting/resources/javascript-tests/classes-expected.js        2016-12-08 00:04:07 UTC (rev 209491)
</span><span class="lines">@@ -79,6 +79,10 @@
</span><span class="cx">     {
</span><span class="cx">         1
</span><span class="cx">     }
</span><ins>+    async a()
+    {
+        1
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> A = class Foo extends (b ? Bar : Bar) {
</span><span class="lines">@@ -114,4 +118,29 @@
</span><span class="cx">     {
</span><span class="cx">         1
</span><span class="cx">     }
</span><ins>+    async a()
+    {
+        1
+    }
</ins><span class="cx"> }
</span><ins>+
+class Foo {
+    static async async()
+    {
+        1
+    }
+    async async()
+    {
+        1
+    }
+    async()
+    {
+        1
+    }
+}
+
+class Foo {
+    async &quot;f&quot;() {}
+    async 1() {}
+    async [&quot;f&quot;]() {}
+}
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectorformattingresourcesjavascripttestsclassesjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/formatting/resources/javascript-tests/classes.js (209490 => 209491)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/formatting/resources/javascript-tests/classes.js        2016-12-07 23:53:10 UTC (rev 209490)
+++ trunk/LayoutTests/inspector/formatting/resources/javascript-tests/classes.js        2016-12-08 00:04:07 UTC (rev 209491)
</span><span class="lines">@@ -13,6 +13,10 @@
</span><span class="cx"> 
</span><span class="cx"> class Foo extends Bar{constructor(){1}static staticMethod(){super.staticMethod()}}
</span><span class="cx"> 
</span><del>-class Foo extends Bar{constructor(){1}static staticMethod(){super.staticMethod()}method1(){1}method2(name,{options}){1}get getter(){1}set setter(x){1}*gen1(){1}* gen2(){1}}
</del><ins>+class Foo extends Bar{constructor(){1}static staticMethod(){super.staticMethod()}method1(){1}method2(name,{options}){1}get getter(){1}set setter(x){1}*gen1(){1}* gen2(){1}async a(){1}}
</ins><span class="cx"> 
</span><del>-A = class Foo extends(b?Bar:Bar){constructor(){new.target.staticMethod()}static staticMethod(){super.staticMethod()}method1(){1}method2(name,{options}){super.method()}get getter(){1}set setter(x){1}*gen1(){1}* gen2(){1}}
</del><ins>+A = class Foo extends(b?Bar:Bar){constructor(){new.target.staticMethod()}static staticMethod(){super.staticMethod()}method1(){1}method2(name,{options}){super.method()}get getter(){1}set setter(x){1}*gen1(){1}* gen2(){1}async a(){1}}
+
+class Foo{static async async(){1}async async(){1}async(){1}}
+
+class Foo{async&quot;f&quot;(){}async 1(){}async[&quot;f&quot;](){}}
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectorformattingresourcesjavascripttestsfunctionsexpectedjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/formatting/resources/javascript-tests/functions-expected.js (209490 => 209491)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/formatting/resources/javascript-tests/functions-expected.js        2016-12-07 23:53:10 UTC (rev 209490)
+++ trunk/LayoutTests/inspector/formatting/resources/javascript-tests/functions-expected.js        2016-12-08 00:04:07 UTC (rev 209491)
</span><span class="lines">@@ -2,6 +2,8 @@
</span><span class="cx"> 
</span><span class="cx"> foo();
</span><span class="cx"> foo(1);
</span><ins>+foo(1, 2);
+foo(1, 2, );
</ins><span class="cx"> foo(1, 2, 3);
</span><span class="cx"> foo(foo(1));
</span><span class="cx"> foo(foo(1), foo(2, 3));
</span><span class="lines">@@ -79,6 +81,10 @@
</span><span class="cx">     1
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+function foo([a, b, ]) {
+    1
+}
+
</ins><span class="cx"> // Methods
</span><span class="cx"> 
</span><span class="cx"> o = {
</span><span class="lines">@@ -87,7 +93,8 @@
</span><span class="cx">     get getter() {},
</span><span class="cx">     set setter(x) {},
</span><span class="cx">     *gen1() {},
</span><del>-    *gen2() {}
</del><ins>+    *gen2() {},
+    async a() {}
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> o = {
</span><span class="lines">@@ -108,6 +115,9 @@
</span><span class="cx">     },
</span><span class="cx">     *gen2() {
</span><span class="cx">         1
</span><ins>+    },
+    async a() {
+        1
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> // Multiple / Nested
</span><span class="lines">@@ -122,3 +132,30 @@
</span><span class="cx">     }
</span><span class="cx">     3
</span><span class="cx"> }
</span><ins>+
+// Async / Await
+
+async function foo() {}
+async function foo() {
+    1
+}
+async function foo() {
+    await foo()
+}
+o = {
+    async async() {},
+    async() {},
+    async: 1
+}
+o = {
+    async 1() {}
+}
+o = {
+    async &quot;foo&quot;() {}
+}
+o = {
+    async [&quot;foo&quot;]() {}
+}
+o = {
+    foo: async function() {}
+}
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectorformattingresourcesjavascripttestsfunctionsjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/formatting/resources/javascript-tests/functions.js (209490 => 209491)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/formatting/resources/javascript-tests/functions.js        2016-12-07 23:53:10 UTC (rev 209490)
+++ trunk/LayoutTests/inspector/formatting/resources/javascript-tests/functions.js        2016-12-08 00:04:07 UTC (rev 209491)
</span><span class="lines">@@ -2,6 +2,8 @@
</span><span class="cx"> 
</span><span class="cx"> foo();
</span><span class="cx"> foo(1);
</span><ins>+foo(1,2);
+foo(1,2,);
</ins><span class="cx"> foo(1,2,3);
</span><span class="cx"> foo(foo(1));
</span><span class="cx"> foo(foo(1),foo(2,3));
</span><span class="lines">@@ -45,11 +47,13 @@
</span><span class="cx"> 
</span><span class="cx"> function foo([a,b]){1}
</span><span class="cx"> 
</span><ins>+function foo([a,b,]){1}
+
</ins><span class="cx"> // Methods
</span><span class="cx"> 
</span><del>-o = {prop:function(){},method(){},get getter(){},set setter(x){},*gen1(){},* gen2(){}}
</del><ins>+o={prop:function(){},method(){},get getter(){},set setter(x){},*gen1(){},* gen2(){}, async a(){}}
</ins><span class="cx"> 
</span><del>-o = {prop:function(){1},method(){1},get getter(){1},set setter(x){1},*gen1(){1},* gen2(){1}}
</del><ins>+o={prop:function(){1},method(){1},get getter(){1},set setter(x){1},*gen1(){1},* gen2(){1}, async a(){1}}
</ins><span class="cx"> 
</span><span class="cx"> // Multiple / Nested
</span><span class="cx"> 
</span><span class="lines">@@ -56,3 +60,14 @@
</span><span class="cx"> function f(){}function f(){}
</span><span class="cx"> 
</span><span class="cx"> function outer(){1;function inner(){2}3}
</span><ins>+
+// Async / Await
+
+async function foo(){}
+async function foo(){1}
+async function foo(){await foo()}
+o={async async(){},async(){},async:1}
+o={async 1(){}}
+o={async&quot;foo&quot;(){}}
+o={async[&quot;foo&quot;](){}}
+o={foo:async function(){}}
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectorformattingresourcesjavascripttestsotherstatementsexpectedjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/formatting/resources/javascript-tests/other-statements-expected.js (209490 => 209491)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/formatting/resources/javascript-tests/other-statements-expected.js        2016-12-07 23:53:10 UTC (rev 209490)
+++ trunk/LayoutTests/inspector/formatting/resources/javascript-tests/other-statements-expected.js        2016-12-08 00:04:07 UTC (rev 209491)
</span><span class="lines">@@ -8,5 +8,9 @@
</span><span class="cx">     a: 1
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+delete x;
+delete x.a;
+delete x[0];
+
</ins><span class="cx"> debugger
</span><span class="cx"> debugger;
</span></span></pre></div>
<a id="trunkLayoutTestsinspectorformattingresourcesjavascripttestsotherstatementsjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/formatting/resources/javascript-tests/other-statements.js (209490 => 209491)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/formatting/resources/javascript-tests/other-statements.js        2016-12-07 23:53:10 UTC (rev 209490)
+++ trunk/LayoutTests/inspector/formatting/resources/javascript-tests/other-statements.js        2016-12-08 00:04:07 UTC (rev 209491)
</span><span class="lines">@@ -6,5 +6,9 @@
</span><span class="cx"> throw new x;
</span><span class="cx"> throw {a:1};
</span><span class="cx"> 
</span><ins>+delete x;
+delete x.a;
+delete x[0];
+
</ins><span class="cx"> debugger
</span><span class="cx"> debugger;
</span></span></pre></div>
<a id="trunkLayoutTestsinspectorformattingresourcesjavascripttestsunarybinaryexpressionsexpectedjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/formatting/resources/javascript-tests/unary-binary-expressions-expected.js (209490 => 209491)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/formatting/resources/javascript-tests/unary-binary-expressions-expected.js        2016-12-07 23:53:10 UTC (rev 209490)
+++ trunk/LayoutTests/inspector/formatting/resources/javascript-tests/unary-binary-expressions-expected.js        2016-12-08 00:04:07 UTC (rev 209491)
</span><span class="lines">@@ -41,6 +41,7 @@
</span><span class="cx">     d: 1,
</span><span class="cx">     s: s
</span><span class="cx"> };
</span><ins>+x = x ** 2;
</ins><span class="cx"> 
</span><span class="cx"> a &lt; b;
</span><span class="cx"> a &gt; b;
</span><span class="lines">@@ -53,6 +54,12 @@
</span><span class="cx"> !a != !b;
</span><span class="cx"> !!a != !!b;
</span><span class="cx"> 
</span><ins>+x += x;
+x *= x;
+x &lt;&lt;= x;
+x **= x;
+x %= x;
+
</ins><span class="cx"> void 0;
</span><span class="cx"> void (0);
</span><span class="cx"> void (0);
</span></span></pre></div>
<a id="trunkLayoutTestsinspectorformattingresourcesjavascripttestsunarybinaryexpressionsjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/formatting/resources/javascript-tests/unary-binary-expressions.js (209490 => 209491)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/formatting/resources/javascript-tests/unary-binary-expressions.js        2016-12-07 23:53:10 UTC (rev 209490)
+++ trunk/LayoutTests/inspector/formatting/resources/javascript-tests/unary-binary-expressions.js        2016-12-08 00:04:07 UTC (rev 209491)
</span><span class="lines">@@ -35,6 +35,7 @@
</span><span class="cx"> x=(1? +1:-s);
</span><span class="cx"> x=[1? -1:+s];
</span><span class="cx"> x={a:-1,b:+1,c:1-1,d:1,s:s};
</span><ins>+x=x**2;
</ins><span class="cx"> 
</span><span class="cx"> a&lt;b;
</span><span class="cx"> a&gt;b;
</span><span class="lines">@@ -47,6 +48,12 @@
</span><span class="cx"> !a!=!b;
</span><span class="cx"> !!a!=!!b;
</span><span class="cx"> 
</span><ins>+x+=x;
+x*=x;
+x&lt;&lt;=x;
+x**=x;
+x%=x;
+
</ins><span class="cx"> void 0;
</span><span class="cx"> void(0);
</span><span class="cx"> void (0);
</span></span></pre></div>
<a id="trunkLayoutTestsinspectormodelparsescriptsyntaxtreeexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/model/parse-script-syntax-tree-expected.txt (209490 => 209491)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/model/parse-script-syntax-tree-expected.txt        2016-12-07 23:53:10 UTC (rev 209490)
+++ trunk/LayoutTests/inspector/model/parse-script-syntax-tree-expected.txt        2016-12-08 00:04:07 UTC (rev 209491)
</span><span class="lines">@@ -43,6 +43,8 @@
</span><span class="cx"> passed ClassStatement, Super, MetaProperty
</span><span class="cx"> passed AssignmentPattern
</span><span class="cx"> passed ArrowFunctionExpression
</span><ins>+passed Async Functions
+passed AwaitExpression
</ins><span class="cx"> passed computed method on object literal
</span><span class="cx"> passed method on object literal
</span><span class="cx"> passed computed method property on object literal
</span></span></pre></div>
<a id="trunkLayoutTestsinspectormodelparsescriptsyntaxtreehtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/model/parse-script-syntax-tree.html (209490 => 209491)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/model/parse-script-syntax-tree.html        2016-12-07 23:53:10 UTC (rev 209490)
+++ trunk/LayoutTests/inspector/model/parse-script-syntax-tree.html        2016-12-08 00:04:07 UTC (rev 209491)
</span><span class="lines">@@ -479,8 +479,8 @@
</span><span class="cx">     InspectorTest.assert(node.body.body[0].value.body.body[0].expression.callee.type === WebInspector.ScriptSyntaxTree.NodeType.Super);
</span><span class="cx">     InspectorTest.assert(node.body.body[0].value.body.body[1].type === WebInspector.ScriptSyntaxTree.NodeType.ExpressionStatement);
</span><span class="cx">     InspectorTest.assert(node.body.body[0].value.body.body[1].expression.type === WebInspector.ScriptSyntaxTree.NodeType.MetaProperty);
</span><del>-    InspectorTest.assert(node.body.body[0].value.body.body[1].expression.meta === &quot;new&quot;);
-    InspectorTest.assert(node.body.body[0].value.body.body[1].expression.property === &quot;target&quot;);
</del><ins>+    InspectorTest.assert(node.body.body[0].value.body.body[1].expression.meta.name === &quot;new&quot;);
+    InspectorTest.assert(node.body.body[0].value.body.body[1].expression.property.name === &quot;target&quot;);
</ins><span class="cx">     InspectorTest.log(&quot;passed ClassStatement, Super, MetaProperty&quot;);
</span><span class="cx"> 
</span><span class="cx">     node = makeNode(&quot;let [x=20] = [];&quot;, false);
</span><span class="lines">@@ -503,20 +503,53 @@
</span><span class="cx">     InspectorTest.assert(node.params[0].type === WebInspector.ScriptSyntaxTree.NodeType.Identifier);
</span><span class="cx">     InspectorTest.assert(node.params[0].name === &quot;x&quot;);
</span><span class="cx">     InspectorTest.assert(node.expression === true);
</span><del>-    InspectorTest.assert(node.defaults.length === 0);
</del><span class="cx">     InspectorTest.assert(node.body.type === WebInspector.ScriptSyntaxTree.NodeType.Identifier);
</span><span class="cx"> 
</span><span class="cx">     node = makeNode(&quot;(x = 20) =&gt; { return x; };&quot;, true);
</span><span class="cx">     InspectorTest.assert(node.type === WebInspector.ScriptSyntaxTree.NodeType.ArrowFunctionExpression);
</span><span class="cx">     InspectorTest.assert(node.params.length === 1);
</span><del>-    InspectorTest.assert(node.params[0].type === WebInspector.ScriptSyntaxTree.NodeType.Identifier);
-    InspectorTest.assert(node.params[0].name === &quot;x&quot;);
</del><ins>+    InspectorTest.assert(node.params[0].type === WebInspector.ScriptSyntaxTree.NodeType.AssignmentPattern);
+    InspectorTest.assert(node.params[0].left.type === WebInspector.ScriptSyntaxTree.NodeType.Identifier);
+    InspectorTest.assert(node.params[0].left.name === &quot;x&quot;);
+    InspectorTest.assert(node.params[0].right.type === WebInspector.ScriptSyntaxTree.NodeType.Literal);
+    InspectorTest.assert(node.params[0].right.value === 20);
</ins><span class="cx">     InspectorTest.assert(node.expression === false);
</span><del>-    InspectorTest.assert(node.defaults.length === 1);
-    InspectorTest.assert(node.defaults[0].type === WebInspector.ScriptSyntaxTree.NodeType.Literal);
</del><span class="cx">     InspectorTest.assert(node.body.type === WebInspector.ScriptSyntaxTree.NodeType.BlockStatement);
</span><span class="cx">     InspectorTest.log(&quot;passed ArrowFunctionExpression&quot;);
</span><span class="cx"> 
</span><ins>+    node = makeNode(&quot;async function foo() {}&quot;, false);
+    InspectorTest.assert(node.type === WebInspector.ScriptSyntaxTree.NodeType.FunctionDeclaration);
+    InspectorTest.assert(node.async);
+    node = makeNode(&quot;function foo() {}&quot;, false);
+    InspectorTest.assert(node.type === WebInspector.ScriptSyntaxTree.NodeType.FunctionDeclaration);
+    InspectorTest.assert(!node.async);
+    node = makeNode(&quot;(async function() {})&quot;, true);
+    InspectorTest.assert(node.type === WebInspector.ScriptSyntaxTree.NodeType.FunctionExpression);
+    InspectorTest.assert(node.async);
+    node = makeNode(&quot;(function() {})&quot;, true);
+    InspectorTest.assert(node.type === WebInspector.ScriptSyntaxTree.NodeType.FunctionExpression);
+    InspectorTest.assert(!node.async);
+    node = makeNode(&quot;async () =&gt; {}&quot;, true);
+    InspectorTest.assert(node.type === WebInspector.ScriptSyntaxTree.NodeType.ArrowFunctionExpression);
+    InspectorTest.assert(node.async);
+    node = makeNode(&quot;() =&gt; {}&quot;, true);
+    InspectorTest.assert(node.type === WebInspector.ScriptSyntaxTree.NodeType.ArrowFunctionExpression);
+    InspectorTest.assert(!node.async);
+    InspectorTest.log(&quot;passed Async Functions&quot;);
+
+    node = makeNode(&quot;async function foo() { await foo(); }&quot;, false);
+    InspectorTest.assert(node.type === WebInspector.ScriptSyntaxTree.NodeType.FunctionDeclaration);
+    InspectorTest.assert(node.async);
+    InspectorTest.assert(node.body.body[0].expression.type === WebInspector.ScriptSyntaxTree.NodeType.AwaitExpression);
+    InspectorTest.assert(node.body.body[0].expression.argument.type === WebInspector.ScriptSyntaxTree.NodeType.CallExpression);
+    node = makeNode(&quot;async function foo() { await 1; }&quot;, false);
+    InspectorTest.assert(node.type === WebInspector.ScriptSyntaxTree.NodeType.FunctionDeclaration);
+    InspectorTest.assert(node.async);
+    InspectorTest.assert(node.body.body[0].expression.type === WebInspector.ScriptSyntaxTree.NodeType.AwaitExpression);
+    InspectorTest.assert(node.body.body[0].expression.argument.type === WebInspector.ScriptSyntaxTree.NodeType.Literal);
+    InspectorTest.assert(node.body.body[0].expression.argument.value === 1);
+    InspectorTest.log(&quot;passed AwaitExpression&quot;);
+
</ins><span class="cx">     node = makeNode(&quot;var o = {['c']() { }};&quot;, false);
</span><span class="cx">     //                        ^
</span><span class="cx">     //                 type profiling return divot.
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/ChangeLog (209490 => 209491)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/ChangeLog        2016-12-07 23:53:10 UTC (rev 209490)
+++ trunk/Source/WebInspectorUI/ChangeLog        2016-12-08 00:04:07 UTC (rev 209491)
</span><span class="lines">@@ -1,5 +1,35 @@
</span><span class="cx"> 2016-12-07  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Web Inspector: Update Esprima to support new features / syntax (**, async/await, trailing comma)
+        https://bugs.webkit.org/show_bug.cgi?id=164830
+        &lt;rdar://problem/29293814&gt;
+
+        Reviewed by Timothy Hatcher.
+
+        * UserInterface/External/Esprima/LICENSE:
+        * UserInterface/External/Esprima/esprima.js:
+        Updated to Esprima@7219731 (4.0.0-dev).
+
+        * UserInterface/Models/ScriptSyntaxTree.js:
+        (WebInspector.ScriptSyntaxTree.prototype._recurse):
+        (WebInspector.ScriptSyntaxTree.prototype._createInternalSyntaxTree):
+        * UserInterface/Workers/Formatter/ESTreeWalker.js:
+        (ESTreeWalker.prototype._walkChildren):
+        Add new nodes (AwaitExpression).
+        Add new states (async boolean property on Functions).
+        Remove stale properties (defaults is no longer needed, as parameters
+        with default values are now AssignmentPatterns).
+        Update MetaProperty where meta/property are now Identifiers not strings.
+
+        * UserInterface/Workers/Formatter/EsprimaFormatter.js:
+        (EsprimaFormatter.prototype._handleTokenAtNode):
+        Handle pretty printing of new nodes and identifiers.
+
+        * Controllers/FrameResourceManager.js
+        Address a console.assert warning for stripping assertions in Production.
+
+2016-12-07  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
+
</ins><span class="cx">         Web Inspector: Remove unused and mostly untested Page domain commands and events
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=165507
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceControllersFrameResourceManagerjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/FrameResourceManager.js (209490 => 209491)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Controllers/FrameResourceManager.js        2016-12-07 23:53:10 UTC (rev 209490)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/FrameResourceManager.js        2016-12-08 00:04:07 UTC (rev 209491)
</span><span class="lines">@@ -425,7 +425,7 @@
</span><span class="cx">             }
</span><span class="cx">         } else {
</span><span class="cx">             // This is a new request for a new frame, which is always the main resource.
</span><del>-            console.assert(!targetId)
</del><ins>+            console.assert(!targetId);
</ins><span class="cx">             resource = new WebInspector.Resource(url, null, type, loaderIdentifier, targetId, requestIdentifier, requestMethod, requestHeaders, requestData, elapsedTime, initiatorSourceCodeLocation, originalRequestWillBeSentTimestamp);
</span><span class="cx">             frame = new WebInspector.Frame(frameIdentifier, frameName, frameSecurityOrigin, loaderIdentifier, resource);
</span><span class="cx">             this._frameIdentifierMap[frame.id] = frame;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceExternalEsprimaLICENSE"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/External/Esprima/LICENSE (209490 => 209491)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/External/Esprima/LICENSE        2016-12-07 23:53:10 UTC (rev 209490)
+++ trunk/Source/WebInspectorUI/UserInterface/External/Esprima/LICENSE        2016-12-08 00:04:07 UTC (rev 209491)
</span><span class="lines">@@ -1,4 +1,4 @@
</span><del>-Copyright (c) jQuery Foundation, Inc. and Contributors, All Rights Reserved.
</del><ins>+Copyright JS Foundation and other contributors, https://js.foundation/
</ins><span class="cx"> 
</span><span class="cx"> Redistribution and use in source and binary forms, with or without
</span><span class="cx"> modification, are permitted provided that the following conditions are met:
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceExternalEsprimaesprimajs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/External/Esprima/esprima.js (209490 => 209491)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/External/Esprima/esprima.js        2016-12-07 23:53:10 UTC (rev 209490)
+++ trunk/Source/WebInspectorUI/UserInterface/External/Esprima/esprima.js        2016-12-08 00:04:07 UTC (rev 209491)
</span><span class="lines">@@ -1,114 +1,346 @@
</span><del>-/*
-  Copyright (c) jQuery Foundation, Inc. and Contributors, All Rights Reserved.
</del><ins>+(function webpackUniversalModuleDefinition(root, factory) {
+/* istanbul ignore next */
+    if(typeof exports === 'object' &amp;&amp; typeof module === 'object')
+        module.exports = factory();
+    else if(typeof define === 'function' &amp;&amp; define.amd)
+        define([], factory);
+/* istanbul ignore next */
+    else if(typeof exports === 'object')
+        exports[&quot;esprima&quot;] = factory();
+    else
+        root[&quot;esprima&quot;] = factory();
+})(this, function() {
+return /******/ (function(modules) { // webpackBootstrap
+/******/     // The module cache
+/******/     var installedModules = {};
</ins><span class="cx"> 
</span><del>-  Redistribution and use in source and binary forms, with or without
-  modification, are permitted provided that the following conditions are met:
</del><ins>+/******/     // The require function
+/******/     function __webpack_require__(moduleId) {
</ins><span class="cx"> 
</span><del>-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright
-      notice, this list of conditions and the following disclaimer in the
-      documentation and/or other materials provided with the distribution.
</del><ins>+/******/         // Check if module is in cache
+/* istanbul ignore if */
+/******/         if(installedModules[moduleId])
+/******/             return installedModules[moduleId].exports;
</ins><span class="cx"> 
</span><del>-  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &quot;AS IS&quot;
-  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-  ARE DISCLAIMED. IN NO EVENT SHALL &lt;COPYRIGHT HOLDER&gt; BE LIABLE FOR ANY
-  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
</del><ins>+/******/         // Create a new module (and put it into the cache)
+/******/         var module = installedModules[moduleId] = {
+/******/             exports: {},
+/******/             id: moduleId,
+/******/             loaded: false
+/******/         };
</ins><span class="cx"> 
</span><del>-(function (root, factory) {
-    'use strict';
</del><ins>+/******/         // Execute the module function
+/******/         modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
</ins><span class="cx"> 
</span><del>-    // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js,
-    // Rhino, and plain browser loading.
</del><ins>+/******/         // Flag the module as loaded
+/******/         module.loaded = true;
</ins><span class="cx"> 
</span><del>-    /* istanbul ignore next */
-    if (typeof define === 'function' &amp;&amp; define.amd) {
-        define(['exports'], factory);
-    } else if (typeof exports !== 'undefined') {
-        factory(exports);
-    } else {
-        factory((root.esprima = {}));
</del><ins>+/******/         // Return the exports of the module
+/******/         return module.exports;
+/******/     }
+
+
+/******/     // expose the modules object (__webpack_modules__)
+/******/     __webpack_require__.m = modules;
+
+/******/     // expose the module cache
+/******/     __webpack_require__.c = installedModules;
+
+/******/     // __webpack_public_path__
+/******/     __webpack_require__.p = &quot;&quot;;
+
+/******/     // Load entry module and return exports
+/******/     return __webpack_require__(0);
+/******/ })
+/************************************************************************/
+/******/ ([
+/* 0 */
+/***/ function(module, exports, __webpack_require__) {
+
+    /*
+      Copyright JS Foundation and other contributors, https://js.foundation/
+
+      Redistribution and use in source and binary forms, with or without
+      modification, are permitted provided that the following conditions are met:
+
+        * Redistributions of source code must retain the above copyright
+          notice, this list of conditions and the following disclaimer.
+        * Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+
+      THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &quot;AS IS&quot;
+      AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+      IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+      ARE DISCLAIMED. IN NO EVENT SHALL &lt;COPYRIGHT HOLDER&gt; BE LIABLE FOR ANY
+      DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+      (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+      LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+      ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+      (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+      THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+    */
+    &quot;use strict&quot;;
+    var comment_handler_1 = __webpack_require__(1);
+    var parser_1 = __webpack_require__(3);
+    var jsx_parser_1 = __webpack_require__(11);
+    var tokenizer_1 = __webpack_require__(15);
+    function parse(code, options, delegate) {
+        var commentHandler = null;
+        var proxyDelegate = function (node, metadata) {
+            if (delegate) {
+                delegate(node, metadata);
+            }
+            if (commentHandler) {
+                commentHandler.visit(node, metadata);
+            }
+        };
+        var parserDelegate = (typeof delegate === 'function') ? proxyDelegate : null;
+        var collectComment = false;
+        if (options) {
+            collectComment = (typeof options.comment === 'boolean' &amp;&amp; options.comment);
+            var attachComment = (typeof options.attachComment === 'boolean' &amp;&amp; options.attachComment);
+            if (collectComment || attachComment) {
+                commentHandler = new comment_handler_1.CommentHandler();
+                commentHandler.attach = attachComment;
+                options.comment = true;
+                parserDelegate = proxyDelegate;
+            }
+        }
+        var isModule = false;
+        if (options &amp;&amp; typeof options.sourceType === 'string') {
+            isModule = (options.sourceType === 'module');
+        }
+        var parser;
+        if (options &amp;&amp; typeof options.jsx === 'boolean' &amp;&amp; options.jsx) {
+            parser = new jsx_parser_1.JSXParser(code, options, parserDelegate);
+        }
+        else {
+            parser = new parser_1.Parser(code, options, parserDelegate);
+        }
+        var program = isModule ? parser.parseModule() : parser.parseScript();
+        var ast = (program);
+        if (collectComment &amp;&amp; commentHandler) {
+            ast.comments = commentHandler.comments;
+        }
+        if (parser.config.tokens) {
+            ast.tokens = parser.tokens;
+        }
+        if (parser.config.tolerant) {
+            ast.errors = parser.errorHandler.errors;
+        }
+        return ast;
</ins><span class="cx">     }
</span><del>-}(this, function (exports) {
-    'use strict';
</del><ins>+    exports.parse = parse;
+    function parseModule(code, options, delegate) {
+        var parsingOptions = options || {};
+        parsingOptions.sourceType = 'module';
+        return parse(code, parsingOptions, delegate);
+    }
+    exports.parseModule = parseModule;
+    function parseScript(code, options, delegate) {
+        var parsingOptions = options || {};
+        parsingOptions.sourceType = 'script';
+        return parse(code, parsingOptions, delegate);
+    }
+    exports.parseScript = parseScript;
+    function tokenize(code, options, delegate) {
+        var tokenizer = new tokenizer_1.Tokenizer(code, options);
+        var tokens;
+        tokens = [];
+        try {
+            while (true) {
+                var token = tokenizer.getNextToken();
+                if (!token) {
+                    break;
+                }
+                if (delegate) {
+                    token = delegate(token);
+                }
+                tokens.push(token);
+            }
+        }
+        catch (e) {
+            tokenizer.errorHandler.tolerate(e);
+        }
+        if (tokenizer.errorHandler.tolerant) {
+            tokens.errors = tokenizer.errors();
+        }
+        return tokens;
+    }
+    exports.tokenize = tokenize;
+    var syntax_1 = __webpack_require__(2);
+    exports.Syntax = syntax_1.Syntax;
+    // Sync with *.json manifests.
+    exports.version = '4.0.0-dev';
</ins><span class="cx"> 
</span><del>-    var Token,
-        TokenName,
-        FnExprTokens,
-        Syntax,
-        PlaceHolders,
-        Messages,
-        Regex,
-        source,
-        strict,
-        index,
-        lineNumber,
-        lineStart,
-        hasLineTerminator,
-        lastIndex,
-        lastLineNumber,
-        lastLineStart,
-        startIndex,
-        startLineNumber,
-        startLineStart,
-        scanning,
-        length,
-        lookahead,
-        state,
-        extra,
-        isBindingElement,
-        isAssignmentTarget,
-        firstCoverInitializedNameError;
</del><span class="cx"> 
</span><del>-    Token = {
-        BooleanLiteral: 1,
-        EOF: 2,
-        Identifier: 3,
-        Keyword: 4,
-        NullLiteral: 5,
-        NumericLiteral: 6,
-        Punctuator: 7,
-        StringLiteral: 8,
-        RegularExpression: 9,
-        Template: 10
-    };
</del><ins>+/***/ },
+/* 1 */
+/***/ function(module, exports, __webpack_require__) {
</ins><span class="cx"> 
</span><del>-    TokenName = {};
-    TokenName[Token.BooleanLiteral] = 'Boolean';
-    TokenName[Token.EOF] = '&lt;end&gt;';
-    TokenName[Token.Identifier] = 'Identifier';
-    TokenName[Token.Keyword] = 'Keyword';
-    TokenName[Token.NullLiteral] = 'Null';
-    TokenName[Token.NumericLiteral] = 'Numeric';
-    TokenName[Token.Punctuator] = 'Punctuator';
-    TokenName[Token.StringLiteral] = 'String';
-    TokenName[Token.RegularExpression] = 'RegularExpression';
-    TokenName[Token.Template] = 'Template';
</del><ins>+    &quot;use strict&quot;;
+    var syntax_1 = __webpack_require__(2);
+    var CommentHandler = (function () {
+        function CommentHandler() {
+            this.attach = false;
+            this.comments = [];
+            this.stack = [];
+            this.leading = [];
+            this.trailing = [];
+        }
+        CommentHandler.prototype.insertInnerComments = function (node, metadata) {
+            //  innnerComments for properties empty block
+            //  `function a() {/** comments **\/}`
+            if (node.type === syntax_1.Syntax.BlockStatement &amp;&amp; node.body.length === 0) {
+                var innerComments = [];
+                for (var i = this.leading.length - 1; i &gt;= 0; --i) {
+                    var entry = this.leading[i];
+                    if (metadata.end.offset &gt;= entry.start) {
+                        innerComments.unshift(entry.comment);
+                        this.leading.splice(i, 1);
+                        this.trailing.splice(i, 1);
+                    }
+                }
+                if (innerComments.length) {
+                    node.innerComments = innerComments;
+                }
+            }
+        };
+        CommentHandler.prototype.findTrailingComments = function (metadata) {
+            var trailingComments = [];
+            if (this.trailing.length &gt; 0) {
+                for (var i = this.trailing.length - 1; i &gt;= 0; --i) {
+                    var entry_1 = this.trailing[i];
+                    if (entry_1.start &gt;= metadata.end.offset) {
+                        trailingComments.unshift(entry_1.comment);
+                    }
+                }
+                this.trailing.length = 0;
+                return trailingComments;
+            }
+            var entry = this.stack[this.stack.length - 1];
+            if (entry &amp;&amp; entry.node.trailingComments) {
+                var firstComment = entry.node.trailingComments[0];
+                if (firstComment &amp;&amp; firstComment.range[0] &gt;= metadata.end.offset) {
+                    trailingComments = entry.node.trailingComments;
+                    delete entry.node.trailingComments;
+                }
+            }
+            return trailingComments;
+        };
+        CommentHandler.prototype.findLeadingComments = function (metadata) {
+            var leadingComments = [];
+            var target;
+            while (this.stack.length &gt; 0) {
+                var entry = this.stack[this.stack.length - 1];
+                if (entry &amp;&amp; entry.start &gt;= metadata.start.offset) {
+                    target = entry.node;
+                    this.stack.pop();
+                }
+                else {
+                    break;
+                }
+            }
+            if (target) {
+                var count = target.leadingComments ? target.leadingComments.length : 0;
+                for (var i = count - 1; i &gt;= 0; --i) {
+                    var comment = target.leadingComments[i];
+                    if (comment.range[1] &lt;= metadata.start.offset) {
+                        leadingComments.unshift(comment);
+                        target.leadingComments.splice(i, 1);
+                    }
+                }
+                if (target.leadingComments &amp;&amp; target.leadingComments.length === 0) {
+                    delete target.leadingComments;
+                }
+                return leadingComments;
+            }
+            for (var i = this.leading.length - 1; i &gt;= 0; --i) {
+                var entry = this.leading[i];
+                if (entry.start &lt;= metadata.start.offset) {
+                    leadingComments.unshift(entry.comment);
+                    this.leading.splice(i, 1);
+                }
+            }
+            return leadingComments;
+        };
+        CommentHandler.prototype.visitNode = function (node, metadata) {
+            if (node.type === syntax_1.Syntax.Program &amp;&amp; node.body.length &gt; 0) {
+                return;
+            }
+            this.insertInnerComments(node, metadata);
+            var trailingComments = this.findTrailingComments(metadata);
+            var leadingComments = this.findLeadingComments(metadata);
+            if (leadingComments.length &gt; 0) {
+                node.leadingComments = leadingComments;
+            }
+            if (trailingComments.length &gt; 0) {
+                node.trailingComments = trailingComments;
+            }
+            this.stack.push({
+                node: node,
+                start: metadata.start.offset
+            });
+        };
+        CommentHandler.prototype.visitComment = function (node, metadata) {
+            var type = (node.type[0] === 'L') ? 'Line' : 'Block';
+            var comment = {
+                type: type,
+                value: node.value
+            };
+            if (node.range) {
+                comment.range = node.range;
+            }
+            if (node.loc) {
+                comment.loc = node.loc;
+            }
+            this.comments.push(comment);
+            if (this.attach) {
+                var entry = {
+                    comment: {
+                        type: type,
+                        value: node.value,
+                        range: [metadata.start.offset, metadata.end.offset]
+                    },
+                    start: metadata.start.offset
+                };
+                if (node.loc) {
+                    entry.comment.loc = node.loc;
+                }
+                node.type = type;
+                this.leading.push(entry);
+                this.trailing.push(entry);
+            }
+        };
+        CommentHandler.prototype.visit = function (node, metadata) {
+            if (node.type === 'LineComment') {
+                this.visitComment(node, metadata);
+            }
+            else if (node.type === 'BlockComment') {
+                this.visitComment(node, metadata);
+            }
+            else if (this.attach) {
+                this.visitNode(node, metadata);
+            }
+        };
+        return CommentHandler;
+    }());
+    exports.CommentHandler = CommentHandler;
</ins><span class="cx"> 
</span><del>-    // A function following one of those tokens is an expression.
-    FnExprTokens = ['(', '{', '[', 'in', 'typeof', 'instanceof', 'new',
-                    'return', 'case', 'delete', 'throw', 'void',
-                    // assignment operators
-                    '=', '+=', '-=', '*=', '/=', '%=', '&lt;&lt;=', '&gt;&gt;=', '&gt;&gt;&gt;=',
-                    '&amp;=', '|=', '^=', ',',
-                    // binary/unary operators
-                    '+', '-', '*', '/', '%', '++', '--', '&lt;&lt;', '&gt;&gt;', '&gt;&gt;&gt;', '&amp;',
-                    '|', '^', '!', '~', '&amp;&amp;', '||', '?', ':', '===', '==', '&gt;=',
-                    '&lt;=', '&lt;', '&gt;', '!=', '!=='];
</del><span class="cx"> 
</span><del>-    Syntax = {
</del><ins>+/***/ },
+/* 2 */
+/***/ function(module, exports) {
+
+    &quot;use strict&quot;;
+    exports.Syntax = {
</ins><span class="cx">         AssignmentExpression: 'AssignmentExpression',
</span><span class="cx">         AssignmentPattern: 'AssignmentPattern',
</span><span class="cx">         ArrayExpression: 'ArrayExpression',
</span><span class="cx">         ArrayPattern: 'ArrayPattern',
</span><span class="cx">         ArrowFunctionExpression: 'ArrowFunctionExpression',
</span><ins>+        AwaitExpression: 'AwaitExpression',
</ins><span class="cx">         BlockStatement: 'BlockStatement',
</span><span class="cx">         BinaryExpression: 'BinaryExpression',
</span><span class="cx">         BreakStatement: 'BreakStatement',
</span><span class="lines">@@ -171,13 +403,3117 @@
</span><span class="cx">         YieldExpression: 'YieldExpression'
</span><span class="cx">     };
</span><span class="cx"> 
</span><del>-    PlaceHolders = {
-        ArrowParameterPlaceHolder: 'ArrowParameterPlaceHolder'
-    };
</del><span class="cx"> 
</span><ins>+/***/ },
+/* 3 */
+/***/ function(module, exports, __webpack_require__) {
+
+    &quot;use strict&quot;;
+    var assert_1 = __webpack_require__(4);
+    var messages_1 = __webpack_require__(5);
+    var error_handler_1 = __webpack_require__(6);
+    var token_1 = __webpack_require__(7);
+    var scanner_1 = __webpack_require__(8);
+    var syntax_1 = __webpack_require__(2);
+    var Node = __webpack_require__(10);
+    var ArrowParameterPlaceHolder = 'ArrowParameterPlaceHolder';
+    var Parser = (function () {
+        function Parser(code, options, delegate) {
+            if (options === void 0) { options = {}; }
+            this.config = {
+                range: (typeof options.range === 'boolean') &amp;&amp; options.range,
+                loc: (typeof options.loc === 'boolean') &amp;&amp; options.loc,
+                source: null,
+                tokens: (typeof options.tokens === 'boolean') &amp;&amp; options.tokens,
+                comment: (typeof options.comment === 'boolean') &amp;&amp; options.comment,
+                tolerant: (typeof options.tolerant === 'boolean') &amp;&amp; options.tolerant
+            };
+            if (this.config.loc &amp;&amp; options.source &amp;&amp; options.source !== null) {
+                this.config.source = String(options.source);
+            }
+            this.delegate = delegate;
+            this.errorHandler = new error_handler_1.ErrorHandler();
+            this.errorHandler.tolerant = this.config.tolerant;
+            this.scanner = new scanner_1.Scanner(code, this.errorHandler);
+            this.scanner.trackComment = this.config.comment;
+            this.operatorPrecedence = {
+                ')': 0,
+                ';': 0,
+                ',': 0,
+                '=': 0,
+                ']': 0,
+                '||': 1,
+                '&amp;&amp;': 2,
+                '|': 3,
+                '^': 4,
+                '&amp;': 5,
+                '==': 6,
+                '!=': 6,
+                '===': 6,
+                '!==': 6,
+                '&lt;': 7,
+                '&gt;': 7,
+                '&lt;=': 7,
+                '&gt;=': 7,
+                '&lt;&lt;': 8,
+                '&gt;&gt;': 8,
+                '&gt;&gt;&gt;': 8,
+                '+': 9,
+                '-': 9,
+                '*': 11,
+                '/': 11,
+                '%': 11
+            };
+            this.lookahead = null;
+            this.hasLineTerminator = false;
+            this.context = {
+                isModule: false,
+                await: false,
+                allowIn: true,
+                allowYield: true,
+                firstCoverInitializedNameError: null,
+                isAssignmentTarget: false,
+                isBindingElement: false,
+                inFunctionBody: false,
+                inIteration: false,
+                inSwitch: false,
+                labelSet: {},
+                strict: false
+            };
+            this.tokens = [];
+            this.startMarker = {
+                index: 0,
+                lineNumber: this.scanner.lineNumber,
+                lineStart: 0
+            };
+            this.lastMarker = {
+                index: 0,
+                lineNumber: this.scanner.lineNumber,
+                lineStart: 0
+            };
+            this.nextToken();
+            this.lastMarker = {
+                index: this.scanner.index,
+                lineNumber: this.scanner.lineNumber,
+                lineStart: this.scanner.lineStart
+            };
+        }
+        Parser.prototype.throwError = function (messageFormat) {
+            var values = [];
+            for (var _i = 1; _i &lt; arguments.length; _i++) {
+                values[_i - 1] = arguments[_i];
+            }
+            var args = Array.prototype.slice.call(arguments, 1);
+            var msg = messageFormat.replace(/%(\d)/g, function (whole, idx) {
+                assert_1.assert(idx &lt; args.length, 'Message reference must be in range');
+                return args[idx];
+            });
+            var index = this.lastMarker.index;
+            var line = this.lastMarker.lineNumber;
+            var column = this.lastMarker.index - this.lastMarker.lineStart + 1;
+            throw this.errorHandler.createError(index, line, column, msg);
+        };
+        Parser.prototype.tolerateError = function (messageFormat) {
+            var values = [];
+            for (var _i = 1; _i &lt; arguments.length; _i++) {
+                values[_i - 1] = arguments[_i];
+            }
+            var args = Array.prototype.slice.call(arguments, 1);
+            var msg = messageFormat.replace(/%(\d)/g, function (whole, idx) {
+                assert_1.assert(idx &lt; args.length, 'Message reference must be in range');
+                return args[idx];
+            });
+            var index = this.lastMarker.index;
+            var line = this.scanner.lineNumber;
+            var column = this.lastMarker.index - this.lastMarker.lineStart + 1;
+            this.errorHandler.tolerateError(index, line, column, msg);
+        };
+        // Throw an exception because of the token.
+        Parser.prototype.unexpectedTokenError = function (token, message) {
+            var msg = message || messages_1.Messages.UnexpectedToken;
+            var value;
+            if (token) {
+                if (!message) {
+                    msg = (token.type === token_1.Token.EOF) ? messages_1.Messages.UnexpectedEOS :
+                        (token.type === token_1.Token.Identifier) ? messages_1.Messages.UnexpectedIdentifier :
+                            (token.type === token_1.Token.NumericLiteral) ? messages_1.Messages.UnexpectedNumber :
+                                (token.type === token_1.Token.StringLiteral) ? messages_1.Messages.UnexpectedString :
+                                    (token.type === token_1.Token.Template) ? messages_1.Messages.UnexpectedTemplate :
+                                        messages_1.Messages.UnexpectedToken;
+                    if (token.type === token_1.Token.Keyword) {
+                        if (this.scanner.isFutureReservedWord(token.value)) {
+                            msg = messages_1.Messages.UnexpectedReserved;
+                        }
+                        else if (this.context.strict &amp;&amp; this.scanner.isStrictModeReservedWord(token.value)) {
+                            msg = messages_1.Messages.StrictReservedWord;
+                        }
+                    }
+                }
+                value = (token.type === token_1.Token.Template) ? token.value.raw : token.value;
+            }
+            else {
+                value = 'ILLEGAL';
+            }
+            msg = msg.replace('%0', value);
+            if (token &amp;&amp; typeof token.lineNumber === 'number') {
+                var index = token.start;
+                var line = token.lineNumber;
+                var column = token.start - this.lastMarker.lineStart + 1;
+                return this.errorHandler.createError(index, line, column, msg);
+            }
+            else {
+                var index = this.lastMarker.index;
+                var line = this.lastMarker.lineNumber;
+                var column = index - this.lastMarker.lineStart + 1;
+                return this.errorHandler.createError(index, line, column, msg);
+            }
+        };
+        Parser.prototype.throwUnexpectedToken = function (token, message) {
+            throw this.unexpectedTokenError(token, message);
+        };
+        Parser.prototype.tolerateUnexpectedToken = function (token, message) {
+            this.errorHandler.tolerate(this.unexpectedTokenError(token, message));
+        };
+        Parser.prototype.collectComments = function () {
+            if (!this.config.comment) {
+                this.scanner.scanComments();
+            }
+            else {
+                var comments = this.scanner.scanComments();
+                if (comments.length &gt; 0 &amp;&amp; this.delegate) {
+                    for (var i = 0; i &lt; comments.length; ++i) {
+                        var e = comments[i];
+                        var node = void 0;
+                        node = {
+                            type: e.multiLine ? 'BlockComment' : 'LineComment',
+                            value: this.scanner.source.slice(e.slice[0], e.slice[1])
+                        };
+                        if (this.config.range) {
+                            node.range = e.range;
+                        }
+                        if (this.config.loc) {
+                            node.loc = e.loc;
+                        }
+                        var metadata = {
+                            start: {
+                                line: e.loc.start.line,
+                                column: e.loc.start.column,
+                                offset: e.range[0]
+                            },
+                            end: {
+                                line: e.loc.end.line,
+                                column: e.loc.end.column,
+                                offset: e.range[1]
+                            }
+                        };
+                        this.delegate(node, metadata);
+                    }
+                }
+            }
+        };
+        // From internal representation to an external structure
+        Parser.prototype.getTokenRaw = function (token) {
+            return this.scanner.source.slice(token.start, token.end);
+        };
+        Parser.prototype.convertToken = function (token) {
+            var t;
+            t = {
+                type: token_1.TokenName[token.type],
+                value: this.getTokenRaw(token)
+            };
+            if (this.config.range) {
+                t.range = [token.start, token.end];
+            }
+            if (this.config.loc) {
+                t.loc = {
+                    start: {
+                        line: this.startMarker.lineNumber,
+                        column: this.startMarker.index - this.startMarker.lineStart
+                    },
+                    end: {
+                        line: this.scanner.lineNumber,
+                        column: this.scanner.index - this.scanner.lineStart
+                    }
+                };
+            }
+            if (token.regex) {
+                t.regex = token.regex;
+            }
+            return t;
+        };
+        Parser.prototype.nextToken = function () {
+            var token = this.lookahead;
+            this.lastMarker.index = this.scanner.index;
+            this.lastMarker.lineNumber = this.scanner.lineNumber;
+            this.lastMarker.lineStart = this.scanner.lineStart;
+            this.collectComments();
+            this.startMarker.index = this.scanner.index;
+            this.startMarker.lineNumber = this.scanner.lineNumber;
+            this.startMarker.lineStart = this.scanner.lineStart;
+            var next;
+            next = this.scanner.lex();
+            this.hasLineTerminator = (token &amp;&amp; next) ? (token.lineNumber !== next.lineNumber) : false;
+            if (next &amp;&amp; this.context.strict &amp;&amp; next.type === token_1.Token.Identifier) {
+                if (this.scanner.isStrictModeReservedWord(next.value)) {
+                    next.type = token_1.Token.Keyword;
+                }
+            }
+            this.lookahead = next;
+            if (this.config.tokens &amp;&amp; next.type !== token_1.Token.EOF) {
+                this.tokens.push(this.convertToken(next));
+            }
+            return token;
+        };
+        Parser.prototype.nextRegexToken = function () {
+            this.collectComments();
+            var token = this.scanner.scanRegExp();
+            if (this.config.tokens) {
+                // Pop the previous token, '/' or '/='
+                // This is added from the lookahead token.
+                this.tokens.pop();
+                this.tokens.push(this.convertToken(token));
+            }
+            // Prime the next lookahead.
+            this.lookahead = token;
+            this.nextToken();
+            return token;
+        };
+        Parser.prototype.createNode = function () {
+            return {
+                index: this.startMarker.index,
+                line: this.startMarker.lineNumber,
+                column: this.startMarker.index - this.startMarker.lineStart
+            };
+        };
+        Parser.prototype.startNode = function (token) {
+            return {
+                index: token.start,
+                line: token.lineNumber,
+                column: token.start - token.lineStart
+            };
+        };
+        Parser.prototype.finalize = function (meta, node) {
+            if (this.config.range) {
+                node.range = [meta.index, this.lastMarker.index];
+            }
+            if (this.config.loc) {
+                node.loc = {
+                    start: {
+                        line: meta.line,
+                        column: meta.column
+                    },
+                    end: {
+                        line: this.lastMarker.lineNumber,
+                        column: this.lastMarker.index - this.lastMarker.lineStart
+                    }
+                };
+                if (this.config.source) {
+                    node.loc.source = this.config.source;
+                }
+            }
+            if (this.delegate) {
+                var metadata = {
+                    start: {
+                        line: meta.line,
+                        column: meta.column,
+                        offset: meta.index
+                    },
+                    end: {
+                        line: this.lastMarker.lineNumber,
+                        column: this.lastMarker.index - this.lastMarker.lineStart,
+                        offset: this.lastMarker.index
+                    }
+                };
+                this.delegate(node, metadata);
+            }
+            return node;
+        };
+        // Expect the next token to match the specified punctuator.
+        // If not, an exception will be thrown.
+        Parser.prototype.expect = function (value) {
+            var token = this.nextToken();
+            if (token.type !== token_1.Token.Punctuator || token.value !== value) {
+                this.throwUnexpectedToken(token);
+            }
+        };
+        // Quietly expect a comma when in tolerant mode, otherwise delegates to expect().
+        Parser.prototype.expectCommaSeparator = function () {
+            if (this.config.tolerant) {
+                var token = this.lookahead;
+                if (token.type === token_1.Token.Punctuator &amp;&amp; token.value === ',') {
+                    this.nextToken();
+                }
+                else if (token.type === token_1.Token.Punctuator &amp;&amp; token.value === ';') {
+                    this.nextToken();
+                    this.tolerateUnexpectedToken(token);
+                }
+                else {
+                    this.tolerateUnexpectedToken(token, messages_1.Messages.UnexpectedToken);
+                }
+            }
+            else {
+                this.expect(',');
+            }
+        };
+        // Expect the next token to match the specified keyword.
+        // If not, an exception will be thrown.
+        Parser.prototype.expectKeyword = function (keyword) {
+            var token = this.nextToken();
+            if (token.type !== token_1.Token.Keyword || token.value !== keyword) {
+                this.throwUnexpectedToken(token);
+            }
+        };
+        // Return true if the next token matches the specified punctuator.
+        Parser.prototype.match = function (value) {
+            return this.lookahead.type === token_1.Token.Punctuator &amp;&amp; this.lookahead.value === value;
+        };
+        // Return true if the next token matches the specified keyword
+        Parser.prototype.matchKeyword = function (keyword) {
+            return this.lookahead.type === token_1.Token.Keyword &amp;&amp; this.lookahead.value === keyword;
+        };
+        // Return true if the next token matches the specified contextual keyword
+        // (where an identifier is sometimes a keyword depending on the context)
+        Parser.prototype.matchContextualKeyword = function (keyword) {
+            return this.lookahead.type === token_1.Token.Identifier &amp;&amp; this.lookahead.value === keyword;
+        };
+        // Return true if the next token is an assignment operator
+        Parser.prototype.matchAssign = function () {
+            if (this.lookahead.type !== token_1.Token.Punctuator) {
+                return false;
+            }
+            var op = this.lookahead.value;
+            return op === '=' ||
+                op === '*=' ||
+                op === '**=' ||
+                op === '/=' ||
+                op === '%=' ||
+                op === '+=' ||
+                op === '-=' ||
+                op === '&lt;&lt;=' ||
+                op === '&gt;&gt;=' ||
+                op === '&gt;&gt;&gt;=' ||
+                op === '&amp;=' ||
+                op === '^=' ||
+                op === '|=';
+        };
+        // Cover grammar support.
+        //
+        // When an assignment expression position starts with an left parenthesis, the determination of the type
+        // of the syntax is to be deferred arbitrarily long until the end of the parentheses pair (plus a lookahead)
+        // or the first comma. This situation also defers the determination of all the expressions nested in the pair.
+        //
+        // There are three productions that can be parsed in a parentheses pair that needs to be determined
+        // after the outermost pair is closed. They are:
+        //
+        //   1. AssignmentExpression
+        //   2. BindingElements
+        //   3. AssignmentTargets
+        //
+        // In order to avoid exponential backtracking, we use two flags to denote if the production can be
+        // binding element or assignment target.
+        //
+        // The three productions have the relationship:
+        //
+        //   BindingElements âŠ† AssignmentTargets âŠ† AssignmentExpression
+        //
+        // with a single exception that CoverInitializedName when used directly in an Expression, generates
+        // an early error. Therefore, we need the third state, firstCoverInitializedNameError, to track the
+        // first usage of CoverInitializedName and report it when we reached the end of the parentheses pair.
+        //
+        // isolateCoverGrammar function runs the given parser function with a new cover grammar context, and it does not
+        // effect the current flags. This means the production the parser parses is only used as an expression. Therefore
+        // the CoverInitializedName check is conducted.
+        //
+        // inheritCoverGrammar function runs the given parse function with a new cover grammar context, and it propagates
+        // the flags outside of the parser. This means the production the parser parses is used as a part of a potential
+        // pattern. The CoverInitializedName check is deferred.
+        Parser.prototype.isolateCoverGrammar = function (parseFunction) {
+            var previousIsBindingElement = this.context.isBindingElement;
+            var previousIsAssignmentTarget = this.context.isAssignmentTarget;
+            var previousFirstCoverInitializedNameError = this.context.firstCoverInitializedNameError;
+            this.context.isBindingElement = true;
+            this.context.isAssignmentTarget = true;
+            this.context.firstCoverInitializedNameError = null;
+            var result = parseFunction.call(this);
+            if (this.context.firstCoverInitializedNameError !== null) {
+                this.throwUnexpectedToken(this.context.firstCoverInitializedNameError);
+            }
+            this.context.isBindingElement = previousIsBindingElement;
+            this.context.isAssignmentTarget = previousIsAssignmentTarget;
+            this.context.firstCoverInitializedNameError = previousFirstCoverInitializedNameError;
+            return result;
+        };
+        Parser.prototype.inheritCoverGrammar = function (parseFunction) {
+            var previousIsBindingElement = this.context.isBindingElement;
+            var previousIsAssignmentTarget = this.context.isAssignmentTarget;
+            var previousFirstCoverInitializedNameError = this.context.firstCoverInitializedNameError;
+            this.context.isBindingElement = true;
+            this.context.isAssignmentTarget = true;
+            this.context.firstCoverInitializedNameError = null;
+            var result = parseFunction.call(this);
+            this.context.isBindingElement = this.context.isBindingElement &amp;&amp; previousIsBindingElement;
+            this.context.isAssignmentTarget = this.context.isAssignmentTarget &amp;&amp; previousIsAssignmentTarget;
+            this.context.firstCoverInitializedNameError = previousFirstCoverInitializedNameError || this.context.firstCoverInitializedNameError;
+            return result;
+        };
+        Parser.prototype.consumeSemicolon = function () {
+            if (this.match(';')) {
+                this.nextToken();
+            }
+            else if (!this.hasLineTerminator) {
+                if (this.lookahead.type !== token_1.Token.EOF &amp;&amp; !this.match('}')) {
+                    this.throwUnexpectedToken(this.lookahead);
+                }
+                this.lastMarker.index = this.startMarker.index;
+                this.lastMarker.lineNumber = this.startMarker.lineNumber;
+                this.lastMarker.lineStart = this.startMarker.lineStart;
+            }
+        };
+        // ECMA-262 12.2 Primary Expressions
+        Parser.prototype.parsePrimaryExpression = function () {
+            var node = this.createNode();
+            var expr;
+            var value, token, raw;
+            switch (this.lookahead.type) {
+                case token_1.Token.Identifier:
+                    if ((this.context.isModule || this.context.await) &amp;&amp; this.lookahead.value === 'await') {
+                        this.tolerateUnexpectedToken(this.lookahead);
+                    }
+                    expr = this.matchAsyncFunction() ? this.parseFunctionExpression() : this.finalize(node, new Node.Identifier(this.nextToken().value));
+                    break;
+                case token_1.Token.NumericLiteral:
+                case token_1.Token.StringLiteral:
+                    if (this.context.strict &amp;&amp; this.lookahead.octal) {
+                        this.tolerateUnexpectedToken(this.lookahead, messages_1.Messages.StrictOctalLiteral);
+                    }
+                    this.context.isAssignmentTarget = false;
+                    this.context.isBindingElement = false;
+                    token = this.nextToken();
+                    raw = this.getTokenRaw(token);
+                    expr = this.finalize(node, new Node.Literal(token.value, raw));
+                    break;
+                case token_1.Token.BooleanLiteral:
+                    this.context.isAssignmentTarget = false;
+                    this.context.isBindingElement = false;
+                    token = this.nextToken();
+                    token.value = (token.value === 'true');
+                    raw = this.getTokenRaw(token);
+                    expr = this.finalize(node, new Node.Literal(token.value, raw));
+                    break;
+                case token_1.Token.NullLiteral:
+                    this.context.isAssignmentTarget = false;
+                    this.context.isBindingElement = false;
+                    token = this.nextToken();
+                    token.value = null;
+                    raw = this.getTokenRaw(token);
+                    expr = this.finalize(node, new Node.Literal(token.value, raw));
+                    break;
+                case token_1.Token.Template:
+                    expr = this.parseTemplateLiteral();
+                    break;
+                case token_1.Token.Punctuator:
+                    value = this.lookahead.value;
+                    switch (value) {
+                        case '(':
+                            this.context.isBindingElement = false;
+                            expr = this.inheritCoverGrammar(this.parseGroupExpression);
+                            break;
+                        case '[':
+                            expr = this.inheritCoverGrammar(this.parseArrayInitializer);
+                            break;
+                        case '{':
+                            expr = this.inheritCoverGrammar(this.parseObjectInitializer);
+                            break;
+                        case '/':
+                        case '/=':
+                            this.context.isAssignmentTarget = false;
+                            this.context.isBindingElement = false;
+                            this.scanner.index = this.startMarker.index;
+                            token = this.nextRegexToken();
+                            raw = this.getTokenRaw(token);
+                            expr = this.finalize(node, new Node.RegexLiteral(token.value, raw, token.regex));
+                            break;
+                        default:
+                            expr = this.throwUnexpectedToken(this.nextToken());
+                    }
+                    break;
+                case token_1.Token.Keyword:
+                    if (!this.context.strict &amp;&amp; this.context.allowYield &amp;&amp; this.matchKeyword('yield')) {
+                        expr = this.parseIdentifierName();
+                    }
+                    else if (!this.context.strict &amp;&amp; this.matchKeyword('let')) {
+                        expr = this.finalize(node, new Node.Identifier(this.nextToken().value));
+                    }
+                    else {
+                        this.context.isAssignmentTarget = false;
+                        this.context.isBindingElement = false;
+                        if (this.matchKeyword('function')) {
+                            expr = this.parseFunctionExpression();
+                        }
+                        else if (this.matchKeyword('this')) {
+                            this.nextToken();
+                            expr = this.finalize(node, new Node.ThisExpression());
+                        }
+                        else if (this.matchKeyword('class')) {
+                            expr = this.parseClassExpression();
+                        }
+                        else {
+                            expr = this.throwUnexpectedToken(this.nextToken());
+                        }
+                    }
+                    break;
+                default:
+                    expr = this.throwUnexpectedToken(this.nextToken());
+            }
+            return expr;
+        };
+        // ECMA-262 12.2.5 Array Initializer
+        Parser.prototype.parseSpreadElement = function () {
+            var node = this.createNode();
+            this.expect('...');
+            var arg = this.inheritCoverGrammar(this.parseAssignmentExpression);
+            return this.finalize(node, new Node.SpreadElement(arg));
+        };
+        Parser.prototype.parseArrayInitializer = function () {
+            var node = this.createNode();
+            var elements = [];
+            this.expect('[');
+            while (!this.match(']')) {
+                if (this.match(',')) {
+                    this.nextToken();
+                    elements.push(null);
+                }
+                else if (this.match('...')) {
+                    var element = this.parseSpreadElement();
+                    if (!this.match(']')) {
+                        this.context.isAssignmentTarget = false;
+                        this.context.isBindingElement = false;
+                        this.expect(',');
+                    }
+                    elements.push(element);
+                }
+                else {
+                    elements.push(this.inheritCoverGrammar(this.parseAssignmentExpression));
+                    if (!this.match(']')) {
+                        this.expect(',');
+                    }
+                }
+            }
+            this.expect(']');
+            return this.finalize(node, new Node.ArrayExpression(elements));
+        };
+        // ECMA-262 12.2.6 Object Initializer
+        Parser.prototype.parsePropertyMethod = function (params) {
+            this.context.isAssignmentTarget = false;
+            this.context.isBindingElement = false;
+            var previousStrict = this.context.strict;
+            var body = this.isolateCoverGrammar(this.parseFunctionSourceElements);
+            if (this.context.strict &amp;&amp; params.firstRestricted) {
+                this.tolerateUnexpectedToken(params.firstRestricted, params.message);
+            }
+            if (this.context.strict &amp;&amp; params.stricted) {
+                this.tolerateUnexpectedToken(params.stricted, params.message);
+            }
+            this.context.strict = previousStrict;
+            return body;
+        };
+        Parser.prototype.parsePropertyMethodFunction = function () {
+            var isGenerator = false;
+            var node = this.createNode();
+            var previousAllowYield = this.context.allowYield;
+            this.context.allowYield = false;
+            var params = this.parseFormalParameters();
+            var method = this.parsePropertyMethod(params);
+            this.context.allowYield = previousAllowYield;
+            return this.finalize(node, new Node.FunctionExpression(null, params.params, method, isGenerator));
+        };
+        Parser.prototype.parsePropertyMethodAsyncFunction = function () {
+            var node = this.createNode();
+            var previousAllowYield = this.context.allowYield;
+            var previousAwait = this.context.await;
+            this.context.allowYield = false;
+            this.context.await = true;
+            var params = this.parseFormalParameters();
+            var method = this.parsePropertyMethod(params);
+            this.context.allowYield = previousAllowYield;
+            this.context.await = previousAwait;
+            return this.finalize(node, new Node.AsyncFunctionExpression(null, params.params, method));
+        };
+        Parser.prototype.parseObjectPropertyKey = function () {
+            var node = this.createNode();
+            var token = this.nextToken();
+            var key;
+            switch (token.type) {
+                case token_1.Token.StringLiteral:
+                case token_1.Token.NumericLiteral:
+                    if (this.context.strict &amp;&amp; token.octal) {
+                        this.tolerateUnexpectedToken(token, messages_1.Messages.StrictOctalLiteral);
+                    }
+                    var raw = this.getTokenRaw(token);
+                    key = this.finalize(node, new Node.Literal(token.value, raw));
+                    break;
+                case token_1.Token.Identifier:
+                case token_1.Token.BooleanLiteral:
+                case token_1.Token.NullLiteral:
+                case token_1.Token.Keyword:
+                    key = this.finalize(node, new Node.Identifier(token.value));
+                    break;
+                case token_1.Token.Punctuator:
+                    if (token.value === '[') {
+                        key = this.isolateCoverGrammar(this.parseAssignmentExpression);
+                        this.expect(']');
+                    }
+                    else {
+                        key = this.throwUnexpectedToken(token);
+                    }
+                    break;
+                default:
+                    key = this.throwUnexpectedToken(token);
+            }
+            return key;
+        };
+        Parser.prototype.isPropertyKey = function (key, value) {
+            return (key.type === syntax_1.Syntax.Identifier &amp;&amp; key.name === value) ||
+                (key.type === syntax_1.Syntax.Literal &amp;&amp; key.value === value);
+        };
+        Parser.prototype.parseObjectProperty = function (hasProto) {
+            var node = this.createNode();
+            var token = this.lookahead;
+            var kind;
+            var key = null;
+            var value = null;
+            var computed = false;
+            var method = false;
+            var shorthand = false;
+            var isAsync = false;
+            if (token.type === token_1.Token.Identifier) {
+                var id = token.value;
+                this.nextToken();
+                if (id === 'async' &amp;&amp; !this.hasLineTerminator) {
+                    computed = this.match('[');
+                    if (computed) {
+                        isAsync = true;
+                        key = this.parseObjectPropertyKey();
+                    }
+                    else {
+                        var punctuator = this.lookahead.value;
+                        if (punctuator !== ':' &amp;&amp; punctuator !== '(' &amp;&amp; punctuator !== '*') {
+                            isAsync = true;
+                            token = this.lookahead;
+                            id = token.value;
+                            this.nextToken();
+                        }
+                        key = this.finalize(node, new Node.Identifier(id));
+                    }
+                }
+                else {
+                    key = this.finalize(node, new Node.Identifier(id));
+                }
+            }
+            else if (this.match('*')) {
+                this.nextToken();
+            }
+            else {
+                computed = this.match('[');
+                key = this.parseObjectPropertyKey();
+            }
+            var lookaheadPropertyKey = this.qualifiedPropertyName(this.lookahead);
+            if (token.type === token_1.Token.Identifier &amp;&amp; !isAsync &amp;&amp; token.value === 'get' &amp;&amp; lookaheadPropertyKey) {
+                kind = 'get';
+                computed = this.match('[');
+                key = this.parseObjectPropertyKey();
+                this.context.allowYield = false;
+                value = this.parseGetterMethod();
+            }
+            else if (token.type === token_1.Token.Identifier &amp;&amp; !isAsync &amp;&amp; token.value === 'set' &amp;&amp; lookaheadPropertyKey) {
+                kind = 'set';
+                computed = this.match('[');
+                key = this.parseObjectPropertyKey();
+                value = this.parseSetterMethod();
+            }
+            else if (token.type === token_1.Token.Punctuator &amp;&amp; token.value === '*' &amp;&amp; lookaheadPropertyKey) {
+                kind = 'init';
+                computed = this.match('[');
+                key = this.parseObjectPropertyKey();
+                value = this.parseGeneratorMethod();
+                method = true;
+            }
+            else {
+                if (!key) {
+                    this.throwUnexpectedToken(this.lookahead);
+                }
+                kind = 'init';
+                if (this.match(':') &amp;&amp; !isAsync) {
+                    if (!computed &amp;&amp; this.isPropertyKey(key, '__proto__')) {
+                        if (hasProto.value) {
+                            this.tolerateError(messages_1.Messages.DuplicateProtoProperty);
+                        }
+                        hasProto.value = true;
+                    }
+                    this.nextToken();
+                    value = this.inheritCoverGrammar(this.parseAssignmentExpression);
+                }
+                else if (this.match('(')) {
+                    value = isAsync ? this.parsePropertyMethodAsyncFunction() : this.parsePropertyMethodFunction();
+                    method = true;
+                }
+                else if (token.type === token_1.Token.Identifier) {
+                    var id = this.finalize(node, new Node.Identifier(token.value));
+                    if (this.match('=')) {
+                        this.context.firstCoverInitializedNameError = this.lookahead;
+                        this.nextToken();
+                        shorthand = true;
+                        var init = this.isolateCoverGrammar(this.parseAssignmentExpression);
+                        value = this.finalize(node, new Node.AssignmentPattern(id, init));
+                    }
+                    else {
+                        shorthand = true;
+                        value = id;
+                    }
+                }
+                else {
+                    this.throwUnexpectedToken(this.nextToken());
+                }
+            }
+            return this.finalize(node, new Node.Property(kind, (key), computed, value, method, shorthand));
+        };
+        Parser.prototype.parseObjectInitializer = function () {
+            var node = this.createNode();
+            this.expect('{');
+            var properties = [];
+            var hasProto = { value: false };
+            while (!this.match('}')) {
+                properties.push(this.parseObjectProperty(hasProto));
+                if (!this.match('}')) {
+                    this.expectCommaSeparator();
+                }
+            }
+            this.expect('}');
+            return this.finalize(node, new Node.ObjectExpression(properties));
+        };
+        // ECMA-262 12.2.9 Template Literals
+        Parser.prototype.parseTemplateHead = function () {
+            assert_1.assert(this.lookahead.head, 'Template literal must start with a template head');
+            var node = this.createNode();
+            var token = this.nextToken();
+            var value = {
+                raw: token.value.raw,
+                cooked: token.value.cooked
+            };
+            return this.finalize(node, new Node.TemplateElement(value, token.tail));
+        };
+        Parser.prototype.parseTemplateElement = function () {
+            if (this.lookahead.type !== token_1.Token.Template) {
+                this.throwUnexpectedToken();
+            }
+            var node = this.createNode();
+            var token = this.nextToken();
+            var value = {
+                raw: token.value.raw,
+                cooked: token.value.cooked
+            };
+            return this.finalize(node, new Node.TemplateElement(value, token.tail));
+        };
+        Parser.prototype.parseTemplateLiteral = function () {
+            var node = this.createNode();
+            var expressions = [];
+            var quasis = [];
+            var quasi = this.parseTemplateHead();
+            quasis.push(quasi);
+            while (!quasi.tail) {
+                expressions.push(this.parseExpression());
+                quasi = this.parseTemplateElement();
+                quasis.push(quasi);
+            }
+            return this.finalize(node, new Node.TemplateLiteral(quasis, expressions));
+        };
+        // ECMA-262 12.2.10 The Grouping Operator
+        Parser.prototype.reinterpretExpressionAsPattern = function (expr) {
+            switch (expr.type) {
+                case syntax_1.Syntax.Identifier:
+                case syntax_1.Syntax.MemberExpression:
+                case syntax_1.Syntax.RestElement:
+                case syntax_1.Syntax.AssignmentPattern:
+                    break;
+                case syntax_1.Syntax.SpreadElement:
+                    expr.type = syntax_1.Syntax.RestElement;
+                    this.reinterpretExpressionAsPattern(expr.argument);
+                    break;
+                case syntax_1.Syntax.ArrayExpression:
+                    expr.type = syntax_1.Syntax.ArrayPattern;
+                    for (var i = 0; i &lt; expr.elements.length; i++) {
+                        if (expr.elements[i] !== null) {
+                            this.reinterpretExpressionAsPattern(expr.elements[i]);
+                        }
+                    }
+                    break;
+                case syntax_1.Syntax.ObjectExpression:
+                    expr.type = syntax_1.Syntax.ObjectPattern;
+                    for (var i = 0; i &lt; expr.properties.length; i++) {
+                        this.reinterpretExpressionAsPattern(expr.properties[i].value);
+                    }
+                    break;
+                case syntax_1.Syntax.AssignmentExpression:
+                    expr.type = syntax_1.Syntax.AssignmentPattern;
+                    delete expr.operator;
+                    this.reinterpretExpressionAsPattern(expr.left);
+                    break;
+                default:
+                    // Allow other node type for tolerant parsing.
+                    break;
+            }
+        };
+        Parser.prototype.parseGroupExpression = function () {
+            var expr;
+            this.expect('(');
+            if (this.match(')')) {
+                this.nextToken();
+                if (!this.match('=&gt;')) {
+                    this.expect('=&gt;');
+                }
+                expr = {
+                    type: ArrowParameterPlaceHolder,
+                    params: [],
+                    async: false
+                };
+            }
+            else {
+                var startToken = this.lookahead;
+                var params = [];
+                if (this.match('...')) {
+                    expr = this.parseRestElement(params);
+                    this.expect(')');
+                    if (!this.match('=&gt;')) {
+                        this.expect('=&gt;');
+                    }
+                    expr = {
+                        type: ArrowParameterPlaceHolder,
+                        params: [expr],
+                        async: false
+                    };
+                }
+                else {
+                    var arrow = false;
+                    this.context.isBindingElement = true;
+                    expr = this.inheritCoverGrammar(this.parseAssignmentExpression);
+                    if (this.match(',')) {
+                        var expressions = [];
+                        this.context.isAssignmentTarget = false;
+                        expressions.push(expr);
+                        while (this.startMarker.index &lt; this.scanner.length) {
+                            if (!this.match(',')) {
+                                break;
+                            }
+                            this.nextToken();
+                            if (this.match(')')) {
+                                this.nextToken();
+                                for (var i = 0; i &lt; expressions.length; i++) {
+                                    this.reinterpretExpressionAsPattern(expressions[i]);
+                                }
+                                arrow = true;
+                                expr = {
+                                    type: ArrowParameterPlaceHolder,
+                                    params: expressions,
+                                    async: false
+                                };
+                            }
+                            else if (this.match('...')) {
+                                if (!this.context.isBindingElement) {
+                                    this.throwUnexpectedToken(this.lookahead);
+                                }
+                                expressions.push(this.parseRestElement(params));
+                                this.expect(')');
+                                if (!this.match('=&gt;')) {
+                                    this.expect('=&gt;');
+                                }
+                                this.context.isBindingElement = false;
+                                for (var i = 0; i &lt; expressions.length; i++) {
+                                    this.reinterpretExpressionAsPattern(expressions[i]);
+                                }
+                                arrow = true;
+                                expr = {
+                                    type: ArrowParameterPlaceHolder,
+                                    params: expressions,
+                                    async: false
+                                };
+                            }
+                            else {
+                                expressions.push(this.inheritCoverGrammar(this.parseAssignmentExpression));
+                            }
+                            if (arrow) {
+                                break;
+                            }
+                        }
+                        if (!arrow) {
+                            expr = this.finalize(this.startNode(startToken), new Node.SequenceExpression(expressions));
+                        }
+                    }
+                    if (!arrow) {
+                        this.expect(')');
+                        if (this.match('=&gt;')) {
+                            if (expr.type === syntax_1.Syntax.Identifier &amp;&amp; expr.name === 'yield') {
+                                arrow = true;
+                                expr = {
+                                    type: ArrowParameterPlaceHolder,
+                                    params: [expr],
+                                    async: false
+                                };
+                            }
+                            if (!arrow) {
+                                if (!this.context.isBindingElement) {
+                                    this.throwUnexpectedToken(this.lookahead);
+                                }
+                                if (expr.type === syntax_1.Syntax.SequenceExpression) {
+                                    for (var i = 0; i &lt; expr.expressions.length; i++) {
+                                        this.reinterpretExpressionAsPattern(expr.expressions[i]);
+                                    }
+                                }
+                                else {
+                                    this.reinterpretExpressionAsPattern(expr);
+                                }
+                                var params_1 = (expr.type === syntax_1.Syntax.SequenceExpression ? expr.expressions : [expr]);
+                                expr = {
+                                    type: ArrowParameterPlaceHolder,
+                                    params: params_1,
+                                    async: false
+                                };
+                            }
+                        }
+                        this.context.isBindingElement = false;
+                    }
+                }
+            }
+            return expr;
+        };
+        // ECMA-262 12.3 Left-Hand-Side Expressions
+        Parser.prototype.parseArguments = function () {
+            this.expect('(');
+            var args = [];
+            if (!this.match(')')) {
+                while (true) {
+                    var expr = this.match('...') ? this.parseSpreadElement() :
+                        this.isolateCoverGrammar(this.parseAssignmentExpression);
+                    args.push(expr);
+                    if (this.match(')')) {
+                        break;
+                    }
+                    this.expectCommaSeparator();
+                    if (this.match(')')) {
+                        break;
+                    }
+                }
+            }
+            this.expect(')');
+            return args;
+        };
+        Parser.prototype.isIdentifierName = function (token) {
+            return token.type === token_1.Token.Identifier ||
+                token.type === token_1.Token.Keyword ||
+                token.type === token_1.Token.BooleanLiteral ||
+                token.type === token_1.Token.NullLiteral;
+        };
+        Parser.prototype.parseIdentifierName = function () {
+            var node = this.createNode();
+            var token = this.nextToken();
+            if (!this.isIdentifierName(token)) {
+                this.throwUnexpectedToken(token);
+            }
+            return this.finalize(node, new Node.Identifier(token.value));
+        };
+        Parser.prototype.parseNewExpression = function () {
+            var node = this.createNode();
+            var id = this.parseIdentifierName();
+            assert_1.assert(id.name === 'new', 'New expression must start with `new`');
+            var expr;
+            if (this.match('.')) {
+                this.nextToken();
+                if (this.lookahead.type === token_1.Token.Identifier &amp;&amp; this.context.inFunctionBody &amp;&amp; this.lookahead.value === 'target') {
+                    var property = this.parseIdentifierName();
+                    expr = new Node.MetaProperty(id, property);
+                }
+                else {
+                    this.throwUnexpectedToken(this.lookahead);
+                }
+            }
+            else {
+                var callee = this.isolateCoverGrammar(this.parseLeftHandSideExpression);
+                var args = this.match('(') ? this.parseArguments() : [];
+                expr = new Node.NewExpression(callee, args);
+                this.context.isAssignmentTarget = false;
+                this.context.isBindingElement = false;
+            }
+            return this.finalize(node, expr);
+        };
+        Parser.prototype.parseAsyncArgument = function () {
+            var arg = this.parseAssignmentExpression();
+            this.context.firstCoverInitializedNameError = null;
+            return arg;
+        };
+        Parser.prototype.parseAsyncArguments = function () {
+            this.expect('(');
+            var args = [];
+            if (!this.match(')')) {
+                while (true) {
+                    var expr = this.match('...') ? this.parseSpreadElement() :
+                        this.isolateCoverGrammar(this.parseAsyncArgument);
+                    args.push(expr);
+                    if (this.match(')')) {
+                        break;
+                    }
+                    this.expectCommaSeparator();
+                    if (this.match(')')) {
+                        break;
+                    }
+                }
+            }
+            this.expect(')');
+            return args;
+        };
+        Parser.prototype.parseLeftHandSideExpressionAllowCall = function () {
+            var startToken = this.lookahead;
+            var maybeAsync = this.matchContextualKeyword('async');
+            var previousAllowIn = this.context.allowIn;
+            this.context.allowIn = true;
+            var expr;
+            if (this.matchKeyword('super') &amp;&amp; this.context.inFunctionBody) {
+                expr = this.createNode();
+                this.nextToken();
+                expr = this.finalize(expr, new Node.Super());
+                if (!this.match('(') &amp;&amp; !this.match('.') &amp;&amp; !this.match('[')) {
+                    this.throwUnexpectedToken(this.lookahead);
+                }
+            }
+            else {
+                expr = this.inheritCoverGrammar(this.matchKeyword('new') ? this.parseNewExpression : this.parsePrimaryExpression);
+            }
+            while (true) {
+                if (this.match('.')) {
+                    this.context.isBindingElement = false;
+                    this.context.isAssignmentTarget = true;
+                    this.expect('.');
+                    var property = this.parseIdentifierName();
+                    expr = this.finalize(this.startNode(startToken), new Node.StaticMemberExpression(expr, property));
+                }
+                else if (this.match('(')) {
+                    var asyncArrow = maybeAsync &amp;&amp; (startToken.lineNumber === this.lookahead.lineNumber);
+                    this.context.isBindingElement = false;
+                    this.context.isAssignmentTarget = false;
+                    var args = asyncArrow ? this.parseAsyncArguments() : this.parseArguments();
+                    expr = this.finalize(this.startNode(startToken), new Node.CallExpression(expr, args));
+                    if (asyncArrow &amp;&amp; this.match('=&gt;')) {
+                        expr = {
+                            type: ArrowParameterPlaceHolder,
+                            params: args,
+                            async: true
+                        };
+                    }
+                }
+                else if (this.match('[')) {
+                    this.context.isBindingElement = false;
+                    this.context.isAssignmentTarget = true;
+                    this.expect('[');
+                    var property = this.isolateCoverGrammar(this.parseExpression);
+                    this.expect(']');
+                    expr = this.finalize(this.startNode(startToken), new Node.ComputedMemberExpression(expr, property));
+                }
+                else if (this.lookahead.type === token_1.Token.Template &amp;&amp; this.lookahead.head) {
+                    var quasi = this.parseTemplateLiteral();
+                    expr = this.finalize(this.startNode(startToken), new Node.TaggedTemplateExpression(expr, quasi));
+                }
+                else {
+                    break;
+                }
+            }
+            this.context.allowIn = previousAllowIn;
+            return expr;
+        };
+        Parser.prototype.parseSuper = function () {
+            var node = this.createNode();
+            this.expectKeyword('super');
+            if (!this.match('[') &amp;&amp; !this.match('.')) {
+                this.throwUnexpectedToken(this.lookahead);
+            }
+            return this.finalize(node, new Node.Super());
+        };
+        Parser.prototype.parseLeftHandSideExpression = function () {
+            assert_1.assert(this.context.allowIn, 'callee of new expression always allow in keyword.');
+            var node = this.startNode(this.lookahead);
+            var expr = (this.matchKeyword('super') &amp;&amp; this.context.inFunctionBody) ? this.parseSuper() :
+                this.inheritCoverGrammar(this.matchKeyword('new') ? this.parseNewExpression : this.parsePrimaryExpression);
+            while (true) {
+                if (this.match('[')) {
+                    this.context.isBindingElement = false;
+                    this.context.isAssignmentTarget = true;
+                    this.expect('[');
+                    var property = this.isolateCoverGrammar(this.parseExpression);
+                    this.expect(']');
+                    expr = this.finalize(node, new Node.ComputedMemberExpression(expr, property));
+                }
+                else if (this.match('.')) {
+                    this.context.isBindingElement = false;
+                    this.context.isAssignmentTarget = true;
+                    this.expect('.');
+                    var property = this.parseIdentifierName();
+                    expr = this.finalize(node, new Node.StaticMemberExpression(expr, property));
+                }
+                else if (this.lookahead.type === token_1.Token.Template &amp;&amp; this.lookahead.head) {
+                    var quasi = this.parseTemplateLiteral();
+                    expr = this.finalize(node, new Node.TaggedTemplateExpression(expr, quasi));
+                }
+                else {
+                    break;
+                }
+            }
+            return expr;
+        };
+        // ECMA-262 12.4 Update Expressions
+        Parser.prototype.parseUpdateExpression = function () {
+            var expr;
+            var startToken = this.lookahead;
+            if (this.match('++') || this.match('--')) {
+                var node = this.startNode(startToken);
+                var token = this.nextToken();
+                expr = this.inheritCoverGrammar(this.parseUnaryExpression);
+                if (this.context.strict &amp;&amp; expr.type === syntax_1.Syntax.Identifier &amp;&amp; this.scanner.isRestrictedWord(expr.name)) {
+                    this.tolerateError(messages_1.Messages.StrictLHSPrefix);
+                }
+                if (!this.context.isAssignmentTarget) {
+                    this.tolerateError(messages_1.Messages.InvalidLHSInAssignment);
+                }
+                var prefix = true;
+                expr = this.finalize(node, new Node.UpdateExpression(token.value, expr, prefix));
+                this.context.isAssignmentTarget = false;
+                this.context.isBindingElement = false;
+            }
+            else {
+                expr = this.inheritCoverGrammar(this.parseLeftHandSideExpressionAllowCall);
+                if (!this.hasLineTerminator &amp;&amp; this.lookahead.type === token_1.Token.Punctuator) {
+                    if (this.match('++') || this.match('--')) {
+                        if (this.context.strict &amp;&amp; expr.type === syntax_1.Syntax.Identifier &amp;&amp; this.scanner.isRestrictedWord(expr.name)) {
+                            this.tolerateError(messages_1.Messages.StrictLHSPostfix);
+                        }
+                        if (!this.context.isAssignmentTarget) {
+                            this.tolerateError(messages_1.Messages.InvalidLHSInAssignment);
+                        }
+                        this.context.isAssignmentTarget = false;
+                        this.context.isBindingElement = false;
+                        var operator = this.nextToken().value;
+                        var prefix = false;
+                        expr = this.finalize(this.startNode(startToken), new Node.UpdateExpression(operator, expr, prefix));
+                    }
+                }
+            }
+            return expr;
+        };
+        // ECMA-262 12.5 Unary Operators
+        Parser.prototype.parseAwaitExpression = function () {
+            var node = this.createNode();
+            this.nextToken();
+            var argument = this.parseUnaryExpression();
+            return this.finalize(node, new Node.AwaitExpression(argument));
+        };
+        Parser.prototype.parseUnaryExpression = function () {
+            var expr;
+            if (this.match('+') || this.match('-') || this.match('~') || this.match('!') ||
+                this.matchKeyword('delete') || this.matchKeyword('void') || this.matchKeyword('typeof')) {
+                var node = this.startNode(this.lookahead);
+                var token = this.nextToken();
+                expr = this.inheritCoverGrammar(this.parseUnaryExpression);
+                expr = this.finalize(node, new Node.UnaryExpression(token.value, expr));
+                if (this.context.strict &amp;&amp; expr.operator === 'delete' &amp;&amp; expr.argument.type === syntax_1.Syntax.Identifier) {
+                    this.tolerateError(messages_1.Messages.StrictDelete);
+                }
+                this.context.isAssignmentTarget = false;
+                this.context.isBindingElement = false;
+            }
+            else if (this.context.await &amp;&amp; this.matchContextualKeyword('await')) {
+                expr = this.parseAwaitExpression();
+            }
+            else {
+                expr = this.parseUpdateExpression();
+            }
+            return expr;
+        };
+        Parser.prototype.parseExponentiationExpression = function () {
+            var startToken = this.lookahead;
+            var expr = this.inheritCoverGrammar(this.parseUnaryExpression);
+            if (expr.type !== syntax_1.Syntax.UnaryExpression &amp;&amp; this.match('**')) {
+                this.nextToken();
+                this.context.isAssignmentTarget = false;
+                this.context.isBindingElement = false;
+                var left = expr;
+                var right = this.isolateCoverGrammar(this.parseExponentiationExpression);
+                expr = this.finalize(this.startNode(startToken), new Node.BinaryExpression('**', left, right));
+            }
+            return expr;
+        };
+        // ECMA-262 12.6 Exponentiation Operators
+        // ECMA-262 12.7 Multiplicative Operators
+        // ECMA-262 12.8 Additive Operators
+        // ECMA-262 12.9 Bitwise Shift Operators
+        // ECMA-262 12.10 Relational Operators
+        // ECMA-262 12.11 Equality Operators
+        // ECMA-262 12.12 Binary Bitwise Operators
+        // ECMA-262 12.13 Binary Logical Operators
+        Parser.prototype.binaryPrecedence = function (token) {
+            var op = token.value;
+            var precedence;
+            if (token.type === token_1.Token.Punctuator) {
+                precedence = this.operatorPrecedence[op] || 0;
+            }
+            else if (token.type === token_1.Token.Keyword) {
+                precedence = (op === 'instanceof' || (this.context.allowIn &amp;&amp; op === 'in')) ? 7 : 0;
+            }
+            else {
+                precedence = 0;
+            }
+            return precedence;
+        };
+        Parser.prototype.parseBinaryExpression = function () {
+            var startToken = this.lookahead;
+            var expr = this.inheritCoverGrammar(this.parseExponentiationExpression);
+            var token = this.lookahead;
+            var prec = this.binaryPrecedence(token);
+            if (prec &gt; 0) {
+                this.nextToken();
+                token.prec = prec;
+                this.context.isAssignmentTarget = false;
+                this.context.isBindingElement = false;
+                var markers = [startToken, this.lookahead];
+                var left = expr;
+                var right = this.isolateCoverGrammar(this.parseExponentiationExpression);
+                var stack = [left, token, right];
+                while (true) {
+                    prec = this.binaryPrecedence(this.lookahead);
+                    if (prec &lt;= 0) {
+                        break;
+                    }
+                    // Reduce: make a binary expression from the three topmost entries.
+                    while ((stack.length &gt; 2) &amp;&amp; (prec &lt;= stack[stack.length - 2].prec)) {
+                        right = stack.pop();
+                        var operator = stack.pop().value;
+                        left = stack.pop();
+                        markers.pop();
+                        var node = this.startNode(markers[markers.length - 1]);
+                        stack.push(this.finalize(node, new Node.BinaryExpression(operator, left, right)));
+                    }
+                    // Shift.
+                    token = this.nextToken();
+                    token.prec = prec;
+                    stack.push(token);
+                    markers.push(this.lookahead);
+                    stack.push(this.isolateCoverGrammar(this.parseExponentiationExpression));
+                }
+                // Final reduce to clean-up the stack.
+                var i = stack.length - 1;
+                expr = stack[i];
+                markers.pop();
+                while (i &gt; 1) {
+                    var node = this.startNode(markers.pop());
+                    expr = this.finalize(node, new Node.BinaryExpression(stack[i - 1].value, stack[i - 2], expr));
+                    i -= 2;
+                }
+            }
+            return expr;
+        };
+        // ECMA-262 12.14 Conditional Operator
+        Parser.prototype.parseConditionalExpression = function () {
+            var startToken = this.lookahead;
+            var expr = this.inheritCoverGrammar(this.parseBinaryExpression);
+            if (this.match('?')) {
+                this.nextToken();
+                var previousAllowIn = this.context.allowIn;
+                this.context.allowIn = true;
+                var consequent = this.isolateCoverGrammar(this.parseAssignmentExpression);
+                this.context.allowIn = previousAllowIn;
+                this.expect(':');
+                var alternate = this.isolateCoverGrammar(this.parseAssignmentExpression);
+                expr = this.finalize(this.startNode(startToken), new Node.ConditionalExpression(expr, consequent, alternate));
+                this.context.isAssignmentTarget = false;
+                this.context.isBindingElement = false;
+            }
+            return expr;
+        };
+        // ECMA-262 12.15 Assignment Operators
+        Parser.prototype.checkPatternParam = function (options, param) {
+            switch (param.type) {
+                case syntax_1.Syntax.Identifier:
+                    this.validateParam(options, param, param.name);
+                    break;
+                case syntax_1.Syntax.RestElement:
+                    this.checkPatternParam(options, param.argument);
+                    break;
+                case syntax_1.Syntax.AssignmentPattern:
+                    this.checkPatternParam(options, param.left);
+                    break;
+                case syntax_1.Syntax.ArrayPattern:
+                    for (var i = 0; i &lt; param.elements.length; i++) {
+                        if (param.elements[i] !== null) {
+                            this.checkPatternParam(options, param.elements[i]);
+                        }
+                    }
+                    break;
+                case syntax_1.Syntax.ObjectPattern:
+                    for (var i = 0; i &lt; param.properties.length; i++) {
+                        this.checkPatternParam(options, param.properties[i].value);
+                    }
+                    break;
+                default:
+                    break;
+            }
+        };
+        Parser.prototype.reinterpretAsCoverFormalsList = function (expr) {
+            var params = [expr];
+            var options;
+            var asyncArrow = false;
+            switch (expr.type) {
+                case syntax_1.Syntax.Identifier:
+                    break;
+                case ArrowParameterPlaceHolder:
+                    params = expr.params;
+                    asyncArrow = expr.async;
+                    break;
+                default:
+                    return null;
+            }
+            options = {
+                paramSet: {}
+            };
+            for (var i = 0; i &lt; params.length; ++i) {
+                var param = params[i];
+                if (param.type === syntax_1.Syntax.AssignmentPattern) {
+                    if (param.right.type === syntax_1.Syntax.YieldExpression) {
+                        if (param.right.argument) {
+                            this.throwUnexpectedToken(this.lookahead);
+                        }
+                        param.right.type = syntax_1.Syntax.Identifier;
+                        param.right.name = 'yield';
+                        delete param.right.argument;
+                        delete param.right.delegate;
+                    }
+                }
+                else if (asyncArrow &amp;&amp; param.type === syntax_1.Syntax.Identifier &amp;&amp; param.name === 'await') {
+                    this.throwUnexpectedToken(this.lookahead);
+                }
+                this.checkPatternParam(options, param);
+                params[i] = param;
+            }
+            if (this.context.strict || !this.context.allowYield) {
+                for (var i = 0; i &lt; params.length; ++i) {
+                    var param = params[i];
+                    if (param.type === syntax_1.Syntax.YieldExpression) {
+                        this.throwUnexpectedToken(this.lookahead);
+                    }
+                }
+            }
+            if (options.message === messages_1.Messages.StrictParamDupe) {
+                var token = this.context.strict ? options.stricted : options.firstRestricted;
+                this.throwUnexpectedToken(token, options.message);
+            }
+            return {
+                params: params,
+                stricted: options.stricted,
+                firstRestricted: options.firstRestricted,
+                message: options.message
+            };
+        };
+        Parser.prototype.parseAssignmentExpression = function () {
+            var expr;
+            if (!this.context.allowYield &amp;&amp; this.matchKeyword('yield')) {
+                expr = this.parseYieldExpression();
+            }
+            else {
+                var startToken = this.lookahead;
+                var token = startToken;
+                expr = this.parseConditionalExpression();
+                if (token.type === token_1.Token.Identifier &amp;&amp; (token.lineNumber === this.lookahead.lineNumber) &amp;&amp; token.value === 'async' &amp;&amp; (this.lookahead.type === token_1.Token.Identifier)) {
+                    var arg = this.parsePrimaryExpression();
+                    expr = {
+                        type: ArrowParameterPlaceHolder,
+                        params: [arg],
+                        async: true
+                    };
+                }
+                if (expr.type === ArrowParameterPlaceHolder || this.match('=&gt;')) {
+                    // ECMA-262 14.2 Arrow Function Definitions
+                    this.context.isAssignmentTarget = false;
+                    this.context.isBindingElement = false;
+                    var isAsync = expr.async;
+                    var list = this.reinterpretAsCoverFormalsList(expr);
+                    if (list) {
+                        if (this.hasLineTerminator) {
+                            this.tolerateUnexpectedToken(this.lookahead);
+                        }
+                        this.context.firstCoverInitializedNameError = null;
+                        var previousStrict = this.context.strict;
+                        var previousAllowYield = this.context.allowYield;
+                        var previousAwait = this.context.await;
+                        this.context.allowYield = true;
+                        this.context.await = isAsync;
+                        var node = this.startNode(startToken);
+                        this.expect('=&gt;');
+                        var body = this.match('{') ? this.parseFunctionSourceElements() :
+                            this.isolateCoverGrammar(this.parseAssignmentExpression);
+                        var expression = body.type !== syntax_1.Syntax.BlockStatement;
+                        if (this.context.strict &amp;&amp; list.firstRestricted) {
+                            this.throwUnexpectedToken(list.firstRestricted, list.message);
+                        }
+                        if (this.context.strict &amp;&amp; list.stricted) {
+                            this.tolerateUnexpectedToken(list.stricted, list.message);
+                        }
+                        expr = isAsync ? this.finalize(node, new Node.AsyncArrowFunctionExpression(list.params, body, expression)) :
+                            this.finalize(node, new Node.ArrowFunctionExpression(list.params, body, expression));
+                        this.context.strict = previousStrict;
+                        this.context.allowYield = previousAllowYield;
+                        this.context.await = previousAwait;
+                    }
+                }
+                else {
+                    if (this.matchAssign()) {
+                        if (!this.context.isAssignmentTarget) {
+                            this.tolerateError(messages_1.Messages.InvalidLHSInAssignment);
+                        }
+                        if (this.context.strict &amp;&amp; expr.type === syntax_1.Syntax.Identifier) {
+                            var id = (expr);
+                            if (this.scanner.isRestrictedWord(id.name)) {
+                                this.tolerateUnexpectedToken(token, messages_1.Messages.StrictLHSAssignment);
+                            }
+                            if (this.scanner.isStrictModeReservedWord(id.name)) {
+                                this.tolerateUnexpectedToken(token, messages_1.Messages.StrictReservedWord);
+                            }
+                        }
+                        if (!this.match('=')) {
+                            this.context.isAssignmentTarget = false;
+                            this.context.isBindingElement = false;
+                        }
+                        else {
+                            this.reinterpretExpressionAsPattern(expr);
+                        }
+                        token = this.nextToken();
+                        var right = this.isolateCoverGrammar(this.parseAssignmentExpression);
+                        expr = this.finalize(this.startNode(startToken), new Node.AssignmentExpression(token.value, expr, right));
+                        this.context.firstCoverInitializedNameError = null;
+                    }
+                }
+            }
+            return expr;
+        };
+        // ECMA-262 12.16 Comma Operator
+        Parser.prototype.parseExpression = function () {
+            var startToken = this.lookahead;
+            var expr = this.isolateCoverGrammar(this.parseAssignmentExpression);
+            if (this.match(',')) {
+                var expressions = [];
+                expressions.push(expr);
+                while (this.startMarker.index &lt; this.scanner.length) {
+                    if (!this.match(',')) {
+                        break;
+                    }
+                    this.nextToken();
+                    expressions.push(this.isolateCoverGrammar(this.parseAssignmentExpression));
+                }
+                expr = this.finalize(this.startNode(startToken), new Node.SequenceExpression(expressions));
+            }
+            return expr;
+        };
+        // ECMA-262 13.2 Block
+        Parser.prototype.parseStatementListItem = function () {
+            var statement;
+            this.context.isAssignmentTarget = true;
+            this.context.isBindingElement = true;
+            if (this.lookahead.type === token_1.Token.Keyword) {
+                switch (this.lookahead.value) {
+                    case 'export':
+                        if (!this.context.isModule) {
+                            this.tolerateUnexpectedToken(this.lookahead, messages_1.Messages.IllegalExportDeclaration);
+                        }
+                        statement = this.parseExportDeclaration();
+                        break;
+                    case 'import':
+                        if (!this.context.isModule) {
+                            this.tolerateUnexpectedToken(this.lookahead, messages_1.Messages.IllegalImportDeclaration);
+                        }
+                        statement = this.parseImportDeclaration();
+                        break;
+                    case 'const':
+                        statement = this.parseLexicalDeclaration({ inFor: false });
+                        break;
+                    case 'function':
+                        statement = this.parseFunctionDeclaration();
+                        break;
+                    case 'class':
+                        statement = this.parseClassDeclaration();
+                        break;
+                    case 'let':
+                        statement = this.isLexicalDeclaration() ? this.parseLexicalDeclaration({ inFor: false }) : this.parseStatement();
+                        break;
+                    default:
+                        statement = this.parseStatement();
+                        break;
+                }
+            }
+            else {
+                statement = this.parseStatement();
+            }
+            return statement;
+        };
+        Parser.prototype.parseBlock = function () {
+            var node = this.createNode();
+            this.expect('{');
+            var block = [];
+            while (true) {
+                if (this.match('}')) {
+                    break;
+                }
+                block.push(this.parseStatementListItem());
+            }
+            this.expect('}');
+            return this.finalize(node, new Node.BlockStatement(block));
+        };
+        // ECMA-262 13.3.1 Let and Const Declarations
+        Parser.prototype.parseLexicalBinding = function (kind, options) {
+            var node = this.createNode();
+            var params = [];
+            var id = this.parsePattern(params, kind);
+            // ECMA-262 12.2.1
+            if (this.context.strict &amp;&amp; id.type === syntax_1.Syntax.Identifier) {
+                if (this.scanner.isRestrictedWord((id).name)) {
+                    this.tolerateError(messages_1.Messages.StrictVarName);
+                }
+            }
+            var init = null;
+            if (kind === 'const') {
+                if (!this.matchKeyword('in') &amp;&amp; !this.matchContextualKeyword('of')) {
+                    if (this.match('=')) {
+                        this.nextToken();
+                        init = this.isolateCoverGrammar(this.parseAssignmentExpression);
+                    }
+                    else {
+                        this.throwError(messages_1.Messages.DeclarationMissingInitializer, 'const');
+                    }
+                }
+            }
+            else if ((!options.inFor &amp;&amp; id.type !== syntax_1.Syntax.Identifier) || this.match('=')) {
+                this.expect('=');
+                init = this.isolateCoverGrammar(this.parseAssignmentExpression);
+            }
+            return this.finalize(node, new Node.VariableDeclarator(id, init));
+        };
+        Parser.prototype.parseBindingList = function (kind, options) {
+            var list = [this.parseLexicalBinding(kind, options)];
+            while (this.match(',')) {
+                this.nextToken();
+                list.push(this.parseLexicalBinding(kind, options));
+            }
+            return list;
+        };
+        Parser.prototype.isLexicalDeclaration = function () {
+            var previousIndex = this.scanner.index;
+            var previousLineNumber = this.scanner.lineNumber;
+            var previousLineStart = this.scanner.lineStart;
+            this.collectComments();
+            var next = this.scanner.lex();
+            this.scanner.index = previousIndex;
+            this.scanner.lineNumber = previousLineNumber;
+            this.scanner.lineStart = previousLineStart;
+            return (next.type === token_1.Token.Identifier) ||
+                (next.type === token_1.Token.Punctuator &amp;&amp; next.value === '[') ||
+                (next.type === token_1.Token.Punctuator &amp;&amp; next.value === '{') ||
+                (next.type === token_1.Token.Keyword &amp;&amp; next.value === 'let') ||
+                (next.type === token_1.Token.Keyword &amp;&amp; next.value === 'yield');
+        };
+        Parser.prototype.parseLexicalDeclaration = function (options) {
+            var node = this.createNode();
+            var kind = this.nextToken().value;
+            assert_1.assert(kind === 'let' || kind === 'const', 'Lexical declaration must be either let or const');
+            var declarations = this.parseBindingList(kind, options);
+            this.consumeSemicolon();
+            return this.finalize(node, new Node.VariableDeclaration(declarations, kind));
+        };
+        // ECMA-262 13.3.3 Destructuring Binding Patterns
+        Parser.prototype.parseBindingRestElement = function (params, kind) {
+            var node = this.createNode();
+            this.expect('...');
+            params.push(this.lookahead);
+            var arg = this.parseVariableIdentifier(kind);
+            return this.finalize(node, new Node.RestElement(arg));
+        };
+        Parser.prototype.parseArrayPattern = function (params, kind) {
+            var node = this.createNode();
+            this.expect('[');
+            var elements = [];
+            while (!this.match(']')) {
+                if (this.match(',')) {
+                    this.nextToken();
+                    elements.push(null);
+                }
+                else {
+                    if (this.match('...')) {
+                        elements.push(this.parseBindingRestElement(params, kind));
+                        break;
+                    }
+                    else {
+                        elements.push(this.parsePatternWithDefault(params, kind));
+                    }
+                    if (!this.match(']')) {
+                        this.expect(',');
+                    }
+                }
+            }
+            this.expect(']');
+            return this.finalize(node, new Node.ArrayPattern(elements));
+        };
+        Parser.prototype.parsePropertyPattern = function (params, kind) {
+            var node = this.createNode();
+            var computed = false;
+            var shorthand = false;
+            var method = false;
+            var key;
+            var value;
+            if (this.lookahead.type === token_1.Token.Identifier) {
+                var keyToken = this.lookahead;
+                key = this.parseVariableIdentifier();
+                var init = this.finalize(node, new Node.Identifier(keyToken.value));
+                if (this.match('=')) {
+                    params.push(keyToken);
+                    shorthand = true;
+                    this.nextToken();
+                    var expr = this.parseAssignmentExpression();
+                    value = this.finalize(this.startNode(keyToken), new Node.AssignmentPattern(init, expr));
+                }
+                else if (!this.match(':')) {
+                    params.push(keyToken);
+                    shorthand = true;
+                    value = init;
+                }
+                else {
+                    this.expect(':');
+                    value = this.parsePatternWithDefault(params, kind);
+                }
+            }
+            else {
+                computed = this.match('[');
+                key = this.parseObjectPropertyKey();
+                this.expect(':');
+                value = this.parsePatternWithDefault(params, kind);
+            }
+            return this.finalize(node, new Node.Property('init', key, computed, value, method, shorthand));
+        };
+        Parser.prototype.parseObjectPattern = function (params, kind) {
+            var node = this.createNode();
+            var properties = [];
+            this.expect('{');
+            while (!this.match('}')) {
+                properties.push(this.parsePropertyPattern(params, kind));
+                if (!this.match('}')) {
+                    this.expect(',');
+                }
+            }
+            this.expect('}');
+            return this.finalize(node, new Node.ObjectPattern(properties));
+        };
+        Parser.prototype.parsePattern = function (params, kind) {
+            var pattern;
+            if (this.match('[')) {
+                pattern = this.parseArrayPattern(params, kind);
+            }
+            else if (this.match('{')) {
+                pattern = this.parseObjectPattern(params, kind);
+            }
+            else {
+                if (this.matchKeyword('let') &amp;&amp; (kind === 'const' || kind === 'let')) {
+                    this.tolerateUnexpectedToken(this.lookahead, messages_1.Messages.LetInLexicalBinding);
+                }
+                params.push(this.lookahead);
+                pattern = this.parseVariableIdentifier(kind);
+            }
+            return pattern;
+        };
+        Parser.prototype.parsePatternWithDefault = function (params, kind) {
+            var startToken = this.lookahead;
+            var pattern = this.parsePattern(params, kind);
+            if (this.match('=')) {
+                this.nextToken();
+                var previousAllowYield = this.context.allowYield;
+                this.context.allowYield = true;
+                var right = this.isolateCoverGrammar(this.parseAssignmentExpression);
+                this.context.allowYield = previousAllowYield;
+                pattern = this.finalize(this.startNode(startToken), new Node.AssignmentPattern(pattern, right));
+            }
+            return pattern;
+        };
+        // ECMA-262 13.3.2 Variable Statement
+        Parser.prototype.parseVariableIdentifier = function (kind) {
+            var node = this.createNode();
+            var token = this.nextToken();
+            if (token.type === token_1.Token.Keyword &amp;&amp; token.value === 'yield') {
+                if (this.context.strict) {
+                    this.tolerateUnexpectedToken(token, messages_1.Messages.StrictReservedWord);
+                }
+                if (!this.context.allowYield) {
+                    this.throwUnexpectedToken(token);
+                }
+            }
+            else if (token.type !== token_1.Token.Identifier) {
+                if (this.context.strict &amp;&amp; token.type === token_1.Token.Keyword &amp;&amp; this.scanner.isStrictModeReservedWord(token.value)) {
+                    this.tolerateUnexpectedToken(token, messages_1.Messages.StrictReservedWord);
+                }
+                else {
+                    if (this.context.strict || token.value !== 'let' || kind !== 'var') {
+                        this.throwUnexpectedToken(token);
+                    }
+                }
+            }
+            else if ((this.context.isModule || this.context.await) &amp;&amp; token.type === token_1.Token.Identifier &amp;&amp; token.value === 'await') {
+                this.tolerateUnexpectedToken(token);
+            }
+            return this.finalize(node, new Node.Identifier(token.value));
+        };
+        Parser.prototype.parseVariableDeclaration = function (options) {
+            var node = this.createNode();
+            var params = [];
+            var id = this.parsePattern(params, 'var');
+            // ECMA-262 12.2.1
+            if (this.context.strict &amp;&amp; id.type === syntax_1.Syntax.Identifier) {
+                if (this.scanner.isRestrictedWord((id).name)) {
+                    this.tolerateError(messages_1.Messages.StrictVarName);
+                }
+            }
+            var init = null;
+            if (this.match('=')) {
+                this.nextToken();
+                init = this.isolateCoverGrammar(this.parseAssignmentExpression);
+            }
+            else if (id.type !== syntax_1.Syntax.Identifier &amp;&amp; !options.inFor) {
+                this.expect('=');
+            }
+            return this.finalize(node, new Node.VariableDeclarator(id, init));
+        };
+        Parser.prototype.parseVariableDeclarationList = function (options) {
+            var opt = { inFor: options.inFor };
+            var list = [];
+            list.push(this.parseVariableDeclaration(opt));
+            while (this.match(',')) {
+                this.nextToken();
+                list.push(this.parseVariableDeclaration(opt));
+            }
+            return list;
+        };
+        Parser.prototype.parseVariableStatement = function () {
+            var node = this.createNode();
+            this.expectKeyword('var');
+            var declarations = this.parseVariableDeclarationList({ inFor: false });
+            this.consumeSemicolon();
+            return this.finalize(node, new Node.VariableDeclaration(declarations, 'var'));
+        };
+        // ECMA-262 13.4 Empty Statement
+        Parser.prototype.parseEmptyStatement = function () {
+            var node = this.createNode();
+            this.expect(';');
+            return this.finalize(node, new Node.EmptyStatement());
+        };
+        // ECMA-262 13.5 Expression Statement
+        Parser.prototype.parseExpressionStatement = function () {
+            var node = this.createNode();
+            var expr = this.parseExpression();
+            this.consumeSemicolon();
+            return this.finalize(node, new Node.ExpressionStatement(expr));
+        };
+        // ECMA-262 13.6 If statement
+        Parser.prototype.parseIfStatement = function () {
+            var node = this.createNode();
+            var consequent;
+            var alternate = null;
+            this.expectKeyword('if');
+            this.expect('(');
+            var test = this.parseExpression();
+            if (!this.match(')') &amp;&amp; this.config.tolerant) {
+                this.tolerateUnexpectedToken(this.nextToken());
+                consequent = this.finalize(this.createNode(), new Node.EmptyStatement());
+            }
+            else {
+                this.expect(')');
+                consequent = this.parseStatement();
+                if (this.matchKeyword('else')) {
+                    this.nextToken();
+                    alternate = this.parseStatement();
+                }
+            }
+            return this.finalize(node, new Node.IfStatement(test, consequent, alternate));
+        };
+        // ECMA-262 13.7.2 The do-while Statement
+        Parser.prototype.parseDoWhileStatement = function () {
+            var node = this.createNode();
+            this.expectKeyword('do');
+            var previousInIteration = this.context.inIteration;
+            this.context.inIteration = true;
+            var body = this.parseStatement();
+            this.context.inIteration = previousInIteration;
+            this.expectKeyword('while');
+            this.expect('(');
+            var test = this.parseExpression();
+            this.expect(')');
+            if (this.match(';')) {
+                this.nextToken();
+            }
+            return this.finalize(node, new Node.DoWhileStatement(body, test));
+        };
+        // ECMA-262 13.7.3 The while Statement
+        Parser.prototype.parseWhileStatement = function () {
+            var node = this.createNode();
+            var body;
+            this.expectKeyword('while');
+            this.expect('(');
+            var test = this.parseExpression();
+            if (!this.match(')') &amp;&amp; this.config.tolerant) {
+                this.tolerateUnexpectedToken(this.nextToken());
+                body = this.finalize(this.createNode(), new Node.EmptyStatement());
+            }
+            else {
+                this.expect(')');
+                var previousInIteration = this.context.inIteration;
+                this.context.inIteration = true;
+                body = this.parseStatement();
+                this.context.inIteration = previousInIteration;
+            }
+            return this.finalize(node, new Node.WhileStatement(test, body));
+        };
+        // ECMA-262 13.7.4 The for Statement
+        // ECMA-262 13.7.5 The for-in and for-of Statements
+        Parser.prototype.parseForStatement = function () {
+            var init = null;
+            var test = null;
+            var update = null;
+            var forIn = true;
+            var left, right;
+            var node = this.createNode();
+            this.expectKeyword('for');
+            this.expect('(');
+            if (this.match(';')) {
+                this.nextToken();
+            }
+            else {
+                if (this.matchKeyword('var')) {
+                    init = this.createNode();
+                    this.nextToken();
+                    var previousAllowIn = this.context.allowIn;
+                    this.context.allowIn = false;
+                    var declarations = this.parseVariableDeclarationList({ inFor: true });
+                    this.context.allowIn = previousAllowIn;
+                    if (declarations.length === 1 &amp;&amp; this.matchKeyword('in')) {
+                        var decl = declarations[0];
+                        if (decl.init &amp;&amp; (decl.id.type === syntax_1.Syntax.ArrayPattern || decl.id.type === syntax_1.Syntax.ObjectPattern || this.context.strict)) {
+                            this.tolerateError(messages_1.Messages.ForInOfLoopInitializer, 'for-in');
+                        }
+                        init = this.finalize(init, new Node.VariableDeclaration(declarations, 'var'));
+                        this.nextToken();
+                        left = init;
+                        right = this.parseExpression();
+                        init = null;
+                    }
+                    else if (declarations.length === 1 &amp;&amp; declarations[0].init === null &amp;&amp; this.matchContextualKeyword('of')) {
+                        init = this.finalize(init, new Node.VariableDeclaration(declarations, 'var'));
+                        this.nextToken();
+                        left = init;
+                        right = this.parseAssignmentExpression();
+                        init = null;
+                        forIn = false;
+                    }
+                    else {
+                        init = this.finalize(init, new Node.VariableDeclaration(declarations, 'var'));
+                        this.expect(';');
+                    }
+                }
+                else if (this.matchKeyword('const') || this.matchKeyword('let')) {
+                    init = this.createNode();
+                    var kind = this.nextToken().value;
+                    if (!this.context.strict &amp;&amp; this.lookahead.value === 'in') {
+                        init = this.finalize(init, new Node.Identifier(kind));
+                        this.nextToken();
+                        left = init;
+                        right = this.parseExpression();
+                        init = null;
+                    }
+                    else {
+                        var previousAllowIn = this.context.allowIn;
+                        this.context.allowIn = false;
+                        var declarations = this.parseBindingList(kind, { inFor: true });
+                        this.context.allowIn = previousAllowIn;
+                        if (declarations.length === 1 &amp;&amp; declarations[0].init === null &amp;&amp; this.matchKeyword('in')) {
+                            init = this.finalize(init, new Node.VariableDeclaration(declarations, kind));
+                            this.nextToken();
+                            left = init;
+                            right = this.parseExpression();
+                            init = null;
+                        }
+                        else if (declarations.length === 1 &amp;&amp; declarations[0].init === null &amp;&amp; this.matchContextualKeyword('of')) {
+                            init = this.finalize(init, new Node.VariableDeclaration(declarations, kind));
+                            this.nextToken();
+                            left = init;
+                            right = this.parseAssignmentExpression();
+                            init = null;
+                            forIn = false;
+                        }
+                        else {
+                            this.consumeSemicolon();
+                            init = this.finalize(init, new Node.VariableDeclaration(declarations, kind));
+                        }
+                    }
+                }
+                else {
+                    var initStartToken = this.lookahead;
+                    var previousAllowIn = this.context.allowIn;
+                    this.context.allowIn = false;
+                    init = this.inheritCoverGrammar(this.parseAssignmentExpression);
+                    this.context.allowIn = previousAllowIn;
+                    if (this.matchKeyword('in')) {
+                        if (!this.context.isAssignmentTarget || init.type === syntax_1.Syntax.AssignmentExpression) {
+                            this.tolerateError(messages_1.Messages.InvalidLHSInForIn);
+                        }
+                        this.nextToken();
+                        this.reinterpretExpressionAsPattern(init);
+                        left = init;
+                        right = this.parseExpression();
+                        init = null;
+                    }
+                    else if (this.matchContextualKeyword('of')) {
+                        if (!this.context.isAssignmentTarget || init.type === syntax_1.Syntax.AssignmentExpression) {
+                            this.tolerateError(messages_1.Messages.InvalidLHSInForLoop);
+                        }
+                        this.nextToken();
+                        this.reinterpretExpressionAsPattern(init);
+                        left = init;
+                        right = this.parseAssignmentExpression();
+                        init = null;
+                        forIn = false;
+                    }
+                    else {
+                        if (this.match(',')) {
+                            var initSeq = [init];
+                            while (this.match(',')) {
+                                this.nextToken();
+                                initSeq.push(this.isolateCoverGrammar(this.parseAssignmentExpression));
+                            }
+                            init = this.finalize(this.startNode(initStartToken), new Node.SequenceExpression(initSeq));
+                        }
+                        this.expect(';');
+                    }
+                }
+            }
+            if (typeof left === 'undefined') {
+                if (!this.match(';')) {
+                    test = this.parseExpression();
+                }
+                this.expect(';');
+                if (!this.match(')')) {
+                    update = this.parseExpression();
+                }
+            }
+            var body;
+            if (!this.match(')') &amp;&amp; this.config.tolerant) {
+                this.tolerateUnexpectedToken(this.nextToken());
+                body = this.finalize(this.createNode(), new Node.EmptyStatement());
+            }
+            else {
+                this.expect(')');
+                var previousInIteration = this.context.inIteration;
+                this.context.inIteration = true;
+                body = this.isolateCoverGrammar(this.parseStatement);
+                this.context.inIteration = previousInIteration;
+            }
+            return (typeof left === 'undefined') ?
+                this.finalize(node, new Node.ForStatement(init, test, update, body)) :
+                forIn ? this.finalize(node, new Node.ForInStatement(left, right, body)) :
+                    this.finalize(node, new Node.ForOfStatement(left, right, body));
+        };
+        // ECMA-262 13.8 The continue statement
+        Parser.prototype.parseContinueStatement = function () {
+            var node = this.createNode();
+            this.expectKeyword('continue');
+            var label = null;
+            if (this.lookahead.type === token_1.Token.Identifier &amp;&amp; !this.hasLineTerminator) {
+                var id = this.parseVariableIdentifier();
+                label = id;
+                var key = '$' + id.name;
+                if (!Object.prototype.hasOwnProperty.call(this.context.labelSet, key)) {
+                    this.throwError(messages_1.Messages.UnknownLabel, id.name);
+                }
+            }
+            this.consumeSemicolon();
+            if (label === null &amp;&amp; !this.context.inIteration) {
+                this.throwError(messages_1.Messages.IllegalContinue);
+            }
+            return this.finalize(node, new Node.ContinueStatement(label));
+        };
+        // ECMA-262 13.9 The break statement
+        Parser.prototype.parseBreakStatement = function () {
+            var node = this.createNode();
+            this.expectKeyword('break');
+            var label = null;
+            if (this.lookahead.type === token_1.Token.Identifier &amp;&amp; !this.hasLineTerminator) {
+                var id = this.parseVariableIdentifier();
+                var key = '$' + id.name;
+                if (!Object.prototype.hasOwnProperty.call(this.context.labelSet, key)) {
+                    this.throwError(messages_1.Messages.UnknownLabel, id.name);
+                }
+                label = id;
+            }
+            this.consumeSemicolon();
+            if (label === null &amp;&amp; !this.context.inIteration &amp;&amp; !this.context.inSwitch) {
+                this.throwError(messages_1.Messages.IllegalBreak);
+            }
+            return this.finalize(node, new Node.BreakStatement(label));
+        };
+        // ECMA-262 13.10 The return statement
+        Parser.prototype.parseReturnStatement = function () {
+            if (!this.context.inFunctionBody) {
+                this.tolerateError(messages_1.Messages.IllegalReturn);
+            }
+            var node = this.createNode();
+            this.expectKeyword('return');
+            var hasArgument = !this.match(';') &amp;&amp; !this.match('}') &amp;&amp;
+                !this.hasLineTerminator &amp;&amp; this.lookahead.type !== token_1.Token.EOF;
+            var argument = hasArgument ? this.parseExpression() : null;
+            this.consumeSemicolon();
+            return this.finalize(node, new Node.ReturnStatement(argument));
+        };
+        // ECMA-262 13.11 The with statement
+        Parser.prototype.parseWithStatement = function () {
+            if (this.context.strict) {
+                this.tolerateError(messages_1.Messages.StrictModeWith);
+            }
+            var node = this.createNode();
+            this.expectKeyword('with');
+            this.expect('(');
+            var object = this.parseExpression();
+            this.expect(')');
+            var body = this.parseStatement();
+            return this.finalize(node, new Node.WithStatement(object, body));
+        };
+        // ECMA-262 13.12 The switch statement
+        Parser.prototype.parseSwitchCase = function () {
+            var node = this.createNode();
+            var test;
+            if (this.matchKeyword('default')) {
+                this.nextToken();
+                test = null;
+            }
+            else {
+                this.expectKeyword('case');
+                test = this.parseExpression();
+            }
+            this.expect(':');
+            var consequent = [];
+            while (true) {
+                if (this.match('}') || this.matchKeyword('default') || this.matchKeyword('case')) {
+                    break;
+                }
+                consequent.push(this.parseStatementListItem());
+            }
+            return this.finalize(node, new Node.SwitchCase(test, consequent));
+        };
+        Parser.prototype.parseSwitchStatement = function () {
+            var node = this.createNode();
+            this.expectKeyword('switch');
+            this.expect('(');
+            var discriminant = this.parseExpression();
+            this.expect(')');
+            var previousInSwitch = this.context.inSwitch;
+            this.context.inSwitch = true;
+            var cases = [];
+            var defaultFound = false;
+            this.expect('{');
+            while (true) {
+                if (this.match('}')) {
+                    break;
+                }
+                var clause = this.parseSwitchCase();
+                if (clause.test === null) {
+                    if (defaultFound) {
+                        this.throwError(messages_1.Messages.MultipleDefaultsInSwitch);
+                    }
+                    defaultFound = true;
+                }
+                cases.push(clause);
+            }
+            this.expect('}');
+            this.context.inSwitch = previousInSwitch;
+            return this.finalize(node, new Node.SwitchStatement(discriminant, cases));
+        };
+        // ECMA-262 13.13 Labelled Statements
+        Parser.prototype.parseLabelledStatement = function () {
+            var node = this.createNode();
+            var expr = this.parseExpression();
+            var statement;
+            if ((expr.type === syntax_1.Syntax.Identifier) &amp;&amp; this.match(':')) {
+                this.nextToken();
+                var id = (expr);
+                var key = '$' + id.name;
+                if (Object.prototype.hasOwnProperty.call(this.context.labelSet, key)) {
+                    this.throwError(messages_1.Messages.Redeclaration, 'Label', id.name);
+                }
+                this.context.labelSet[key] = true;
+                var labeledBody = this.parseStatement();
+                delete this.context.labelSet[key];
+                statement = new Node.LabeledStatement(id, labeledBody);
+            }
+            else {
+                this.consumeSemicolon();
+                statement = new Node.ExpressionStatement(expr);
+            }
+            return this.finalize(node, statement);
+        };
+        // ECMA-262 13.14 The throw statement
+        Parser.prototype.parseThrowStatement = function () {
+            var node = this.createNode();
+            this.expectKeyword('throw');
+            if (this.hasLineTerminator) {
+                this.throwError(messages_1.Messages.NewlineAfterThrow);
+            }
+            var argument = this.parseExpression();
+            this.consumeSemicolon();
+            return this.finalize(node, new Node.ThrowStatement(argument));
+        };
+        // ECMA-262 13.15 The try statement
+        Parser.prototype.parseCatchClause = function () {
+            var node = this.createNode();
+            this.expectKeyword('catch');
+            this.expect('(');
+            if (this.match(')')) {
+                this.throwUnexpectedToken(this.lookahead);
+            }
+            var params = [];
+            var param = this.parsePattern(params);
+            var paramMap = {};
+            for (var i = 0; i &lt; params.length; i++) {
+                var key = '$' + params[i].value;
+                if (Object.prototype.hasOwnProperty.call(paramMap, key)) {
+                    this.tolerateError(messages_1.Messages.DuplicateBinding, params[i].value);
+                }
+                paramMap[key] = true;
+            }
+            if (this.context.strict &amp;&amp; param.type === syntax_1.Syntax.Identifier) {
+                if (this.scanner.isRestrictedWord((param).name)) {
+                    this.tolerateError(messages_1.Messages.StrictCatchVariable);
+                }
+            }
+            this.expect(')');
+            var body = this.parseBlock();
+            return this.finalize(node, new Node.CatchClause(param, body));
+        };
+        Parser.prototype.parseFinallyClause = function () {
+            this.expectKeyword('finally');
+            return this.parseBlock();
+        };
+        Parser.prototype.parseTryStatement = function () {
+            var node = this.createNode();
+            this.expectKeyword('try');
+            var block = this.parseBlock();
+            var handler = this.matchKeyword('catch') ? this.parseCatchClause() : null;
+            var finalizer = this.matchKeyword('finally') ? this.parseFinallyClause() : null;
+            if (!handler &amp;&amp; !finalizer) {
+                this.throwError(messages_1.Messages.NoCatchOrFinally);
+            }
+            return this.finalize(node, new Node.TryStatement(block, handler, finalizer));
+        };
+        // ECMA-262 13.16 The debugger statement
+        Parser.prototype.parseDebuggerStatement = function () {
+            var node = this.createNode();
+            this.expectKeyword('debugger');
+            this.consumeSemicolon();
+            return this.finalize(node, new Node.DebuggerStatement());
+        };
+        // ECMA-262 13 Statements
+        Parser.prototype.parseStatement = function () {
+            var statement;
+            switch (this.lookahead.type) {
+                case token_1.Token.BooleanLiteral:
+                case token_1.Token.NullLiteral:
+                case token_1.Token.NumericLiteral:
+                case token_1.Token.StringLiteral:
+                case token_1.Token.Template:
+                case token_1.Token.RegularExpression:
+                    statement = this.parseExpressionStatement();
+                    break;
+                case token_1.Token.Punctuator:
+                    var value = this.lookahead.value;
+                    if (value === '{') {
+                        statement = this.parseBlock();
+                    }
+                    else if (value === '(') {
+                        statement = this.parseExpressionStatement();
+                    }
+                    else if (value === ';') {
+                        statement = this.parseEmptyStatement();
+                    }
+                    else {
+                        statement = this.parseExpressionStatement();
+                    }
+                    break;
+                case token_1.Token.Identifier:
+                    statement = this.matchAsyncFunction() ? this.parseFunctionDeclaration() : this.parseLabelledStatement();
+                    break;
+                case token_1.Token.Keyword:
+                    switch (this.lookahead.value) {
+                        case 'break':
+                            statement = this.parseBreakStatement();
+                            break;
+                        case 'continue':
+                            statement = this.parseContinueStatement();
+                            break;
+                        case 'debugger':
+                            statement = this.parseDebuggerStatement();
+                            break;
+                        case 'do':
+                            statement = this.parseDoWhileStatement();
+                            break;
+                        case 'for':
+                            statement = this.parseForStatement();
+                            break;
+                        case 'function':
+                            statement = this.parseFunctionDeclaration();
+                            break;
+                        case 'if':
+                            statement = this.parseIfStatement();
+                            break;
+                        case 'return':
+                            statement = this.parseReturnStatement();
+                            break;
+                        case 'switch':
+                            statement = this.parseSwitchStatement();
+                            break;
+                        case 'throw':
+                            statement = this.parseThrowStatement();
+                            break;
+                        case 'try':
+                            statement = this.parseTryStatement();
+                            break;
+                        case 'var':
+                            statement = this.parseVariableStatement();
+                            break;
+                        case 'while':
+                            statement = this.parseWhileStatement();
+                            break;
+                        case 'with':
+                            statement = this.parseWithStatement();
+                            break;
+                        default:
+                            statement = this.parseExpressionStatement();
+                            break;
+                    }
+                    break;
+                default:
+                    statement = this.throwUnexpectedToken(this.lookahead);
+            }
+            return statement;
+        };
+        // ECMA-262 14.1 Function Definition
+        Parser.prototype.parseFunctionSourceElements = function () {
+            var node = this.createNode();
+            this.expect('{');
+            var body = this.parseDirectivePrologues();
+            var previousLabelSet = this.context.labelSet;
+            var previousInIteration = this.context.inIteration;
+            var previousInSwitch = this.context.inSwitch;
+            var previousInFunctionBody = this.context.inFunctionBody;
+            this.context.labelSet = {};
+            this.context.inIteration = false;
+            this.context.inSwitch = false;
+            this.context.inFunctionBody = true;
+            while (this.startMarker.index &lt; this.scanner.length) {
+                if (this.match('}')) {
+                    break;
+                }
+                body.push(this.parseStatementListItem());
+            }
+            this.expect('}');
+            this.context.labelSet = previousLabelSet;
+            this.context.inIteration = previousInIteration;
+            this.context.inSwitch = previousInSwitch;
+            this.context.inFunctionBody = previousInFunctionBody;
+            return this.finalize(node, new Node.BlockStatement(body));
+        };
+        Parser.prototype.validateParam = function (options, param, name) {
+            var key = '$' + name;
+            if (this.context.strict) {
+                if (this.scanner.isRestrictedWord(name)) {
+                    options.stricted = param;
+                    options.message = messages_1.Messages.StrictParamName;
+                }
+                if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) {
+                    options.stricted = param;
+                    options.message = messages_1.Messages.StrictParamDupe;
+                }
+            }
+            else if (!options.firstRestricted) {
+                if (this.scanner.isRestrictedWord(name)) {
+                    options.firstRestricted = param;
+                    options.message = messages_1.Messages.StrictParamName;
+                }
+                else if (this.scanner.isStrictModeReservedWord(name)) {
+                    options.firstRestricted = param;
+                    options.message = messages_1.Messages.StrictReservedWord;
+                }
+                else if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) {
+                    options.stricted = param;
+                    options.message = messages_1.Messages.StrictParamDupe;
+                }
+            }
+            /* istanbul ignore next */
+            if (typeof Object.defineProperty === 'function') {
+                Object.defineProperty(options.paramSet, key, { value: true, enumerable: true, writable: true, configurable: true });
+            }
+            else {
+                options.paramSet[key] = true;
+            }
+        };
+        Parser.prototype.parseRestElement = function (params) {
+            var node = this.createNode();
+            this.nextToken();
+            if (this.match('{')) {
+                this.throwError(messages_1.Messages.ObjectPatternAsRestParameter);
+            }
+            params.push(this.lookahead);
+            var param = this.parseVariableIdentifier();
+            if (this.match('=')) {
+                this.throwError(messages_1.Messages.DefaultRestParameter);
+            }
+            if (!this.match(')')) {
+                this.throwError(messages_1.Messages.ParameterAfterRestParameter);
+            }
+            return this.finalize(node, new Node.RestElement(param));
+        };
+        Parser.prototype.parseFormalParameter = function (options) {
+            var param;
+            var params = [];
+            var token = this.lookahead;
+            if (token.value === '...') {
+                param = this.parseRestElement(params);
+                this.validateParam(options, param.argument, param.argument.name);
+                options.params.push(param);
+                return;
+            }
+            param = this.parsePatternWithDefault(params);
+            for (var i = 0; i &lt; params.length; i++) {
+                this.validateParam(options, params[i], params[i].value);
+            }
+            options.params.push(param);
+        };
+        Parser.prototype.parseFormalParameters = function (firstRestricted) {
+            var options;
+            options = {
+                params: [],
+                firstRestricted: firstRestricted
+            };
+            this.expect('(');
+            if (!this.match(')')) {
+                options.paramSet = {};
+                while (this.startMarker.index &lt; this.scanner.length) {
+                    this.parseFormalParameter(options);
+                    if (this.match(')')) {
+                        break;
+                    }
+                    this.expect(',');
+                    if (this.match(')')) {
+                        break;
+                    }
+                }
+            }
+            this.expect(')');
+            return {
+                params: options.params,
+                stricted: options.stricted,
+                firstRestricted: options.firstRestricted,
+                message: options.message
+            };
+        };
+        Parser.prototype.matchAsyncFunction = function () {
+            var match = this.matchContextualKeyword('async');
+            if (match) {
+                var previousIndex = this.scanner.index;
+                var previousLineNumber = this.scanner.lineNumber;
+                var previousLineStart = this.scanner.lineStart;
+                this.collectComments();
+                var next = this.scanner.lex();
+                this.scanner.index = previousIndex;
+                this.scanner.lineNumber = previousLineNumber;
+                this.scanner.lineStart = previousLineStart;
+                match = (previousLineNumber === next.lineNumber) &amp;&amp; ((next.type === token_1.Token.Keyword) || (next.value === 'function'));
+            }
+            return match;
+        };
+        Parser.prototype.parseFunctionDeclaration = function (identifierIsOptional) {
+            var node = this.createNode();
+            var isAsync = this.matchContextualKeyword('async');
+            if (isAsync) {
+                this.nextToken();
+            }
+            this.expectKeyword('function');
+            var isGenerator = isAsync ? false : this.match('*');
+            if (isGenerator) {
+                this.nextToken();
+            }
+            var message;
+            var id = null;
+            var firstRestricted = null;
+            if (!identifierIsOptional || !this.match('(')) {
+                var token = this.lookahead;
+                id = this.parseVariableIdentifier();
+                if (this.context.strict) {
+                    if (this.scanner.isRestrictedWord(token.value)) {
+                        this.tolerateUnexpectedToken(token, messages_1.Messages.StrictFunctionName);
+                    }
+                }
+                else {
+                    if (this.scanner.isRestrictedWord(token.value)) {
+                        firstRestricted = token;
+                        message = messages_1.Messages.StrictFunctionName;
+                    }
+                    else if (this.scanner.isStrictModeReservedWord(token.value)) {
+                        firstRestricted = token;
+                        message = messages_1.Messages.StrictReservedWord;
+                    }
+                }
+            }
+            var previousAllowAwait = this.context.await;
+            var previousAllowYield = this.context.allowYield;
+            this.context.await = isAsync;
+            this.context.allowYield = !isGenerator;
+            var formalParameters = this.parseFormalParameters(firstRestricted);
+            var params = formalParameters.params;
+            var stricted = formalParameters.stricted;
+            firstRestricted = formalParameters.firstRestricted;
+            if (formalParameters.message) {
+                message = formalParameters.message;
+            }
+            var previousStrict = this.context.strict;
+            var body = this.parseFunctionSourceElements();
+            if (this.context.strict &amp;&amp; firstRestricted) {
+                this.throwUnexpectedToken(firstRestricted, message);
+            }
+            if (this.context.strict &amp;&amp; stricted) {
+                this.tolerateUnexpectedToken(stricted, message);
+            }
+            this.context.strict = previousStrict;
+            this.context.await = previousAllowAwait;
+            this.context.allowYield = previousAllowYield;
+            return isAsync ? this.finalize(node, new Node.AsyncFunctionDeclaration(id, params, body)) :
+                this.finalize(node, new Node.FunctionDeclaration(id, params, body, isGenerator));
+        };
+        Parser.prototype.parseFunctionExpression = function () {
+            var node = this.createNode();
+            var isAsync = this.matchContextualKeyword('async');
+            if (isAsync) {
+                this.nextToken();
+            }
+            this.expectKeyword('function');
+            var isGenerator = isAsync ? false : this.match('*');
+            if (isGenerator) {
+                this.nextToken();
+            }
+            var message;
+            var id = null;
+            var firstRestricted;
+            var previousAllowAwait = this.context.await;
+            var previousAllowYield = this.context.allowYield;
+            this.context.await = isAsync;
+            this.context.allowYield = !isGenerator;
+            if (!this.match('(')) {
+                var token = this.lookahead;
+                id = (!this.context.strict &amp;&amp; !isGenerator &amp;&amp; this.matchKeyword('yield')) ? this.parseIdentifierName() : this.parseVariableIdentifier();
+                if (this.context.strict) {
+                    if (this.scanner.isRestrictedWord(token.value)) {
+                        this.tolerateUnexpectedToken(token, messages_1.Messages.StrictFunctionName);
+                    }
+                }
+                else {
+                    if (this.scanner.isRestrictedWord(token.value)) {
+                        firstRestricted = token;
+                        message = messages_1.Messages.StrictFunctionName;
+                    }
+                    else if (this.scanner.isStrictModeReservedWord(token.value)) {
+                        firstRestricted = token;
+                        message = messages_1.Messages.StrictReservedWord;
+                    }
+                }
+            }
+            var formalParameters = this.parseFormalParameters(firstRestricted);
+            var params = formalParameters.params;
+            var stricted = formalParameters.stricted;
+            firstRestricted = formalParameters.firstRestricted;
+            if (formalParameters.message) {
+                message = formalParameters.message;
+            }
+            var previousStrict = this.context.strict;
+            var body = this.parseFunctionSourceElements();
+            if (this.context.strict &amp;&amp; firstRestricted) {
+                this.throwUnexpectedToken(firstRestricted, message);
+            }
+            if (this.context.strict &amp;&amp; stricted) {
+                this.tolerateUnexpectedToken(stricted, message);
+            }
+            this.context.strict = previousStrict;
+            this.context.await = previousAllowAwait;
+            this.context.allowYield = previousAllowYield;
+            return isAsync ? this.finalize(node, new Node.AsyncFunctionExpression(id, params, body)) :
+                this.finalize(node, new Node.FunctionExpression(id, params, body, isGenerator));
+        };
+        // ECMA-262 14.1.1 Directive Prologues
+        Parser.prototype.parseDirective = function () {
+            var token = this.lookahead;
+            var node = this.createNode();
+            var expr = this.parseExpression();
+            var directive = (expr.type === syntax_1.Syntax.Literal) ? this.getTokenRaw(token).slice(1, -1) : null;
+            this.consumeSemicolon();
+            return this.finalize(node, directive ? new Node.Directive(expr, directive) : new Node.ExpressionStatement(expr));
+        };
+        Parser.prototype.parseDirectivePrologues = function () {
+            var firstRestricted = null;
+            var body = [];
+            while (true) {
+                var token = this.lookahead;
+                if (token.type !== token_1.Token.StringLiteral) {
+                    break;
+                }
+                var statement = this.parseDirective();
+                body.push(statement);
+                var directive = statement.directive;
+                if (typeof directive !== 'string') {
+                    break;
+                }
+                if (directive === 'use strict') {
+                    this.context.strict = true;
+                    if (firstRestricted) {
+                        this.tolerateUnexpectedToken(firstRestricted, messages_1.Messages.StrictOctalLiteral);
+                    }
+                }
+                else {
+                    if (!firstRestricted &amp;&amp; token.octal) {
+                        firstRestricted = token;
+                    }
+                }
+            }
+            return body;
+        };
+        // ECMA-262 14.3 Method Definitions
+        Parser.prototype.qualifiedPropertyName = function (token) {
+            switch (token.type) {
+                case token_1.Token.Identifier:
+                case token_1.Token.StringLiteral:
+                case token_1.Token.BooleanLiteral:
+                case token_1.Token.NullLiteral:
+                case token_1.Token.NumericLiteral:
+                case token_1.Token.Keyword:
+                    return true;
+                case token_1.Token.Punctuator:
+                    return token.value === '[';
+            }
+            return false;
+        };
+        Parser.prototype.parseGetterMethod = function () {
+            var node = this.createNode();
+            this.expect('(');
+            this.expect(')');
+            var isGenerator = false;
+            var params = {
+                params: [],
+                stricted: null,
+                firstRestricted: null,
+                message: null
+            };
+            var previousAllowYield = this.context.allowYield;
+            this.context.allowYield = false;
+            var method = this.parsePropertyMethod(params);
+            this.context.allowYield = previousAllowYield;
+            return this.finalize(node, new Node.FunctionExpression(null, params.params, method, isGenerator));
+        };
+        Parser.prototype.parseSetterMethod = function () {
+            var node = this.createNode();
+            var options = {
+                params: [],
+                firstRestricted: null,
+                paramSet: {}
+            };
+            var isGenerator = false;
+            var previousAllowYield = this.context.allowYield;
+            this.context.allowYield = false;
+            this.expect('(');
+            if (this.match(')')) {
+                this.tolerateUnexpectedToken(this.lookahead);
+            }
+            else {
+                this.parseFormalParameter(options);
+            }
+            this.expect(')');
+            var method = this.parsePropertyMethod(options);
+            this.context.allowYield = previousAllowYield;
+            return this.finalize(node, new Node.FunctionExpression(null, options.params, method, isGenerator));
+        };
+        Parser.prototype.parseGeneratorMethod = function () {
+            var node = this.createNode();
+            var isGenerator = true;
+            var previousAllowYield = this.context.allowYield;
+            this.context.allowYield = true;
+            var params = this.parseFormalParameters();
+            this.context.allowYield = false;
+            var method = this.parsePropertyMethod(params);
+            this.context.allowYield = previousAllowYield;
+            return this.finalize(node, new Node.FunctionExpression(null, params.params, method, isGenerator));
+        };
+        // ECMA-262 14.4 Generator Function Definitions
+        Parser.prototype.parseYieldExpression = function () {
+            var node = this.createNode();
+            this.expectKeyword('yield');
+            var argument = null;
+            var delegate = false;
+            if (!this.hasLineTerminator) {
+                var previousAllowYield = this.context.allowYield;
+                this.context.allowYield = false;
+                delegate = this.match('*');
+                if (delegate) {
+                    this.nextToken();
+                    argument = this.parseAssignmentExpression();
+                }
+                else {
+                    if (!this.match(';') &amp;&amp; !this.match('}') &amp;&amp; !this.match(')') &amp;&amp; this.lookahead.type !== token_1.Token.EOF) {
+                        argument = this.parseAssignmentExpression();
+                    }
+                }
+                this.context.allowYield = previousAllowYield;
+            }
+            return this.finalize(node, new Node.YieldExpression(argument, delegate));
+        };
+        // ECMA-262 14.5 Class Definitions
+        Parser.prototype.parseClassElement = function (hasConstructor) {
+            var token = this.lookahead;
+            var node = this.createNode();
+            var kind = '';
+            var key = null;
+            var value = null;
+            var computed = false;
+            var method = false;
+            var isStatic = false;
+            var isAsync = false;
+            if (this.match('*')) {
+                this.nextToken();
+            }
+            else {
+                computed = this.match('[');
+                key = this.parseObjectPropertyKey();
+                var id = key;
+                if (id.name === 'static' &amp;&amp; (this.qualifiedPropertyName(this.lookahead) || this.match('*'))) {
+                    token = this.lookahead;
+                    isStatic = true;
+                    computed = this.match('[');
+                    if (this.match('*')) {
+                        this.nextToken();
+                    }
+                    else {
+                        key = this.parseObjectPropertyKey();
+                    }
+                }
+                if ((token.type === token_1.Token.Identifier) &amp;&amp; !this.hasLineTerminator &amp;&amp; (token.value === 'async')) {
+                    var punctuator = this.lookahead.value;
+                    if (punctuator !== ':' &amp;&amp; punctuator !== '(' &amp;&amp; punctuator !== '*') {
+                        isAsync = true;
+                        token = this.lookahead;
+                        key = this.parseObjectPropertyKey();
+                        if (token.type === token_1.Token.Identifier) {
+                            if (token.value === 'get' || token.value === 'set') {
+                                this.tolerateUnexpectedToken(token);
+                            }
+                            else if (token.value === 'constructor') {
+                                this.tolerateUnexpectedToken(token, messages_1.Messages.ConstructorIsAsync);
+                            }
+                        }
+                    }
+                }
+            }
+            var lookaheadPropertyKey = this.qualifiedPropertyName(this.lookahead);
+            if (token.type === token_1.Token.Identifier) {
+                if (token.value === 'get' &amp;&amp; lookaheadPropertyKey) {
+                    kind = 'get';
+                    computed = this.match('[');
+                    key = this.parseObjectPropertyKey();
+                    this.context.allowYield = false;
+                    value = this.parseGetterMethod();
+                }
+                else if (token.value === 'set' &amp;&amp; lookaheadPropertyKey) {
+                    kind = 'set';
+                    computed = this.match('[');
+                    key = this.parseObjectPropertyKey();
+                    value = this.parseSetterMethod();
+                }
+            }
+            else if (token.type === token_1.Token.Punctuator &amp;&amp; token.value === '*' &amp;&amp; lookaheadPropertyKey) {
+                kind = 'init';
+                computed = this.match('[');
+                key = this.parseObjectPropertyKey();
+                value = this.parseGeneratorMethod();
+                method = true;
+            }
+            if (!kind &amp;&amp; key &amp;&amp; this.match('(')) {
+                kind = 'init';
+                value = isAsync ? this.parsePropertyMethodAsyncFunction() : this.parsePropertyMethodFunction();
+                method = true;
+            }
+            if (!kind) {
+                this.throwUnexpectedToken(this.lookahead);
+            }
+            if (kind === 'init') {
+                kind = 'method';
+            }
+            if (!computed) {
+                if (isStatic &amp;&amp; this.isPropertyKey(key, 'prototype')) {
+                    this.throwUnexpectedToken(token, messages_1.Messages.StaticPrototype);
+                }
+                if (!isStatic &amp;&amp; this.isPropertyKey(key, 'constructor')) {
+                    if (kind !== 'method' || !method || (value &amp;&amp; value.generator)) {
+                        this.throwUnexpectedToken(token, messages_1.Messages.ConstructorSpecialMethod);
+                    }
+                    if (hasConstructor.value) {
+                        this.throwUnexpectedToken(token, messages_1.Messages.DuplicateConstructor);
+                    }
+                    else {
+                        hasConstructor.value = true;
+                    }
+                    kind = 'constructor';
+                }
+            }
+            return this.finalize(node, new Node.MethodDefinition(key, computed, value, kind, isStatic));
+        };
+        Parser.prototype.parseClassElementList = function () {
+            var body = [];
+            var hasConstructor = { value: false };
+            this.expect('{');
+            while (!this.match('}')) {
+                if (this.match(';')) {
+                    this.nextToken();
+                }
+                else {
+                    body.push(this.parseClassElement(hasConstructor));
+                }
+            }
+            this.expect('}');
+            return body;
+        };
+        Parser.prototype.parseClassBody = function () {
+            var node = this.createNode();
+            var elementList = this.parseClassElementList();
+            return this.finalize(node, new Node.ClassBody(elementList));
+        };
+        Parser.prototype.parseClassDeclaration = function (identifierIsOptional) {
+            var node = this.createNode();
+            var previousStrict = this.context.strict;
+            this.context.strict = true;
+            this.expectKeyword('class');
+            var id = (identifierIsOptional &amp;&amp; (this.lookahead.type !== token_1.Token.Identifier)) ? null : this.parseVariableIdentifier();
+            var superClass = null;
+            if (this.matchKeyword('extends')) {
+                this.nextToken();
+                superClass = this.isolateCoverGrammar(this.parseLeftHandSideExpressionAllowCall);
+            }
+            var classBody = this.parseClassBody();
+            this.context.strict = previousStrict;
+            return this.finalize(node, new Node.ClassDeclaration(id, superClass, classBody));
+        };
+        Parser.prototype.parseClassExpression = function () {
+            var node = this.createNode();
+            var previousStrict = this.context.strict;
+            this.context.strict = true;
+            this.expectKeyword('class');
+            var id = (this.lookahead.type === token_1.Token.Identifier) ? this.parseVariableIdentifier() : null;
+            var superClass = null;
+            if (this.matchKeyword('extends')) {
+                this.nextToken();
+                superClass = this.isolateCoverGrammar(this.parseLeftHandSideExpressionAllowCall);
+            }
+            var classBody = this.parseClassBody();
+            this.context.strict = previousStrict;
+            return this.finalize(node, new Node.ClassExpression(id, superClass, classBody));
+        };
+        // ECMA-262 15.1 Scripts
+        // ECMA-262 15.2 Modules
+        Parser.prototype.parseModule = function () {
+            this.context.strict = true;
+            this.context.isModule = true;
+            var node = this.createNode();
+            var body = this.parseDirectivePrologues();
+            while (this.startMarker.index &lt; this.scanner.length) {
+                body.push(this.parseStatementListItem());
+            }
+            return this.finalize(node, new Node.Module(body));
+        };
+        Parser.prototype.parseScript = function () {
+            var node = this.createNode();
+            var body = this.parseDirectivePrologues();
+            while (this.startMarker.index &lt; this.scanner.length) {
+                body.push(this.parseStatementListItem());
+            }
+            return this.finalize(node, new Node.Script(body));
+        };
+        // ECMA-262 15.2.2 Imports
+        Parser.prototype.parseModuleSpecifier = function () {
+            var node = this.createNode();
+            if (this.lookahead.type !== token_1.Token.StringLiteral) {
+                this.throwError(messages_1.Messages.InvalidModuleSpecifier);
+            }
+            var token = this.nextToken();
+            var raw = this.getTokenRaw(token);
+            return this.finalize(node, new Node.Literal(token.value, raw));
+        };
+        // import {&lt;foo as bar&gt;} ...;
+        Parser.prototype.parseImportSpecifier = function () {
+            var node = this.createNode();
+            var imported;
+            var local;
+            if (this.lookahead.type === token_1.Token.Identifier) {
+                imported = this.parseVariableIdentifier();
+                local = imported;
+                if (this.matchContextualKeyword('as')) {
+                    this.nextToken();
+                    local = this.parseVariableIdentifier();
+                }
+            }
+            else {
+                imported = this.parseIdentifierName();
+                local = imported;
+                if (this.matchContextualKeyword('as')) {
+                    this.nextToken();
+                    local = this.parseVariableIdentifier();
+                }
+                else {
+                    this.throwUnexpectedToken(this.nextToken());
+                }
+            }
+            return this.finalize(node, new Node.ImportSpecifier(local, imported));
+        };
+        // {foo, bar as bas}
+        Parser.prototype.parseNamedImports = function () {
+            this.expect('{');
+            var specifiers = [];
+            while (!this.match('}')) {
+                specifiers.push(this.parseImportSpecifier());
+                if (!this.match('}')) {
+                    this.expect(',');
+                }
+            }
+            this.expect('}');
+            return specifiers;
+        };
+        // import &lt;foo&gt; ...;
+        Parser.prototype.parseImportDefaultSpecifier = function () {
+            var node = this.createNode();
+            var local = this.parseIdentifierName();
+            return this.finalize(node, new Node.ImportDefaultSpecifier(local));
+        };
+        // import &lt;* as foo&gt; ...;
+        Parser.prototype.parseImportNamespaceSpecifier = function () {
+            var node = this.createNode();
+            this.expect('*');
+            if (!this.matchContextualKeyword('as')) {
+                this.throwError(messages_1.Messages.NoAsAfterImportNamespace);
+            }
+            this.nextToken();
+            var local = this.parseIdentifierName();
+            return this.finalize(node, new Node.ImportNamespaceSpecifier(local));
+        };
+        Parser.prototype.parseImportDeclaration = function () {
+            if (this.context.inFunctionBody) {
+                this.throwError(messages_1.Messages.IllegalImportDeclaration);
+            }
+            var node = this.createNode();
+            this.expectKeyword('import');
+            var src;
+            var specifiers = [];
+            if (this.lookahead.type === token_1.Token.StringLiteral) {
+                // import 'foo';
+                src = this.parseModuleSpecifier();
+            }
+            else {
+                if (this.match('{')) {
+                    // import {bar}
+                    specifiers = specifiers.concat(this.parseNamedImports());
+                }
+                else if (this.match('*')) {
+                    // import * as foo
+                    specifiers.push(this.parseImportNamespaceSpecifier());
+                }
+                else if (this.isIdentifierName(this.lookahead) &amp;&amp; !this.matchKeyword('default')) {
+                    // import foo
+                    specifiers.push(this.parseImportDefaultSpecifier());
+                    if (this.match(',')) {
+                        this.nextToken();
+                        if (this.match('*')) {
+                            // import foo, * as foo
+                            specifiers.push(this.parseImportNamespaceSpecifier());
+                        }
+                        else if (this.match('{')) {
+                            // import foo, {bar}
+                            specifiers = specifiers.concat(this.parseNamedImports());
+                        }
+                        else {
+                            this.throwUnexpectedToken(this.lookahead);
+                        }
+                    }
+                }
+                else {
+                    this.throwUnexpectedToken(this.nextToken());
+                }
+                if (!this.matchContextualKeyword('from')) {
+                    var message = this.lookahead.value ? messages_1.Messages.UnexpectedToken : messages_1.Messages.MissingFromClause;
+                    this.throwError(message, this.lookahead.value);
+                }
+                this.nextToken();
+                src = this.parseModuleSpecifier();
+            }
+            this.consumeSemicolon();
+            return this.finalize(node, new Node.ImportDeclaration(specifiers, src));
+        };
+        // ECMA-262 15.2.3 Exports
+        Parser.prototype.parseExportSpecifier = function () {
+            var node = this.createNode();
+            var local = this.parseIdentifierName();
+            var exported = local;
+            if (this.matchContextualKeyword('as')) {
+                this.nextToken();
+                exported = this.parseIdentifierName();
+            }
+            return this.finalize(node, new Node.ExportSpecifier(local, exported));
+        };
+        Parser.prototype.parseExportDeclaration = function () {
+            if (this.context.inFunctionBody) {
+                this.throwError(messages_1.Messages.IllegalExportDeclaration);
+            }
+            var node = this.createNode();
+            this.expectKeyword('export');
+            var exportDeclaration;
+            if (this.matchKeyword('default')) {
+                // export default ...
+                this.nextToken();
+                if (this.matchKeyword('function')) {
+                    // export default function foo () {}
+                    // export default function () {}
+                    var declaration = this.parseFunctionDeclaration(true);
+                    exportDeclaration = this.finalize(node, new Node.ExportDefaultDeclaration(declaration));
+                }
+                else if (this.matchKeyword('class')) {
+                    // export default class foo {}
+                    var declaration = this.parseClassDeclaration(true);
+                    exportDeclaration = this.finalize(node, new Node.ExportDefaultDeclaration(declaration));
+                }
+                else {
+                    if (this.matchContextualKeyword('from')) {
+                        this.throwError(messages_1.Messages.UnexpectedToken, this.lookahead.value);
+                    }
+                    // export default {};
+                    // export default [];
+                    // export default (1 + 2);
+                    var declaration = this.match('{') ? this.parseObjectInitializer() :
+                        this.match('[') ? this.parseArrayInitializer() : this.parseAssignmentExpression();
+                    this.consumeSemicolon();
+                    exportDeclaration = this.finalize(node, new Node.ExportDefaultDeclaration(declaration));
+                }
+            }
+            else if (this.match('*')) {
+                // export * from 'foo';
+                this.nextToken();
+                if (!this.matchContextualKeyword('from')) {
+                    var message = this.lookahead.value ? messages_1.Messages.UnexpectedToken : messages_1.Messages.MissingFromClause;
+                    this.throwError(message, this.lookahead.value);
+                }
+                this.nextToken();
+                var src = this.parseModuleSpecifier();
+                this.consumeSemicolon();
+                exportDeclaration = this.finalize(node, new Node.ExportAllDeclaration(src));
+            }
+            else if (this.lookahead.type === token_1.Token.Keyword) {
+                // export var f = 1;
+                var declaration = void 0;
+                switch (this.lookahead.value) {
+                    case 'let':
+                    case 'const':
+                        declaration = this.parseLexicalDeclaration({ inFor: false });
+                        break;
+                    case 'var':
+                    case 'class':
+                    case 'function':
+                        declaration = this.parseStatementListItem();
+                        break;
+                    default:
+                        this.throwUnexpectedToken(this.lookahead);
+                }
+                exportDeclaration = this.finalize(node, new Node.ExportNamedDeclaration(declaration, [], null));
+            }
+            else if (this.matchAsyncFunction()) {
+                var declaration = this.parseFunctionDeclaration();
+                exportDeclaration = this.finalize(node, new Node.ExportNamedDeclaration(declaration, [], null));
+            }
+            else {
+                var specifiers = [];
+                var source = null;
+                var isExportFromIdentifier = false;
+                this.expect('{');
+                while (!this.match('}')) {
+                    isExportFromIdentifier = isExportFromIdentifier || this.matchKeyword('default');
+                    specifiers.push(this.parseExportSpecifier());
+                    if (!this.match('}')) {
+                        this.expect(',');
+                    }
+                }
+                this.expect('}');
+                if (this.matchContextualKeyword('from')) {
+                    // export {default} from 'foo';
+                    // export {foo} from 'foo';
+                    this.nextToken();
+                    source = this.parseModuleSpecifier();
+                    this.consumeSemicolon();
+                }
+                else if (isExportFromIdentifier) {
+                    // export {default}; // missing fromClause
+                    var message = this.lookahead.value ? messages_1.Messages.UnexpectedToken : messages_1.Messages.MissingFromClause;
+                    this.throwError(message, this.lookahead.value);
+                }
+                else {
+                    // export {foo};
+                    this.consumeSemicolon();
+                }
+                exportDeclaration = this.finalize(node, new Node.ExportNamedDeclaration(null, specifiers, source));
+            }
+            return exportDeclaration;
+        };
+        return Parser;
+    }());
+    exports.Parser = Parser;
+
+
+/***/ },
+/* 4 */
+/***/ function(module, exports) {
+
+    // Ensure the condition is true, otherwise throw an error.
+    // This is only to have a better contract semantic, i.e. another safety net
+    // to catch a logic error. The condition shall be fulfilled in normal case.
+    // Do NOT use this to enforce a certain condition on any user input.
+    &quot;use strict&quot;;
+    function assert(condition, message) {
+        /* istanbul ignore if */
+        if (!condition) {
+            throw new Error('ASSERT: ' + message);
+        }
+    }
+    exports.assert = assert;
+
+
+/***/ },
+/* 5 */
+/***/ function(module, exports) {
+
+    &quot;use strict&quot;;
</ins><span class="cx">     // Error messages should be identical to V8.
</span><del>-    Messages = {
</del><ins>+    exports.Messages = {
</ins><span class="cx">         UnexpectedToken: 'Unexpected token %0',
</span><ins>+        UnexpectedTokenIllegal: 'Unexpected token ILLEGAL',
</ins><span class="cx">         UnexpectedNumber: 'Unexpected number',
</span><span class="cx">         UnexpectedString: 'Unexpected string',
</span><span class="cx">         UnexpectedIdentifier: 'Unexpected identifier',
</span><span class="lines">@@ -222,1078 +3558,1092 @@
</span><span class="cx">         InvalidModuleSpecifier: 'Unexpected token',
</span><span class="cx">         IllegalImportDeclaration: 'Unexpected token',
</span><span class="cx">         IllegalExportDeclaration: 'Unexpected token',
</span><del>-        DuplicateBinding: 'Duplicate binding %0'
</del><ins>+        DuplicateBinding: 'Duplicate binding %0',
+        DeclarationMissingInitializer: 'Missing initializer in %0 declaration',
+        LetInLexicalBinding: 'let is disallowed as a lexically bound name',
+        ForInOfLoopInitializer: '%0 loop variable declaration may not have an initializer',
+        ConstructorIsAsync: 'Class constructor may not be an async method'
</ins><span class="cx">     };
</span><span class="cx"> 
</span><del>-    // See also tools/generate-unicode-regex.js.
-    Regex = {
-        // ECMAScript 6/Unicode v7.0.0 NonAsciiIdentifierStart:
-        NonAsciiIdentifierStart: /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\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-\u08B2\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\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\u0B5
 D\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-\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-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\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\u2118-\u211D\u2124\u2126\u2128\u212A-\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\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309B-\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-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF
 900-\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]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE
 8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDE00-\uDE11\uDE13-\uDE2B\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF5D-\uDF61]|\uD805[\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDE00-\uDE2F\uDE44\uDE80-\uDEAA]|\uD806[\uDCA0-\uDCDF\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF98]|\uD809[\uDC00-\uDC6E]|[\uD80C\uD840-\uD868\uD86A-\uD86C][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\
 uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D]|\uD87E[\uDC00-\uDE1D]/,
</del><span class="cx"> 
</span><del>-        // ECMAScript 6/Unicode v7.0.0 NonAsciiIdentifierPart:
-        NonAsciiIdentifierPart: /[\xAA\xB5\xB7\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\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-\u08B2\u08E4-\u0963\u0966-\u096F\u0971-\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\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58\u0C59\u0C60-\u0C63\u0C66-\u0C6F\u0C81-\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\u0D01-\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\u0DE6-\u0DEF\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\u1369-\u1371\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\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-\u191E\u1920-\u192B\u1
 930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\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\u2118-\u211D\u2124\u2126\u2128\u212A-\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\u3005-\u3007\u3021-\u302F\u3031-\u3
 035\u3038-\u303C\u3041-\u3096\u3099-\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-\uA69D\uA69F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\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-\uFE2D\uFE33\uFE34\uFE4D-\uFE4F\uFE7
 0-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDD0-\uDDDA\uDE00-\uDE11\
 uDE13-\uDE37\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF01-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9]|\uD806[\uDCA0-\uDCE9\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF98]|\uD809[\uDC00-\uDC6E]|[\uD80C\uD840-\uD868\uD86A-\uD86C][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07
 -\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/
-    };
</del><ins>+/***/ },
+/* 6 */
+/***/ function(module, exports) {
</ins><span class="cx"> 
</span><del>-    // Ensure the condition is true, otherwise throw an error.
-    // This is only to have a better contract semantic, i.e. another safety net
-    // to catch a logic error. The condition shall be fulfilled in normal case.
-    // Do NOT use this to enforce a certain condition on any user input.
-
-    function assert(condition, message) {
-        /* istanbul ignore if */
-        if (!condition) {
-            throw new Error('ASSERT: ' + message);
</del><ins>+    &quot;use strict&quot;;
+    var ErrorHandler = (function () {
+        function ErrorHandler() {
+            this.errors = [];
+            this.tolerant = false;
</ins><span class="cx">         }
</span><del>-    }
-
-    function isDecimalDigit(ch) {
-        return (ch &gt;= 0x30 &amp;&amp; ch &lt;= 0x39);   // 0..9
-    }
-
-    function isHexDigit(ch) {
-        return '0123456789abcdefABCDEF'.indexOf(ch) &gt;= 0;
-    }
-
-    function isOctalDigit(ch) {
-        return '01234567'.indexOf(ch) &gt;= 0;
-    }
-
-    function octalToDecimal(ch) {
-        // \0 is not octal escape sequence
-        var octal = (ch !== '0'), code = '01234567'.indexOf(ch);
-
-        if (index &lt; length &amp;&amp; isOctalDigit(source[index])) {
-            octal = true;
-            code = code * 8 + '01234567'.indexOf(source[index++]);
-
-            // 3 digits are only allowed when string starts
-            // with 0, 1, 2, 3
-            if ('0123'.indexOf(ch) &gt;= 0 &amp;&amp;
-                    index &lt; length &amp;&amp;
-                    isOctalDigit(source[index])) {
-                code = code * 8 + '01234567'.indexOf(source[index++]);
</del><ins>+        ;
+        ErrorHandler.prototype.recordError = function (error) {
+            this.errors.push(error);
+        };
+        ;
+        ErrorHandler.prototype.tolerate = function (error) {
+            if (this.tolerant) {
+                this.recordError(error);
</ins><span class="cx">             }
</span><del>-        }
-
-        return {
-            code: code,
-            octal: octal
</del><ins>+            else {
+                throw error;
+            }
</ins><span class="cx">         };
</span><del>-    }
</del><ins>+        ;
+        ErrorHandler.prototype.constructError = function (msg, column) {
+            var error = new Error(msg);
+            try {
+                throw error;
+            }
+            catch (base) {
+                /* istanbul ignore else */
+                if (Object.create &amp;&amp; Object.defineProperty) {
+                    error = Object.create(base);
+                    Object.defineProperty(error, 'column', { value: column });
+                }
+            }
+            finally {
+                return error;
+            }
+            /* istanbul ignore next */
+            return error;
+        };
+        ;
+        ErrorHandler.prototype.createError = function (index, line, col, description) {
+            var msg = 'Line ' + line + ': ' + description;
+            var error = this.constructError(msg, col);
+            error.index = index;
+            error.lineNumber = line;
+            error.description = description;
+            return error;
+        };
+        ;
+        ErrorHandler.prototype.throwError = function (index, line, col, description) {
+            throw this.createError(index, line, col, description);
+        };
+        ;
+        ErrorHandler.prototype.tolerateError = function (index, line, col, description) {
+            var error = this.createError(index, line, col, description);
+            if (this.tolerant) {
+                this.recordError(error);
+            }
+            else {
+                throw error;
+            }
+        };
+        ;
+        return ErrorHandler;
+    }());
+    exports.ErrorHandler = ErrorHandler;
</ins><span class="cx"> 
</span><del>-    // ECMA-262 11.2 White Space
</del><span class="cx"> 
</span><del>-    function isWhiteSpace(ch) {
-        return (ch === 0x20) || (ch === 0x09) || (ch === 0x0B) || (ch === 0x0C) || (ch === 0xA0) ||
-            (ch &gt;= 0x1680 &amp;&amp; [0x1680, 0x180E, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000, 0xFEFF].indexOf(ch) &gt;= 0);
-    }
</del><ins>+/***/ },
+/* 7 */
+/***/ function(module, exports) {
</ins><span class="cx"> 
</span><del>-    // ECMA-262 11.3 Line Terminators
</del><ins>+    &quot;use strict&quot;;
+    (function (Token) {
+        Token[Token[&quot;BooleanLiteral&quot;] = 1] = &quot;BooleanLiteral&quot;;
+        Token[Token[&quot;EOF&quot;] = 2] = &quot;EOF&quot;;
+        Token[Token[&quot;Identifier&quot;] = 3] = &quot;Identifier&quot;;
+        Token[Token[&quot;Keyword&quot;] = 4] = &quot;Keyword&quot;;
+        Token[Token[&quot;NullLiteral&quot;] = 5] = &quot;NullLiteral&quot;;
+        Token[Token[&quot;NumericLiteral&quot;] = 6] = &quot;NumericLiteral&quot;;
+        Token[Token[&quot;Punctuator&quot;] = 7] = &quot;Punctuator&quot;;
+        Token[Token[&quot;StringLiteral&quot;] = 8] = &quot;StringLiteral&quot;;
+        Token[Token[&quot;RegularExpression&quot;] = 9] = &quot;RegularExpression&quot;;
+        Token[Token[&quot;Template&quot;] = 10] = &quot;Template&quot;;
+    })(exports.Token || (exports.Token = {}));
+    var Token = exports.Token;
+    ;
+    exports.TokenName = {};
+    exports.TokenName[Token.BooleanLiteral] = 'Boolean';
+    exports.TokenName[Token.EOF] = '&lt;end&gt;';
+    exports.TokenName[Token.Identifier] = 'Identifier';
+    exports.TokenName[Token.Keyword] = 'Keyword';
+    exports.TokenName[Token.NullLiteral] = 'Null';
+    exports.TokenName[Token.NumericLiteral] = 'Numeric';
+    exports.TokenName[Token.Punctuator] = 'Punctuator';
+    exports.TokenName[Token.StringLiteral] = 'String';
+    exports.TokenName[Token.RegularExpression] = 'RegularExpression';
+    exports.TokenName[Token.Template] = 'Template';
</ins><span class="cx"> 
</span><del>-    function isLineTerminator(ch) {
-        return (ch === 0x0A) || (ch === 0x0D) || (ch === 0x2028) || (ch === 0x2029);
-    }
</del><span class="cx"> 
</span><del>-    // ECMA-262 11.6 Identifier Names and Identifiers
</del><ins>+/***/ },
+/* 8 */
+/***/ function(module, exports, __webpack_require__) {
</ins><span class="cx"> 
</span><del>-    function fromCodePoint(cp) {
-        return (cp &lt; 0x10000) ? String.fromCharCode(cp) :
-            String.fromCharCode(0xD800 + ((cp - 0x10000) &gt;&gt; 10)) +
-            String.fromCharCode(0xDC00 + ((cp - 0x10000) &amp; 1023));
</del><ins>+    &quot;use strict&quot;;
+    var assert_1 = __webpack_require__(4);
+    var messages_1 = __webpack_require__(5);
+    var character_1 = __webpack_require__(9);
+    var token_1 = __webpack_require__(7);
+    function hexValue(ch) {
+        return '0123456789abcdef'.indexOf(ch.toLowerCase());
</ins><span class="cx">     }
</span><del>-
-    function isIdentifierStart(ch) {
-        return (ch === 0x24) || (ch === 0x5F) ||  // $ (dollar) and _ (underscore)
-            (ch &gt;= 0x41 &amp;&amp; ch &lt;= 0x5A) ||         // A..Z
-            (ch &gt;= 0x61 &amp;&amp; ch &lt;= 0x7A) ||         // a..z
-            (ch === 0x5C) ||                      // \ (backslash)
-            ((ch &gt;= 0x80) &amp;&amp; Regex.NonAsciiIdentifierStart.test(fromCodePoint(ch)));
</del><ins>+    function octalValue(ch) {
+        return '01234567'.indexOf(ch);
</ins><span class="cx">     }
</span><del>-
-    function isIdentifierPart(ch) {
-        return (ch === 0x24) || (ch === 0x5F) ||  // $ (dollar) and _ (underscore)
-            (ch &gt;= 0x41 &amp;&amp; ch &lt;= 0x5A) ||         // A..Z
-            (ch &gt;= 0x61 &amp;&amp; ch &lt;= 0x7A) ||         // a..z
-            (ch &gt;= 0x30 &amp;&amp; ch &lt;= 0x39) ||         // 0..9
-            (ch === 0x5C) ||                      // \ (backslash)
-            ((ch &gt;= 0x80) &amp;&amp; Regex.NonAsciiIdentifierPart.test(fromCodePoint(ch)));
-    }
-
-    // ECMA-262 11.6.2.2 Future Reserved Words
-
-    function isFutureReservedWord(id) {
-        switch (id) {
-        case 'enum':
-        case 'export':
-        case 'import':
-        case 'super':
-            return true;
-        default:
-            return false;
</del><ins>+    var Scanner = (function () {
+        function Scanner(code, handler) {
+            this.source = code;
+            this.errorHandler = handler;
+            this.trackComment = false;
+            this.length = code.length;
+            this.index = 0;
+            this.lineNumber = (code.length &gt; 0) ? 1 : 0;
+            this.lineStart = 0;
+            this.curlyStack = [];
</ins><span class="cx">         }
</span><del>-    }
-
-    function isStrictModeReservedWord(id) {
-        switch (id) {
-        case 'implements':
-        case 'interface':
-        case 'package':
-        case 'private':
-        case 'protected':
-        case 'public':
-        case 'static':
-        case 'yield':
-        case 'let':
-            return true;
-        default:
-            return false;
-        }
-    }
-
-    function isRestrictedWord(id) {
-        return id === 'eval' || id === 'arguments';
-    }
-
-    // ECMA-262 11.6.2.1 Keywords
-
-    function isKeyword(id) {
-
-        // 'const' is specialized as Keyword in V8.
-        // 'yield' and 'let' are for compatibility with SpiderMonkey and ES.next.
-        // Some others are from future reserved words.
-
-        switch (id.length) {
-        case 2:
-            return (id === 'if') || (id === 'in') || (id === 'do');
-        case 3:
-            return (id === 'var') || (id === 'for') || (id === 'new') ||
-                (id === 'try') || (id === 'let');
-        case 4:
-            return (id === 'this') || (id === 'else') || (id === 'case') ||
-                (id === 'void') || (id === 'with') || (id === 'enum');
-        case 5:
-            return (id === 'while') || (id === 'break') || (id === 'catch') ||
-                (id === 'throw') || (id === 'const') || (id === 'yield') ||
-                (id === 'class') || (id === 'super');
-        case 6:
-            return (id === 'return') || (id === 'typeof') || (id === 'delete') ||
-                (id === 'switch') || (id === 'export') || (id === 'import');
-        case 7:
-            return (id === 'default') || (id === 'finally') || (id === 'extends');
-        case 8:
-            return (id === 'function') || (id === 'continue') || (id === 'debugger');
-        case 10:
-            return (id === 'instanceof');
-        default:
-            return false;
-        }
-    }
-
-    // ECMA-262 11.4 Comments
-
-    function addComment(type, value, start, end, loc) {
-        var comment;
-
-        assert(typeof start === 'number', 'Comment must have valid position');
-
-        state.lastCommentStart = start;
-
-        comment = {
-            type: type,
-            value: value
</del><ins>+        ;
+        Scanner.prototype.eof = function () {
+            return this.index &gt;= this.length;
</ins><span class="cx">         };
</span><del>-        if (extra.range) {
-            comment.range = [start, end];
-        }
-        if (extra.loc) {
-            comment.loc = loc;
-        }
-        extra.comments.push(comment);
-        if (extra.attachComment) {
-            extra.leadingComments.push(comment);
-            extra.trailingComments.push(comment);
-        }
-    }
-
-    function skipSingleLineComment(offset) {
-        var start, loc, ch, comment;
-
-        start = index - offset;
-        loc = {
-            start: {
-                line: lineNumber,
-                column: index - lineStart - offset
</del><ins>+        ;
+        Scanner.prototype.throwUnexpectedToken = function (message) {
+            if (message === void 0) { message = messages_1.Messages.UnexpectedTokenIllegal; }
+            this.errorHandler.throwError(this.index, this.lineNumber, this.index - this.lineStart + 1, message);
+        };
+        ;
+        Scanner.prototype.tolerateUnexpectedToken = function () {
+            this.errorHandler.tolerateError(this.index, this.lineNumber, this.index - this.lineStart + 1, messages_1.Messages.UnexpectedTokenIllegal);
+        };
+        ;
+        // ECMA-262 11.4 Comments
+        Scanner.prototype.skipSingleLineComment = function (offset) {
+            var comments = [];
+            var start, loc;
+            if (this.trackComment) {
+                comments = [];
+                start = this.index - offset;
+                loc = {
+                    start: {
+                        line: this.lineNumber,
+                        column: this.index - this.lineStart - offset
+                    },
+                    end: {}
+                };
</ins><span class="cx">             }
</span><ins>+            while (!this.eof()) {
+                var ch = this.source.charCodeAt(this.index);
+                ++this.index;
+                if (character_1.Character.isLineTerminator(ch)) {
+                    if (this.trackComment) {
+                        loc.end = {
+                            line: this.lineNumber,
+                            column: this.index - this.lineStart - 1
+                        };
+                        var entry = {
+                            multiLine: false,
+                            slice: [start + offset, this.index - 1],
+                            range: [start, this.index - 1],
+                            loc: loc
+                        };
+                        comments.push(entry);
+                    }
+                    if (ch === 13 &amp;&amp; this.source.charCodeAt(this.index) === 10) {
+                        ++this.index;
+                    }
+                    ++this.lineNumber;
+                    this.lineStart = this.index;
+                    return comments;
+                }
+            }
+            if (this.trackComment) {
+                loc.end = {
+                    line: this.lineNumber,
+                    column: this.index - this.lineStart
+                };
+                var entry = {
+                    multiLine: false,
+                    slice: [start + offset, this.index],
+                    range: [start, this.index],
+                    loc: loc
+                };
+                comments.push(entry);
+            }
+            return comments;
</ins><span class="cx">         };
</span><del>-
-        while (index &lt; length) {
-            ch = source.charCodeAt(index);
-            ++index;
-            if (isLineTerminator(ch)) {
-                hasLineTerminator = true;
-                if (extra.comments) {
-                    comment = source.slice(start + offset, index - 1);
-                    loc.end = {
-                        line: lineNumber,
-                        column: index - lineStart - 1
-                    };
-                    addComment('Line', comment, start, index - 1, loc);
</del><ins>+        ;
+        Scanner.prototype.skipMultiLineComment = function () {
+            var comments = [];
+            var start, loc;
+            if (this.trackComment) {
+                comments = [];
+                start = this.index - 2;
+                loc = {
+                    start: {
+                        line: this.lineNumber,
+                        column: this.index - this.lineStart - 2
+                    },
+                    end: {}
+                };
+            }
+            while (!this.eof()) {
+                var ch = this.source.charCodeAt(this.index);
+                if (character_1.Character.isLineTerminator(ch)) {
+                    if (ch === 0x0D &amp;&amp; this.source.charCodeAt(this.index + 1) === 0x0A) {
+                        ++this.index;
+                    }
+                    ++this.lineNumber;
+                    ++this.index;
+                    this.lineStart = this.index;
</ins><span class="cx">                 }
</span><del>-                if (ch === 13 &amp;&amp; source.charCodeAt(index) === 10) {
-                    ++index;
</del><ins>+                else if (ch === 0x2A) {
+                    // Block comment ends with '*/'.
+                    if (this.source.charCodeAt(this.index + 1) === 0x2F) {
+                        this.index += 2;
+                        if (this.trackComment) {
+                            loc.end = {
+                                line: this.lineNumber,
+                                column: this.index - this.lineStart
+                            };
+                            var entry = {
+                                multiLine: true,
+                                slice: [start + 2, this.index - 2],
+                                range: [start, this.index],
+                                loc: loc
+                            };
+                            comments.push(entry);
+                        }
+                        return comments;
+                    }
+                    ++this.index;
</ins><span class="cx">                 }
</span><del>-                ++lineNumber;
-                lineStart = index;
-                return;
</del><ins>+                else {
+                    ++this.index;
+                }
</ins><span class="cx">             }
</span><del>-        }
-
-        if (extra.comments) {
-            comment = source.slice(start + offset, index);
-            loc.end = {
-                line: lineNumber,
-                column: index - lineStart
-            };
-            addComment('Line', comment, start, index, loc);
-        }
-    }
-
-    function skipMultiLineComment() {
-        var start, loc, ch, comment;
-
-        if (extra.comments) {
-            start = index - 2;
-            loc = {
-                start: {
-                    line: lineNumber,
-                    column: index - lineStart - 2
</del><ins>+            // Ran off the end of the file - the whole thing is a comment
+            if (this.trackComment) {
+                loc.end = {
+                    line: this.lineNumber,
+                    column: this.index - this.lineStart
+                };
+                var entry = {
+                    multiLine: true,
+                    slice: [start + 2, this.index],
+                    range: [start, this.index],
+                    loc: loc
+                };
+                comments.push(entry);
+            }
+            this.tolerateUnexpectedToken();
+            return comments;
+        };
+        ;
+        Scanner.prototype.scanComments = function () {
+            var comments;
+            if (this.trackComment) {
+                comments = [];
+            }
+            var start = (this.index === 0);
+            while (!this.eof()) {
+                var ch = this.source.charCodeAt(this.index);
+                if (character_1.Character.isWhiteSpace(ch)) {
+                    ++this.index;
</ins><span class="cx">                 }
</span><del>-            };
-        }
-
-        while (index &lt; length) {
-            ch = source.charCodeAt(index);
-            if (isLineTerminator(ch)) {
-                if (ch === 0x0D &amp;&amp; source.charCodeAt(index + 1) === 0x0A) {
-                    ++index;
</del><ins>+                else if (character_1.Character.isLineTerminator(ch)) {
+                    ++this.index;
+                    if (ch === 0x0D &amp;&amp; this.source.charCodeAt(this.index) === 0x0A) {
+                        ++this.index;
+                    }
+                    ++this.lineNumber;
+                    this.lineStart = this.index;
+                    start = true;
</ins><span class="cx">                 }
</span><del>-                hasLineTerminator = true;
-                ++lineNumber;
-                ++index;
-                lineStart = index;
-            } else if (ch === 0x2A) {
-                // Block comment ends with '*/'.
-                if (source.charCodeAt(index + 1) === 0x2F) {
-                    ++index;
-                    ++index;
-                    if (extra.comments) {
-                        comment = source.slice(start + 2, index - 2);
-                        loc.end = {
-                            line: lineNumber,
-                            column: index - lineStart
-                        };
-                        addComment('Block', comment, start, index, loc);
</del><ins>+                else if (ch === 0x2F) {
+                    ch = this.source.charCodeAt(this.index + 1);
+                    if (ch === 0x2F) {
+                        this.index += 2;
+                        var comment = this.skipSingleLineComment(2);
+                        if (this.trackComment) {
+                            comments = comments.concat(comment);
+                        }
+                        start = true;
</ins><span class="cx">                     }
</span><del>-                    return;
</del><ins>+                    else if (ch === 0x2A) {
+                        this.index += 2;
+                        var comment = this.skipMultiLineComment();
+                        if (this.trackComment) {
+                            comments = comments.concat(comment);
+                        }
+                    }
+                    else {
+                        break;
+                    }
</ins><span class="cx">                 }
</span><del>-                ++index;
-            } else {
-                ++index;
-            }
-        }
-
-        // Ran off the end of the file - the whole thing is a comment
-        if (extra.comments) {
-            loc.end = {
-                line: lineNumber,
-                column: index - lineStart
-            };
-            comment = source.slice(start + 2, index);
-            addComment('Block', comment, start, index, loc);
-        }
-        tolerateUnexpectedToken();
-    }
-
-    function skipComment() {
-        var ch, start;
-        hasLineTerminator = false;
-
-        start = (index === 0);
-        while (index &lt; length) {
-            ch = source.charCodeAt(index);
-
-            if (isWhiteSpace(ch)) {
-                ++index;
-            } else if (isLineTerminator(ch)) {
-                hasLineTerminator = true;
-                ++index;
-                if (ch === 0x0D &amp;&amp; source.charCodeAt(index) === 0x0A) {
-                    ++index;
</del><ins>+                else if (start &amp;&amp; ch === 0x2D) {
+                    // U+003E is '&gt;'
+                    if ((this.source.charCodeAt(this.index + 1) === 0x2D) &amp;&amp; (this.source.charCodeAt(this.index + 2) === 0x3E)) {
+                        // '--&gt;' is a single-line comment
+                        this.index += 3;
+                        var comment = this.skipSingleLineComment(3);
+                        if (this.trackComment) {
+                            comments = comments.concat(comment);
+                        }
+                    }
+                    else {
+                        break;
+                    }
</ins><span class="cx">                 }
</span><del>-                ++lineNumber;
-                lineStart = index;
-                start = true;
-            } else if (ch === 0x2F) { // U+002F is '/'
-                ch = source.charCodeAt(index + 1);
-                if (ch === 0x2F) {
-                    ++index;
-                    ++index;
-                    skipSingleLineComment(2);
-                    start = true;
-                } else if (ch === 0x2A) {  // U+002A is '*'
-                    ++index;
-                    ++index;
-                    skipMultiLineComment();
-                } else {
-                    break;
</del><ins>+                else if (ch === 0x3C) {
+                    if (this.source.slice(this.index + 1, this.index + 4) === '!--') {
+                        this.index += 4; // `&lt;!--`
+                        var comment = this.skipSingleLineComment(4);
+                        if (this.trackComment) {
+                            comments = comments.concat(comment);
+                        }
+                    }
+                    else {
+                        break;
+                    }
</ins><span class="cx">                 }
</span><del>-            } else if (start &amp;&amp; ch === 0x2D) { // U+002D is '-'
-                // U+003E is '&gt;'
-                if ((source.charCodeAt(index + 1) === 0x2D) &amp;&amp; (source.charCodeAt(index + 2) === 0x3E)) {
-                    // '--&gt;' is a single-line comment
-                    index += 3;
-                    skipSingleLineComment(3);
-                } else {
</del><ins>+                else {
</ins><span class="cx">                     break;
</span><span class="cx">                 }
</span><del>-            } else if (ch === 0x3C) { // U+003C is '&lt;'
-                if (source.slice(index + 1, index + 4) === '!--') {
-                    ++index; // `&lt;`
-                    ++index; // `!`
-                    ++index; // `-`
-                    ++index; // `-`
-                    skipSingleLineComment(4);
-                } else {
-                    break;
</del><ins>+            }
+            return comments;
+        };
+        ;
+        // ECMA-262 11.6.2.2 Future Reserved Words
+        Scanner.prototype.isFutureReservedWord = function (id) {
+            switch (id) {
+                case 'enum':
+                case 'export':
+                case 'import':
+                case 'super':
+                    return true;
+                default:
+                    return false;
+            }
+        };
+        ;
+        Scanner.prototype.isStrictModeReservedWord = function (id) {
+            switch (id) {
+                case 'implements':
+                case 'interface':
+                case 'package':
+                case 'private':
+                case 'protected':
+                case 'public':
+                case 'static':
+                case 'yield':
+                case 'let':
+                    return true;
+                default:
+                    return false;
+            }
+        };
+        ;
+        Scanner.prototype.isRestrictedWord = function (id) {
+            return id === 'eval' || id === 'arguments';
+        };
+        ;
+        // ECMA-262 11.6.2.1 Keywords
+        Scanner.prototype.isKeyword = function (id) {
+            switch (id.length) {
+                case 2:
+                    return (id === 'if') || (id === 'in') || (id === 'do');
+                case 3:
+                    return (id === 'var') || (id === 'for') || (id === 'new') ||
+                        (id === 'try') || (id === 'let');
+                case 4:
+                    return (id === 'this') || (id === 'else') || (id === 'case') ||
+                        (id === 'void') || (id === 'with') || (id === 'enum');
+                case 5:
+                    return (id === 'while') || (id === 'break') || (id === 'catch') ||
+                        (id === 'throw') || (id === 'const') || (id === 'yield') ||
+                        (id === 'class') || (id === 'super');
+                case 6:
+                    return (id === 'return') || (id === 'typeof') || (id === 'delete') ||
+                        (id === 'switch') || (id === 'export') || (id === 'import');
+                case 7:
+                    return (id === 'default') || (id === 'finally') || (id === 'extends');
+                case 8:
+                    return (id === 'function') || (id === 'continue') || (id === 'debugger');
+                case 10:
+                    return (id === 'instanceof');
+                default:
+                    return false;
+            }
+        };
+        ;
+        Scanner.prototype.codePointAt = function (i) {
+            var cp = this.source.charCodeAt(i);
+            if (cp &gt;= 0xD800 &amp;&amp; cp &lt;= 0xDBFF) {
+                var second = this.source.charCodeAt(i + 1);
+                if (second &gt;= 0xDC00 &amp;&amp; second &lt;= 0xDFFF) {
+                    var first = cp;
+                    cp = (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
</ins><span class="cx">                 }
</span><del>-            } else {
-                break;
</del><span class="cx">             }
</span><del>-        }
-    }
-
-    function scanHexEscape(prefix) {
-        var i, len, ch, code = 0;
-
-        len = (prefix === 'u') ? 4 : 2;
-        for (i = 0; i &lt; len; ++i) {
-            if (index &lt; length &amp;&amp; isHexDigit(source[index])) {
-                ch = source[index++];
-                code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase());
-            } else {
-                return '';
</del><ins>+            return cp;
+        };
+        ;
+        Scanner.prototype.scanHexEscape = function (prefix) {
+            var len = (prefix === 'u') ? 4 : 2;
+            var code = 0;
+            for (var i = 0; i &lt; len; ++i) {
+                if (!this.eof() &amp;&amp; character_1.Character.isHexDigit(this.source.charCodeAt(this.index))) {
+                    code = code * 16 + hexValue(this.source[this.index++]);
+                }
+                else {
+                    return '';
+                }
</ins><span class="cx">             }
</span><del>-        }
-        return String.fromCharCode(code);
-    }
-
-    function scanUnicodeCodePointEscape() {
-        var ch, code;
-
-        ch = source[index];
-        code = 0;
-
-        // At least, one hex digit is required.
-        if (ch === '}') {
-            throwUnexpectedToken();
-        }
-
-        while (index &lt; length) {
-            ch = source[index++];
-            if (!isHexDigit(ch)) {
-                break;
</del><ins>+            return String.fromCharCode(code);
+        };
+        ;
+        Scanner.prototype.scanUnicodeCodePointEscape = function () {
+            var ch = this.source[this.index];
+            var code = 0;
+            // At least, one hex digit is required.
+            if (ch === '}') {
+                this.throwUnexpectedToken();
</ins><span class="cx">             }
</span><del>-            code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase());
-        }
-
-        if (code &gt; 0x10FFFF || ch !== '}') {
-            throwUnexpectedToken();
-        }
-
-        return fromCodePoint(code);
-    }
-
-    function codePointAt(i) {
-        var cp, first, second;
-
-        cp = source.charCodeAt(i);
-        if (cp &gt;= 0xD800 &amp;&amp; cp &lt;= 0xDBFF) {
-            second = source.charCodeAt(i + 1);
-            if (second &gt;= 0xDC00 &amp;&amp; second &lt;= 0xDFFF) {
-                first = cp;
-                cp = (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
</del><ins>+            while (!this.eof()) {
+                ch = this.source[this.index++];
+                if (!character_1.Character.isHexDigit(ch.charCodeAt(0))) {
+                    break;
+                }
+                code = code * 16 + hexValue(ch);
</ins><span class="cx">             }
</span><del>-        }
-
-        return cp;
-    }
-
-    function getComplexIdentifier() {
-        var cp, ch, id;
-
-        cp = codePointAt(index);
-        id = fromCodePoint(cp);
-        index += id.length;
-
-        // '\u' (U+005C, U+0075) denotes an escaped character.
-        if (cp === 0x5C) {
-            if (source.charCodeAt(index) !== 0x75) {
-                throwUnexpectedToken();
</del><ins>+            if (code &gt; 0x10FFFF || ch !== '}') {
+                this.throwUnexpectedToken();
</ins><span class="cx">             }
</span><del>-            ++index;
-            if (source[index] === '{') {
-                ++index;
-                ch = scanUnicodeCodePointEscape();
-            } else {
-                ch = scanHexEscape('u');
-                cp = ch.charCodeAt(0);
-                if (!ch || ch === '\\' || !isIdentifierStart(cp)) {
-                    throwUnexpectedToken();
</del><ins>+            return character_1.Character.fromCodePoint(code);
+        };
+        ;
+        Scanner.prototype.getIdentifier = function () {
+            var start = this.index++;
+            while (!this.eof()) {
+                var ch = this.source.charCodeAt(this.index);
+                if (ch === 0x5C) {
+                    // Blackslash (U+005C) marks Unicode escape sequence.
+                    this.index = start;
+                    return this.getComplexIdentifier();
</ins><span class="cx">                 }
</span><ins>+                else if (ch &gt;= 0xD800 &amp;&amp; ch &lt; 0xDFFF) {
+                    // Need to handle surrogate pairs.
+                    this.index = start;
+                    return this.getComplexIdentifier();
+                }
+                if (character_1.Character.isIdentifierPart(ch)) {
+                    ++this.index;
+                }
+                else {
+                    break;
+                }
</ins><span class="cx">             }
</span><del>-            id = ch;
-        }
-
-        while (index &lt; length) {
-            cp = codePointAt(index);
-            if (!isIdentifierPart(cp)) {
-                break;
-            }
-            ch = fromCodePoint(cp);
-            id += ch;
-            index += ch.length;
-
</del><ins>+            return this.source.slice(start, this.index);
+        };
+        ;
+        Scanner.prototype.getComplexIdentifier = function () {
+            var cp = this.codePointAt(this.index);
+            var id = character_1.Character.fromCodePoint(cp);
+            this.index += id.length;
</ins><span class="cx">             // '\u' (U+005C, U+0075) denotes an escaped character.
</span><ins>+            var ch;
</ins><span class="cx">             if (cp === 0x5C) {
</span><del>-                id = id.substr(0, id.length - 1);
-                if (source.charCodeAt(index) !== 0x75) {
-                    throwUnexpectedToken();
</del><ins>+                if (this.source.charCodeAt(this.index) !== 0x75) {
+                    this.throwUnexpectedToken();
</ins><span class="cx">                 }
</span><del>-                ++index;
-                if (source[index] === '{') {
-                    ++index;
-                    ch = scanUnicodeCodePointEscape();
-                } else {
-                    ch = scanHexEscape('u');
</del><ins>+                ++this.index;
+                if (this.source[this.index] === '{') {
+                    ++this.index;
+                    ch = this.scanUnicodeCodePointEscape();
+                }
+                else {
+                    ch = this.scanHexEscape('u');
</ins><span class="cx">                     cp = ch.charCodeAt(0);
</span><del>-                    if (!ch || ch === '\\' || !isIdentifierPart(cp)) {
-                        throwUnexpectedToken();
</del><ins>+                    if (!ch || ch === '\\' || !character_1.Character.isIdentifierStart(cp)) {
+                        this.throwUnexpectedToken();
</ins><span class="cx">                     }
</span><span class="cx">                 }
</span><ins>+                id = ch;
+            }
+            while (!this.eof()) {
+                cp = this.codePointAt(this.index);
+                if (!character_1.Character.isIdentifierPart(cp)) {
+                    break;
+                }
+                ch = character_1.Character.fromCodePoint(cp);
</ins><span class="cx">                 id += ch;
</span><ins>+                this.index += ch.length;
+                // '\u' (U+005C, U+0075) denotes an escaped character.
+                if (cp === 0x5C) {
+                    id = id.substr(0, id.length - 1);
+                    if (this.source.charCodeAt(this.index) !== 0x75) {
+                        this.throwUnexpectedToken();
+                    }
+                    ++this.index;
+                    if (this.source[this.index] === '{') {
+                        ++this.index;
+                        ch = this.scanUnicodeCodePointEscape();
+                    }
+                    else {
+                        ch = this.scanHexEscape('u');
+                        cp = ch.charCodeAt(0);
+                        if (!ch || ch === '\\' || !character_1.Character.isIdentifierPart(cp)) {
+                            this.throwUnexpectedToken();
+                        }
+                    }
+                    id += ch;
+                }
</ins><span class="cx">             }
</span><del>-        }
-
-        return id;
-    }
-
-    function getIdentifier() {
-        var start, ch;
-
-        start = index++;
-        while (index &lt; length) {
-            ch = source.charCodeAt(index);
-            if (ch === 0x5C) {
-                // Blackslash (U+005C) marks Unicode escape sequence.
-                index = start;
-                return getComplexIdentifier();
-            } else if (ch &gt;= 0xD800 &amp;&amp; ch &lt; 0xDFFF) {
-                // Need to handle surrogate pairs.
-                index = start;
-                return getComplexIdentifier();
</del><ins>+            return id;
+        };
+        ;
+        Scanner.prototype.octalToDecimal = function (ch) {
+            // \0 is not octal escape sequence
+            var octal = (ch !== '0');
+            var code = octalValue(ch);
+            if (!this.eof() &amp;&amp; character_1.Character.isOctalDigit(this.source.charCodeAt(this.index))) {
+                octal = true;
+                code = code * 8 + octalValue(this.source[this.index++]);
+                // 3 digits are only allowed when string starts
+                // with 0, 1, 2, 3
+                if ('0123'.indexOf(ch) &gt;= 0 &amp;&amp; !this.eof() &amp;&amp; character_1.Character.isOctalDigit(this.source.charCodeAt(this.index))) {
+                    code = code * 8 + octalValue(this.source[this.index++]);
+                }
</ins><span class="cx">             }
</span><del>-            if (isIdentifierPart(ch)) {
-                ++index;
-            } else {
-                break;
-            }
-        }
-
-        return source.slice(start, index);
-    }
-
-    function scanIdentifier() {
-        var start, id, type;
-
-        start = index;
-
-        // Backslash (U+005C) starts an escaped character.
-        id = (source.charCodeAt(index) === 0x5C) ? getComplexIdentifier() : getIdentifier();
-
-        // There is no keyword or literal with only one character.
-        // Thus, it must be an identifier.
-        if (id.length === 1) {
-            type = Token.Identifier;
-        } else if (isKeyword(id)) {
-            type = Token.Keyword;
-        } else if (id === 'null') {
-            type = Token.NullLiteral;
-        } else if (id === 'true' || id === 'false') {
-            type = Token.BooleanLiteral;
-        } else {
-            type = Token.Identifier;
-        }
-
-        return {
-            type: type,
-            value: id,
-            lineNumber: lineNumber,
-            lineStart: lineStart,
-            start: start,
-            end: index
</del><ins>+            return {
+                code: code,
+                octal: octal
+            };
</ins><span class="cx">         };
</span><del>-    }
-
-
-    // ECMA-262 11.7 Punctuators
-
-    function scanPunctuator() {
-        var token, str;
-
-        token = {
-            type: Token.Punctuator,
-            value: '',
-            lineNumber: lineNumber,
-            lineStart: lineStart,
-            start: index,
-            end: index
-        };
-
-        // Check for most common single-character punctuators.
-        str = source[index];
-        switch (str) {
-
-        case '(':
-            if (extra.tokenize) {
-                extra.openParenToken = extra.tokens.length;
</del><ins>+        ;
+        // ECMA-262 11.6 Names and Keywords
+        Scanner.prototype.scanIdentifier = function () {
+            var type;
+            var start = this.index;
+            // Backslash (U+005C) starts an escaped character.
+            var id = (this.source.charCodeAt(start) === 0x5C) ? this.getComplexIdentifier() : this.getIdentifier();
+            // There is no keyword or literal with only one character.
+            // Thus, it must be an identifier.
+            if (id.length === 1) {
+                type = token_1.Token.Identifier;
</ins><span class="cx">             }
</span><del>-            ++index;
-            break;
-
-        case '{':
-            if (extra.tokenize) {
-                extra.openCurlyToken = extra.tokens.length;
</del><ins>+            else if (this.isKeyword(id)) {
+                type = token_1.Token.Keyword;
</ins><span class="cx">             }
</span><del>-            state.curlyStack.push('{');
-            ++index;
-            break;
-
-        case '.':
-            ++index;
-            if (source[index] === '.' &amp;&amp; source[index + 1] === '.') {
-                // Spread operator: ...
-                index += 2;
-                str = '...';
</del><ins>+            else if (id === 'null') {
+                type = token_1.Token.NullLiteral;
</ins><span class="cx">             }
</span><del>-            break;
-
-        case '}':
-            ++index;
-            state.curlyStack.pop();
-            break;
-        case ')':
-        case ';':
-        case ',':
-        case '[':
-        case ']':
-        case ':':
-        case '?':
-        case '~':
-            ++index;
-            break;
-
-        default:
-            // 4-character punctuator.
-            str = source.substr(index, 4);
-            if (str === '&gt;&gt;&gt;=') {
-                index += 4;
-            } else {
-
-                // 3-character punctuators.
-                str = str.substr(0, 3);
-                if (str === '===' || str === '!==' || str === '&gt;&gt;&gt;' ||
-                    str === '&lt;&lt;=' || str === '&gt;&gt;=') {
-                    index += 3;
-                } else {
-
-                    // 2-character punctuators.
-                    str = str.substr(0, 2);
-                    if (str === '&amp;&amp;' || str === '||' || str === '==' || str === '!=' ||
-                        str === '+=' || str === '-=' || str === '*=' || str === '/=' ||
-                        str === '++' || str === '--' || str === '&lt;&lt;' || str === '&gt;&gt;' ||
-                        str === '&amp;=' || str === '|=' || str === '^=' || str === '%=' ||
-                        str === '&lt;=' || str === '&gt;=' || str === '=&gt;') {
-                        index += 2;
-                    } else {
-
-                        // 1-character punctuators.
-                        str = source[index];
-                        if ('&lt;&gt;=!+-*%&amp;|^/'.indexOf(str) &gt;= 0) {
-                            ++index;
</del><ins>+            else if (id === 'true' || id === 'false') {
+                type = token_1.Token.BooleanLiteral;
+            }
+            else {
+                type = token_1.Token.Identifier;
+            }
+            return {
+                type: type,
+                value: id,
+                lineNumber: this.lineNumber,
+                lineStart: this.lineStart,
+                start: start,
+                end: this.index
+            };
+        };
+        ;
+        // ECMA-262 11.7 Punctuators
+        Scanner.prototype.scanPunctuator = function () {
+            var token = {
+                type: token_1.Token.Punctuator,
+                value: '',
+                lineNumber: this.lineNumber,
+                lineStart: this.lineStart,
+                start: this.index,
+                end: this.index
+            };
+            // Check for most common single-character punctuators.
+            var str = this.source[this.index];
+            switch (str) {
+                case '(':
+                case '{':
+                    if (str === '{') {
+                        this.curlyStack.push('{');
+                    }
+                    ++this.index;
+                    break;
+                case '.':
+                    ++this.index;
+                    if (this.source[this.index] === '.' &amp;&amp; this.source[this.index + 1] === '.') {
+                        // Spread operator: ...
+                        this.index += 2;
+                        str = '...';
+                    }
+                    break;
+                case '}':
+                    ++this.index;
+                    this.curlyStack.pop();
+                    break;
+                case ')':
+                case ';':
+                case ',':
+                case '[':
+                case ']':
+                case ':':
+                case '?':
+                case '~':
+                    ++this.index;
+                    break;
+                default:
+                    // 4-character punctuator.
+                    str = this.source.substr(this.index, 4);
+                    if (str === '&gt;&gt;&gt;=') {
+                        this.index += 4;
+                    }
+                    else {
+                        // 3-character punctuators.
+                        str = str.substr(0, 3);
+                        if (str === '===' || str === '!==' || str === '&gt;&gt;&gt;' ||
+                            str === '&lt;&lt;=' || str === '&gt;&gt;=' || str === '**=') {
+                            this.index += 3;
</ins><span class="cx">                         }
</span><ins>+                        else {
+                            // 2-character punctuators.
+                            str = str.substr(0, 2);
+                            if (str === '&amp;&amp;' || str === '||' || str === '==' || str === '!=' ||
+                                str === '+=' || str === '-=' || str === '*=' || str === '/=' ||
+                                str === '++' || str === '--' || str === '&lt;&lt;' || str === '&gt;&gt;' ||
+                                str === '&amp;=' || str === '|=' || str === '^=' || str === '%=' ||
+                                str === '&lt;=' || str === '&gt;=' || str === '=&gt;' || str === '**') {
+                                this.index += 2;
+                            }
+                            else {
+                                // 1-character punctuators.
+                                str = this.source[this.index];
+                                if ('&lt;&gt;=!+-*%&amp;|^/'.indexOf(str) &gt;= 0) {
+                                    ++this.index;
+                                }
+                            }
+                        }
</ins><span class="cx">                     }
</span><del>-                }
</del><span class="cx">             }
</span><del>-        }
-
-        if (index === token.start) {
-            throwUnexpectedToken();
-        }
-
-        token.end = index;
-        token.value = str;
-        return token;
-    }
-
-    // ECMA-262 11.8.3 Numeric Literals
-
-    function scanHexLiteral(start) {
-        var number = '';
-
-        while (index &lt; length) {
-            if (!isHexDigit(source[index])) {
-                break;
</del><ins>+            if (this.index === token.start) {
+                this.throwUnexpectedToken();
</ins><span class="cx">             }
</span><del>-            number += source[index++];
-        }
-
-        if (number.length === 0) {
-            throwUnexpectedToken();
-        }
-
-        if (isIdentifierStart(source.charCodeAt(index))) {
-            throwUnexpectedToken();
-        }
-
-        return {
-            type: Token.NumericLiteral,
-            value: parseInt('0x' + number, 16),
-            lineNumber: lineNumber,
-            lineStart: lineStart,
-            start: start,
-            end: index
</del><ins>+            token.end = this.index;
+            token.value = str;
+            return token;
</ins><span class="cx">         };
</span><del>-    }
-
-    function scanBinaryLiteral(start) {
-        var ch, number;
-
-        number = '';
-
-        while (index &lt; length) {
-            ch = source[index];
-            if (ch !== '0' &amp;&amp; ch !== '1') {
-                break;
</del><ins>+        ;
+        // ECMA-262 11.8.3 Numeric Literals
+        Scanner.prototype.scanHexLiteral = function (start) {
+            var number = '';
+            while (!this.eof()) {
+                if (!character_1.Character.isHexDigit(this.source.charCodeAt(this.index))) {
+                    break;
+                }
+                number += this.source[this.index++];
</ins><span class="cx">             }
</span><del>-            number += source[index++];
-        }
-
-        if (number.length === 0) {
-            // only 0b or 0B
-            throwUnexpectedToken();
-        }
-
-        if (index &lt; length) {
-            ch = source.charCodeAt(index);
-            /* istanbul ignore else */
-            if (isIdentifierStart(ch) || isDecimalDigit(ch)) {
-                throwUnexpectedToken();
</del><ins>+            if (number.length === 0) {
+                this.throwUnexpectedToken();
</ins><span class="cx">             }
</span><del>-        }
-
-        return {
-            type: Token.NumericLiteral,
-            value: parseInt(number, 2),
-            lineNumber: lineNumber,
-            lineStart: lineStart,
-            start: start,
-            end: index
</del><ins>+            if (character_1.Character.isIdentifierStart(this.source.charCodeAt(this.index))) {
+                this.throwUnexpectedToken();
+            }
+            return {
+                type: token_1.Token.NumericLiteral,
+                value: parseInt('0x' + number, 16),
+                lineNumber: this.lineNumber,
+                lineStart: this.lineStart,
+                start: start,
+                end: this.index
+            };
</ins><span class="cx">         };
</span><del>-    }
-
-    function scanOctalLiteral(prefix, start) {
-        var number, octal;
-
-        if (isOctalDigit(prefix)) {
-            octal = true;
-            number = '0' + source[index++];
-        } else {
-            octal = false;
-            ++index;
-            number = '';
-        }
-
-        while (index &lt; length) {
-            if (!isOctalDigit(source[index])) {
-                break;
</del><ins>+        ;
+        Scanner.prototype.scanBinaryLiteral = function (start) {
+            var number = '';
+            var ch;
+            while (!this.eof()) {
+                ch = this.source[this.index];
+                if (ch !== '0' &amp;&amp; ch !== '1') {
+                    break;
+                }
+                number += this.source[this.index++];
</ins><span class="cx">             }
</span><del>-            number += source[index++];
-        }
-
-        if (!octal &amp;&amp; number.length === 0) {
-            // only 0o or 0O
-            throwUnexpectedToken();
-        }
-
-        if (isIdentifierStart(source.charCodeAt(index)) || isDecimalDigit(source.charCodeAt(index))) {
-            throwUnexpectedToken();
-        }
-
-        return {
-            type: Token.NumericLiteral,
-            value: parseInt(number, 8),
-            octal: octal,
-            lineNumber: lineNumber,
-            lineStart: lineStart,
-            start: start,
-            end: index
</del><ins>+            if (number.length === 0) {
+                // only 0b or 0B
+                this.throwUnexpectedToken();
+            }
+            if (!this.eof()) {
+                ch = this.source.charCodeAt(this.index);
+                /* istanbul ignore else */
+                if (character_1.Character.isIdentifierStart(ch) || character_1.Character.isDecimalDigit(ch)) {
+                    this.throwUnexpectedToken();
+                }
+            }
+            return {
+                type: token_1.Token.NumericLiteral,
+                value: parseInt(number, 2),
+                lineNumber: this.lineNumber,
+                lineStart: this.lineStart,
+                start: start,
+                end: this.index
+            };
</ins><span class="cx">         };
</span><del>-    }
-
-    function isImplicitOctalLiteral() {
-        var i, ch;
-
-        // Implicit octal, unless there is a non-octal digit.
-        // (Annex B.1.1 on Numeric Literals)
-        for (i = index + 1; i &lt; length; ++i) {
-            ch = source[i];
-            if (ch === '8' || ch === '9') {
-                return false;
</del><ins>+        ;
+        Scanner.prototype.scanOctalLiteral = function (prefix, start) {
+            var number = '';
+            var octal = false;
+            if (character_1.Character.isOctalDigit(prefix.charCodeAt(0))) {
+                octal = true;
+                number = '0' + this.source[this.index++];
</ins><span class="cx">             }
</span><del>-            if (!isOctalDigit(ch)) {
-                return true;
</del><ins>+            else {
+                ++this.index;
</ins><span class="cx">             }
</span><del>-        }
-
-        return true;
-    }
-
-    function scanNumericLiteral() {
-        var number, start, ch;
-
-        ch = source[index];
-        assert(isDecimalDigit(ch.charCodeAt(0)) || (ch === '.'),
-            'Numeric literal must start with a decimal digit or a decimal point');
-
-        start = index;
-        number = '';
-        if (ch !== '.') {
-            number = source[index++];
-            ch = source[index];
-
-            // Hex number starts with '0x'.
-            // Octal number starts with '0'.
-            // Octal number in ES6 starts with '0o'.
-            // Binary number in ES6 starts with '0b'.
-            if (number === '0') {
-                if (ch === 'x' || ch === 'X') {
-                    ++index;
-                    return scanHexLiteral(start);
</del><ins>+            while (!this.eof()) {
+                if (!character_1.Character.isOctalDigit(this.source.charCodeAt(this.index))) {
+                    break;
</ins><span class="cx">                 }
</span><del>-                if (ch === 'b' || ch === 'B') {
-                    ++index;
-                    return scanBinaryLiteral(start);
</del><ins>+                number += this.source[this.index++];
+            }
+            if (!octal &amp;&amp; number.length === 0) {
+                // only 0o or 0O
+                this.throwUnexpectedToken();
+            }
+            if (character_1.Character.isIdentifierStart(this.source.charCodeAt(this.index)) || character_1.Character.isDecimalDigit(this.source.charCodeAt(this.index))) {
+                this.throwUnexpectedToken();
+            }
+            return {
+                type: token_1.Token.NumericLiteral,
+                value: parseInt(number, 8),
+                octal: octal,
+                lineNumber: this.lineNumber,
+                lineStart: this.lineStart,
+                start: start,
+                end: this.index
+            };
+        };
+        ;
+        Scanner.prototype.isImplicitOctalLiteral = function () {
+            // Implicit octal, unless there is a non-octal digit.
+            // (Annex B.1.1 on Numeric Literals)
+            for (var i = this.index + 1; i &lt; this.length; ++i) {
+                var ch = this.source[i];
+                if (ch === '8' || ch === '9') {
+                    return false;
</ins><span class="cx">                 }
</span><del>-                if (ch === 'o' || ch === 'O') {
-                    return scanOctalLiteral(ch, start);
</del><ins>+                if (!character_1.Character.isOctalDigit(ch.charCodeAt(0))) {
+                    return true;
</ins><span class="cx">                 }
</span><del>-
-                if (isOctalDigit(ch)) {
-                    if (isImplicitOctalLiteral()) {
-                        return scanOctalLiteral(ch, start);
</del><ins>+            }
+            return true;
+        };
+        ;
+        Scanner.prototype.scanNumericLiteral = function () {
+            var start = this.index;
+            var ch = this.source[start];
+            assert_1.assert(character_1.Character.isDecimalDigit(ch.charCodeAt(0)) || (ch === '.'), 'Numeric literal must start with a decimal digit or a decimal point');
+            var number = '';
+            if (ch !== '.') {
+                number = this.source[this.index++];
+                ch = this.source[this.index];
+                // Hex number starts with '0x'.
+                // Octal number starts with '0'.
+                // Octal number in ES6 starts with '0o'.
+                // Binary number in ES6 starts with '0b'.
+                if (number === '0') {
+                    if (ch === 'x' || ch === 'X') {
+                        ++this.index;
+                        return this.scanHexLiteral(start);
</ins><span class="cx">                     }
</span><ins>+                    if (ch === 'b' || ch === 'B') {
+                        ++this.index;
+                        return this.scanBinaryLiteral(start);
+                    }
+                    if (ch === 'o' || ch === 'O') {
+                        return this.scanOctalLiteral(ch, start);
+                    }
+                    if (ch &amp;&amp; character_1.Character.isOctalDigit(ch.charCodeAt(0))) {
+                        if (this.isImplicitOctalLiteral()) {
+                            return this.scanOctalLiteral(ch, start);
+                        }
+                    }
</ins><span class="cx">                 }
</span><ins>+                while (character_1.Character.isDecimalDigit(this.source.charCodeAt(this.index))) {
+                    number += this.source[this.index++];
+                }
+                ch = this.source[this.index];
</ins><span class="cx">             }
</span><del>-
-            while (isDecimalDigit(source.charCodeAt(index))) {
-                number += source[index++];
</del><ins>+            if (ch === '.') {
+                number += this.source[this.index++];
+                while (character_1.Character.isDecimalDigit(this.source.charCodeAt(this.index))) {
+                    number += this.source[this.index++];
+                }
+                ch = this.source[this.index];
</ins><span class="cx">             }
</span><del>-            ch = source[index];
-        }
-
-        if (ch === '.') {
-            number += source[index++];
-            while (isDecimalDigit(source.charCodeAt(index))) {
-                number += source[index++];
</del><ins>+            if (ch === 'e' || ch === 'E') {
+                number += this.source[this.index++];
+                ch = this.source[this.index];
+                if (ch === '+' || ch === '-') {
+                    number += this.source[this.index++];
+                }
+                if (character_1.Character.isDecimalDigit(this.source.charCodeAt(this.index))) {
+                    while (character_1.Character.isDecimalDigit(this.source.charCodeAt(this.index))) {
+                        number += this.source[this.index++];
+                    }
+                }
+                else {
+                    this.throwUnexpectedToken();
+                }
</ins><span class="cx">             }
</span><del>-            ch = source[index];
-        }
-
-        if (ch === 'e' || ch === 'E') {
-            number += source[index++];
-
-            ch = source[index];
-            if (ch === '+' || ch === '-') {
-                number += source[index++];
</del><ins>+            if (character_1.Character.isIdentifierStart(this.source.charCodeAt(this.index))) {
+                this.throwUnexpectedToken();
</ins><span class="cx">             }
</span><del>-            if (isDecimalDigit(source.charCodeAt(index))) {
-                while (isDecimalDigit(source.charCodeAt(index))) {
-                    number += source[index++];
</del><ins>+            return {
+                type: token_1.Token.NumericLiteral,
+                value: parseFloat(number),
+                lineNumber: this.lineNumber,
+                lineStart: this.lineStart,
+                start: start,
+                end: this.index
+            };
+        };
+        ;
+        // ECMA-262 11.8.4 String Literals
+        Scanner.prototype.scanStringLiteral = function () {
+            var start = this.index;
+            var quote = this.source[start];
+            assert_1.assert((quote === '\'' || quote === '&quot;'), 'String literal must starts with a quote');
+            ++this.index;
+            var octal = false;
+            var str = '';
+            while (!this.eof()) {
+                var ch = this.source[this.index++];
+                if (ch === quote) {
+                    quote = '';
+                    break;
</ins><span class="cx">                 }
</span><del>-            } else {
-                throwUnexpectedToken();
-            }
-        }
-
-        if (isIdentifierStart(source.charCodeAt(index))) {
-            throwUnexpectedToken();
-        }
-
-        return {
-            type: Token.NumericLiteral,
-            value: parseFloat(number),
-            lineNumber: lineNumber,
-            lineStart: lineStart,
-            start: start,
-            end: index
-        };
-    }
-
-    // ECMA-262 11.8.4 String Literals
-
-    function scanStringLiteral() {
-        var str = '', quote, start, ch, unescaped, octToDec, octal = false;
-
-        quote = source[index];
-        assert((quote === '\'' || quote === '&quot;'),
-            'String literal must starts with a quote');
-
-        start = index;
-        ++index;
-
-        while (index &lt; length) {
-            ch = source[index++];
-
-            if (ch === quote) {
-                quote = '';
-                break;
-            } else if (ch === '\\') {
-                ch = source[index++];
-                if (!ch || !isLineTerminator(ch.charCodeAt(0))) {
-                    switch (ch) {
-                    case 'u':
-                    case 'x':
-                        if (source[index] === '{') {
-                            ++index;
-                            str += scanUnicodeCodePointEscape();
-                        } else {
-                            unescaped = scanHexEscape(ch);
-                            if (!unescaped) {
-                                throw throwUnexpectedToken();
-                            }
-                            str += unescaped;
</del><ins>+                else if (ch === '\\') {
+                    ch = this.source[this.index++];
+                    if (!ch || !character_1.Character.isLineTerminator(ch.charCodeAt(0))) {
+                        switch (ch) {
+                            case 'u':
+                            case 'x':
+                                if (this.source[this.index] === '{') {
+                                    ++this.index;
+                                    str += this.scanUnicodeCodePointEscape();
+                                }
+                                else {
+                                    var unescaped = this.scanHexEscape(ch);
+                                    if (!unescaped) {
+                                        this.throwUnexpectedToken();
+                                    }
+                                    str += unescaped;
+                                }
+                                break;
+                            case 'n':
+                                str += '\n';
+                                break;
+                            case 'r':
+                                str += '\r';
+                                break;
+                            case 't':
+                                str += '\t';
+                                break;
+                            case 'b':
+                                str += '\b';
+                                break;
+                            case 'f':
+                                str += '\f';
+                                break;
+                            case 'v':
+                                str += '\x0B';
+                                break;
+                            case '8':
+                            case '9':
+                                str += ch;
+                                this.tolerateUnexpectedToken();
+                                break;
+                            default:
+                                if (ch &amp;&amp; character_1.Character.isOctalDigit(ch.charCodeAt(0))) {
+                                    var octToDec = this.octalToDecimal(ch);
+                                    octal = octToDec.octal || octal;
+                                    str += String.fromCharCode(octToDec.code);
+                                }
+                                else {
+                                    str += ch;
+                                }
+                                break;
</ins><span class="cx">                         }
</span><del>-                        break;
-                    case 'n':
-                        str += '\n';
-                        break;
-                    case 'r':
-                        str += '\r';
-                        break;
-                    case 't':
-                        str += '\t';
-                        break;
-                    case 'b':
-                        str += '\b';
-                        break;
-                    case 'f':
-                        str += '\f';
-                        break;
-                    case 'v':
-                        str += '\x0B';
-                        break;
-                    case '8':
-                    case '9':
-                        str += ch;
-                        tolerateUnexpectedToken();
-                        break;
-
-                    default:
-                        if (isOctalDigit(ch)) {
-                            octToDec = octalToDecimal(ch);
-
-                            octal = octToDec.octal || octal;
-                            str += String.fromCharCode(octToDec.code);
-                        } else {
-                            str += ch;
</del><ins>+                    }
+                    else {
+                        ++this.lineNumber;
+                        if (ch === '\r' &amp;&amp; this.source[this.index] === '\n') {
+                            ++this.index;
</ins><span class="cx">                         }
</span><del>-                        break;
</del><ins>+                        this.lineStart = this.index;
</ins><span class="cx">                     }
</span><del>-                } else {
-                    ++lineNumber;
-                    if (ch === '\r' &amp;&amp; source[index] === '\n') {
-                        ++index;
-                    }
-                    lineStart = index;
</del><span class="cx">                 }
</span><del>-            } else if (isLineTerminator(ch.charCodeAt(0))) {
-                break;
-            } else {
-                str += ch;
</del><ins>+                else if (character_1.Character.isLineTerminator(ch.charCodeAt(0))) {
+                    break;
+                }
+                else {
+                    str += ch;
+                }
</ins><span class="cx">             }
</span><del>-        }
-
-        if (quote !== '') {
-            throwUnexpectedToken();
-        }
-
-        return {
-            type: Token.StringLiteral,
-            value: str,
-            octal: octal,
-            lineNumber: startLineNumber,
-            lineStart: startLineStart,
-            start: start,
-            end: index
</del><ins>+            if (quote !== '') {
+                this.index = start;
+                this.throwUnexpectedToken();
+            }
+            return {
+                type: token_1.Token.StringLiteral,
+                value: str,
+                octal: octal,
+                lineNumber: this.lineNumber,
+                lineStart: this.lineStart,
+                start: start,
+                end: this.index
+            };
</ins><span class="cx">         };
</span><del>-    }
-
-    // ECMA-262 11.8.6 Template Literal Lexical Components
-
-    function scanTemplate() {
-        var cooked = '', ch, start, rawOffset, terminated, head, tail, restore, unescaped;
-
-        terminated = false;
-        tail = false;
-        start = index;
-        head = (source[index] === '`');
-        rawOffset = 2;
-
-        ++index;
-
-        while (index &lt; length) {
-            ch = source[index++];
-            if (ch === '`') {
-                rawOffset = 1;
-                tail = true;
-                terminated = true;
-                break;
-            } else if (ch === '$') {
-                if (source[index] === '{') {
-                    state.curlyStack.push('${');
-                    ++index;
</del><ins>+        ;
+        // ECMA-262 11.8.6 Template Literal Lexical Components
+        Scanner.prototype.scanTemplate = function () {
+            var cooked = '';
+            var terminated = false;
+            var start = this.index;
+            var head = (this.source[start] === '`');
+            var tail = false;
+            var rawOffset = 2;
+            ++this.index;
+            while (!this.eof()) {
+                var ch = this.source[this.index++];
+                if (ch === '`') {
+                    rawOffset = 1;
+                    tail = true;
</ins><span class="cx">                     terminated = true;
</span><span class="cx">                     break;
</span><span class="cx">                 }
</span><del>-                cooked += ch;
-            } else if (ch === '\\') {
-                ch = source[index++];
-                if (!isLineTerminator(ch.charCodeAt(0))) {
-                    switch (ch) {
-                    case 'n':
-                        cooked += '\n';
</del><ins>+                else if (ch === '$') {
+                    if (this.source[this.index] === '{') {
+                        this.curlyStack.push('${');
+                        ++this.index;
+                        terminated = true;
</ins><span class="cx">                         break;
</span><del>-                    case 'r':
-                        cooked += '\r';
-                        break;
-                    case 't':
-                        cooked += '\t';
-                        break;
-                    case 'u':
-                    case 'x':
-                        if (source[index] === '{') {
-                            ++index;
-                            cooked += scanUnicodeCodePointEscape();
-                        } else {
-                            restore = index;
-                            unescaped = scanHexEscape(ch);
-                            if (unescaped) {
-                                cooked += unescaped;
-                            } else {
-                                index = restore;
-                                cooked += ch;
-                            }
</del><ins>+                    }
+                    cooked += ch;
+                }
+                else if (ch === '\\') {
+                    ch = this.source[this.index++];
+                    if (!character_1.Character.isLineTerminator(ch.charCodeAt(0))) {
+                        switch (ch) {
+                            case 'n':
+                                cooked += '\n';
+                                break;
+                            case 'r':
+                                cooked += '\r';
+                                break;
+                            case 't':
+                                cooked += '\t';
+                                break;
+                            case 'u':
+                            case 'x':
+                                if (this.source[this.index] === '{') {
+                                    ++this.index;
+                                    cooked += this.scanUnicodeCodePointEscape();
+                                }
+                                else {
+                                    var restore = this.index;
+                                    var unescaped = this.scanHexEscape(ch);
+                                    if (unescaped) {
+                                        cooked += unescaped;
+                                    }
+                                    else {
+                                        this.index = restore;
+                                        cooked += ch;
+                                    }
+                                }
+                                break;
+                            case 'b':
+                                cooked += '\b';
+                                break;
+                            case 'f':
+                                cooked += '\f';
+                                break;
+                            case 'v':
+                                cooked += '\v';
+                                break;
+                            default:
+                                if (ch === '0') {
+                                    if (character_1.Character.isDecimalDigit(this.source.charCodeAt(this.index))) {
+                                        // Illegal: \01 \02 and so on
+                                        this.throwUnexpectedToken(messages_1.Messages.TemplateOctalLiteral);
+                                    }
+                                    cooked += '\0';
+                                }
+                                else if (character_1.Character.isOctalDigit(ch.charCodeAt(0))) {
+                                    // Illegal: \1 \2
+                                    this.throwUnexpectedToken(messages_1.Messages.TemplateOctalLiteral);
+                                }
+                                else {
+                                    cooked += ch;
+                                }
+                                break;
</ins><span class="cx">                         }
</span><del>-                        break;
-                    case 'b':
-                        cooked += '\b';
-                        break;
-                    case 'f':
-                        cooked += '\f';
-                        break;
-                    case 'v':
-                        cooked += '\v';
-                        break;
-
-                    default:
-                        if (ch === '0') {
-                            if (isDecimalDigit(source.charCodeAt(index))) {
-                                // Illegal: \01 \02 and so on
-                                throwError(Messages.TemplateOctalLiteral);
-                            }
-                            cooked += '\0';
-                        } else if (isOctalDigit(ch)) {
-                            // Illegal: \1 \2
-                            throwError(Messages.TemplateOctalLiteral);
-                        } else {
-                            cooked += ch;
</del><ins>+                    }
+                    else {
+                        ++this.lineNumber;
+                        if (ch === '\r' &amp;&amp; this.source[this.index] === '\n') {
+                            ++this.index;
</ins><span class="cx">                         }
</span><del>-                        break;
</del><ins>+                        this.lineStart = this.index;
</ins><span class="cx">                     }
</span><del>-                } else {
-                    ++lineNumber;
-                    if (ch === '\r' &amp;&amp; source[index] === '\n') {
-                        ++index;
</del><ins>+                }
+                else if (character_1.Character.isLineTerminator(ch.charCodeAt(0))) {
+                    ++this.lineNumber;
+                    if (ch === '\r' &amp;&amp; this.source[this.index] === '\n') {
+                        ++this.index;
</ins><span class="cx">                     }
</span><del>-                    lineStart = index;
</del><ins>+                    this.lineStart = this.index;
+                    cooked += '\n';
</ins><span class="cx">                 }
</span><del>-            } else if (isLineTerminator(ch.charCodeAt(0))) {
-                ++lineNumber;
-                if (ch === '\r' &amp;&amp; source[index] === '\n') {
-                    ++index;
</del><ins>+                else {
+                    cooked += ch;
</ins><span class="cx">                 }
</span><del>-                lineStart = index;
-                cooked += '\n';
-            } else {
-                cooked += ch;
</del><span class="cx">             }
</span><del>-        }
-
-        if (!terminated) {
-            throwUnexpectedToken();
-        }
-
-        if (!head) {
-            state.curlyStack.pop();
-        }
-
-        return {
-            type: Token.Template,
-            value: {
-                cooked: cooked,
-                raw: source.slice(start + 1, index - rawOffset)
-            },
-            head: head,
-            tail: tail,
-            lineNumber: lineNumber,
-            lineStart: lineStart,
-            start: start,
-            end: index
</del><ins>+            if (!terminated) {
+                this.throwUnexpectedToken();
+            }
+            if (!head) {
+                this.curlyStack.pop();
+            }
+            return {
+                type: token_1.Token.Template,
+                value: {
+                    cooked: cooked,
+                    raw: this.source.slice(start + 1, this.index - rawOffset)
+                },
+                head: head,
+                tail: tail,
+                lineNumber: this.lineNumber,
+                lineStart: this.lineStart,
+                start: start,
+                end: this.index
+            };
</ins><span class="cx">         };
</span><del>-    }
-
-    // ECMA-262 11.8.5 Regular Expression Literals
-
-    function testRegExp(pattern, flags) {
-        // The BMP character to use as a replacement for astral symbols when
-        // translating an ES6 &quot;u&quot;-flagged pattern to an ES5-compatible
-        // approximation.
-        // Note: replacing with '\uFFFF' enables false positives in unlikely
-        // scenarios. For example, `[\u{1044f}-\u{10440}]` is an invalid
-        // pattern that would not be detected by this substitution.
-        var astralSubstitute = '\uFFFF',
-            tmp = pattern;
-
-        if (flags.indexOf('u') &gt;= 0) {
-            tmp = tmp
-                // Replace every Unicode escape sequence with the equivalent
-                // BMP character or a constant ASCII code point in the case of
-                // astral symbols. (See the above note on `astralSubstitute`
-                // for more information.)
-                .replace(/\\u\{([0-9a-fA-F]+)\}|\\u([a-fA-F0-9]{4})/g, function ($0, $1, $2) {
</del><ins>+        ;
+        // ECMA-262 11.8.5 Regular Expression Literals
+        Scanner.prototype.testRegExp = function (pattern, flags) {
+            // The BMP character to use as a replacement for astral symbols when
+            // translating an ES6 &quot;u&quot;-flagged pattern to an ES5-compatible
+            // approximation.
+            // Note: replacing with '\uFFFF' enables false positives in unlikely
+            // scenarios. For example, `[\u{1044f}-\u{10440}]` is an invalid
+            // pattern that would not be detected by this substitution.
+            var astralSubstitute = '\uFFFF';
+            var tmp = pattern;
+            var self = this;
+            if (flags.indexOf('u') &gt;= 0) {
+                tmp = tmp
+                    .replace(/\\u\{([0-9a-fA-F]+)\}|\\u([a-fA-F0-9]{4})/g, function ($0, $1, $2) {
</ins><span class="cx">                     var codePoint = parseInt($1 || $2, 16);
</span><span class="cx">                     if (codePoint &gt; 0x10FFFF) {
</span><del>-                        throwUnexpectedToken(null, Messages.InvalidRegExp);
</del><ins>+                        self.throwUnexpectedToken(messages_1.Messages.InvalidRegExp);
</ins><span class="cx">                     }
</span><span class="cx">                     if (codePoint &lt;= 0xFFFF) {
</span><span class="cx">                         return String.fromCharCode(codePoint);
</span><span class="lines">@@ -1300,847 +4650,710 @@
</span><span class="cx">                     }
</span><span class="cx">                     return astralSubstitute;
</span><span class="cx">                 })
</span><del>-                // Replace each paired surrogate with a single ASCII symbol to
-                // avoid throwing on regular expressions that are only valid in
-                // combination with the &quot;u&quot; flag.
-                .replace(
-                    /[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
-                    astralSubstitute
-                );
-        }
-
-        // First, detect invalid regular expressions.
-        try {
-            RegExp(tmp);
-        } catch (e) {
-            throwUnexpectedToken(null, Messages.InvalidRegExp);
-        }
-
-        // Return a regular expression object for this pattern-flag pair, or
-        // `null` in case the current environment doesn't support the flags it
-        // uses.
-        try {
-            return new RegExp(pattern, flags);
-        } catch (exception) {
-            return null;
-        }
-    }
-
-    function scanRegExpBody() {
-        var ch, str, classMarker, terminated, body;
-
-        ch = source[index];
-        assert(ch === '/', 'Regular expression literal must start with a slash');
-        str = source[index++];
-
-        classMarker = false;
-        terminated = false;
-        while (index &lt; length) {
-            ch = source[index++];
-            str += ch;
-            if (ch === '\\') {
-                ch = source[index++];
-                // ECMA-262 7.8.5
-                if (isLineTerminator(ch.charCodeAt(0))) {
-                    throwUnexpectedToken(null, Messages.UnterminatedRegExp);
-                }
</del><ins>+                    .replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, astralSubstitute);
+            }
+            // First, detect invalid regular expressions.
+            try {
+                RegExp(tmp);
+            }
+            catch (e) {
+                this.throwUnexpectedToken(messages_1.Messages.InvalidRegExp);
+            }
+            // Return a regular expression object for this pattern-flag pair, or
+            // `null` in case the current environment doesn't support the flags it
+            // uses.
+            try {
+                return new RegExp(pattern, flags);
+            }
+            catch (exception) {
+                /* istanbul ignore next */
+                return null;
+            }
+        };
+        ;
+        Scanner.prototype.scanRegExpBody = function () {
+            var ch = this.source[this.index];
+            assert_1.assert(ch === '/', 'Regular expression literal must start with a slash');
+            var str = this.source[this.index++];
+            var classMarker = false;
+            var terminated = false;
+            while (!this.eof()) {
+                ch = this.source[this.index++];
</ins><span class="cx">                 str += ch;
</span><del>-            } else if (isLineTerminator(ch.charCodeAt(0))) {
-                throwUnexpectedToken(null, Messages.UnterminatedRegExp);
-            } else if (classMarker) {
-                if (ch === ']') {
-                    classMarker = false;
</del><ins>+                if (ch === '\\') {
+                    ch = this.source[this.index++];
+                    // ECMA-262 7.8.5
+                    if (character_1.Character.isLineTerminator(ch.charCodeAt(0))) {
+                        this.throwUnexpectedToken(messages_1.Messages.UnterminatedRegExp);
+                    }
+                    str += ch;
</ins><span class="cx">                 }
</span><del>-            } else {
-                if (ch === '/') {
-                    terminated = true;
-                    break;
-                } else if (ch === '[') {
-                    classMarker = true;
</del><ins>+                else if (character_1.Character.isLineTerminator(ch.charCodeAt(0))) {
+                    this.throwUnexpectedToken(messages_1.Messages.UnterminatedRegExp);
</ins><span class="cx">                 }
</span><ins>+                else if (classMarker) {
+                    if (ch === ']') {
+                        classMarker = false;
+                    }
+                }
+                else {
+                    if (ch === '/') {
+                        terminated = true;
+                        break;
+                    }
+                    else if (ch === '[') {
+                        classMarker = true;
+                    }
+                }
</ins><span class="cx">             }
</span><del>-        }
-
-        if (!terminated) {
-            throwUnexpectedToken(null, Messages.UnterminatedRegExp);
-        }
-
-        // Exclude leading and trailing slash.
-        body = str.substr(1, str.length - 2);
-        return {
-            value: body,
-            literal: str
</del><ins>+            if (!terminated) {
+                this.throwUnexpectedToken(messages_1.Messages.UnterminatedRegExp);
+            }
+            // Exclude leading and trailing slash.
+            var body = str.substr(1, str.length - 2);
+            return {
+                value: body,
+                literal: str
+            };
</ins><span class="cx">         };
</span><del>-    }
-
-    function scanRegExpFlags() {
-        var ch, str, flags, restore;
-
-        str = '';
-        flags = '';
-        while (index &lt; length) {
-            ch = source[index];
-            if (!isIdentifierPart(ch.charCodeAt(0))) {
-                break;
-            }
-
-            ++index;
-            if (ch === '\\' &amp;&amp; index &lt; length) {
-                ch = source[index];
-                if (ch === 'u') {
-                    ++index;
-                    restore = index;
-                    ch = scanHexEscape('u');
-                    if (ch) {
-                        flags += ch;
-                        for (str += '\\u'; restore &lt; index; ++restore) {
-                            str += source[restore];
</del><ins>+        ;
+        Scanner.prototype.scanRegExpFlags = function () {
+            var str = '';
+            var flags = '';
+            while (!this.eof()) {
+                var ch = this.source[this.index];
+                if (!character_1.Character.isIdentifierPart(ch.charCodeAt(0))) {
+                    break;
+                }
+                ++this.index;
+                if (ch === '\\' &amp;&amp; !this.eof()) {
+                    ch = this.source[this.index];
+                    if (ch === 'u') {
+                        ++this.index;
+                        var restore = this.index;
+                        ch = this.scanHexEscape('u');
+                        if (ch) {
+                            flags += ch;
+                            for (str += '\\u'; restore &lt; this.index; ++restore) {
+                                str += this.source[restore];
+                            }
</ins><span class="cx">                         }
</span><del>-                    } else {
-                        index = restore;
-                        flags += 'u';
-                        str += '\\u';
</del><ins>+                        else {
+                            this.index = restore;
+                            flags += 'u';
+                            str += '\\u';
+                        }
+                        this.tolerateUnexpectedToken();
</ins><span class="cx">                     }
</span><del>-                    tolerateUnexpectedToken();
-                } else {
-                    str += '\\';
-                    tolerateUnexpectedToken();
</del><ins>+                    else {
+                        str += '\\';
+                        this.tolerateUnexpectedToken();
+                    }
</ins><span class="cx">                 }
</span><del>-            } else {
-                flags += ch;
-                str += ch;
</del><ins>+                else {
+                    flags += ch;
+                    str += ch;
+                }
</ins><span class="cx">             }
</span><del>-        }
-
-        return {
-            value: flags,
-            literal: str
</del><ins>+            return {
+                value: flags,
+                literal: str
+            };
</ins><span class="cx">         };
</span><del>-    }
-
-    function scanRegExp() {
-        var start, body, flags, value;
-        scanning = true;
-
-        lookahead = null;
-        skipComment();
-        start = index;
-
-        body = scanRegExpBody();
-        flags = scanRegExpFlags();
-        value = testRegExp(body.value, flags.value);
-        scanning = false;
-        if (extra.tokenize) {
</del><ins>+        ;
+        Scanner.prototype.scanRegExp = function () {
+            var start = this.index;
+            var body = this.scanRegExpBody();
+            var flags = this.scanRegExpFlags();
+            var value = this.testRegExp(body.value, flags.value);
</ins><span class="cx">             return {
</span><del>-                type: Token.RegularExpression,
</del><ins>+                type: token_1.Token.RegularExpression,
</ins><span class="cx">                 value: value,
</span><ins>+                literal: body.literal + flags.literal,
</ins><span class="cx">                 regex: {
</span><span class="cx">                     pattern: body.value,
</span><span class="cx">                     flags: flags.value
</span><span class="cx">                 },
</span><del>-                lineNumber: lineNumber,
-                lineStart: lineStart,
</del><ins>+                lineNumber: this.lineNumber,
+                lineStart: this.lineStart,
</ins><span class="cx">                 start: start,
</span><del>-                end: index
</del><ins>+                end: this.index
</ins><span class="cx">             };
</span><del>-        }
-
-        return {
-            literal: body.literal + flags.literal,
-            value: value,
-            regex: {
-                pattern: body.value,
-                flags: flags.value
-            },
-            start: start,
-            end: index
</del><span class="cx">         };
</span><del>-    }
-
-    function collectRegex() {
-        var pos, loc, regex, token;
-
-        skipComment();
-
-        pos = index;
-        loc = {
-            start: {
-                line: lineNumber,
-                column: index - lineStart
</del><ins>+        ;
+        Scanner.prototype.lex = function () {
+            if (this.eof()) {
+                return {
+                    type: token_1.Token.EOF,
+                    lineNumber: this.lineNumber,
+                    lineStart: this.lineStart,
+                    start: this.index,
+                    end: this.index
+                };
</ins><span class="cx">             }
</span><del>-        };
-
-        regex = scanRegExp();
-
-        loc.end = {
-            line: lineNumber,
-            column: index - lineStart
-        };
-
-        /* istanbul ignore next */
-        if (!extra.tokenize) {
-            // Pop the previous token, which is likely '/' or '/='
-            if (extra.tokens.length &gt; 0) {
-                token = extra.tokens[extra.tokens.length - 1];
-                if (token.range[0] === pos &amp;&amp; token.type === 'Punctuator') {
-                    if (token.value === '/' || token.value === '/=') {
-                        extra.tokens.pop();
-                    }
-                }
</del><ins>+            var cp = this.source.charCodeAt(this.index);
+            if (character_1.Character.isIdentifierStart(cp)) {
+                return this.scanIdentifier();
</ins><span class="cx">             }
</span><del>-
-            extra.tokens.push({
-                type: 'RegularExpression',
-                value: regex.literal,
-                regex: regex.regex,
-                range: [pos, index],
-                loc: loc
-            });
-        }
-
-        return regex;
-    }
-
-    function isIdentifierName(token) {
-        return token.type === Token.Identifier ||
-            token.type === Token.Keyword ||
-            token.type === Token.BooleanLiteral ||
-            token.type === Token.NullLiteral;
-    }
-
-    function advanceSlash() {
-        var prevToken,
-            checkToken;
-        // Using the following algorithm:
-        // https://github.com/mozilla/sweet.js/wiki/design
-        prevToken = extra.tokens[extra.tokens.length - 1];
-        if (!prevToken) {
-            // Nothing before that: it cannot be a division.
-            return collectRegex();
-        }
-        if (prevToken.type === 'Punctuator') {
-            if (prevToken.value === ']') {
-                return scanPunctuator();
</del><ins>+            // Very common: ( and ) and ;
+            if (cp === 0x28 || cp === 0x29 || cp === 0x3B) {
+                return this.scanPunctuator();
</ins><span class="cx">             }
</span><del>-            if (prevToken.value === ')') {
-                checkToken = extra.tokens[extra.openParenToken - 1];
-                if (checkToken &amp;&amp;
-                        checkToken.type === 'Keyword' &amp;&amp;
-                        (checkToken.value === 'if' ||
-                         checkToken.value === 'while' ||
-                         checkToken.value === 'for' ||
-                         checkToken.value === 'with')) {
-                    return collectRegex();
-                }
-                return scanPunctuator();
</del><ins>+            // String literal starts with single quote (U+0027) or double quote (U+0022).
+            if (cp === 0x27 || cp === 0x22) {
+                return this.scanStringLiteral();
</ins><span class="cx">             }
</span><del>-            if (prevToken.value === '}') {
-                // Dividing a function by anything makes little sense,
-                // but we have to check for that.
-                if (extra.tokens[extra.openCurlyToken - 3] &amp;&amp;
-                        extra.tokens[extra.openCurlyToken - 3].type === 'Keyword') {
-                    // Anonymous function.
-                    checkToken = extra.tokens[extra.openCurlyToken - 4];
-                    if (!checkToken) {
-                        return scanPunctuator();
-                    }
-                } else if (extra.tokens[extra.openCurlyToken - 4] &amp;&amp;
-                        extra.tokens[extra.openCurlyToken - 4].type === 'Keyword') {
-                    // Named function.
-                    checkToken = extra.tokens[extra.openCurlyToken - 5];
-                    if (!checkToken) {
-                        return collectRegex();
-                    }
-                } else {
-                    return scanPunctuator();
</del><ins>+            // Dot (.) U+002E can also start a floating-point number, hence the need
+            // to check the next character.
+            if (cp === 0x2E) {
+                if (character_1.Character.isDecimalDigit(this.source.charCodeAt(this.index + 1))) {
+                    return this.scanNumericLiteral();
</ins><span class="cx">                 }
</span><del>-                // checkToken determines whether the function is
-                // a declaration or an expression.
-                if (FnExprTokens.indexOf(checkToken.value) &gt;= 0) {
-                    // It is an expression.
-                    return scanPunctuator();
-                }
-                // It is a declaration.
-                return collectRegex();
</del><ins>+                return this.scanPunctuator();
</ins><span class="cx">             }
</span><del>-            return collectRegex();
-        }
-        if (prevToken.type === 'Keyword' &amp;&amp; prevToken.value !== 'this') {
-            return collectRegex();
-        }
-        return scanPunctuator();
-    }
-
-    function advance() {
-        var cp, token;
-
-        if (index &gt;= length) {
-            return {
-                type: Token.EOF,
-                lineNumber: lineNumber,
-                lineStart: lineStart,
-                start: index,
-                end: index
-            };
-        }
-
-        cp = source.charCodeAt(index);
-
-        if (isIdentifierStart(cp)) {
-            token = scanIdentifier();
-            if (strict &amp;&amp; isStrictModeReservedWord(token.value)) {
-                token.type = Token.Keyword;
</del><ins>+            if (character_1.Character.isDecimalDigit(cp)) {
+                return this.scanNumericLiteral();
</ins><span class="cx">             }
</span><del>-            return token;
-        }
-
-        // Very common: ( and ) and ;
-        if (cp === 0x28 || cp === 0x29 || cp === 0x3B) {
-            return scanPunctuator();
-        }
-
-        // String literal starts with single quote (U+0027) or double quote (U+0022).
-        if (cp === 0x27 || cp === 0x22) {
-            return scanStringLiteral();
-        }
-
-        // Dot (.) U+002E can also start a floating-point number, hence the need
-        // to check the next character.
-        if (cp === 0x2E) {
-            if (isDecimalDigit(source.charCodeAt(index + 1))) {
-                return scanNumericLiteral();
</del><ins>+            // Template literals start with ` (U+0060) for template head
+            // or } (U+007D) for template middle or template tail.
+            if (cp === 0x60 || (cp === 0x7D &amp;&amp; this.curlyStack[this.curlyStack.length - 1] === '${')) {
+                return this.scanTemplate();
</ins><span class="cx">             }
</span><del>-            return scanPunctuator();
-        }
-
-        if (isDecimalDigit(cp)) {
-            return scanNumericLiteral();
-        }
-
-        // Slash (/) U+002F can also start a regex.
-        if (extra.tokenize &amp;&amp; cp === 0x2F) {
-            return advanceSlash();
-        }
-
-        // Template literals start with ` (U+0060) for template head
-        // or } (U+007D) for template middle or template tail.
-        if (cp === 0x60 || (cp === 0x7D &amp;&amp; state.curlyStack[state.curlyStack.length - 1] === '${')) {
-            return scanTemplate();
-        }
-
-        // Possible identifier start in a surrogate pair.
-        if (cp &gt;= 0xD800 &amp;&amp; cp &lt; 0xDFFF) {
-            cp = codePointAt(index);
-            if (isIdentifierStart(cp)) {
-                return scanIdentifier();
</del><ins>+            // Possible identifier start in a surrogate pair.
+            if (cp &gt;= 0xD800 &amp;&amp; cp &lt; 0xDFFF) {
+                if (character_1.Character.isIdentifierStart(this.codePointAt(this.index))) {
+                    return this.scanIdentifier();
+                }
</ins><span class="cx">             }
</span><del>-        }
-
-        return scanPunctuator();
-    }
-
-    function collectToken() {
-        var loc, token, value, entry;
-
-        loc = {
-            start: {
-                line: lineNumber,
-                column: index - lineStart
-            }
</del><ins>+            return this.scanPunctuator();
</ins><span class="cx">         };
</span><ins>+        ;
+        return Scanner;
+    }());
+    exports.Scanner = Scanner;
</ins><span class="cx"> 
</span><del>-        token = advance();
-        loc.end = {
-            line: lineNumber,
-            column: index - lineStart
-        };
</del><span class="cx"> 
</span><del>-        if (token.type !== Token.EOF) {
-            value = source.slice(token.start, token.end);
-            entry = {
-                type: TokenName[token.type],
-                value: value,
-                range: [token.start, token.end],
-                loc: loc
-            };
-            if (token.regex) {
-                entry.regex = {
-                    pattern: token.regex.pattern,
-                    flags: token.regex.flags
-                };
-            }
-            extra.tokens.push(entry);
-        }
</del><ins>+/***/ },
+/* 9 */
+/***/ function(module, exports) {
</ins><span class="cx"> 
</span><del>-        return token;
-    }
-
-    function lex() {
-        var token;
-        scanning = true;
-
-        lastIndex = index;
-        lastLineNumber = lineNumber;
-        lastLineStart = lineStart;
-
-        skipComment();
-
-        token = lookahead;
-
-        startIndex = index;
-        startLineNumber = lineNumber;
-        startLineStart = lineStart;
-
-        lookahead = (typeof extra.tokens !== 'undefined') ? collectToken() : advance();
-        scanning = false;
-        return token;
-    }
-
-    function peek() {
-        scanning = true;
-
-        skipComment();
-
-        lastIndex = index;
-        lastLineNumber = lineNumber;
-        lastLineStart = lineStart;
-
-        startIndex = index;
-        startLineNumber = lineNumber;
-        startLineStart = lineStart;
-
-        lookahead = (typeof extra.tokens !== 'undefined') ? collectToken() : advance();
-        scanning = false;
-    }
-
-    function Position() {
-        this.line = startLineNumber;
-        this.column = startIndex - startLineStart;
-    }
-
-    function SourceLocation() {
-        this.start = new Position();
-        this.end = null;
-    }
-
-    function WrappingSourceLocation(startToken) {
-        this.start = {
-            line: startToken.lineNumber,
-            column: startToken.start - startToken.lineStart
-        };
-        this.end = null;
-    }
-
-    function Node() {
-        if (extra.range) {
-            this.range = [startIndex, 0];
</del><ins>+    &quot;use strict&quot;;
+    // See also tools/generate-unicode-regex.js.
+    var Regex = {
+        // Unicode v8.0.0 NonAsciiIdentifierStart:
+        NonAsciiIdentifierStart: /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\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-\u08B4\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\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\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5
 C\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-\u0C39\u0C3D\u0C58-\u0C5A\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\u0D5F-\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-\u12C
 5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\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\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D0
 0-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309B-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\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]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0
 -\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD
 07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1]|\uD87E[\uDC00-\uDE1D]/,
+        // Unicode v8.0.0 NonAsciiIdentifierPart:
+        NonAsciiIdentifierPart: /[\xAA\xB5\xB7\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\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-\u08B4\u08E3-\u0963\u0966-\u096F\u0971-\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\u0AF9\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\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C81-\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\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD
 4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\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\u1369-\u1371\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\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-\u
 191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\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\u2118-\u211D\u2124\u2126\u2128\u212A-\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\u3005-\u3007\u3
 021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\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-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uF
 E76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76
 \uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9
 D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD
 86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/
+    };
+    exports.Character = {
+        fromCodePoint: function (cp) {
+            return (cp &lt; 0x10000) ? String.fromCharCode(cp) :
+                String.fromCharCode(0xD800 + ((cp - 0x10000) &gt;&gt; 10)) +
+                    String.fromCharCode(0xDC00 + ((cp - 0x10000) &amp; 1023));
+        },
+        // ECMA-262 11.2 White Space
+        isWhiteSpace: function (cp) {
+            return (cp === 0x20) || (cp === 0x09) || (cp === 0x0B) || (cp === 0x0C) || (cp === 0xA0) ||
+                (cp &gt;= 0x1680 &amp;&amp; [0x1680, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000, 0xFEFF].indexOf(cp) &gt;= 0);
+        },
+        // ECMA-262 11.3 Line Terminators
+        isLineTerminator: function (cp) {
+            return (cp === 0x0A) || (cp === 0x0D) || (cp === 0x2028) || (cp === 0x2029);
+        },
+        // ECMA-262 11.6 Identifier Names and Identifiers
+        isIdentifierStart: function (cp) {
+            return (cp === 0x24) || (cp === 0x5F) ||
+                (cp &gt;= 0x41 &amp;&amp; cp &lt;= 0x5A) ||
+                (cp &gt;= 0x61 &amp;&amp; cp &lt;= 0x7A) ||
+                (cp === 0x5C) ||
+                ((cp &gt;= 0x80) &amp;&amp; Regex.NonAsciiIdentifierStart.test(exports.Character.fromCodePoint(cp)));
+        },
+        isIdentifierPart: function (cp) {
+            return (cp === 0x24) || (cp === 0x5F) ||
+                (cp &gt;= 0x41 &amp;&amp; cp &lt;= 0x5A) ||
+                (cp &gt;= 0x61 &amp;&amp; cp &lt;= 0x7A) ||
+                (cp &gt;= 0x30 &amp;&amp; cp &lt;= 0x39) ||
+                (cp === 0x5C) ||
+                ((cp &gt;= 0x80) &amp;&amp; Regex.NonAsciiIdentifierPart.test(exports.Character.fromCodePoint(cp)));
+        },
+        // ECMA-262 11.8.3 Numeric Literals
+        isDecimalDigit: function (cp) {
+            return (cp &gt;= 0x30 &amp;&amp; cp &lt;= 0x39); // 0..9
+        },
+        isHexDigit: function (cp) {
+            return (cp &gt;= 0x30 &amp;&amp; cp &lt;= 0x39) ||
+                (cp &gt;= 0x41 &amp;&amp; cp &lt;= 0x46) ||
+                (cp &gt;= 0x61 &amp;&amp; cp &lt;= 0x66); // a..f
+        },
+        isOctalDigit: function (cp) {
+            return (cp &gt;= 0x30 &amp;&amp; cp &lt;= 0x37); // 0..7
</ins><span class="cx">         }
</span><del>-        if (extra.loc) {
-            this.loc = new SourceLocation();
-        }
-    }
</del><ins>+    };
</ins><span class="cx"> 
</span><del>-    function WrappingNode(startToken) {
-        if (extra.range) {
-            this.range = [startToken.start, 0];
-        }
-        if (extra.loc) {
-            this.loc = new WrappingSourceLocation(startToken);
-        }
-    }
</del><span class="cx"> 
</span><del>-    WrappingNode.prototype = Node.prototype = {
</del><ins>+/***/ },
+/* 10 */
+/***/ function(module, exports, __webpack_require__) {
</ins><span class="cx"> 
</span><del>-        processComment: function () {
-            var lastChild,
-                leadingComments,
-                trailingComments,
-                bottomRight = extra.bottomRightStack,
-                i,
-                comment,
-                last = bottomRight[bottomRight.length - 1];
-
-            if (this.type === Syntax.Program) {
-                if (this.body.length &gt; 0) {
-                    return;
-                }
-            }
-
-            if (extra.trailingComments.length &gt; 0) {
-                trailingComments = [];
-                for (i = extra.trailingComments.length - 1; i &gt;= 0; --i) {
-                    comment = extra.trailingComments[i];
-                    if (comment.range[0] &gt;= this.range[1]) {
-                        trailingComments.unshift(comment);
-                        extra.trailingComments.splice(i, 1);
-                    }
-                }
-                extra.trailingComments = [];
-            } else {
-                if (last &amp;&amp; last.trailingComments &amp;&amp; last.trailingComments[0].range[0] &gt;= this.range[1]) {
-                    trailingComments = last.trailingComments;
-                    delete last.trailingComments;
-                }
-            }
-
-            // Eating the stack.
-            while (last &amp;&amp; last.range[0] &gt;= this.range[0]) {
-                lastChild = bottomRight.pop();
-                last = bottomRight[bottomRight.length - 1];
-            }
-
-            if (lastChild) {
-                if (lastChild.leadingComments) {
-                    leadingComments = [];
-                    for (i = lastChild.leadingComments.length - 1; i &gt;= 0; --i) {
-                        comment = lastChild.leadingComments[i];
-                        if (comment.range[1] &lt;= this.range[0]) {
-                            leadingComments.unshift(comment);
-                            lastChild.leadingComments.splice(i, 1);
-                        }
-                    }
-
-                    if (!lastChild.leadingComments.length) {
-                        lastChild.leadingComments = undefined;
-                    }
-                }
-            } else if (extra.leadingComments.length &gt; 0) {
-                leadingComments = [];
-                for (i = extra.leadingComments.length - 1; i &gt;= 0; --i) {
-                    comment = extra.leadingComments[i];
-                    if (comment.range[1] &lt;= this.range[0]) {
-                        leadingComments.unshift(comment);
-                        extra.leadingComments.splice(i, 1);
-                    }
-                }
-            }
-
-
-            if (leadingComments &amp;&amp; leadingComments.length &gt; 0) {
-                this.leadingComments = leadingComments;
-            }
-            if (trailingComments &amp;&amp; trailingComments.length &gt; 0) {
-                this.trailingComments = trailingComments;
-            }
-
-            bottomRight.push(this);
-        },
-
-        finish: function () {
-            if (extra.range) {
-                this.range[1] = lastIndex;
-            }
-            if (extra.loc) {
-                this.loc.end = {
-                    line: lastLineNumber,
-                    column: lastIndex - lastLineStart
-                };
-                if (extra.source) {
-                    this.loc.source = extra.source;
-                }
-            }
-
-            if (extra.attachComment) {
-                this.processComment();
-            }
-        },
-
-        finishArrayExpression: function (elements) {
-            this.type = Syntax.ArrayExpression;
</del><ins>+    &quot;use strict&quot;;
+    var syntax_1 = __webpack_require__(2);
+    var ArrayExpression = (function () {
+        function ArrayExpression(elements) {
+            this.type = syntax_1.Syntax.ArrayExpression;
</ins><span class="cx">             this.elements = elements;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishArrayPattern: function (elements) {
-            this.type = Syntax.ArrayPattern;
</del><ins>+        }
+        return ArrayExpression;
+    }());
+    exports.ArrayExpression = ArrayExpression;
+    var ArrayPattern = (function () {
+        function ArrayPattern(elements) {
+            this.type = syntax_1.Syntax.ArrayPattern;
</ins><span class="cx">             this.elements = elements;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishArrowFunctionExpression: function (params, defaults, body, expression) {
-            this.type = Syntax.ArrowFunctionExpression;
</del><ins>+        }
+        return ArrayPattern;
+    }());
+    exports.ArrayPattern = ArrayPattern;
+    var ArrowFunctionExpression = (function () {
+        function ArrowFunctionExpression(params, body, expression) {
+            this.type = syntax_1.Syntax.ArrowFunctionExpression;
</ins><span class="cx">             this.id = null;
</span><span class="cx">             this.params = params;
</span><del>-            this.defaults = defaults;
</del><span class="cx">             this.body = body;
</span><span class="cx">             this.generator = false;
</span><span class="cx">             this.expression = expression;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishAssignmentExpression: function (operator, left, right) {
-            this.type = Syntax.AssignmentExpression;
</del><ins>+            this.async = false;
+        }
+        return ArrowFunctionExpression;
+    }());
+    exports.ArrowFunctionExpression = ArrowFunctionExpression;
+    var AssignmentExpression = (function () {
+        function AssignmentExpression(operator, left, right) {
+            this.type = syntax_1.Syntax.AssignmentExpression;
</ins><span class="cx">             this.operator = operator;
</span><span class="cx">             this.left = left;
</span><span class="cx">             this.right = right;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishAssignmentPattern: function (left, right) {
-            this.type = Syntax.AssignmentPattern;
</del><ins>+        }
+        return AssignmentExpression;
+    }());
+    exports.AssignmentExpression = AssignmentExpression;
+    var AssignmentPattern = (function () {
+        function AssignmentPattern(left, right) {
+            this.type = syntax_1.Syntax.AssignmentPattern;
</ins><span class="cx">             this.left = left;
</span><span class="cx">             this.right = right;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishBinaryExpression: function (operator, left, right) {
-            this.type = (operator === '||' || operator === '&amp;&amp;') ? Syntax.LogicalExpression : Syntax.BinaryExpression;
</del><ins>+        }
+        return AssignmentPattern;
+    }());
+    exports.AssignmentPattern = AssignmentPattern;
+    var AsyncArrowFunctionExpression = (function () {
+        function AsyncArrowFunctionExpression(params, body, expression) {
+            this.type = syntax_1.Syntax.ArrowFunctionExpression;
+            this.id = null;
+            this.params = params;
+            this.body = body;
+            this.generator = false;
+            this.expression = expression;
+            this.async = true;
+        }
+        return AsyncArrowFunctionExpression;
+    }());
+    exports.AsyncArrowFunctionExpression = AsyncArrowFunctionExpression;
+    var AsyncFunctionDeclaration = (function () {
+        function AsyncFunctionDeclaration(id, params, body) {
+            this.type = syntax_1.Syntax.FunctionDeclaration;
+            this.id = id;
+            this.params = params;
+            this.body = body;
+            this.generator = false;
+            this.expression = false;
+            this.async = true;
+        }
+        return AsyncFunctionDeclaration;
+    }());
+    exports.AsyncFunctionDeclaration = AsyncFunctionDeclaration;
+    var AsyncFunctionExpression = (function () {
+        function AsyncFunctionExpression(id, params, body) {
+            this.type = syntax_1.Syntax.FunctionExpression;
+            this.id = id;
+            this.params = params;
+            this.body = body;
+            this.generator = false;
+            this.expression = false;
+            this.async = true;
+        }
+        return AsyncFunctionExpression;
+    }());
+    exports.AsyncFunctionExpression = AsyncFunctionExpression;
+    var AwaitExpression = (function () {
+        function AwaitExpression(argument) {
+            this.type = syntax_1.Syntax.AwaitExpression;
+            this.argument = argument;
+        }
+        return AwaitExpression;
+    }());
+    exports.AwaitExpression = AwaitExpression;
+    var BinaryExpression = (function () {
+        function BinaryExpression(operator, left, right) {
+            var logical = (operator === '||' || operator === '&amp;&amp;');
+            this.type = logical ? syntax_1.Syntax.LogicalExpression : syntax_1.Syntax.BinaryExpression;
</ins><span class="cx">             this.operator = operator;
</span><span class="cx">             this.left = left;
</span><span class="cx">             this.right = right;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishBlockStatement: function (body) {
-            this.type = Syntax.BlockStatement;
</del><ins>+        }
+        return BinaryExpression;
+    }());
+    exports.BinaryExpression = BinaryExpression;
+    var BlockStatement = (function () {
+        function BlockStatement(body) {
+            this.type = syntax_1.Syntax.BlockStatement;
</ins><span class="cx">             this.body = body;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishBreakStatement: function (label) {
-            this.type = Syntax.BreakStatement;
</del><ins>+        }
+        return BlockStatement;
+    }());
+    exports.BlockStatement = BlockStatement;
+    var BreakStatement = (function () {
+        function BreakStatement(label) {
+            this.type = syntax_1.Syntax.BreakStatement;
</ins><span class="cx">             this.label = label;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishCallExpression: function (callee, args) {
-            this.type = Syntax.CallExpression;
</del><ins>+        }
+        return BreakStatement;
+    }());
+    exports.BreakStatement = BreakStatement;
+    var CallExpression = (function () {
+        function CallExpression(callee, args) {
+            this.type = syntax_1.Syntax.CallExpression;
</ins><span class="cx">             this.callee = callee;
</span><span class="cx">             this.arguments = args;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishCatchClause: function (param, body) {
-            this.type = Syntax.CatchClause;
</del><ins>+        }
+        return CallExpression;
+    }());
+    exports.CallExpression = CallExpression;
+    var CatchClause = (function () {
+        function CatchClause(param, body) {
+            this.type = syntax_1.Syntax.CatchClause;
</ins><span class="cx">             this.param = param;
</span><span class="cx">             this.body = body;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishClassBody: function (body) {
-            this.type = Syntax.ClassBody;
</del><ins>+        }
+        return CatchClause;
+    }());
+    exports.CatchClause = CatchClause;
+    var ClassBody = (function () {
+        function ClassBody(body) {
+            this.type = syntax_1.Syntax.ClassBody;
</ins><span class="cx">             this.body = body;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishClassDeclaration: function (id, superClass, body) {
-            this.type = Syntax.ClassDeclaration;
</del><ins>+        }
+        return ClassBody;
+    }());
+    exports.ClassBody = ClassBody;
+    var ClassDeclaration = (function () {
+        function ClassDeclaration(id, superClass, body) {
+            this.type = syntax_1.Syntax.ClassDeclaration;
</ins><span class="cx">             this.id = id;
</span><span class="cx">             this.superClass = superClass;
</span><span class="cx">             this.body = body;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishClassExpression: function (id, superClass, body) {
-            this.type = Syntax.ClassExpression;
</del><ins>+        }
+        return ClassDeclaration;
+    }());
+    exports.ClassDeclaration = ClassDeclaration;
+    var ClassExpression = (function () {
+        function ClassExpression(id, superClass, body) {
+            this.type = syntax_1.Syntax.ClassExpression;
</ins><span class="cx">             this.id = id;
</span><span class="cx">             this.superClass = superClass;
</span><span class="cx">             this.body = body;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishConditionalExpression: function (test, consequent, alternate) {
-            this.type = Syntax.ConditionalExpression;
</del><ins>+        }
+        return ClassExpression;
+    }());
+    exports.ClassExpression = ClassExpression;
+    var ComputedMemberExpression = (function () {
+        function ComputedMemberExpression(object, property) {
+            this.type = syntax_1.Syntax.MemberExpression;
+            this.computed = true;
+            this.object = object;
+            this.property = property;
+        }
+        return ComputedMemberExpression;
+    }());
+    exports.ComputedMemberExpression = ComputedMemberExpression;
+    var ConditionalExpression = (function () {
+        function ConditionalExpression(test, consequent, alternate) {
+            this.type = syntax_1.Syntax.ConditionalExpression;
</ins><span class="cx">             this.test = test;
</span><span class="cx">             this.consequent = consequent;
</span><span class="cx">             this.alternate = alternate;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishContinueStatement: function (label) {
-            this.type = Syntax.ContinueStatement;
</del><ins>+        }
+        return ConditionalExpression;
+    }());
+    exports.ConditionalExpression = ConditionalExpression;
+    var ContinueStatement = (function () {
+        function ContinueStatement(label) {
+            this.type = syntax_1.Syntax.ContinueStatement;
</ins><span class="cx">             this.label = label;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishDebuggerStatement: function () {
-            this.type = Syntax.DebuggerStatement;
-            this.finish();
-            return this;
-        },
-
-        finishDoWhileStatement: function (body, test) {
-            this.type = Syntax.DoWhileStatement;
</del><ins>+        }
+        return ContinueStatement;
+    }());
+    exports.ContinueStatement = ContinueStatement;
+    var DebuggerStatement = (function () {
+        function DebuggerStatement() {
+            this.type = syntax_1.Syntax.DebuggerStatement;
+        }
+        return DebuggerStatement;
+    }());
+    exports.DebuggerStatement = DebuggerStatement;
+    var Directive = (function () {
+        function Directive(expression, directive) {
+            this.type = syntax_1.Syntax.ExpressionStatement;
+            this.expression = expression;
+            this.directive = directive;
+        }
+        return Directive;
+    }());
+    exports.Directive = Directive;
+    var DoWhileStatement = (function () {
+        function DoWhileStatement(body, test) {
+            this.type = syntax_1.Syntax.DoWhileStatement;
</ins><span class="cx">             this.body = body;
</span><span class="cx">             this.test = test;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishEmptyStatement: function () {
-            this.type = Syntax.EmptyStatement;
-            this.finish();
-            return this;
-        },
-
-        finishExpressionStatement: function (expression) {
-            this.type = Syntax.ExpressionStatement;
</del><ins>+        }
+        return DoWhileStatement;
+    }());
+    exports.DoWhileStatement = DoWhileStatement;
+    var EmptyStatement = (function () {
+        function EmptyStatement() {
+            this.type = syntax_1.Syntax.EmptyStatement;
+        }
+        return EmptyStatement;
+    }());
+    exports.EmptyStatement = EmptyStatement;
+    var ExportAllDeclaration = (function () {
+        function ExportAllDeclaration(source) {
+            this.type = syntax_1.Syntax.ExportAllDeclaration;
+            this.source = source;
+        }
+        return ExportAllDeclaration;
+    }());
+    exports.ExportAllDeclaration = ExportAllDeclaration;
+    var ExportDefaultDeclaration = (function () {
+        function ExportDefaultDeclaration(declaration) {
+            this.type = syntax_1.Syntax.ExportDefaultDeclaration;
+            this.declaration = declaration;
+        }
+        return ExportDefaultDeclaration;
+    }());
+    exports.ExportDefaultDeclaration = ExportDefaultDeclaration;
+    var ExportNamedDeclaration = (function () {
+        function ExportNamedDeclaration(declaration, specifiers, source) {
+            this.type = syntax_1.Syntax.ExportNamedDeclaration;
+            this.declaration = declaration;
+            this.specifiers = specifiers;
+            this.source = source;
+        }
+        return ExportNamedDeclaration;
+    }());
+    exports.ExportNamedDeclaration = ExportNamedDeclaration;
+    var ExportSpecifier = (function () {
+        function ExportSpecifier(local, exported) {
+            this.type = syntax_1.Syntax.ExportSpecifier;
+            this.exported = exported;
+            this.local = local;
+        }
+        return ExportSpecifier;
+    }());
+    exports.ExportSpecifier = ExportSpecifier;
+    var ExpressionStatement = (function () {
+        function ExpressionStatement(expression) {
+            this.type = syntax_1.Syntax.ExpressionStatement;
</ins><span class="cx">             this.expression = expression;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishForStatement: function (init, test, update, body) {
-            this.type = Syntax.ForStatement;
-            this.init = init;
-            this.test = test;
-            this.update = update;
-            this.body = body;
-            this.finish();
-            return this;
-        },
-
-        finishForOfStatement: function (left, right, body) {
-            this.type = Syntax.ForOfStatement;
</del><ins>+        }
+        return ExpressionStatement;
+    }());
+    exports.ExpressionStatement = ExpressionStatement;
+    var ForInStatement = (function () {
+        function ForInStatement(left, right, body) {
+            this.type = syntax_1.Syntax.ForInStatement;
</ins><span class="cx">             this.left = left;
</span><span class="cx">             this.right = right;
</span><span class="cx">             this.body = body;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishForInStatement: function (left, right, body) {
-            this.type = Syntax.ForInStatement;
</del><ins>+            this.each = false;
+        }
+        return ForInStatement;
+    }());
+    exports.ForInStatement = ForInStatement;
+    var ForOfStatement = (function () {
+        function ForOfStatement(left, right, body) {
+            this.type = syntax_1.Syntax.ForOfStatement;
</ins><span class="cx">             this.left = left;
</span><span class="cx">             this.right = right;
</span><span class="cx">             this.body = body;
</span><del>-            this.each = false;
-            this.finish();
-            return this;
-        },
-
-        finishFunctionDeclaration: function (id, params, defaults, body, generator) {
-            this.type = Syntax.FunctionDeclaration;
</del><ins>+        }
+        return ForOfStatement;
+    }());
+    exports.ForOfStatement = ForOfStatement;
+    var ForStatement = (function () {
+        function ForStatement(init, test, update, body) {
+            this.type = syntax_1.Syntax.ForStatement;
+            this.init = init;
+            this.test = test;
+            this.update = update;
+            this.body = body;
+        }
+        return ForStatement;
+    }());
+    exports.ForStatement = ForStatement;
+    var FunctionDeclaration = (function () {
+        function FunctionDeclaration(id, params, body, generator) {
+            this.type = syntax_1.Syntax.FunctionDeclaration;
</ins><span class="cx">             this.id = id;
</span><span class="cx">             this.params = params;
</span><del>-            this.defaults = defaults;
</del><span class="cx">             this.body = body;
</span><span class="cx">             this.generator = generator;
</span><span class="cx">             this.expression = false;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishFunctionExpression: function (id, params, defaults, body, generator) {
-            this.type = Syntax.FunctionExpression;
</del><ins>+            this.async = false;
+        }
+        return FunctionDeclaration;
+    }());
+    exports.FunctionDeclaration = FunctionDeclaration;
+    var FunctionExpression = (function () {
+        function FunctionExpression(id, params, body, generator) {
+            this.type = syntax_1.Syntax.FunctionExpression;
</ins><span class="cx">             this.id = id;
</span><span class="cx">             this.params = params;
</span><del>-            this.defaults = defaults;
</del><span class="cx">             this.body = body;
</span><span class="cx">             this.generator = generator;
</span><span class="cx">             this.expression = false;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishIdentifier: function (name) {
-            this.type = Syntax.Identifier;
</del><ins>+            this.async = false;
+        }
+        return FunctionExpression;
+    }());
+    exports.FunctionExpression = FunctionExpression;
+    var Identifier = (function () {
+        function Identifier(name) {
+            this.type = syntax_1.Syntax.Identifier;
</ins><span class="cx">             this.name = name;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishIfStatement: function (test, consequent, alternate) {
-            this.type = Syntax.IfStatement;
</del><ins>+        }
+        return Identifier;
+    }());
+    exports.Identifier = Identifier;
+    var IfStatement = (function () {
+        function IfStatement(test, consequent, alternate) {
+            this.type = syntax_1.Syntax.IfStatement;
</ins><span class="cx">             this.test = test;
</span><span class="cx">             this.consequent = consequent;
</span><span class="cx">             this.alternate = alternate;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishLabeledStatement: function (label, body) {
-            this.type = Syntax.LabeledStatement;
</del><ins>+        }
+        return IfStatement;
+    }());
+    exports.IfStatement = IfStatement;
+    var ImportDeclaration = (function () {
+        function ImportDeclaration(specifiers, source) {
+            this.type = syntax_1.Syntax.ImportDeclaration;
+            this.specifiers = specifiers;
+            this.source = source;
+        }
+        return ImportDeclaration;
+    }());
+    exports.ImportDeclaration = ImportDeclaration;
+    var ImportDefaultSpecifier = (function () {
+        function ImportDefaultSpecifier(local) {
+            this.type = syntax_1.Syntax.ImportDefaultSpecifier;
+            this.local = local;
+        }
+        return ImportDefaultSpecifier;
+    }());
+    exports.ImportDefaultSpecifier = ImportDefaultSpecifier;
+    var ImportNamespaceSpecifier = (function () {
+        function ImportNamespaceSpecifier(local) {
+            this.type = syntax_1.Syntax.ImportNamespaceSpecifier;
+            this.local = local;
+        }
+        return ImportNamespaceSpecifier;
+    }());
+    exports.ImportNamespaceSpecifier = ImportNamespaceSpecifier;
+    var ImportSpecifier = (function () {
+        function ImportSpecifier(local, imported) {
+            this.type = syntax_1.Syntax.ImportSpecifier;
+            this.local = local;
+            this.imported = imported;
+        }
+        return ImportSpecifier;
+    }());
+    exports.ImportSpecifier = ImportSpecifier;
+    var LabeledStatement = (function () {
+        function LabeledStatement(label, body) {
+            this.type = syntax_1.Syntax.LabeledStatement;
</ins><span class="cx">             this.label = label;
</span><span class="cx">             this.body = body;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishLiteral: function (token) {
-            this.type = Syntax.Literal;
-            this.value = token.value;
-            this.raw = source.slice(token.start, token.end);
-            if (token.regex) {
-                this.regex = token.regex;
-            }
-            this.finish();
-            return this;
-        },
-
-        finishMemberExpression: function (accessor, object, property) {
-            this.type = Syntax.MemberExpression;
-            this.computed = accessor === '[';
-            this.object = object;
-            this.property = property;
-            this.finish();
-            return this;
-        },
-
-        finishMetaProperty: function (meta, property) {
-            this.type = Syntax.MetaProperty;
</del><ins>+        }
+        return LabeledStatement;
+    }());
+    exports.LabeledStatement = LabeledStatement;
+    var Literal = (function () {
+        function Literal(value, raw) {
+            this.type = syntax_1.Syntax.Literal;
+            this.value = value;
+            this.raw = raw;
+        }
+        return Literal;
+    }());
+    exports.Literal = Literal;
+    var MetaProperty = (function () {
+        function MetaProperty(meta, property) {
+            this.type = syntax_1.Syntax.MetaProperty;
</ins><span class="cx">             this.meta = meta;
</span><span class="cx">             this.property = property;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishNewExpression: function (callee, args) {
-            this.type = Syntax.NewExpression;
</del><ins>+        }
+        return MetaProperty;
+    }());
+    exports.MetaProperty = MetaProperty;
+    var MethodDefinition = (function () {
+        function MethodDefinition(key, computed, value, kind, isStatic) {
+            this.type = syntax_1.Syntax.MethodDefinition;
+            this.key = key;
+            this.computed = computed;
+            this.value = value;
+            this.kind = kind;
+            this.static = isStatic;
+        }
+        return MethodDefinition;
+    }());
+    exports.MethodDefinition = MethodDefinition;
+    var Module = (function () {
+        function Module(body) {
+            this.type = syntax_1.Syntax.Program;
+            this.body = body;
+            this.sourceType = 'module';
+        }
+        return Module;
+    }());
+    exports.Module = Module;
+    var NewExpression = (function () {
+        function NewExpression(callee, args) {
+            this.type = syntax_1.Syntax.NewExpression;
</ins><span class="cx">             this.callee = callee;
</span><span class="cx">             this.arguments = args;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishObjectExpression: function (properties) {
-            this.type = Syntax.ObjectExpression;
</del><ins>+        }
+        return NewExpression;
+    }());
+    exports.NewExpression = NewExpression;
+    var ObjectExpression = (function () {
+        function ObjectExpression(properties) {
+            this.type = syntax_1.Syntax.ObjectExpression;
</ins><span class="cx">             this.properties = properties;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishObjectPattern: function (properties) {
-            this.type = Syntax.ObjectPattern;
</del><ins>+        }
+        return ObjectExpression;
+    }());
+    exports.ObjectExpression = ObjectExpression;
+    var ObjectPattern = (function () {
+        function ObjectPattern(properties) {
+            this.type = syntax_1.Syntax.ObjectPattern;
</ins><span class="cx">             this.properties = properties;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishPostfixExpression: function (operator, argument) {
-            this.type = Syntax.UpdateExpression;
-            this.operator = operator;
-            this.argument = argument;
-            this.prefix = false;
-            this.finish();
-            return this;
-        },
-
-        finishProgram: function (body, sourceType) {
-            this.type = Syntax.Program;
-            this.body = body;
-            this.sourceType = sourceType;
-            this.finish();
-            return this;
-        },
-
-        finishProperty: function (kind, key, computed, value, method, shorthand) {
-            this.type = Syntax.Property;
</del><ins>+        }
+        return ObjectPattern;
+    }());
+    exports.ObjectPattern = ObjectPattern;
+    var Property = (function () {
+        function Property(kind, key, computed, value, method, shorthand) {
+            this.type = syntax_1.Syntax.Property;
</ins><span class="cx">             this.key = key;
</span><span class="cx">             this.computed = computed;
</span><span class="cx">             this.value = value;
</span><span class="lines">@@ -2147,3514 +5360,1302 @@
</span><span class="cx">             this.kind = kind;
</span><span class="cx">             this.method = method;
</span><span class="cx">             this.shorthand = shorthand;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishRestElement: function (argument) {
-            this.type = Syntax.RestElement;
</del><ins>+        }
+        return Property;
+    }());
+    exports.Property = Property;
+    var RegexLiteral = (function () {
+        function RegexLiteral(value, raw, regex) {
+            this.type = syntax_1.Syntax.Literal;
+            this.value = value;
+            this.raw = raw;
+            this.regex = regex;
+        }
+        return RegexLiteral;
+    }());
+    exports.RegexLiteral = RegexLiteral;
+    var RestElement = (function () {
+        function RestElement(argument) {
+            this.type = syntax_1.Syntax.RestElement;
</ins><span class="cx">             this.argument = argument;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishReturnStatement: function (argument) {
-            this.type = Syntax.ReturnStatement;
</del><ins>+        }
+        return RestElement;
+    }());
+    exports.RestElement = RestElement;
+    var ReturnStatement = (function () {
+        function ReturnStatement(argument) {
+            this.type = syntax_1.Syntax.ReturnStatement;
</ins><span class="cx">             this.argument = argument;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishSequenceExpression: function (expressions) {
-            this.type = Syntax.SequenceExpression;
</del><ins>+        }
+        return ReturnStatement;
+    }());
+    exports.ReturnStatement = ReturnStatement;
+    var Script = (function () {
+        function Script(body) {
+            this.type = syntax_1.Syntax.Program;
+            this.body = body;
+            this.sourceType = 'script';
+        }
+        return Script;
+    }());
+    exports.Script = Script;
+    var SequenceExpression = (function () {
+        function SequenceExpression(expressions) {
+            this.type = syntax_1.Syntax.SequenceExpression;
</ins><span class="cx">             this.expressions = expressions;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishSpreadElement: function (argument) {
-            this.type = Syntax.SpreadElement;
</del><ins>+        }
+        return SequenceExpression;
+    }());
+    exports.SequenceExpression = SequenceExpression;
+    var SpreadElement = (function () {
+        function SpreadElement(argument) {
+            this.type = syntax_1.Syntax.SpreadElement;
</ins><span class="cx">             this.argument = argument;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishSwitchCase: function (test, consequent) {
-            this.type = Syntax.SwitchCase;
</del><ins>+        }
+        return SpreadElement;
+    }());
+    exports.SpreadElement = SpreadElement;
+    var StaticMemberExpression = (function () {
+        function StaticMemberExpression(object, property) {
+            this.type = syntax_1.Syntax.MemberExpression;
+            this.computed = false;
+            this.object = object;
+            this.property = property;
+        }
+        return StaticMemberExpression;
+    }());
+    exports.StaticMemberExpression = StaticMemberExpression;
+    var Super = (function () {
+        function Super() {
+            this.type = syntax_1.Syntax.Super;
+        }
+        return Super;
+    }());
+    exports.Super = Super;
+    var SwitchCase = (function () {
+        function SwitchCase(test, consequent) {
+            this.type = syntax_1.Syntax.SwitchCase;
</ins><span class="cx">             this.test = test;
</span><span class="cx">             this.consequent = consequent;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishSuper: function () {
-            this.type = Syntax.Super;
-            this.finish();
-            return this;
-        },
-
-        finishSwitchStatement: function (discriminant, cases) {
-            this.type = Syntax.SwitchStatement;
</del><ins>+        }
+        return SwitchCase;
+    }());
+    exports.SwitchCase = SwitchCase;
+    var SwitchStatement = (function () {
+        function SwitchStatement(discriminant, cases) {
+            this.type = syntax_1.Syntax.SwitchStatement;
</ins><span class="cx">             this.discriminant = discriminant;
</span><span class="cx">             this.cases = cases;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishTaggedTemplateExpression: function (tag, quasi) {
-            this.type = Syntax.TaggedTemplateExpression;
</del><ins>+        }
+        return SwitchStatement;
+    }());
+    exports.SwitchStatement = SwitchStatement;
+    var TaggedTemplateExpression = (function () {
+        function TaggedTemplateExpression(tag, quasi) {
+            this.type = syntax_1.Syntax.TaggedTemplateExpression;
</ins><span class="cx">             this.tag = tag;
</span><span class="cx">             this.quasi = quasi;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishTemplateElement: function (value, tail) {
-            this.type = Syntax.TemplateElement;
</del><ins>+        }
+        return TaggedTemplateExpression;
+    }());
+    exports.TaggedTemplateExpression = TaggedTemplateExpression;
+    var TemplateElement = (function () {
+        function TemplateElement(value, tail) {
+            this.type = syntax_1.Syntax.TemplateElement;
</ins><span class="cx">             this.value = value;
</span><span class="cx">             this.tail = tail;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishTemplateLiteral: function (quasis, expressions) {
-            this.type = Syntax.TemplateLiteral;
</del><ins>+        }
+        return TemplateElement;
+    }());
+    exports.TemplateElement = TemplateElement;
+    var TemplateLiteral = (function () {
+        function TemplateLiteral(quasis, expressions) {
+            this.type = syntax_1.Syntax.TemplateLiteral;
</ins><span class="cx">             this.quasis = quasis;
</span><span class="cx">             this.expressions = expressions;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishThisExpression: function () {
-            this.type = Syntax.ThisExpression;
-            this.finish();
-            return this;
-        },
-
-        finishThrowStatement: function (argument) {
-            this.type = Syntax.ThrowStatement;
</del><ins>+        }
+        return TemplateLiteral;
+    }());
+    exports.TemplateLiteral = TemplateLiteral;
+    var ThisExpression = (function () {
+        function ThisExpression() {
+            this.type = syntax_1.Syntax.ThisExpression;
+        }
+        return ThisExpression;
+    }());
+    exports.ThisExpression = ThisExpression;
+    var ThrowStatement = (function () {
+        function ThrowStatement(argument) {
+            this.type = syntax_1.Syntax.ThrowStatement;
</ins><span class="cx">             this.argument = argument;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishTryStatement: function (block, handler, finalizer) {
-            this.type = Syntax.TryStatement;
</del><ins>+        }
+        return ThrowStatement;
+    }());
+    exports.ThrowStatement = ThrowStatement;
+    var TryStatement = (function () {
+        function TryStatement(block, handler, finalizer) {
+            this.type = syntax_1.Syntax.TryStatement;
</ins><span class="cx">             this.block = block;
</span><del>-            this.guardedHandlers = [];
-            this.handlers = handler ? [handler] : [];
</del><span class="cx">             this.handler = handler;
</span><span class="cx">             this.finalizer = finalizer;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishUnaryExpression: function (operator, argument) {
-            this.type = (operator === '++' || operator === '--') ? Syntax.UpdateExpression : Syntax.UnaryExpression;
</del><ins>+        }
+        return TryStatement;
+    }());
+    exports.TryStatement = TryStatement;
+    var UnaryExpression = (function () {
+        function UnaryExpression(operator, argument) {
+            this.type = syntax_1.Syntax.UnaryExpression;
</ins><span class="cx">             this.operator = operator;
</span><span class="cx">             this.argument = argument;
</span><span class="cx">             this.prefix = true;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishVariableDeclaration: function (declarations) {
-            this.type = Syntax.VariableDeclaration;
</del><ins>+        }
+        return UnaryExpression;
+    }());
+    exports.UnaryExpression = UnaryExpression;
+    var UpdateExpression = (function () {
+        function UpdateExpression(operator, argument, prefix) {
+            this.type = syntax_1.Syntax.UpdateExpression;
+            this.operator = operator;
+            this.argument = argument;
+            this.prefix = prefix;
+        }
+        return UpdateExpression;
+    }());
+    exports.UpdateExpression = UpdateExpression;
+    var VariableDeclaration = (function () {
+        function VariableDeclaration(declarations, kind) {
+            this.type = syntax_1.Syntax.VariableDeclaration;
</ins><span class="cx">             this.declarations = declarations;
</span><del>-            this.kind = 'var';
-            this.finish();
-            return this;
-        },
-
-        finishLexicalDeclaration: function (declarations, kind) {
-            this.type = Syntax.VariableDeclaration;
-            this.declarations = declarations;
</del><span class="cx">             this.kind = kind;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishVariableDeclarator: function (id, init) {
-            this.type = Syntax.VariableDeclarator;
</del><ins>+        }
+        return VariableDeclaration;
+    }());
+    exports.VariableDeclaration = VariableDeclaration;
+    var VariableDeclarator = (function () {
+        function VariableDeclarator(id, init) {
+            this.type = syntax_1.Syntax.VariableDeclarator;
</ins><span class="cx">             this.id = id;
</span><span class="cx">             this.init = init;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishWhileStatement: function (test, body) {
-            this.type = Syntax.WhileStatement;
</del><ins>+        }
+        return VariableDeclarator;
+    }());
+    exports.VariableDeclarator = VariableDeclarator;
+    var WhileStatement = (function () {
+        function WhileStatement(test, body) {
+            this.type = syntax_1.Syntax.WhileStatement;
</ins><span class="cx">             this.test = test;
</span><span class="cx">             this.body = body;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishWithStatement: function (object, body) {
-            this.type = Syntax.WithStatement;
</del><ins>+        }
+        return WhileStatement;
+    }());
+    exports.WhileStatement = WhileStatement;
+    var WithStatement = (function () {
+        function WithStatement(object, body) {
+            this.type = syntax_1.Syntax.WithStatement;
</ins><span class="cx">             this.object = object;
</span><span class="cx">             this.body = body;
</span><del>-            this.finish();
-            return this;
-        },
-
-        finishExportSpecifier: function (local, exported) {
-            this.type = Syntax.ExportSpecifier;
-            this.exported = exported || local;
-            this.local = local;
-            this.finish();
-            return this;
-        },
-
-        finishImportDefaultSpecifier: function (local) {
-            this.type = Syntax.ImportDefaultSpecifier;
-            this.local = local;
-            this.finish();
-            return this;
-        },
-
-        finishImportNamespaceSpecifier: function (local) {
-            this.type = Syntax.ImportNamespaceSpecifier;
-            this.local = local;
-            this.finish();
-            return this;
-        },
-
-        finishExportNamedDeclaration: function (declaration, specifiers, src) {
-            this.type = Syntax.ExportNamedDeclaration;
-            this.declaration = declaration;
-            this.specifiers = specifiers;
-            this.source = src;
-            this.finish();
-            return this;
-        },
-
-        finishExportDefaultDeclaration: function (declaration) {
-            this.type = Syntax.ExportDefaultDeclaration;
-            this.declaration = declaration;
-            this.finish();
-            return this;
-        },
-
-        finishExportAllDeclaration: function (src) {
-            this.type = Syntax.ExportAllDeclaration;
-            this.source = src;
-            this.finish();
-            return this;
-        },
-
-        finishImportSpecifier: function (local, imported) {
-            this.type = Syntax.ImportSpecifier;
-            this.local = local || imported;
-            this.imported = imported;
-            this.finish();
-            return this;
-        },
-
-        finishImportDeclaration: function (specifiers, src) {
-            this.type = Syntax.ImportDeclaration;
-            this.specifiers = specifiers;
-            this.source = src;
-            this.finish();
-            return this;
-        },
-
-        finishYieldExpression: function (argument, delegate) {
-            this.type = Syntax.YieldExpression;
</del><ins>+        }
+        return WithStatement;
+    }());
+    exports.WithStatement = WithStatement;
+    var YieldExpression = (function () {
+        function YieldExpression(argument, delegate) {
+            this.type = syntax_1.Syntax.YieldExpression;
</ins><span class="cx">             this.argument = argument;
</span><span class="cx">             this.delegate = delegate;
</span><del>-            this.finish();
-            return this;
</del><span class="cx">         }
</span><del>-    };
</del><ins>+        return YieldExpression;
+    }());
+    exports.YieldExpression = YieldExpression;
</ins><span class="cx"> 
</span><span class="cx"> 
</span><del>-    function recordError(error) {
-        var e, existing;
</del><ins>+/***/ },
+/* 11 */
+/***/ function(module, exports, __webpack_require__) {
</ins><span class="cx"> 
</span><del>-        for (e = 0; e &lt; extra.errors.length; e++) {
-            existing = extra.errors[e];
-            // Prevent duplicated error.
-            /* istanbul ignore next */
-            if (existing.index === error.index &amp;&amp; existing.message === error.message) {
-                return;
-            }
</del><ins>+    &quot;use strict&quot;;
+/* istanbul ignore next */
+    var __extends = (this &amp;&amp; this.__extends) || function (d, b) {
+        for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+    var character_1 = __webpack_require__(9);
+    var token_1 = __webpack_require__(7);
+    var parser_1 = __webpack_require__(3);
+    var xhtml_entities_1 = __webpack_require__(12);
+    var jsx_syntax_1 = __webpack_require__(13);
+    var Node = __webpack_require__(10);
+    var JSXNode = __webpack_require__(14);
+    var JSXToken;
+    (function (JSXToken) {
+        JSXToken[JSXToken[&quot;Identifier&quot;] = 100] = &quot;Identifier&quot;;
+        JSXToken[JSXToken[&quot;Text&quot;] = 101] = &quot;Text&quot;;
+    })(JSXToken || (JSXToken = {}));
+    token_1.TokenName[JSXToken.Identifier] = 'JSXIdentifier';
+    token_1.TokenName[JSXToken.Text] = 'JSXText';
+    // Fully qualified element name, e.g. &lt;svg:path&gt; returns &quot;svg:path&quot;
+    function getQualifiedElementName(elementName) {
+        var qualifiedName;
+        switch (elementName.type) {
+            case jsx_syntax_1.JSXSyntax.JSXIdentifier:
+                var id = (elementName);
+                qualifiedName = id.name;
+                break;
+            case jsx_syntax_1.JSXSyntax.JSXNamespacedName:
+                var ns = (elementName);
+                qualifiedName = getQualifiedElementName(ns.namespace) + ':' +
+                    getQualifiedElementName(ns.name);
+                break;
+            case jsx_syntax_1.JSXSyntax.JSXMemberExpression:
+                var expr = (elementName);
+                qualifiedName = getQualifiedElementName(expr.object) + '.' +
+                    getQualifiedElementName(expr.property);
+                break;
</ins><span class="cx">         }
</span><del>-
-        extra.errors.push(error);
</del><ins>+        return qualifiedName;
</ins><span class="cx">     }
</span><del>-
-    function constructError(msg, column) {
-        var error = new Error(msg);
-        try {
-            throw error;
-        } catch (base) {
-            /* istanbul ignore else */
-            if (Object.create &amp;&amp; Object.defineProperty) {
-                error = Object.create(base);
-                Object.defineProperty(error, 'column', { value: column });
-            }
-        } finally {
-            return error;
</del><ins>+    var JSXParser = (function (_super) {
+        __extends(JSXParser, _super);
+        function JSXParser(code, options, delegate) {
+            _super.call(this, code, options, delegate);
</ins><span class="cx">         }
</span><del>-    }
-
-    function createError(line, pos, description) {
-        var msg, column, error;
-
-        msg = 'Line ' + line + ': ' + description;
-        column = pos - (scanning ? lineStart : lastLineStart) + 1;
-        error = constructError(msg, column);
-        error.lineNumber = line;
-        error.description = description;
-        error.index = pos;
-        return error;
-    }
-
-    // Throw an exception
-
-    function throwError(messageFormat) {
-        var args, msg;
-
-        args = Array.prototype.slice.call(arguments, 1);
-        msg = messageFormat.replace(/%(\d)/g,
-            function (whole, idx) {
-                assert(idx &lt; args.length, 'Message reference must be in range');
-                return args[idx];
</del><ins>+        JSXParser.prototype.parsePrimaryExpression = function () {
+            return this.match('&lt;') ? this.parseJSXRoot() : _super.prototype.parsePrimaryExpression.call(this);
+        };
+        JSXParser.prototype.startJSX = function () {
+            // Unwind the scanner before the lookahead token.
+            this.scanner.index = this.startMarker.index;
+            this.scanner.lineNumber = this.startMarker.lineNumber;
+            this.scanner.lineStart = this.startMarker.lineStart;
+        };
+        JSXParser.prototype.finishJSX = function () {
+            // Prime the next lookahead.
+            this.nextToken();
+        };
+        JSXParser.prototype.reenterJSX = function () {
+            this.startJSX();
+            this.expectJSX('}');
+            // Pop the closing '}' added from the lookahead.
+            if (this.config.tokens) {
+                this.tokens.pop();
</ins><span class="cx">             }
</span><del>-        );
-
-        throw createError(lastLineNumber, lastIndex, msg);
-    }
-
-    function tolerateError(messageFormat) {
-        var args, msg, error;
-
-        args = Array.prototype.slice.call(arguments, 1);
-        /* istanbul ignore next */
-        msg = messageFormat.replace(/%(\d)/g,
-            function (whole, idx) {
-                assert(idx &lt; args.length, 'Message reference must be in range');
-                return args[idx];
-            }
-        );
-
-        error = createError(lineNumber, lastIndex, msg);
-        if (extra.errors) {
-            recordError(error);
-        } else {
-            throw error;
-        }
-    }
-
-    // Throw an exception because of the token.
-
-    function unexpectedTokenError(token, message) {
-        var value, msg = message || Messages.UnexpectedToken;
-
-        if (token) {
-            if (!message) {
-                msg = (token.type === Token.EOF) ? Messages.UnexpectedEOS :
-                    (token.type === Token.Identifier) ? Messages.UnexpectedIdentifier :
-                    (token.type === Token.NumericLiteral) ? Messages.UnexpectedNumber :
-                    (token.type === Token.StringLiteral) ? Messages.UnexpectedString :
-                    (token.type === Token.Template) ? Messages.UnexpectedTemplate :
-                    Messages.UnexpectedToken;
-
-                if (token.type === Token.Keyword) {
-                    if (isFutureReservedWord(token.value)) {
-                        msg = Messages.UnexpectedReserved;
-                    } else if (strict &amp;&amp; isStrictModeReservedWord(token.value)) {
-                        msg = Messages.StrictReservedWord;
</del><ins>+        };
+        JSXParser.prototype.createJSXNode = function () {
+            this.collectComments();
+            return {
+                index: this.scanner.index,
+                line: this.scanner.lineNumber,
+                column: this.scanner.index - this.scanner.lineStart
+            };
+        };
+        JSXParser.prototype.createJSXChildNode = function () {
+            return {
+                index: this.scanner.index,
+                line: this.scanner.lineNumber,
+                column: this.scanner.index - this.scanner.lineStart
+            };
+        };
+        JSXParser.prototype.scanXHTMLEntity = function (quote) {
+            var result = '&amp;';
+            var valid = true;
+            var terminated = false;
+            var numeric = false;
+            var hex = false;
+            while (!this.scanner.eof() &amp;&amp; valid &amp;&amp; !terminated) {
+                var ch = this.scanner.source[this.scanner.index];
+                if (ch === quote) {
+                    break;
+                }
+                terminated = (ch === ';');
+                result += ch;
+                ++this.scanner.index;
+                if (!terminated) {
+                    switch (result.length) {
+                        case 2:
+                            // e.g. '&amp;#123;'
+                            numeric = (ch === '#');
+                            break;
+                        case 3:
+                            if (numeric) {
+                                // e.g. '&amp;#x41;'
+                                hex = (ch === 'x');
+                                valid = hex || character_1.Character.isDecimalDigit(ch.charCodeAt(0));
+                                numeric = numeric &amp;&amp; !hex;
+                            }
+                            break;
+                        default:
+                            valid = valid &amp;&amp; !(numeric &amp;&amp; !character_1.Character.isDecimalDigit(ch.charCodeAt(0)));
+                            valid = valid &amp;&amp; !(hex &amp;&amp; !character_1.Character.isHexDigit(ch.charCodeAt(0)));
+                            break;
</ins><span class="cx">                     }
</span><span class="cx">                 }
</span><span class="cx">             }
</span><del>-
-            value = (token.type === Token.Template) ? token.value.raw : token.value;
-        } else {
-            value = 'ILLEGAL';
-        }
-
-        msg = msg.replace('%0', value);
-
-        return (token &amp;&amp; typeof token.lineNumber === 'number') ?
-            createError(token.lineNumber, token.start, msg) :
-            createError(scanning ? lineNumber : lastLineNumber, scanning ? index : lastIndex, msg);
-    }
-
-    function throwUnexpectedToken(token, message) {
-        throw unexpectedTokenError(token, message);
-    }
-
-    function tolerateUnexpectedToken(token, message) {
-        var error = unexpectedTokenError(token, message);
-        if (extra.errors) {
-            recordError(error);
-        } else {
-            throw error;
-        }
-    }
-
-    // Expect the next token to match the specified punctuator.
-    // If not, an exception will be thrown.
-
-    function expect(value) {
-        var token = lex();
-        if (token.type !== Token.Punctuator || token.value !== value) {
-            throwUnexpectedToken(token);
-        }
-    }
-
-    /**
-     * @name expectCommaSeparator
-     * @description Quietly expect a comma when in tolerant mode, otherwise delegates
-     * to &lt;code&gt;expect(value)&lt;/code&gt;
-     * @since 2.0
-     */
-    function expectCommaSeparator() {
-        var token;
-
-        if (extra.errors) {
-            token = lookahead;
-            if (token.type === Token.Punctuator &amp;&amp; token.value === ',') {
-                lex();
-            } else if (token.type === Token.Punctuator &amp;&amp; token.value === ';') {
-                lex();
-                tolerateUnexpectedToken(token);
-            } else {
-                tolerateUnexpectedToken(token, Messages.UnexpectedToken);
-            }
-        } else {
-            expect(',');
-        }
-    }
-
-    // Expect the next token to match the specified keyword.
-    // If not, an exception will be thrown.
-
-    function expectKeyword(keyword) {
-        var token = lex();
-        if (token.type !== Token.Keyword || token.value !== keyword) {
-            throwUnexpectedToken(token);
-        }
-    }
-
-    // Return true if the next token matches the specified punctuator.
-
-    function match(value) {
-        return lookahead.type === Token.Punctuator &amp;&amp; lookahead.value === value;
-    }
-
-    // Return true if the next token matches the specified keyword
-
-    function matchKeyword(keyword) {
-        return lookahead.type === Token.Keyword &amp;&amp; lookahead.value === keyword;
-    }
-
-    // Return true if the next token matches the specified contextual keyword
-    // (where an identifier is sometimes a keyword depending on the context)
-
-    function matchContextualKeyword(keyword) {
-        return lookahead.type === Token.Identifier &amp;&amp; lookahead.value === keyword;
-    }
-
-    // Return true if the next token is an assignment operator
-
-    function matchAssign() {
-        var op;
-
-        if (lookahead.type !== Token.Punctuator) {
-            return false;
-        }
-        op = lookahead.value;
-        return op === '=' ||
-            op === '*=' ||
-            op === '/=' ||
-            op === '%=' ||
-            op === '+=' ||
-            op === '-=' ||
-            op === '&lt;&lt;=' ||
-            op === '&gt;&gt;=' ||
-            op === '&gt;&gt;&gt;=' ||
-            op === '&amp;=' ||
-            op === '^=' ||
-            op === '|=';
-    }
-
-    function consumeSemicolon() {
-        // Catch the very common case first: immediately a semicolon (U+003B).
-        if (source.charCodeAt(startIndex) === 0x3B || match(';')) {
-            lex();
-            return;
-        }
-
-        if (hasLineTerminator) {
-            return;
-        }
-
-        // FIXME(ikarienator): this is seemingly an issue in the previous location info convention.
-        lastIndex = startIndex;
-        lastLineNumber = startLineNumber;
-        lastLineStart = startLineStart;
-
-        if (lookahead.type !== Token.EOF &amp;&amp; !match('}')) {
-            throwUnexpectedToken(lookahead);
-        }
-    }
-
-    // Cover grammar support.
-    //
-    // When an assignment expression position starts with an left parenthesis, the determination of the type
-    // of the syntax is to be deferred arbitrarily long until the end of the parentheses pair (plus a lookahead)
-    // or the first comma. This situation also defers the determination of all the expressions nested in the pair.
-    //
-    // There are three productions that can be parsed in a parentheses pair that needs to be determined
-    // after the outermost pair is closed. They are:
-    //
-    //   1. AssignmentExpression
-    //   2. BindingElements
-    //   3. AssignmentTargets
-    //
-    // In order to avoid exponential backtracking, we use two flags to denote if the production can be
-    // binding element or assignment target.
-    //
-    // The three productions have the relationship:
-    //
-    //   BindingElements âŠ† AssignmentTargets âŠ† AssignmentExpression
-    //
-    // with a single exception that CoverInitializedName when used directly in an Expression, generates
-    // an early error. Therefore, we need the third state, firstCoverInitializedNameError, to track the
-    // first usage of CoverInitializedName and report it when we reached the end of the parentheses pair.
-    //
-    // isolateCoverGrammar function runs the given parser function with a new cover grammar context, and it does not
-    // effect the current flags. This means the production the parser parses is only used as an expression. Therefore
-    // the CoverInitializedName check is conducted.
-    //
-    // inheritCoverGrammar function runs the given parse function with a new cover grammar context, and it propagates
-    // the flags outside of the parser. This means the production the parser parses is used as a part of a potential
-    // pattern. The CoverInitializedName check is deferred.
-    function isolateCoverGrammar(parser) {
-        var oldIsBindingElement = isBindingElement,
-            oldIsAssignmentTarget = isAssignmentTarget,
-            oldFirstCoverInitializedNameError = firstCoverInitializedNameError,
-            result;
-        isBindingElement = true;
-        isAssignmentTarget = true;
-        firstCoverInitializedNameError = null;
-        result = parser();
-        if (firstCoverInitializedNameError !== null) {
-            throwUnexpectedToken(firstCoverInitializedNameError);
-        }
-        isBindingElement = oldIsBindingElement;
-        isAssignmentTarget = oldIsAssignmentTarget;
-        firstCoverInitializedNameError = oldFirstCoverInitializedNameError;
-        return result;
-    }
-
-    function inheritCoverGrammar(parser) {
-        var oldIsBindingElement = isBindingElement,
-            oldIsAssignmentTarget = isAssignmentTarget,
-            oldFirstCoverInitializedNameError = firstCoverInitializedNameError,
-            result;
-        isBindingElement = true;
-        isAssignmentTarget = true;
-        firstCoverInitializedNameError = null;
-        result = parser();
-        isBindingElement = isBindingElement &amp;&amp; oldIsBindingElement;
-        isAssignmentTarget = isAssignmentTarget &amp;&amp; oldIsAssignmentTarget;
-        firstCoverInitializedNameError = oldFirstCoverInitializedNameError || firstCoverInitializedNameError;
-        return result;
-    }
-
-    // ECMA-262 13.3.3 Destructuring Binding Patterns
-
-    function parseArrayPattern(params, kind) {
-        var node = new Node(), elements = [], rest, restNode;
-        expect('[');
-
-        while (!match(']')) {
-            if (match(',')) {
-                lex();
-                elements.push(null);
-            } else {
-                if (match('...')) {
-                    restNode = new Node();
-                    lex();
-                    params.push(lookahead);
-                    rest = parseVariableIdentifier(params, kind);
-                    elements.push(restNode.finishRestElement(rest));
-                    break;
-                } else {
-                    elements.push(parsePatternWithDefault(params, kind));
</del><ins>+            if (valid &amp;&amp; terminated &amp;&amp; result.length &gt; 2) {
+                // e.g. '&amp;#x41;' becomes just '#x41'
+                var str = result.substr(1, result.length - 2);
+                if (numeric &amp;&amp; str.length &gt; 1) {
+                    result = String.fromCharCode(parseInt(str.substr(1), 10));
</ins><span class="cx">                 }
</span><del>-                if (!match(']')) {
-                    expect(',');
</del><ins>+                else if (hex &amp;&amp; str.length &gt; 2) {
+                    result = String.fromCharCode(parseInt('0' + str.substr(1), 16));
</ins><span class="cx">                 }
</span><del>-            }
-
-        }
-
-        expect(']');
-
-        return node.finishArrayPattern(elements);
-    }
-
-    function parsePropertyPattern(params, kind) {
-        var node = new Node(), key, keyToken, computed = match('['), init;
-        if (lookahead.type === Token.Identifier) {
-            keyToken = lookahead;
-            key = parseVariableIdentifier();
-            if (match('=')) {
-                params.push(keyToken);
-                lex();
-                init = parseAssignmentExpression();
-
-                return node.finishProperty(
-                    'init', key, false,
-                    new WrappingNode(keyToken).finishAssignmentPattern(key, init), false, false);
-            } else if (!match(':')) {
-                params.push(keyToken);
-                return node.finishProperty('init', key, false, key, false, true);
-            }
-        } else {
-            key = parseObjectPropertyKey(params, kind);
-        }
-        expect(':');
-        init = parsePatternWithDefault(params, kind);
-        return node.finishProperty('init', key, computed, init, false, false);
-    }
-
-    function parseObjectPattern(params, kind) {
-        var node = new Node(), properties = [];
-
-        expect('{');
-
-        while (!match('}')) {
-            properties.push(parsePropertyPattern(params, kind));
-            if (!match('}')) {
-                expect(',');
-            }
-        }
-
-        lex();
-
-        return node.finishObjectPattern(properties);
-    }
-
-    function parsePattern(params, kind) {
-        if (match('[')) {
-            return parseArrayPattern(params, kind);
-        } else if (match('{')) {
-            return parseObjectPattern(params, kind);
-        }
-        params.push(lookahead);
-        return parseVariableIdentifier(kind);
-    }
-
-    function parsePatternWithDefault(params, kind) {
-        var startToken = lookahead, pattern, previousAllowYield, right;
-        pattern = parsePattern(params, kind);
-        if (match('=')) {
-            lex();
-            previousAllowYield = state.allowYield;
-            state.allowYield = true;
-            right = isolateCoverGrammar(parseAssignmentExpression);
-            state.allowYield = previousAllowYield;
-            pattern = new WrappingNode(startToken).finishAssignmentPattern(pattern, right);
-        }
-        return pattern;
-    }
-
-    // ECMA-262 12.2.5 Array Initializer
-
-    function parseArrayInitializer() {
-        var elements = [], node = new Node(), restSpread;
-
-        expect('[');
-
-        while (!match(']')) {
-            if (match(',')) {
-                lex();
-                elements.push(null);
-            } else if (match('...')) {
-                restSpread = new Node();
-                lex();
-                restSpread.finishSpreadElement(inheritCoverGrammar(parseAssignmentExpression));
-
-                if (!match(']')) {
-                    isAssignmentTarget = isBindingElement = false;
-                    expect(',');
</del><ins>+                else if (!numeric &amp;&amp; !hex &amp;&amp; xhtml_entities_1.XHTMLEntities[str]) {
+                    result = xhtml_entities_1.XHTMLEntities[str];
</ins><span class="cx">                 }
</span><del>-                elements.push(restSpread);
-            } else {
-                elements.push(inheritCoverGrammar(parseAssignmentExpression));
-
-                if (!match(']')) {
-                    expect(',');
-                }
</del><span class="cx">             }
</span><del>-        }
-
-        lex();
-
-        return node.finishArrayExpression(elements);
-    }
-
-    // ECMA-262 12.2.6 Object Initializer
-
-    function parsePropertyFunction(node, paramInfo, isGenerator) {
-        var previousStrict, body;
-
-        isAssignmentTarget = isBindingElement = false;
-
-        previousStrict = strict;
-        body = isolateCoverGrammar(parseFunctionSourceElements);
-
-        if (strict &amp;&amp; paramInfo.firstRestricted) {
-            tolerateUnexpectedToken(paramInfo.firstRestricted, paramInfo.message);
-        }
-        if (strict &amp;&amp; paramInfo.stricted) {
-            tolerateUnexpectedToken(paramInfo.stricted, paramInfo.message);
-        }
-
-        strict = previousStrict;
-        return node.finishFunctionExpression(null, paramInfo.params, paramInfo.defaults, body, isGenerator);
-    }
-
-    function parsePropertyMethodFunction() {
-        var params, method, node = new Node(),
-            previousAllowYield = state.allowYield;
-
-        state.allowYield = false;
-        params = parseParams();
-        state.allowYield = previousAllowYield;
-
-        state.allowYield = false;
-        method = parsePropertyFunction(node, params, false);
-        state.allowYield = previousAllowYield;
-
-        return method;
-    }
-
-    function parseObjectPropertyKey() {
-        var token, node = new Node(), expr;
-
-        token = lex();
-
-        // Note: This function is called only from parseObjectProperty(), where
-        // EOF and Punctuator tokens are already filtered out.
-
-        switch (token.type) {
-        case Token.StringLiteral:
-        case Token.NumericLiteral:
-            if (strict &amp;&amp; token.octal) {
-                tolerateUnexpectedToken(token, Messages.StrictOctalLiteral);
</del><ins>+            return result;
+        };
+        // Scan the next JSX token. This replaces Scanner#lex when in JSX mode.
+        JSXParser.prototype.lexJSX = function () {
+            var cp = this.scanner.source.charCodeAt(this.scanner.index);
+            // &lt; &gt; / : = { }
+            if (cp === 60 || cp === 62 || cp === 47 || cp === 58 || cp === 61 || cp === 123 || cp === 125) {
+                var value = this.scanner.source[this.scanner.index++];
+                return {
+                    type: token_1.Token.Punctuator,
+                    value: value,
+                    lineNumber: this.scanner.lineNumber,
+                    lineStart: this.scanner.lineStart,
+                    start: this.scanner.index - 1,
+                    end: this.scanner.index
+                };
</ins><span class="cx">             }
</span><del>-            return node.finishLiteral(token);
-        case Token.Identifier:
-        case Token.BooleanLiteral:
-        case Token.NullLiteral:
-        case Token.Keyword:
-            return node.finishIdentifier(token.value);
-        case Token.Punctuator:
-            if (token.value === '[') {
-                expr = isolateCoverGrammar(parseAssignmentExpression);
-                expect(']');
-                return expr;
-            }
-            break;
-        }
-        throwUnexpectedToken(token);
-    }
-
-    function lookaheadPropertyName() {
-        switch (lookahead.type) {
-        case Token.Identifier:
-        case Token.StringLiteral:
-        case Token.BooleanLiteral:
-        case Token.NullLiteral:
-        case Token.NumericLiteral:
-        case Token.Keyword:
-            return true;
-        case Token.Punctuator:
-            return lookahead.value === '[';
-        }
-        return false;
-    }
-
-    // This function is to try to parse a MethodDefinition as defined in 14.3. But in the case of object literals,
-    // it might be called at a position where there is in fact a short hand identifier pattern or a data property.
-    // This can only be determined after we consumed up to the left parentheses.
-    //
-    // In order to avoid back tracking, it returns `null` if the position is not a MethodDefinition and the caller
-    // is responsible to visit other options.
-    function tryParseMethodDefinition(token, key, computed, node) {
-        var value, options, methodNode, params,
-            previousAllowYield = state.allowYield;
-
-        if (token.type === Token.Identifier) {
-            // check for `get` and `set`;
-
-            if (token.value === 'get' &amp;&amp; lookaheadPropertyName()) {
-                computed = match('[');
-                key = parseObjectPropertyKey();
-                methodNode = new Node();
-                expect('(');
-                expect(')');
-
-                state.allowYield = false;
-                value = parsePropertyFunction(methodNode, {
-                    params: [],
-                    defaults: [],
-                    stricted: null,
-                    firstRestricted: null,
-                    message: null
-                }, false);
-                state.allowYield = previousAllowYield;
-
-                return node.finishProperty('get', key, computed, value, false, false);
-            } else if (token.value === 'set' &amp;&amp; lookaheadPropertyName()) {
-                computed = match('[');
-                key = parseObjectPropertyKey();
-                methodNode = new Node();
-                expect('(');
-
-                options = {
-                    params: [],
-                    defaultCount: 0,
-                    defaults: [],
-                    firstRestricted: null,
-                    paramSet: {}
-                };
-                if (match(')')) {
-                    tolerateUnexpectedToken(lookahead);
-                } else {
-                    state.allowYield = false;
-                    parseParam(options);
-                    state.allowYield = previousAllowYield;
-                    if (options.defaultCount === 0) {
-                        options.defaults = [];
</del><ins>+            // &quot; '
+            if (cp === 34 || cp === 39) {
+                var start = this.scanner.index;
+                var quote = this.scanner.source[this.scanner.index++];
+                var str = '';
+                while (!this.scanner.eof()) {
+                    var ch = this.scanner.source[this.scanner.index++];
+                    if (ch === quote) {
+                        break;
</ins><span class="cx">                     }
</span><ins>+                    else if (ch === '&amp;') {
+                        str += this.scanXHTMLEntity(quote);
+                    }
+                    else {
+                        str += ch;
+                    }
</ins><span class="cx">                 }
</span><del>-                expect(')');
-
-                state.allowYield = false;
-                value = parsePropertyFunction(methodNode, options, false);
-                state.allowYield = previousAllowYield;
-
-                return node.finishProperty('set', key, computed, value, false, false);
</del><ins>+                return {
+                    type: token_1.Token.StringLiteral,
+                    value: str,
+                    lineNumber: this.scanner.lineNumber,
+                    lineStart: this.scanner.lineStart,
+                    start: start,
+                    end: this.scanner.index
+                };
</ins><span class="cx">             }
</span><del>-        } else if (token.type === Token.Punctuator &amp;&amp; token.value === '*' &amp;&amp; lookaheadPropertyName()) {
-            computed = match('[');
-            key = parseObjectPropertyKey();
-            methodNode = new Node();
-
-            state.allowYield = true;
-            params = parseParams();
-            state.allowYield = previousAllowYield;
-
-            state.allowYield = false;
-            value = parsePropertyFunction(methodNode, params, true);
-            state.allowYield = previousAllowYield;
-
-            return node.finishProperty('init', key, computed, value, true, false);
-        }
-
-        if (key &amp;&amp; match('(')) {
-            value = parsePropertyMethodFunction();
-            return node.finishProperty('init', key, computed, value, true, false);
-        }
-
-        // Not a MethodDefinition.
-        return null;
-    }
-
-    function parseObjectProperty(hasProto) {
-        var token = lookahead, node = new Node(), computed, key, maybeMethod, proto, value;
-
-        computed = match('[');
-        if (match('*')) {
-            lex();
-        } else {
-            key = parseObjectPropertyKey();
-        }
-        maybeMethod = tryParseMethodDefinition(token, key, computed, node);
-        if (maybeMethod) {
-            return maybeMethod;
-        }
-
-        if (!key) {
-            throwUnexpectedToken(lookahead);
-        }
-
-        // Check for duplicated __proto__
-        if (!computed) {
-            proto = (key.type === Syntax.Identifier &amp;&amp; key.name === '__proto__') ||
-                (key.type === Syntax.Literal &amp;&amp; key.value === '__proto__');
-            if (hasProto.value &amp;&amp; proto) {
-                tolerateError(Messages.DuplicateProtoProperty);
</del><ins>+            // ... or .
+            if (cp === 46) {
+                var n1 = this.scanner.source.charCodeAt(this.scanner.index + 1);
+                var n2 = this.scanner.source.charCodeAt(this.scanner.index + 2);
+                var value = (n1 === 46 &amp;&amp; n2 === 46) ? '...' : '.';
+                var start = this.scanner.index;
+                this.scanner.index += value.length;
+                return {
+                    type: token_1.Token.Punctuator,
+                    value: value,
+                    lineNumber: this.scanner.lineNumber,
+                    lineStart: this.scanner.lineStart,
+                    start: start,
+                    end: this.scanner.index
+                };
</ins><span class="cx">             }
</span><del>-            hasProto.value |= proto;
-        }
-
-        if (match(':')) {
-            lex();
-            value = inheritCoverGrammar(parseAssignmentExpression);
-            return node.finishProperty('init', key, computed, value, false, false);
-        }
-
-        if (token.type === Token.Identifier) {
-            if (match('=')) {
-                firstCoverInitializedNameError = lookahead;
-                lex();
-                value = isolateCoverGrammar(parseAssignmentExpression);
-                return node.finishProperty('init', key, computed,
-                    new WrappingNode(token).finishAssignmentPattern(key, value), false, true);
</del><ins>+            // `
+            if (cp === 96) {
+                // Only placeholder, since it will be rescanned as a real assignment expression.
+                return {
+                    type: token_1.Token.Template,
+                    lineNumber: this.scanner.lineNumber,
+                    lineStart: this.scanner.lineStart,
+                    start: this.scanner.index,
+                    end: this.scanner.index
+                };
</ins><span class="cx">             }
</span><del>-            return node.finishProperty('init', key, computed, key, false, true);
-        }
-
-        throwUnexpectedToken(lookahead);
-    }
-
-    function parseObjectInitializer() {
-        var properties = [], hasProto = {value: false}, node = new Node();
-
-        expect('{');
-
-        while (!match('}')) {
-            properties.push(parseObjectProperty(hasProto));
-
-            if (!match('}')) {
-                expectCommaSeparator();
-            }
-        }
-
-        expect('}');
-
-        return node.finishObjectExpression(properties);
-    }
-
-    function reinterpretExpressionAsPattern(expr) {
-        var i;
-        switch (expr.type) {
-        case Syntax.Identifier:
-        case Syntax.MemberExpression:
-        case Syntax.RestElement:
-        case Syntax.AssignmentPattern:
-            break;
-        case Syntax.SpreadElement:
-            expr.type = Syntax.RestElement;
-            reinterpretExpressionAsPattern(expr.argument);
-            break;
-        case Syntax.ArrayExpression:
-            expr.type = Syntax.ArrayPattern;
-            for (i = 0; i &lt; expr.elements.length; i++) {
-                if (expr.elements[i] !== null) {
-                    reinterpretExpressionAsPattern(expr.elements[i]);
-                }
-            }
-            break;
-        case Syntax.ObjectExpression:
-            expr.type = Syntax.ObjectPattern;
-            for (i = 0; i &lt; expr.properties.length; i++) {
-                reinterpretExpressionAsPattern(expr.properties[i].value);
-            }
-            break;
-        case Syntax.AssignmentExpression:
-            expr.type = Syntax.AssignmentPattern;
-            reinterpretExpressionAsPattern(expr.left);
-            break;
-        default:
-            // Allow other node type for tolerant parsing.
-            break;
-        }
-    }
-
-    // ECMA-262 12.2.9 Template Literals
-
-    function parseTemplateElement(option) {
-        var node, token;
-
-        if (lookahead.type !== Token.Template || (option.head &amp;&amp; !lookahead.head)) {
-            throwUnexpectedToken();
-        }
-
-        node = new Node();
-        token = lex();
-
-        return node.finishTemplateElement({ raw: token.value.raw, cooked: token.value.cooked }, token.tail);
-    }
-
-    function parseTemplateLiteral() {
-        var quasi, quasis, expressions, node = new Node();
-
-        quasi = parseTemplateElement({ head: true });
-        quasis = [quasi];
-        expressions = [];
-
-        while (!quasi.tail) {
-            expressions.push(parseExpression());
-            quasi = parseTemplateElement({ head: false });
-            quasis.push(quasi);
-        }
-
-        return node.finishTemplateLiteral(quasis, expressions);
-    }
-
-    // ECMA-262 12.2.10 The Grouping Operator
-
-    function parseGroupExpression() {
-        var expr, expressions, startToken, i, params = [];
-
-        expect('(');
-
-        if (match(')')) {
-            lex();
-            if (!match('=&gt;')) {
-                expect('=&gt;');
-            }
-            return {
-                type: PlaceHolders.ArrowParameterPlaceHolder,
-                params: [],
-                rawParams: []
-            };
-        }
-
-        startToken = lookahead;
-        if (match('...')) {
-            expr = parseRestElement(params);
-            expect(')');
-            if (!match('=&gt;')) {
-                expect('=&gt;');
-            }
-            return {
-                type: PlaceHolders.ArrowParameterPlaceHolder,
-                params: [expr]
-            };
-        }
-
-        isBindingElement = true;
-        expr = inheritCoverGrammar(parseAssignmentExpression);
-
-        if (match(',')) {
-            isAssignmentTarget = false;
-            expressions = [expr];
-
-            while (startIndex &lt; length) {
-                if (!match(',')) {
-                    break;
-                }
-                lex();
-
-                if (match('...')) {
-                    if (!isBindingElement) {
-                        throwUnexpectedToken(lookahead);
</del><ins>+            // Identifer can not contain backslash (char code 92).
+            if (character_1.Character.isIdentifierStart(cp) &amp;&amp; (cp !== 92)) {
+                var start = this.scanner.index;
+                ++this.scanner.index;
+                while (!this.scanner.eof()) {
+                    var ch = this.scanner.source.charCodeAt(this.scanner.index);
+                    if (character_1.Character.isIdentifierPart(ch) &amp;&amp; (ch !== 92)) {
+                        ++this.scanner.index;
</ins><span class="cx">                     }
</span><del>-                    expressions.push(parseRestElement(params));
-                    expect(')');
-                    if (!match('=&gt;')) {
-                        expect('=&gt;');
</del><ins>+                    else if (ch === 45) {
+                        // Hyphen (char code 45) can be part of an identifier.
+                        ++this.scanner.index;
</ins><span class="cx">                     }
</span><del>-                    isBindingElement = false;
-                    for (i = 0; i &lt; expressions.length; i++) {
-                        reinterpretExpressionAsPattern(expressions[i]);
</del><ins>+                    else {
+                        break;
</ins><span class="cx">                     }
</span><del>-                    return {
-                        type: PlaceHolders.ArrowParameterPlaceHolder,
-                        params: expressions
-                    };
</del><span class="cx">                 }
</span><del>-
-                expressions.push(inheritCoverGrammar(parseAssignmentExpression));
-            }
-
-            expr = new WrappingNode(startToken).finishSequenceExpression(expressions);
-        }
-
-
-        expect(')');
-
-        if (match('=&gt;')) {
-            if (expr.type === Syntax.Identifier &amp;&amp; expr.name === 'yield') {
</del><ins>+                var id = this.scanner.source.slice(start, this.scanner.index);
</ins><span class="cx">                 return {
</span><del>-                    type: PlaceHolders.ArrowParameterPlaceHolder,
-                    params: [expr]
</del><ins>+                    type: JSXToken.Identifier,
+                    value: id,
+                    lineNumber: this.scanner.lineNumber,
+                    lineStart: this.scanner.lineStart,
+                    start: start,
+                    end: this.scanner.index
</ins><span class="cx">                 };
</span><span class="cx">             }
</span><del>-
-            if (!isBindingElement) {
-                throwUnexpectedToken(lookahead);
</del><ins>+            this.scanner.throwUnexpectedToken();
+        };
+        JSXParser.prototype.nextJSXToken = function () {
+            this.collectComments();
+            this.startMarker.index = this.scanner.index;
+            this.startMarker.lineNumber = this.scanner.lineNumber;
+            this.startMarker.lineStart = this.scanner.lineStart;
+            var token = this.lexJSX();
+            this.lastMarker.index = this.scanner.index;
+            this.lastMarker.lineNumber = this.scanner.lineNumber;
+            this.lastMarker.lineStart = this.scanner.lineStart;
+            if (this.config.tokens) {
+                this.tokens.push(this.convertToken(token));
</ins><span class="cx">             }
</span><del>-
-            if (expr.type === Syntax.SequenceExpression) {
-                for (i = 0; i &lt; expr.expressions.length; i++) {
-                    reinterpretExpressionAsPattern(expr.expressions[i]);
</del><ins>+            return token;
+        };
+        JSXParser.prototype.nextJSXText = function () {
+            this.startMarker.index = this.scanner.index;
+            this.startMarker.lineNumber = this.scanner.lineNumber;
+            this.startMarker.lineStart = this.scanner.lineStart;
+            var start = this.scanner.index;
+            var text = '';
+            while (!this.scanner.eof()) {
+                var ch = this.scanner.source[this.scanner.index];
+                if (ch === '{' || ch === '&lt;') {
+                    break;
</ins><span class="cx">                 }
</span><del>-            } else {
-                reinterpretExpressionAsPattern(expr);
</del><ins>+                ++this.scanner.index;
+                text += ch;
+                if (character_1.Character.isLineTerminator(ch.charCodeAt(0))) {
+                    ++this.scanner.lineNumber;
+                    if (ch === '\r' &amp;&amp; this.scanner.source[this.scanner.index] === '\n') {
+                        ++this.scanner.index;
+                    }
+                    this.scanner.lineStart = this.scanner.index;
+                }
</ins><span class="cx">             }
</span><del>-
-            expr = {
-                type: PlaceHolders.ArrowParameterPlaceHolder,
-                params: expr.type === Syntax.SequenceExpression ? expr.expressions : [expr]
</del><ins>+            this.lastMarker.index = this.scanner.index;
+            this.lastMarker.lineNumber = this.scanner.lineNumber;
+            this.lastMarker.lineStart = this.scanner.lineStart;
+            var token = {
+                type: JSXToken.Text,
+                value: text,
+                lineNumber: this.scanner.lineNumber,
+                lineStart: this.scanner.lineStart,
+                start: start,
+                end: this.scanner.index
</ins><span class="cx">             };
</span><del>-        }
-        isBindingElement = false;
-        return expr;
-    }
-
-
-    // ECMA-262 12.2 Primary Expressions
-
-    function parsePrimaryExpression() {
-        var type, token, expr, node;
-
-        if (match('(')) {
-            isBindingElement = false;
-            return inheritCoverGrammar(parseGroupExpression);
-        }
-
-        if (match('[')) {
-            return inheritCoverGrammar(parseArrayInitializer);
-        }
-
-        if (match('{')) {
-            return inheritCoverGrammar(parseObjectInitializer);
-        }
-
-        type = lookahead.type;
-        node = new Node();
-
-        if (type === Token.Identifier) {
-            if (state.sourceType === 'module' &amp;&amp; lookahead.value === 'await') {
-                tolerateUnexpectedToken(lookahead);
</del><ins>+            if ((text.length &gt; 0) &amp;&amp; this.config.tokens) {
+                this.tokens.push(this.convertToken(token));
</ins><span class="cx">             }
</span><del>-            expr = node.finishIdentifier(lex().value);
-        } else if (type === Token.StringLiteral || type === Token.NumericLiteral) {
-            isAssignmentTarget = isBindingElement = false;
-            if (strict &amp;&amp; lookahead.octal) {
-                tolerateUnexpectedToken(lookahead, Messages.StrictOctalLiteral);
</del><ins>+            return token;
+        };
+        JSXParser.prototype.peekJSXToken = function () {
+            var previousIndex = this.scanner.index;
+            var previousLineNumber = this.scanner.lineNumber;
+            var previousLineStart = this.scanner.lineStart;
+            this.scanner.scanComments();
+            var next = this.lexJSX();
+            this.scanner.index = previousIndex;
+            this.scanner.lineNumber = previousLineNumber;
+            this.scanner.lineStart = previousLineStart;
+            return next;
+        };
+        // Expect the next JSX token to match the specified punctuator.
+        // If not, an exception will be thrown.
+        JSXParser.prototype.expectJSX = function (value) {
+            var token = this.nextJSXToken();
+            if (token.type !== token_1.Token.Punctuator || token.value !== value) {
+                this.throwUnexpectedToken(token);
</ins><span class="cx">             }
</span><del>-            expr = node.finishLiteral(lex());
-        } else if (type === Token.Keyword) {
-            if (!strict &amp;&amp; state.allowYield &amp;&amp; matchKeyword('yield')) {
-                return parseNonComputedProperty();
</del><ins>+        };
+        // Return true if the next JSX token matches the specified punctuator.
+        JSXParser.prototype.matchJSX = function (value) {
+            var next = this.peekJSXToken();
+            return next.type === token_1.Token.Punctuator &amp;&amp; next.value === value;
+        };
+        JSXParser.prototype.parseJSXIdentifier = function () {
+            var node = this.createJSXNode();
+            var token = this.nextJSXToken();
+            if (token.type !== JSXToken.Identifier) {
+                this.throwUnexpectedToken(token);
</ins><span class="cx">             }
</span><del>-            isAssignmentTarget = isBindingElement = false;
-            if (matchKeyword('function')) {
-                return parseFunctionExpression();
</del><ins>+            return this.finalize(node, new JSXNode.JSXIdentifier(token.value));
+        };
+        JSXParser.prototype.parseJSXElementName = function () {
+            var node = this.createJSXNode();
+            var elementName = this.parseJSXIdentifier();
+            if (this.matchJSX(':')) {
+                var namespace = elementName;
+                this.expectJSX(':');
+                var name_1 = this.parseJSXIdentifier();
+                elementName = this.finalize(node, new JSXNode.JSXNamespacedName(namespace, name_1));
</ins><span class="cx">             }
</span><del>-            if (matchKeyword('this')) {
-                lex();
-                return node.finishThisExpression();
-            }
-            if (matchKeyword('class')) {
-                return parseClassExpression();
-            }
-            throwUnexpectedToken(lex());
-        } else if (type === Token.BooleanLiteral) {
-            isAssignmentTarget = isBindingElement = false;
-            token = lex();
-            token.value = (token.value === 'true');
-            expr = node.finishLiteral(token);
-        } else if (type === Token.NullLiteral) {
-            isAssignmentTarget = isBindingElement = false;
-            token = lex();
-            token.value = null;
-            expr = node.finishLiteral(token);
-        } else if (match('/') || match('/=')) {
-            isAssignmentTarget = isBindingElement = false;
-            index = startIndex;
-
-            if (typeof extra.tokens !== 'undefined') {
-                token = collectRegex();
-            } else {
-                token = scanRegExp();
-            }
-            lex();
-            expr = node.finishLiteral(token);
-        } else if (type === Token.Template) {
-            expr = parseTemplateLiteral();
-        } else {
-            throwUnexpectedToken(lex());
-        }
-
-        return expr;
-    }
-
-    // ECMA-262 12.3 Left-Hand-Side Expressions
-
-    function parseArguments() {
-        var args = [], expr;
-
-        expect('(');
-
-        if (!match(')')) {
-            while (startIndex &lt; length) {
-                if (match('...')) {
-                    expr = new Node();
-                    lex();
-                    expr.finishSpreadElement(isolateCoverGrammar(parseAssignmentExpression));
-                } else {
-                    expr = isolateCoverGrammar(parseAssignmentExpression);
</del><ins>+            else if (this.matchJSX('.')) {
+                while (this.matchJSX('.')) {
+                    var object = elementName;
+                    this.expectJSX('.');
+                    var property = this.parseJSXIdentifier();
+                    elementName = this.finalize(node, new JSXNode.JSXMemberExpression(object, property));
</ins><span class="cx">                 }
</span><del>-                args.push(expr);
-                if (match(')')) {
-                    break;
-                }
-                expectCommaSeparator();
</del><span class="cx">             }
</span><del>-        }
-
-        expect(')');
-
-        return args;
-    }
-
-    function parseNonComputedProperty() {
-        var token, node = new Node();
-
-        token = lex();
-
-        if (!isIdentifierName(token)) {
-            throwUnexpectedToken(token);
-        }
-
-        return node.finishIdentifier(token.value);
-    }
-
-    function parseNonComputedMember() {
-        expect('.');
-
-        return parseNonComputedProperty();
-    }
-
-    function parseComputedMember() {
-        var expr;
-
-        expect('[');
-
-        expr = isolateCoverGrammar(parseExpression);
-
-        expect(']');
-
-        return expr;
-    }
-
-    // ECMA-262 12.3.3 The new Operator
-
-    function parseNewExpression() {
-        var callee, args, node = new Node();
-
-        expectKeyword('new');
-
-        if (match('.')) {
-            lex();
-            if (lookahead.type === Token.Identifier &amp;&amp; lookahead.value === 'target') {
-                if (state.inFunctionBody) {
-                    lex();
-                    return node.finishMetaProperty('new', 'target');
-                }
</del><ins>+            return elementName;
+        };
+        JSXParser.prototype.parseJSXAttributeName = function () {
+            var node = this.createJSXNode();
+            var attributeName;
+            var identifier = this.parseJSXIdentifier();
+            if (this.matchJSX(':')) {
+                var namespace = identifier;
+                this.expectJSX(':');
+                var name_2 = this.parseJSXIdentifier();
+                attributeName = this.finalize(node, new JSXNode.JSXNamespacedName(namespace, name_2));
</ins><span class="cx">             }
</span><del>-            throwUnexpectedToken(lookahead);
-        }
-
-        callee = isolateCoverGrammar(parseLeftHandSideExpression);
-        args = match('(') ? parseArguments() : [];
-
-        isAssignmentTarget = isBindingElement = false;
-
-        return node.finishNewExpression(callee, args);
-    }
-
-    // ECMA-262 12.3.4 Function Calls
-
-    function parseLeftHandSideExpressionAllowCall() {
-        var quasi, expr, args, property, startToken, previousAllowIn = state.allowIn;
-
-        startToken = lookahead;
-        state.allowIn = true;
-
-        if (matchKeyword('super') &amp;&amp; state.inFunctionBody) {
-            expr = new Node();
-            lex();
-            expr = expr.finishSuper();
-            if (!match('(') &amp;&amp; !match('.') &amp;&amp; !match('[')) {
-                throwUnexpectedToken(lookahead);
</del><ins>+            else {
+                attributeName = identifier;
</ins><span class="cx">             }
</span><del>-        } else {
-            expr = inheritCoverGrammar(matchKeyword('new') ? parseNewExpression : parsePrimaryExpression);
-        }
-
-        for (;;) {
-            if (match('.')) {
-                isBindingElement = false;
-                isAssignmentTarget = true;
-                property = parseNonComputedMember();
-                expr = new WrappingNode(startToken).finishMemberExpression('.', expr, property);
-            } else if (match('(')) {
-                isBindingElement = false;
-                isAssignmentTarget = false;
-                args = parseArguments();
-                expr = new WrappingNode(startToken).finishCallExpression(expr, args);
-            } else if (match('[')) {
-                isBindingElement = false;
-                isAssignmentTarget = true;
-                property = parseComputedMember();
-                expr = new WrappingNode(startToken).finishMemberExpression('[', expr, property);
-            } else if (lookahead.type === Token.Template &amp;&amp; lookahead.head) {
-                quasi = parseTemplateLiteral();
-                expr = new WrappingNode(startToken).finishTaggedTemplateExpression(expr, quasi);
-            } else {
-                break;
</del><ins>+            return attributeName;
+        };
+        JSXParser.prototype.parseJSXStringLiteralAttribute = function () {
+            var node = this.createJSXNode();
+            var token = this.nextJSXToken();
+            if (token.type !== token_1.Token.StringLiteral) {
+                this.throwUnexpectedToken(token);
</ins><span class="cx">             }
</span><del>-        }
-        state.allowIn = previousAllowIn;
-
-        return expr;
-    }
-
-    // ECMA-262 12.3 Left-Hand-Side Expressions
-
-    function parseLeftHandSideExpression() {
-        var quasi, expr, property, startToken;
-        assert(state.allowIn, 'callee of new expression always allow in keyword.');
-
-        startToken = lookahead;
-
-        if (matchKeyword('super') &amp;&amp; state.inFunctionBody) {
-            expr = new Node();
-            lex();
-            expr = expr.finishSuper();
-            if (!match('[') &amp;&amp; !match('.')) {
-                throwUnexpectedToken(lookahead);
</del><ins>+            var raw = this.getTokenRaw(token);
+            return this.finalize(node, new Node.Literal(token.value, raw));
+        };
+        JSXParser.prototype.parseJSXExpressionAttribute = function () {
+            var node = this.createJSXNode();
+            this.expectJSX('{');
+            this.finishJSX();
+            if (this.match('}')) {
+                this.tolerateError('JSX attributes must only be assigned a non-empty expression');
</ins><span class="cx">             }
</span><del>-        } else {
-            expr = inheritCoverGrammar(matchKeyword('new') ? parseNewExpression : parsePrimaryExpression);
-        }
-
-        for (;;) {
-            if (match('[')) {
-                isBindingElement = false;
-                isAssignmentTarget = true;
-                property = parseComputedMember();
-                expr = new WrappingNode(startToken).finishMemberExpression('[', expr, property);
-            } else if (match('.')) {
-                isBindingElement = false;
-                isAssignmentTarget = true;
-                property = parseNonComputedMember();
-                expr = new WrappingNode(startToken).finishMemberExpression('.', expr, property);
-            } else if (lookahead.type === Token.Template &amp;&amp; lookahead.head) {
-                quasi = parseTemplateLiteral();
-                expr = new WrappingNode(startToken).finishTaggedTemplateExpression(expr, quasi);
-            } else {
-                break;
</del><ins>+            var expression = this.parseAssignmentExpression();
+            this.reenterJSX();
+            return this.finalize(node, new JSXNode.JSXExpressionContainer(expression));
+        };
+        JSXParser.prototype.parseJSXAttributeValue = function () {
+            return this.matchJSX('{') ? this.parseJSXExpressionAttribute() :
+                this.matchJSX('&lt;') ? this.parseJSXElement() : this.parseJSXStringLiteralAttribute();
+        };
+        JSXParser.prototype.parseJSXNameValueAttribute = function () {
+            var node = this.createJSXNode();
+            var name = this.parseJSXAttributeName();
+            var value = null;
+            if (this.matchJSX('=')) {
+                this.expectJSX('=');
+                value = this.parseJSXAttributeValue();
</ins><span class="cx">             }
</span><del>-        }
-        return expr;
-    }
-
-    // ECMA-262 12.4 Postfix Expressions
-
-    function parsePostfixExpression() {
-        var expr, token, startToken = lookahead;
-
-        expr = inheritCoverGrammar(parseLeftHandSideExpressionAllowCall);
-
-        if (!hasLineTerminator &amp;&amp; lookahead.type === Token.Punctuator) {
-            if (match('++') || match('--')) {
-                // ECMA-262 11.3.1, 11.3.2
-                if (strict &amp;&amp; expr.type === Syntax.Identifier &amp;&amp; isRestrictedWord(expr.name)) {
-                    tolerateError(Messages.StrictLHSPostfix);
-                }
-
-                if (!isAssignmentTarget) {
-                    tolerateError(Messages.InvalidLHSInAssignment);
-                }
-
-                isAssignmentTarget = isBindingElement = false;
-
-                token = lex();
-                expr = new WrappingNode(startToken).finishPostfixExpression(token.value, expr);
</del><ins>+            return this.finalize(node, new JSXNode.JSXAttribute(name, value));
+        };
+        JSXParser.prototype.parseJSXSpreadAttribute = function () {
+            var node = this.createJSXNode();
+            this.expectJSX('{');
+            this.expectJSX('...');
+            this.finishJSX();
+            var argument = this.parseAssignmentExpression();
+            this.reenterJSX();
+            return this.finalize(node, new JSXNode.JSXSpreadAttribute(argument));
+        };
+        JSXParser.prototype.parseJSXAttributes = function () {
+            var attributes = [];
+            while (!this.matchJSX('/') &amp;&amp; !this.matchJSX('&gt;')) {
+                var attribute = this.matchJSX('{') ? this.parseJSXSpreadAttribute() :
+                    this.parseJSXNameValueAttribute();
+                attributes.push(attribute);
</ins><span class="cx">             }
</span><del>-        }
-
-        return expr;
-    }
-
-    // ECMA-262 12.5 Unary Operators
-
-    function parseUnaryExpression() {
-        var token, expr, startToken;
-
-        if (lookahead.type !== Token.Punctuator &amp;&amp; lookahead.type !== Token.Keyword) {
-            expr = parsePostfixExpression();
-        } else if (match('++') || match('--')) {
-            startToken = lookahead;
-            token = lex();
-            expr = inheritCoverGrammar(parseUnaryExpression);
-            // ECMA-262 11.4.4, 11.4.5
-            if (strict &amp;&amp; expr.type === Syntax.Identifier &amp;&amp; isRestrictedWord(expr.name)) {
-                tolerateError(Messages.StrictLHSPrefix);
</del><ins>+            return attributes;
+        };
+        JSXParser.prototype.parseJSXOpeningElement = function () {
+            var node = this.createJSXNode();
+            this.expectJSX('&lt;');
+            var name = this.parseJSXElementName();
+            var attributes = this.parseJSXAttributes();
+            var selfClosing = this.matchJSX('/');
+            if (selfClosing) {
+                this.expectJSX('/');
</ins><span class="cx">             }
</span><del>-
-            if (!isAssignmentTarget) {
-                tolerateError(Messages.InvalidLHSInAssignment);
</del><ins>+            this.expectJSX('&gt;');
+            return this.finalize(node, new JSXNode.JSXOpeningElement(name, selfClosing, attributes));
+        };
+        JSXParser.prototype.parseJSXBoundaryElement = function () {
+            var node = this.createJSXNode();
+            this.expectJSX('&lt;');
+            if (this.matchJSX('/')) {
+                this.expectJSX('/');
+                var name_3 = this.parseJSXElementName();
+                this.expectJSX('&gt;');
+                return this.finalize(node, new JSXNode.JSXClosingElement(name_3));
</ins><span class="cx">             }
</span><del>-            expr = new WrappingNode(startToken).finishUnaryExpression(token.value, expr);
-            isAssignmentTarget = isBindingElement = false;
-        } else if (match('+') || match('-') || match('~') || match('!')) {
-            startToken = lookahead;
-            token = lex();
-            expr = inheritCoverGrammar(parseUnaryExpression);
-            expr = new WrappingNode(startToken).finishUnaryExpression(token.value, expr);
-            isAssignmentTarget = isBindingElement = false;
-        } else if (matchKeyword('delete') || matchKeyword('void') || matchKeyword('typeof')) {
-            startToken = lookahead;
-            token = lex();
-            expr = inheritCoverGrammar(parseUnaryExpression);
-            expr = new WrappingNode(startToken).finishUnaryExpression(token.value, expr);
-            if (strict &amp;&amp; expr.operator === 'delete' &amp;&amp; expr.argument.type === Syntax.Identifier) {
-                tolerateError(Messages.StrictDelete);
</del><ins>+            var name = this.parseJSXElementName();
+            var attributes = this.parseJSXAttributes();
+            var selfClosing = this.matchJSX('/');
+            if (selfClosing) {
+                this.expectJSX('/');
</ins><span class="cx">             }
</span><del>-            isAssignmentTarget = isBindingElement = false;
-        } else {
-            expr = parsePostfixExpression();
-        }
-
-        return expr;
-    }
-
-    function binaryPrecedence(token, allowIn) {
-        var prec = 0;
-
-        if (token.type !== Token.Punctuator &amp;&amp; token.type !== Token.Keyword) {
-            return 0;
-        }
-
-        switch (token.value) {
-        case '||':
-            prec = 1;
-            break;
-
-        case '&amp;&amp;':
-            prec = 2;
-            break;
-
-        case '|':
-            prec = 3;
-            break;
-
-        case '^':
-            prec = 4;
-            break;
-
-        case '&amp;':
-            prec = 5;
-            break;
-
-        case '==':
-        case '!=':
-        case '===':
-        case '!==':
-            prec = 6;
-            break;
-
-        case '&lt;':
-        case '&gt;':
-        case '&lt;=':
-        case '&gt;=':
-        case 'instanceof':
-            prec = 7;
-            break;
-
-        case 'in':
-            prec = allowIn ? 7 : 0;
-            break;
-
-        case '&lt;&lt;':
-        case '&gt;&gt;':
-        case '&gt;&gt;&gt;':
-            prec = 8;
-            break;
-
-        case '+':
-        case '-':
-            prec = 9;
-            break;
-
-        case '*':
-        case '/':
-        case '%':
-            prec = 11;
-            break;
-
-        default:
-            break;
-        }
-
-        return prec;
-    }
-
-    // ECMA-262 12.6 Multiplicative Operators
-    // ECMA-262 12.7 Additive Operators
-    // ECMA-262 12.8 Bitwise Shift Operators
-    // ECMA-262 12.9 Relational Operators
-    // ECMA-262 12.10 Equality Operators
-    // ECMA-262 12.11 Binary Bitwise Operators
-    // ECMA-262 12.12 Binary Logical Operators
-
-    function parseBinaryExpression() {
-        var marker, markers, expr, token, prec, stack, right, operator, left, i;
-
-        marker = lookahead;
-        left = inheritCoverGrammar(parseUnaryExpression);
-
-        token = lookahead;
-        prec = binaryPrecedence(token, state.allowIn);
-        if (prec === 0) {
-            return left;
-        }
-        isAssignmentTarget = isBindingElement = false;
-        token.prec = prec;
-        lex();
-
-        markers = [marker, lookahead];
-        right = isolateCoverGrammar(parseUnaryExpression);
-
-        stack = [left, token, right];
-
-        while ((prec = binaryPrecedence(lookahead, state.allowIn)) &gt; 0) {
-
-            // Reduce: make a binary expression from the three topmost entries.
-            while ((stack.length &gt; 2) &amp;&amp; (prec &lt;= stack[stack.length - 2].prec)) {
-                right = stack.pop();
-                operator = stack.pop().value;
-                left = stack.pop();
-                markers.pop();
-                expr = new WrappingNode(markers[markers.length - 1]).finishBinaryExpression(operator, left, right);
-                stack.push(expr);
-            }
-
-            // Shift.
-            token = lex();
-            token.prec = prec;
-            stack.push(token);
-            markers.push(lookahead);
-            expr = isolateCoverGrammar(parseUnaryExpression);
-            stack.push(expr);
-        }
-
-        // Final reduce to clean-up the stack.
-        i = stack.length - 1;
-        expr = stack[i];
-        markers.pop();
-        while (i &gt; 1) {
-            expr = new WrappingNode(markers.pop()).finishBinaryExpression(stack[i - 1].value, stack[i - 2], expr);
-            i -= 2;
-        }
-
-        return expr;
-    }
-
-
-    // ECMA-262 12.13 Conditional Operator
-
-    function parseConditionalExpression() {
-        var expr, previousAllowIn, consequent, alternate, startToken;
-
-        startToken = lookahead;
-
-        expr = inheritCoverGrammar(parseBinaryExpression);
-        if (match('?')) {
-            lex();
-            previousAllowIn = state.allowIn;
-            state.allowIn = true;
-            consequent = isolateCoverGrammar(parseAssignmentExpression);
-            state.allowIn = previousAllowIn;
-            expect(':');
-            alternate = isolateCoverGrammar(parseAssignmentExpression);
-
-            expr = new WrappingNode(startToken).finishConditionalExpression(expr, consequent, alternate);
-            isAssignmentTarget = isBindingElement = false;
-        }
-
-        return expr;
-    }
-
-    // ECMA-262 14.2 Arrow Function Definitions
-
-    function parseConciseBody() {
-        if (match('{')) {
-            return parseFunctionSourceElements();
-        }
-        return isolateCoverGrammar(parseAssignmentExpression);
-    }
-
-    function checkPatternParam(options, param) {
-        var i;
-        switch (param.type) {
-        case Syntax.Identifier:
-            validateParam(options, param, param.name);
-            break;
-        case Syntax.RestElement:
-            checkPatternParam(options, param.argument);
-            break;
-        case Syntax.AssignmentPattern:
-            checkPatternParam(options, param.left);
-            break;
-        case Syntax.ArrayPattern:
-            for (i = 0; i &lt; param.elements.length; i++) {
-                if (param.elements[i] !== null) {
-                    checkPatternParam(options, param.elements[i]);
-                }
-            }
-            break;
-        case Syntax.YieldExpression:
-            break;
-        default:
-            assert(param.type === Syntax.ObjectPattern, 'Invalid type');
-            for (i = 0; i &lt; param.properties.length; i++) {
-                checkPatternParam(options, param.properties[i].value);
-            }
-            break;
-        }
-    }
-    function reinterpretAsCoverFormalsList(expr) {
-        var i, len, param, params, defaults, defaultCount, options, token;
-
-        defaults = [];
-        defaultCount = 0;
-        params = [expr];
-
-        switch (expr.type) {
-        case Syntax.Identifier:
-            break;
-        case PlaceHolders.ArrowParameterPlaceHolder:
-            params = expr.params;
-            break;
-        default:
-            return null;
-        }
-
-        options = {
-            paramSet: {}
</del><ins>+            this.expectJSX('&gt;');
+            return this.finalize(node, new JSXNode.JSXOpeningElement(name, selfClosing, attributes));
</ins><span class="cx">         };
</span><del>-
-        for (i = 0, len = params.length; i &lt; len; i += 1) {
-            param = params[i];
-            switch (param.type) {
-            case Syntax.AssignmentPattern:
-                params[i] = param.left;
-                if (param.right.type === Syntax.YieldExpression) {
-                    if (param.right.argument) {
-                        throwUnexpectedToken(lookahead);
-                    }
-                    param.right.type = Syntax.Identifier;
-                    param.right.name = 'yield';
-                    delete param.right.argument;
-                    delete param.right.delegate;
-                }
-                defaults.push(param.right);
-                ++defaultCount;
-                checkPatternParam(options, param.left);
-                break;
-            default:
-                checkPatternParam(options, param);
-                params[i] = param;
-                defaults.push(null);
-                break;
</del><ins>+        JSXParser.prototype.parseJSXEmptyExpression = function () {
+            var node = this.createJSXChildNode();
+            this.collectComments();
+            this.lastMarker.index = this.scanner.index;
+            this.lastMarker.lineNumber = this.scanner.lineNumber;
+            this.lastMarker.lineStart = this.scanner.lineStart;
+            return this.finalize(node, new JSXNode.JSXEmptyExpression());
+        };
+        JSXParser.prototype.parseJSXExpressionContainer = function () {
+            var node = this.createJSXNode();
+            this.expectJSX('{');
+            var expression;
+            if (this.matchJSX('}')) {
+                expression = this.parseJSXEmptyExpression();
+                this.expectJSX('}');
</ins><span class="cx">             }
</span><del>-        }
-
-        if (strict || !state.allowYield) {
-            for (i = 0, len = params.length; i &lt; len; i += 1) {
-                param = params[i];
-                if (param.type === Syntax.YieldExpression) {
-                    throwUnexpectedToken(lookahead);
-                }
</del><ins>+            else {
+                this.finishJSX();
+                expression = this.parseAssignmentExpression();
+                this.reenterJSX();
</ins><span class="cx">             }
</span><del>-        }
-
-        if (options.message === Messages.StrictParamDupe) {
-            token = strict ? options.stricted : options.firstRestricted;
-            throwUnexpectedToken(token, options.message);
-        }
-
-        if (defaultCount === 0) {
-            defaults = [];
-        }
-
-        return {
-            params: params,
-            defaults: defaults,
-            stricted: options.stricted,
-            firstRestricted: options.firstRestricted,
-            message: options.message
</del><ins>+            return this.finalize(node, new JSXNode.JSXExpressionContainer(expression));
</ins><span class="cx">         };
</span><del>-    }
-
-    function parseArrowFunctionExpression(options, node) {
-        var previousStrict, previousAllowYield, body;
-
-        if (hasLineTerminator) {
-            tolerateUnexpectedToken(lookahead);
-        }
-        expect('=&gt;');
-
-        previousStrict = strict;
-        previousAllowYield = state.allowYield;
-        state.allowYield = true;
-
-        body = parseConciseBody();
-
-        if (strict &amp;&amp; options.firstRestricted) {
-            throwUnexpectedToken(options.firstRestricted, options.message);
-        }
-        if (strict &amp;&amp; options.stricted) {
-            tolerateUnexpectedToken(options.stricted, options.message);
-        }
-
-        strict = previousStrict;
-        state.allowYield = previousAllowYield;
-
-        return node.finishArrowFunctionExpression(options.params, options.defaults, body, body.type !== Syntax.BlockStatement);
-    }
-
-    // ECMA-262 14.4 Yield expression
-
-    function parseYieldExpression() {
-        var argument, expr, delegate, previousAllowYield;
-
-        argument = null;
-        expr = new Node();
-
-        expectKeyword('yield');
-
-        if (!hasLineTerminator) {
-            previousAllowYield = state.allowYield;
-            state.allowYield = false;
-            delegate = match('*');
-            if (delegate) {
-                lex();
-                argument = parseAssignmentExpression();
-            } else {
-                if (!match(';') &amp;&amp; !match('}') &amp;&amp; !match(')') &amp;&amp; lookahead.type !== Token.EOF) {
-                    argument = parseAssignmentExpression();
</del><ins>+        JSXParser.prototype.parseJSXChildren = function () {
+            var children = [];
+            while (!this.scanner.eof()) {
+                var node = this.createJSXChildNode();
+                var token = this.nextJSXText();
+                if (token.start &lt; token.end) {
+                    var raw = this.getTokenRaw(token);
+                    var child = this.finalize(node, new JSXNode.JSXText(token.value, raw));
+                    children.push(child);
</ins><span class="cx">                 }
</span><del>-            }
-            state.allowYield = previousAllowYield;
-        }
-
-        return expr.finishYieldExpression(argument, delegate);
-    }
-
-    // ECMA-262 12.14 Assignment Operators
-
-    function parseAssignmentExpression() {
-        var token, expr, right, list, startToken;
-
-        startToken = lookahead;
-        token = lookahead;
-
-        if (!state.allowYield &amp;&amp; matchKeyword('yield')) {
-            return parseYieldExpression();
-        }
-
-        expr = parseConditionalExpression();
-
-        if (expr.type === PlaceHolders.ArrowParameterPlaceHolder || match('=&gt;')) {
-            isAssignmentTarget = isBindingElement = false;
-            list = reinterpretAsCoverFormalsList(expr);
-
-            if (list) {
-                firstCoverInitializedNameError = null;
-                return parseArrowFunctionExpression(list, new WrappingNode(startToken));
-            }
-
-            return expr;
-        }
-
-        if (matchAssign()) {
-            if (!isAssignmentTarget) {
-                tolerateError(Messages.InvalidLHSInAssignment);
-            }
-
-            // ECMA-262 12.1.1
-            if (strict &amp;&amp; expr.type === Syntax.Identifier) {
-                if (isRestrictedWord(expr.name)) {
-                    tolerateUnexpectedToken(token, Messages.StrictLHSAssignment);
</del><ins>+                if (this.scanner.source[this.scanner.index] === '{') {
+                    var container = this.parseJSXExpressionContainer();
+                    children.push(container);
</ins><span class="cx">                 }
</span><del>-                if (isStrictModeReservedWord(expr.name)) {
-                    tolerateUnexpectedToken(token, Messages.StrictReservedWord);
-                }
-            }
-
-            if (!match('=')) {
-                isAssignmentTarget = isBindingElement = false;
-            } else {
-                reinterpretExpressionAsPattern(expr);
-            }
-
-            token = lex();
-            right = isolateCoverGrammar(parseAssignmentExpression);
-            expr = new WrappingNode(startToken).finishAssignmentExpression(token.value, expr, right);
-            firstCoverInitializedNameError = null;
-        }
-
-        return expr;
-    }
-
-    // ECMA-262 12.15 Comma Operator
-
-    function parseExpression() {
-        var expr, startToken = lookahead, expressions;
-
-        expr = isolateCoverGrammar(parseAssignmentExpression);
-
-        if (match(',')) {
-            expressions = [expr];
-
-            while (startIndex &lt; length) {
-                if (!match(',')) {
</del><ins>+                else {
</ins><span class="cx">                     break;
</span><span class="cx">                 }
</span><del>-                lex();
-                expressions.push(isolateCoverGrammar(parseAssignmentExpression));
</del><span class="cx">             }
</span><del>-
-            expr = new WrappingNode(startToken).finishSequenceExpression(expressions);
-        }
-
-        return expr;
-    }
-
-    // ECMA-262 13.2 Block
-
-    function parseStatementListItem() {
-        if (lookahead.type === Token.Keyword) {
-            switch (lookahead.value) {
-            case 'export':
-                if (state.sourceType !== 'module') {
-                    tolerateUnexpectedToken(lookahead, Messages.IllegalExportDeclaration);
</del><ins>+            return children;
+        };
+        JSXParser.prototype.parseComplexJSXElement = function (el) {
+            var stack = [];
+            while (!this.scanner.eof()) {
+                el.children = el.children.concat(this.parseJSXChildren());
+                var node = this.createJSXChildNode();
+                var element = this.parseJSXBoundaryElement();
+                if (element.type === jsx_syntax_1.JSXSyntax.JSXOpeningElement) {
+                    var opening = (element);
+                    if (opening.selfClosing) {
+                        var child = this.finalize(node, new JSXNode.JSXElement(opening, [], null));
+                        el.children.push(child);
+                    }
+                    else {
+                        stack.push(el);
+                        el = { node: node, opening: opening, closing: null, children: [] };
+                    }
</ins><span class="cx">                 }
</span><del>-                return parseExportDeclaration();
-            case 'import':
-                if (state.sourceType !== 'module') {
-                    tolerateUnexpectedToken(lookahead, Messages.IllegalImportDeclaration);
-                }
-                return parseImportDeclaration();
-            case 'const':
-            case 'let':
-                return parseLexicalDeclaration({inFor: false});
-            case 'function':
-                return parseFunctionDeclaration(new Node());
-            case 'class':
-                return parseClassDeclaration();
-            }
-        }
-
-        return parseStatement();
-    }
-
-    function parseStatementList() {
-        var list = [];
-        while (startIndex &lt; length) {
-            if (match('}')) {
-                break;
-            }
-            list.push(parseStatementListItem());
-        }
-
-        return list;
-    }
-
-    function parseBlock() {
-        var block, node = new Node();
-
-        expect('{');
-
-        block = parseStatementList();
-
-        expect('}');
-
-        return node.finishBlockStatement(block);
-    }
-
-    // ECMA-262 13.3.2 Variable Statement
-
-    function parseVariableIdentifier(kind) {
-        var token, node = new Node();
-
-        token = lex();
-
-        if (token.type === Token.Keyword &amp;&amp; token.value === 'yield') {
-            if (strict) {
-                tolerateUnexpectedToken(token, Messages.StrictReservedWord);
-            } if (!state.allowYield) {
-                throwUnexpectedToken(token);
-            }
-        } else if (token.type !== Token.Identifier) {
-            if (strict &amp;&amp; token.type === Token.Keyword &amp;&amp; isStrictModeReservedWord(token.value)) {
-                tolerateUnexpectedToken(token, Messages.StrictReservedWord);
-            } else {
-                if (strict || token.value !== 'let' || kind !== 'var') {
-                    throwUnexpectedToken(token);
-                }
-            }
-        } else if (state.sourceType === 'module' &amp;&amp; token.type === Token.Identifier &amp;&amp; token.value === 'await') {
-            tolerateUnexpectedToken(token);
-        }
-
-        return node.finishIdentifier(token.value);
-    }
-
-    function parseVariableDeclaration(options) {
-        var init = null, id, node = new Node(), params = [];
-
-        id = parsePattern(params, 'var');
-
-        // ECMA-262 12.2.1
-        if (strict &amp;&amp; isRestrictedWord(id.name)) {
-            tolerateError(Messages.StrictVarName);
-        }
-
-        if (match('=')) {
-            lex();
-            init = isolateCoverGrammar(parseAssignmentExpression);
-        } else if (id.type !== Syntax.Identifier &amp;&amp; !options.inFor) {
-            expect('=');
-        }
-
-        return node.finishVariableDeclarator(id, init);
-    }
-
-    function parseVariableDeclarationList(options) {
-        var list = [];
-
-        do {
-            list.push(parseVariableDeclaration({ inFor: options.inFor }));
-            if (!match(',')) {
-                break;
-            }
-            lex();
-        } while (startIndex &lt; length);
-
-        return list;
-    }
-
-    function parseVariableStatement(node) {
-        var declarations;
-
-        expectKeyword('var');
-
-        declarations = parseVariableDeclarationList({ inFor: false });
-
-        consumeSemicolon();
-
-        return node.finishVariableDeclaration(declarations);
-    }
-
-    // ECMA-262 13.3.1 Let and Const Declarations
-
-    function parseLexicalBinding(kind, options) {
-        var init = null, id, node = new Node(), params = [];
-
-        id = parsePattern(params, kind);
-
-        // ECMA-262 12.2.1
-        if (strict &amp;&amp; id.type === Syntax.Identifier &amp;&amp; isRestrictedWord(id.name)) {
-            tolerateError(Messages.StrictVarName);
-        }
-
-        if (kind === 'const') {
-            if (!matchKeyword('in') &amp;&amp; !matchContextualKeyword('of')) {
-                expect('=');
-                init = isolateCoverGrammar(parseAssignmentExpression);
-            }
-        } else if ((!options.inFor &amp;&amp; id.type !== Syntax.Identifier) || match('=')) {
-            expect('=');
-            init = isolateCoverGrammar(parseAssignmentExpression);
-        }
-
-        return node.finishVariableDeclarator(id, init);
-    }
-
-    function parseBindingList(kind, options) {
-        var list = [];
-
-        do {
-            list.push(parseLexicalBinding(kind, options));
-            if (!match(',')) {
-                break;
-            }
-            lex();
-        } while (startIndex &lt; length);
-
-        return list;
-    }
-
-    function parseLexicalDeclaration(options) {
-        var kind, declarations, node = new Node();
-
-        kind = lex().value;
-        assert(kind === 'let' || kind === 'const', 'Lexical declaration must be either let or const');
-
-        declarations = parseBindingList(kind, options);
-
-        consumeSemicolon();
-
-        return node.finishLexicalDeclaration(declarations, kind);
-    }
-
-    function parseRestElement(params) {
-        var param, node = new Node();
-
-        lex();
-
-        if (match('{')) {
-            throwError(Messages.ObjectPatternAsRestParameter);
-        }
-
-        params.push(lookahead);
-
-        param = parseVariableIdentifier();
-
-        if (match('=')) {
-            throwError(Messages.DefaultRestParameter);
-        }
-
-        if (!match(')')) {
-            throwError(Messages.ParameterAfterRestParameter);
-        }
-
-        return node.finishRestElement(param);
-    }
-
-    // ECMA-262 13.4 Empty Statement
-
-    function parseEmptyStatement(node) {
-        expect(';');
-        return node.finishEmptyStatement();
-    }
-
-    // ECMA-262 12.4 Expression Statement
-
-    function parseExpressionStatement(node) {
-        var expr = parseExpression();
-        consumeSemicolon();
-        return node.finishExpressionStatement(expr);
-    }
-
-    // ECMA-262 13.6 If statement
-
-    function parseIfStatement(node) {
-        var test, consequent, alternate;
-
-        expectKeyword('if');
-
-        expect('(');
-
-        test = parseExpression();
-
-        expect(')');
-
-        consequent = parseStatement();
-
-        if (matchKeyword('else')) {
-            lex();
-            alternate = parseStatement();
-        } else {
-            alternate = null;
-        }
-
-        return node.finishIfStatement(test, consequent, alternate);
-    }
-
-    // ECMA-262 13.7 Iteration Statements
-
-    function parseDoWhileStatement(node) {
-        var body, test, oldInIteration;
-
-        expectKeyword('do');
-
-        oldInIteration = state.inIteration;
-        state.inIteration = true;
-
-        body = parseStatement();
-
-        state.inIteration = oldInIteration;
-
-        expectKeyword('while');
-
-        expect('(');
-
-        test = parseExpression();
-
-        expect(')');
-
-        if (match(';')) {
-            lex();
-        }
-
-        return node.finishDoWhileStatement(body, test);
-    }
-
-    function parseWhileStatement(node) {
-        var test, body, oldInIteration;
-
-        expectKeyword('while');
-
-        expect('(');
-
-        test = parseExpression();
-
-        expect(')');
-
-        oldInIteration = state.inIteration;
-        state.inIteration = true;
-
-        body = parseStatement();
-
-        state.inIteration = oldInIteration;
-
-        return node.finishWhileStatement(test, body);
-    }
-
-    function parseForStatement(node) {
-        var init, forIn, initSeq, initStartToken, test, update, left, right, kind, declarations,
-            body, oldInIteration, previousAllowIn = state.allowIn;
-
-        init = test = update = null;
-        forIn = true;
-
-        expectKeyword('for');
-
-        expect('(');
-
-        if (match(';')) {
-            lex();
-        } else {
-            if (matchKeyword('var')) {
-                init = new Node();
-                lex();
-
-                state.allowIn = false;
-                declarations = parseVariableDeclarationList({ inFor: true });
-                state.allowIn = previousAllowIn;
-
-                if (declarations.length === 1 &amp;&amp; matchKeyword('in')) {
-                    init = init.finishVariableDeclaration(declarations);
-                    lex();
-                    left = init;
-                    right = parseExpression();
-                    init = null;
-                } else if (declarations.length === 1 &amp;&amp; declarations[0].init === null &amp;&amp; matchContextualKeyword('of')) {
-                    init = init.finishVariableDeclaration(declarations);
-                    lex();
-                    left = init;
-                    right = parseAssignmentExpression();
-                    init = null;
-                    forIn = false;
-                } else {
-                    init = init.finishVariableDeclaration(declarations);
-                    expect(';');
-                }
-            } else if (matchKeyword('const') || matchKeyword('let')) {
-                init = new Node();
-                kind = lex().value;
-
-                state.allowIn = false;
-                declarations = parseBindingList(kind, {inFor: true});
-                state.allowIn = previousAllowIn;
-
-                if (declarations.length === 1 &amp;&amp; declarations[0].init === null &amp;&amp; matchKeyword('in')) {
-                    init = init.finishLexicalDeclaration(declarations, kind);
-                    lex();
-                    left = init;
-                    right = parseExpression();
-                    init = null;
-                } else if (declarations.length === 1 &amp;&amp; declarations[0].init === null &amp;&amp; matchContextualKeyword('of')) {
-                    init = init.finishLexicalDeclaration(declarations, kind);
-                    lex();
-                    left = init;
-                    right = parseAssignmentExpression();
-                    init = null;
-                    forIn = false;
-                } else {
-                    consumeSemicolon();
-                    init = init.finishLexicalDeclaration(declarations, kind);
-                }
-            } else {
-                initStartToken = lookahead;
-                state.allowIn = false;
-                init = inheritCoverGrammar(parseAssignmentExpression);
-                state.allowIn = previousAllowIn;
-
-                if (matchKeyword('in')) {
-                    if (!isAssignmentTarget) {
-                        tolerateError(Messages.InvalidLHSInForIn);
</del><ins>+                if (element.type === jsx_syntax_1.JSXSyntax.JSXClosingElement) {
+                    el.closing = (element);
+                    var open_1 = getQualifiedElementName(el.opening.name);
+                    var close_1 = getQualifiedElementName(el.closing.name);
+                    if (open_1 !== close_1) {
+                        this.tolerateError('Expected corresponding JSX closing tag for %0', open_1);
</ins><span class="cx">                     }
</span><del>-
-                    lex();
-                    reinterpretExpressionAsPattern(init);
-                    left = init;
-                    right = parseExpression();
-                    init = null;
-                } else if (matchContextualKeyword('of')) {
-                    if (!isAssignmentTarget) {
-                        tolerateError(Messages.InvalidLHSInForLoop);
</del><ins>+                    if (stack.length &gt; 0) {
+                        var child = this.finalize(el.node, new JSXNode.JSXElement(el.opening, el.children, el.closing));
+                        el = stack[stack.length - 1];
+                        el.children.push(child);
+                        stack.pop();
</ins><span class="cx">                     }
</span><del>-
-                    lex();
-                    reinterpretExpressionAsPattern(init);
-                    left = init;
-                    right = parseAssignmentExpression();
-                    init = null;
-                    forIn = false;
-                } else {
-                    if (match(',')) {
-                        initSeq = [init];
-                        while (match(',')) {
-                            lex();
-                            initSeq.push(isolateCoverGrammar(parseAssignmentExpression));
-                        }
-                        init = new WrappingNode(initStartToken).finishSequenceExpression(initSeq);
</del><ins>+                    else {
+                        break;
</ins><span class="cx">                     }
</span><del>-                    expect(';');
</del><span class="cx">                 }
</span><span class="cx">             }
</span><del>-        }
-
-        if (typeof left === 'undefined') {
-
-            if (!match(';')) {
-                test = parseExpression();
</del><ins>+            return el;
+        };
+        JSXParser.prototype.parseJSXElement = function () {
+            var node = this.createJSXNode();
+            var opening = this.parseJSXOpeningElement();
+            var children = [];
+            var closing = null;
+            if (!opening.selfClosing) {
+                var el = this.parseComplexJSXElement({ node: node, opening: opening, closing: closing, children: children });
+                children = el.children;
+                closing = el.closing;
</ins><span class="cx">             }
</span><del>-            expect(';');
-
-            if (!match(')')) {
-                update = parseExpression();
</del><ins>+            return this.finalize(node, new JSXNode.JSXElement(opening, children, closing));
+        };
+        JSXParser.prototype.parseJSXRoot = function () {
+            // Pop the opening '&lt;' added from the lookahead.
+            if (this.config.tokens) {
+                this.tokens.pop();
</ins><span class="cx">             }
</span><del>-        }
</del><ins>+            this.startJSX();
+            var element = this.parseJSXElement();
+            this.finishJSX();
+            return element;
+        };
+        return JSXParser;
+    }(parser_1.Parser));
+    exports.JSXParser = JSXParser;
</ins><span class="cx"> 
</span><del>-        expect(')');
</del><span class="cx"> 
</span><del>-        oldInIteration = state.inIteration;
-        state.inIteration = true;
</del><ins>+/***/ },
+/* 12 */
+/***/ function(module, exports) {
</ins><span class="cx"> 
</span><del>-        body = isolateCoverGrammar(parseStatement);
</del><ins>+    // Generated by generate-xhtml-entities.js. DO NOT MODIFY!
+    &quot;use strict&quot;;
+    exports.XHTMLEntities = {
+        quot: '\u0022',
+        amp: '\u0026',
+        apos: '\u0027',
+        gt: '\u003E',
+        nbsp: '\u00A0',
+        iexcl: '\u00A1',
+        cent: '\u00A2',
+        pound: '\u00A3',
+        curren: '\u00A4',
+        yen: '\u00A5',
+        brvbar: '\u00A6',
+        sect: '\u00A7',
+        uml: '\u00A8',
+        copy: '\u00A9',
+        ordf: '\u00AA',
+        laquo: '\u00AB',
+        not: '\u00AC',
+        shy: '\u00AD',
+        reg: '\u00AE',
+        macr: '\u00AF',
+        deg: '\u00B0',
+        plusmn: '\u00B1',
+        sup2: '\u00B2',
+        sup3: '\u00B3',
+        acute: '\u00B4',
+        micro: '\u00B5',
+        para: '\u00B6',
+        middot: '\u00B7',
+        cedil: '\u00B8',
+        sup1: '\u00B9',
+        ordm: '\u00BA',
+        raquo: '\u00BB',
+        frac14: '\u00BC',
+        frac12: '\u00BD',
+        frac34: '\u00BE',
+        iquest: '\u00BF',
+        Agrave: '\u00C0',
+        Aacute: '\u00C1',
+        Acirc: '\u00C2',
+        Atilde: '\u00C3',
+        Auml: '\u00C4',
+        Aring: '\u00C5',
+        AElig: '\u00C6',
+        Ccedil: '\u00C7',
+        Egrave: '\u00C8',
+        Eacute: '\u00C9',
+        Ecirc: '\u00CA',
+        Euml: '\u00CB',
+        Igrave: '\u00CC',
+        Iacute: '\u00CD',
+        Icirc: '\u00CE',
+        Iuml: '\u00CF',
+        ETH: '\u00D0',
+        Ntilde: '\u00D1',
+        Ograve: '\u00D2',
+        Oacute: '\u00D3',
+        Ocirc: '\u00D4',
+        Otilde: '\u00D5',
+        Ouml: '\u00D6',
+        times: '\u00D7',
+        Oslash: '\u00D8',
+        Ugrave: '\u00D9',
+        Uacute: '\u00DA',
+        Ucirc: '\u00DB',
+        Uuml: '\u00DC',
+        Yacute: '\u00DD',
+        THORN: '\u00DE',
+        szlig: '\u00DF',
+        agrave: '\u00E0',
+        aacute: '\u00E1',
+        acirc: '\u00E2',
+        atilde: '\u00E3',
+        auml: '\u00E4',
+        aring: '\u00E5',
+        aelig: '\u00E6',
+        ccedil: '\u00E7',
+        egrave: '\u00E8',
+        eacute: '\u00E9',
+        ecirc: '\u00EA',
+        euml: '\u00EB',
+        igrave: '\u00EC',
+        iacute: '\u00ED',
+        icirc: '\u00EE',
+        iuml: '\u00EF',
+        eth: '\u00F0',
+        ntilde: '\u00F1',
+        ograve: '\u00F2',
+        oacute: '\u00F3',
+        ocirc: '\u00F4',
+        otilde: '\u00F5',
+        ouml: '\u00F6',
+        divide: '\u00F7',
+        oslash: '\u00F8',
+        ugrave: '\u00F9',
+        uacute: '\u00FA',
+        ucirc: '\u00FB',
+        uuml: '\u00FC',
+        yacute: '\u00FD',
+        thorn: '\u00FE',
+        yuml: '\u00FF',
+        OElig: '\u0152',
+        oelig: '\u0153',
+        Scaron: '\u0160',
+        scaron: '\u0161',
+        Yuml: '\u0178',
+        fnof: '\u0192',
+        circ: '\u02C6',
+        tilde: '\u02DC',
+        Alpha: '\u0391',
+        Beta: '\u0392',
+        Gamma: '\u0393',
+        Delta: '\u0394',
+        Epsilon: '\u0395',
+        Zeta: '\u0396',
+        Eta: '\u0397',
+        Theta: '\u0398',
+        Iota: '\u0399',
+        Kappa: '\u039A',
+        Lambda: '\u039B',
+        Mu: '\u039C',
+        Nu: '\u039D',
+        Xi: '\u039E',
+        Omicron: '\u039F',
+        Pi: '\u03A0',
+        Rho: '\u03A1',
+        Sigma: '\u03A3',
+        Tau: '\u03A4',
+        Upsilon: '\u03A5',
+        Phi: '\u03A6',
+        Chi: '\u03A7',
+        Psi: '\u03A8',
+        Omega: '\u03A9',
+        alpha: '\u03B1',
+        beta: '\u03B2',
+        gamma: '\u03B3',
+        delta: '\u03B4',
+        epsilon: '\u03B5',
+        zeta: '\u03B6',
+        eta: '\u03B7',
+        theta: '\u03B8',
+        iota: '\u03B9',
+        kappa: '\u03BA',
+        lambda: '\u03BB',
+        mu: '\u03BC',
+        nu: '\u03BD',
+        xi: '\u03BE',
+        omicron: '\u03BF',
+        pi: '\u03C0',
+        rho: '\u03C1',
+        sigmaf: '\u03C2',
+        sigma: '\u03C3',
+        tau: '\u03C4',
+        upsilon: '\u03C5',
+        phi: '\u03C6',
+        chi: '\u03C7',
+        psi: '\u03C8',
+        omega: '\u03C9',
+        thetasym: '\u03D1',
+        upsih: '\u03D2',
+        piv: '\u03D6',
+        ensp: '\u2002',
+        emsp: '\u2003',
+        thinsp: '\u2009',
+        zwnj: '\u200C',
+        zwj: '\u200D',
+        lrm: '\u200E',
+        rlm: '\u200F',
+        ndash: '\u2013',
+        mdash: '\u2014',
+        lsquo: '\u2018',
+        rsquo: '\u2019',
+        sbquo: '\u201A',
+        ldquo: '\u201C',
+        rdquo: '\u201D',
+        bdquo: '\u201E',
+        dagger: '\u2020',
+        Dagger: '\u2021',
+        bull: '\u2022',
+        hellip: '\u2026',
+        permil: '\u2030',
+        prime: '\u2032',
+        Prime: '\u2033',
+        lsaquo: '\u2039',
+        rsaquo: '\u203A',
+        oline: '\u203E',
+        frasl: '\u2044',
+        euro: '\u20AC',
+        image: '\u2111',
+        weierp: '\u2118',
+        real: '\u211C',
+        trade: '\u2122',
+        alefsym: '\u2135',
+        larr: '\u2190',
+        uarr: '\u2191',
+        rarr: '\u2192',
+        darr: '\u2193',
+        harr: '\u2194',
+        crarr: '\u21B5',
+        lArr: '\u21D0',
+        uArr: '\u21D1',
+        rArr: '\u21D2',
+        dArr: '\u21D3',
+        hArr: '\u21D4',
+        forall: '\u2200',
+        part: '\u2202',
+        exist: '\u2203',
+        empty: '\u2205',
+        nabla: '\u2207',
+        isin: '\u2208',
+        notin: '\u2209',
+        ni: '\u220B',
+        prod: '\u220F',
+        sum: '\u2211',
+        minus: '\u2212',
+        lowast: '\u2217',
+        radic: '\u221A',
+        prop: '\u221D',
+        infin: '\u221E',
+        ang: '\u2220',
+        and: '\u2227',
+        or: '\u2228',
+        cap: '\u2229',
+        cup: '\u222A',
+        int: '\u222B',
+        there4: '\u2234',
+        sim: '\u223C',
+        cong: '\u2245',
+        asymp: '\u2248',
+        ne: '\u2260',
+        equiv: '\u2261',
+        le: '\u2264',
+        ge: '\u2265',
+        sub: '\u2282',
+        sup: '\u2283',
+        nsub: '\u2284',
+        sube: '\u2286',
+        supe: '\u2287',
+        oplus: '\u2295',
+        otimes: '\u2297',
+        perp: '\u22A5',
+        sdot: '\u22C5',
+        lceil: '\u2308',
+        rceil: '\u2309',
+        lfloor: '\u230A',
+        rfloor: '\u230B',
+        loz: '\u25CA',
+        spades: '\u2660',
+        clubs: '\u2663',
+        hearts: '\u2665',
+        diams: '\u2666',
+        lang: '\u27E8',
+        rang: '\u27E9'
+    };
</ins><span class="cx"> 
</span><del>-        state.inIteration = oldInIteration;
</del><span class="cx"> 
</span><del>-        return (typeof left === 'undefined') ?
-                node.finishForStatement(init, test, update, body) :
-                forIn ? node.finishForInStatement(left, right, body) :
-                    node.finishForOfStatement(left, right, body);
-    }
</del><ins>+/***/ },
+/* 13 */
+/***/ function(module, exports) {
</ins><span class="cx"> 
</span><del>-    // ECMA-262 13.8 The continue statement
</del><ins>+    &quot;use strict&quot;;
+    exports.JSXSyntax = {
+        JSXAttribute: 'JSXAttribute',
+        JSXClosingElement: 'JSXClosingElement',
+        JSXElement: 'JSXElement',
+        JSXEmptyExpression: 'JSXEmptyExpression',
+        JSXExpressionContainer: 'JSXExpressionContainer',
+        JSXIdentifier: 'JSXIdentifier',
+        JSXMemberExpression: 'JSXMemberExpression',
+        JSXNamespacedName: 'JSXNamespacedName',
+        JSXOpeningElement: 'JSXOpeningElement',
+        JSXSpreadAttribute: 'JSXSpreadAttribute',
+        JSXText: 'JSXText'
+    };
</ins><span class="cx"> 
</span><del>-    function parseContinueStatement(node) {
-        var label = null, key;
</del><span class="cx"> 
</span><del>-        expectKeyword('continue');
</del><ins>+/***/ },
+/* 14 */
+/***/ function(module, exports, __webpack_require__) {
</ins><span class="cx"> 
</span><del>-        // Optimize the most common form: 'continue;'.
-        if (source.charCodeAt(startIndex) === 0x3B) {
-            lex();
-
-            if (!state.inIteration) {
-                throwError(Messages.IllegalContinue);
-            }
-
-            return node.finishContinueStatement(null);
</del><ins>+    &quot;use strict&quot;;
+    var jsx_syntax_1 = __webpack_require__(13);
+    var JSXClosingElement = (function () {
+        function JSXClosingElement(name) {
+            this.type = jsx_syntax_1.JSXSyntax.JSXClosingElement;
+            this.name = name;
</ins><span class="cx">         }
</span><del>-
-        if (hasLineTerminator) {
-            if (!state.inIteration) {
-                throwError(Messages.IllegalContinue);
-            }
-
-            return node.finishContinueStatement(null);
</del><ins>+        return JSXClosingElement;
+    }());
+    exports.JSXClosingElement = JSXClosingElement;
+    var JSXElement = (function () {
+        function JSXElement(openingElement, children, closingElement) {
+            this.type = jsx_syntax_1.JSXSyntax.JSXElement;
+            this.openingElement = openingElement;
+            this.children = children;
+            this.closingElement = closingElement;
</ins><span class="cx">         }
</span><del>-
-        if (lookahead.type === Token.Identifier) {
-            label = parseVariableIdentifier();
-
-            key = '$' + label.name;
-            if (!Object.prototype.hasOwnProperty.call(state.labelSet, key)) {
-                throwError(Messages.UnknownLabel, label.name);
-            }
</del><ins>+        return JSXElement;
+    }());
+    exports.JSXElement = JSXElement;
+    var JSXEmptyExpression = (function () {
+        function JSXEmptyExpression() {
+            this.type = jsx_syntax_1.JSXSyntax.JSXEmptyExpression;
</ins><span class="cx">         }
</span><del>-
-        consumeSemicolon();
-
-        if (label === null &amp;&amp; !state.inIteration) {
-            throwError(Messages.IllegalContinue);
</del><ins>+        return JSXEmptyExpression;
+    }());
+    exports.JSXEmptyExpression = JSXEmptyExpression;
+    var JSXExpressionContainer = (function () {
+        function JSXExpressionContainer(expression) {
+            this.type = jsx_syntax_1.JSXSyntax.JSXExpressionContainer;
+            this.expression = expression;
</ins><span class="cx">         }
</span><del>-
-        return node.finishContinueStatement(label);
-    }
-
-    // ECMA-262 13.9 The break statement
-
-    function parseBreakStatement(node) {
-        var label = null, key;
-
-        expectKeyword('break');
-
-        // Catch the very common case first: immediately a semicolon (U+003B).
-        if (source.charCodeAt(lastIndex) === 0x3B) {
-            lex();
-
-            if (!(state.inIteration || state.inSwitch)) {
-                throwError(Messages.IllegalBreak);
-            }
-
-            return node.finishBreakStatement(null);
</del><ins>+        return JSXExpressionContainer;
+    }());
+    exports.JSXExpressionContainer = JSXExpressionContainer;
+    var JSXIdentifier = (function () {
+        function JSXIdentifier(name) {
+            this.type = jsx_syntax_1.JSXSyntax.JSXIdentifier;
+            this.name = name;
</ins><span class="cx">         }
</span><del>-
-        if (hasLineTerminator) {
-            if (!(state.inIteration || state.inSwitch)) {
-                throwError(Messages.IllegalBreak);
-            }
-
-            return node.finishBreakStatement(null);
</del><ins>+        return JSXIdentifier;
+    }());
+    exports.JSXIdentifier = JSXIdentifier;
+    var JSXMemberExpression = (function () {
+        function JSXMemberExpression(object, property) {
+            this.type = jsx_syntax_1.JSXSyntax.JSXMemberExpression;
+            this.object = object;
+            this.property = property;
</ins><span class="cx">         }
</span><del>-
-        if (lookahead.type === Token.Identifier) {
-            label = parseVariableIdentifier();
-
-            key = '$' + label.name;
-            if (!Object.prototype.hasOwnProperty.call(state.labelSet, key)) {
-                throwError(Messages.UnknownLabel, label.name);
-            }
</del><ins>+        return JSXMemberExpression;
+    }());
+    exports.JSXMemberExpression = JSXMemberExpression;
+    var JSXAttribute = (function () {
+        function JSXAttribute(name, value) {
+            this.type = jsx_syntax_1.JSXSyntax.JSXAttribute;
+            this.name = name;
+            this.value = value;
</ins><span class="cx">         }
</span><del>-
-        consumeSemicolon();
-
-        if (label === null &amp;&amp; !(state.inIteration || state.inSwitch)) {
-            throwError(Messages.IllegalBreak);
</del><ins>+        return JSXAttribute;
+    }());
+    exports.JSXAttribute = JSXAttribute;
+    var JSXNamespacedName = (function () {
+        function JSXNamespacedName(namespace, name) {
+            this.type = jsx_syntax_1.JSXSyntax.JSXNamespacedName;
+            this.namespace = namespace;
+            this.name = name;
</ins><span class="cx">         }
</span><del>-
-        return node.finishBreakStatement(label);
-    }
-
-    // ECMA-262 13.10 The return statement
-
-    function parseReturnStatement(node) {
-        var argument = null;
-
-        expectKeyword('return');
-
-        if (!state.inFunctionBody) {
-            tolerateError(Messages.IllegalReturn);
</del><ins>+        return JSXNamespacedName;
+    }());
+    exports.JSXNamespacedName = JSXNamespacedName;
+    var JSXOpeningElement = (function () {
+        function JSXOpeningElement(name, selfClosing, attributes) {
+            this.type = jsx_syntax_1.JSXSyntax.JSXOpeningElement;
+            this.name = name;
+            this.selfClosing = selfClosing;
+            this.attributes = attributes;
</ins><span class="cx">         }
</span><del>-
-        // 'return' followed by a space and an identifier is very common.
-        if (source.charCodeAt(lastIndex) === 0x20) {
-            if (isIdentifierStart(source.charCodeAt(lastIndex + 1))) {
-                argument = parseExpression();
-                consumeSemicolon();
-                return node.finishReturnStatement(argument);
-            }
</del><ins>+        return JSXOpeningElement;
+    }());
+    exports.JSXOpeningElement = JSXOpeningElement;
+    var JSXSpreadAttribute = (function () {
+        function JSXSpreadAttribute(argument) {
+            this.type = jsx_syntax_1.JSXSyntax.JSXSpreadAttribute;
+            this.argument = argument;
</ins><span class="cx">         }
</span><del>-
-        if (hasLineTerminator) {
-            // HACK
-            return node.finishReturnStatement(null);
</del><ins>+        return JSXSpreadAttribute;
+    }());
+    exports.JSXSpreadAttribute = JSXSpreadAttribute;
+    var JSXText = (function () {
+        function JSXText(value, raw) {
+            this.type = jsx_syntax_1.JSXSyntax.JSXText;
+            this.value = value;
+            this.raw = raw;
</ins><span class="cx">         }
</span><ins>+        return JSXText;
+    }());
+    exports.JSXText = JSXText;
</ins><span class="cx"> 
</span><del>-        if (!match(';')) {
-            if (!match('}') &amp;&amp; lookahead.type !== Token.EOF) {
-                argument = parseExpression();
-            }
-        }
</del><span class="cx"> 
</span><del>-        consumeSemicolon();
</del><ins>+/***/ },
+/* 15 */
+/***/ function(module, exports, __webpack_require__) {
</ins><span class="cx"> 
</span><del>-        return node.finishReturnStatement(argument);
-    }
-
-    // ECMA-262 13.11 The with statement
-
-    function parseWithStatement(node) {
-        var object, body;
-
-        if (strict) {
-            tolerateError(Messages.StrictModeWith);
</del><ins>+    &quot;use strict&quot;;
+    var scanner_1 = __webpack_require__(8);
+    var error_handler_1 = __webpack_require__(6);
+    var token_1 = __webpack_require__(7);
+    var Reader = (function () {
+        function Reader() {
+            this.values = [];
+            this.curly = this.paren = -1;
</ins><span class="cx">         }
</span><del>-
-        expectKeyword('with');
-
-        expect('(');
-
-        object = parseExpression();
-
-        expect(')');
-
-        body = parseStatement();
-
-        return node.finishWithStatement(object, body);
-    }
-
-    // ECMA-262 13.12 The switch statement
-
-    function parseSwitchCase() {
-        var test, consequent = [], statement, node = new Node();
-
-        if (matchKeyword('default')) {
-            lex();
-            test = null;
-        } else {
-            expectKeyword('case');
-            test = parseExpression();
-        }
-        expect(':');
-
-        while (startIndex &lt; length) {
-            if (match('}') || matchKeyword('default') || matchKeyword('case')) {
-                break;
-            }
-            statement = parseStatementListItem();
-            consequent.push(statement);
-        }
-
-        return node.finishSwitchCase(test, consequent);
-    }
-
-    function parseSwitchStatement(node) {
-        var discriminant, cases, clause, oldInSwitch, defaultFound;
-
-        expectKeyword('switch');
-
-        expect('(');
-
-        discriminant = parseExpression();
-
-        expect(')');
-
-        expect('{');
-
-        cases = [];
-
-        if (match('}')) {
-            lex();
-            return node.finishSwitchStatement(discriminant, cases);
-        }
-
-        oldInSwitch = state.inSwitch;
-        state.inSwitch = true;
-        defaultFound = false;
-
-        while (startIndex &lt; length) {
-            if (match('}')) {
-                break;
-            }
-            clause = parseSwitchCase();
-            if (clause.test === null) {
-                if (defaultFound) {
-                    throwError(Messages.MultipleDefaultsInSwitch);
-                }
-                defaultFound = true;
-            }
-            cases.push(clause);
-        }
-
-        state.inSwitch = oldInSwitch;
-
-        expect('}');
-
-        return node.finishSwitchStatement(discriminant, cases);
-    }
-
-    // ECMA-262 13.14 The throw statement
-
-    function parseThrowStatement(node) {
-        var argument;
-
-        expectKeyword('throw');
-
-        if (hasLineTerminator) {
-            throwError(Messages.NewlineAfterThrow);
-        }
-
-        argument = parseExpression();
-
-        consumeSemicolon();
-
-        return node.finishThrowStatement(argument);
-    }
-
-    // ECMA-262 13.15 The try statement
-
-    function parseCatchClause() {
-        var param, params = [], paramMap = {}, key, i, body, node = new Node();
-
-        expectKeyword('catch');
-
-        expect('(');
-        if (match(')')) {
-            throwUnexpectedToken(lookahead);
-        }
-
-        param = parsePattern(params);
-        for (i = 0; i &lt; params.length; i++) {
-            key = '$' + params[i].value;
-            if (Object.prototype.hasOwnProperty.call(paramMap, key)) {
-                tolerateError(Messages.DuplicateBinding, params[i].value);
-            }
-            paramMap[key] = true;
-        }
-
-        // ECMA-262 12.14.1
-        if (strict &amp;&amp; isRestrictedWord(param.name)) {
-            tolerateError(Messages.StrictCatchVariable);
-        }
-
-        expect(')');
-        body = parseBlock();
-        return node.finishCatchClause(param, body);
-    }
-
-    function parseTryStatement(node) {
-        var block, handler = null, finalizer = null;
-
-        expectKeyword('try');
-
-        block = parseBlock();
-
-        if (matchKeyword('catch')) {
-            handler = parseCatchClause();
-        }
-
-        if (matchKeyword('finally')) {
-            lex();
-            finalizer = parseBlock();
-        }
-
-        if (!handler &amp;&amp; !finalizer) {
-            throwError(Messages.NoCatchOrFinally);
-        }
-
-        return node.finishTryStatement(block, handler, finalizer);
-    }
-
-    // ECMA-262 13.16 The debugger statement
-
-    function parseDebuggerStatement(node) {
-        expectKeyword('debugger');
-
-        consumeSemicolon();
-
-        return node.finishDebuggerStatement();
-    }
-
-    // 13 Statements
-
-    function parseStatement() {
-        var type = lookahead.type,
-            expr,
-            labeledBody,
-            key,
-            node;
-
-        if (type === Token.EOF) {
-            throwUnexpectedToken(lookahead);
-        }
-
-        if (type === Token.Punctuator &amp;&amp; lookahead.value === '{') {
-            return parseBlock();
-        }
-        isAssignmentTarget = isBindingElement = true;
-        node = new Node();
-
-        if (type === Token.Punctuator) {
-            switch (lookahead.value) {
-            case ';':
-                return parseEmptyStatement(node);
-            case '(':
-                return parseExpressionStatement(node);
-            default:
-                break;
-            }
-        } else if (type === Token.Keyword) {
-            switch (lookahead.value) {
-            case 'break':
-                return parseBreakStatement(node);
-            case 'continue':
-                return parseContinueStatement(node);
-            case 'debugger':
-                return parseDebuggerStatement(node);
-            case 'do':
-                return parseDoWhileStatement(node);
-            case 'for':
-                return parseForStatement(node);
-            case 'function':
-                return parseFunctionDeclaration(node);
-            case 'if':
-                return parseIfStatement(node);
-            case 'return':
-                return parseReturnStatement(node);
-            case 'switch':
-                return parseSwitchStatement(node);
-            case 'throw':
-                return parseThrowStatement(node);
-            case 'try':
-                return parseTryStatement(node);
-            case 'var':
-                return parseVariableStatement(node);
-            case 'while':
-                return parseWhileStatement(node);
-            case 'with':
-                return parseWithStatement(node);
-            default:
-                break;
-            }
-        }
-
-        expr = parseExpression();
-
-        // ECMA-262 12.12 Labelled Statements
-        if ((expr.type === Syntax.Identifier) &amp;&amp; match(':')) {
-            lex();
-
-            key = '$' + expr.name;
-            if (Object.prototype.hasOwnProperty.call(state.labelSet, key)) {
-                throwError(Messages.Redeclaration, 'Label', expr.name);
-            }
-
-            state.labelSet[key] = true;
-            labeledBody = parseStatement();
-            delete state.labelSet[key];
-            return node.finishLabeledStatement(expr, labeledBody);
-        }
-
-        consumeSemicolon();
-
-        return node.finishExpressionStatement(expr);
-    }
-
-    // ECMA-262 14.1 Function Definition
-
-    function parseFunctionSourceElements() {
-        var statement, body = [], token, directive, firstRestricted,
-            oldLabelSet, oldInIteration, oldInSwitch, oldInFunctionBody, oldParenthesisCount,
-            node = new Node();
-
-        expect('{');
-
-        while (startIndex &lt; length) {
-            if (lookahead.type !== Token.StringLiteral) {
-                break;
-            }
-            token = lookahead;
-
-            statement = parseStatementListItem();
-            body.push(statement);
-            if (statement.expression.type !== Syntax.Literal) {
-                // this is not directive
-                break;
-            }
-            directive = source.slice(token.start + 1, token.end - 1);
-            if (directive === 'use strict') {
-                strict = true;
-                if (firstRestricted) {
-                    tolerateUnexpectedToken(firstRestricted, Messages.StrictOctalLiteral);
-                }
-            } else {
-                if (!firstRestricted &amp;&amp; token.octal) {
-                    firstRestricted = token;
-                }
-            }
-        }
-
-        oldLabelSet = state.labelSet;
-        oldInIteration = state.inIteration;
-        oldInSwitch = state.inSwitch;
-        oldInFunctionBody = state.inFunctionBody;
-        oldParenthesisCount = state.parenthesizedCount;
-
-        state.labelSet = {};
-        state.inIteration = false;
-        state.inSwitch = false;
-        state.inFunctionBody = true;
-        state.parenthesizedCount = 0;
-
-        while (startIndex &lt; length) {
-            if (match('}')) {
-                break;
-            }
-            body.push(parseStatementListItem());
-        }
-
-        expect('}');
-
-        state.labelSet = oldLabelSet;
-        state.inIteration = oldInIteration;
-        state.inSwitch = oldInSwitch;
-        state.inFunctionBody = oldInFunctionBody;
-        state.parenthesizedCount = oldParenthesisCount;
-
-        return node.finishBlockStatement(body);
-    }
-
-    function validateParam(options, param, name) {
-        var key = '$' + name;
-        if (strict) {
-            if (isRestrictedWord(name)) {
-                options.stricted = param;
-                options.message = Messages.StrictParamName;
-            }
-            if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) {
-                options.stricted = param;
-                options.message = Messages.StrictParamDupe;
-            }
-        } else if (!options.firstRestricted) {
-            if (isRestrictedWord(name)) {
-                options.firstRestricted = param;
-                options.message = Messages.StrictParamName;
-            } else if (isStrictModeReservedWord(name)) {
-                options.firstRestricted = param;
-                options.message = Messages.StrictReservedWord;
-            } else if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) {
-                options.stricted = param;
-                options.message = Messages.StrictParamDupe;
-            }
-        }
-        options.paramSet[key] = true;
-    }
-
-    function parseParam(options) {
-        var token, param, params = [], i, def;
-
-        token = lookahead;
-        if (token.value === '...') {
-            param = parseRestElement(params);
-            validateParam(options, param.argument, param.argument.name);
-            options.params.push(param);
-            options.defaults.push(null);
-            return false;
-        }
-
-        param = parsePatternWithDefault(params);
-        for (i = 0; i &lt; params.length; i++) {
-            validateParam(options, params[i], params[i].value);
-        }
-
-        if (param.type === Syntax.AssignmentPattern) {
-            def = param.right;
-            param = param.left;
-            ++options.defaultCount;
-        }
-
-        options.params.push(param);
-        options.defaults.push(def);
-
-        return !match(')');
-    }
-
-    function parseParams(firstRestricted) {
-        var options;
-
-        options = {
-            params: [],
-            defaultCount: 0,
-            defaults: [],
-            firstRestricted: firstRestricted
</del><ins>+        ;
+        // A function following one of those tokens is an expression.
+        Reader.prototype.beforeFunctionExpression = function (t) {
+            return ['(', '{', '[', 'in', 'typeof', 'instanceof', 'new',
+                'return', 'case', 'delete', 'throw', 'void',
+                // assignment operators
+                '=', '+=', '-=', '*=', '**=', '/=', '%=', '&lt;&lt;=', '&gt;&gt;=', '&gt;&gt;&gt;=',
+                '&amp;=', '|=', '^=', ',',
+                // binary/unary operators
+                '+', '-', '*', '**', '/', '%', '++', '--', '&lt;&lt;', '&gt;&gt;', '&gt;&gt;&gt;', '&amp;',
+                '|', '^', '!', '~', '&amp;&amp;', '||', '?', ':', '===', '==', '&gt;=',
+                '&lt;=', '&lt;', '&gt;', '!=', '!=='].indexOf(t) &gt;= 0;
</ins><span class="cx">         };
</span><del>-
-        expect('(');
-
-        if (!match(')')) {
-            options.paramSet = {};
-            while (startIndex &lt; length) {
-                if (!parseParam(options)) {
</del><ins>+        ;
+        // Determine if forward slash (/) is an operator or part of a regular expression
+        // https://github.com/mozilla/sweet.js/wiki/design
+        Reader.prototype.isRegexStart = function () {
+            var previous = this.values[this.values.length - 1];
+            var regex = (previous !== null);
+            switch (previous) {
+                case 'this':
+                case ']':
+                    regex = false;
</ins><span class="cx">                     break;
</span><del>-                }
-                expect(',');
</del><ins>+                case ')':
+                    var check = this.values[this.paren - 1];
+                    regex = (check === 'if' || check === 'while' || check === 'for' || check === 'with');
+                    break;
+                case '}':
+                    // Dividing a function by anything makes little sense,
+                    // but we have to check for that.
+                    regex = false;
+                    if (this.values[this.curly - 3] === 'function') {
+                        // Anonymous function, e.g. function(){} /42
+                        var check_1 = this.values[this.curly - 4];
+                        regex = check_1 ? !this.beforeFunctionExpression(check_1) : false;
+                    }
+                    else if (this.values[this.curly - 4] === 'function') {
+                        // Named function, e.g. function f(){} /42/
+                        var check_2 = this.values[this.curly - 5];
+                        regex = check_2 ? !this.beforeFunctionExpression(check_2) : true;
+                    }
</ins><span class="cx">             }
</span><del>-        }
-
-        expect(')');
-
-        if (options.defaultCount === 0) {
-            options.defaults = [];
-        }
-
-        return {
-            params: options.params,
-            defaults: options.defaults,
-            stricted: options.stricted,
-            firstRestricted: options.firstRestricted,
-            message: options.message
</del><ins>+            return regex;
</ins><span class="cx">         };
</span><del>-    }
-
-    function parseFunctionDeclaration(node, identifierIsOptional) {
-        var id = null, params = [], defaults = [], body, token, stricted, tmp, firstRestricted, message, previousStrict,
-            isGenerator, previousAllowYield;
-
-        previousAllowYield = state.allowYield;
-
-        expectKeyword('function');
-
-        isGenerator = match('*');
-        if (isGenerator) {
-            lex();
-        }
-
-        if (!identifierIsOptional || !match('(')) {
-            token = lookahead;
-            id = parseVariableIdentifier();
-            if (strict) {
-                if (isRestrictedWord(token.value)) {
-                    tolerateUnexpectedToken(token, Messages.StrictFunctionName);
</del><ins>+        ;
+        Reader.prototype.push = function (token) {
+            if (token.type === token_1.Token.Punctuator || token.type === token_1.Token.Keyword) {
+                if (token.value === '{') {
+                    this.curly = this.values.length;
</ins><span class="cx">                 }
</span><del>-            } else {
-                if (isRestrictedWord(token.value)) {
-                    firstRestricted = token;
-                    message = Messages.StrictFunctionName;
-                } else if (isStrictModeReservedWord(token.value)) {
-                    firstRestricted = token;
-                    message = Messages.StrictReservedWord;
</del><ins>+                else if (token.value === '(') {
+                    this.paren = this.values.length;
</ins><span class="cx">                 }
</span><ins>+                this.values.push(token.value);
</ins><span class="cx">             }
</span><del>-        }
-
-        state.allowYield = !isGenerator;
-        tmp = parseParams(firstRestricted);
-        params = tmp.params;
-        defaults = tmp.defaults;
-        stricted = tmp.stricted;
-        firstRestricted = tmp.firstRestricted;
-        if (tmp.message) {
-            message = tmp.message;
-        }
-
-
-        previousStrict = strict;
-        body = parseFunctionSourceElements();
-        if (strict &amp;&amp; firstRestricted) {
-            throwUnexpectedToken(firstRestricted, message);
-        }
-        if (strict &amp;&amp; stricted) {
-            tolerateUnexpectedToken(stricted, message);
-        }
-
-        strict = previousStrict;
-        state.allowYield = previousAllowYield;
-
-        return node.finishFunctionDeclaration(id, params, defaults, body, isGenerator);
-    }
-
-    function parseFunctionExpression() {
-        var token, id = null, stricted, firstRestricted, message, tmp,
-            params = [], defaults = [], body, previousStrict, node = new Node(),
-            isGenerator, previousAllowYield;
-
-        previousAllowYield = state.allowYield;
-
-        expectKeyword('function');
-
-        isGenerator = match('*');
-        if (isGenerator) {
-            lex();
-        }
-
-        state.allowYield = !isGenerator;
-        if (!match('(')) {
-            token = lookahead;
-            id = (!strict &amp;&amp; !isGenerator &amp;&amp; matchKeyword('yield')) ? parseNonComputedProperty() : parseVariableIdentifier();
-            if (strict) {
-                if (isRestrictedWord(token.value)) {
-                    tolerateUnexpectedToken(token, Messages.StrictFunctionName);
-                }
-            } else {
-                if (isRestrictedWord(token.value)) {
-                    firstRestricted = token;
-                    message = Messages.StrictFunctionName;
-                } else if (isStrictModeReservedWord(token.value)) {
-                    firstRestricted = token;
-                    message = Messages.StrictReservedWord;
-                }
</del><ins>+            else {
+                this.values.push(null);
</ins><span class="cx">             }
</span><ins>+        };
+        ;
+        return Reader;
+    }());
+    var Tokenizer = (function () {
+        function Tokenizer(code, config) {
+            this.errorHandler = new error_handler_1.ErrorHandler();
+            this.errorHandler.tolerant = config ? (typeof config.tolerant === 'boolean' &amp;&amp; config.tolerant) : false;
+            this.scanner = new scanner_1.Scanner(code, this.errorHandler);
+            this.scanner.trackComment = config ? (typeof config.comment === 'boolean' &amp;&amp; config.comment) : false;
+            this.trackRange = config ? (typeof config.range === 'boolean' &amp;&amp; config.range) : false;
+            this.trackLoc = config ? (typeof config.loc === 'boolean' &amp;&amp; config.loc) : false;
+            this.buffer = [];
+            this.reader = new Reader();
</ins><span class="cx">         }
</span><del>-
-        tmp = parseParams(firstRestricted);
-        params = tmp.params;
-        defaults = tmp.defaults;
-        stricted = tmp.stricted;
-        firstRestricted = tmp.firstRestricted;
-        if (tmp.message) {
-            message = tmp.message;
-        }
-
-        previousStrict = strict;
-        body = parseFunctionSourceElements();
-        if (strict &amp;&amp; firstRestricted) {
-            throwUnexpectedToken(firstRestricted, message);
-        }
-        if (strict &amp;&amp; stricted) {
-            tolerateUnexpectedToken(stricted, message);
-        }
-        strict = previousStrict;
-        state.allowYield = previousAllowYield;
-
-        return node.finishFunctionExpression(id, params, defaults, body, isGenerator);
-    }
-
-    // ECMA-262 14.5 Class Definitions
-
-    function parseClassBody() {
-        var classBody, token, isStatic, hasConstructor = false, body, method, computed, key;
-
-        classBody = new Node();
-
-        expect('{');
-        body = [];
-        while (!match('}')) {
-            if (match(';')) {
-                lex();
-            } else {
-                method = new Node();
-                token = lookahead;
-                isStatic = false;
-                computed = match('[');
-                if (match('*')) {
-                    lex();
-                } else {
-                    key = parseObjectPropertyKey();
-                    if (key.name === 'static' &amp;&amp; (lookaheadPropertyName() || match('*'))) {
-                        token = lookahead;
-                        isStatic = true;
-                        computed = match('[');
-                        if (match('*')) {
-                            lex();
-                        } else {
-                            key = parseObjectPropertyKey();
</del><ins>+        ;
+        Tokenizer.prototype.errors = function () {
+            return this.errorHandler.errors;
+        };
+        ;
+        Tokenizer.prototype.getNextToken = function () {
+            if (this.buffer.length === 0) {
+                var comments = this.scanner.scanComments();
+                if (this.scanner.trackComment) {
+                    for (var i = 0; i &lt; comments.length; ++i) {
+                        var e = comments[i];
+                        var comment = void 0;
+                        var value = this.scanner.source.slice(e.slice[0], e.slice[1]);
+                        comment = {
+                            type: e.multiLine ? 'BlockComment' : 'LineComment',
+                            value: value
+                        };
+                        if (this.trackRange) {
+                            comment.range = e.range;
</ins><span class="cx">                         }
</span><ins>+                        if (this.trackLoc) {
+                            comment.loc = e.loc;
+                        }
+                        this.buffer.push(comment);
</ins><span class="cx">                     }
</span><span class="cx">                 }
</span><del>-                method = tryParseMethodDefinition(token, key, computed, method);
-                if (method) {
-                    method['static'] = isStatic; // jscs:ignore requireDotNotation
-                    if (method.kind === 'init') {
-                        method.kind = 'method';
</del><ins>+                if (!this.scanner.eof()) {
+                    var loc = void 0;
+                    if (this.trackLoc) {
+                        loc = {
+                            start: {
+                                line: this.scanner.lineNumber,
+                                column: this.scanner.index - this.scanner.lineStart
+                            },
+                            end: {}
+                        };
</ins><span class="cx">                     }
</span><del>-                    if (!isStatic) {
-                        if (!method.computed &amp;&amp; (method.key.name || method.key.value.toString()) === 'constructor') {
-                            if (method.kind !== 'method' || !method.method || method.value.generator) {
-                                throwUnexpectedToken(token, Messages.ConstructorSpecialMethod);
-                            }
-                            if (hasConstructor) {
-                                throwUnexpectedToken(token, Messages.DuplicateConstructor);
-                            } else {
-                                hasConstructor = true;
-                            }
-                            method.kind = 'constructor';
-                        }
-                    } else {
-                        if (!method.computed &amp;&amp; (method.key.name || method.key.value.toString()) === 'prototype') {
-                            throwUnexpectedToken(token, Messages.StaticPrototype);
-                        }
</del><ins>+                    var token = void 0;
+                    if (this.scanner.source[this.scanner.index] === '/') {
+                        token = this.reader.isRegexStart() ? this.scanner.scanRegExp() : this.scanner.scanPunctuator();
</ins><span class="cx">                     }
</span><del>-                    method.type = Syntax.MethodDefinition;
-                    delete method.method;
-                    delete method.shorthand;
-                    body.push(method);
-                } else {
-                    throwUnexpectedToken(lookahead);
-                }
-            }
-        }
-        lex();
-        return classBody.finishClassBody(body);
-    }
-
-    function parseClassDeclaration(identifierIsOptional) {
-        var id = null, superClass = null, classNode = new Node(), classBody, previousStrict = strict;
-        strict = true;
-
-        expectKeyword('class');
-
-        if (!identifierIsOptional || lookahead.type === Token.Identifier) {
-            id = parseVariableIdentifier();
-        }
-
-        if (matchKeyword('extends')) {
-            lex();
-            superClass = isolateCoverGrammar(parseLeftHandSideExpressionAllowCall);
-        }
-        classBody = parseClassBody();
-        strict = previousStrict;
-
-        return classNode.finishClassDeclaration(id, superClass, classBody);
-    }
-
-    function parseClassExpression() {
-        var id = null, superClass = null, classNode = new Node(), classBody, previousStrict = strict;
-        strict = true;
-
-        expectKeyword('class');
-
-        if (lookahead.type === Token.Identifier) {
-            id = parseVariableIdentifier();
-        }
-
-        if (matchKeyword('extends')) {
-            lex();
-            superClass = isolateCoverGrammar(parseLeftHandSideExpressionAllowCall);
-        }
-        classBody = parseClassBody();
-        strict = previousStrict;
-
-        return classNode.finishClassExpression(id, superClass, classBody);
-    }
-
-    // ECMA-262 15.2 Modules
-
-    function parseModuleSpecifier() {
-        var node = new Node();
-
-        if (lookahead.type !== Token.StringLiteral) {
-            throwError(Messages.InvalidModuleSpecifier);
-        }
-        return node.finishLiteral(lex());
-    }
-
-    // ECMA-262 15.2.3 Exports
-
-    function parseExportSpecifier() {
-        var exported, local, node = new Node(), def;
-        if (matchKeyword('default')) {
-            // export {default} from 'something';
-            def = new Node();
-            lex();
-            local = def.finishIdentifier('default');
-        } else {
-            local = parseVariableIdentifier();
-        }
-        if (matchContextualKeyword('as')) {
-            lex();
-            exported = parseNonComputedProperty();
-        }
-        return node.finishExportSpecifier(local, exported);
-    }
-
-    function parseExportNamedDeclaration(node) {
-        var declaration = null,
-            isExportFromIdentifier,
-            src = null, specifiers = [];
-
-        // non-default export
-        if (lookahead.type === Token.Keyword) {
-            // covers:
-            // export var f = 1;
-            switch (lookahead.value) {
-                case 'let':
-                case 'const':
-                case 'var':
-                case 'class':
-                case 'function':
-                    declaration = parseStatementListItem();
-                    return node.finishExportNamedDeclaration(declaration, specifiers, null);
-            }
-        }
-
-        expect('{');
-        while (!match('}')) {
-            isExportFromIdentifier = isExportFromIdentifier || matchKeyword('default');
-            specifiers.push(parseExportSpecifier());
-            if (!match('}')) {
-                expect(',');
-                if (match('}')) {
-                    break;
-                }
-            }
-        }
-        expect('}');
-
-        if (matchContextualKeyword('from')) {
-            // covering:
-            // export {default} from 'foo';
-            // export {foo} from 'foo';
-            lex();
-            src = parseModuleSpecifier();
-            consumeSemicolon();
-        } else if (isExportFromIdentifier) {
-            // covering:
-            // export {default}; // missing fromClause
-            throwError(lookahead.value ?
-                    Messages.UnexpectedToken : Messages.MissingFromClause, lookahead.value);
-        } else {
-            // cover
-            // export {foo};
-            consumeSemicolon();
-        }
-        return node.finishExportNamedDeclaration(declaration, specifiers, src);
-    }
-
-    function parseExportDefaultDeclaration(node) {
-        var declaration = null,
-            expression = null;
-
-        // covers:
-        // export default ...
-        expectKeyword('default');
-
-        if (matchKeyword('function')) {
-            // covers:
-            // export default function foo () {}
-            // export default function () {}
-            declaration = parseFunctionDeclaration(new Node(), true);
-            return node.finishExportDefaultDeclaration(declaration);
-        }
-        if (matchKeyword('class')) {
-            declaration = parseClassDeclaration(true);
-            return node.finishExportDefaultDeclaration(declaration);
-        }
-
-        if (matchContextualKeyword('from')) {
-            throwError(Messages.UnexpectedToken, lookahead.value);
-        }
-
-        // covers:
-        // export default {};
-        // export default [];
-        // export default (1 + 2);
-        if (match('{')) {
-            expression = parseObjectInitializer();
-        } else if (match('[')) {
-            expression = parseArrayInitializer();
-        } else {
-            expression = parseAssignmentExpression();
-        }
-        consumeSemicolon();
-        return node.finishExportDefaultDeclaration(expression);
-    }
-
-    function parseExportAllDeclaration(node) {
-        var src;
-
-        // covers:
-        // export * from 'foo';
-        expect('*');
-        if (!matchContextualKeyword('from')) {
-            throwError(lookahead.value ?
-                    Messages.UnexpectedToken : Messages.MissingFromClause, lookahead.value);
-        }
-        lex();
-        src = parseModuleSpecifier();
-        consumeSemicolon();
-
-        return node.finishExportAllDeclaration(src);
-    }
-
-    function parseExportDeclaration() {
-        var node = new Node();
-        if (state.inFunctionBody) {
-            throwError(Messages.IllegalExportDeclaration);
-        }
-
-        expectKeyword('export');
-
-        if (matchKeyword('default')) {
-            return parseExportDefaultDeclaration(node);
-        }
-        if (match('*')) {
-            return parseExportAllDeclaration(node);
-        }
-        return parseExportNamedDeclaration(node);
-    }
-
-    // ECMA-262 15.2.2 Imports
-
-    function parseImportSpecifier() {
-        // import {&lt;foo as bar&gt;} ...;
-        var local, imported, node = new Node();
-
-        imported = parseNonComputedProperty();
-        if (matchContextualKeyword('as')) {
-            lex();
-            local = parseVariableIdentifier();
-        }
-
-        return node.finishImportSpecifier(local, imported);
-    }
-
-    function parseNamedImports() {
-        var specifiers = [];
-        // {foo, bar as bas}
-        expect('{');
-        while (!match('}')) {
-            specifiers.push(parseImportSpecifier());
-            if (!match('}')) {
-                expect(',');
-                if (match('}')) {
-                    break;
-                }
-            }
-        }
-        expect('}');
-        return specifiers;
-    }
-
-    function parseImportDefaultSpecifier() {
-        // import &lt;foo&gt; ...;
-        var local, node = new Node();
-
-        local = parseNonComputedProperty();
-
-        return node.finishImportDefaultSpecifier(local);
-    }
-
-    function parseImportNamespaceSpecifier() {
-        // import &lt;* as foo&gt; ...;
-        var local, node = new Node();
-
-        expect('*');
-        if (!matchContextualKeyword('as')) {
-            throwError(Messages.NoAsAfterImportNamespace);
-        }
-        lex();
-        local = parseNonComputedProperty();
-
-        return node.finishImportNamespaceSpecifier(local);
-    }
-
-    function parseImportDeclaration() {
-        var specifiers = [], src, node = new Node();
-
-        if (state.inFunctionBody) {
-            throwError(Messages.IllegalImportDeclaration);
-        }
-
-        expectKeyword('import');
-
-        if (lookahead.type === Token.StringLiteral) {
-            // import 'foo';
-            src = parseModuleSpecifier();
-        } else {
-
-            if (match('{')) {
-                // import {bar}
-                specifiers = specifiers.concat(parseNamedImports());
-            } else if (match('*')) {
-                // import * as foo
-                specifiers.push(parseImportNamespaceSpecifier());
-            } else if (isIdentifierName(lookahead) &amp;&amp; !matchKeyword('default')) {
-                // import foo
-                specifiers.push(parseImportDefaultSpecifier());
-                if (match(',')) {
-                    lex();
-                    if (match('*')) {
-                        // import foo, * as foo
-                        specifiers.push(parseImportNamespaceSpecifier());
-                    } else if (match('{')) {
-                        // import foo, {bar}
-                        specifiers = specifiers.concat(parseNamedImports());
-                    } else {
-                        throwUnexpectedToken(lookahead);
</del><ins>+                    else {
+                        token = this.scanner.lex();
</ins><span class="cx">                     }
</span><del>-                }
-            } else {
-                throwUnexpectedToken(lex());
-            }
-
-            if (!matchContextualKeyword('from')) {
-                throwError(lookahead.value ?
-                        Messages.UnexpectedToken : Messages.MissingFromClause, lookahead.value);
-            }
-            lex();
-            src = parseModuleSpecifier();
-        }
-
-        consumeSemicolon();
-        return node.finishImportDeclaration(specifiers, src);
-    }
-
-    // ECMA-262 15.1 Scripts
-
-    function parseScriptBody() {
-        var statement, body = [], token, directive, firstRestricted;
-
-        while (startIndex &lt; length) {
-            token = lookahead;
-            if (token.type !== Token.StringLiteral) {
-                break;
-            }
-
-            statement = parseStatementListItem();
-            body.push(statement);
-            if (statement.expression.type !== Syntax.Literal) {
-                // this is not directive
-                break;
-            }
-            directive = source.slice(token.start + 1, token.end - 1);
-            if (directive === 'use strict') {
-                strict = true;
-                if (firstRestricted) {
-                    tolerateUnexpectedToken(firstRestricted, Messages.StrictOctalLiteral);
-                }
-            } else {
-                if (!firstRestricted &amp;&amp; token.octal) {
-                    firstRestricted = token;
-                }
-            }
-        }
-
-        while (startIndex &lt; length) {
-            statement = parseStatementListItem();
-            /* istanbul ignore if */
-            if (typeof statement === 'undefined') {
-                break;
-            }
-            body.push(statement);
-        }
-        return body;
-    }
-
-    function parseProgram() {
-        var body, node;
-
-        peek();
-        node = new Node();
-
-        body = parseScriptBody();
-        return node.finishProgram(body, state.sourceType);
-    }
-
-    function filterTokenLocation() {
-        var i, entry, token, tokens = [];
-
-        for (i = 0; i &lt; extra.tokens.length; ++i) {
-            entry = extra.tokens[i];
-            token = {
-                type: entry.type,
-                value: entry.value
-            };
-            if (entry.regex) {
-                token.regex = {
-                    pattern: entry.regex.pattern,
-                    flags: entry.regex.flags
-                };
-            }
-            if (extra.range) {
-                token.range = entry.range;
-            }
-            if (extra.loc) {
-                token.loc = entry.loc;
-            }
-            tokens.push(token);
-        }
-
-        extra.tokens = tokens;
-    }
-
-    function tokenize(code, options) {
-        var toString,
-            tokens;
-
-        toString = String;
-        if (typeof code !== 'string' &amp;&amp; !(code instanceof String)) {
-            code = toString(code);
-        }
-
-        source = code;
-        index = 0;
-        lineNumber = (source.length &gt; 0) ? 1 : 0;
-        lineStart = 0;
-        startIndex = index;
-        startLineNumber = lineNumber;
-        startLineStart = lineStart;
-        length = source.length;
-        lookahead = null;
-        state = {
-            allowIn: true,
-            allowYield: true,
-            labelSet: {},
-            inFunctionBody: false,
-            inIteration: false,
-            inSwitch: false,
-            lastCommentStart: -1,
-            curlyStack: []
-        };
-
-        extra = {};
-
-        // Options matching.
-        options = options || {};
-
-        // Of course we collect tokens here.
-        options.tokens = true;
-        extra.tokens = [];
-        extra.tokenize = true;
-        // The following two fields are necessary to compute the Regex tokens.
-        extra.openParenToken = -1;
-        extra.openCurlyToken = -1;
-
-        extra.range = (typeof options.range === 'boolean') &amp;&amp; options.range;
-        extra.loc = (typeof options.loc === 'boolean') &amp;&amp; options.loc;
-
-        if (typeof options.comment === 'boolean' &amp;&amp; options.comment) {
-            extra.comments = [];
-        }
-        if (typeof options.tolerant === 'boolean' &amp;&amp; options.tolerant) {
-            extra.errors = [];
-        }
-
-        try {
-            peek();
-            if (lookahead.type === Token.EOF) {
-                return extra.tokens;
-            }
-
-            lex();
-            while (lookahead.type !== Token.EOF) {
-                try {
-                    lex();
-                } catch (lexError) {
-                    if (extra.errors) {
-                        recordError(lexError);
-                        // We have to break on the first error
-                        // to avoid infinite loops.
-                        break;
-                    } else {
-                        throw lexError;
</del><ins>+                    this.reader.push(token);
+                    var entry = void 0;
+                    entry = {
+                        type: token_1.TokenName[token.type],
+                        value: this.scanner.source.slice(token.start, token.end)
+                    };
+                    if (this.trackRange) {
+                        entry.range = [token.start, token.end];
</ins><span class="cx">                     }
</span><ins>+                    if (this.trackLoc) {
+                        loc.end = {
+                            line: this.scanner.lineNumber,
+                            column: this.scanner.index - this.scanner.lineStart
+                        };
+                        entry.loc = loc;
+                    }
+                    if (token.regex) {
+                        entry.regex = token.regex;
+                    }
+                    this.buffer.push(entry);
</ins><span class="cx">                 }
</span><span class="cx">             }
</span><del>-
-            filterTokenLocation();
-            tokens = extra.tokens;
-            if (typeof extra.comments !== 'undefined') {
-                tokens.comments = extra.comments;
-            }
-            if (typeof extra.errors !== 'undefined') {
-                tokens.errors = extra.errors;
-            }
-        } catch (e) {
-            throw e;
-        } finally {
-            extra = {};
-        }
-        return tokens;
-    }
-
-    function parse(code, options) {
-        var program, toString;
-
-        toString = String;
-        if (typeof code !== 'string' &amp;&amp; !(code instanceof String)) {
-            code = toString(code);
-        }
-
-        source = code;
-        index = 0;
-        lineNumber = (source.length &gt; 0) ? 1 : 0;
-        lineStart = 0;
-        startIndex = index;
-        startLineNumber = lineNumber;
-        startLineStart = lineStart;
-        length = source.length;
-        lookahead = null;
-        state = {
-            allowIn: true,
-            allowYield: true,
-            labelSet: {},
-            inFunctionBody: false,
-            inIteration: false,
-            inSwitch: false,
-            lastCommentStart: -1,
-            curlyStack: [],
-            sourceType: 'script'
</del><ins>+            return this.buffer.shift();
</ins><span class="cx">         };
</span><del>-        strict = false;
</del><ins>+        ;
+        return Tokenizer;
+    }());
+    exports.Tokenizer = Tokenizer;
</ins><span class="cx"> 
</span><del>-        extra = {};
-        if (typeof options !== 'undefined') {
-            extra.range = (typeof options.range === 'boolean') &amp;&amp; options.range;
-            extra.loc = (typeof options.loc === 'boolean') &amp;&amp; options.loc;
-            extra.attachComment = (typeof options.attachComment === 'boolean') &amp;&amp; options.attachComment;
</del><span class="cx"> 
</span><del>-            if (extra.loc &amp;&amp; options.source !== null &amp;&amp; options.source !== undefined) {
-                extra.source = toString(options.source);
-            }
-
-            if (typeof options.tokens === 'boolean' &amp;&amp; options.tokens) {
-                extra.tokens = [];
-            }
-            if (typeof options.comment === 'boolean' &amp;&amp; options.comment) {
-                extra.comments = [];
-            }
-            if (typeof options.tolerant === 'boolean' &amp;&amp; options.tolerant) {
-                extra.errors = [];
-            }
-            if (extra.attachComment) {
-                extra.range = true;
-                extra.comments = [];
-                extra.bottomRightStack = [];
-                extra.trailingComments = [];
-                extra.leadingComments = [];
-            }
-            if (options.sourceType === 'module') {
-                // very restrictive condition for now
-                state.sourceType = options.sourceType;
-                strict = true;
-            }
-        }
-
-        try {
-            program = parseProgram();
-            if (typeof extra.comments !== 'undefined') {
-                program.comments = extra.comments;
-            }
-            if (typeof extra.tokens !== 'undefined') {
-                filterTokenLocation();
-                program.tokens = extra.tokens;
-            }
-            if (typeof extra.errors !== 'undefined') {
-                program.errors = extra.errors;
-            }
-        } catch (e) {
-            throw e;
-        } finally {
-            extra = {};
-        }
-
-        return program;
-    }
-
-    // Sync with *.json manifests.
-    exports.version = '2.6.0';
-
-    exports.tokenize = tokenize;
-
-    exports.parse = parse;
-
-    // Deep copy.
-    /* istanbul ignore next */
-    exports.Syntax = (function () {
-        var name, types = {};
-
-        if (typeof Object.create === 'function') {
-            types = Object.create(null);
-        }
-
-        for (name in Syntax) {
-            if (Syntax.hasOwnProperty(name)) {
-                types[name] = Syntax[name];
-            }
-        }
-
-        if (typeof Object.freeze === 'function') {
-            Object.freeze(types);
-        }
-
-        return types;
-    }());
-
-}));
</del><ins>+/***/ }
+/******/ ])
+});
+;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceModelsScriptSyntaxTreejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Models/ScriptSyntaxTree.js (209490 => 209491)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Models/ScriptSyntaxTree.js        2016-12-07 23:53:10 UTC (rev 209490)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/ScriptSyntaxTree.js        2016-12-08 00:04:07 UTC (rev 209491)
</span><span class="lines">@@ -327,6 +327,9 @@
</span><span class="cx">             this._recurse(node.left, callback, state);
</span><span class="cx">             this._recurse(node.right, callback, state);
</span><span class="cx">             break;
</span><ins>+        case WebInspector.ScriptSyntaxTree.NodeType.AwaitExpression:
+            this._recurse(node.argument, callback, state);
+            break;
</ins><span class="cx">         case WebInspector.ScriptSyntaxTree.NodeType.BlockStatement:
</span><span class="cx">             this._recurseArray(node.body, callback, state);
</span><span class="cx">             break;
</span><span class="lines">@@ -381,7 +384,6 @@
</span><span class="cx">         case WebInspector.ScriptSyntaxTree.NodeType.ArrowFunctionExpression:
</span><span class="cx">             this._recurse(node.id, callback, state);
</span><span class="cx">             this._recurseArray(node.params, callback, state);
</span><del>-            this._recurseArray(node.defaults, callback, state);
</del><span class="cx">             this._recurse(node.body, callback, state);
</span><span class="cx">             break;
</span><span class="cx">         case WebInspector.ScriptSyntaxTree.NodeType.IfStatement:
</span><span class="lines">@@ -534,10 +536,10 @@
</span><span class="cx">                 type: WebInspector.ScriptSyntaxTree.NodeType.ArrowFunctionExpression,
</span><span class="cx">                 id: this._createInternalSyntaxTree(node.id),
</span><span class="cx">                 params: node.params.map(this._createInternalSyntaxTree, this),
</span><del>-                defaults: node.defaults.map(this._createInternalSyntaxTree, this),
</del><span class="cx">                 body: this._createInternalSyntaxTree(node.body),
</span><span class="cx">                 generator: node.generator,
</span><span class="cx">                 expression: node.expression, // Boolean indicating if the body a single expression or a block statement.
</span><ins>+                async: node.async,
</ins><span class="cx">                 typeProfilingReturnDivot: node.range[0]
</span><span class="cx">             };
</span><span class="cx">             break;
</span><span class="lines">@@ -556,6 +558,12 @@
</span><span class="cx">                 right: this._createInternalSyntaxTree(node.right),
</span><span class="cx">             };
</span><span class="cx">             break;
</span><ins>+        case &quot;AwaitExpression&quot;:
+            result = {
+                type: WebInspector.ScriptSyntaxTree.NodeType.AwaitExpression,
+                argument: this._createInternalSyntaxTree(node.argument),
+            };
+            break;
</ins><span class="cx">         case &quot;BlockStatement&quot;:
</span><span class="cx">             result = {
</span><span class="cx">                 type: WebInspector.ScriptSyntaxTree.NodeType.BlockStatement,
</span><span class="lines">@@ -679,9 +687,9 @@
</span><span class="cx">                 type: WebInspector.ScriptSyntaxTree.NodeType.FunctionDeclaration,
</span><span class="cx">                 id: this._createInternalSyntaxTree(node.id),
</span><span class="cx">                 params: node.params.map(this._createInternalSyntaxTree, this),
</span><del>-                defaults: node.defaults.map(this._createInternalSyntaxTree, this),
</del><span class="cx">                 body: this._createInternalSyntaxTree(node.body),
</span><span class="cx">                 generator: node.generator,
</span><ins>+                async: node.async,
</ins><span class="cx">                 typeProfilingReturnDivot: node.range[0]
</span><span class="cx">             };
</span><span class="cx">             break;
</span><span class="lines">@@ -690,9 +698,9 @@
</span><span class="cx">                 type: WebInspector.ScriptSyntaxTree.NodeType.FunctionExpression,
</span><span class="cx">                 id: this._createInternalSyntaxTree(node.id),
</span><span class="cx">                 params: node.params.map(this._createInternalSyntaxTree, this),
</span><del>-                defaults: node.defaults.map(this._createInternalSyntaxTree, this),
</del><span class="cx">                 body: this._createInternalSyntaxTree(node.body),
</span><span class="cx">                 generator: node.generator,
</span><ins>+                async: node.async,
</ins><span class="cx">                 typeProfilingReturnDivot: node.range[0] // This may be overridden in the Property AST node.
</span><span class="cx">             };
</span><span class="cx">             break;
</span><span class="lines">@@ -744,8 +752,8 @@
</span><span class="cx">             // i.e: new.target produces {meta: &quot;new&quot;, property: &quot;target&quot;}
</span><span class="cx">             result = {
</span><span class="cx">                 type: WebInspector.ScriptSyntaxTree.NodeType.MetaProperty,
</span><del>-                meta: node.meta,
-                property: node.property
</del><ins>+                meta: this._createInternalSyntaxTree(node.meta),
+                property: this._createInternalSyntaxTree(node.property),
</ins><span class="cx">             };
</span><span class="cx">             break;
</span><span class="cx">         case &quot;MethodDefinition&quot;:
</span><span class="lines">@@ -955,6 +963,7 @@
</span><span class="cx">     ArrowFunctionExpression: Symbol(&quot;arrow-function-expression&quot;),
</span><span class="cx">     AssignmentExpression: Symbol(&quot;assignment-expression&quot;),
</span><span class="cx">     AssignmentPattern: Symbol(&quot;assignment-pattern&quot;),
</span><ins>+    AwaitExpression: Symbol(&quot;await-expression&quot;),
</ins><span class="cx">     BinaryExpression: Symbol(&quot;binary-expression&quot;),
</span><span class="cx">     BlockStatement: Symbol(&quot;block-statement&quot;),
</span><span class="cx">     BreakStatement: Symbol(&quot;break-statement&quot;),
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceWorkersFormatterESTreeWalkerjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Workers/Formatter/ESTreeWalker.js (209490 => 209491)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Workers/Formatter/ESTreeWalker.js        2016-12-07 23:53:10 UTC (rev 209490)
+++ trunk/Source/WebInspectorUI/UserInterface/Workers/Formatter/ESTreeWalker.js        2016-12-08 00:04:07 UTC (rev 209491)
</span><span class="lines">@@ -86,6 +86,9 @@
</span><span class="cx">             this._walk(node.left, node);
</span><span class="cx">             this._walk(node.right, node);
</span><span class="cx">             break;
</span><ins>+        case &quot;AwaitExpression&quot;:
+            this._walk(node.argument, node);
+            break;
</ins><span class="cx">         case &quot;BlockStatement&quot;:
</span><span class="cx">             this._walkArray(node.body, node);
</span><span class="cx">             break;
</span><span class="lines">@@ -137,9 +140,7 @@
</span><span class="cx">         case &quot;FunctionExpression&quot;:
</span><span class="cx">         case &quot;ArrowFunctionExpression&quot;:
</span><span class="cx">             this._walk(node.id, node);
</span><del>-            // FIXME: This should probably iterate params/defaults in special order.
</del><span class="cx">             this._walkArray(node.params, node);
</span><del>-            this._walkArray(node.defaults, node);
</del><span class="cx">             this._walk(node.body, node);
</span><span class="cx">             break;
</span><span class="cx">         case &quot;IfStatement&quot;:
</span><span class="lines">@@ -269,6 +270,10 @@
</span><span class="cx">             this._walk(node.imported, node);
</span><span class="cx">             this._walk(node.local, node);
</span><span class="cx">             break;
</span><ins>+        case &quot;MetaProperty&quot;:
+            this._walk(node.meta, node);
+            this._walk(node.property, node);
+            break;
</ins><span class="cx"> 
</span><span class="cx">         // Special case. We want to walk in program order,
</span><span class="cx">         // so walk quasi, expression, quasi, expression, etc.
</span><span class="lines">@@ -284,7 +289,6 @@
</span><span class="cx">         case &quot;EmptyStatement&quot;:
</span><span class="cx">         case &quot;Identifier&quot;:
</span><span class="cx">         case &quot;Literal&quot;:
</span><del>-        case &quot;MetaProperty&quot;:
</del><span class="cx">         case &quot;Super&quot;:
</span><span class="cx">         case &quot;ThisExpression&quot;:
</span><span class="cx">         case &quot;TemplateElement&quot;:
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceWorkersFormatterEsprimaFormatterjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Workers/Formatter/EsprimaFormatter.js (209490 => 209491)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Workers/Formatter/EsprimaFormatter.js        2016-12-07 23:53:10 UTC (rev 209490)
+++ trunk/Source/WebInspectorUI/UserInterface/Workers/Formatter/EsprimaFormatter.js        2016-12-08 00:04:07 UTC (rev 209491)
</span><span class="lines">@@ -209,11 +209,19 @@
</span><span class="cx">         let tokenOffset = token.range[0];
</span><span class="cx"> 
</span><span class="cx">         // Very common types that just pass through.
</span><del>-        if (nodeType === &quot;Identifier&quot; || nodeType === &quot;MemberExpression&quot; || nodeType === &quot;Literal&quot; || nodeType === &quot;ThisExpression&quot; || nodeType === &quot;UpdateExpression&quot;) {
</del><ins>+        if (nodeType === &quot;MemberExpression&quot; || nodeType === &quot;Literal&quot; || nodeType === &quot;ThisExpression&quot; || nodeType === &quot;UpdateExpression&quot;) {
</ins><span class="cx">             builder.appendToken(tokenValue, tokenOffset);
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        // Most identifiers just pass through, but a few are special.
+        if (nodeType === &quot;Identifier&quot;) {
+            builder.appendToken(tokenValue, tokenOffset);
+            if (tokenValue === &quot;async&quot; &amp;&amp; node.parent.type === &quot;Property&quot; &amp;&amp; node.parent.value.async &amp;&amp; token.range[1] !== node.range[1])
+                builder.appendSpace();
+            return;
+        }
+
</ins><span class="cx">         // Most newline handling is done with semicolons. However, we preserve
</span><span class="cx">         // newlines so code relying on automatic semicolon insertion should
</span><span class="cx">         // continue to work.
</span><span class="lines">@@ -426,6 +434,11 @@
</span><span class="cx">                     builder.appendSpace();
</span><span class="cx">                 return;
</span><span class="cx">             }
</span><ins>+            if (tokenType === &quot;Identifier&quot; &amp;&amp; tokenValue === &quot;async&quot;) {
+                builder.appendToken(tokenValue, tokenOffset);
+                builder.appendSpace();
+                return;
+            }
</ins><span class="cx">             builder.appendToken(tokenValue, tokenOffset);
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="lines">@@ -661,16 +674,34 @@
</span><span class="cx">                 }
</span><span class="cx">             }
</span><span class="cx">             builder.appendToken(tokenValue, tokenOffset);
</span><ins>+            if (tokenType === &quot;Identifier&quot; &amp;&amp; tokenValue === &quot;async&quot;)
+                builder.appendSpace();
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        if (nodeType === &quot;AwaitExpression&quot;) {
+            builder.appendToken(tokenValue, tokenOffset);
+            if (tokenType === &quot;Identifier&quot; &amp;&amp; tokenValue === &quot;await&quot;)
+                builder.appendSpace();
+            return;
+        }
+
</ins><span class="cx">         if (nodeType === &quot;Property&quot;) {
</span><ins>+            console.assert(tokenValue === &quot;:&quot; || tokenValue === &quot;get&quot; || tokenValue === &quot;set&quot; || tokenValue === &quot;async&quot; || tokenValue === &quot;*&quot; || tokenValue === &quot;[&quot; || tokenValue === &quot;]&quot;, token);
</ins><span class="cx">             builder.appendToken(tokenValue, tokenOffset);
</span><del>-            if (tokenValue === &quot;:&quot; || tokenValue === &quot;get&quot; || tokenValue === &quot;set&quot;)
</del><ins>+            if (tokenValue === &quot;:&quot; || tokenValue === &quot;get&quot; || tokenValue === &quot;set&quot; || tokenValue === &quot;async&quot;)
</ins><span class="cx">                 builder.appendSpace();
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        if (nodeType === &quot;MethodDefinition&quot;) {
+            console.assert(tokenValue === &quot;static&quot; || tokenValue === &quot;get&quot; || tokenValue === &quot;set&quot; || tokenValue === &quot;async&quot; || tokenValue === &quot;*&quot; || tokenValue === &quot;[&quot; || tokenValue === &quot;]&quot;, token);
+            builder.appendToken(tokenValue, tokenOffset);
+            if (tokenValue === &quot;static&quot; || tokenValue === &quot;get&quot; || tokenValue === &quot;set&quot; || tokenValue === &quot;async&quot;)
+                builder.appendSpace();
+            return;
+        }
+
</ins><span class="cx">         if (nodeType === &quot;BreakStatement&quot; || nodeType === &quot;ContinueStatement&quot;) {
</span><span class="cx">             builder.appendToken(tokenValue, tokenOffset);
</span><span class="cx">             if (tokenType === &quot;Keyword&quot; &amp;&amp; node.label)
</span><span class="lines">@@ -758,14 +789,6 @@
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        if (nodeType === &quot;MethodDefinition&quot;) {
-            console.assert(tokenValue === &quot;static&quot; || tokenValue === &quot;get&quot; || tokenValue === &quot;set&quot; || tokenValue === &quot;*&quot;, token);
-            builder.appendToken(tokenValue, tokenOffset);
-            if (tokenValue !== &quot;*&quot;)
-                builder.appendSpace();
-            return;
-        }
-
</del><span class="cx">         if (nodeType === &quot;YieldExpression&quot;) {
</span><span class="cx">             if (tokenType === &quot;Keyword&quot;) {
</span><span class="cx">                 console.assert(tokenValue === &quot;yield&quot;, token);
</span><span class="lines">@@ -810,7 +833,8 @@
</span><span class="cx">             || nodeType === &quot;RestElement&quot;
</span><span class="cx">             || nodeType === &quot;TemplateElement&quot;
</span><span class="cx">             || nodeType === &quot;TemplateLiteral&quot;
</span><del>-            || nodeType === &quot;DebuggerStatement&quot;) {
</del><ins>+            || nodeType === &quot;DebuggerStatement&quot;
+            || nodeType === &quot;AssignmentPattern&quot;) {
</ins><span class="cx">             builder.appendToken(tokenValue, tokenOffset);
</span><span class="cx">             return;
</span><span class="cx">         }
</span></span></pre>
</div>
</div>

</body>
</html>